From 25616b791461608b082291dda431d8247fe8fb21 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Tue, 16 Jan 2018 12:21:37 +0200 Subject: Factor out bpkg repository fetching code used in rep-fetch and rep-info Note that now rep-info in the manifest mode does not dump any of the repository type-specific information. --- bpkg/fetch.hxx | 4 +- bpkg/rep-fetch.cxx | 135 ++++++++++++++++++++++++++++++++------------------ bpkg/rep-fetch.hxx | 23 +++++++++ bpkg/rep-info.cxx | 87 +++++++++----------------------- tests/rep-create.test | 6 --- tests/rep-info.test | 2 - 6 files changed, 136 insertions(+), 121 deletions(-) diff --git a/bpkg/fetch.hxx b/bpkg/fetch.hxx index e047f29..4e7b271 100644 --- a/bpkg/fetch.hxx +++ b/bpkg/fetch.hxx @@ -17,7 +17,7 @@ namespace bpkg repository_manifests fetch_repositories (const dir_path&, bool ignore_unknown); - pair + pair fetch_repositories (const common_options&, const repository_location&, bool ignore_unknown); @@ -25,7 +25,7 @@ namespace bpkg package_manifests fetch_packages (const dir_path&, bool ignore_unknown); - pair + pair fetch_packages (const common_options&, const repository_location&, bool ignore_unknown); diff --git a/bpkg/rep-fetch.cxx b/bpkg/rep-fetch.cxx index 2a298b8..93ccbc6 100644 --- a/bpkg/rep-fetch.cxx +++ b/bpkg/rep-fetch.cxx @@ -4,8 +4,6 @@ #include -#include - #include #include #include @@ -18,6 +16,86 @@ using namespace butl; namespace bpkg { + static rep_fetch_data + rep_fetch_bpkg (const common_options& co, + const dir_path* conf, + const repository_location& rl, + bool ignore_unknown) + { + // First fetch the repositories list and authenticate the base's + // certificate. + // + pair rmc ( + fetch_repositories (co, rl, ignore_unknown)); + + repository_manifests& rms (rmc.first); + + bool a (co.auth () != auth::none && + (co.auth () == auth::all || rl.remote ())); + + shared_ptr cert; + const optional& cert_pem (rms.back ().certificate); + + if (a) + { + cert = authenticate_certificate (co, conf, cert_pem, rl); + a = !cert->dummy (); + } + + // Now fetch the packages list and make sure it matches the repositories + // we just fetched. + // + pair pmc ( + fetch_packages (co, rl, ignore_unknown)); + + package_manifests& pms (pmc.first); + + if (rmc.second != pms.sha256sum) + fail << "repositories manifest file checksum mismatch for " + << rl.canonical_name () << + info << "try again"; + + if (a) + { + signature_manifest sm ( + fetch_signature (co, rl, true /* ignore_unknown */)); + + if (sm.sha256sum != pmc.second) + fail << "packages manifest file checksum mismatch for " + << rl.canonical_name () << + info << "try again"; + + assert (cert != nullptr); + authenticate_repository (co, conf, cert_pem, *cert, sm, rl); + } + + return rep_fetch_data {move (rms), move (pms), move (cert)}; + } + + static rep_fetch_data + rep_fetch_git (const common_options&, + const dir_path*, + const repository_location&, + bool) + { + fail << "not implemented" << endf; + } + + rep_fetch_data + rep_fetch (const common_options& co, + const dir_path* conf, + const repository_location& rl, + bool iu) + { + switch (rl.type ()) + { + case repository_type::bpkg: return rep_fetch_bpkg (co, conf, rl, iu); + case repository_type::git: return rep_fetch_git (co, conf, rl, iu); + } + + return rep_fetch_data (); + } + static void rep_fetch (const configuration_options& co, transaction& t, @@ -54,53 +132,14 @@ namespace bpkg r->fetched = true; // Mark as being fetched. - // Load the 'repositories' file and use it to populate the prerequisite - // and complement repository sets. - // - pair rmc ( - fetch_repositories (co, rl, true)); - - repository_manifests& rms (rmc.first); - - bool a (co.auth () != auth::none && - (co.auth () == auth::all || rl.remote ())); - - shared_ptr cert; - - if (a) - { - cert = authenticate_certificate ( - co, &co.directory (), rms.back ().certificate, rl); - - a = !cert->dummy (); - } - - // Load the 'packages' file. + // Load the repositories and packages and use it to populate the + // prerequisite and complement repository sets as well as available + // packages. // - pair pmc ( - fetch_packages (co, rl, true)); - - package_manifests& pms (pmc.first); - - if (rmc.second != pms.sha256sum) - fail << "repositories manifest file checksum mismatch for " - << rl.canonical_name () << - info << "try again"; - - if (a) - { - signature_manifest sm (fetch_signature (co, rl, true)); - - if (sm.sha256sum != pmc.second) - fail << "packages manifest file checksum mismatch for " - << rl.canonical_name () << - info << "try again"; - - assert (cert != nullptr); - authenticate_repository (co, &co.directory (), nullopt, *cert, sm, rl); - } + rep_fetch_data rfd ( + rep_fetch (co, &co.directory (), rl, true /* ignore_unknow */)); - for (repository_manifest& rm: rms) + for (repository_manifest& rm: rfd.repositories) { repository_role rr (rm.effective_role ()); @@ -193,7 +232,7 @@ namespace bpkg session& s (session::current ()); session::reset_current (); - for (package_manifest& pm: pms) + for (package_manifest& pm: rfd.packages) { // We might already have this package in the database. // diff --git a/bpkg/rep-fetch.hxx b/bpkg/rep-fetch.hxx index ccc9e11..c54119f 100644 --- a/bpkg/rep-fetch.hxx +++ b/bpkg/rep-fetch.hxx @@ -5,6 +5,8 @@ #ifndef BPKG_REP_FETCH_HXX #define BPKG_REP_FETCH_HXX +#include + #include #include @@ -14,6 +16,27 @@ namespace bpkg { int rep_fetch (const rep_fetch_options&, cli::scanner& args); + + // Fetch and authenticate repositories and packages manifests. + // + // If conf is NULL, then assume not running in a bpkg configuration. If it + // is empty, then check if the bpkg configuration exists in the current + // working directory. + // + class certificate; + + struct rep_fetch_data + { + std::vector repositories; + std::vector packages; + shared_ptr certificate; // Can be NULL. + }; + + rep_fetch_data + rep_fetch (const common_options& co, + const dir_path* conf, + const repository_location& rl, + bool ignore_unknown); } #endif // BPKG_REP_FETCH_HXX diff --git a/bpkg/rep-info.cxx b/bpkg/rep-info.cxx index 322ff6b..128951a 100644 --- a/bpkg/rep-info.cxx +++ b/bpkg/rep-info.cxx @@ -12,11 +12,12 @@ #include #include -#include #include #include #include +#include + using namespace std; using namespace butl; @@ -38,65 +39,14 @@ namespace bpkg : nullopt)); // Fetch everything we will need before printing anything. Ignore - // unknown manifest entries unless we are dumping them. First fetch - // the repositories list and authenticate the base's certificate. + // unknown manifest entries unless we are dumping them. // - pair rmc ( - fetch_repositories (o, rl, !o.manifest ())); - - repository_manifests& rms (rmc.first); - - bool a (o.auth () != auth::none && - (o.auth () == auth::all || rl.remote ())); - - const optional cert_pem (rms.back ().certificate); - shared_ptr cert; - - if (a) - { - dir_path d (o.directory ()); - cert = authenticate_certificate ( - o, - o.directory_specified () && d.empty () ? nullptr : &d, - cert_pem, - rl); - - a = !cert->dummy (); - } - - // Now fetch the packages list and make sure it matches the repositories - // we just fetched. - // - pair pmc ( - fetch_packages (o, rl, !o.manifest ())); - - package_manifests& pms (pmc.first); - - if (rmc.second != pms.sha256sum) - fail << "repositories manifest file checksum mismatch for " - << rl.canonical_name () << - info << "try again"; - - if (a) - { - signature_manifest sm (fetch_signature (o, rl, true)); - - if (sm.sha256sum != pmc.second) - fail << "packages manifest file checksum mismatch for " - << rl.canonical_name () << - info << "try again"; - - dir_path d (o.directory ()); - assert (cert != nullptr); - - authenticate_repository ( - o, - o.directory_specified () && d.empty () ? nullptr : &d, - cert_pem, - *cert, - sm, - rl); - } + dir_path d (o.directory ()); + rep_fetch_data rfd ( + rep_fetch (o, + o.directory_specified () && d.empty () ? nullptr : &d, + rl, + !o.manifest () /* ignore_unknow */)); // Now print. // @@ -121,6 +71,9 @@ namespace bpkg // if (all || cert_info) { + shared_ptr& cert (rfd.certificate); + const optional& cert_pem (rfd.repositories.back ().certificate); + if (cert_pem) { // Repository is signed. If we got the repository certificate as the @@ -192,12 +145,16 @@ namespace bpkg { if (o.manifest ()) { + // Note: serializing without any extra repository_manifests info. + // manifest_serializer s (cout, "STDOUT"); - rms.serialize (s); + for (const repository_manifest& rm: rfd.repositories) + rm.serialize (s); + s.next ("", ""); // End of stream. } else { - for (const repository_manifest& rm: rms) + for (const repository_manifest& rm: rfd.repositories) { repository_role rr (rm.effective_role ()); @@ -228,8 +185,12 @@ namespace bpkg { if (o.manifest ()) { + // Note: serializing without any extra package_manifests info. + // manifest_serializer s (cout, "STDOUT"); - pms.serialize (s); + for (const package_manifest& pm: rfd.packages) + pm.serialize (s); + s.next ("", ""); // End of stream. } else { @@ -237,7 +198,7 @@ namespace bpkg // cout << endl; - for (const package_manifest& pm: pms) + for (const package_manifest& pm: rfd.packages) cout << pm.name << "/" << pm.version << endl; } } diff --git a/tests/rep-create.test b/tests/rep-create.test index 01ab7f8..b64c518 100644 --- a/tests/rep-create.test +++ b/tests/rep-create.test @@ -34,8 +34,6 @@ $rep_info -p -m 1/stable/ >>EOO : 1 - sha256sum: 6cac7ffa1f02f90776fc89bcacf38604ba0eddf176f2314c75dc9bf1b10a8b32 - : name: foo version: 1 summary: The "Foo" utility @@ -62,8 +60,6 @@ $rep_info -p -m 1/stable/ >>EOO : 1 - sha256sum: 6cac7ffa1f02f90776fc89bcacf38604ba0eddf176f2314c75dc9bf1b10a8b32 - : name: foo version: 1 summary: The "Foo" utility @@ -106,8 +102,6 @@ $rep_info --cert-fingerprint -p -m 1/stable/ >>~"%EOO%" $cert_fp : 1 - %sha256sum: .+% - : name: foo version: 1 summary: The "Foo" utility diff --git a/tests/rep-info.test b/tests/rep-info.test index f9791b0..fbe7c0a 100644 --- a/tests/rep-info.test +++ b/tests/rep-info.test @@ -81,8 +81,6 @@ $* --name $rep/testing >"bpkg:build2.org/rep-info/testing ($rep/testing)" : $* --packages --manifest $rep/testing >>EOO : 1 - sha256sum: 7cdc5965cf41742a7feb1c4b73f1438f35e6a6ed7e4e6b30d9fba36c26baca04 - : name: foo version: 1 summary: The "Foo" utility -- cgit v1.1