Skip to content
This repository has been archived by the owner on Jul 30, 2020. It is now read-only.

Add global .cquery file #702

Merged
merged 21 commits into from
Jun 29, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/platform.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,5 @@ void TraceMe();

optional<std::string> RunExecutable(const std::vector<std::string>& command,
std::string_view input);

optional<std::string> GetGlobalConfigDirectory();
25 changes: 25 additions & 0 deletions src/platform_posix.cc
Original file line number Diff line number Diff line change
Expand Up @@ -368,4 +368,29 @@ optional<std::string> RunExecutable(const std::vector<std::string>& command,
return result;
}

optional<std::string> GetGlobalConfigDirectory() {
char const* xdg_config_home = std::getenv("XDG_CONFIG_HOME");
char const* home = std::getenv("HOME");
optional<std::string> config;

// If it exists use XDG_CONFIG_HOME to comply with the XDG base
// directory spec. Otherwise, use HOME if available.
if (xdg_config_home) {
config = std::string(xdg_config_home);
EnsureEndsInSlash(*config);
*config += "cquery";
if (!FileExists(*config)) {
MakeDirectoryRecursive(AbsolutePath(*config, false));
}
} else if (home) {
*config = home;
}

if (config) {
EnsureEndsInSlash(*config);
}

return config;
}

#endif
28 changes: 28 additions & 0 deletions src/platform_win.cc
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
#include <fcntl.h>
#include <io.h>
#include <windows.h>
#include <Shlobj.h>
#include <Objbase.h>
#include <Knownfolders.h>

#include <sys/stat.h>
#include <sys/types.h>
Expand All @@ -17,6 +20,8 @@
#include <cassert>
#include <iostream>
#include <string>
#include <locale>
#include <codecvt>

namespace {
void EmitError(const std::string& message) {
Expand Down Expand Up @@ -351,4 +356,27 @@ optional<std::string> RunExecutable(const std::vector<std::string>& command,
return output;
}

optional<std::string> GetGlobalConfigDirectory() {
wchar_t *roaming_path = NULL;
optional<std::string> cfg_path = {};
if (SUCCEEDED(SHGetKnownFolderPath(FOLDERID_RoamingAppData, KF_FLAG_DEFAULT,
NULL, &roaming_path))) {
std::wstringstream roaming_stream;
roaming_stream << roaming_path << L"/cquery";

// Convert the roaming path string to a normal string so it
// is analogous with the string returned by the posix version.
using convert_type = std::codecvt_utf8<wchar_t>;
std::wstring_convert<convert_type, wchar_t> converter;
cfg_path = converter.to_bytes(roaming_stream.str());

// As per the docs for SHGetKnownFolderPath
// (https://msdn.microsoft.com/en-us/library/bb762188(VS.85).aspx)
// we must free roaming_path using CoTaskMemFree once
// finished with it.
CoTaskMemFree(static_cast<void*>(roaming_path));
}
return cfg_path;
}

#endif
47 changes: 33 additions & 14 deletions src/project.cc
Original file line number Diff line number Diff line change
Expand Up @@ -456,7 +456,9 @@ std::vector<std::string> ReadCompilerArgumentsFromFile(
return args;
}

std::vector<Project::Entry> LoadFromDirectoryListing(ProjectConfig* config) {
std::vector<Project::Entry> LoadFromDirectoryListing(
ProjectConfig* config,
bool use_global_config = false) {
std::vector<Project::Entry> result;
config->mode = ProjectMode::DotCquery;

Expand All @@ -476,18 +478,31 @@ std::vector<Project::Entry> LoadFromDirectoryListing(ProjectConfig* config) {
}
}

GetFilesInFolder(config->project_dir, true /*recursive*/,
true /*add_folder_to_path*/,
[&folder_args, &files](const std::string& path) {
if (SourceFileLanguage(path) != LanguageId::Unknown) {
files.push_back(path);
} else if (GetBaseName(path) == ".cquery") {
LOG_S(INFO) << "Using .cquery arguments from " << path;
folder_args.emplace(GetDirName(path),
ReadCompilerArgumentsFromFile(path));
}
});

GetFilesInFolder(
config->project_dir, true /*recursive*/, true /*add_folder_to_path*/,
[&folder_args, &files](const std::string& path) {
if (SourceFileLanguage(path) != LanguageId::Unknown) {
files.push_back(path);
} else if (GetBaseName(path) == ".cquery") {
LOG_S(INFO) << "Using .cquery arguments from " << path;
folder_args.emplace(GetDirName(path),
ReadCompilerArgumentsFromFile(path));
}
});

if (use_global_config) {
optional<std::string> maybe_cfg = GetGlobalConfigDirectory();
if (folder_args.empty() && maybe_cfg) {
std::string cfg = *maybe_cfg + ".cquery";
if (cfg.size() && FileExists(cfg)) {
LOG_S(INFO) << "Using .cquery arguments from " << cfg;
folder_args.emplace(config->project_dir,
ReadCompilerArgumentsFromFile(cfg));
}
}
}

LOG_IF_S(WARNING, folder_args.empty() && config->extra_flags.empty()
&& !c_cpp_props)
<< "cquery has no clang arguments. Considering adding a "
Expand Down Expand Up @@ -541,8 +556,11 @@ std::vector<Project::Entry> LoadCompilationEntriesFromDirectory(
ProjectConfig* project,
const std::string& opt_compilation_db_dir) {
// If there is a .cquery file always load using directory listing.
if (FileExists(project->project_dir + ".cquery"))
// The .cquery file can be in the project or home dir but the project
// dir takes precedence.
if (FileExists(project->project_dir + ".cquery")) {
return LoadFromDirectoryListing(project);
}

// If |compilationDatabaseCommand| is specified, execute it to get the compdb.
std::string comp_db_dir(opt_compilation_db_dir);
Expand Down Expand Up @@ -596,6 +614,7 @@ std::vector<Project::Entry> LoadCompilationEntriesFromDirectory(
project->project_dir.c_str(), &cx_db_load_error);
}
}

if (!g_config->compilationDatabaseCommand.empty()) {
#if defined(_WIN32)
// TODO
Expand All @@ -608,7 +627,7 @@ std::vector<Project::Entry> LoadCompilationEntriesFromDirectory(
if (cx_db_load_error != CXCompilationDatabase_NoError) {
LOG_S(INFO) << "Unable to load compile_commands.json located at \""
<< comp_db_dir << "\"; using directory listing instead.";
return LoadFromDirectoryListing(project);
return LoadFromDirectoryListing(project, true);
}

Timer clang_time;
Expand Down