From 61483c233fdc4de872be5796d2defc50ca158efa Mon Sep 17 00:00:00 2001 From: Mateusz Suski Date: Mon, 11 May 2026 17:02:35 +0000 Subject: [PATCH] Add Python tooling validation foundation --- .github/workflows/lint.yml | 3 ++ AGENTS.md | 10 ++++++ scripts/check-python.sh | 62 ++++++++++++++++++++++++++++++++++++++ scripts/validate-repo.sh | 6 ++++ 4 files changed, 81 insertions(+) create mode 100755 scripts/check-python.sh diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index f2280f5..fc3d799 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -28,6 +28,9 @@ jobs: -P infra-run/scripts/bash/gpfs \ -P infra-run/scripts/bash/veritas + - name: Python syntax checks + run: bash scripts/check-python.sh + - name: yamllint run: yamllint . diff --git a/AGENTS.md b/AGENTS.md index 9e9218e..9a8db87 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -41,6 +41,7 @@ Focused checks: ```bash ./scripts/check-bash.sh ./scripts/check-ansible.sh +./scripts/check-python.sh ./scripts/check-docs.sh ``` @@ -64,6 +65,15 @@ Also run targeted checks for changed files, such as `bash -n`, `ansible-playbook - Exit codes: `0` OK, `1` operational issue, `2` invalid input or missing dependency. - Keep scripts readable; separate discovery, pre-check, change, post-check, and reporting when it helps. +## Python Standards + +- Use Python for parsing, reporting, and structured operational tooling where it adds value over Bash. +- Keep Python tools read-only by default. +- Prefer the Python standard library. +- Avoid frameworks and unnecessary abstractions. +- Use clear operational output and meaningful exit codes. +- Keep tools small, focused, and easy to validate. + ## Ansible Standards - Keep playbooks short and roles simple. diff --git a/scripts/check-python.sh b/scripts/check-python.sh new file mode 100755 index 0000000..e6933d9 --- /dev/null +++ b/scripts/check-python.sh @@ -0,0 +1,62 @@ +#!/usr/bin/env bash +set -o errexit +set -o nounset +set -o pipefail + +ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +PYTHON_DIR="$ROOT_DIR/infra-run/scripts/python" + +ok_count=0 +warn_count=0 +fail_count=0 + +ok() { + printf 'OK: %s\n' "$*" + ok_count=$((ok_count + 1)) +} + +warning() { + printf 'WARNING: %s\n' "$*" + warn_count=$((warn_count + 1)) +} + +critical() { + printf 'CRITICAL: %s\n' "$*" + fail_count=$((fail_count + 1)) +} + +if ! command -v python3 >/dev/null 2>&1; then + critical "python3 not installed" + printf '\nPython summary: %d OK, %d WARNING, %d CRITICAL\n' "$ok_count" "$warn_count" "$fail_count" + exit 2 +fi + +if [[ ! -d "$PYTHON_DIR" ]]; then + warning "No infra-run/scripts/python directory found" + printf '\nPython summary: %d OK, %d WARNING, %d CRITICAL\n' "$ok_count" "$warn_count" "$fail_count" + exit 0 +fi + +mapfile -t python_files < <(find "$PYTHON_DIR" -type f -name '*.py' -print | sort) + +if ((${#python_files[@]} == 0)); then + warning "No Python files found under infra-run/scripts/python" +else + ok "Found ${#python_files[@]} Python files" +fi + +for file in "${python_files[@]}"; do + if python3 -m py_compile "$file"; then + ok "py_compile ${file#"$ROOT_DIR"/}" + else + critical "Python syntax failed: ${file#"$ROOT_DIR"/}" + fi +done + +printf '\nPython summary: %d OK, %d WARNING, %d CRITICAL\n' "$ok_count" "$warn_count" "$fail_count" + +if ((fail_count > 0)); then + exit 1 +fi + +exit 0 diff --git a/scripts/validate-repo.sh b/scripts/validate-repo.sh index 5367d32..b681876 100755 --- a/scripts/validate-repo.sh +++ b/scripts/validate-repo.sh @@ -12,6 +12,11 @@ run_check() { shift printf '\n== %s ==\n' "$name" + if [[ ! -x "$1" ]]; then + printf 'WARNING: %s check is missing or not executable: %s\n' "$name" "$1" + return 0 + fi + if "$@"; then printf 'OK: %s completed\n' "$name" else @@ -22,6 +27,7 @@ run_check() { run_check "Bash" "$ROOT_DIR/scripts/check-bash.sh" run_check "Ansible" "$ROOT_DIR/scripts/check-ansible.sh" +run_check "Python" "$ROOT_DIR/scripts/check-python.sh" run_check "Docs" "$ROOT_DIR/scripts/check-docs.sh" printf '\n== Repository summary ==\n'