mirror of
https://github.com/ansible/awx.git
synced 2026-10-29 22:03:20 -02:30
AAP-85334: Replace Black + Flake8 with Ruff
Migrate Python linting and formatting toolchain from Black (formatter) and Flake8 (linter) to Ruff, which provides both in a single tool. - pyproject.toml: remove [tool.black], add [tool.ruff] config sections - tox.ini: replace black+flake8 deps/commands with ruff in linters env - awxkit/tox.ini: replace flake8 with ruff in lint env - Makefile: replace `black` target with `format` + `lint`, keep `black` as legacy alias, update `check` and `api-lint` - pre-commit.sh: use `ruff format --check`, honor AWX_IGNORE_RUFF - requirements_dev.txt: swap black/flake8 for ruff - Dockerfile.j2: install ruff instead of black - CONTRIBUTING.md: update tool references - Fix noqa comments to use # separator instead of ; (ruff requirement) - Add noqa: F841 for false positive in awxkit/cli/__init__.py Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
b84931a49b
commit
4b73e1264b
+2
-2
@@ -109,7 +109,7 @@ Install the pre-commit hook before contributing:
|
||||
make pre-commit
|
||||
```
|
||||
|
||||
When you attempt to perform a `git commit` there will be a pre-commit hook that gets run before the commit is allowed to your local repository. For example, python's [black](https://pypi.org/project/black/) will be run to test the formatting of any python files.
|
||||
When you attempt to perform a `git commit` there will be a pre-commit hook that gets run before the commit is allowed to your local repository. For example, [ruff](https://docs.astral.sh/ruff/) will be run to check the formatting of any python files.
|
||||
|
||||
While you can use environment variables to skip the pre-commit hooks GitHub will run similar tests and prevent merging of PRs if the tests do not pass.
|
||||
|
||||
@@ -148,7 +148,7 @@ Fixes and Features for AWX will go through the Github pull request process. Subm
|
||||
Here are a few things you can do to help the visibility of your change, and increase the likelihood that it will be accepted:
|
||||
|
||||
- No issues when running linters/code checkers
|
||||
- Python: black: `(container)/awx_devel$ make black`
|
||||
- Python: ruff: `(container)/awx_devel$ make format`
|
||||
- No issues from unit tests
|
||||
- Python: py.test: `(container)/awx_devel$ make test`
|
||||
- Write tests for new functionality, update/add tests for bug fixes
|
||||
|
||||
@@ -348,9 +348,17 @@ run-ws-heartbeat:
|
||||
reports:
|
||||
mkdir -p $@
|
||||
|
||||
black: reports
|
||||
@command -v black >/dev/null 2>&1 || { echo "could not find black on your PATH, you may need to \`pip install black\`, or set AWX_IGNORE_BLACK=1" && exit 1; }
|
||||
@(set -o pipefail && $@ $(BLACK_ARGS) awx awxkit awx_collection | tee reports/$@.report)
|
||||
## awx_collection is excluded: ansible-test sanity runs its own linters which conflict with ruff
|
||||
format: reports
|
||||
@command -v ruff >/dev/null 2>&1 || { echo "could not find ruff on your PATH, you may need to \`pip install ruff\`" && exit 1; }
|
||||
@(set -o pipefail && ruff format $(RUFF_FORMAT_ARGS) awx awxkit | tee reports/format.report)
|
||||
|
||||
lint: reports
|
||||
@command -v ruff >/dev/null 2>&1 || { echo "could not find ruff on your PATH, you may need to \`pip install ruff\`" && exit 1; }
|
||||
ruff check awx awxkit
|
||||
|
||||
## Legacy alias
|
||||
black: format
|
||||
|
||||
$(GIT_COMMON_DIR)/hooks/pre-commit:
|
||||
ln -sf ../../pre-commit.sh $(GIT_COMMON_DIR)/hooks/pre-commit
|
||||
@@ -369,11 +377,11 @@ genschema-yaml: awx-link reports
|
||||
fi; \
|
||||
$(MANAGEMENT_COMMAND) spectacular --format openapi --file schema.yaml
|
||||
|
||||
check: black
|
||||
check: format
|
||||
|
||||
api-lint:
|
||||
BLACK_ARGS="--check" $(MAKE) black
|
||||
flake8 awx
|
||||
RUFF_FORMAT_ARGS="--check" $(MAKE) format
|
||||
$(MAKE) lint
|
||||
yamllint -s .
|
||||
|
||||
## Run egg_info_dev to generate awx.egg-info for development.
|
||||
|
||||
@@ -6,7 +6,7 @@ from awx.api.versioning import reverse
|
||||
from django.test.utils import override_settings
|
||||
|
||||
from ansible_base.jwt_consumer.common.util import generate_x_trusted_proxy_header
|
||||
from ansible_base.lib.testing.fixtures import rsa_keypair_factory, rsa_keypair # noqa: F401; pylint: disable=unused-import
|
||||
from ansible_base.lib.testing.fixtures import rsa_keypair_factory, rsa_keypair # noqa: F401 # pylint: disable=unused-import
|
||||
|
||||
|
||||
class HeaderTrackingMiddleware(object):
|
||||
|
||||
@@ -16,7 +16,7 @@ from rest_framework.exceptions import ValidationError
|
||||
|
||||
# DAB
|
||||
from ansible_base.jwt_consumer.common.util import generate_x_trusted_proxy_header
|
||||
from ansible_base.lib.testing.fixtures import rsa_keypair_factory, rsa_keypair # noqa: F401; pylint: disable=unused-import
|
||||
from ansible_base.lib.testing.fixtures import rsa_keypair_factory, rsa_keypair # noqa: F401 # pylint: disable=unused-import
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
@@ -161,7 +161,7 @@ def test_invalid_json_body(patch, job_template_factory, alice, json_body):
|
||||
objs = job_template_factory('jt', organization='org1')
|
||||
objs.job_template.admin_role.members.add(alice)
|
||||
resp = patch(reverse('api:job_template_detail', kwargs={'pk': objs.job_template.id}), json_body, alice, expect=400)
|
||||
assert resp.data['detail'] == (u'JSON parse error - not a JSON object')
|
||||
assert resp.data['detail'] == ('JSON parse error - not a JSON object')
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
@@ -432,7 +432,7 @@ class TestJobTemplateCallbackProxyIntegration:
|
||||
data={'host_config_key': 'abcd'},
|
||||
user=admin_user,
|
||||
expect=expected,
|
||||
**headers
|
||||
**headers,
|
||||
)
|
||||
|
||||
@override_settings(REMOTE_HOST_HEADERS=['HTTP_X_FROM_THE_LOAD_BALANCER', 'REMOTE_ADDR', 'REMOTE_HOST'], PROXY_IP_ALLOWED_LIST=[])
|
||||
@@ -462,7 +462,7 @@ class TestJobTemplateCallbackProxyIntegration:
|
||||
data={'host_config_key': 'abcd'},
|
||||
user=admin_user,
|
||||
expect=201,
|
||||
**headers
|
||||
**headers,
|
||||
)
|
||||
|
||||
@override_settings(REMOTE_HOST_HEADERS=['HTTP_X_FROM_THE_LOAD_BALANCER', 'REMOTE_ADDR', 'REMOTE_HOST'], PROXY_IP_ALLOWED_LIST=['my.proxy.example.org'])
|
||||
@@ -483,5 +483,5 @@ class TestJobTemplateCallbackProxyIntegration:
|
||||
data={'host_config_key': 'abcd'},
|
||||
user=admin_user,
|
||||
expect=400,
|
||||
**headers
|
||||
**headers,
|
||||
)
|
||||
|
||||
@@ -15,7 +15,7 @@ from awx.api.versioning import reverse
|
||||
# These tests are invoked from the awx/main/tests/live/ subfolder
|
||||
# so any fixtures from higher-up conftest files must be explicitly included
|
||||
from awx.main.tests.functional.conftest import * # noqa
|
||||
from awx.main.tests.conftest import load_all_credentials # noqa: F401; pylint: disable=unused-import
|
||||
from awx.main.tests.conftest import load_all_credentials # noqa: F401 # pylint: disable=unused-import
|
||||
from awx.main.tests import data
|
||||
|
||||
from awx.main.models import Project, JobTemplate, Organization, Inventory, WorkflowJob, UnifiedJob
|
||||
|
||||
@@ -56,7 +56,7 @@ import logging
|
||||
|
||||
# In this module we don't use EXPORTABLE_RESOURCES, we just want to validate that our installed awxkit has import/export
|
||||
try:
|
||||
from awxkit.api.pages.api import EXPORTABLE_RESOURCES # noqa: F401; pylint: disable=unused-import
|
||||
from awxkit.api.pages.api import EXPORTABLE_RESOURCES # noqa: F401 # pylint: disable=unused-import
|
||||
|
||||
HAS_EXPORTABLE_RESOURCES = True
|
||||
except ImportError:
|
||||
|
||||
@@ -21,9 +21,9 @@ from ansible_base.rbac.models import RoleDefinition, DABPermission
|
||||
from ansible_base.rbac import permission_registry
|
||||
|
||||
from awx.main.migrations._dab_rbac import setup_managed_role_definitions
|
||||
from awx.main.tests.conftest import load_all_credentials # noqa: F401; pylint: disable=unused-import
|
||||
from awx.main.tests.conftest import load_all_credentials # noqa: F401 # pylint: disable=unused-import
|
||||
from awx.main.tests.functional.conftest import _request
|
||||
from awx.main.tests.functional.conftest import credentialtype_scm, credentialtype_ssh # noqa: F401; pylint: disable=unused-import
|
||||
from awx.main.tests.functional.conftest import credentialtype_scm, credentialtype_ssh # noqa: F401 # pylint: disable=unused-import
|
||||
from awx.main.models import (
|
||||
Organization,
|
||||
Project,
|
||||
|
||||
@@ -7,7 +7,7 @@ import pytest
|
||||
from awx.main.models.execution_environments import ExecutionEnvironment
|
||||
from awx.main.models.jobs import JobTemplate
|
||||
|
||||
from awx.main.tests.functional.conftest import user, system_auditor # noqa: F401; pylint: disable=unused-import
|
||||
from awx.main.tests.functional.conftest import user, system_auditor # noqa: F401 # pylint: disable=unused-import
|
||||
|
||||
|
||||
ASSETS = set([
|
||||
|
||||
@@ -26,10 +26,8 @@ def run(stdout=sys.stdout, stderr=sys.stderr, argv=[]):
|
||||
sys.exit(1)
|
||||
except ConnectionError as e:
|
||||
cli.parser.print_help()
|
||||
msg = (
|
||||
'\nThere was a network error of some kind trying to reach '
|
||||
'{}.\nYou might need to specify (or double-check) '
|
||||
'--conf.host'.format(cli.get_config('host'))
|
||||
msg = '\nThere was a network error of some kind trying to reach {}.\nYou might need to specify (or double-check) --conf.host'.format(
|
||||
cli.get_config('host')
|
||||
)
|
||||
if isinstance(e, SSLError):
|
||||
msg = (
|
||||
@@ -60,7 +58,7 @@ def run(stdout=sys.stdout, stderr=sys.stderr, argv=[]):
|
||||
sys.stdout.write(e.__class__.__name__)
|
||||
print('')
|
||||
sys.exit(1)
|
||||
except Exception as e:
|
||||
except Exception as e: # noqa: F841
|
||||
if cli.verbose:
|
||||
e = traceback.format_exc()
|
||||
cprint(e, 'red', file=stderr)
|
||||
|
||||
+2
-7
@@ -26,11 +26,9 @@ commands =
|
||||
[testenv:lint]
|
||||
deps =
|
||||
{[testenv]deps}
|
||||
flake8
|
||||
ruff
|
||||
commands =
|
||||
flake8 awxkit
|
||||
# pylama --report report.pylama awxkit
|
||||
# py.test awxkit --pylama --junitxml=report.pylama {posargs}
|
||||
ruff check awxkit
|
||||
- coverage erase
|
||||
|
||||
[testenv:coveralls]
|
||||
@@ -39,9 +37,6 @@ commands=
|
||||
- coverage report -m
|
||||
- coveralls
|
||||
|
||||
[flake8]
|
||||
max-line-length = 120
|
||||
|
||||
[pytest]
|
||||
addopts = -v --tb=native
|
||||
testpaths = test
|
||||
|
||||
+4
-4
@@ -1,11 +1,11 @@
|
||||
#!/usr/bin/env bash
|
||||
if [ -z $AWX_IGNORE_BLACK ] ; then
|
||||
if [ -z "$AWX_IGNORE_BLACK" ] && [ -z "$AWX_IGNORE_RUFF" ] ; then
|
||||
python_files_changed=$(git diff --cached --name-only --diff-filter=AM awx/ awxkit/ tools/ | grep -E '\.py$')
|
||||
if [ "x$python_files_changed" != "x" ] ; then
|
||||
black --check $python_files_changed || \
|
||||
ruff format --check $python_files_changed || \
|
||||
if [ $? != 0 ] ; then
|
||||
echo 'To fix this, run `make black` to auto-format your code prior to commit, or set AWX_IGNORE_BLACK=1'
|
||||
exit 1
|
||||
echo 'To fix this, run `make format` to auto-format your code prior to commit, or set AWX_IGNORE_RUFF=1'
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
+13
-4
@@ -6,8 +6,17 @@ build-backend = "setuptools.build_meta"
|
||||
# causes the "version" key in setup.cfg to be ignored.
|
||||
# [tool.setuptools_scm]
|
||||
|
||||
[tool.black]
|
||||
[tool.ruff]
|
||||
line-length = 160
|
||||
fast = true
|
||||
skip-string-normalization = true
|
||||
extend-exclude = "awx_collection"
|
||||
extend-exclude = ["awx_collection"]
|
||||
|
||||
[tool.ruff.format]
|
||||
quote-style = "preserve"
|
||||
|
||||
[tool.ruff.lint]
|
||||
select = [
|
||||
"E722",
|
||||
"F401", "F402", "F405", "F523", "F541",
|
||||
"F811", "F821", "F822", "F841",
|
||||
"W291", "W605",
|
||||
]
|
||||
|
||||
@@ -6,7 +6,7 @@ openapi-spec-validator # OpenAPI 3.0 schema validation
|
||||
# pprofile - re-add once https://github.com/vpelletier/pprofile/issues/41 is addressed
|
||||
ipython>=7.31.1 # https://github.com/ansible/awx/security/dependabot/30
|
||||
unittest2
|
||||
black
|
||||
ruff
|
||||
pytest!=7.0.0
|
||||
pytest-asyncio
|
||||
pytest-cov
|
||||
@@ -21,7 +21,6 @@ jupyter
|
||||
backports.tempfile # support in unit tests for py32+ tempfile.TemporaryDirectory
|
||||
gprof2dot
|
||||
atomicwrites
|
||||
flake8
|
||||
yamllint
|
||||
pip>=25.3 # PEP 660 – Editable installs for pyproject.toml based builds (wheel based)
|
||||
awx-tui
|
||||
|
||||
@@ -184,7 +184,7 @@ RUN dnf module -y enable nodejs:18 && dnf module -y install nodejs:18/common &&
|
||||
unzip
|
||||
|
||||
RUN pip3.12 install -vv git+https://github.com/coderanger/supervisor-stdout.git@973ba19967cdaf46d9c1634d1675fc65b9574f6e
|
||||
RUN pip3.12 install -vv black setuptools-scm build
|
||||
RUN pip3.12 install -vv ruff setuptools-scm build
|
||||
|
||||
# This package randomly fails to download.
|
||||
# It is nice to have in the dev env, but not necessary.
|
||||
|
||||
@@ -3,22 +3,17 @@ isolated_build = True
|
||||
|
||||
[testenv:linters]
|
||||
deps =
|
||||
black
|
||||
flake8
|
||||
ruff
|
||||
yamllint
|
||||
allowlist_externals = make
|
||||
setenv =
|
||||
BLACK_ARGS = --check
|
||||
PYTHON = python3
|
||||
commands =
|
||||
make black
|
||||
flake8 awx awxkit awx_collection
|
||||
# awx_collection is excluded: ansible-test sanity runs its own linters which conflict with ruff
|
||||
ruff format --check awx awxkit
|
||||
ruff check awx awxkit
|
||||
yamllint -s .
|
||||
|
||||
[flake8]
|
||||
select = F401,F402,F821,F823,F841,F811,E265,E266,F541,W605,E722,F822,F523,W291,F405
|
||||
exclude = env,awx_collection_build,.tox
|
||||
|
||||
[testenv:pip-compile-docs]
|
||||
description = Compile docs build lockfiles
|
||||
deps =
|
||||
|
||||
Reference in New Issue
Block a user