Skip to content

Commit 6258dc9

Browse files
wphillipmoorewphillipmoore-claude
andauthored
feat(validate): adopt validate_local.sh dispatch architecture (#341)
* feat(validate): adopt validate_local.sh dispatch architecture Add primary_language: python to repo profile. Replace validate_local.py with synced shell-based driver and language-specific scripts. Extract license allowlist to .pip-licenses-allowlist. Create validate_local_custom.sh for repo-specific checks (validate_venv, validate_dependency_specs, validate_version, mypy/ty on examples/). Co-Authored-By: wphillipmoore-claude <255925739+wphillipmoore-claude@users.noreply.github.com> * chore: sync managed scripts against standard-tooling v1.1.0 Co-Authored-By: wphillipmoore-claude <255925739+wphillipmoore-claude@users.noreply.github.com> --------- Co-authored-by: wphillipmoore-claude <255925739+wphillipmoore-claude@users.noreply.github.com>
1 parent f84709a commit 6258dc9

12 files changed

Lines changed: 456 additions & 135 deletions

.pip-licenses-allowlist

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# Allowed license identifiers for pip-licenses compliance checks.
2+
# One entry per line. Lines starting with # are comments.
3+
Apache-2.0
4+
Apache-2.0 OR BSD-2-Clause
5+
Apache Software License
6+
BSD License
7+
BSD-2-Clause
8+
BSD-3-Clause
9+
GPL-3.0-or-later
10+
MIT
11+
MIT License
12+
Mozilla Public License 2.0 (MPL 2.0)
13+
PSF-2.0
14+
Python Software Foundation License

docs/repository-standards.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
- branching_model: library-release
3232
- release_model: artifact-publishing
3333
- supported_release_lines: current and previous
34+
- primary_language: python
3435

3536
## Local validation
3637

scripts/dev/prepare_release.py

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
- Python: reads version from pyproject.toml
99
- Maven: reads version from pom.xml
1010
- Go: reads version from **/version.go
11+
- VERSION file: reads version from VERSION (fallback)
1112
1213
Usage:
1314
scripts/dev/prepare_release.py --issue 42
@@ -85,10 +86,26 @@ def detect_go() -> str | None:
8586
return None
8687

8788

89+
def detect_version_file() -> str | None:
90+
"""Return the version from a VERSION file at the repo root (fallback)."""
91+
path = Path("VERSION")
92+
if not path.is_file():
93+
return None
94+
version = path.read_text(encoding="utf-8").strip()
95+
if not re.fullmatch(r"\d+\.\d+\.\d+", version):
96+
message = (
97+
f"VERSION file contains '{version}' which is not valid semver.\n"
98+
f"Expected format: MAJOR.MINOR.PATCH (e.g. 1.2.3)"
99+
)
100+
raise SystemExit(message)
101+
return version
102+
103+
88104
DETECTORS = [
89105
("python", detect_python),
90106
("maven", detect_maven),
91107
("go", detect_go),
108+
("version-file", detect_version_file),
92109
]
93110

94111

@@ -102,7 +119,8 @@ def detect_ecosystem() -> tuple[str, str]:
102119
"Could not detect ecosystem. Expected one of:\n"
103120
" - pyproject.toml with version (Python)\n"
104121
" - pom.xml with version (Maven)\n"
105-
" - go.mod + **/version.go (Go)"
122+
" - go.mod + **/version.go (Go)\n"
123+
" - VERSION file with MAJOR.MINOR.PATCH"
106124
)
107125
raise SystemExit(message)
108126

scripts/dev/sync-tooling.sh

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,11 @@ MANAGED_FILES=(
2929
scripts/dev/prepare_release.py
3030
scripts/dev/finalize_repo.sh
3131
scripts/dev/sync-tooling.sh
32+
scripts/dev/validate_local.sh
33+
scripts/dev/validate_local_common.sh
34+
scripts/dev/validate_local_python.sh
35+
scripts/dev/validate_local_go.sh
36+
scripts/dev/validate_local_java.sh
3237
)
3338

3439
# Lint scripts that also get copied to the actions path.

scripts/dev/validate_local.py

Lines changed: 0 additions & 133 deletions
This file was deleted.

scripts/dev/validate_local.sh

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
#!/usr/bin/env bash
2+
# Canonical source: standard-tooling
3+
# validate_local.sh — shared driver for pre-PR local validation.
4+
#
5+
# Reads primary_language from docs/repository-standards.md, then runs:
6+
# 1. validate_local_common.sh (always)
7+
# 2. validate_local_<lang>.sh (if primary_language is set and script exists)
8+
# 3. validate_local_custom.sh (if exists — repo-specific escape hatch)
9+
set -euo pipefail
10+
11+
scripts_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
12+
repo_root="$(cd "$scripts_dir/../.." && pwd)"
13+
profile_file="$repo_root/docs/repository-standards.md"
14+
15+
# -- helpers -----------------------------------------------------------------
16+
17+
run() {
18+
echo "Running: $*"
19+
"$@"
20+
}
21+
22+
# -- read primary_language from repo profile ---------------------------------
23+
24+
primary_language=""
25+
if [[ -f "$profile_file" ]]; then
26+
while IFS= read -r line; do
27+
if [[ "$line" =~ ^[[:space:]-]*primary_language:[[:space:]]*(.+)$ ]]; then
28+
primary_language="${BASH_REMATCH[1]}"
29+
break
30+
fi
31+
done < "$profile_file"
32+
fi
33+
34+
echo "========================================"
35+
echo "validate_local.sh"
36+
echo "primary_language: ${primary_language:-<not set>}"
37+
echo "========================================"
38+
echo ""
39+
40+
# -- common checks (always) -------------------------------------------------
41+
42+
common_script="$scripts_dir/validate_local_common.sh"
43+
if [[ -f "$common_script" ]]; then
44+
run "$common_script"
45+
else
46+
echo "WARNING: $common_script not found; skipping common checks" >&2
47+
fi
48+
49+
# -- language-specific checks ------------------------------------------------
50+
51+
if [[ -n "$primary_language" && "$primary_language" != "none" ]]; then
52+
lang_script="$scripts_dir/validate_local_${primary_language}.sh"
53+
if [[ -f "$lang_script" ]]; then
54+
echo ""
55+
run "$lang_script"
56+
fi
57+
fi
58+
59+
# -- repo-specific custom checks --------------------------------------------
60+
61+
custom_script="$scripts_dir/validate_local_custom.sh"
62+
if [[ -f "$custom_script" ]]; then
63+
echo ""
64+
run "$custom_script"
65+
fi
66+
67+
echo ""
68+
echo "========================================"
69+
echo "validate_local.sh: all checks passed"
70+
echo "========================================"
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
#!/usr/bin/env bash
2+
# Canonical source: standard-tooling
3+
# validate_local_common.sh — shared checks run for ALL repos.
4+
set -euo pipefail
5+
6+
repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
7+
8+
run() {
9+
echo "Running: $*"
10+
"$@"
11+
}
12+
13+
# -- required tools ----------------------------------------------------------
14+
15+
missing=()
16+
command -v shellcheck >/dev/null 2>&1 || missing+=("shellcheck")
17+
command -v markdownlint >/dev/null 2>&1 || missing+=("markdownlint")
18+
19+
if [[ ${#missing[@]} -gt 0 ]]; then
20+
echo "ERROR: required tools not found: ${missing[*]}" >&2
21+
exit 1
22+
fi
23+
24+
# -- repo profile validation -------------------------------------------------
25+
26+
if [[ -f "$repo_root/scripts/lint/repo-profile.sh" ]]; then
27+
run "$repo_root/scripts/lint/repo-profile.sh"
28+
fi
29+
30+
# -- markdown lint -----------------------------------------------------------
31+
32+
if [[ -f "$repo_root/scripts/lint/markdown-standards.sh" ]]; then
33+
run "$repo_root/scripts/lint/markdown-standards.sh"
34+
fi
35+
36+
# -- shellcheck on all shell scripts -----------------------------------------
37+
38+
shell_files=()
39+
while IFS= read -r f; do
40+
shell_files+=("$f")
41+
done < <(
42+
find "$repo_root/scripts" -type f -name '*.sh' 2>/dev/null
43+
find "$repo_root/scripts/git-hooks" -type f 2>/dev/null
44+
)
45+
46+
if [[ ${#shell_files[@]} -gt 0 ]]; then
47+
run shellcheck "${shell_files[@]}"
48+
fi
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
#!/usr/bin/env bash
2+
# validate_local_custom.sh — mq-rest-admin-python repo-specific checks.
3+
# This file is NOT synced from standard-tooling.
4+
set -euo pipefail
5+
6+
repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
7+
8+
run() {
9+
echo "Running: $*"
10+
"$@"
11+
}
12+
13+
# -- resolve base ref for version validation ---------------------------------
14+
15+
base_ref=""
16+
if git symbolic-ref --quiet refs/remotes/origin/HEAD >/dev/null 2>&1; then
17+
ref="$(git symbolic-ref --quiet refs/remotes/origin/HEAD)"
18+
base_ref="${ref##*/}"
19+
fi
20+
21+
if [[ -z "$base_ref" ]]; then
22+
if git rev-parse --verify --quiet develop >/dev/null 2>&1 ||
23+
git rev-parse --verify --quiet origin/develop >/dev/null 2>&1; then
24+
base_ref="develop"
25+
fi
26+
fi
27+
28+
if [[ -z "$base_ref" ]]; then
29+
echo "ERROR: could not resolve base ref for version validation" >&2
30+
exit 1
31+
fi
32+
33+
# -- repo-specific validation scripts ---------------------------------------
34+
35+
run uv run python3 "$repo_root/scripts/dev/validate_venv.py"
36+
run uv run python3 "$repo_root/scripts/dev/validate_dependency_specs.py"
37+
run uv run python3 "$repo_root/scripts/dev/validate_version.py" --base-ref "$base_ref"
38+
39+
# -- type checking on examples/ (beyond what synced python script covers) ----
40+
41+
if [[ -d "$repo_root/examples" ]]; then
42+
run uv run mypy examples/
43+
if uv run ty --version >/dev/null 2>&1; then
44+
run uv run ty check examples
45+
fi
46+
fi

0 commit comments

Comments
 (0)