Skip to content

fix: do not change directory to repo-root#349

Open
2bndy5 wants to merge 6 commits into
mainfrom
no-chdir
Open

fix: do not change directory to repo-root#349
2bndy5 wants to merge 6 commits into
mainfrom
no-chdir

Conversation

@2bndy5

@2bndy5 2bndy5 commented Jun 10, 2026

Copy link
Copy Markdown
Collaborator

ref:

Let cpp-linter stay in working directory. Instead of changing into the given --repo-root, this patch uses the value as a scope of file system focus.

  • All clang tools are invoked in the given --repo-root.
  • All discovered files are stripped of --repo-root
  • Any local caching done is prefixed with --repo-root value.

--repo-root value has always been expected as a relative path, but this should also work if given an absolute path too.

Summary by CodeRabbit

  • Bug Fixes

    • More reliable repository-root handling so file operations and tooling run consistently across different project layouts.
    • Cache is now stored under the repository to avoid misplaced cache files and ensure predictable behavior.
  • Refactor

    • Path resolution and tooling invocations were reorganized to be repo-root–relative, improving consistency and test stability.

@2bndy5 2bndy5 added the bug Something isn't working label Jun 10, 2026
@codecov

codecov Bot commented Jun 10, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 85.24590% with 9 lines in your changes missing coverage. Please review.
✅ Project coverage is 92.43%. Comparing base (1089800) to head (9b74fbd).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
cpp-linter/src/clang_tools/clang_format.rs 42.85% 4 Missing ⚠️
cpp-linter/src/clang_tools/clang_tidy.rs 73.33% 4 Missing ⚠️
cpp-linter/src/clang_tools/mod.rs 83.33% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #349      +/-   ##
==========================================
- Coverage   92.85%   92.43%   -0.42%     
==========================================
  Files          22       21       -1     
  Lines        3316     3226      -90     
==========================================
- Hits         3079     2982      -97     
- Misses        237      244       +7     

☔ View full report in Codecov by Harness.
📢 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.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@2bndy5

2bndy5 commented Jun 10, 2026

Copy link
Copy Markdown
Collaborator Author

This seemed easier than I thought it would be. Let's see what the AI review thinks...

@2bndy5 2bndy5 marked this pull request as ready for review June 10, 2026 13:08
@coderabbitai

coderabbitai Bot commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

This PR threads a repo_root PathBuf through CLI params, RestClient, FileObj suggestion generation, and clang tool invocations; clang-format/tidy now run with CWD=repo_root and caches/IO use repo_root.join(CACHE_DIR) and repo_root.join(file.name) rather than relying on process CWD or a derived project cache dir.

Changes

Repository Root Path Propagation

Layer / File(s) Summary
Type contracts and API signatures
cpp-linter/src/clang_tools/mod.rs, cpp-linter/src/cli/structs.rs, cpp-linter/src/rest_client/mod.rs
Add pub const CACHE_DIR; replace ClangParams.project_cache_dir with repo_root: PathBuf; add repo_root: &Path parameter to RestClient::get_list_of_changed_files and update constructors/defaults.
RestClient path relativization and suggestion wiring
cpp-linter/src/rest_client/mod.rs, cpp-linter/src/common_fs/mod.rs
Construct FileObj paths by stripping repo_root prefix when possible; thread repo_root into FileObj::make_suggestions_from_patch calls.
Main execution flow and cache setup
cpp-linter/src/run.rs
Stop changing process CWD for --repo-root; derive repo_root_path once, pass it into changed-files calls and directory walking; compute cache dir at repo_root.join(CACHE_DIR) and write .gitignore there.
clang-format working directory and file resolution
cpp-linter/src/clang_tools/clang_format.rs
Set clang-format process CWD to clang_params.repo_root; compute format-patches cache at clang_params.repo_root.join(CACHE_DIR).join("patches"); read original file content from repo_root.join(&file.name).
clang-tidy working directory, parsing, and patch restore
cpp-linter/src/clang_tools/clang_tidy.rs
Refactor parse_tidy_output to take repo_root: &Path; set clang-tidy CWD to clang_params.repo_root; normalize filenames and restore patched files using repo-root-relative paths; update tests to pass PathBuf::from(".") as repo_root.
FileObj suggestion IO
cpp-linter/src/common_fs/mod.rs
FileObj::make_suggestions_from_patch now accepts repo_root: &Path and reads original contents from repo_root.join(&self.name).
Tests and helpers
cpp-linter/tests/*, cpp-linter/src/git.rs, cpp-linter/tests/common/mod.rs
Update test helpers to accept a TempDir and pass --repo-root=<tmpdir> to run_main instead of changing process CWD; adjust temp dir creation prefix and meson command status handling.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title 'fix: do not change directory to repo-root' directly and clearly describes the main change: refactoring how repo-root is handled by eliminating directory changes.
Docstring Coverage ✅ Passed Docstring coverage is 100.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 docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch no-chdir

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.

@coderabbitai coderabbitai Bot left a comment

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.

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 `@cpp-linter/src/rest_client/mod.rs`:
- Around line 76-81: RestClient::get_list_of_changed_files currently constructs
FileObj.name as a repo-root-relative path via
FileObj::from(...strip_prefix(repo_root)...), which causes
FileObj::make_suggestions_from_patch and clang_tidy::run_clang_tidy to fail
because they call fs::read/_write using that relative name while the process cwd
is not repo_root; fix by making file access use repo_root.join(&file.name) (or
store absolute paths in FileObj.name) — update FileObj::from (used by
RestClient::get_list_of_changed_files) or ensure all reads/writes in
FileObj::make_suggestions_from_patch (cpp-linter/src/common_fs/mod.rs) and
clang_tidy::run_clang_tidy (cpp-linter/src/clang_tools/clang_tidy.rs) prepend
clang_params.repo_root/appropriate repo_root PathBuf via join before calling
fs::read, fs::write, or any file APIs so behaviour matches clang_format which
already uses clang_params.repo_root.join(&file.name).
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 291ffd5c-14ca-44fc-a032-30bdee4b61c4

📥 Commits

Reviewing files that changed from the base of the PR and between 1089800 and a395b75.

📒 Files selected for processing (8)
  • cpp-linter/src/clang_tools/clang_format.rs
  • cpp-linter/src/clang_tools/clang_tidy.rs
  • cpp-linter/src/clang_tools/mod.rs
  • cpp-linter/src/cli/structs.rs
  • cpp-linter/src/git.rs
  • cpp-linter/src/rest_client/mod.rs
  • cpp-linter/src/run.rs
  • cpp-linter/tests/paginated_changed_files.rs

Comment thread cpp-linter/src/rest_client/mod.rs

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 1

🧹 Nitpick comments (2)
cpp-linter/tests/common/mod.rs (1)

51-54: 💤 Low value

Lost diagnostic output when Meson commands fail.

The change from .output() to .status() discards stdout/stderr. If meson init or meson setup fails, developers will only see the generic panic message without the command's actual error output, making failures harder to debug.

🔧 Proposed fix to preserve diagnostic output
-    let status = cmd.status().expect("Failed to run 'meson init'");
-    if !status.success() {
-        panic!("Failed to initialize meson project with 'meson init'");
-    }
+    let output = cmd.output().expect("Failed to run 'meson init'");
+    if !output.status.success() {
+        panic!(
+            "Failed to initialize meson project with 'meson init':\n{}",
+            String::from_utf8_lossy(&output.stderr)
+        );
+    }

Apply the same pattern to the meson setup command:

-    let status = cmd
-        .status()
-        .expect("Failed to generate build assets with 'meson setup'");
-    if !status.success() {
-        panic!("Failed to generate build assets with 'meson setup'");
-    }
+    let output = cmd
+        .output()
+        .expect("Failed to generate build assets with 'meson setup'");
+    if !output.status.success() {
+        panic!(
+            "Failed to generate build assets with 'meson setup':\n{}",
+            String::from_utf8_lossy(&output.stderr)
+        );
+    }

Also applies to: 63-68

🤖 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 `@cpp-linter/tests/common/mod.rs` around lines 51 - 54, The tests currently
call cmd.status() for the "meson init" (and similarly for "meson setup")
commands which discards stdout/stderr; change these to use cmd.output(), check
output.status.success(), and include output.stdout and output.stderr in the
panic/error message so failing meson invocations show diagnostic output; update
the blocks that create/run the command (the occurrences that set status from cmd
and panic on failure) to capture and print the command's stdout/stderr for both
"meson init" and "meson setup".
cpp-linter/src/clang_tools/clang_tidy.rs (1)

300-300: 💤 Low value

Consider using .join() for consistency with clang_format.rs.

The equivalent path construction in clang_format.rs (line 127) uses clang_params.repo_root.join(&file.name). Using the same idiom here improves consistency across the codebase.

Suggested change
-    let repo_file_path = PathBuf::from_iter([&clang_params.repo_root, &file.name]);
+    let repo_file_path = clang_params.repo_root.join(&file.name);
🤖 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 `@cpp-linter/src/clang_tools/clang_tidy.rs` at line 300, Replace the
PathBuf::from_iter construction used to build repo_file_path with the same join
idiom used in clang_format.rs for consistency: use
clang_params.repo_root.join(&file.name) when creating repo_file_path (symbols to
update: repo_file_path, clang_params, file.name in clang_tidy.rs).
🤖 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 `@cpp-linter/tests/paginated_changed_files.rs`:
- Line 39: The test get_paginated_changes has an incomplete refactor: remove the
unused internal TempDir and any env::set_current_dir calls, stop creating a new
TempDir inside the helper, and use the passed _tmp_dir (rename to tmp_dir if you
remove the underscore) throughout; specifically, replace uses of tmp.path() and
&PathBuf::from(".") with tmp_dir.path(), add the repo-root arg using
tmp_dir.path() (e.g. --repo-root=<tmp_dir.path()>), and update event_payload
construction to use tmp_dir.path() so the helper and get_paginated_changes
mirror the patterns in comments.rs and reviews.rs.

---

Nitpick comments:
In `@cpp-linter/src/clang_tools/clang_tidy.rs`:
- Line 300: Replace the PathBuf::from_iter construction used to build
repo_file_path with the same join idiom used in clang_format.rs for consistency:
use clang_params.repo_root.join(&file.name) when creating repo_file_path
(symbols to update: repo_file_path, clang_params, file.name in clang_tidy.rs).

In `@cpp-linter/tests/common/mod.rs`:
- Around line 51-54: The tests currently call cmd.status() for the "meson init"
(and similarly for "meson setup") commands which discards stdout/stderr; change
these to use cmd.output(), check output.status.success(), and include
output.stdout and output.stderr in the panic/error message so failing meson
invocations show diagnostic output; update the blocks that create/run the
command (the occurrences that set status from cmd and panic on failure) to
capture and print the command's stdout/stderr for both "meson init" and "meson
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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: ec802b89-c7de-497c-baf3-f795a7061a57

📥 Commits

Reviewing files that changed from the base of the PR and between a395b75 and e80aa10.

📒 Files selected for processing (10)
  • cpp-linter/src/clang_tools/clang_tidy.rs
  • cpp-linter/src/cli/structs.rs
  • cpp-linter/src/common_fs/mod.rs
  • cpp-linter/src/git.rs
  • cpp-linter/src/rest_client/mod.rs
  • cpp-linter/src/run.rs
  • cpp-linter/tests/comments.rs
  • cpp-linter/tests/common/mod.rs
  • cpp-linter/tests/paginated_changed_files.rs
  • cpp-linter/tests/reviews.rs
🚧 Files skipped from review as they are similar to previous changes (2)
  • cpp-linter/src/git.rs
  • cpp-linter/src/run.rs

Comment thread cpp-linter/tests/paginated_changed_files.rs Outdated
2bndy5 added 6 commits June 10, 2026 20:27
ref:
- cpp-linter/cpp-linter#144
- cpp-linter/cpp-linter#146

Let cpp-linter stay in working directory. Instead of changing into the given `--repo-root`, this patch uses the value as a scope of file system focus.

- All clang tools are invoked in the given `--repo-root`.
- All discovered files are stripped of `--repo-root`
- Any local caching done is prefixed with `--repo-root` value.

`--repo-root` value has always been expected sa a relative path, but this should also work if given an absolute path too.

@coderabbitai coderabbitai Bot left a comment

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.

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 `@cpp-linter/src/clang_tools/mod.rs`:
- Around line 143-151: The code builds the compile_commands.json path by joining
db_path twice when db_path.is_relative() (resulting in
<repo_root>/<db_path>/<db_path>/compile_commands.json); fix this in the fs::read
call in clang_tools/mod.rs by first computing a single base path (let base = if
db_path.is_relative() { clang_params.repo_root.join(db_path) } else {
db_path.to_path_buf() }) and then calling base.join("compile_commands.json")
(remove the extra .join(db_path)), ensuring the code that reads/opens the DB
uses that corrected base path.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 56ed8a21-4ff5-460f-b9be-e4d93a4f0ae3

📥 Commits

Reviewing files that changed from the base of the PR and between e80aa10 and 9b74fbd.

📒 Files selected for processing (12)
  • cpp-linter/src/clang_tools/clang_format.rs
  • cpp-linter/src/clang_tools/clang_tidy.rs
  • cpp-linter/src/clang_tools/mod.rs
  • cpp-linter/src/cli/structs.rs
  • cpp-linter/src/common_fs/mod.rs
  • cpp-linter/src/git.rs
  • cpp-linter/src/rest_client/mod.rs
  • cpp-linter/src/run.rs
  • cpp-linter/tests/comments.rs
  • cpp-linter/tests/common/mod.rs
  • cpp-linter/tests/paginated_changed_files.rs
  • cpp-linter/tests/reviews.rs
🚧 Files skipped from review as they are similar to previous changes (9)
  • cpp-linter/tests/common/mod.rs
  • cpp-linter/src/common_fs/mod.rs
  • cpp-linter/src/clang_tools/clang_format.rs
  • cpp-linter/tests/comments.rs
  • cpp-linter/src/rest_client/mod.rs
  • cpp-linter/tests/reviews.rs
  • cpp-linter/src/clang_tools/clang_tidy.rs
  • cpp-linter/src/run.rs
  • cpp-linter/src/cli/structs.rs

Comment on lines +143 to +151
&& let Ok(db_str) = fs::read(
if db_path.is_relative() {
clang_params.repo_root.join(db_path)
} else {
db_path.to_path_buf()
}
.join(db_path)
.join("compile_commands.json"),
)

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.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Relative compile database paths are joined twice.

For relative clang_params.database, the code builds <repo_root>/<db_path>/<db_path>/compile_commands.json, so DB parsing is skipped unexpectedly and tidy filename mapping can degrade.

Suggested fix
-    if let Some(db_path) = &clang_params.database
-        && let Ok(db_str) = fs::read(
-            if db_path.is_relative() {
-                clang_params.repo_root.join(db_path)
-            } else {
-                db_path.to_path_buf()
-            }
-            .join(db_path)
-            .join("compile_commands.json"),
-        )
+    if let Some(db_path) = &clang_params.database
+        && let Ok(db_str) = fs::read(
+            (if db_path.is_relative() {
+                clang_params.repo_root.join(db_path)
+            } else {
+                db_path.to_path_buf()
+            })
+            .join("compile_commands.json"),
+        )
🤖 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 `@cpp-linter/src/clang_tools/mod.rs` around lines 143 - 151, The code builds
the compile_commands.json path by joining db_path twice when
db_path.is_relative() (resulting in
<repo_root>/<db_path>/<db_path>/compile_commands.json); fix this in the fs::read
call in clang_tools/mod.rs by first computing a single base path (let base = if
db_path.is_relative() { clang_params.repo_root.join(db_path) } else {
db_path.to_path_buf() }) and then calling base.join("compile_commands.json")
(remove the extra .join(db_path)), ensuring the code that reads/opens the DB
uses that corrected base path.

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

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant