Skip to content

Conversation

@shenxianpeng
Copy link
Contributor

@shenxianpeng shenxianpeng commented Sep 7, 2025

Summary by CodeRabbit

  • New Features

    • CLI now reads piped STDIN and forwards it to checks, enabling validations without a Git repo.
    • Commit message, author (name/email) and branch checks can use values supplied via STDIN while preserving default behavior when absent.
  • Bug Fixes

    • Added guard and user notice for missing regex patterns to avoid false failures.
  • Tests

    • Updated tests to exercise STDIN-driven flows and remain backward compatible.

@shenxianpeng shenxianpeng requested a review from a team as a code owner September 7, 2025 14:21
@shenxianpeng shenxianpeng added the enhancement New feature or request label Sep 7, 2025
@shenxianpeng shenxianpeng requested a review from Copilot September 7, 2025 14:22
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 7, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Warning

Rate limit exceeded

@shenxianpeng has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 2 minutes and 45 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, 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 have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between fc2c73c and 611faec.

📒 Files selected for processing (3)
  • .pre-commit-config.yaml (1 hunks)
  • commit_check/main.py (3 hunks)
  • tests/commit_test.py (3 hunks)

Walkthrough

Adds optional stdin_text parameters to author, branch, and commit check functions; main.py reads non-interactive STDIN and forwards it. Checks use stdin_text when provided (bypassing repo/file reads); otherwise retain prior behavior. Tests updated to pass and tolerate the new argument signatures.

Changes

Cohort / File(s) Summary
Checks: stdin passthrough
commit_check/author.py, commit_check/branch.py, commit_check/commit.py
Add stdin_text: Optional[str] to public check functions. When provided, use stdin_text as the input (author value, branch name, or commit message) and skip repo/file lookups; otherwise retain prior behavior. author adds a guard for missing regex (prints notice and returns PASS).
Entrypoint: stdin capture & wiring
commit_check/main.py
Read non-interactive STDIN once into stdin_text and pass stdin_text=stdin_text to all applicable check calls. No other control-flow changes.
Tests: commit message checks
tests/commit_test.py
Update tests to call check_imperative(..., stdin_text=...); assert commit message read when stdin_text=None.
Tests: main integration
tests/main_test.py
Update mocks to accept stdin_text kwarg; loosen author_side_effect signature to accept extra kwargs.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant CLI as CLI
  participant Main as main.py
  participant Branch as branch.check_branch
  participant Author as author.check_author
  participant Commit as commit.check_*

  Note over CLI,Main: Optional piped STDIN (branch/author/commit message)
  CLI->>Main: invoke commit-check (with or without STDIN)
  Main->>Main: read non-interactive STDIN -> stdin_text or None
  Main->>Branch: check_branch(checks, stdin_text)
  Branch-->>Main: result
  Main->>Author: check_author(checks, which, stdin_text)
  Author-->>Main: result
  Main->>Commit: check_commit_msg(..., stdin_text)
  Commit-->>Main: result
  Main->>Commit: check_commit_signoff(..., stdin_text)
  Commit-->>Main: result
  Main->>Commit: check_imperative(..., stdin_text)
  Commit-->>Main: result
  Main-->>CLI: aggregate exit code
Loading
sequenceDiagram
  participant Check as check_*
  participant Repo as Git/Files

  alt stdin_text provided
    Note right of Check: Use stdin_text directly (no repo/file I/O)
    Check--x Repo: skip has_commits()/file reads
    Check-->>Check: apply regex/validation
  else stdin_text is None
    Check->>Repo: perform has_commits()/read files/derive values
    Check-->>Check: apply regex/validation
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related issues

Possibly related PRs

Suggested labels

minor

Poem

I tapped the pipe with whisker grace,
A branch, a name, a message trace—
Through stdin’s tunnel, swift and bright,
The checks now read by burrowed light.
Thump-thump! I sign off, ears held high. 🐇✨

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/support-check-stdin

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.

This comment was marked as outdated.

@codecov
Copy link

codecov bot commented Sep 7, 2025

Codecov Report

❌ Patch coverage is 88.09524% with 5 lines in your changes missing coverage. Please review.
✅ Project coverage is 97.80%. Comparing base (8991ac1) to head (611faec).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
commit_check/commit.py 84.21% 3 Missing ⚠️
commit_check/author.py 83.33% 1 Missing ⚠️
commit_check/main.py 92.85% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #272      +/-   ##
==========================================
- Coverage   99.13%   97.80%   -1.33%     
==========================================
  Files           8        8              
  Lines         346      365      +19     
==========================================
+ Hits          343      357      +14     
- Misses          3        8       +5     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@codspeed-hq
Copy link

codspeed-hq bot commented Sep 7, 2025

CodSpeed Performance Report

Merging #272 will improve performances by 29.68%

Comparing feature/support-check-stdin (611faec) with main (8991ac1)

Summary

⚡ 1 improvements
✅ 106 untouched benchmarks

Benchmarks breakdown

Benchmark BASE HEAD Change
test_check_imperative_different_check_type 967.4 µs 746 µs +29.68%

Copy link
Contributor

@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: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
commit_check/commit.py (1)

97-105: Bug: get_commit_info('H') runs even with stdin override (no repo).

When stdin_text is provided, this still calls Git to fetch the hash, which can fail outside a repo. Avoid Git calls in stdin mode.

-            commit_hash = get_commit_info("H")
+            commit_hash = get_commit_info("H") if stdin_text is None else "N/A"
♻️ Duplicate comments (2)
commit_check/branch.py (1)

17-17: Good fix: guard on None instead of truthiness.

This addresses the prior AttributeError risk noted earlier.

tests/main_test.py (1)

165-177: Fix: invalid keyword passed to mocker.patch (will raise TypeError)

stdin_text is a kwarg to the target function, not to patch(). This breaks test collection/execution. Remove stdin_text=None from patch calls and, if needed, assert on called kwargs instead.

Apply:

-        mocker.patch(
-            "commit_check.commit.check_commit_msg", return_value=message_result, stdin_text=None
-        )
+        mocker.patch("commit_check.commit.check_commit_msg", return_value=message_result)
@@
-        mocker.patch(
-            "commit_check.commit.check_commit_signoff",
-            return_value=commit_signoff_result, stdin_text=None
-        )
+        mocker.patch("commit_check.commit.check_commit_signoff", return_value=commit_signoff_result)
@@
-        mocker.patch("commit_check.branch.check_branch", return_value=branch_result, stdin_text=None)
+        mocker.patch("commit_check.branch.check_branch", return_value=branch_result)
@@
-        mocker.patch(
-            "commit_check.branch.check_merge_base", return_value=merge_base_result, stdin_text=None
-        )
+        mocker.patch("commit_check.branch.check_merge_base", return_value=merge_base_result)
-        mocker.patch("commit_check.commit.check_imperative", return_value=PASS, stdin_text=None)
+        mocker.patch("commit_check.commit.check_imperative", return_value=PASS)

Optional: after main(), verify kwargs for the calls that should have occurred:

for m, expected_calls in [
    (mocker.get_mock("commit_check.commit.check_commit_msg"), check_commit_call_count),
    (mocker.get_mock("commit_check.commit.check_commit_signoff"), check_commit_signoff_call_count),
    (mocker.get_mock("commit_check.branch.check_branch"), check_branch_call_count),
    (mocker.get_mock("commit_check.commit.check_imperative"), check_imperative_call_count),
]:
    if expected_calls:
        assert "stdin_text" in m.call_args.kwargs
🧹 Nitpick comments (7)
commit_check/branch.py (1)

16-18: Clarify behavior for blank/whitespace-only stdin.

Current logic treats any provided stdin (even " \n") as the branch name after strip(), yielding "" and likely failing regex. If prior behavior expected empty stdin to fall back to git branch, consider:

-            branch_name = stdin_text.strip() if stdin_text is not None else get_branch_name()
+            if stdin_text is not None:
+                branch_name = stdin_text.strip()
+                if branch_name == "":
+                    branch_name = get_branch_name()
+            else:
+                branch_name = get_branch_name()
commit_check/author.py (1)

20-27: Harden check_type handling and normalize stdin.

  • Use .strip() on stdin to avoid newline/space mismatches.
  • Make the author name/email selection mutually exclusive and fail loudly on unknown types to avoid UnboundLocalError.
-            if stdin_text is not None:
-                config_value = stdin_text
+            if stdin_text is not None:
+                config_value = stdin_text.strip()
             else:
-                if check_type == "author_name":
-                    format_str = "an"
-                if check_type == 'author_email':
-                    format_str = "ae"
+                if check_type == "author_name":
+                    format_str = "an"
+                elif check_type == "author_email":
+                    format_str = "ae"
+                else:
+                    raise ValueError(f"Unsupported check_type: {check_type}")
                 config_value = str(get_commit_info(format_str))
commit_check/commit.py (3)

31-46: Skip work when no message checks are configured; minor truthiness nit.

  • Add a fast path to avoid reading messages when no 'message' check exists.
  • Prefer a simple truthiness check for commit_msg_file.
 def check_commit_msg(checks: list, commit_msg_file: str = "", stdin_text: Optional[str] = None) -> int:
@@
-    if stdin_text is None and has_commits() is False:
+    if stdin_text is None and has_commits() is False:
         return PASS # pragma: no cover
 
+    # Fast path: if no 'message' check configured, skip reading
+    if not any(c.get('check') == 'message' for c in checks):
+        return PASS
+
     if stdin_text is not None:
         commit_msg = stdin_text
     else:
-        if commit_msg_file is None or commit_msg_file == "":
+        if not commit_msg_file:
             commit_msg_file = get_default_commit_msg_file()
         commit_msg = read_commit_msg(commit_msg_file)

70-81: Add fast path for signoff like imperative.

Avoid reading commit message when no 'commit_signoff' check is present.

 def check_commit_signoff(checks: list, commit_msg_file: str = "", stdin_text: Optional[str] = None) -> int:
@@
-    if stdin_text is not None:
+    # Fast path: if no 'commit_signoff' check configured, skip
+    if not any(c.get('check') == 'commit_signoff' for c in checks):
+        return PASS
+
+    if stdin_text is not None:
         commit_msg = stdin_text
     else:
-        if commit_msg_file is None or commit_msg_file == "":
+        if not commit_msg_file:
             commit_msg_file = get_default_commit_msg_file()
         commit_msg = read_commit_msg(commit_msg_file)

127-129: Consistency nit: use if not commit_msg_file in all three places.

Unify the None/empty checks across functions for readability.

-        if commit_msg_file is None or commit_msg_file == "":
+        if not commit_msg_file:
             commit_msg_file = get_default_commit_msg_file()

Also applies to: 79-80, 43-45

tests/commit_test.py (1)

360-363: LGTM: stdin overrides file read path is not exercised here

This test asserts early-exit on different check type and ensures read_commit_msg isn’t called. Consider adding a separate test that actually exercises the imperative path using stdin_text (e.g., “feat: Add …”) and asserts read_commit_msg is not used.
Example new test (outside this hunk):

def test_check_imperative_uses_stdin_when_provided(mocker):
    checks = [{"check": "imperative", "regex": "", "error": "", "suggest": ""}]
    m_read = mocker.patch("commit_check.commit.read_commit_msg")
    assert check_imperative(checks, None, stdin_text="feat: Add feature") == PASS
    m_read.assert_not_called()
commit_check/main.py (1)

128-130: Deduplicate validate_config call

validate_config is invoked twice; cache the result.

-        config = validate_config(args.config) if validate_config(
-            args.config,
-        ) else DEFAULT_CONFIG
+        _cfg = validate_config(args.config)
+        config = _cfg if _cfg else DEFAULT_CONFIG
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between dc9dd4e and ebae968.

📒 Files selected for processing (6)
  • commit_check/author.py (2 hunks)
  • commit_check/branch.py (1 hunks)
  • commit_check/commit.py (4 hunks)
  • commit_check/main.py (3 hunks)
  • tests/commit_test.py (3 hunks)
  • tests/main_test.py (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (3)
commit_check/author.py (1)
tests/author_test.py (5)
  • test_check_author_with_different_check (73-90)
  • test_check_author_with_different_check (188-205)
  • test_check_author_with_empty_checks (56-70)
  • test_check_author_with_empty_checks (171-185)
  • test_check_author (16-33)
commit_check/branch.py (1)
tests/branch_test.py (4)
  • TestCheckBranch (10-120)
  • test_check_branch_with_empty_checks (32-46)
  • test_check_branch_with_different_check (49-66)
  • test_check_branch (12-29)
tests/main_test.py (1)
tests/author_test.py (7)
  • test_check_author_with_empty_checks (171-185)
  • test_check_author_with_different_check (73-90)
  • test_check_author_with_different_check (188-205)
  • TestAuthor (9-260)
  • test_check_author_with_empty_checks (56-70)
  • TestAuthorEmail (146-260)
  • test_check_author (151-168)
🔇 Additional comments (9)
commit_check/branch.py (1)

3-3: Type hint import looks good.

commit_check/author.py (2)

3-3: Type hint import is fine.


8-11: Gating works as intended for stdin override.

Proceeding when stdin_text is provided and short-circuiting otherwise is correct.

commit_check/commit.py (2)

2-2: Type hint import is fine.


118-121: Nice: fast path prevents unnecessary IO.

tests/commit_test.py (2)

343-345: LGTM: explicit stdin passthrough for merge-commit skip

Passing stdin_text=None keeps behavior unchanged while exercising the new parameter. Looks good.


391-393: LGTM: empty checks short-circuit without file read

Nice guard; verifies no I/O when checks are empty.

tests/main_test.py (1)

178-180: LGTM: author mock tolerates extra kwargs

Accepting **kwargs avoids brittle test failures as signatures evolve.

commit_check/main.py (1)

132-147: LGTM: consistent stdin_text propagation

Passing stdin_text through all relevant checks matches the new API and keeps behavior cohesive.

shenxianpeng and others added 3 commits September 7, 2025 17:48
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Copy link
Contributor

@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: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
commit_check/commit.py (1)

97-105: Bug: avoid git dependency in stdin-only mode for signoff check

When stdin_text is provided (running outside a git repo), get_commit_info("H") can fail. Use a placeholder instead.

Apply:

-            commit_hash = get_commit_info("H")
+            # Avoid git dependency when using stdin-only mode
+            commit_hash = get_commit_info("H") if stdin_text is None else "<stdin>"

Would you like a small test covering check_commit_signoff with stdin_text and no repo?

♻️ Duplicate comments (1)
commit_check/branch.py (1)

16-16: Good fix: guard on None rather than truthiness for stdin_text

stdin_text.strip() if stdin_text is not None correctly handles empty strings and resolves the prior review concern.

🧹 Nitpick comments (3)
commit_check/commit.py (1)

118-125: Optional: fast-exit and truly lazy message loading in imperative check

You always read the commit message even when no imperative rules are configured. Early-return to skip I/O, then keep the existing lazy read. Note: this changes current test expectations (one test asserts a read on empty checks).

 def check_imperative(checks: list, commit_msg_file: str = "", stdin_text: Optional[str] = None) -> int:
     """Check if commit message uses imperative mood."""
     if stdin_text is None and has_commits() is False:
         return PASS # pragma: no cover
+
+    # Fast-exit if no imperative rules configured
+    if not any(c.get('check') == 'imperative' for c in checks):
+        return PASS
@@
-    # Lazily obtain commit message only when needed
-    if stdin_text is not None:
-        commit_msg = stdin_text
-    else:
-        if commit_msg_file is None or commit_msg_file == "":
-            commit_msg_file = get_default_commit_msg_file()
-        commit_msg = read_commit_msg(commit_msg_file)
+    # Lazily obtain commit message only when needed
+    if stdin_text is not None:
+        commit_msg = stdin_text
+    else:
+        if not commit_msg_file:
+            commit_msg_file = get_default_commit_msg_file()
+        commit_msg = read_commit_msg(commit_msg_file)

Also applies to: 126-153

commit_check/main.py (2)

123-124: Remove redundant second dry-run check

There’s already an early return at Line 112.

-    if args.dry_run:
-        return PASS

8-8: Narrow the broad except when capturing stdin

Catching Exception is too wide. Limit to expected I/O errors and add the import.

@@
-import sys
+import sys
+import io
@@
-    except Exception:
+    except (OSError, io.UnsupportedOperation):
         stdin_text = None

Optionally, only read stdin when a stdin-aware check is requested (message, author_*, branch, commit_signoff, imperative) to avoid surprising reads for --merge-base-only runs. Happy to draft a follow-up diff if you want it.

Also applies to: 121-122

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ebae968 and 6593542.

📒 Files selected for processing (4)
  • commit_check/branch.py (1 hunks)
  • commit_check/commit.py (4 hunks)
  • commit_check/main.py (3 hunks)
  • tests/commit_test.py (3 hunks)
🧰 Additional context used
🧬 Code graph analysis (4)
commit_check/branch.py (2)
commit_check/util.py (4)
  • get_branch_name (15-30)
  • print_error_header (128-144)
  • print_error_message (147-159)
  • print_suggestion (162-173)
tests/branch_test.py (3)
  • TestCheckBranch (10-120)
  • test_check_branch_with_empty_checks (32-46)
  • test_check_branch_with_different_check (49-66)
commit_check/main.py (3)
commit_check/commit.py (3)
  • check_commit_msg (31-67)
  • check_commit_signoff (70-110)
  • check_imperative (113-153)
commit_check/author.py (1)
  • check_author (8-39)
commit_check/branch.py (1)
  • check_branch (8-28)
commit_check/commit.py (1)
commit_check/util.py (1)
  • has_commits (33-46)
tests/commit_test.py (1)
commit_check/commit.py (1)
  • check_imperative (113-153)
🪛 Ruff (0.12.2)
commit_check/main.py

121-121: Do not catch blind exception: Exception

(BLE001)

tests/commit_test.py

392-392: Use of assert detected

(S101)


393-393: Use of assert detected

(S101)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (8)
  • GitHub Check: install (3.13, windows-latest)
  • GitHub Check: install (3.10, macos-latest)
  • GitHub Check: install (3.11, windows-latest)
  • GitHub Check: install (3.12, windows-latest)
  • GitHub Check: install (3.10, windows-latest)
  • GitHub Check: install (3.9, macos-latest)
  • GitHub Check: install (3.9, windows-latest)
  • GitHub Check: Run benchmarks
🔇 Additional comments (1)
tests/commit_test.py (1)

343-345: Tests align with new stdin_text API

  • Using stdin_text=None keeps old path intact.
  • Passing stdin_text="..." ensures no file read.
  • Empty-checks case documents current behavior (read occurs); if you adopt the fast-exit refactor, update this assertion.

Also applies to: 360-363, 391-394

@shenxianpeng shenxianpeng changed the title feat: commit-check support check from stdin feat: commit-check can be supplied directly via STDIN Sep 7, 2025
Copy link
Contributor

@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: 1

🧹 Nitpick comments (3)
commit_check/author.py (3)

26-28: Treat blank stdin as “not provided” and trim inputs

Whitespace-only stdin currently forces validation of an empty string. Prefer trimming and falling back to git-derived value when stdin is blank; also strip git value to avoid newline artifacts.

-    if stdin_text is None and has_commits() is False:
+    if (stdin_text is None || (isinstance(stdin_text, str) and not stdin_text.strip())) and has_commits() is False:
         return PASS # pragma: no cover
@@
-    if stdin_text is not None:
-        value = stdin_text
-    else:
-        value = _get_author_value(check_type)
+    if stdin_text is not None and stdin_text.strip():
+        value = stdin_text.strip()
+    else:
+        value = _get_author_value(check_type).strip()

Also applies to: 40-43


35-38: Polish user-facing message

Small grammar fix for clarity.

-        print(f"{YELLOW}Not found regex for {check_type}. skip checking.{RESET_COLOR}")
+        print(f"{YELLOW}No regex found for {check_type}; skipping.{RESET_COLOR}")

45-45: Use fullmatch to prevent partial matches

re.match allows prefix matches; fullmatch enforces complete validation (useful for strict author name/email formats).

-    if re.match(regex, value):
+    if re.fullmatch(regex, value):
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6593542 and 3561e64.

📒 Files selected for processing (4)
  • commit_check/author.py (3 hunks)
  • commit_check/branch.py (2 hunks)
  • commit_check/commit.py (6 hunks)
  • tests/commit_test.py (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • commit_check/commit.py
  • commit_check/branch.py
  • tests/commit_test.py
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-09-07T15:16:47.288Z
Learnt from: CR
PR: commit-check/commit-check#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-07T15:16:47.288Z
Learning: Ensure author information in commits is valid: proper author name and email formats

Applied to files:

  • commit_check/author.py
🧬 Code graph analysis (1)
commit_check/author.py (1)
commit_check/util.py (1)
  • has_commits (54-67)
🪛 Ruff (0.12.2)
commit_check/author.py

25-25: SyntaxError: Got unexpected token ,

🪛 GitHub Actions: main
commit_check/author.py

[error] 25-25: Sphinx configuration error: invalid character ',' (U+FF0C) found in author.py at line 25.

🔇 Additional comments (1)
commit_check/author.py (1)

3-3: Import Optional — LGTM

Type import is correct and scoped to the new param.

@shenxianpeng shenxianpeng changed the title feat: commit-check can be supplied directly via STDIN feat: commit-check support reads piped STDIN Sep 9, 2025
@shenxianpeng shenxianpeng requested a review from Copilot September 9, 2025 11:53
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR adds support for reading piped STDIN input to the commit-check CLI tool, allowing validations to run without requiring a Git repository. The implementation enables commit message, author information, and branch name checks to accept values via STDIN while maintaining backward compatibility with existing file-based workflows.

Key changes:

  • Enhanced CLI to capture and forward STDIN input to validation functions
  • Updated all check functions to accept optional stdin_text parameter
  • Modified Git repository dependency logic to allow STDIN-driven validation

Reviewed Changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
commit_check/main.py Added STDIN capture logic and modified all check function calls to pass stdin_text parameter
commit_check/commit.py Updated commit validation functions to accept and use stdin_text when provided
commit_check/branch.py Modified branch check to use stdin_text for branch name validation
commit_check/author.py Enhanced author validation to support stdin_text input
tests/main_test.py Updated test mocks to include new stdin_text parameter
tests/commit_test.py Modified test calls to include stdin_text parameter
.pre-commit-config.yaml Updated ruff version and removed requirements-txt-fixer hook

return PASS

branch_name = get_branch_name()
branch_name = stdin_text.strip() if stdin_text is not None else get_branch_name()
Copy link

Copilot AI Sep 9, 2025

Choose a reason for hiding this comment

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

This line will raise an AttributeError if stdin_text is an empty string, since empty strings are not None but calling .strip() on None would fail. Should check for both None and empty string: stdin_text.strip() if stdin_text else get_branch_name()

Suggested change
branch_name = stdin_text.strip() if stdin_text is not None else get_branch_name()
branch_name = stdin_text.strip() if stdin_text is not None and stdin_text.strip() != "" else get_branch_name()

Copilot uses AI. Check for mistakes.
@sonarqubecloud
Copy link

sonarqubecloud bot commented Sep 9, 2025

@shenxianpeng shenxianpeng added this to the v1.0.0 release milestone Sep 9, 2025
@shenxianpeng shenxianpeng merged commit a673de4 into main Sep 9, 2025
27 of 29 checks passed
@shenxianpeng shenxianpeng deleted the feature/support-check-stdin branch September 9, 2025 13:30
@coderabbitai coderabbitai bot mentioned this pull request Oct 6, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants