feat: Enhance configuration with CLI, env vars, and TOML support#357
feat: Enhance configuration with CLI, env vars, and TOML support#357shenxianpeng merged 4 commits intomainfrom
Conversation
…upport - Introduced a new ConfigMerger class to handle merging configurations from multiple sources: command-line arguments, environment variables, TOML files, and defaults. - Added command-line options for various commit and branch configurations, including subject length, imperative mood, and allowed commit types. - Updated README and configuration documentation to reflect new configuration methods and examples. - Implemented comprehensive tests for CLI argument integration, environment variable handling, and configuration priority. - Ensured backward compatibility with existing configuration files while providing enhanced flexibility for users.
✅ Deploy Preview for commit-check ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
📝 WalkthroughWalkthroughAdds a multi-source configuration system (CLI, environment variables, TOML, defaults) with a ConfigMerger, updates main to use it and exposes many new CLI options, updates docs and README with configuration guidance, updates pre-commit hook version, and adds extensive tests for merging and priority behavior. Changes
Sequence Diagram(s)sequenceDiagram
participant CLI
participant Env as "Environment\n(CCHK_... vars)"
participant TOML as "TOML File\n(commit-check.toml/cchk.toml)"
participant Defaults
participant Merger as ConfigMerger
participant Main
CLI->>Merger: provide CLI args
Env->>Merger: provide CCHK_* env vars
TOML->>Merger: provide parsed TOML (if present)
Defaults->>Merger: provide default config
Merger->>Merger: deep_merge(TOML into Defaults)\nthen merge Env, then CLI (priority)
Merger->>Main: return merged config dict
Main->>Main: build rules and run validations using merged config
Estimated code review effort🎯 4 (Complex) | ⏱️ ~50 minutes Possibly related PRs
Suggested labels
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧪 Generate unit tests (beta)
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. Comment |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #357 +/- ##
==========================================
+ Coverage 93.22% 94.35% +1.12%
==========================================
Files 8 9 +1
Lines 694 797 +103
==========================================
+ Hits 647 752 +105
+ Misses 47 45 -2 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Fix all issues with AI agents
In `@commit_check/config_merger.py`:
- Around line 65-66: The default configuration in commit_check/config_merger.py
currently sets "subject_max_length": 80 and "subject_min_length": 5 which
conflicts with the documented defaults of None; update the defaults to match the
docs by changing the values for the keys subject_max_length and
subject_min_length to None (no limit) in the default config/dict (where these
keys are defined) so validation will behave as documented.
In `@docs/configuration.rst`:
- Around line 122-131: The documentation example shows the pre-commit hook repo
entry using rev: v2.2.0 which mismatches the updated .pre-commit-config.yaml;
update the example's rev value from v2.2.0 to v2.3.0 for the commit-check repo
entry (the block containing repo: https://github.com/commit-check/commit-check
and id: commit-check) so the docs match the actual hook version and the new CLI
args work as expected.
In `@README.rst`:
- Around line 106-115: Update the pre-commit example's repo revision from v2.2.0
to v2.3.0: locate the pre-commit hooks block that contains the line "rev:
v2.2.0" (the example under repos -> repo:
https://github.com/commit-check/commit-check and hook id: commit-check) and
change the revision string to "v2.3.0" so it matches the new features and the
docs/configuration.rst example.
🧹 Nitpick comments (6)
commit_check/config_merger.py (4)
51-55: Preserve exception chain withraise ... from.When re-raising a ValueError inside an except block, use
raise ... fromto maintain the exception chain for better debugging.♻️ Suggested fix
if isinstance(value, str): try: return int(value.strip()) except ValueError as err: - raise ValueError(f"Cannot parse '{value}' as integer") + raise ValueError(f"Cannot parse '{value}' as integer") from err raise TypeError(f"Cannot convert {type(value).__name__} to int")
100-122: Consider annotating mutable class attribute withClassVar.The
ENV_VAR_MAPPINGdictionary is a class-level constant that should be annotated withtyping.ClassVarto indicate it's shared across all instances and not meant to be modified per-instance.♻️ Suggested fix
+from typing import ClassVar + class ConfigMerger: """Merges configurations from multiple sources with priority: CLI > Env > TOML > Defaults.""" # Mapping of environment variable names to config keys - ENV_VAR_MAPPING: Dict[str, Tuple[str, str, Callable[[Any], Any]]] = { + ENV_VAR_MAPPING: ClassVar[Dict[str, Tuple[str, str, Callable[[Any], Any]]]] = {
135-137: Warning output to stdout may interfere with piped workflows.Using
print()for warnings sends output to stdout, which could interfere with scenarios where commit-check output is piped. Consider usingsys.stderror theloggingmodule instead.♻️ Suggested fix
+import sys + except (ValueError, TypeError) as e: # Log warning but don't fail - just skip invalid env vars - print(f"Warning: Invalid value for {env_var}: {e}") + print(f"Warning: Invalid value for {env_var}: {e}", file=sys.stderr)
144-222: Consider reducing repetition inparse_cli_args.The method has significant repetition with the
hasattr/is not Nonepattern. A data-driven approach similar toENV_VAR_MAPPINGwould reduce maintenance burden and be more consistent.♻️ Example refactor approach
CLI_ARG_MAPPING = { # (attr_name, section, config_key) ("conventional_commits", "commit", "conventional_commits"), ("subject_capitalized", "commit", "subject_capitalized"), ("subject_imperative", "commit", "subject_imperative"), # ... etc } `@staticmethod` def parse_cli_args(args: argparse.Namespace) -> Dict[str, Any]: config: Dict[str, Any] = {"commit": {}, "branch": {}} for attr, section, key in ConfigMerger.CLI_ARG_MAPPING: value = getattr(args, attr, None) if value is not None: config[section][key] = value config = {k: v for k, v in config.items() if v} return configcommit_check/main.py (1)
355-360: Dead code branch in stdin handling.The
elif not any(...)block at line 355-357 contains only apassstatement and has no effect. This could be simplified or removed.♻️ Suggested simplification
if args.message == "": # Only set stdin_content if there's actual piped input stdin_content = stdin_reader.read_piped_input() if not stdin_content: # No stdin and no file - let validators get data from git themselves stdin_content = None else: # Message is a file path commit_file_path = args.message - elif not any([args.branch, args.author_name, args.author_email]): - # If no specific validation type is requested, don't read stdin - pass - else: + elif any([args.branch, args.author_name, args.author_email]): # For non-message validations (branch, author), check for stdin input stdin_content = stdin_reader.read_piped_input()tests/config_merger_test.py (1)
254-261: Remove unusedtmp_pathfixture parameter.The
tmp_pathfixture parameter is declared but not used in this test method.♻️ Suggested fix
- def test_default_config_only(self, tmp_path): + def test_default_config_only(self): # No TOML file, no env vars, no CLI args args = argparse.Namespace() config = ConfigMerger.from_all_sources(args)
| "subject_max_length": 80, | ||
| "subject_min_length": 5, |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# First, check the documentation as suggested
rg -n "subject_max_length|subject_min_length" docs/configuration.rst | head -20Repository: commit-check/commit-check
Length of output: 427
🏁 Script executed:
# Read the full context around lines 65-66 in config_merger.py
cat -n commit_check/config_merger.py | sed -n '50,80p'Repository: commit-check/commit-check
Length of output: 1794
🏁 Script executed:
# Also check if there are multiple config files or defaults defined elsewhere
fd -t f config || true
fd -t f "\.py$" commit_check/ | xargs rg -l "subject_max_length|subject_min_length"Repository: commit-check/commit-check
Length of output: 326
🏁 Script executed:
# Get more context around lines 279-287 in the documentation
cat -n docs/configuration.rst | sed -n '270,300p'Repository: commit-check/commit-check
Length of output: 1169
🏁 Script executed:
# Check broader context around lines 62-63 and 183-186
cat -n docs/configuration.rst | sed -n '55,75p'
cat -n docs/configuration.rst | sed -n '175,195p'Repository: commit-check/commit-check
Length of output: 1978
Default values in code conflict with documented behavior.
The code sets subject_max_length to 80 and subject_min_length to 5, but the documentation at lines 279-287 specifies these options default to None (no limit). This mismatch could cause unexpected validation failures for users relying on the documented default behavior.
Align either the code defaults or documentation to ensure consistency.
🤖 Prompt for AI Agents
In `@commit_check/config_merger.py` around lines 65 - 66, The default
configuration in commit_check/config_merger.py currently sets
"subject_max_length": 80 and "subject_min_length": 5 which conflicts with the
documented defaults of None; update the defaults to match the docs by changing
the values for the keys subject_max_length and subject_min_length to None (no
limit) in the default config/dict (where these keys are defined) so validation
will behave as documented.
Merging this PR will degrade performance by 57.64%
Performance Changes
Comparing Footnotes
|
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
6280a54 to
8f80ac6
Compare
There was a problem hiding this comment.
Pull request overview
This PR enhances commit-check's configuration system to support CLI arguments, environment variables, and TOML files with a clear priority hierarchy (CLI > Env > TOML > Defaults), directly addressing issue #339 which requested the ability to configure the tool via CLI parameters in pre-commit hooks without requiring a TOML configuration file.
Changes:
- Introduced a new
ConfigMergerclass that merges configurations from multiple sources with proper priority handling - Added comprehensive CLI arguments for all commit and branch validation options using custom parsers (
parse_bool,parse_list,parse_int) - Implemented environment variable support with the
CCHK_prefix for all configuration options - Updated documentation extensively to explain the new configuration methods, priority system, and usage patterns
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| commit_check/config_merger.py | New module implementing configuration merging logic with support for CLI args, env vars, TOML files, and defaults |
| commit_check/main.py | Added CLI argument definitions for all configuration options and integrated ConfigMerger |
| tests/config_merger_test.py | Comprehensive unit tests for ConfigMerger, parse functions, and priority handling |
| tests/main_test.py | Integration tests verifying CLI args, env vars, and priority system work end-to-end |
| docs/configuration.rst | Extensive documentation additions covering CLI args, env vars, priority system, and mapping tables |
| README.rst | Updated to document the three configuration methods and their priority |
| .pre-commit-config.yaml | Version bump to v2.3.0 |
|
@shenxianpeng I've opened a new pull request, #358, to work on those changes. Once the pull request is ready, I'll request review from you. |
* Initial plan * refactor: Use data-driven approach in parse_cli_args to reduce duplication Co-authored-by: shenxianpeng <3353385+shenxianpeng@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: shenxianpeng <3353385+shenxianpeng@users.noreply.github.com>
|
| - repo: https://github.com/commit-check/commit-check | ||
| rev: v2.3.0 | ||
| hooks: | ||
| - id: commit-check |
There was a problem hiding this comment.
The id: commit-check is not correct...
It is not defined in https://github.com/commit-check/commit-check/blob/main/.pre-commit-hooks.yaml
There was a problem hiding this comment.
Thanks! fixed into the main branch.
There was a problem hiding this comment.
I'm not sure if it is just on my side, but I'm getting error:
$ git commit -m 'feat: improve logging messages and add checks for .lycheecache'
...
...
...
check commit message.....................................................Failed
- hook id: check-message
- exit code: 2
usage: commit-check [-h] [-v] [-c CONFIG] [-m [MESSAGE]] [-b] [-n] [-e] [-d]
[--conventional-commits BOOL] [--subject-capitalized BOOL]
[--subject-imperative BOOL] [--subject-max-length INT]
[--subject-min-length INT] [--allow-commit-types LIST]
[--allow-merge-commits BOOL] [--allow-revert-commits BOOL]
[--allow-empty-commits BOOL] [--allow-fixup-commits BOOL]
[--allow-wip-commits BOOL] [--require-body BOOL]
[--require-signed-off-by BOOL] [--ignore-authors LIST]
[--conventional-branch BOOL] [--allow-branch-types LIST]
[--allow-branch-names LIST]
[--require-rebase-target BRANCH]
[--branch-ignore-authors LIST]
commit-check: error: unrecognized arguments: .git/COMMIT_EDITMSG
I have this in .pre-commit-config.yaml:
- repo: https://github.com/commit-check/commit-check
rev: v2.4.0
hooks:
- id: check-message
args:
- --subject-imperative=false
- id: check-branch
- id: check-author-name
- id: check-author-email


closes #339
Summary by CodeRabbit
New Features
Documentation
Tests
Chores
✏️ Tip: You can customize this high-level summary in your review settings.