diff options
Diffstat (limited to 'bpkg/package.cxx')
-rw-r--r-- | bpkg/package.cxx | 130 |
1 files changed, 91 insertions, 39 deletions
diff --git a/bpkg/package.cxx b/bpkg/package.cxx index 6cd555e..05dbc0d 100644 --- a/bpkg/package.cxx +++ b/bpkg/package.cxx @@ -6,6 +6,7 @@ #include <bpkg/database.hxx> #include <bpkg/checksum.hxx> +#include <bpkg/rep-mask.hxx> #include <bpkg/pkg-verify.hxx> #include <bpkg/diagnostics.hxx> #include <bpkg/satisfaction.hxx> @@ -69,6 +70,42 @@ namespace bpkg return r != 0 ? (r < 0) : (db < v.db); } + // package_version_key + // + string package_version_key:: + string (bool ignore_version) const + { + std::string r (name.string ()); + + if (version && !version->empty () && !ignore_version) + { + r += '/'; + r += version->string (); + } + + const std::string& d (db.get ().string); + + if (!d.empty ()) + { + r += ' '; + r += d; + } + + return r; + } + + bool package_version_key:: + operator< (const package_version_key& v) const + { + // NOTE: remember to update cmdline_adjustments::tried_earlier() if + // changing anything here. + // + if (int r = name.compare (v.name)) + return r < 0; + + return version != v.version ? (version < v.version) : (db < v.db); + } + // available_package // const version* available_package:: @@ -211,7 +248,7 @@ namespace bpkg // Quote the result as it contains the space character. // - return "'" + name.string () + ' ' + constraint->string () + "'"; + return '\'' + name.string () + ' ' + constraint->string () + '\''; } // selected_package @@ -279,7 +316,7 @@ namespace bpkg if (s == "user") return config_source::user; else if (s == "dependent") return config_source::dependent; else if (s == "reflect") return config_source::reflect; - else throw invalid_argument ("invalid config source '" + s + "'"); + else throw invalid_argument ("invalid config source '" + s + '\''); } shared_ptr<available_package> @@ -295,12 +332,18 @@ namespace bpkg // The package is in at least fetched state, which means we should // be able to get its manifest. // - const optional<path>& a (sp->archive); - + // @@ PERF We should probably implement the available package caching not + // to parse the same manifests multiple times during all that build + // plan refinement iterations. What should be the cache key? Feels like + // it should be the archive/directory path. Note that the package + // manifests can potentially differ in different external package + // directories for the same version iteration. Testing showed 6% + // speedup on tests (debug/sanitized). + // package_manifest m ( sp->state == package_state::fetched ? pkg_verify (options, - a->absolute () ? *a : db.config_orig / *a, + sp->effective_archive (db.config_orig), true /* ignore_unknown */, false /* ignore_toolchain */, false /* expand_values */, @@ -373,7 +416,7 @@ namespace bpkg { const shared_ptr<repository_fragment>& rf (prf.repository_fragment); - if (rf->location.directory_based ()) + if (!rep_masked_fragment (db, rf) && rf->location.directory_based ()) fail << "external package " << n << '/' << v << " is already available from " << rf->location.canonical_name (); @@ -389,45 +432,54 @@ namespace bpkg false /* iteration */)) return nullopt; - string mc (package_checksum (o, d, pi)); - - // The selected package must not be "simulated" (see pkg-build for - // details). - // - assert (p->manifest_checksum); - - bool changed (mc != *p->manifest_checksum); + bool changed (!p->external ()); - // If the manifest hasn't changed and the package has buildfile clauses in - // the dependencies, then check if the buildfiles haven't changed either. + // If the selected package is not external, then increment the iteration + // number to make the external package preferable. Note that for such + // packages the manifest/subprojects and buildfiles checksums are absent. // - if (!changed && p->buildfiles_checksum) + if (!changed) { - // Always calculate the checksum over the buildfiles since the package - // is external. + // The selected package must not be "simulated" (see pkg-build for + // details). // - changed = package_buildfiles_checksum ( - nullopt /* bootstrap_build */, - nullopt /* root_build */, - {} /* buildfiles */, - d) != *p->buildfiles_checksum; - } + assert (p->manifest_checksum); - // If the manifest hasn't changed but the selected package points to an - // external source directory, then we also check if the directory have - // moved. - // - if (!changed && p->external ()) - { - dir_path src_root (p->effective_src_root (db.config)); + changed = (package_checksum (o, d, pi) != *p->manifest_checksum); - // We need to complete and normalize the source directory as it may - // generally be completed against the configuration directory (unlikely - // but possible), that can be relative and/or not normalized. + // If the manifest hasn't changed and the package has buildfile clauses + // in the dependencies, then check if the buildfiles haven't changed + // either. // - normalize (src_root, "package source"); + if (!changed && p->buildfiles_checksum) + { + // Always calculate the checksum over the buildfiles since the package + // is external. + // + changed = package_buildfiles_checksum ( + nullopt /* bootstrap_build */, + nullopt /* root_build */, + {} /* buildfiles */, + d) != *p->buildfiles_checksum; + } + + // If the manifest hasn't changed but the selected package points to an + // external source directory, then we also check if the directory have + // moved. + // + if (!changed) + { + dir_path src_root (p->effective_src_root (db.config)); + + // We need to complete and normalize the source directory as it may + // generally be completed against the configuration directory + // (unlikely but possible), that can be relative and/or not + // normalized. + // + normalize (src_root, "package source"); - changed = src_root != normalize (d, "package source"); + changed = src_root != normalize (d, "package source"); + } } return !changed @@ -464,7 +516,7 @@ namespace bpkg else if (s == "fetched") return package_state::fetched; else if (s == "unpacked") return package_state::unpacked; else if (s == "configured") return package_state::configured; - else throw invalid_argument ("invalid package state '" + s + "'"); + else throw invalid_argument ("invalid package state '" + s + '\''); } // substate @@ -486,7 +538,7 @@ namespace bpkg { if (s == "none") return package_substate::none; else if (s == "system") return package_substate::system; - else throw invalid_argument ("invalid package substate '" + s + "'"); + else throw invalid_argument ("invalid package substate '" + s + '\''); } // certificate |