Line data Source code
1 : /*! 2 : * \file esys/repo/manifest.cpp 3 : * \brief 4 : * 5 : * \cond 6 : * __legal_b__ 7 : * 8 : * Copyright (c) 2020-2021 Michel Gillet 9 : * Distributed under the MIT License. 10 : * (See accompanying file LICENSE.txt or 11 : * copy at https://opensource.org/licenses/MIT) 12 : * 13 : * __legal_e__ 14 : * \endcond 15 : * 16 : */ 17 : 18 : #include "esys/repo/esysrepo_prec.h" 19 : #include "esys/repo/manifest.h" 20 : #include "esys/repo/manifest/repository.h" 21 : 22 : #include <cassert> 23 : 24 : namespace esys::repo 25 : { 26 : 27 59 : Manifest::Manifest() = default; 28 : 29 77 : Manifest::~Manifest() = default; 30 : 31 57 : void Manifest::set_type(manifest::Type type) 32 : { 33 57 : m_type = type; 34 57 : } 35 : 36 5 : manifest::Type Manifest::get_type() const 37 : { 38 5 : return m_type; 39 : } 40 : 41 59 : void Manifest::set_kind(manifest::Kind kind) 42 : { 43 59 : m_kind = kind; 44 59 : } 45 : 46 31 : manifest::Kind Manifest::get_kind() const 47 : { 48 31 : return m_kind; 49 : } 50 : 51 26 : void Manifest::set_format(manifest::Format format) 52 : { 53 26 : m_format = format; 54 26 : } 55 : 56 9 : manifest::Format Manifest::get_format() const 57 : { 58 9 : return m_format; 59 : } 60 : 61 88 : int Manifest::add_location(std::shared_ptr<manifest::Location> location, bool is_default) 62 : { 63 88 : assert(location != nullptr); 64 88 : assert(!location->get_name().empty()); 65 : 66 88 : auto it = m_map_locations.find(location->get_name()); 67 88 : if (it != m_map_locations.end()) return -1; 68 : 69 88 : m_locations.push_back(location); 70 88 : m_map_locations[location->get_name()] = location; 71 92 : if (is_default) set_default_location(location); 72 : 73 : return 0; 74 : } 75 : 76 111 : std::vector<std::shared_ptr<manifest::Location>> &Manifest::get_locations() 77 : { 78 111 : return m_locations; 79 : } 80 : 81 6 : const std::vector<std::shared_ptr<manifest::Location>> &Manifest::get_locations() const 82 : { 83 6 : return m_locations; 84 : } 85 : 86 0 : std::map<std::string, std::shared_ptr<manifest::Location>> &Manifest::get_map_locations() 87 : { 88 0 : return m_map_locations; 89 : } 90 : 91 0 : const std::map<std::string, std::shared_ptr<manifest::Location>> &Manifest::get_map_locations() const 92 : { 93 0 : return m_map_locations; 94 : } 95 : 96 404 : std::shared_ptr<manifest::Location> Manifest::find_location(const std::string &name) 97 : { 98 404 : auto it = m_map_locations.find(name); 99 : 100 404 : if (it == m_map_locations.end()) return nullptr; 101 : 102 404 : return it->second; 103 : } 104 : 105 21 : std::shared_ptr<manifest::Repository> Manifest::find_repo_by_path(const std::string &path) 106 : { 107 21 : std::shared_ptr<manifest::Repository> repo; 108 : 109 38 : for (auto &location : get_locations()) 110 : { 111 76 : repo = location->find_repo_by_path(path); 112 38 : if (repo != nullptr) return repo; 113 : } 114 21 : return nullptr; 115 21 : } 116 : 117 0 : std::string Manifest::find_repo_path_by_url(const std::string &git_repo_name) 118 : { 119 0 : std::string path; 120 : 121 0 : for (auto &location : get_locations()) 122 : { 123 0 : path = location->find_repo_path_by_url(git_repo_name); 124 0 : if (!path.empty()) return path; 125 : } 126 0 : return ""; 127 0 : } 128 : 129 0 : std::shared_ptr<manifest::Repository> Manifest::find_repo_by_url(const std::string &url) 130 : { 131 0 : std::shared_ptr<manifest::Repository> repo; 132 : 133 0 : for (auto &location : get_locations()) 134 : { 135 0 : repo = location->find_repo_by_url(url); 136 0 : if (repo != nullptr) return repo; 137 : } 138 0 : return nullptr; 139 : 140 0 : } 141 : 142 1 : std::vector<std::shared_ptr<manifest::Repository>> Manifest::find_repos_by_name(const std::string &name) 143 : { 144 1 : std::vector<std::shared_ptr<manifest::Repository>> matches; 145 2 : for (auto &location : get_locations()) 146 : { 147 1 : if (location == nullptr) continue; 148 1 : auto repo = location->find_repo_by_name(name); 149 1 : if (repo != nullptr) matches.push_back(repo); 150 1 : } 151 1 : return matches; 152 0 : } 153 : 154 1 : std::shared_ptr<manifest::Repository> Manifest::find_repo_by_name(const std::string &name) 155 : { 156 1 : auto matches = find_repos_by_name(name); 157 1 : if (matches.size() != 1) return nullptr; 158 1 : return matches[0]; 159 1 : } 160 : 161 2 : std::vector<std::shared_ptr<manifest::Repository>> Manifest::find_repos_by_project(const std::string &project) 162 : { 163 2 : std::vector<std::shared_ptr<manifest::Repository>> matches; 164 2 : if (project.empty()) return matches; 165 : 166 4 : for (auto &location : get_locations()) 167 : { 168 2 : if (location == nullptr) continue; 169 6 : for (auto &repo : location->get_repos()) 170 : { 171 4 : if (repo == nullptr) continue; 172 4 : const std::string &name = repo->get_name(); 173 4 : if (name == project) 174 : { 175 0 : matches.push_back(repo); 176 0 : continue; 177 : } 178 4 : const std::string suffix = "/" + name; 179 8 : if (project.size() > suffix.size() && 180 4 : project.compare(project.size() - suffix.size(), suffix.size(), suffix) == 0) 181 2 : matches.push_back(repo); 182 4 : } 183 : } 184 : return matches; 185 0 : } 186 : 187 1 : std::shared_ptr<manifest::Repository> Manifest::find_repo_by_project(const std::string &project) 188 : { 189 1 : auto matches = find_repos_by_project(project); 190 1 : if (matches.size() != 1) return nullptr; 191 1 : return matches[0]; 192 1 : } 193 : 194 2 : void Manifest::set_default_location(std::shared_ptr<manifest::Location> default_location) 195 : { 196 2 : m_default_location = default_location; 197 2 : } 198 : 199 357 : std::shared_ptr<manifest::Location> Manifest::get_default_location() 200 : { 201 357 : if (m_default_location != nullptr) return m_default_location; 202 : 203 345 : if (m_default_location_str.empty()) return nullptr; 204 : 205 345 : return find_location(m_default_location_str); 206 : } 207 : 208 24 : void Manifest::set_default_location(const std::string &default_location_str) 209 : { 210 24 : m_default_location_str = default_location_str; 211 24 : } 212 : 213 0 : const std::string &Manifest::get_default_location_str() const 214 : { 215 0 : return m_default_location_str; 216 : } 217 : 218 55 : void Manifest::set_default_revision(const std::string &default_revision) 219 : { 220 55 : m_default_revision = default_revision; 221 55 : } 222 : 223 152 : const std::string &Manifest::get_default_revision() const 224 : { 225 152 : return m_default_revision; 226 : } 227 : 228 52 : void Manifest::set_default_job_count(int default_job_count) 229 : { 230 52 : m_default_job_count = default_job_count; 231 52 : } 232 : 233 20 : int Manifest::get_default_job_count() const 234 : { 235 20 : return m_default_job_count; 236 : } 237 : 238 4 : void Manifest::set_default_sync_s(std::optional<bool> sync_s) 239 : { 240 4 : m_default_sync_s = sync_s; 241 4 : } 242 : 243 136 : const std::optional<bool> &Manifest::get_default_sync_s() const 244 : { 245 136 : return m_default_sync_s; 246 : } 247 : 248 181 : std::string Manifest::get_repo_revision(std::shared_ptr<manifest::Repository> repo) 249 : { 250 181 : if (repo == nullptr) return get_default_revision(); 251 : 252 181 : const std::string pinned = get_pinned_revision(repo->get_path()); 253 181 : if (!pinned.empty()) return pinned; 254 : 255 179 : const std::string set_name = get_effective_revision_set_name(); 256 179 : if (!set_name.empty()) 257 : { 258 8 : auto revision_set = get_revision_sets().find_by_name(set_name); 259 8 : if (revision_set != nullptr) 260 : { 261 8 : const std::string path_rev = revision_set->get_repo_revision(repo->get_path()); 262 8 : if (!path_rev.empty()) return path_rev; 263 5 : if (!revision_set->get_default_revision().empty()) return revision_set->get_default_revision(); 264 8 : } 265 8 : } 266 : 267 171 : if (!repo->get_revision().empty()) return repo->get_revision(); 268 104 : return get_default_revision(); 269 362 : } 270 : 271 21 : void Manifest::set_revision_pins(std::shared_ptr<RevisionPins> pins) 272 : { 273 21 : m_revision_pins = pins; 274 21 : } 275 : 276 0 : std::shared_ptr<RevisionPins> Manifest::get_revision_pins() const 277 : { 278 0 : return m_revision_pins; 279 : } 280 : 281 0 : void Manifest::clear_revision_pins() 282 : { 283 0 : m_revision_pins.reset(); 284 0 : } 285 : 286 41 : bool Manifest::has_revision_pin(const std::string &path) const 287 : { 288 41 : return !get_pinned_revision(path).empty(); 289 : } 290 : 291 222 : std::string Manifest::get_pinned_revision(const std::string &path) const 292 : { 293 222 : if (m_revision_pins == nullptr) return ""; 294 163 : return m_revision_pins->get_rev_for_path(path); 295 : } 296 : 297 3 : void Manifest::set_default_revision_set(const std::string &name) 298 : { 299 3 : m_default_revision_set = name; 300 3 : } 301 : 302 28 : const std::string &Manifest::get_default_revision_set() const 303 : { 304 28 : return m_default_revision_set; 305 : } 306 : 307 23 : void Manifest::set_active_revision_set(const std::string &name) 308 : { 309 23 : m_active_revision_set = name; 310 23 : } 311 : 312 1 : const std::string &Manifest::get_active_revision_set() const 313 : { 314 1 : return m_active_revision_set; 315 : } 316 : 317 24 : Result Manifest::select_revision_set(const std::string &preferred) 318 : { 319 24 : if (!preferred.empty()) 320 : { 321 7 : if (get_revision_sets().find_by_name(preferred) == nullptr) 322 1 : return ESYSREPO_RESULT(ResultCode::MANIFEST_REVISION_SET_UNKNOWN, preferred); 323 3 : set_active_revision_set(preferred); 324 3 : return ESYSREPO_RESULT(ResultCode::OK); 325 : } 326 : 327 20 : if (!get_default_revision_set().empty()) 328 : { 329 0 : if (get_revision_sets().find_by_name(get_default_revision_set()) == nullptr) 330 0 : return ESYSREPO_RESULT(ResultCode::MANIFEST_REVISION_SET_UNKNOWN, get_default_revision_set()); 331 0 : set_active_revision_set(get_default_revision_set()); 332 0 : return ESYSREPO_RESULT(ResultCode::OK); 333 : } 334 : 335 20 : set_active_revision_set(""); 336 20 : return ESYSREPO_RESULT(ResultCode::OK); 337 : } 338 : 339 179 : std::string Manifest::get_effective_revision_set_name() const 340 : { 341 179 : if (!m_active_revision_set.empty()) return m_active_revision_set; 342 174 : return m_default_revision_set; 343 : } 344 : 345 85 : manifest::RevisionSets &Manifest::get_revision_sets() 346 : { 347 85 : return m_revision_sets; 348 : } 349 : 350 0 : const manifest::RevisionSets &Manifest::get_revision_sets() const 351 : { 352 0 : return m_revision_sets; 353 : } 354 : 355 59 : void Manifest::clear() 356 : { 357 59 : m_type = manifest::Type::NOT_SET; 358 59 : m_locations.clear(); 359 59 : m_map_locations.clear(); 360 59 : m_map_locations_by_path.clear(); 361 59 : m_default_location.reset(); 362 59 : get_groups().clear(); 363 59 : get_revision_sets().clear(); 364 59 : m_revision_pins.reset(); 365 59 : m_map_locations_by_path.clear(); 366 59 : m_default_location_str.clear(); 367 59 : m_default_revision = "master"; 368 59 : m_default_revision_set.clear(); 369 59 : m_active_revision_set.clear(); 370 59 : m_default_job_count = 1; 371 59 : m_default_sync_s.reset(); 372 59 : } 373 : 374 161 : manifest::Groups &Manifest::get_groups() 375 : { 376 161 : return m_groups; 377 : } 378 : 379 0 : const manifest::Groups &Manifest::get_groups() const 380 : { 381 0 : return m_groups; 382 : } 383 : 384 2 : void Manifest::add_include(std::shared_ptr<manifest::Include> include) 385 : { 386 2 : m_includes.push_back(include); 387 2 : } 388 : 389 : 390 4 : std::vector<std::shared_ptr<manifest::Include>> &Manifest::get_includes() 391 : { 392 4 : return m_includes; 393 : } 394 : 395 2 : const std::vector<std::shared_ptr<manifest::Include>> &Manifest::get_includes() const 396 : { 397 2 : return m_includes; 398 : } 399 : 400 1 : bool Manifest::operator==(const Manifest &other) const 401 : { 402 1 : if (get_type() != other.get_type()) return false; 403 : 404 1 : if (get_locations().size() != other.get_locations().size()) return false; 405 : 406 2 : for (std::size_t idx = 0; idx < get_locations().size(); ++idx) 407 : { 408 1 : if (*get_locations()[idx] != *other.get_locations()[idx]) return false; 409 : } 410 : 411 1 : if (get_includes().size() != other.get_includes().size()) return false; 412 : 413 : 414 : 415 : return true; 416 : } 417 : 418 0 : bool Manifest::operator!=(const Manifest &other) const 419 : { 420 0 : return !operator==(other); 421 : } 422 : 423 0 : ESYSREPO_API std::ostream &operator<<(std::ostream &os, const Manifest &manifest) 424 : { 425 0 : return os; 426 : } 427 : 428 : } // namespace esys::repo