Skip to content

Make compilation database search more robust#323

Open
alcxpr wants to merge 4 commits intoclice-io:mainfrom
alcxpr:main
Open

Make compilation database search more robust#323
alcxpr wants to merge 4 commits intoclice-io:mainfrom
alcxpr:main

Conversation

@alcxpr
Copy link
Copy Markdown

@alcxpr alcxpr commented Dec 15, 2025

Fix #223.

Summary by CodeRabbit

  • New Features

    • Compile commands auto-discovery: if no compile-commands paths are configured, the system now scans the workspace root and immediate subdirectories for compile_commands.json.
    • Default configuration change: the default list of compile-commands directories is now empty, causing auto-discovery to trigger unless paths are provided.
  • Tests

    • Added integration tests validating auto-discovery and command parsing.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Dec 15, 2025

Walkthrough

The default compile_commands search path was changed from ${workspace}/build to empty, and auto-discovery logic was added to locate compile_commands.json in the workspace root and its immediate subdirectories when no directories are configured. A unit test for the auto-discovery was added.

Changes

Cohort / File(s) Change Summary
Default Configuration Update
include/Server/Config.h
Changed default initializer of ProjectOptions::compile_commands_dirs from {"${workspace}/build"} to {} (empty vector).
Auto-Discovery Implementation
src/Server/Lifecycle.cpp
Added static std::vector<std::string> find_compile_commands(llvm::StringRef workspace) with internal linkage; updated on_initialize() to use auto-discovery when compile_commands_dirs is empty; added includes for filesystem/LLVM headers and error handling adjustments.
Integration Test
tests/unit/Compiler/CommandTests.cpp
Added AutoDiscoveryIntegration test creating a temporary workspace and compile_commands.json, loading the compile database and asserting parsed command args; added <fstream> and <llvm/Support/FileSystem.h> includes.

Sequence Diagram(s)

sequenceDiagram
    participant Client as Editor/Client
    participant Server as Language Server
    participant FS as FileSystem
    participant DB as CompileDatabaseLoader

    Client->>Server: initialize / open workspace
    Server->>Server: check config.project.compile_commands_dirs
    alt compile_commands_dirs non-empty
        Server->>FS: read each configured directory
        FS-->>Server: paths to compile_commands.json
    else empty (auto-discovery)
        Server->>FS: scan workspace root and immediate subdirs for compile_commands.json
        FS-->>Server: discovered compile_commands.json paths
    end
    Server->>DB: load discovered compile_commands.json files
    DB-->>Server: parsed compile commands
    Server->>Client: initialization complete (with compile DB loaded)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Review find_compile_commands() for correctness: directory traversal limits, symlink handling, permission/IO error cases.
  • Verify on_initialize() correctly prefers configured dirs when provided and falls back only when empty.
  • Inspect the new unit test for duplication (appears inserted twice) and proper cleanup of temp files.

Poem

🐰
I sniff the root with eager nose,
No build/ path to tell me where it goes.
I hop through folders, soft and round,
Find compile commands upon the ground.
Joyful paws — the code is found! 🥕✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately captures the main change: making compilation database search more robust by auto-discovering compile_commands.json instead of just defaulting to build/.
Linked Issues check ✅ Passed The PR directly addresses issue #223 by implementing auto-discovery of compile_commands.json at workspace root and subdirectories, allowing detection beyond just the build/ directory.
Out of Scope Changes check ✅ Passed All changes are scope-aligned: default value removal, auto-discovery implementation in Lifecycle.cpp, and integration tests for the new functionality.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 635d740 and 367f323.

📒 Files selected for processing (1)
  • src/Server/Lifecycle.cpp (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/Server/Lifecycle.cpp
⏰ 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). (7)
  • GitHub Check: build (ubuntu-24.04, Debug, clang-20, clang++-20)
  • GitHub Check: build (windows-2025, RelWithDebInfo, clang, clang++)
  • GitHub Check: build (ubuntu-24.04, debug)
  • GitHub Check: build (macos-15, debug)
  • GitHub Check: build (ubuntu-24.04, releasedbg)
  • GitHub Check: build (macos-15, releasedbg)
  • GitHub Check: build (windows-2025, releasedbg)

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

🧹 Nitpick comments (5)
tests/unit/Compiler/CommandTests.cpp (2)

1-10: Check that filesystem helper headers expose fs and path::join here

AutoDiscoveryIntegration uses fs::create_directories, fs::remove, and path::join, but this TU only directly includes <llvm/Support/FileSystem.h> and not "Support/FileSystem.h". If fs / path are only brought in via that project header (e.g., namespace path { ... join(...) }, aliasing llvm::sys), this test may be relying on transitive includes from Compiler/Command.h / Compiler/Compilation.h.

Consider explicitly including "Support/FileSystem.h" (or whichever header defines fs and path::join) in this file to avoid fragile transitive dependencies.


239-273: Make AutoDiscoveryIntegration more robust and portable

Nice integration-style check that load_compile_database parses compile_commands.json correctly. Two follow‑ups to consider:

  • The hardcoded "/tmp/clice_autodiscovery_test" is POSIX‑specific and may not work on Windows or constrained environments. Using LLVM’s temp directory helpers (e.g., llvm::sys::fs::createUniqueDirectory with system_temp_directory) or a project helper would make the test portable.
  • Cleanup currently happens only on the happy path at the end of the test. Using llvm::make_scope_exit (already included via ScopeExit.h) to fs::remove the file and directory would keep /tmp tidy even if an assertion fails midway.

These are test-only, so non‑blocking, but will improve reliability across platforms and runs.

src/Server/Lifecycle.cpp (2)

10-28: Auto-discovery logic looks correct; consider minimal error handling/logging

The find_compile_commands implementation correctly:

  • Checks ${workspace}/compile_commands.json first.
  • Iterates immediate subdirectories and looks for compile_commands.json in each, using path::join and fs::directory_iterator.

Functionally this satisfies the issue: it will find both ${workspace}/compile_commands.json and ${workspace}/build/compile_commands.json (and similar).

Two small, non‑blocking ideas:

  • If fs::directory_iterator sets ec (e.g., permission issues), we currently just stop scanning silently. A debug‑level log when ec is set would make diagnosing discovery issues easier.
  • If multiple compile_commands.json files are found, we silently load all. If order matters, documenting that “all discovered DBs are loaded, in directory iteration order” would help future readers.

No correctness blockers here.


64-72: New on_initialize behavior aligns with auto-discovery goal

The split logic:

  • When config.project.compile_commands_dirs is empty, call find_compile_commands(workspace) and load_compile_database on each discovered file.
  • When it’s non‑empty, preserve previous behavior and load path::join(dir, "compile_commands.json") for each configured directory.

This:

  • Keeps explicit compile_commands_dirs behavior intact.
  • Extends default behavior from just ${workspace}/build to root + all immediate subdirectories, covering ./compile_commands.json as requested.

One minor improvement to consider: if auto‑discovery finds nothing, a warning log (e.g., “no compile_commands.json found under workspace; semantic features may be degraded”) would make misconfiguration more obvious to users.

Otherwise this looks good.

include/Server/Config.h (1)

24-24: Defaulting compile_commands_dirs to empty is reasonable with auto-discovery in place

Changing the default from {"${workspace}/build"} to {} is consistent with the new auto‑discovery logic in Server::on_initialize: an empty vector triggers scanning of the workspace root and immediate subdirectories, which still includes ${workspace}/build while adding support for ./compile_commands.json.

You may want to ensure any user‑facing configuration docs mention that:

  • Leaving compile_commands_dirs unset/empty enables auto‑discovery, and
  • Setting it explicitly disables auto‑discovery in favor of the configured directories.

From a code perspective, the new default is fine.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between cec13ec and 635d740.

📒 Files selected for processing (3)
  • include/Server/Config.h (1 hunks)
  • src/Server/Lifecycle.cpp (2 hunks)
  • tests/unit/Compiler/CommandTests.cpp (2 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
src/Server/Lifecycle.cpp (1)
include/Support/FileSystem.h (1)
  • path (15-24)
⏰ 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: build (windows-2025, RelWithDebInfo, clang, clang++)
  • GitHub Check: build (macos-15, debug)
  • GitHub Check: build (macos-15, Debug, clang, clang++)
  • GitHub Check: build (ubuntu-24.04, Debug, clang-20, clang++-20)
  • GitHub Check: build (macos-15, releasedbg)
  • GitHub Check: build (ubuntu-24.04, releasedbg)
  • GitHub Check: build (ubuntu-24.04, debug)
  • GitHub Check: build (windows-2025, releasedbg)

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.

Clice didn't use the compile_commands.json in the root directory

1 participant