Add ruff
Change-Id: Iaaf8628a74f7d90a41cc7f0d58b2a2c49f9bf815 Signed-off-by: Stephen Finucane <stephenfin@redhat.com>
This commit is contained in:
@@ -12,13 +12,15 @@ repos:
|
||||
- id: debug-statements
|
||||
- id: check-yaml
|
||||
files: .*\.(yaml|yml)$
|
||||
- repo: https://github.com/astral-sh/ruff-pre-commit
|
||||
rev: v0.14.7
|
||||
hooks:
|
||||
- id: ruff-check
|
||||
args: ['--fix', '--unsafe-fixes']
|
||||
- id: ruff-format
|
||||
- repo: https://opendev.org/openstack/hacking
|
||||
rev: 7.0.0
|
||||
rev: 8.0.0
|
||||
hooks:
|
||||
- id: hacking
|
||||
additional_dependencies: []
|
||||
- repo: https://github.com/asottile/pyupgrade
|
||||
rev: v3.20.0
|
||||
hooks:
|
||||
- id: pyupgrade
|
||||
args: [--py310-plus]
|
||||
exclude: '^(doc|releasenotes)/.*$'
|
||||
|
||||
@@ -34,10 +34,7 @@ copyright = '2018, Oslo Contributors'
|
||||
|
||||
# Add any Sphinx extension module names here, as strings. They can be
|
||||
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
|
||||
extensions = [
|
||||
'sphinx.ext.autodoc',
|
||||
'openstackdocstheme'
|
||||
]
|
||||
extensions = ['sphinx.ext.autodoc', 'openstackdocstheme']
|
||||
|
||||
# The master toctree document.
|
||||
master_doc = 'index'
|
||||
|
||||
@@ -22,22 +22,19 @@ from oslo_upgradecheck import upgradecheck
|
||||
|
||||
class Checks(upgradecheck.UpgradeCommands):
|
||||
def success(self):
|
||||
return upgradecheck.Result(upgradecheck.Code.SUCCESS,
|
||||
'Always succeeds')
|
||||
return upgradecheck.Result(
|
||||
upgradecheck.Code.SUCCESS, 'Always succeeds'
|
||||
)
|
||||
|
||||
def failure(self):
|
||||
return upgradecheck.Result(upgradecheck.Code.FAILURE, 'Always fails')
|
||||
|
||||
_upgrade_checks = (('always succeeds', success),
|
||||
('always fails', failure),
|
||||
)
|
||||
_upgrade_checks = (('always succeeds', success), ('always fails', failure))
|
||||
|
||||
|
||||
def main():
|
||||
return upgradecheck.main(
|
||||
conf=cfg.CONF,
|
||||
project='myprojectname',
|
||||
upgrade_command=Checks(),
|
||||
conf=cfg.CONF, project='myprojectname', upgrade_command=Checks()
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -26,16 +26,17 @@ def check_policy_json(self, conf):
|
||||
# NOTE(gmann): This method need [oslo_policy].policy_file
|
||||
# config value so register those options in case they
|
||||
# are not register by services.
|
||||
conf.register_opts(policy_opts._options,
|
||||
group=policy_opts._option_group)
|
||||
conf.register_opts(policy_opts._options, group=policy_opts._option_group)
|
||||
|
||||
msg = ("Your policy file is JSON-formatted which is "
|
||||
"deprecated. You need to switch to YAML-formatted file. "
|
||||
"Use the ``oslopolicy-convert-json-to-yaml`` "
|
||||
"tool to convert the existing JSON-formatted files to "
|
||||
"YAML in a backwards-compatible manner: "
|
||||
"https://docs.openstack.org/oslo.policy/"
|
||||
"latest/cli/oslopolicy-convert-json-to-yaml.html.")
|
||||
msg = (
|
||||
"Your policy file is JSON-formatted which is "
|
||||
"deprecated. You need to switch to YAML-formatted file. "
|
||||
"Use the ``oslopolicy-convert-json-to-yaml`` "
|
||||
"tool to convert the existing JSON-formatted files to "
|
||||
"YAML in a backwards-compatible manner: "
|
||||
"https://docs.openstack.org/oslo.policy/"
|
||||
"latest/cli/oslopolicy-convert-json-to-yaml.html."
|
||||
)
|
||||
status = upgradecheck.Result(upgradecheck.Code.SUCCESS)
|
||||
# Check if policy file exist and is JSON-formatted.
|
||||
policy_path = conf.find_file(conf.oslo_policy.policy_file)
|
||||
|
||||
@@ -26,24 +26,24 @@ from oslo_upgradecheck import upgradecheck
|
||||
|
||||
|
||||
class TestUpgradeCheckPolicyJSON(base.BaseTestCase):
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
conf_fixture = self.useFixture(config.Config())
|
||||
conf_fixture.load_raw_values()
|
||||
self.conf = conf_fixture.conf
|
||||
self.conf.register_opts(policy_opts._options,
|
||||
group=policy_opts._option_group)
|
||||
self.conf.register_opts(
|
||||
policy_opts._options, group=policy_opts._option_group
|
||||
)
|
||||
|
||||
self.cmd = upgradecheck.UpgradeCommands()
|
||||
self.cmd._upgrade_checks = (('Policy File JSON to YAML Migration',
|
||||
(common_checks.check_policy_json,
|
||||
{'conf': self.conf})),)
|
||||
self.cmd._upgrade_checks = (
|
||||
(
|
||||
'Policy File JSON to YAML Migration',
|
||||
(common_checks.check_policy_json, {'conf': self.conf}),
|
||||
),
|
||||
)
|
||||
|
||||
self.data = {
|
||||
'rule_admin': 'True',
|
||||
'rule_admin2': 'is_admin:True'
|
||||
}
|
||||
self.data = {'rule_admin': 'True', 'rule_admin2': 'is_admin:True'}
|
||||
self.temp_dir = self.useFixture(fixtures.TempDir())
|
||||
fd, self.json_file = tempfile.mkstemp(dir=self.temp_dir.path)
|
||||
fd, self.yaml_file = tempfile.mkstemp(dir=self.temp_dir.path)
|
||||
@@ -59,44 +59,45 @@ class TestUpgradeCheckPolicyJSON(base.BaseTestCase):
|
||||
return original_search_dirs(dirs, name)
|
||||
|
||||
mock_search_dir = self.useFixture(
|
||||
fixtures.MockPatch('oslo_config.cfg._search_dirs')).mock
|
||||
fixtures.MockPatch('oslo_config.cfg._search_dirs')
|
||||
).mock
|
||||
mock_search_dir.side_effect = fake_search_dirs
|
||||
|
||||
def test_policy_json_file_fail_upgrade(self):
|
||||
# Test with policy json file full path set in config.
|
||||
self.conf.set_override('policy_file', self.json_file,
|
||||
group="oslo_policy")
|
||||
self.assertEqual(upgradecheck.Code.FAILURE,
|
||||
self.cmd.check())
|
||||
self.conf.set_override(
|
||||
'policy_file', self.json_file, group="oslo_policy"
|
||||
)
|
||||
self.assertEqual(upgradecheck.Code.FAILURE, self.cmd.check())
|
||||
|
||||
def test_policy_yaml_file_pass_upgrade(self):
|
||||
# Test with full policy yaml file path set in config.
|
||||
self.conf.set_override('policy_file', self.yaml_file,
|
||||
group="oslo_policy")
|
||||
self.assertEqual(upgradecheck.Code.SUCCESS,
|
||||
self.cmd.check())
|
||||
self.conf.set_override(
|
||||
'policy_file', self.yaml_file, group="oslo_policy"
|
||||
)
|
||||
self.assertEqual(upgradecheck.Code.SUCCESS, self.cmd.check())
|
||||
|
||||
def test_no_policy_file_pass_upgrade(self):
|
||||
# Test with no policy file exist, means use policy from code.
|
||||
self.conf.set_override('policy_file', 'non_exist_file',
|
||||
group="oslo_policy")
|
||||
self.assertEqual(upgradecheck.Code.SUCCESS,
|
||||
self.cmd.check())
|
||||
self.conf.set_override(
|
||||
'policy_file', 'non_exist_file', group="oslo_policy"
|
||||
)
|
||||
self.assertEqual(upgradecheck.Code.SUCCESS, self.cmd.check())
|
||||
|
||||
def test_default_policy_yaml_file_pass_upgrade(self):
|
||||
self.conf.set_override('policy_file', 'policy.yaml',
|
||||
group="oslo_policy")
|
||||
self.conf.set_override(
|
||||
'policy_file', 'policy.yaml', group="oslo_policy"
|
||||
)
|
||||
tmpfilename = os.path.join(self.temp_dir.path, 'policy.yaml')
|
||||
with open(tmpfilename, 'w') as fh:
|
||||
yaml.dump(self.data, fh)
|
||||
self.assertEqual(upgradecheck.Code.SUCCESS,
|
||||
self.cmd.check())
|
||||
self.assertEqual(upgradecheck.Code.SUCCESS, self.cmd.check())
|
||||
|
||||
def test_old_default_policy_json_file_fail_upgrade(self):
|
||||
self.conf.set_override('policy_file', 'policy.json',
|
||||
group="oslo_policy")
|
||||
self.conf.set_override(
|
||||
'policy_file', 'policy.json', group="oslo_policy"
|
||||
)
|
||||
tmpfilename = os.path.join(self.temp_dir.path, 'policy.json')
|
||||
with open(tmpfilename, 'w') as fh:
|
||||
jsonutils.dump(self.data, fh)
|
||||
self.assertEqual(upgradecheck.Code.FAILURE,
|
||||
self.cmd.check())
|
||||
self.assertEqual(upgradecheck.Code.FAILURE, self.cmd.check())
|
||||
|
||||
@@ -29,7 +29,6 @@ from oslo_upgradecheck import upgradecheck
|
||||
|
||||
|
||||
class TestUpgradeCheckResult(base.BaseTestCase):
|
||||
|
||||
def test_details(self):
|
||||
result = upgradecheck.Result(upgradecheck.Code.SUCCESS, 'test details')
|
||||
self.assertEqual(0, result.code)
|
||||
@@ -38,8 +37,9 @@ class TestUpgradeCheckResult(base.BaseTestCase):
|
||||
|
||||
class TestCommands(upgradecheck.UpgradeCommands):
|
||||
def success(self):
|
||||
return upgradecheck.Result(upgradecheck.Code.SUCCESS,
|
||||
'Always succeeds')
|
||||
return upgradecheck.Result(
|
||||
upgradecheck.Code.SUCCESS, 'Always succeeds'
|
||||
)
|
||||
|
||||
def warning(self):
|
||||
return upgradecheck.Result(upgradecheck.Code.WARNING, 'Always warns')
|
||||
@@ -47,10 +47,11 @@ class TestCommands(upgradecheck.UpgradeCommands):
|
||||
def failure(self):
|
||||
return upgradecheck.Result(upgradecheck.Code.FAILURE, 'Always fails')
|
||||
|
||||
_upgrade_checks = (('always succeeds', success),
|
||||
('always warns', warning),
|
||||
('always fails', failure),
|
||||
)
|
||||
_upgrade_checks = (
|
||||
('always succeeds', success),
|
||||
('always warns', warning),
|
||||
('always fails', failure),
|
||||
)
|
||||
|
||||
|
||||
class SuccessCommands(TestCommands):
|
||||
@@ -98,10 +99,13 @@ class TestMain(base.BaseTestCase):
|
||||
|
||||
class TestExampleFile(base.BaseTestCase):
|
||||
def test_example_main(self):
|
||||
path = os.path.join(os.path.dirname(os.path.abspath(__file__)),
|
||||
'../../doc/source/main.py')
|
||||
path = os.path.join(
|
||||
os.path.dirname(os.path.abspath(__file__)),
|
||||
'../../doc/source/main.py',
|
||||
)
|
||||
# The example includes both a passing and failing test, which means the
|
||||
# overall result is failure.
|
||||
self.assertEqual(
|
||||
upgradecheck.Code.FAILURE,
|
||||
subprocess.call([sys.executable, path, 'upgrade', 'check']))
|
||||
subprocess.call([sys.executable, path, 'upgrade', 'check']),
|
||||
)
|
||||
|
||||
@@ -77,14 +77,18 @@ class UpgradeCommands:
|
||||
done through the sqlalchemy query language directly like the database
|
||||
schema migrations.
|
||||
"""
|
||||
|
||||
display_title = _('Upgrade Check Results')
|
||||
_upgrade_checks = ()
|
||||
|
||||
def _get_details(self, upgrade_check_result):
|
||||
if upgrade_check_result.details is not None:
|
||||
# wrap the text on the details to 60 characters
|
||||
return '\n'.join(textwrap.wrap(upgrade_check_result.details, 60,
|
||||
subsequent_indent=' '))
|
||||
return '\n'.join(
|
||||
textwrap.wrap(
|
||||
upgrade_check_result.details, 60, subsequent_indent=' '
|
||||
)
|
||||
)
|
||||
|
||||
def check(self):
|
||||
"""Performs checks to see if the deployment is ready for upgrade.
|
||||
@@ -125,17 +129,22 @@ class UpgradeCommands:
|
||||
|
||||
# Since registering opts can be overridden by consuming code, we can't
|
||||
# assume that our locally defined option exists.
|
||||
if (hasattr(CONF, 'command') and hasattr(CONF.command, 'json') and
|
||||
CONF.command.json):
|
||||
if (
|
||||
hasattr(CONF, 'command')
|
||||
and hasattr(CONF.command, 'json')
|
||||
and CONF.command.json
|
||||
):
|
||||
# NOTE(bnemec): We use str on the translated string to
|
||||
# force immediate translation if lazy translation is in use.
|
||||
# See lp1801761 for details.
|
||||
output = {'name': str(self.display_title), 'checks': []}
|
||||
for name, result in check_results:
|
||||
output['checks'].append(
|
||||
{'check': name,
|
||||
'result': result.code,
|
||||
'details': result.details}
|
||||
{
|
||||
'check': name,
|
||||
'result': result.code,
|
||||
'details': result.details,
|
||||
}
|
||||
)
|
||||
print(json.dumps(output))
|
||||
else:
|
||||
@@ -143,19 +152,17 @@ class UpgradeCommands:
|
||||
# force immediate translation if lazy translation is in use.
|
||||
# See lp1801761 for details.
|
||||
t = prettytable.PrettyTable(
|
||||
[str(self.display_title)], hrules=prettytable.ALL)
|
||||
[str(self.display_title)], hrules=prettytable.ALL
|
||||
)
|
||||
t.align = 'l'
|
||||
for name, result in check_results:
|
||||
cell = (
|
||||
_('Check: %(name)s\n'
|
||||
'Result: %(result)s\n'
|
||||
'Details: %(details)s') %
|
||||
{
|
||||
'name': name,
|
||||
'result': UPGRADE_CHECK_MSG_MAP[result.code],
|
||||
'details': self._get_details(result),
|
||||
}
|
||||
)
|
||||
cell = _(
|
||||
'Check: %(name)s\nResult: %(result)s\nDetails: %(details)s'
|
||||
) % {
|
||||
'name': name,
|
||||
'result': UPGRADE_CHECK_MSG_MAP[result.code],
|
||||
'details': self._get_details(result),
|
||||
}
|
||||
t.add_row([cell])
|
||||
print(t)
|
||||
|
||||
@@ -171,6 +178,7 @@ def register_cli_options(conf, upgrade_command):
|
||||
upgrade check arguments.
|
||||
:param upgrade_command: The UpgradeCommands instance.
|
||||
"""
|
||||
|
||||
def add_parsers(subparsers):
|
||||
upgrade_action = subparsers.add_parser('upgrade')
|
||||
upgrade_action.add_argument('check')
|
||||
@@ -179,7 +187,8 @@ def register_cli_options(conf, upgrade_command):
|
||||
'--json',
|
||||
action='store_true',
|
||||
help='Output the results in JSON format. Default is to print '
|
||||
'results in human readable table format.')
|
||||
'results in human readable table format.',
|
||||
)
|
||||
|
||||
opt = cfg.SubCommandOpt('command', handler=add_parsers)
|
||||
conf.register_cli_opt(opt)
|
||||
@@ -199,9 +208,13 @@ def run(conf):
|
||||
return 255
|
||||
|
||||
|
||||
def main(conf, project, upgrade_command,
|
||||
argv=sys.argv[1:],
|
||||
default_config_files=None):
|
||||
def main(
|
||||
conf,
|
||||
project,
|
||||
upgrade_command,
|
||||
argv=sys.argv[1:],
|
||||
default_config_files=None,
|
||||
):
|
||||
"""Simple implementation of main for upgrade checks
|
||||
|
||||
This can be used in upgrade check commands to provide the minimum
|
||||
@@ -223,10 +236,6 @@ def main(conf, project, upgrade_command,
|
||||
global CONF
|
||||
register_cli_options(conf, upgrade_command)
|
||||
|
||||
conf(
|
||||
args=argv,
|
||||
project=project,
|
||||
default_config_files=default_config_files,
|
||||
)
|
||||
conf(args=argv, project=project, default_config_files=default_config_files)
|
||||
CONF = conf
|
||||
return run(conf)
|
||||
|
||||
@@ -34,3 +34,21 @@ Repository = "https://opendev.org/openstack/oslo.upgradecheck"
|
||||
packages = [
|
||||
"oslo_upgradecheck"
|
||||
]
|
||||
|
||||
[tool.ruff]
|
||||
line-length = 79
|
||||
|
||||
[tool.ruff.lint]
|
||||
select = ["C4", "E4", "E5", "E7", "E9", "F", "S", "UP"]
|
||||
ignore = [
|
||||
# we only use asserts for type narrowing
|
||||
"S101",
|
||||
]
|
||||
|
||||
[tool.ruff.lint.per-file-ignores]
|
||||
"oslo_upgradecheck/tests/*" = ["S"]
|
||||
|
||||
[tool.ruff.format]
|
||||
quote-style = "preserve"
|
||||
docstring-code-format = true
|
||||
skip-magic-trailing-comma = true
|
||||
|
||||
@@ -33,10 +33,7 @@ release = ''
|
||||
|
||||
# Add any Sphinx extension module names here, as strings. They can be
|
||||
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
|
||||
extensions = [
|
||||
'reno.sphinxext',
|
||||
'openstackdocstheme',
|
||||
]
|
||||
extensions = ['reno.sphinxext', 'openstackdocstheme']
|
||||
|
||||
# The master toctree document.
|
||||
master_doc = 'index'
|
||||
|
||||
4
setup.py
4
setup.py
@@ -15,6 +15,4 @@
|
||||
|
||||
import setuptools
|
||||
|
||||
setuptools.setup(
|
||||
setup_requires=['pbr'],
|
||||
pbr=True)
|
||||
setuptools.setup(setup_requires=['pbr'], pbr=True)
|
||||
|
||||
11
tox.ini
11
tox.ini
@@ -59,11 +59,14 @@ commands =
|
||||
commands = oslo_debug_helper {posargs}
|
||||
|
||||
[flake8]
|
||||
# E123, E125 skipped as they are invalid PEP-8.
|
||||
# We only enable the hacking (H) checks
|
||||
select = H
|
||||
# H301 Black will put commas after imports that can't fit on one line
|
||||
# H404 Docstrings don't always start with a newline
|
||||
# H405 Multiline docstrings are okay
|
||||
ignore = H301,H403,H404,H405
|
||||
show-source = True
|
||||
ignore = E123,E125,W504
|
||||
builtins = _
|
||||
exclude=.venv,.git,.tox,dist,doc,releasenotes,*lib/python*,*egg,build
|
||||
exclude = .venv,.git,.tox,dist,doc,releasenotes,*lib/python*,*egg,build
|
||||
|
||||
[hacking]
|
||||
import_exception = oslo_upgradecheck._i18n
|
||||
|
||||
Reference in New Issue
Block a user