Skip to content

fix(rules): allow ocr rules check in non-git directories - #1705

Open
akushonkamen wants to merge 1 commit into
alibaba:mainfrom
akushonkamen:fix/1704-rules-check-nogit
Open

akushonkamen wants to merge 1 commit into
alibaba:mainfrom
akushonkamen:fix/1704-rules-check-nogit

Conversation

@akushonkamen

Copy link
Copy Markdown

Description

ocr rules check failed fast in any directory that is not a git repository (Error: <dir> is not a git repository), even though rule resolution itself has no git dependency. The git requirement was an artifact of the command reusing the review path's directory resolver:

  • runRulesCheck calls resolveRepoDir (cmd/opencodereview/rules_cmd.go:46), which delegated to resolveWorkingDir(input, true) — requireGit hardcoded to true, which is the review path's semantics where the diff concept requires git (cmd/opencodereview/review_cmd.go:457-460 before this change).
  • But the rules resolver is then invoked with rules.ResolverOptions{} (cmd/opencodereview/rules_cmd.go:51), so Ref is empty and the sniffer reads file content from the working tree via os.Open (internal/config/rules/sniffer.go:99 ref gate; the git show branch at sniffer.go:120-134 never triggers without a ref).

This change resolves the rules-check directory with requireGit=false, matching the existing scan (cmd/opencodereview/shared.go:104-105) and session (cmd/opencodereview/session_cmd.go:623-628) precedents. Inside a git repo, resolveRepoDir still anchors at the git top-level (git rev-parse --show-toplevel), so rule resolution stays consistent with the review path when run from a monorepo subdirectory (#287); bare repos keep failing loudly instead of silently reusing the subdirectory.

Single-function change in cmd/opencodereview/review_cmd.go, plus tests: two behavior-locked tests flipped to the corrected behavior and two new guard tests added for the non-git case (cmd/opencodereview/git_test.go, cmd/opencodereview/rules_check_test.go).

Type of Change

  • Bug fix (non-breaking change that fixes an issue)

How Has This Been Tested?

  • make test passes locally (race enabled; Go 1.26.9, macOS arm64): 24 packages ok, 0 FAIL
  • Manual testing (described below)

Red/green: with the one-function fix reverted and the new tests kept, go test ./cmd/opencodereview/ -run 'TestResolveRepoDir|TestRunRulesCheck' -count=1 fails exactly the two new assertions (TestResolveRepoDir_NotGitRepo, TestRunRulesCheck/non-git_repo_dir_still_resolves_(#1704)); with the fix applied the same command passes 12/12, and the full cmd/opencodereview suite reports 839 top-level tests passed / 0 failed (~21s, plus 546 subtests). go build ./... and make check (license headers, English-only, go mod tidy, gofmt, go vet) pass with a clean working tree.

End-to-end with the locally built CLI:

  • Non-git directory: ocr rules check --repo /tmp/nogit foo.java printed Error: /tmp/nogit is not a git repository and exited 1 before the fix; after the fix it exits 0 and prints the matching System built-in rule.
  • Git repo root and monorepo subdirectory: pre-fix and post-fix binaries produce byte-identical output for both, so the file_read call failures in a monorepo #287 top-level anchoring and existing behavior are preserved.

Notes: the ocr review --audience agent pre-commit review command suggested in AGENTS.md was attempted with the locally built CLI but could not resolve an LLM endpoint because none is configured in this environment. Module downloads went through GOPROXY=https://goproxy.cn because proxy.golang.org was unreachable from this network.

Checklist

  • My code follows the project's coding style (go fmt, go vet)
  • I have performed a self-review of my code
  • I have added tests that prove my fix is effective or my feature works
  • New and existing unit tests pass locally with my changes
  • I have updated the documentation accordingly (if applicable)
  • I have signed the CLA
  • I did not use AI/LLM to create this PR, or I disclosed the tool/model below and reviewed its output; I did not attribute commits to AI and will answer maintainer questions and review comments myself without AI/LLM.

AI/LLM disclosure: this fix was produced with AI assistance on behalf of @akushonkamen, as already disclosed on issue #1704 — triage and root-cause analysis with Claude Code, and the patch, tests, and pre-submission validation prepared with Claude Code and a GLM (Z.ai) coding agent. The commit carries no AI attribution.

Related Issues

Fixes #1704

)

resolveRepoDir delegated to resolveWorkingDir(requireGit=true), so
`ocr rules check` failed fast outside a git repo even though rule
resolution has no git dependency: with ResolverOptions{} the ref is
empty and the sniffer reads the working tree via os.Open, never via
git show. The git gate was an artifact of reusing the review path's
resolver.

Resolve with requireGit=false (matching the scan/session precedents),
but keep anchoring at the git top-level inside a git repo so rule
resolution stays consistent with the review path when run from a
monorepo subdirectory (alibaba#287). Bare repos still fail loudly, as before.
@CLAassistant

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@github-actions

github-actions Bot commented Oct 11, 2026 •

Copy link
Copy Markdown
Contributor

🔍 OpenCodeReview found 1 issue(s) in this PR.

  • ✅ Successfully posted inline: 1 comment(s)

Comment on lines +467 to +472
top, topErr := runGitCmdStdout(absPath, "rev-parse", "--show-toplevel")
t := strings.TrimSpace(string(top))
if topErr != nil || t == "" {
return "", fmt.Errorf("%s is a git repository without a work tree (bare repo?); cannot resolve its top level", absPath)
}
absPath = t

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

maintainability · medium
The bare-repo / top-level resolution logic here is an exact duplicate of what resolveWorkingDir already does when requireGit=true (shared.go:179-191). If that logic is ever updated (e.g., different error message, additional validation), this copy will silently drift.

Consider extracting the "anchor to git top-level" step into a shared helper (e.g., anchorToGitTopLevel(absPath) (string, error)) that both resolveWorkingDir and resolveRepoDir can call. This keeps the non-git passthrough behavior of resolveRepoDir while eliminating the duplication.

This branch has not been deployed

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

rules check功能可以不依赖git

2 participants