From 8b1c1ff7c0d143c06f7ebd3636e56dffddc764c0 Mon Sep 17 00:00:00 2001 From: sugan0tech Date: Wed, 20 Aug 2025 00:16:33 +0530 Subject: [PATCH 1/4] chore(pre-commit): require issue reference in commit messages Closes #34 --- .pre-commit-config.yaml | 7 +++++++ CONTRIBUTING.md | 3 +++ scripts/require_issue_ref.sh | 39 ++++++++++++++++++++++++++++++++++++ 3 files changed, 49 insertions(+) create mode 100644 scripts/require_issue_ref.sh diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 42df6bc..55ee291 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -55,6 +55,13 @@ repos: entry: bash -lc 'go vet ./...' language: system pass_filenames: false + - id: require-issue-reference + name: require issue reference in commit message + description: Ensure commit messages reference a GitHub issue like #123 + entry: bash -lc 'scripts/require_issue_ref.sh "$1"' + language: system + stages: [commit-msg] + pass_filenames: true # GolangCI-Lint (static analysis) - repo: https://github.com/golangci/golangci-lint diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index fb4745d..c30aa0b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -67,6 +67,9 @@ Our pre-commit `no-commit-to-branch` hook blocks commits on non-conforming branc ``` or commit normally and the `commit-msg` hook will validate. +- Issue reference: include a GitHub issue reference (`#`) somewhere in the commit + message (body or footer). Examples: `Refs #29`, `Closes #102`. + ## Development Workflow - Create or pick up an issue. For new features, propose design via an issue first. diff --git a/scripts/require_issue_ref.sh b/scripts/require_issue_ref.sh new file mode 100644 index 0000000..2ca37d5 --- /dev/null +++ b/scripts/require_issue_ref.sh @@ -0,0 +1,39 @@ +#!/usr/bin/env bash +set -euo pipefail + +# pre-commit commit-msg hook: ensure commit message references a GitHub issue +# Usage: scripts/require_issue_ref.sh + +msg_file="${1:-}" +if [[ -z "${msg_file}" || ! -f "${msg_file}" ]]; then + echo "commit-msg hook error: commit message file not found" >&2 + exit 1 +fi + +# Read first line (subject) +subject="$(head -n1 "$msg_file" | tr -d '\r')" + +# Allow merges and reverts to pass without extra checks +if [[ "$subject" =~ ^Merge\ || "$subject" =~ ^Revert\ ]]; then + exit 0 +fi + +# Allow automated release/version bump commits +if [[ "$subject" =~ ^chore\(release\):\ || "$subject" =~ ^bump: ]]; then + exit 0 +fi + +# Require a # anywhere in the message (subject or body) +if rg -N --pcre2 -q "#[0-9]{1,7}\b" "$msg_file" 2>/dev/null; then + exit 0 +fi + +# Fallback to grep if ripgrep is unavailable +if command -v grep >/dev/null 2>&1 && grep -Eq "#[0-9]{1,7}(\b|$)" "$msg_file"; then + exit 0 +fi + +echo "Commit message must reference a GitHub issue (e.g., 'Refs #123' or 'Closes #123')." >&2 +echo "Branch already encodes the issue ID; please include '#' in the message body or footer." >&2 +exit 1 + From ecfb227bd68fb14707cba76eb4bda8402472794e Mon Sep 17 00:00:00 2001 From: sugan0tech Date: Wed, 20 Aug 2025 00:25:54 +0530 Subject: [PATCH 2/4] chore(pre-commit): enforce line count limits (warn >300, block >450) Refs #34 --- .pre-commit-config.yaml | 6 ++++ CONTRIBUTING.md | 7 +++++ scripts/line_count_check.sh | 62 +++++++++++++++++++++++++++++++++++++ 3 files changed, 75 insertions(+) create mode 100644 scripts/line_count_check.sh diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 55ee291..85c2cca 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -62,6 +62,12 @@ repos: language: system stages: [commit-msg] pass_filenames: true + - id: line-count-limit + name: line count limit (warn >300, block >450) + description: Warn on files 301–450 lines; fail if any >450 lines + entry: bash -lc 'scripts/line_count_check.sh' + language: system + pass_filenames: true # GolangCI-Lint (static analysis) - repo: https://github.com/golangci/golangci-lint diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c30aa0b..ee27b00 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -89,6 +89,13 @@ Our pre-commit `no-commit-to-branch` hook blocks commits on non-conforming branc - `go fmt ./...` and `go vet ./...` run via pre-commit. - `golangci-lint` runs as part of pre-commit; CI integration may run it on PRs as well. +## File Size Guidelines + +- Keep source files concise. The pre-commit hook warns when a changed file exceeds 300 lines and blocks commits for files over 450 lines. + - Warning: 301–450 lines (message only; commit proceeds) + - Error: >450 lines (commit blocked) + - Consider splitting large files into smaller units for readability and maintainability. + ## Security & Secrets - `detect-secrets` scans for potential credentials. diff --git a/scripts/line_count_check.sh b/scripts/line_count_check.sh new file mode 100644 index 0000000..f8998d3 --- /dev/null +++ b/scripts/line_count_check.sh @@ -0,0 +1,62 @@ +#!/usr/bin/env bash +set -euo pipefail + +# Pre-commit hook: Warn for files >300 lines (up to 450), +# block commit if any file exceeds 450 lines. + +warn_threshold=300 +block_threshold=450 + +warned=0 +blocked=0 +declare -a blocked_files +declare -a warned_files + +is_regular_file() { + [[ -f "$1" ]] +} + +line_count() { + # Use wc -l; handle files with no trailing newline + wc -l < "$1" | awk '{print $1}' +} + +for f in "$@"; do + # Skip if not a regular file (deleted, dir, symlink, etc.) + if ! is_regular_file "$f"; then + continue + fi + + # Skip binary files by simple heuristic: if it contains NUL bytes, treat as binary + if LC_ALL=C grep -Iq $'\0' "$f"; then + continue + fi + + cnt=$(line_count "$f" || echo 0) + + if (( cnt > block_threshold )); then + blocked=1 + blocked_files+=("$f ($cnt lines)") + elif (( cnt > warn_threshold )); then + warned=1 + warned_files+=("$f ($cnt lines)") + fi +done + +if (( warned == 1 )); then + echo "[line-count] Warning: some files exceed ${warn_threshold} lines:" >&2 + for w in "${warned_files[@]}"; do + echo " - $w" >&2 + done +fi + +if (( blocked == 1 )); then + echo "[line-count] Error: files exceed ${block_threshold} lines; reduce size or split files:" >&2 + for b in "${blocked_files[@]}"; do + echo " - $b" >&2 + done + exit 1 +fi + +exit 0 + From 6909acddc06e7bc5ecacd63edf80b2b140f216e2 Mon Sep 17 00:00:00 2001 From: sugan0tech Date: Wed, 20 Aug 2025 00:29:18 +0530 Subject: [PATCH 3/4] chore(pre-commit): robust binary detection in line-count hook\n\nRefs #34 --- scripts/line_count_check.sh | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/scripts/line_count_check.sh b/scripts/line_count_check.sh index f8998d3..472a2ff 100644 --- a/scripts/line_count_check.sh +++ b/scripts/line_count_check.sh @@ -27,8 +27,8 @@ for f in "$@"; do continue fi - # Skip binary files by simple heuristic: if it contains NUL bytes, treat as binary - if LC_ALL=C grep -Iq $'\0' "$f"; then + # Skip binary files: if grep treating binary as non-text, skip + if ! LC_ALL=C grep -Iq . "$f"; then continue fi @@ -59,4 +59,3 @@ if (( blocked == 1 )); then fi exit 0 - From edf5b8bee0c27666da6d962cec79170827440193 Mon Sep 17 00:00:00 2001 From: sugan0tech Date: Thu, 21 Aug 2025 21:40:45 +0530 Subject: [PATCH 4/4] chore(pre-commit): relax thresholds and warn on issue reference\n\n- Warn above 500 lines; error above 750 lines.\n- Downgrade missing issue reference from error to warning.\n- Make exemptions (merge/revert/release bump) case-insensitive.\n\nRefs #34 --- .pre-commit-config.yaml | 8 ++++---- CONTRIBUTING.md | 7 ++++--- scripts/line_count_check.sh | 8 ++++---- scripts/require_issue_ref.sh | 14 +++++++------- 4 files changed, 19 insertions(+), 18 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 85c2cca..2efe478 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -56,15 +56,15 @@ repos: language: system pass_filenames: false - id: require-issue-reference - name: require issue reference in commit message - description: Ensure commit messages reference a GitHub issue like #123 + name: issue reference check (warning) + description: Warn if commit message lacks a GitHub issue reference like #123 entry: bash -lc 'scripts/require_issue_ref.sh "$1"' language: system stages: [commit-msg] pass_filenames: true - id: line-count-limit - name: line count limit (warn >300, block >450) - description: Warn on files 301–450 lines; fail if any >450 lines + name: line count limit (warn >500, block >750) + description: Warn on files 501–750 lines; fail if any >750 lines entry: bash -lc 'scripts/line_count_check.sh' language: system pass_filenames: true diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ee27b00..1fc582b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -69,6 +69,7 @@ Our pre-commit `no-commit-to-branch` hook blocks commits on non-conforming branc - Issue reference: include a GitHub issue reference (`#`) somewhere in the commit message (body or footer). Examples: `Refs #29`, `Closes #102`. + The commit-msg hook only warns if missing; commits still proceed. ## Development Workflow @@ -91,9 +92,9 @@ Our pre-commit `no-commit-to-branch` hook blocks commits on non-conforming branc ## File Size Guidelines -- Keep source files concise. The pre-commit hook warns when a changed file exceeds 300 lines and blocks commits for files over 450 lines. - - Warning: 301–450 lines (message only; commit proceeds) - - Error: >450 lines (commit blocked) +- Keep source files concise. The pre-commit hook warns when a changed file exceeds 500 lines and blocks commits for files over 750 lines. + - Warning: 501–750 lines (message only; commit proceeds) + - Error: >750 lines (commit blocked) - Consider splitting large files into smaller units for readability and maintainability. ## Security & Secrets diff --git a/scripts/line_count_check.sh b/scripts/line_count_check.sh index 472a2ff..a868114 100644 --- a/scripts/line_count_check.sh +++ b/scripts/line_count_check.sh @@ -1,11 +1,11 @@ #!/usr/bin/env bash set -euo pipefail -# Pre-commit hook: Warn for files >300 lines (up to 450), -# block commit if any file exceeds 450 lines. +# Pre-commit hook: Warn for files >500 lines (up to 750), +# block commit if any file exceeds 750 lines. -warn_threshold=300 -block_threshold=450 +warn_threshold=500 +block_threshold=750 warned=0 blocked=0 diff --git a/scripts/require_issue_ref.sh b/scripts/require_issue_ref.sh index 2ca37d5..0259b6c 100644 --- a/scripts/require_issue_ref.sh +++ b/scripts/require_issue_ref.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash set -euo pipefail -# pre-commit commit-msg hook: ensure commit message references a GitHub issue +# pre-commit commit-msg hook: check commit message references a GitHub issue # Usage: scripts/require_issue_ref.sh msg_file="${1:-}" @@ -12,14 +12,15 @@ fi # Read first line (subject) subject="$(head -n1 "$msg_file" | tr -d '\r')" +lower_subject="$(printf '%s' "$subject" | tr '[:upper:]' '[:lower:]')" # Allow merges and reverts to pass without extra checks -if [[ "$subject" =~ ^Merge\ || "$subject" =~ ^Revert\ ]]; then +if [[ "$lower_subject" =~ ^merge\ || "$lower_subject" =~ ^revert\ ]]; then exit 0 fi # Allow automated release/version bump commits -if [[ "$subject" =~ ^chore\(release\):\ || "$subject" =~ ^bump: ]]; then +if [[ "$lower_subject" =~ ^chore\(release\):\ || "$lower_subject" =~ ^bump: ]]; then exit 0 fi @@ -33,7 +34,6 @@ if command -v grep >/dev/null 2>&1 && grep -Eq "#[0-9]{1,7}(\b|$)" "$msg_file"; exit 0 fi -echo "Commit message must reference a GitHub issue (e.g., 'Refs #123' or 'Closes #123')." >&2 -echo "Branch already encodes the issue ID; please include '#' in the message body or footer." >&2 -exit 1 - +echo "[issue-ref] Warning: no GitHub issue reference found (e.g., 'refs #123' or 'closes #123')." >&2 +echo "Include '#' in the message body or footer when possible." >&2 +exit 0