#include #include #include #include #include #include #include Config ProjectList::GetNewConfig( const std::filesystem::path& config_directory) { std::lock_guard guard(lock_file_); LoadWithouLock(); 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); return {path_to_config}; } void ProjectList::Load() { std::lock_guard guard(lock_file_); LoadWithouLock(); } void ProjectList::LoadWithouLock() { std::ifstream in(path_); Project current; while (in >> current.root_project >> current.configuration_file) { projects_.push_back(current); } } std::optional ProjectList::GetCurrentProject() { auto current_path = std::filesystem::current_path(); std::optional 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; }