Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .flake8
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[flake8]
max-line-length = 100
52 changes: 43 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,6 @@ Update to latest:

```bash
git submodule update --remote code_checking
git add code_checking
git commit -m "Update code_checking submodule"
```

Consumer repositories keep:
Expand Down Expand Up @@ -117,14 +115,34 @@ managed section. It also seeds baseline `.gitignore`,
consumer root when those files are missing. Running `sync-consumer` means you
do not need to run `setup-github-workflow.sh` separately.

After `sync-consumer` completes, commit all integration files in a single commit
using the site commit message standards from
[docs/git-commit-message-guidelines.md](docs/git-commit-message-guidelines.md).
Example commit message format:

```text
TKT-XXXX: Add code-checking submodule integration

Integrated code-checking as a top-level submodule to provide shared linting
and check scripts across the repository. Bootstraps baseline workflows,
pre-commit hooks configuration, and IDE settings.

Consumer integration:
- Added .github/workflows with code-checking checks
- Configured pre-commit hooks to use code-checking entrypoints
- Seeded baseline configuration files (.yamllint, cspell.config.yaml, etc.)
- Updated README.md with code-checking managed section
```

To skip README updates for a specific run:

```bash
./code_checking/bin/sync-consumer.sh --skip-readme
```

For an initial consumer-repo integration commit after running
`sync-consumer`, stage and review these files:
`sync-consumer`, stage all of these files together and commit with a proper
commit message following the site standards:

- `.github/workflows/` (may need to add newly created files instead)
- `.gitignore` (if seeded)
Expand All @@ -135,20 +153,36 @@ For an initial consumer-repo integration commit after running
- `.yamllint` (if seeded)
- `vscode-project-words.txt` (if seeded)

The `code_checking` submodule directory itself should also be staged:

- `code_checking/`

The `code_checking` submodule was previously added. Changes inside that
directory are not required for this integration commit.

Example staging commands:

```bash
git add .github/workflows/ # May need to add newly added files instead.
git add .gitignore # seeded if missing
git add .github/workflows/
git add .gitignore
git add .gitmodules
git add .pre-commit-config.yaml # if setup-dev was run
git add .pre-commit-config.yaml
git add .pylint
git add .yamllint
git add code_checking
git add cspell.config.yaml
git add README.md
git add cspell.config.yaml # seeded if missing
git add .yamllint # seeded if missing
git add vscode-project-words.txt # seeded if missing
git add vscode-project-words.txt
```

Then commit with a proper message:

```bash
git commit
```

This will open your editor to write a commit message following the guidelines.

Do not stage `code-checking-ref` for normal integration commits. An
intentional validation PR may track it temporarily when testing a
`code_checking` PR ref.
Expand Down
48 changes: 18 additions & 30 deletions bin/run-linters.sh
Original file line number Diff line number Diff line change
Expand Up @@ -123,34 +123,28 @@ for linter in "${REQUIRED_LINTERS[@]}"; do
case "${linter}" in
shellcheck)
run_args=("${run_args_common[@]}")
if ! "${LIB_ROOT}/checks/linters/shellcheck/run.sh" "${run_args[@]}"; then
linter_rc=$?
fi
"${LIB_ROOT}/checks/linters/shellcheck/run.sh" "${run_args[@]}" \
|| linter_rc=$?
;;
groovylint)
run_args=("${run_args_common[@]}")
if ! "${LIB_ROOT}/checks/linters/groovylint/run.sh" "${run_args[@]}"; then
linter_rc=$?
fi
"${LIB_ROOT}/checks/linters/groovylint/run.sh" "${run_args[@]}" \
|| linter_rc=$?
;;
markdownlint)
run_args=("${run_args_common[@]}")
if ! "${LIB_ROOT}/checks/linters/markdownlint/run.sh" "${run_args[@]}";
then
linter_rc=$?
fi
"${LIB_ROOT}/checks/linters/markdownlint/run.sh" "${run_args[@]}" \
|| linter_rc=$?
;;
yamllint)
run_args=("${run_args_common[@]}")
if ! "${LIB_ROOT}/checks/linters/yamllint/run.sh" "${run_args[@]}"; then
linter_rc=$?
fi
"${LIB_ROOT}/checks/linters/yamllint/run.sh" "${run_args[@]}" \
|| linter_rc=$?
;;
python)
run_args=("${run_args_common[@]}")
if ! "${LIB_ROOT}/checks/linters/python/run.sh" "${run_args[@]}"; then
linter_rc=$?
fi
"${LIB_ROOT}/checks/linters/python/run.sh" "${run_args[@]}" \
|| linter_rc=$?
;;
copyright)
run_args=("${run_args_common[@]}")
Expand All @@ -160,15 +154,13 @@ for linter in "${REQUIRED_LINTERS[@]}"; do
run_args+=(--no-stage)
fi
fi
if ! "${LIB_ROOT}/checks/linters/copyright/run.sh" "${run_args[@]}"; then
linter_rc=$?
fi
"${LIB_ROOT}/checks/linters/copyright/run.sh" "${run_args[@]}" \
|| linter_rc=$?
;;
codespell)
run_args=("${run_args_common[@]}")
if ! "${LIB_ROOT}/checks/linters/codespell/run.sh" "${run_args[@]}"; then
linter_rc=$?
fi
"${LIB_ROOT}/checks/linters/codespell/run.sh" "${run_args[@]}" \
|| linter_rc=$?
;;
text-hygiene)
run_args=("${run_args_common[@]}")
Expand All @@ -178,17 +170,13 @@ for linter in "${REQUIRED_LINTERS[@]}"; do
run_args+=(--no-stage)
fi
fi
if ! "${LIB_ROOT}/checks/linters/text-hygiene/run.sh" "${run_args[@]}";
then
linter_rc=$?
fi
"${LIB_ROOT}/checks/linters/text-hygiene/run.sh" "${run_args[@]}" \
|| linter_rc=$?
;;
filename-portability)
run_args=("${run_args_common[@]}")
if ! "${LIB_ROOT}/checks/linters/filename-portability/run.sh" "${run_args[@]}";
then
linter_rc=$?
fi
"${LIB_ROOT}/checks/linters/filename-portability/run.sh" "${run_args[@]}" \
|| linter_rc=$?
;;
*)
echo "Unknown linter selected: ${linter}" >&2
Expand Down
14 changes: 12 additions & 2 deletions bin/sync-consumer.sh
Original file line number Diff line number Diff line change
Expand Up @@ -228,8 +228,8 @@ if [[ "${UPDATE_README}" == true ]]; then

This repository uses the shared \`code_checking\` submodule.

- Framework documentation: [code_checking README](./${SUBMODULE_PATH}/README.md)
- Integration guide:
* Framework documentation: [code_checking README](./${SUBMODULE_PATH}/README.md)
* Integration guide:
[code_checking integration](./${SUBMODULE_PATH}/docs/integration.md)

${END_MARKER}"
Expand Down Expand Up @@ -307,4 +307,14 @@ if [[ ! -f "${TARGET_ROOT}/vscode-project-words.txt" ]]; then
fi
fi

if [[ ! -f "${TARGET_ROOT}/.flake8" ]]; then
FLAKE8_BASELINE="${LIB_ROOT}/.flake8"
if [[ -f "${FLAKE8_BASELINE}" ]]; then
cp "${FLAKE8_BASELINE}" "${TARGET_ROOT}/.flake8"
echo "[sync-consumer] created .flake8 from code_checking baseline"
else
echo "[sync-consumer] baseline not found: ${FLAKE8_BASELINE}" >&2
fi
fi

echo "[sync-consumer] complete"
55 changes: 48 additions & 7 deletions checks/linters/groovylint/check-implicit-bindings.sh
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,54 @@ for file_path in "$@"; do
# Guard against Groovy script binding side effects from bare assignments like
# `myVar = value`. In Jenkins pipelines these become shared script properties
# and can cause nondeterministic behavior in parallel execution.
if grep -nE '^[[:space:]]*[A-Za-z_][A-Za-z0-9_]*[[:space:]]*=[^=~]' \
"${file_path}" >/dev/null; then
echo "[groovylint] implicit script-binding assignment detected: ${file_path}" >&2
grep -nE '^[[:space:]]*[A-Za-z_][A-Za-z0-9_]*[[:space:]]*=[^=~]' \
"${file_path}" >&2
violations=1
fi
# Exclude assignments inside declarative `environment { }` blocks (legitimate).
violations_in_file=$(awk '
BEGIN { in_environment = 0; env_brace_depth = 0 }
/environment[[:space:]]*\{/ {
in_environment = 1
env_brace_depth += gsub(/\{/, "{")
env_brace_depth -= gsub(/\}/, "}")
next
}
in_environment {
env_brace_depth += gsub(/\{/, "{")
env_brace_depth -= gsub(/\}/, "}")
if (env_brace_depth <= 0) {
in_environment = 0
}
next
}
!in_environment && /^[[:space:]]*[A-Za-z_][A-Za-z0-9_]*[[:space:]]*=[^=~]/ {
print NR": "$0
exit 1
}
END { exit 0 }
' "${file_path}" 2>/dev/null) || {
if [[ -n "${violations_in_file}" ]]; then
echo "[groovylint] implicit script-binding assignment detected: ${file_path}" >&2
awk '
BEGIN { in_environment = 0; env_brace_depth = 0 }
/environment[[:space:]]*\{/ {
in_environment = 1
env_brace_depth += gsub(/\{/, "{")
env_brace_depth -= gsub(/\}/, "}")
next
}
in_environment {
env_brace_depth += gsub(/\{/, "{")
env_brace_depth -= gsub(/\}/, "}")
if (env_brace_depth <= 0) {
in_environment = 0
}
next
}
!in_environment && /^[[:space:]]*[A-Za-z_][A-Za-z0-9_]*[[:space:]]*=[^=~]/ {
print NR": "$0
}
' "${file_path}" >&2
violations=1
fi
}
done

if [[ ${violations} -ne 0 ]]; then
Expand Down
1 change: 1 addition & 0 deletions vscode-project-words.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ filemode
gitfs
gitlink
groovylint
gsub
gvars
isort
LASTEXITCODE
Expand Down
Loading