From 68d3918114cb2fd2889c37005ad432a79df8844a Mon Sep 17 00:00:00 2001 From: Andrew Hosgood Date: Tue, 5 May 2026 16:48:28 +0100 Subject: [PATCH 01/13] Replace isort and flake8 with ruff for code formatting and linting; remove old configuration files --- docker/tna-python-dev/Dockerfile | 6 ++--- docker/tna-python-dev/bin/dev/format | 39 +++++++--------------------- docker/tna-python-dev/lib/.flake8 | 5 ---- docker/tna-python-dev/lib/.isort.cfg | 3 --- docker/tna-python-dev/lib/ruff.toml | 10 +++++++ 5 files changed, 22 insertions(+), 41 deletions(-) delete mode 100644 docker/tna-python-dev/lib/.flake8 delete mode 100644 docker/tna-python-dev/lib/.isort.cfg create mode 100644 docker/tna-python-dev/lib/ruff.toml diff --git a/docker/tna-python-dev/Dockerfile b/docker/tna-python-dev/Dockerfile index 0cb98bc..8b68fa3 100644 --- a/docker/tna-python-dev/Dockerfile +++ b/docker/tna-python-dev/Dockerfile @@ -45,9 +45,7 @@ RUN apt-get update; \ # Set the versions for various tools that we # want to install to help with development # ========================================== -ENV BLACK_VERSION=26.3.1 \ - FLAKE8_VERSION=7.1.1 \ - ISORT_VERSION=8.0.1 \ +ENV RUFF_VERSION=0.15.12 \ DJLINT_VERSION=1.36.4 \ DJHTML_VERSION=3.0.11 \ DJANGO_DEBUG_TOOLBAR_VERSION=6.3.0 \ @@ -85,7 +83,7 @@ ENV PATH="/home/app/.local/bin/tasks:/home/app/.local/bin/dev:$PATH" # ========================================== # hadolint ignore=SC1091 RUN install-format-dependencies; \ - python -m pip install --no-cache-dir --quiet black=="$BLACK_VERSION" flake8=="$FLAKE8_VERSION" isort=="$ISORT_VERSION" djlint=="$DJLINT_VERSION" djhtml=="$DJHTML_VERSION" + python -m pip install --no-cache-dir --quiet ruff=="$RUFF_VERSION" djlint=="$DJLINT_VERSION" djhtml=="$DJHTML_VERSION" # ========================================== # Copy any configuration files into the main diff --git a/docker/tna-python-dev/bin/dev/format b/docker/tna-python-dev/bin/dev/format index 8b037d8..9806b64 100755 --- a/docker/tna-python-dev/bin/dev/format +++ b/docker/tna-python-dev/bin/dev/format @@ -14,44 +14,25 @@ else fi echo -echo "Running isort..." -if [ -f "/app/.isort.cfg" ] +echo "Running ruff..." +if [ -f "/app/ruff.toml" ] then - ISORT_CONFIG="/app/.isort.cfg" - echo "Using app config ($ISORT_CONFIG)" + RUFF_CONFIG="/app/ruff.toml" + echo "Using app config ($RUFF_CONFIG)" else - ISORT_CONFIG="/home/app/.isort.cfg" - echo "Using default config ($ISORT_CONFIG)" + RUFF_CONFIG="/home/app/ruff.toml" + echo "Using default config ($RUFF_CONFIG)" fi if [ "$FIX" = true ] then - isort --settings-file "$ISORT_CONFIG" /app --overwrite-in-place + ruff check /app --fix --config "$RUFF_CONFIG" + ruff format /app --fix --config "$RUFF_CONFIG" else - isort --settings-file "$ISORT_CONFIG" /app --diff + ruff check /app --config "$RUFF_CONFIG" + ruff format /app --config "$RUFF_CONFIG" fi echo -echo "Running black..." -if [ "$FIX" = true ] -then - black -t py310 -t py311 -t py312 -t py313 -t py314 /app -else - black -t py310 -t py311 -t py312 -t py313 -t py314 --check /app -fi -echo - -echo "Running flake8..." -if [ -f "/app/.flake8" ] -then - FLAKE8_CONFIG="/app/.flake8" - echo "Using app config ($FLAKE8_CONFIG)" -else - FLAKE8_CONFIG="/home/app/.flake8" - echo "Using default config ($FLAKE8_CONFIG)" -fi -flake8 --config="$FLAKE8_CONFIG" /app -echo - if [ -d "/app/app/templates" ] then echo "Running djLint..." diff --git a/docker/tna-python-dev/lib/.flake8 b/docker/tna-python-dev/lib/.flake8 deleted file mode 100644 index a24cadd..0000000 --- a/docker/tna-python-dev/lib/.flake8 +++ /dev/null @@ -1,5 +0,0 @@ -[flake8] -ignore = E203, W503, E501 -exclude = venv*,__pycache__,node_modules,migrations,.git -max-line-length = 88 -max-complexity = 12 diff --git a/docker/tna-python-dev/lib/.isort.cfg b/docker/tna-python-dev/lib/.isort.cfg deleted file mode 100644 index 1c9f724..0000000 --- a/docker/tna-python-dev/lib/.isort.cfg +++ /dev/null @@ -1,3 +0,0 @@ -[settings] -profile = black -skip = migrations,node_modules \ No newline at end of file diff --git a/docker/tna-python-dev/lib/ruff.toml b/docker/tna-python-dev/lib/ruff.toml new file mode 100644 index 0000000..242b356 --- /dev/null +++ b/docker/tna-python-dev/lib/ruff.toml @@ -0,0 +1,10 @@ +line-length = 88 + +[format] +exclude = ["migrations"] + +[lint] +ignore = ["E203", "W503", "E501"] + +[lint.mccabe] +max-complexity = 12 \ No newline at end of file From 9047ace49b4d3bcff0f8863389ae43a0d6197648 Mon Sep 17 00:00:00 2001 From: Andrew Hosgood Date: Tue, 5 May 2026 17:03:05 +0100 Subject: [PATCH 02/13] Add ty for type checking and update installation script --- docker/tna-python-dev/Dockerfile | 3 ++- docker/tna-python-dev/bin/dev/format | 12 ++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/docker/tna-python-dev/Dockerfile b/docker/tna-python-dev/Dockerfile index 8b68fa3..4242c21 100644 --- a/docker/tna-python-dev/Dockerfile +++ b/docker/tna-python-dev/Dockerfile @@ -46,6 +46,7 @@ RUN apt-get update; \ # want to install to help with development # ========================================== ENV RUFF_VERSION=0.15.12 \ + TY_VERSION=0.0.34 \ DJLINT_VERSION=1.36.4 \ DJHTML_VERSION=3.0.11 \ DJANGO_DEBUG_TOOLBAR_VERSION=6.3.0 \ @@ -83,7 +84,7 @@ ENV PATH="/home/app/.local/bin/tasks:/home/app/.local/bin/dev:$PATH" # ========================================== # hadolint ignore=SC1091 RUN install-format-dependencies; \ - python -m pip install --no-cache-dir --quiet ruff=="$RUFF_VERSION" djlint=="$DJLINT_VERSION" djhtml=="$DJHTML_VERSION" + python -m pip install --no-cache-dir --quiet ruff=="$RUFF_VERSION" ty=="$TY_VERSION" djlint=="$DJLINT_VERSION" djhtml=="$DJHTML_VERSION" # ========================================== # Copy any configuration files into the main diff --git a/docker/tna-python-dev/bin/dev/format b/docker/tna-python-dev/bin/dev/format index 9806b64..5a4682a 100755 --- a/docker/tna-python-dev/bin/dev/format +++ b/docker/tna-python-dev/bin/dev/format @@ -33,6 +33,18 @@ else fi echo +echo "Running ty..." +if [ -f "/app/ty.toml" ] +then + TY_CONFIG="/app/ty.toml" + echo "Using app config ($TY_CONFIG)" +else + TY_CONFIG="/home/app/ty.toml" + echo "Using default config ($TY_CONFIG)" +fi +ty check /app --config "$TY_CONFIG" +echo + if [ -d "/app/app/templates" ] then echo "Running djLint..." From d929618b3320ba4e24dd32555b87730e2110b0a7 Mon Sep 17 00:00:00 2001 From: Andrew Hosgood Date: Wed, 6 May 2026 13:59:11 +0100 Subject: [PATCH 03/13] Remove ty dependency and related checks; update default ruff configuration --- docker/tna-python-dev/Dockerfile | 3 +-- docker/tna-python-dev/bin/dev/format | 12 ------------ docker/tna-python-dev/lib/ruff.toml | 23 ++++++++++++++++++----- 3 files changed, 19 insertions(+), 19 deletions(-) diff --git a/docker/tna-python-dev/Dockerfile b/docker/tna-python-dev/Dockerfile index 4242c21..8b68fa3 100644 --- a/docker/tna-python-dev/Dockerfile +++ b/docker/tna-python-dev/Dockerfile @@ -46,7 +46,6 @@ RUN apt-get update; \ # want to install to help with development # ========================================== ENV RUFF_VERSION=0.15.12 \ - TY_VERSION=0.0.34 \ DJLINT_VERSION=1.36.4 \ DJHTML_VERSION=3.0.11 \ DJANGO_DEBUG_TOOLBAR_VERSION=6.3.0 \ @@ -84,7 +83,7 @@ ENV PATH="/home/app/.local/bin/tasks:/home/app/.local/bin/dev:$PATH" # ========================================== # hadolint ignore=SC1091 RUN install-format-dependencies; \ - python -m pip install --no-cache-dir --quiet ruff=="$RUFF_VERSION" ty=="$TY_VERSION" djlint=="$DJLINT_VERSION" djhtml=="$DJHTML_VERSION" + python -m pip install --no-cache-dir --quiet ruff=="$RUFF_VERSION" djlint=="$DJLINT_VERSION" djhtml=="$DJHTML_VERSION" # ========================================== # Copy any configuration files into the main diff --git a/docker/tna-python-dev/bin/dev/format b/docker/tna-python-dev/bin/dev/format index 5a4682a..9806b64 100755 --- a/docker/tna-python-dev/bin/dev/format +++ b/docker/tna-python-dev/bin/dev/format @@ -33,18 +33,6 @@ else fi echo -echo "Running ty..." -if [ -f "/app/ty.toml" ] -then - TY_CONFIG="/app/ty.toml" - echo "Using app config ($TY_CONFIG)" -else - TY_CONFIG="/home/app/ty.toml" - echo "Using default config ($TY_CONFIG)" -fi -ty check /app --config "$TY_CONFIG" -echo - if [ -d "/app/app/templates" ] then echo "Running djLint..." diff --git a/docker/tna-python-dev/lib/ruff.toml b/docker/tna-python-dev/lib/ruff.toml index 242b356..00ff090 100644 --- a/docker/tna-python-dev/lib/ruff.toml +++ b/docker/tna-python-dev/lib/ruff.toml @@ -1,10 +1,23 @@ -line-length = 88 - -[format] -exclude = ["migrations"] +exclude = [ + "migrations" +] [lint] -ignore = ["E203", "W503", "E501"] +select = [ + "E4", + "E7", + "E9", + "F", + "B", + "W", + "Q", + "C901" +] + +[lint.per-file-ignores] +"__init__.py" = [ + "F401" +] [lint.mccabe] max-complexity = 12 \ No newline at end of file From 75dea893bbf5edfcc837ca89425eb1b4044c20a6 Mon Sep 17 00:00:00 2001 From: Andrew Hosgood Date: Wed, 6 May 2026 14:00:14 +0100 Subject: [PATCH 04/13] Remove complexity check from ruff configuration --- docker/tna-python-dev/lib/ruff.toml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docker/tna-python-dev/lib/ruff.toml b/docker/tna-python-dev/lib/ruff.toml index 00ff090..abc88bc 100644 --- a/docker/tna-python-dev/lib/ruff.toml +++ b/docker/tna-python-dev/lib/ruff.toml @@ -10,8 +10,7 @@ select = [ "F", "B", "W", - "Q", - "C901" + "Q" ] [lint.per-file-ignores] From 5e1161e9b11815e050d61d1f54cab56fb188a763 Mon Sep 17 00:00:00 2001 From: Andrew Hosgood Date: Wed, 6 May 2026 14:28:19 +0100 Subject: [PATCH 05/13] Update ruff format command to use --check option in non-fix mode --- docker/tna-python-dev/bin/dev/format | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docker/tna-python-dev/bin/dev/format b/docker/tna-python-dev/bin/dev/format index 9806b64..8bd5283 100755 --- a/docker/tna-python-dev/bin/dev/format +++ b/docker/tna-python-dev/bin/dev/format @@ -26,10 +26,10 @@ fi if [ "$FIX" = true ] then ruff check /app --fix --config "$RUFF_CONFIG" - ruff format /app --fix --config "$RUFF_CONFIG" + ruff format /app --config "$RUFF_CONFIG" else ruff check /app --config "$RUFF_CONFIG" - ruff format /app --config "$RUFF_CONFIG" + ruff format --check /app --config "$RUFF_CONFIG" fi echo From 9312d2a0f188bf36a3cd255439dac0f35e628482 Mon Sep 17 00:00:00 2001 From: Andrew Hosgood Date: Wed, 6 May 2026 14:32:40 +0100 Subject: [PATCH 06/13] Add C901 to ruff linting rules for complexity checks --- docker/tna-python-dev/lib/ruff.toml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docker/tna-python-dev/lib/ruff.toml b/docker/tna-python-dev/lib/ruff.toml index abc88bc..00ff090 100644 --- a/docker/tna-python-dev/lib/ruff.toml +++ b/docker/tna-python-dev/lib/ruff.toml @@ -10,7 +10,8 @@ select = [ "F", "B", "W", - "Q" + "Q", + "C901" ] [lint.per-file-ignores] From c0bb685a04990117a3e7215ae0f3404219bda688 Mon Sep 17 00:00:00 2001 From: Andrew Hosgood Date: Wed, 6 May 2026 14:50:27 +0100 Subject: [PATCH 07/13] Add 'I' to ruff linting rules for improved checks --- docker/tna-python-dev/lib/ruff.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/docker/tna-python-dev/lib/ruff.toml b/docker/tna-python-dev/lib/ruff.toml index 00ff090..aad1278 100644 --- a/docker/tna-python-dev/lib/ruff.toml +++ b/docker/tna-python-dev/lib/ruff.toml @@ -11,6 +11,7 @@ select = [ "B", "W", "Q", + "I", "C901" ] From 6e7ccf7507c45522ec820c77548119e3a7186c8f Mon Sep 17 00:00:00 2001 From: Andrew Hosgood Date: Tue, 12 May 2026 17:15:53 +0100 Subject: [PATCH 08/13] Update ruff linting rules to include additional checks and allowed confusables --- docker/tna-python-dev/lib/ruff.toml | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/docker/tna-python-dev/lib/ruff.toml b/docker/tna-python-dev/lib/ruff.toml index aad1278..99a452f 100644 --- a/docker/tna-python-dev/lib/ruff.toml +++ b/docker/tna-python-dev/lib/ruff.toml @@ -12,12 +12,33 @@ select = [ "W", "Q", "I", - "C901" + "C90", + "FAST", + "DJ", + "FIX", + "A", + "LOG", + "T20", + "RET", + "SIM", + "TD", + "N", + "PL", + "UP", + "RUF" + # "TRY" +] +allowed-confusables = [ + "—", + "–", + "’" ] [lint.per-file-ignores] "__init__.py" = [ - "F401" + "E402", + "F401", + "PLC0415" ] [lint.mccabe] From 47dbe3980acdc8c6596e208aac506461d6c4ea1a Mon Sep 17 00:00:00 2001 From: Andrew Hosgood Date: Wed, 13 May 2026 10:36:30 +0100 Subject: [PATCH 09/13] Refactor ruff configuration and scripts to support strict mode checks --- docker/tna-python-dev/bin/dev/checkformat | 10 ++++++++- docker/tna-python-dev/bin/dev/format | 20 +++++++++++++++-- docker/tna-python-dev/lib/ruff-strict.toml | 22 ++++++++++++++++++ docker/tna-python-dev/lib/ruff.toml | 26 ++++------------------ 4 files changed, 53 insertions(+), 25 deletions(-) create mode 100644 docker/tna-python-dev/lib/ruff-strict.toml diff --git a/docker/tna-python-dev/bin/dev/checkformat b/docker/tna-python-dev/bin/dev/checkformat index 2440cd8..df60d98 100755 --- a/docker/tna-python-dev/bin/dev/checkformat +++ b/docker/tna-python-dev/bin/dev/checkformat @@ -1,3 +1,11 @@ #!/bin/bash -FIX=false format +STRICT=false + +while getopts "s:" flag; do + case $flag in + s) STRICT=true ;; + esac +done + +STRICT=$STRICT FIX=false format diff --git a/docker/tna-python-dev/bin/dev/format b/docker/tna-python-dev/bin/dev/format index 8bd5283..69587f6 100755 --- a/docker/tna-python-dev/bin/dev/format +++ b/docker/tna-python-dev/bin/dev/format @@ -2,9 +2,16 @@ set -e -cd /app || return - [[ -z $FIX ]] && FIX=true +[[ -z $STRICT ]] && STRICT=false + +while getopts "s:" flag; do + case $flag in + s) STRICT=true ;; + esac +done + +cd /app || return if [ "$FIX" = true ] then @@ -18,6 +25,15 @@ echo "Running ruff..." if [ -f "/app/ruff.toml" ] then RUFF_CONFIG="/app/ruff.toml" + if [ "$STRICT" = true ] + then + echo "Using app config ($RUFF_CONFIG - ignoring strict mode)" + else + echo "Using app config ($RUFF_CONFIG)" + fi +elif [ "$STRICT" = true ] +then + RUFF_CONFIG="/app/ruff-strict.toml" echo "Using app config ($RUFF_CONFIG)" else RUFF_CONFIG="/home/app/ruff.toml" diff --git a/docker/tna-python-dev/lib/ruff-strict.toml b/docker/tna-python-dev/lib/ruff-strict.toml new file mode 100644 index 0000000..874a8ef --- /dev/null +++ b/docker/tna-python-dev/lib/ruff-strict.toml @@ -0,0 +1,22 @@ +extend = "./ruff.toml" + +[lint] +extend-select = [ + "FAST", + "DJ", + "FIX", + "A", + "LOG", + "T20", + "RET", + "SIM", + "TD", + "N", + "PL", + "UP", + "RUF", + "TRY" +] + +[lint.mccabe] +max-complexity = 12 \ No newline at end of file diff --git a/docker/tna-python-dev/lib/ruff.toml b/docker/tna-python-dev/lib/ruff.toml index 99a452f..d4757c0 100644 --- a/docker/tna-python-dev/lib/ruff.toml +++ b/docker/tna-python-dev/lib/ruff.toml @@ -1,32 +1,14 @@ -exclude = [ +extend-exclude = [ "migrations" ] [lint] -select = [ - "E4", - "E7", - "E9", - "F", +extend-select = [ "B", "W", "Q", "I", - "C90", - "FAST", - "DJ", - "FIX", - "A", - "LOG", - "T20", - "RET", - "SIM", - "TD", - "N", - "PL", - "UP", - "RUF" - # "TRY" + "C90" ] allowed-confusables = [ "—", @@ -42,4 +24,4 @@ allowed-confusables = [ ] [lint.mccabe] -max-complexity = 12 \ No newline at end of file +max-complexity = 20 \ No newline at end of file From 539b715d40ddbf8ab92128bfc4adb16965d5950d Mon Sep 17 00:00:00 2001 From: Andrew Hosgood Date: Wed, 13 May 2026 11:08:04 +0100 Subject: [PATCH 10/13] Refactor checkformat and format scripts to simplify strict mode handling --- docker/tna-python-dev/bin/dev/checkformat | 9 ++++----- docker/tna-python-dev/bin/dev/format | 10 +++++----- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/docker/tna-python-dev/bin/dev/checkformat b/docker/tna-python-dev/bin/dev/checkformat index df60d98..c564a2f 100755 --- a/docker/tna-python-dev/bin/dev/checkformat +++ b/docker/tna-python-dev/bin/dev/checkformat @@ -1,11 +1,10 @@ #!/bin/bash +PARAM=$1; shift STRICT=false -while getopts "s:" flag; do - case $flag in - s) STRICT=true ;; - esac -done +if [[ "$PARAM" == "--strict" ]]; then + STRICT=true +fi STRICT=$STRICT FIX=false format diff --git a/docker/tna-python-dev/bin/dev/format b/docker/tna-python-dev/bin/dev/format index 69587f6..dd5afed 100755 --- a/docker/tna-python-dev/bin/dev/format +++ b/docker/tna-python-dev/bin/dev/format @@ -5,11 +5,11 @@ set -e [[ -z $FIX ]] && FIX=true [[ -z $STRICT ]] && STRICT=false -while getopts "s:" flag; do - case $flag in - s) STRICT=true ;; - esac -done +PARAM=$1; shift + +if [[ "$PARAM" == "--strict" ]]; then + STRICT=true +fi cd /app || return From 09e565d641295d923ca402a4383e0f15685c8705 Mon Sep 17 00:00:00 2001 From: Andrew Hosgood Date: Wed, 13 May 2026 11:58:48 +0100 Subject: [PATCH 11/13] Refactor checkformat and format scripts for consistent strict mode handling --- docker/tna-python-dev/bin/dev/checkformat | 2 +- docker/tna-python-dev/bin/dev/format | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docker/tna-python-dev/bin/dev/checkformat b/docker/tna-python-dev/bin/dev/checkformat index c564a2f..fb2e177 100755 --- a/docker/tna-python-dev/bin/dev/checkformat +++ b/docker/tna-python-dev/bin/dev/checkformat @@ -4,7 +4,7 @@ PARAM=$1; shift STRICT=false if [[ "$PARAM" == "--strict" ]]; then - STRICT=true + STRICT=true fi STRICT=$STRICT FIX=false format diff --git a/docker/tna-python-dev/bin/dev/format b/docker/tna-python-dev/bin/dev/format index dd5afed..29c8c4d 100755 --- a/docker/tna-python-dev/bin/dev/format +++ b/docker/tna-python-dev/bin/dev/format @@ -8,7 +8,7 @@ set -e PARAM=$1; shift if [[ "$PARAM" == "--strict" ]]; then - STRICT=true + STRICT=true fi cd /app || return @@ -33,8 +33,8 @@ then fi elif [ "$STRICT" = true ] then - RUFF_CONFIG="/app/ruff-strict.toml" - echo "Using app config ($RUFF_CONFIG)" + RUFF_CONFIG="/home/app/ruff-strict.toml" + echo "Using default strict config ($RUFF_CONFIG)" else RUFF_CONFIG="/home/app/ruff.toml" echo "Using default config ($RUFF_CONFIG)" From ab7754ade22da36306a46bbd87536b962999e498 Mon Sep 17 00:00:00 2001 From: Andrew Hosgood Date: Wed, 13 May 2026 15:30:14 +0100 Subject: [PATCH 12/13] Refactor checkformat and format scripts to streamline strict mode handling --- docker/tna-python-dev/bin/dev/checkformat | 3 +-- docker/tna-python-dev/bin/dev/format | 16 +++++++--------- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/docker/tna-python-dev/bin/dev/checkformat b/docker/tna-python-dev/bin/dev/checkformat index fb2e177..3b630c8 100755 --- a/docker/tna-python-dev/bin/dev/checkformat +++ b/docker/tna-python-dev/bin/dev/checkformat @@ -1,9 +1,8 @@ #!/bin/bash -PARAM=$1; shift STRICT=false -if [[ "$PARAM" == "--strict" ]]; then +if [[ "$1" == "--strict" ]]; then STRICT=true fi diff --git a/docker/tna-python-dev/bin/dev/format b/docker/tna-python-dev/bin/dev/format index 29c8c4d..e994682 100755 --- a/docker/tna-python-dev/bin/dev/format +++ b/docker/tna-python-dev/bin/dev/format @@ -3,15 +3,6 @@ set -e [[ -z $FIX ]] && FIX=true -[[ -z $STRICT ]] && STRICT=false - -PARAM=$1; shift - -if [[ "$PARAM" == "--strict" ]]; then - STRICT=true -fi - -cd /app || return if [ "$FIX" = true ] then @@ -21,6 +12,13 @@ else fi echo +[[ -z $STRICT ]] && STRICT=false +if [[ "$1" == "--strict" ]]; then + STRICT=true +fi + +cd /app || return + echo "Running ruff..." if [ -f "/app/ruff.toml" ] then From f9d6dd685411742df0c0c6c07744ab46642ff022 Mon Sep 17 00:00:00 2001 From: Andrew Hosgood Date: Thu, 14 May 2026 13:49:13 +0100 Subject: [PATCH 13/13] Update README to reflect changes in Python formatting tools and Ruff configuration --- .github/actions/test-build/action.yml | 2 +- CHANGELOG.md | 3 + docker/tna-python-dev/README.md | 92 ++++++++++++++++++---- docker/tna-python-dev/lib/ruff-strict.toml | 18 +++-- docker/tna-python-dev/lib/ruff.toml | 10 +-- 5 files changed, 94 insertions(+), 31 deletions(-) diff --git a/.github/actions/test-build/action.yml b/.github/actions/test-build/action.yml index 2db1d79..1a07522 100644 --- a/.github/actions/test-build/action.yml +++ b/.github/actions/test-build/action.yml @@ -18,7 +18,7 @@ runs: steps: - name: Create version tag id: version-tag - uses: nationalarchives/ds-docker-actions/.github/actions/get-version-tag@main # TODO: Could replace the "Prepare image tag" step below? + uses: nationalarchives/ds-docker-actions/.github/actions/get-version-tag@main # TODO: Could replace the "Prepare image tag" step below? - name: Test new image tag run: | diff --git a/CHANGELOG.md b/CHANGELOG.md index 9b97fd8..e68a6a4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased](https://github.com/nationalarchives/docker/compare/v1.11.1...HEAD) ### Added + +- Added Ruff as a replacement for isort, Flake8 and Black + ### Changed - Update default isort config to ignore `node_modules` diff --git a/docker/tna-python-dev/README.md b/docker/tna-python-dev/README.md index 3832424..73bdc0c 100644 --- a/docker/tna-python-dev/README.md +++ b/docker/tna-python-dev/README.md @@ -4,9 +4,9 @@ This image extends `tna-python` and can be used for local development **ONLY**. It adds: -- `black`, `flake8` and `isort` for formatting Python code +- `ruff` for formatting and linting Python - `prettier`, `eslint` and `stylelint` for formatting JavaScript and CSS -- scripts for formatting code +- scripts for formatting - `django-debug-toolbar` for debugging Django applications - `git` @@ -92,30 +92,92 @@ The process for these commands is: ### `format` -1. Run `isort` -1. Run `black` -1. Run `flake8` +1. Run `ruff` 1. Run `djlint` to check HTML templates for Jinja compliance 1. Apply `prettier` to all files in the `/app` directory 1. Run `stylelint` against all SCSS files in the `/app` directory 1. Run `eslint` against all JavaScript files in the `/app` directory -#### How to override the default configurations +#### Ruff + +By default, Ruff is only configured to check the following when running `format` and `checkformat`: + +| Code | Purpose | Defined by | +| ---------------- | ------------------------------------------------------------------------------- | ------------------------------------------------------------------------ | +| `E4`, `E7`, `E9` | [Subset of pycodestyle errors](https://pypi.org/project/pycodestyle/) | [Ruff default configuration](https://docs.astral.sh/ruff/configuration/) | +| `F` | [Pyflakes](https://pypi.org/project/pyflakes/) | [Ruff default configuration](https://docs.astral.sh/ruff/configuration/) | +| `W` | [pycodestyle warnings](https://pypi.org/project/pycodestyle/) | [`/home/app/ruff.toml`](./lib/ruff.toml) | +| `C901` | [mccabe "Function is too complex"](https://www.flake8rules.com/rules/C901.html) | [`/home/app/ruff.toml`](./lib/ruff.toml) | +| `B` | [flake8-bugbear](https://pypi.org/project/flake8-bugbear/) | [`/home/app/ruff.toml`](./lib/ruff.toml) | +| `I` | [isort](https://pypi.org/project/isort/) | [`/home/app/ruff.toml`](./lib/ruff.toml) | +| `Q` | [flake8-quotes](https://pypi.org/project/flake8-quotes/) | [`/home/app/ruff.toml`](./lib/ruff.toml) | + +Running `format --strict` or `checkformat --strict` will apply some extra rules defined in [`/home/app/ruff-strict.toml`](./lib/ruff-strict.toml): + +| Code | Purpose | +| ------ | --------------------------------------------------------------------- | +| `A` | [flake8-builtins](https://pypi.org/project/flake8-builtins/) | +| `DJ` | [flake8-django](https://pypi.org/project/flake8-django/) | +| `ERA` | [eradicate](https://pypi.org/project/eradicate/) | +| `FAST` | [fastapi](https://pypi.org/project/fastapi/) | +| `FIX` | [flake8-fixme](https://github.com/tommilligan/flake8-fixme) | +| `LOG` | [flake8-logging](https://pypi.org/project/flake8-logging/) | +| `N` | [pep8-naming](https://pypi.org/project/pep8-naming/) | +| `PL` | [pylint](https://pypi.org/project/pylint/) | +| `RET` | [flake8-return](https://pypi.org/project/flake8-return/) | +| `RSE` | [flake8-raise](https://pypi.org/project/flake8-raise/) | +| `RUF` | [Ruff-specific rules](https://docs.astral.sh/ruff/settings/#lintruff) | +| `SIM` | [flake8-simplify](https://pypi.org/project/flake8-simplify/) | +| `T20` | [flake8-print](https://pypi.org/project/flake8-print/) | +| `TD` | [flake8-todos](https://github.com/orsinium-labs/flake8-todos/) | +| `TRY` | [tryceratops](https://pypi.org/project/tryceratops/) | +| `UP` | [pyupgrade](https://pypi.org/project/pyupgrade/) | + +##### How to override Ruff configuration + +Create a `ruff.toml` file in your project root. If this file exists, the `--strict` parameter will be ignored on `format --strict` and `checkformat --strict`. + +```toml +# Extend the default Ruff configuration +extend = "/home/app/ruff.toml" + +# ...or extend the strict ruleset +# extend = "/home/app/ruff-strict.toml" + +extend-exclude = [ + # "migrations" # Exclude the "migrations" directory +] + +[lint] +ignore = [ + # Add rules to ignore in your project +] +``` + +##### Ignoring code -| Tool | Overwrite solution | More information | -| ----------- | ------------------------------------------------- | ------------------------------------------------------------------------------------------------------- | -| `isort` | `.isort.cfg` file in the project root | https://pycqa.github.io/isort/docs/configuration/config_files.html#isortcfg-preferred-format | -| `black` | Add `[tool.black]` config to the `pyproject.toml` | https://black.readthedocs.io/en/stable/usage_and_configuration/the_basics.html#configuration-via-a-file | -| `flake8` | `.flake8` file in the project root | https://flake8.pycqa.org/en/latest/user/configuration.html#configuration-locations | -| `djlint` | `.djlintrc` file in the project root | https://djlint.com/docs/configuration/ | -| `prettier` | `.prettierignore` file in the project root | https://prettier.io/docs/en/ignore.html | -| `stylelint` | `.stylelintrc` file in the project root | https://stylelint.io/user-guide/configure/ | -| `eslint` | `.eslintrc.js` file in the project root | https://eslint.org/docs/latest/use/configure/configuration-files#using-configuration-files | +Use the `# noqa` annotation from [In-line Ignoring Errorsin Flake8](https://flake8.pycqa.org/en/latest/user/violations.html#in-line-ignoring-errors) to ignore failing lines. + +```python +def my_overly_complex_function(): # noqa: C901 + pass +``` + +#### How to override other default configurations + +| Tool | Overwrite solution | More information | +| ----------- | ------------------------------------------ | ------------------------------------------------------------------------------------------ | +| `djlint` | `.djlintrc` file in the project root | https://djlint.com/docs/configuration/ | +| `prettier` | `.prettierignore` file in the project root | https://prettier.io/docs/en/ignore.html | +| `stylelint` | `.stylelintrc` file in the project root | https://stylelint.io/user-guide/configure/ | +| `eslint` | `.eslintrc.js` file in the project root | https://eslint.org/docs/latest/use/configure/configuration-files#using-configuration-files | ### `checkformat` Runs the same tests as `format` but doesn't fix issues. Can be used in CI/CD pipelines to check formatting. +Like `format --strict`, `checkformat --strict` uses an [expanded set of Ruff rules](#ruff). + ### `outdated` 1. Shows outdated Poetry dependencies diff --git a/docker/tna-python-dev/lib/ruff-strict.toml b/docker/tna-python-dev/lib/ruff-strict.toml index 874a8ef..7d6cdc4 100644 --- a/docker/tna-python-dev/lib/ruff-strict.toml +++ b/docker/tna-python-dev/lib/ruff-strict.toml @@ -2,20 +2,22 @@ extend = "./ruff.toml" [lint] extend-select = [ - "FAST", + "A", "DJ", + "ERA", + "FAST", "FIX", - "A", "LOG", - "T20", - "RET", - "SIM", - "TD", "N", "PL", - "UP", + "RET", + "RSE", "RUF", - "TRY" + "SIM", + "T20", + "TD", + "TRY", + "UP" ] [lint.mccabe] diff --git a/docker/tna-python-dev/lib/ruff.toml b/docker/tna-python-dev/lib/ruff.toml index d4757c0..4e1b9b4 100644 --- a/docker/tna-python-dev/lib/ruff.toml +++ b/docker/tna-python-dev/lib/ruff.toml @@ -1,14 +1,10 @@ -extend-exclude = [ - "migrations" -] - [lint] extend-select = [ - "B", "W", - "Q", + "C901", + "B", "I", - "C90" + "Q" ] allowed-confusables = [ "—",