diff --git a/indexer/CompilationDatabase.cc b/indexer/CompilationDatabase.cc index aaa29ad7..57e3fb10 100644 --- a/indexer/CompilationDatabase.cc +++ b/indexer/CompilationDatabase.cc @@ -535,6 +535,28 @@ compdb::File compdb::File::open(const StdPath &path, if (fileSizeError) { return compdbFile; } + if (validationOptions.tryDetectOutOfProjectRoot) { + auto dirPath = path.lexically_normal(); + while (dirPath.has_parent_path() && dirPath.parent_path() != dirPath) { + dirPath = dirPath.parent_path(); + auto maybeGitDirPath = dirPath / ".git"; + std::error_code error; + auto status = std::filesystem::status(maybeGitDirPath, error); + if (!error && status.type() == std::filesystem::file_type::directory) { + auto cwd = std::filesystem::current_path(); + if (cwd != dirPath) { + spdlog::warn( + "found .git directory in {} but current working directory is {};" + " did you invoke scip-clang from the project root?", + dirPath.string(), cwd.string()); + spdlog::info( + "invoking scip-clang from a directory other than the project root" + " may lead to incorrect indexing results"); + break; + } + } + } + } compdbFile._sizeInBytes = size; compdbFile._commandCount = validateAndCountJobs( compdbFile._sizeInBytes, compdbFile.file, validationOptions); diff --git a/indexer/CompilationDatabase.h b/indexer/CompilationDatabase.h index 1c25c36c..6e635c4d 100644 --- a/indexer/CompilationDatabase.h +++ b/indexer/CompilationDatabase.h @@ -29,6 +29,7 @@ namespace compdb { struct ValidationOptions { bool checkDirectoryPathsAreAbsolute; + bool tryDetectOutOfProjectRoot; }; class File { diff --git a/indexer/Driver.cc b/indexer/Driver.cc index 846bd59d..c8872bb6 100644 --- a/indexer/Driver.cc +++ b/indexer/Driver.cc @@ -1227,8 +1227,9 @@ class Driver { StdPath compdbStdPath{this->compdbPath().asStringRef()}; auto compdbFile = compdb::File::openAndExitOnErrors( compdbStdPath, - compdb::ValidationOptions{.checkDirectoryPathsAreAbsolute = - !this->options.isTesting}); + compdb::ValidationOptions{ + .checkDirectoryPathsAreAbsolute = !this->options.isTesting, + .tryDetectOutOfProjectRoot = !this->options.isTesting}); this->compdbCommandCount = compdbFile.commandCount(); this->options.numWorkers = std::min(this->compdbCommandCount, this->numWorkers()); diff --git a/indexer/Worker.cc b/indexer/Worker.cc index 2c2b9b05..0b91ecff 100644 --- a/indexer/Worker.cc +++ b/indexer/Worker.cc @@ -144,7 +144,8 @@ Worker::Worker(WorkerOptions &&options) case WorkerMode::Compdb: { auto compdbFile = compdb::File::openAndExitOnErrors( this->options.compdbPath, - compdb::ValidationOptions{.checkDirectoryPathsAreAbsolute = true}); + compdb::ValidationOptions{.checkDirectoryPathsAreAbsolute = true, + .tryDetectOutOfProjectRoot = true}); compdb::ResumableParser parser{}; parser.initialize(compdbFile, compdb::ParseOptions::create( diff --git a/test/test_main.cc b/test/test_main.cc index 953c45be..823d776f 100644 --- a/test/test_main.cc +++ b/test/test_main.cc @@ -175,7 +175,8 @@ TEST_CASE("COMPDB_PARSING") { auto compdbFile = compdb::File::openAndExitOnErrors( jsonFilePath, - compdb::ValidationOptions{.checkDirectoryPathsAreAbsolute = false}); + compdb::ValidationOptions{.checkDirectoryPathsAreAbsolute = false, + .tryDetectOutOfProjectRoot = false}); if (!compdbFile.file) { spdlog::error("missing JSON file at path {}", jsonFilePath.c_str()); REQUIRE(compdbFile.file);