aboutsummaryrefslogtreecommitdiff
path: root/bpkg/package.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'bpkg/package.cxx')
-rw-r--r--bpkg/package.cxx130
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