Skip to content

Fix detection of Golang project layout#435

Open
mmorhun wants to merge 2 commits into
ambient-code:mainfrom
mmorhun:fix-golang-dir-layout
Open

Fix detection of Golang project layout#435
mmorhun wants to merge 2 commits into
ambient-code:mainfrom
mmorhun:fix-golang-dir-layout

Conversation

@mmorhun
Copy link
Copy Markdown

@mmorhun mmorhun commented May 15, 2026

Assisted-by: Claude

Description

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation update
  • Refactoring (no functional changes)
  • Performance improvement
  • Test coverage improvement

Related Issues

Relates to #378

Changes Made

  • Fix the logic of Golang (and others) project detection: if go.mod (or any other language project files) found in the project root, assume we deal with a project in that language. If none or a few markers found, rely on old logic.
  • Added tests

Testing

  • Unit tests pass (pytest)
  • Integration tests pass
  • Manual testing performed on a local real repos
  • No new warnings or errors

Checklist

  • My code follows the project's code style
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes
  • Any dependent changes have been merged and published

Screenshots (if applicable)

Additional Notes

Before the fix on an Golang k8s operator:

standard_layout                     ❌ FAIL         0/2 directories (need: 2/2 directories)

After the fix:

standard_layout                     ✅ PASS         100/100 

Summary by CodeRabbit

  • Bug Fixes

    • Improved primary-language detection to prefer repositories with definitive root manifests and to resolve JavaScript/TypeScript ties more predictably.
  • Tests

    • Added comprehensive unit tests for primary-language selection covering Go, Python, TypeScript/JavaScript, Java, and Rust manifest and file-count scenarios.
    • Added a Go structure assessment test verifying detection when go.mod and typical Go directories are present.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 15, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Enterprise

Run ID: 154bc942-0449-4695-a3c6-769a20fda555

📥 Commits

Reviewing files that changed from the base of the PR and between 0d09a0b and d4295f2.

📒 Files selected for processing (3)
  • src/agentready/assessors/base.py
  • tests/unit/test_assessors_base.py
  • tests/unit/test_assessors_structure.py
💤 Files with no reviewable changes (1)
  • tests/unit/test_assessors_structure.py

📝 Walkthrough

Walkthrough

BaseAssessor._primary_language() now prefers root-level manifests (expanded mappings include TS and C#), with JS/TS tie-breaks and refined fallbacks. Unit tests and a Go layout integration test validate manifest precedence and file-count fallback behavior.

Changes

Language Primary-Detection Enhancement with Manifest-Based Prioritization

Layer / File(s) Summary
Manifest mapping and primary-language refactor
src/agentready/assessors/base.py
_LANG_ROOT_MANIFESTS expanded (TypeScript now signals via package.json and tsconfig.json; C# adds *.csproj/*.sln). _primary_language() refactored to detect root manifests first, return a unique manifest winner, prefer tsconfig.json when JS+TS both present, and otherwise fall back to repository file-count tie-breaking.
Primary-language unit tests
tests/unit/test_assessors_base.py
Adds ConcreteAssessor test harness and ~12 tests covering Go, Python, TypeScript (with/without tsconfig.json), Java (Maven/Gradle), Rust, multiple-manifest tie-breaking, file-count fallback, non-candidate manifests, and empty-language handling.
Go layout integration test
tests/unit/test_assessors_structure.py
Adds test_go_project_with_gomod_uses_go_assessment which builds a temp repo with go.mod plus cmd//internal/ and asserts StandardLayoutAssessor evidence includes go.mod and cmd/ or internal/.

Possibly Related PRs

Suggested Labels

released

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Title check ⚠️ Warning Title does not follow Conventional Commits format (type(scope): description). Missing 'test' or 'fix' type prefix and parenthetical scope. Update title to Conventional Commits format, e.g., 'fix(assessor): improve detection of Go project layout' or 'test(assessor): add Go project detection tests'.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed Docstring coverage is 85.00% which is sufficient. The required threshold is 80.00%.
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
✨ Simplify code
  • Create PR with simplified code

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

🤖 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 `@tests/unit/test_assessors_structure.py`:
- Around line 908-912: The current assertion using evidence_str is too
permissive; update the check so that when "src/" appears it must be accompanied
by clear Go indicators. Replace the single permissive assert on evidence_str
with logic: if "src/" in evidence_str.lower(): assert "source" not in
evidence_str.lower() and ( "go.mod" in evidence_str.lower() or "module " in
evidence_str.lower() or re.search(r"\bpackage\s+\w+", evidence_str.lower()) ),
otherwise allow evidence_str to omit "src/". This uses the existing evidence_str
variable to ensure "src/" presence actually reflects a Go layout.
🪄 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: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Enterprise

Run ID: 3abdf512-a64f-4f94-b0f6-60dd342d48db

📥 Commits

Reviewing files that changed from the base of the PR and between 312c99a and 984d11e.

📒 Files selected for processing (2)
  • src/agentready/assessors/structure.py
  • tests/unit/test_assessors_structure.py

Comment thread tests/unit/test_assessors_structure.py
@mmorhun mmorhun force-pushed the fix-golang-dir-layout branch from 984d11e to 58a4921 Compare May 15, 2026 08:28
@mmorhun
Copy link
Copy Markdown
Author

mmorhun commented May 15, 2026

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 15, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@mmorhun mmorhun force-pushed the fix-golang-dir-layout branch from 58a4921 to 24981e9 Compare May 19, 2026 11:48
@mmorhun
Copy link
Copy Markdown
Author

mmorhun commented May 19, 2026

Rebased and resolved merge conflicts.

Copy link
Copy Markdown
Contributor

@natifridman natifridman left a comment

Choose a reason for hiding this comment

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

Code Review

Overall: Good bug fix with solid tests. The core idea — using go.mod as a definitive signal instead of file counts — is the right call.

The bug (confirmed valid)

_primary_language() uses file counts with a 30% threshold for tiebreaking. In a Go operator repo with many Python scripts, if Python files outnumber Go by more than 30%, the manifest tiebreaker never fires, and the assessor evaluates Python layout rules (src/ + tests/) against a Go project — guaranteed fail.

The fix

Replacing _primary_language(repository, {"Python", "Go"}) == "Go" with _find_go_module_roots(repository) bypasses the file-count heuristic entirely. go.mod presence is treated as definitive. This is correct — go.mod is the canonical Go project marker.

Concerns

1. Overly broad go.mod detection_find_go_module_roots() finds go.mod at any depth (excluding vendor/testdata). A Python project with a Go tool in a subdirectory (e.g., tools/linter/go.mod) would now route to Go assessment, which is likely wrong. A safer fix might be to check root-level go.mod only:

if (repository.path / "go.mod").exists():
    return self._assess_go_layout(repository)

This still fixes the reported bug (Go operators have go.mod at root) while avoiding false positives from subdirectory Go modules in non-Go projects.

2. Other assessors have the same vulnerability_primary_language() is still used by code_quality.py (lines 62, 445, 719), documentation.py (line 1203), and testing.py (line 59). Those assessors face the same Python-files-outnumber-Go-files issue for the same types of repos. This PR fixes structure.py only. Not a blocker, but worth tracking.

3. Overly complex test assertion — The last assertion block in test_go_project_with_python_scripts_uses_go_assessment (lines ~908-912) is hard to follow and tests a condition that can't actually trigger — the Go assessor doesn't produce evidence containing "src/". The assertion will always be vacuously true. Consider dropping it for clarity, or simplifying to just asserting "source" not in evidence_str.lower().

What's good

  • The bug is real and well-demonstrated (before/after in PR description)
  • Tests cover both the simple case and the exact bug scenario
  • Minimal diff in production code (3 lines changed)

🤖 Generated with Claude Code

Signed-off-by: Mykola Morhun <mmorhun@redhat.com>
Assisted-by: Claude
@mmorhun mmorhun force-pushed the fix-golang-dir-layout branch from 24981e9 to 0d09a0b Compare May 20, 2026 13:30
@mmorhun
Copy link
Copy Markdown
Author

mmorhun commented May 20, 2026

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 20, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

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: 2

🤖 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 `@tests/unit/test_assessors_base.py`:
- Line 30: The test currently shells out to "git init" which is unnecessary for
testing _primary_language(); remove the subprocess.run(["git", "init"], ...)
call and instead stub/mock the code path that queries git: patch the
helper/function that invokes git (the _primary_language() call or the
subprocess.run wrapper it uses) to return the expected language value, or create
the minimal file(s) the function inspects directly so no git command is
executed; apply this same replacement for all other instances of
subprocess.run(["git", "init"], ...) in the file so tests no longer depend on an
external git binary.
- Around line 21-23: The assess method in ConcreteAssessor (def assess(self,
repository: Repository) -> Finding) references self.attribute which doesn't
exist on BaseAssessor; update the method to use the correct attribute name
self.attribute_id when calling Finding.create_pass (or otherwise pass the
intended attribute identifier) so the call uses a defined property and doesn't
raise an AttributeError.
🪄 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: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Enterprise

Run ID: 4cb62baf-5961-4f52-9c37-e8804e3fdbe8

📥 Commits

Reviewing files that changed from the base of the PR and between 24981e9 and 0d09a0b.

📒 Files selected for processing (3)
  • src/agentready/assessors/base.py
  • tests/unit/test_assessors_base.py
  • tests/unit/test_assessors_structure.py

Comment thread tests/unit/test_assessors_base.py
Comment thread tests/unit/test_assessors_base.py Outdated
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 20, 2026

📈 Test Coverage Report

Branch Coverage
This PR 73.7%
Main 73.7%
Diff ✅ +0%

Coverage calculated from unit tests only

Signed-off-by: Mykola Morhun <mmorhun@redhat.com>
Assisted-by: Claude
@mmorhun mmorhun force-pushed the fix-golang-dir-layout branch from 0d09a0b to d4295f2 Compare May 20, 2026 15:59
@mmorhun
Copy link
Copy Markdown
Author

mmorhun commented May 20, 2026

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 20, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

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: 2

🤖 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 `@src/agentready/assessors/base.py`:
- Line 77: The TypeScript entry in the language detection map is being triggered
by package.json alone causing false positives; update the detection logic that
builds the candidates set so that "TypeScript" is only added when tsconfig.json
is present or when .ts/.tsx source files are detected (not when only
package.json exists). Specifically, change the code that uses the mapping
containing "TypeScript": ["package.json", "tsconfig.json"] and the branch that
checks the resulting candidates set (including the block referencing candidates
== {"TypeScript"}) to exclude TypeScript if the only match is package.json, and
mirror the same fix in the second occurrence around the other candidates-check.

In `@tests/unit/test_assessors_base.py`:
- Around line 71-136: Add a regression test that covers the TS-only candidate
edge case: create a new test (e.g.,
test_typescript_only_candidate_without_tsconfig) in
tests/unit/test_assessors_base.py that writes only package.json (no
tsconfig.json), patches Repository.__post_init__ as in the other tests,
constructs a Repository with languages={"TypeScript": N} (no "JavaScript"), and
calls ConcreteAssessor()._primary_language(repo, {"TypeScript"}) and assert it
returns "TypeScript"; use the same Repository construction pattern and patching
used by the surrounding tests to locate the correct setup.
🪄 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: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Enterprise

Run ID: f236282d-2906-493a-a2c0-1e5ad8cf2b75

📥 Commits

Reviewing files that changed from the base of the PR and between 0d09a0b and d4295f2.

📒 Files selected for processing (3)
  • src/agentready/assessors/base.py
  • tests/unit/test_assessors_base.py
  • tests/unit/test_assessors_structure.py
💤 Files with no reviewable changes (1)
  • tests/unit/test_assessors_structure.py

Comment thread src/agentready/assessors/base.py
Comment thread tests/unit/test_assessors_base.py
@mmorhun
Copy link
Copy Markdown
Author

mmorhun commented May 20, 2026

I'll deal with the above next day.

@jwm4 jwm4 self-requested a review May 20, 2026 16:44
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.

2 participants