diff options
author | Karen Arutyunov <karen@codesynthesis.com> | 2018-04-27 15:53:00 +0300 |
---|---|---|
committer | Karen Arutyunov <karen@codesynthesis.com> | 2018-04-27 15:55:18 +0300 |
commit | a2b084651909929d58f6b4bc0f3c742d87ee31f6 (patch) | |
tree | 63ef970e6edc44473ca9450dce93cbd130127d57 /bpkg/rep-info.cxx | |
parent | f86216071cd4d8d120a8afb83f4b452ef7892ea1 (diff) |
Add support for repository fragments
Diffstat (limited to 'bpkg/rep-info.cxx')
-rw-r--r-- | bpkg/rep-info.cxx | 126 |
1 files changed, 114 insertions, 12 deletions
diff --git a/bpkg/rep-info.cxx b/bpkg/rep-info.cxx index 0e7f911..7dd4a28 100644 --- a/bpkg/rep-info.cxx +++ b/bpkg/rep-info.cxx @@ -4,7 +4,8 @@ #include <bpkg/rep-info.hxx> -#include <iostream> // cout +#include <iostream> // cout +#include <algorithm> // find_if() #include <libbutl/sha256.mxx> // sha256_to_fingerprint() #include <libbutl/manifest-serializer.mxx> @@ -72,7 +73,7 @@ namespace bpkg if (all || cert_info) { shared_ptr<const certificate>& cert (rfd.certificate); - const optional<string>& cert_pem (rfd.repositories.back ().certificate); + const optional<string>& cert_pem (rfd.cert_pem); if (cert_pem) { @@ -145,23 +146,89 @@ namespace bpkg { if (o.manifest ()) { + // Merge repository manifest lists, adding the fragment value to + // prerequisite/complement repository manifests, and picking the + // latest base repository manifest. + // + vector<repository_manifest> rms; + + for (rep_fetch_data::fragment& fr: rfd.fragments) + { + for (repository_manifest& rm: fr.repositories) + { + if (rm.effective_role () != repository_role::base) + { + if (!fr.id.empty ()) + rm.fragment = fr.id; + + rms.push_back (move (rm)); + } + } + } + + // Append the latest base repository manifest. + // + // Note that there must be at least one fragment with at least a + // base repository being present. + // + assert (!rfd.fragments.empty () && + !rfd.fragments.back ().repositories.empty ()); + + rms.push_back (move (rfd.fragments.back ().repositories.back ())); + // Note: serializing without any extra repository_manifests info. // manifest_serializer s (cout, "STDOUT"); - for (const repository_manifest& rm: rfd.repositories) + + for (const repository_manifest& rm: rms) rm.serialize (s); + s.next ("", ""); // End of stream. } else { - for (const repository_manifest& rm: rfd.repositories) + // Merge complements/prerequisites from all fragments "upgrading" + // prerequisites to complements and preferring locations from the + // latest fragments. + // + vector<repository_manifest> rms; + + for (rep_fetch_data::fragment& fr: rfd.fragments) { - repository_role rr (rm.effective_role ()); + for (repository_manifest& rm: fr.repositories) + { + if (rm.effective_role () == repository_role::base) + continue; + + repository_location l (rm.location, rl); // Complete. + + auto i (find_if (rms.begin (), rms.end (), + [&l] (const repository_manifest& i) + { + return i.location.canonical_name () == + l.canonical_name (); + })); + + if (i == rms.end ()) + { + rm.location = move (l); + rms.push_back (move (rm)); + } + else + { + if (rm.effective_role () == repository_role::complement) + i->role = rm.effective_role (); - if (rr == repository_role::base) - continue; // Entry for this repository. + i->location = move (l); + } + } + } + + for (const repository_manifest& rm: rms) + { + repository_role rr (rm.effective_role ()); - repository_location l (rm.location, rl); // Complete. + const repository_location& l (rm.location); const string& n (l.canonical_name ()); switch (rr) @@ -185,21 +252,56 @@ namespace bpkg { if (o.manifest ()) { + // Merge package manifest lists, adding the fragment. + // + vector<package_manifest> pms; + + for (rep_fetch_data::fragment& fr: rfd.fragments) + { + for (package_manifest& pm: fr.packages) + { + if (!fr.id.empty ()) + pm.fragment = fr.id; + + pms.push_back (move (pm)); + } + } + // Note: serializing without any extra package_manifests info. // manifest_serializer s (cout, "STDOUT"); - for (const rep_fetch_data::package& p: rfd.packages) - p.manifest.serialize (s); + for (const package_manifest& pm: pms) + pm.serialize (s); s.next ("", ""); // End of stream. } else { + // Merge packages from all the fragments. + // + vector<package_manifest> pms; + + for (rep_fetch_data::fragment& fr: rfd.fragments) + { + for (package_manifest& pm: fr.packages) + { + auto i (find_if (pms.begin (), pms.end (), + [&pm] (const package_manifest& i) + { + return i.name == pm.name && + i.version == pm.version; + })); + + if (i == pms.end ()) + pms.push_back (move (pm)); + } + } + // Separate package list from the general repository info. // cout << endl; - for (const rep_fetch_data::package& p: rfd.packages) - cout << p.manifest.name << "/" << p.manifest.version << endl; + for (const package_manifest& pm: pms) + cout << pm.name << "/" << pm.version << endl; } } } |