Skip to content

Config, Outsider finder, Scope parser#5

Merged
thumbrise merged 10 commits into
mainfrom
scope-parser
May 28, 2026
Merged

Config, Outsider finder, Scope parser#5
thumbrise merged 10 commits into
mainfrom
scope-parser

Conversation

@thumbrise
Copy link
Copy Markdown
Owner

@thumbrise thumbrise commented May 28, 2026

Summary by CodeRabbit

  • New Features

    • Added configuration loading from .commitlint-scope file to customize scope validation patterns and regex.
    • Scope validation now uses configured patterns and regex rules from loaded configuration.
  • Bug Fixes

    • JSON validation violations output now writes to standard output instead of error output.
  • Refactor

    • Updated internal validator interfaces for improved scope extraction and pattern matching logic.

Review Change Stack

@thumbrise thumbrise self-assigned this May 28, 2026
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 28, 2026

Warning

Review limit reached

@thumbrise, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 27 minutes and 7 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 06300c98-d1a7-477c-b6e6-d838184873e3

📥 Commits

Reviewing files that changed from the base of the PR and between adfcc4b and 002bf55.

📒 Files selected for processing (7)
  • cmd/root.go
  • pkg/validator/config.go
  • pkg/validator/outsider_finder.go
  • pkg/validator/outsider_finder_test.go
  • pkg/validator/scope_parser_test.go
  • pkg/validator/validator.go
  • pkg/validator/validator_test.go
📝 Walkthrough

Walkthrough

This PR refactors the validator to load scope-validation configuration from .commitlint-scope files and provides default implementations for scope extraction and file matching. Config loading uses viper with custom regex decoding, the validator contracts change to return structured Outsider types, and the CLI integrates config loading at startup.

Changes

Configuration-driven scope validation

Layer / File(s) Summary
Config loading infrastructure and dependencies
pkg/validator/config.go, go.mod
Config struct holds compiled ScopeRegex and Patterns map. LoadConfig() instantiates viper, reads .commitlint-scope files, applies custom regexDecode hook to compile regex fields, and returns loaded Config or error. Dependencies added for viper, mapstructure/v2, and glob library; several golang.org/x/* module versions bumped.
Validator type and interface contracts
pkg/validator/validator.go
Violation.Outsiders changed to []Outsider struct (from []string). ScopeParser.Parse() now returns single string scope (removed bool ok indicator). OutsiderFinder.Find() now returns []Outsider (from []string). NewValidator() signature updated to accept Config parameter and auto-creates ScopeParser/OutsiderFinder defaults from cfg.Patterns and cfg.ScopeRegex when nil.
Mock generation updates
pkg/validator/mocks_test.go
MockScopeParser.Parse() return type updated to string (removed second bool). MockOutsiderFinder.Find() return type updated to []Outsider (from []string). Associated call helper methods (Return, RunAndReturn) adjusted to match new signatures.
Scope parser implementation and tests
pkg/validator/scope_parser.go, pkg/validator/scope_parser_test.go
DefaultScopeParser stores compiled regex and Parse() extracts named capture group scope from message, returning empty string on nil regex, no match, or missing submatch index. Tests cover nil regex, matching/non-matching messages, missing groups, and breaking-change syntax.
Outsider finder implementation and tests
pkg/validator/outsider_finder.go, pkg/validator/outsider_finder_test.go
DefaultOutsiderFinder compiles per-scope glob patterns at construction and Find() identifies files not matching any pattern. Falls back to scope + "/**" when no patterns exist for scope. Outsider struct exposes file and unmatched patterns. Tests validate wildcard, globstar, dotfile, and multi-pattern matching.
Validator test updates
pkg/validator/validator_test.go
TestableCommit now uses outsidersFiles (slice of filenames) instead of outsiders. Test commits and validator construction updated to pass Config{} to NewValidator(). Mock expectations refactored to construct []Outsider from file lists and match new Parse()/Find() signatures.
CLI config integration
cmd/root.go
Command Action now calls validator.LoadConfig() before validator construction, wrapping config-load errors with context. JSON violations output destination switched from ErrWriter to Writer.
Minor cleanup
pkg/validator/git.go
Gosec linter comment corrected from "no another way" to "no other way".

Sequence Diagram

sequenceDiagram
  participant CLI as CLI Command
  participant LoadCfg as LoadConfig()
  participant Parser as DefaultScopeParser
  participant Finder as DefaultOutsiderFinder
  participant Validator
  
  CLI->>LoadCfg: Call LoadConfig()
  LoadCfg-->>CLI: Return Config{ScopeRegex, Patterns}
  
  CLI->>Validator: NewValidator(Config, Options)
  Validator->>Parser: NewDefaultScopeParser(config.ScopeRegex)
  Validator->>Finder: NewDefaultOutsiderFinder(config.Patterns)
  
  CLI->>Validator: Validate(commit)
  Validator->>Parser: Parse(message)
  Parser-->>Validator: scope string
  
  Validator->>Finder: Find(scope, files)
  Finder-->>Validator: []Outsider
  
  Validator-->>CLI: Violation{Scopes, Outsiders}
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • thumbrise/commitlint-scope#2: Introduces the validator package contracts and structure that this PR refactors and expands with configuration-driven implementation.
  • thumbrise/commitlint-scope#1: Modifies cmd/root.go command initialization and validator wiring, directly related to the CLI integration changes in this PR.
  • thumbrise/commitlint-scope#4: Also updates cmd/root.go and validator.NewValidator() construction in the same validator initialization path.

Poem

🐰 A config file hops into view,
Scope parsing regex extracts what's true,
Globs catch files that don't belong,
New contracts harmonize the song,
Mock and test keep pace throughout! 🐇

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 9.09% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly captures the three main additions: configuration loading (Config), outsider detection (Outsider finder), and scope extraction (Scope parser).
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch scope-parser

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@pkg/validator/config.go`:
- Around line 42-44: The regexp decode hook (regexDecode) currently panics on a
type mismatch; change it to return a typed error instead so v.Unmarshal(&cfg,
regexDecode) can propagate it (avoid crashing the CLI). Locate the decode hook
implementation in pkg/validator/config.go (the function referenced as
regexDecode used by v.Unmarshal) and replace the panic(fmt.Sprintf("expected
string but got %T", data)) with returning an error (e.g., fmt.Errorf("regex
decode: expected string but got %T", data)) following the decode hook's error
return convention so callers receive a normal error value rather than a panic.

In `@pkg/validator/outsider_finder.go`:
- Line 21: Replace uses of glob.MustCompile in outsider_finder.go with the
non-panicking glob.Compile and propagate/handle errors so invalid glob patterns
produce a validation error instead of panicking; specifically, in the code that
builds the globs slice (the line using glob.MustCompile(p, '/')) and the other
MustCompile occurrence referenced in the comment, call glob.Compile(p, '/') (or
glob.Compile(scope+"/**", '/')) and if Compile returns an error convert it into
the appropriate validation error return path used by this package (same style as
other validation errors in outsider_finder.go), rather than allowing a panic to
occur.

In `@pkg/validator/scope_parser_test.go`:
- Around line 21-22: Remove the duplicated table-driven test entry named "match
with scope" in scope_parser_test.go so only one case with regex:
compile(`^[a-z]+(?:\((?P<scope>[^)]+)\))?!?:\s`), message: "feat(api): add
endpoint", want: "api" remains; locate the test cases slice in the Test...
function (the table containing entries with name/regex/message/want) and delete
the redundant second occurrence to avoid running the same subtest twice.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 5beeea5d-7ee1-485a-96a1-94a817b56824

📥 Commits

Reviewing files that changed from the base of the PR and between 646f84c and adfcc4b.

⛔ Files ignored due to path filters (1)
  • go.sum is excluded by !**/*.sum
📒 Files selected for processing (11)
  • cmd/root.go
  • go.mod
  • pkg/validator/config.go
  • pkg/validator/git.go
  • pkg/validator/mocks_test.go
  • pkg/validator/outsider_finder.go
  • pkg/validator/outsider_finder_test.go
  • pkg/validator/scope_parser.go
  • pkg/validator/scope_parser_test.go
  • pkg/validator/validator.go
  • pkg/validator/validator_test.go

Comment thread pkg/validator/config.go
Comment thread pkg/validator/outsider_finder.go Outdated
for scope, pats := range patterns {
globs := make([]glob.Glob, 0, len(pats))
for _, p := range pats {
globs = append(globs, glob.MustCompile(p, '/'))
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect the outsider finder implementation and nearby code
FILE="pkg/validator/outsider_finder.go"
if [ ! -f "$FILE" ]; then
  echo "Missing file: $FILE" >&2
  exit 1
fi

echo "== File: $FILE =="
nl -ba "$FILE" | sed -n '1,200p'
echo "== End =="

# Find all MustCompile usages in the repo for context
echo
echo "== Searching for glob.MustCompile usage =="
rg -n "glob\.MustCompile" -S . || true

# Identify the glob package import in the file
echo
echo "== Imports in outsider_finder.go =="
rg -n "import|github\.com|glob" "$FILE" || true

Repository: thumbrise/commitlint-scope

Length of output: 177


🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE="pkg/validator/outsider_finder.go"
echo "== File: $FILE =="
nl -ba "$FILE" | sed -n '1,220p'

echo
echo "== Search for glob.MustCompile usage =="
rg -n "glob\.MustCompile" -S .

echo
echo "== Search for glob\.Compile usage =="
rg -n "glob\.Compile" -S . || true

Repository: thumbrise/commitlint-scope

Length of output: 176


🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE="pkg/validator/outsider_finder.go"
nl -ba "$FILE" | sed -n '1,220p'

Repository: thumbrise/commitlint-scope

Length of output: 113


🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE="pkg/validator/outsider_finder.go"
echo "== File: $FILE =="
nl -ba "$FILE" | sed -n '1,260p'

echo
echo "== Search for glob.MustCompile usage =="
rg -n "glob\.MustCompile" -S . || true

echo
echo "== Search for glob\.Compile usage =="
rg -n "glob\.Compile" -S . || true

echo
echo "== Imports in $FILE =="
sed -n '1,80p' "$FILE"

Repository: thumbrise/commitlint-scope

Length of output: 176


Fix panic risk from glob.MustCompile in outsider finder.

glob.MustCompile is used to compile both configured glob patterns and a fallback pattern (scope + "/**"). Since MustCompile panics on invalid glob syntax, malformed config input or an unexpected scope value can crash validation instead of returning a validation error.

Also apply the same non-panicking glob.Compile/error-path handling to the other MustCompile occurrence at the referenced second location.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/validator/outsider_finder.go` at line 21, Replace uses of
glob.MustCompile in outsider_finder.go with the non-panicking glob.Compile and
propagate/handle errors so invalid glob patterns produce a validation error
instead of panicking; specifically, in the code that builds the globs slice (the
line using glob.MustCompile(p, '/')) and the other MustCompile occurrence
referenced in the comment, call glob.Compile(p, '/') (or
glob.Compile(scope+"/**", '/')) and if Compile returns an error convert it into
the appropriate validation error return path used by this package (same style as
other validation errors in outsider_finder.go), rather than allowing a panic to
occur.

Comment thread pkg/validator/scope_parser_test.go Outdated
@thumbrise thumbrise merged commit bc629f4 into main May 28, 2026
4 checks passed
@thumbrise thumbrise deleted the scope-parser branch May 28, 2026 03:29
@github-actions
Copy link
Copy Markdown

🎉 This PR is included in version 0.5.0 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant