2022-08-10 21:52:07 +03:00
|
|
|
#include <clippy/project_list.hpp>
|
|
|
|
#include <filesystem>
|
|
|
|
#include <utils/lock_file.hpp>
|
|
|
|
|
|
|
|
#include <fstream>
|
|
|
|
#include <mutex>
|
2022-08-11 16:43:53 +03:00
|
|
|
#include <random>
|
|
|
|
#include <chrono>
|
2022-08-10 21:52:07 +03:00
|
|
|
|
2022-08-11 16:43:53 +03:00
|
|
|
Config ProjectList::GetNewConfig(
|
|
|
|
const std::filesystem::path& config_directory) {
|
|
|
|
std::lock_guard guard(lock_file_);
|
2022-08-10 21:52:07 +03:00
|
|
|
|
2022-08-11 16:43:53 +03:00
|
|
|
LoadWithouLock();
|
2022-08-10 21:52:07 +03:00
|
|
|
|
2022-08-11 16:43:53 +03:00
|
|
|
std::mt19937 rnd(std::chrono::system_clock::now().time_since_epoch().count());
|
|
|
|
|
|
|
|
auto RandomSymbol = [&rnd]() {
|
|
|
|
int n = rnd() % (26 + 26 + 10);
|
|
|
|
if (n < 26) {
|
|
|
|
return 'a' + n;
|
|
|
|
} else if (n < 26 + 26) {
|
|
|
|
return 'A' + n - 26;
|
|
|
|
} else {
|
|
|
|
return '0' + n - 26 - 26;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
auto GenerateFilename = [&rnd, &RandomSymbol]() {
|
|
|
|
std::string filename;
|
|
|
|
for (size_t i = 0; i < 6; ++i) {
|
|
|
|
filename += RandomSymbol();
|
|
|
|
}
|
|
|
|
|
|
|
|
return filename;
|
|
|
|
};
|
|
|
|
|
|
|
|
auto filename = GenerateFilename();
|
|
|
|
while (true) {
|
|
|
|
bool exist_config = false;
|
|
|
|
for (auto& project : projects_) {
|
|
|
|
if (filename == project.configuration_file.filename()) {
|
|
|
|
exist_config = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!exist_config) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
filename = GenerateFilename();
|
|
|
|
}
|
|
|
|
|
|
|
|
auto path_to_config = config_directory / filename;
|
|
|
|
|
|
|
|
std::ofstream out(path_, std::ios::ate);
|
|
|
|
out << std::filesystem::current_path() << " " << path_to_config << std::endl;
|
|
|
|
out.close();
|
|
|
|
|
|
|
|
projects_.emplace_back(std::filesystem::current_path(), path_to_config);
|
|
|
|
|
2022-08-11 21:42:53 +03:00
|
|
|
return {path_to_config, std::filesystem::current_path()};
|
2022-08-11 16:43:53 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void ProjectList::Load() {
|
|
|
|
std::lock_guard guard(lock_file_);
|
|
|
|
|
|
|
|
LoadWithouLock();
|
|
|
|
}
|
|
|
|
|
|
|
|
void ProjectList::LoadWithouLock() {
|
|
|
|
std::ifstream in(path_);
|
2022-08-10 21:52:07 +03:00
|
|
|
|
|
|
|
Project current;
|
|
|
|
|
|
|
|
while (in >> current.root_project >> current.configuration_file) {
|
|
|
|
projects_.push_back(current);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
std::optional<Project> ProjectList::GetCurrentProject() {
|
|
|
|
auto current_path = std::filesystem::current_path();
|
|
|
|
|
|
|
|
std::optional<Project> result;
|
|
|
|
auto UpdateResult = [&result](Project p) {
|
|
|
|
if (!result.has_value()) {
|
|
|
|
result = p;
|
|
|
|
} else {
|
|
|
|
result = std::max(p, result.value());
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
for (auto& project : projects_) {
|
|
|
|
auto prefix_current_path = current_path;
|
|
|
|
|
|
|
|
if (project.root_project == "/") {
|
|
|
|
UpdateResult(project);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
while (prefix_current_path != "/") {
|
|
|
|
if (prefix_current_path == project.root_project) {
|
|
|
|
UpdateResult(project);
|
|
|
|
}
|
|
|
|
prefix_current_path = prefix_current_path.parent_path();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|