aboutsummaryrefslogtreecommitdiff
path: root/bpkg
diff options
context:
space:
mode:
Diffstat (limited to 'bpkg')
-rw-r--r--bpkg/manifest-utility.cxx92
-rw-r--r--bpkg/manifest-utility.hxx38
-rw-r--r--bpkg/manifest-utility.ixx14
-rw-r--r--bpkg/package-query.cxx124
-rw-r--r--bpkg/package.cxx38
-rw-r--r--bpkg/package.hxx12
-rw-r--r--bpkg/pkg-build-collect.cxx24
-rw-r--r--bpkg/pkg-build.cli9
-rw-r--r--bpkg/pkg-build.cxx71
-rw-r--r--bpkg/pkg-checkout.cxx15
-rw-r--r--bpkg/pkg-fetch.cxx15
-rw-r--r--bpkg/pkg-unpack.cxx5
-rw-r--r--bpkg/rep-fetch.cxx4
-rw-r--r--bpkg/rep-remove.cxx22
-rw-r--r--bpkg/rep-remove.hxx3
-rw-r--r--bpkg/system-package-manager.cxx3
16 files changed, 419 insertions, 70 deletions
diff --git a/bpkg/manifest-utility.cxx b/bpkg/manifest-utility.cxx
index 76db3a7..a96f3b9 100644
--- a/bpkg/manifest-utility.cxx
+++ b/bpkg/manifest-utility.cxx
@@ -23,6 +23,98 @@ namespace bpkg
const path signature_file ("signature.manifest");
const path manifest_file ("manifest");
+ // Masked repositories.
+ //
+ static strings masked_repository_names;
+ static vector<repository_url> masked_repository_urls;
+
+ void
+ mask_repository (const string& r)
+ {
+ if (repository_name (r))
+ {
+ // Verify that the canonical name is of the pkg or dir type.
+ //
+ size_t p (r.find (':'));
+ if (p == string::npos)
+ fail << "invalid repository name '" << r << "': expected to start "
+ << "with colon-separated type";
+
+ try
+ {
+ repository_type t (to_repository_type (string (r, 0, p)));
+
+ if (t != repository_type::pkg && t != repository_type::dir)
+ fail << "invalid repository name '" << r << "': only repositories "
+ << "of pkg and dir types can be masked";
+
+ masked_repository_names.push_back (r);
+ }
+ catch (const invalid_argument& e)
+ {
+ fail << "invalid repository name '" << r << "': " << e;
+ }
+ }
+ else
+ {
+ repository_location rl (parse_location (r, nullopt /* type */));
+
+ if (rl.type () != repository_type::pkg &&
+ rl.type () != repository_type::dir)
+ fail << "invalid repository location '" << r << "': only repositories "
+ << "of pkg and dir types can be masked";
+
+ masked_repository_urls.push_back (rl.url ());
+ }
+ }
+
+ bool
+ masked_repository (const repository_location& rl)
+ {
+ // Optimize for the common case when no repositories are masked.
+ //
+ if (masked_repository_names.empty () && masked_repository_urls.empty ())
+ return false;
+
+ const string& n (rl.canonical_name ());
+ const repository_url& u (rl.url ());
+
+ bool r (find (masked_repository_names.begin (),
+ masked_repository_names.end (),
+ n) != masked_repository_names.end () ||
+ find_if (masked_repository_urls.begin (),
+ masked_repository_urls.end (),
+ [&u] (const repository_url& ru) {return ru == u;}) !=
+ masked_repository_urls.end ());
+
+ // Note that the parse_location() function called by mask_repository()
+ // could potentially mis-guess the type of the git repository (for
+ // example, mistakenly deciding it is a pkg repository). If that's the
+ // case, we would silently mask it, despite the fact we don't support
+ // masking of git repositories. By checking the type here we at least
+ // don't erroneously consider a git repository as masked and fail, which
+ // is better late then never. The solution feels more as a hack but to
+ // properly fix that we just need to add support for masking git
+ // repositories.
+ //
+ if (r &&
+ rl.type () != repository_type::pkg &&
+ rl.type () != repository_type::dir)
+ fail << "invalid repository location '" << u << "': only repositories "
+ << "of pkg and dir types can be masked";
+
+ return r;
+ }
+
+ bool
+ masked_repositories ()
+ {
+ return !masked_repository_names.empty () ||
+ !masked_repository_urls.empty ();
+ }
+
+ // package
+ //
vector<package_info>
package_b_info (const common_options& o,
const dir_paths& ds,
diff --git a/bpkg/manifest-utility.hxx b/bpkg/manifest-utility.hxx
index a5ea962..522ec2b 100644
--- a/bpkg/manifest-utility.hxx
+++ b/bpkg/manifest-utility.hxx
@@ -112,6 +112,42 @@ namespace bpkg
bool
repository_name (const string&);
+ // To pretend that repositories don't exist in the configurations, mask them
+ // by specifying either repository location canonical name or URL.
+ //
+ // Note that specifying a canonical name masks potentially multiple
+ // repositories (think of local and remote pkg repository locations), while
+ // specifying a URL masks a single repository.
+ //
+ // Also note that there is no straightforward way to deduce the list of
+ // repositories a specific repository fragment belongs to. To keep things
+ // simple, we currently only support masking of pkg and dir repositories.
+ // Such repositories have the only non-shared fragment which name and
+ // location are equal to the ones of the containing repository. Once we
+ // decide to also support repositories which support fragmentation (git),
+ // the potential implementation can preload all the masked fragments from
+ // all the databases, so that the masked_repository_fragment() predicate can
+ // refer to them.
+ //
+ void
+ mask_repository (const string&);
+
+ // Return true if a repository is masked either by name or by URL.
+ //
+ bool
+ masked_repository (const repository_location&);
+
+ // Return true if a repository fragment belongs to the masked repositories
+ // only (see package.hxx for the fragment/repository relationship details).
+ //
+ bool
+ masked_repository_fragment (const repository_location&);
+
+ // Return true if any repositories are masked.
+ //
+ bool
+ masked_repositories ();
+
// Return the versions of packages as provided by the build2 version module
// together with the build2 project info the versions originate from (in
// case the caller may want to reuse it). Return nullopt as a package
@@ -190,4 +226,6 @@ namespace bpkg
bool err_path_relative = false);
}
+#include <bpkg/manifest-utility.ixx>
+
#endif // BPKG_MANIFEST_UTILITY_HXX
diff --git a/bpkg/manifest-utility.ixx b/bpkg/manifest-utility.ixx
new file mode 100644
index 0000000..d623747
--- /dev/null
+++ b/bpkg/manifest-utility.ixx
@@ -0,0 +1,14 @@
+// file : bpkg/manifest-utility.ixx -*- C++ -*-
+// license : MIT; see accompanying LICENSE file
+
+namespace bpkg
+{
+ // NOTE: the implementation relies on the fact that only pkg and dir
+ // repositories are currently supported.
+ //
+ inline bool
+ masked_repository_fragment (const repository_location& rl)
+ {
+ return masked_repository (rl);
+ }
+}
diff --git a/bpkg/package-query.cxx b/bpkg/package-query.cxx
index 9675d97..4377f5c 100644
--- a/bpkg/package-query.cxx
+++ b/bpkg/package-query.cxx
@@ -136,6 +136,8 @@ namespace bpkg
repository_fragments& chain,
bool prereq)
{
+ assert (!masked_repository_fragment (rf));
+
// Prerequisites are not searched through recursively.
//
assert (!prereq || chain.empty ());
@@ -159,6 +161,9 @@ namespace bpkg
{
const lazy_shared_ptr<repository_fragment>& lrf (pl.repository_fragment);
+ if (masked_repository_fragment (lrf))
+ continue;
+
// First check the repository itself.
//
if (lrf.object_id () == rf->name)
@@ -175,20 +180,26 @@ namespace bpkg
for (const lazy_weak_ptr<repository>& r: cs)
{
- const auto& frs (r.load ()->fragments);
+ if (!masked_repository (r))
+ {
+ const auto& frs (r.load ()->fragments);
- if (find_if (frs.begin (), frs.end (), pr) != frs.end ())
- return lrf.load ();
+ if (find_if (frs.begin (), frs.end (), pr) != frs.end ())
+ return lrf.load ();
+ }
}
if (prereq)
{
for (const lazy_weak_ptr<repository>& r: ps)
{
- const auto& frs (r.load ()->fragments);
+ if (!masked_repository (r))
+ {
+ const auto& frs (r.load ()->fragments);
- if (find_if (frs.begin (), frs.end (), pr) != frs.end ())
- return lrf.load ();
+ if (find_if (frs.begin (), frs.end (), pr) != frs.end ())
+ return lrf.load ();
+ }
}
}
}
@@ -198,14 +209,17 @@ namespace bpkg
//
for (const lazy_weak_ptr<repository>& cr: cs)
{
- for (const auto& fr: cr.load ()->fragments)
+ if (!masked_repository (cr))
{
- // Should we consider prerequisites of our complements as our
- // prerequisites? I'd say not.
- //
- if (shared_ptr<repository_fragment> r =
- find (fr.fragment.load (), ap, chain, false))
- return r;
+ for (const auto& fr: cr.load ()->fragments)
+ {
+ // Should we consider prerequisites of our complements as our
+ // prerequisites? I'd say not.
+ //
+ if (shared_ptr<repository_fragment> r =
+ find (fr.fragment.load (), ap, chain, false))
+ return r;
+ }
}
}
@@ -213,11 +227,14 @@ namespace bpkg
{
for (const lazy_weak_ptr<repository>& pr: ps)
{
- for (const auto& fr: pr.load ()->fragments)
+ if (!masked_repository (pr))
{
- if (shared_ptr<repository_fragment> r =
- find (fr.fragment.load (), ap, chain, false))
- return r;
+ for (const auto& fr: pr.load ()->fragments)
+ {
+ if (shared_ptr<repository_fragment> r =
+ find (fr.fragment.load (), ap, chain, false))
+ return r;
+ }
}
}
}
@@ -239,6 +256,8 @@ namespace bpkg
result<available_package>&& apr,
bool prereq)
{
+ assert (!masked_repository_fragment (r));
+
vector<shared_ptr<available_package>> aps;
for (shared_ptr<available_package> ap: pointer_result (apr))
@@ -258,6 +277,8 @@ namespace bpkg
using result = pair<shared_ptr<available_package>,
shared_ptr<repository_fragment>>;
+ assert (!masked_repository_fragment (r));
+
for (shared_ptr<available_package> ap: pointer_result (apr))
{
if (shared_ptr<repository_fragment> pr = filter (r, ap, prereq))
@@ -345,15 +366,20 @@ namespace bpkg
for (shared_ptr<available_package> ap:
pointer_result (query_available (db, name, c)))
{
- // An available package should come from at least one fetched
- // repository fragment.
+ // All repository fragments the package comes from are equally good,
+ // so we pick the first unmasked one.
//
- assert (!ap->locations.empty ());
+ for (const auto& pl: ap->locations)
+ {
+ const lazy_shared_ptr<repository_fragment>& lrf (
+ pl.repository_fragment);
- // All repository fragments the package comes from are equally good, so
- // we pick the first one.
- //
- r.emplace_back (move (ap), ap->locations[0].repository_fragment);
+ if (!masked_repository_fragment (lrf))
+ {
+ r.emplace_back (move (ap), lrf);
+ break;
+ }
+ }
}
}
@@ -415,6 +441,8 @@ namespace bpkg
const lazy_shared_ptr<repository_fragment>& rf,
bool prereq)
{
+ assert (!masked_repository_fragment (rf));
+
vector<shared_ptr<available_package>> r;
database& db (rf.database ());
@@ -438,6 +466,8 @@ namespace bpkg
bool prereq,
bool revision)
{
+ assert (!masked_repository_fragment (rf));
+
// Filter the result based on the repository fragment to which each
// version belongs.
//
@@ -527,17 +557,22 @@ namespace bpkg
const shared_ptr<selected_package>& sp)
{
available_package_id pid (sp->name, sp->version);
+ const string& cn (sp->repository_fragment.canonical_name ());
+
for (database& ddb: dependent_repo_configs (db))
{
shared_ptr<available_package> ap (ddb.find<available_package> (pid));
if (ap != nullptr && !ap->stub ())
{
- if (shared_ptr<repository_fragment> f = ddb.find<repository_fragment> (
- sp->repository_fragment.canonical_name ()))
- return make_pair (ap,
- lazy_shared_ptr<repository_fragment> (ddb,
- move (f)));
+ if (shared_ptr<repository_fragment> f =
+ ddb.find<repository_fragment> (cn))
+ {
+ if (!masked_repository_fragment (f))
+ return make_pair (ap,
+ lazy_shared_ptr<repository_fragment> (ddb,
+ move (f)));
+ }
}
}
@@ -592,15 +627,20 @@ namespace bpkg
pointer_result (
query_available (db, name, nullopt /* version_constraint */)))
{
- // An available package should come from at least one fetched
- // repository fragment.
+ // All repository fragments the package comes from are equally good,
+ // so we pick the first unmasked one.
//
- assert (!ap->locations.empty ());
+ for (const auto& pl: ap->locations)
+ {
+ const lazy_shared_ptr<repository_fragment>& lrf (
+ pl.repository_fragment);
- // All repository fragments the package comes from are equally good, so
- // we pick the first one.
- //
- r.emplace_back (move (ap), ap->locations[0].repository_fragment);
+ if (!masked_repository_fragment (lrf))
+ {
+ r.emplace_back (move (ap), lrf);
+ break;
+ }
+ }
}
}
@@ -638,14 +678,18 @@ namespace bpkg
// anyway.
//
lazy_shared_ptr<repository_fragment> rf;
+ const string& cn (sp->repository_fragment.canonical_name ());
for (database& ddb: dependent_repo_configs (db))
{
- if (shared_ptr<repository_fragment> f = ddb.find<repository_fragment> (
- sp->repository_fragment.canonical_name ()))
+ if (shared_ptr<repository_fragment> f =
+ ddb.find<repository_fragment> (cn))
{
- rf = lazy_shared_ptr<repository_fragment> (ddb, move (f));
- break;
+ if (!masked_repository_fragment (f))
+ {
+ rf = lazy_shared_ptr<repository_fragment> (ddb, move (f));
+ break;
+ }
}
}
diff --git a/bpkg/package.cxx b/bpkg/package.cxx
index c98e7a4..c19f95d 100644
--- a/bpkg/package.cxx
+++ b/bpkg/package.cxx
@@ -17,6 +17,41 @@ namespace bpkg
{
const version wildcard_version (0, "0", nullopt, nullopt, 0);
+ // repository
+ //
+ bool
+ masked_repository (const lazy_weak_ptr<repository>& rf)
+ {
+ // Optimize for the common case when no repositories are masked to avoid
+ // an unnecessary load of the lazy pointer.
+ //
+ return masked_repositories () && masked_repository (rf.load ()->location);
+ }
+
+ bool
+ masked_repository (const shared_ptr<repository>& rf)
+ {
+ return masked_repository (rf->location);
+ }
+
+ // repository_fragment
+ //
+ bool
+ masked_repository_fragment (const lazy_shared_ptr<repository_fragment>& rf)
+ {
+ // Optimize for the common case when no repositories are masked to avoid
+ // an unnecessary load of the lazy pointer.
+ //
+ return masked_repositories () &&
+ masked_repository_fragment (rf.load ()->location);
+ }
+
+ bool
+ masked_repository_fragment (const shared_ptr<repository_fragment>& rf)
+ {
+ return masked_repository_fragment (rf->location);
+ }
+
// configuration
//
configuration::
@@ -373,7 +408,8 @@ namespace bpkg
{
const shared_ptr<repository_fragment>& rf (prf.repository_fragment);
- if (rf->location.directory_based ())
+ if (!masked_repository_fragment (rf) &&
+ rf->location.directory_based ())
fail << "external package " << n << '/' << v
<< " is already available from "
<< rf->location.canonical_name ();
diff --git a/bpkg/package.hxx b/bpkg/package.hxx
index 060f13a..d18742e 100644
--- a/bpkg/package.hxx
+++ b/bpkg/package.hxx
@@ -454,6 +454,18 @@ namespace bpkg
operator size_t () const {return result;}
};
+ bool
+ masked_repository (const lazy_weak_ptr<repository>&);
+
+ bool
+ masked_repository (const shared_ptr<repository>&);
+
+ bool
+ masked_repository_fragment (const lazy_shared_ptr<repository_fragment>&);
+
+ bool
+ masked_repository_fragment (const shared_ptr<repository_fragment>&);
+
// repository
//
#pragma db object pointer(shared_ptr) session
diff --git a/bpkg/pkg-build-collect.cxx b/bpkg/pkg-build-collect.cxx
index 86dcb24..73b5dc0 100644
--- a/bpkg/pkg-build-collect.cxx
+++ b/bpkg/pkg-build-collect.cxx
@@ -153,7 +153,20 @@ namespace bpkg
// If adjustment or orphan, then new and old are the same.
//
- if (available == nullptr || available->locations.empty ())
+ small_vector<reference_wrapper<const package_location>, 8> locations;
+
+ if (available != nullptr)
+ {
+ locations.reserve (available->locations.size ());
+
+ for (const package_location& pl: available->locations)
+ {
+ if (!masked_repository_fragment (pl.repository_fragment))
+ locations.push_back (pl);
+ }
+ }
+
+ if (locations.empty ())
{
assert (selected != nullptr);
@@ -169,7 +182,7 @@ namespace bpkg
}
else
{
- const package_location& pl (available->locations[0]);
+ const package_location& pl (locations[0]);
if (pl.repository_fragment.object_id () == "") // Special root?
{
@@ -189,7 +202,7 @@ namespace bpkg
// Note that such repository fragments are always preferred over
// others (see below).
//
- for (const package_location& pl: available->locations)
+ for (const package_location& pl: locations)
{
const repository_location& rl (
pl.repository_fragment.load ()->location);
@@ -1127,7 +1140,7 @@ namespace bpkg
void build_packages::
enter (package_name name, build_package pkg)
{
- assert (!pkg.action);
+ assert (!pkg.action && pkg.repository_fragment == nullptr);
database& db (pkg.db); // Save before the move() call.
auto p (map_.emplace (package_key {db, move (name)},
@@ -1157,6 +1170,9 @@ namespace bpkg
tracer trace ("collect_build");
+ assert (pkg.repository_fragment == nullptr ||
+ !masked_repository_fragment (pkg.repository_fragment));
+
// See the above notes.
//
bool recursive (dep_chain != nullptr);
diff --git a/bpkg/pkg-build.cli b/bpkg/pkg-build.cli
index 05d4077..244ebac 100644
--- a/bpkg/pkg-build.cli
+++ b/bpkg/pkg-build.cli
@@ -397,6 +397,15 @@ namespace bpkg
option in \l{bpkg-rep-fetch(1)} for details."
}
+ strings --mask-repository
+ {
+ "<rep>",
+ "Pretend, for the duration of the command execution, that repository
+ doesn't exist in the configuration. The repository can be specified
+ either as a repository name or as a repository location (URL or a
+ directory path). Repeat this option to mask multiple repositories."
+ }
+
bool --no-refinement
{
"Don't try to refine the configuration by offering to drop any unused
diff --git a/bpkg/pkg-build.cxx b/bpkg/pkg-build.cxx
index a469a2b..d48f6af 100644
--- a/bpkg/pkg-build.cxx
+++ b/bpkg/pkg-build.cxx
@@ -75,6 +75,17 @@ namespace bpkg
const available_package_id& id,
config_repo_fragments& r)
{
+#ifndef NDEBUG
+ if (masked_repositories ())
+ {
+ for (const auto& v: r)
+ {
+ for (const shared_ptr<repository_fragment>& f: v.second)
+ assert (!masked_repository_fragment (f));
+ }
+ }
+#endif
+
for (database& ddb: dependent_repo_configs (db))
{
shared_ptr<available_package> dap (ddb.find<available_package> (id));
@@ -93,11 +104,24 @@ namespace bpkg
for (const auto& pl: dap->locations)
{
- shared_ptr<repository_fragment> rf (pl.repository_fragment.load ());
+ const lazy_shared_ptr<repository_fragment>& lrf (
+ pl.repository_fragment);
- if (find (rfs.begin (), rfs.end (), rf) == rfs.end ())
- rfs.push_back (move (rf));
+ if (!masked_repository_fragment (lrf))
+ {
+ shared_ptr<repository_fragment> rf (lrf.load ());
+
+ if (find (rfs.begin (), rfs.end (), rf) == rfs.end ())
+ rfs.push_back (move (rf));
+ }
}
+
+ // If we didn't add any repository fragments from this database since
+ // all of the available package repositories are masked, then just
+ // erase the entry in the map if it contains no fragments.
+ //
+ if (rfs.empty ())
+ r.erase (i);
}
}
}
@@ -171,8 +195,12 @@ namespace bpkg
for (database& ddb: dependent_repo_configs (db))
{
- if (ddb.find<repository_fragment> (cn) != nullptr)
- return false;
+ if (shared_ptr<repository_fragment> f =
+ ddb.find<repository_fragment> (cn))
+ {
+ if (!masked_repository_fragment (f))
+ return false;
+ }
}
return true;
@@ -1485,6 +1513,11 @@ namespace bpkg
validate_options (o, ""); // Global package options.
+ // Mask the repositories.
+ //
+ for (const string& r: o.mask_repository ())
+ mask_repository (r);
+
// Note that the session spans all our transactions. The idea here is that
// selected_package objects in build_packages below will be cached in this
// session. When subsequent transactions modify any of these objects, they
@@ -1741,6 +1774,10 @@ namespace bpkg
info << "repository location cannot be specified for "
<< "dependencies";
+ if (masked_repositories ())
+ fail << "package repository location may not be specified "
+ << "together with --mask-repository option";
+
string pks (p > 1 ? string (a, 0, p - 1) : empty_string);
for (size_t i (0); i != dbs.size (); ++i)
@@ -2338,6 +2375,10 @@ namespace bpkg
//
database& pdb (ps.db);
+ // Should have failed earlier.
+ //
+ assert (!masked_repository (ps.location));
+
// Expand the [[<packages>]@]<location> spec. Fail if the repository
// is not found in this configuration, that can be the case in the
// presence of --no-fetch option.
@@ -5763,18 +5804,24 @@ namespace bpkg
for (const package_location& l: ap->locations)
{
- const repository_location& rl (
- l.repository_fragment.load ()->location);
-
- if (!basis || rl.local ()) // First or local?
+ if (!masked_repository_fragment (l.repository_fragment))
{
- basis = rl.basis ();
+ const repository_location& rl (
+ l.repository_fragment.load ()->location);
- if (rl.directory_based ())
- break;
+ if (!basis || rl.local ()) // First or local?
+ {
+ basis = rl.basis ();
+
+ if (rl.directory_based ())
+ break;
+ }
}
}
+ // We should have failed earlier if all the package repository
+ // fragments are masked.
+ //
assert (basis);
// All calls commit the transaction.
diff --git a/bpkg/pkg-checkout.cxx b/bpkg/pkg-checkout.cxx
index 9793c41..7a78cb6 100644
--- a/bpkg/pkg-checkout.cxx
+++ b/bpkg/pkg-checkout.cxx
@@ -148,14 +148,17 @@ namespace bpkg
for (const package_location& l: ap->locations)
{
- const repository_location& rl (l.repository_fragment.load ()->location);
-
- if (rl.version_control_based () && (pl == nullptr || rl.local ()))
+ if (!masked_repository_fragment (l.repository_fragment))
{
- pl = &l;
+ const repository_location& rl (l.repository_fragment.load ()->location);
+
+ if (rl.version_control_based () && (pl == nullptr || rl.local ()))
+ {
+ pl = &l;
- if (rl.local ())
- break;
+ if (rl.local ())
+ break;
+ }
}
}
diff --git a/bpkg/pkg-fetch.cxx b/bpkg/pkg-fetch.cxx
index 50f0937..2917c51 100644
--- a/bpkg/pkg-fetch.cxx
+++ b/bpkg/pkg-fetch.cxx
@@ -224,14 +224,17 @@ namespace bpkg
for (const package_location& l: ap->locations)
{
- const repository_location& rl (l.repository_fragment.load ()->location);
-
- if (rl.archive_based () && (pl == nullptr || rl.local ()))
+ if (!masked_repository_fragment (l.repository_fragment))
{
- pl = &l;
+ const repository_location& rl (l.repository_fragment.load ()->location);
+
+ if (rl.archive_based () && (pl == nullptr || rl.local ()))
+ {
+ pl = &l;
- if (rl.local ())
- break;
+ if (rl.local ())
+ break;
+ }
}
}
diff --git a/bpkg/pkg-unpack.cxx b/bpkg/pkg-unpack.cxx
index 5c88cc6..1d55ab6 100644
--- a/bpkg/pkg-unpack.cxx
+++ b/bpkg/pkg-unpack.cxx
@@ -70,6 +70,8 @@ namespace bpkg
bool purge,
bool simulate)
{
+ assert (!masked_repository_fragment (rl));
+
// Make the package path absolute and normalized. If the package is inside
// the configuration, use the relative path. This way we can move the
// configuration around.
@@ -304,7 +306,8 @@ namespace bpkg
for (const package_location& l: ap->locations)
{
- if (l.repository_fragment.load ()->location.directory_based ())
+ if (!masked_repository_fragment (l.repository_fragment) &&
+ l.repository_fragment.load ()->location.directory_based ())
{
pl = &l;
break;
diff --git a/bpkg/rep-fetch.cxx b/bpkg/rep-fetch.cxx
index 6f31478..e267412 100644
--- a/bpkg/rep-fetch.cxx
+++ b/bpkg/rep-fetch.cxx
@@ -871,6 +871,8 @@ namespace bpkg
}
}
+ assert (!masked_repository_fragment (rfl));
+
shared_ptr<repository_fragment> rf (
db.find<repository_fragment> (rfl.canonical_name ()));
@@ -1229,6 +1231,8 @@ namespace bpkg
tracer_guard tg (db, trace);
+ assert (!masked_repository (r));
+
// Check that the repository is not fetched yet and register it as fetched
// otherwise.
//
diff --git a/bpkg/rep-remove.cxx b/bpkg/rep-remove.cxx
index 700534f..0c28159 100644
--- a/bpkg/rep-remove.cxx
+++ b/bpkg/rep-remove.cxx
@@ -284,6 +284,28 @@ namespace bpkg
}
void
+ rep_mask (const strings& repos)
+ {
+ // @@ Do we want to fail if a name or url is not present in all the dbs?
+ //
+
+ for (database& db: repo_configs)
+ {
+ for (const string& repo: repos)
+ {
+ if (repository_name (repo))
+ {
+ if (shared_ptr<repository> r
+ }
+ else
+ {
+
+ }
+ }
+ }
+ }
+
+ void
rep_remove_clean (const common_options& o, database& db, bool quiet)
{
tracer trace ("rep_remove_clean");
diff --git a/bpkg/rep-remove.hxx b/bpkg/rep-remove.hxx
index 0fc82e8..41d8578 100644
--- a/bpkg/rep-remove.hxx
+++ b/bpkg/rep-remove.hxx
@@ -57,6 +57,9 @@ namespace bpkg
rep_remove_package_locations (database&,
transaction&,
const string& fragment_name);
+
+ void
+ rep_mask (const strings&);
}
#endif // BPKG_REP_REMOVE_HXX
diff --git a/bpkg/system-package-manager.cxx b/bpkg/system-package-manager.cxx
index 373e8ff..6f8026d 100644
--- a/bpkg/system-package-manager.cxx
+++ b/bpkg/system-package-manager.cxx
@@ -13,6 +13,7 @@
#include <bpkg/package-odb.hxx>
#include <bpkg/database.hxx>
#include <bpkg/diagnostics.hxx>
+#include <bpkg/manifest-utility.hxx>
#include <bpkg/pkg-bindist-options.hxx>
@@ -566,6 +567,8 @@ namespace bpkg
for (const auto& a: aps)
{
+ assert (!masked_repository_fragment (a.second));
+
const shared_ptr<available_package>& ap (a.first);
for (const distribution_name_value& nv: ap->distribution_values)