aboutsummaryrefslogtreecommitdiff
path: root/bpkg
diff options
context:
space:
mode:
authorKaren Arutyunov <karen@codesynthesis.com>2023-06-20 20:22:29 +0300
committerKaren Arutyunov <karen@codesynthesis.com>2023-06-21 12:01:03 +0300
commitfdfd3e0644095022b61316e220fce3f5a7a1a9ef (patch)
treeb4e8098437fe5e11920aebd71dd581212c4d2f10 /bpkg
parent8ae1780760db7f73c7045481e6fd18c7fbada60d (diff)
Add --mask-repository-uuid pkg-build option
Diffstat (limited to 'bpkg')
-rw-r--r--bpkg/pkg-build.cli13
-rw-r--r--bpkg/pkg-build.cxx6
-rw-r--r--bpkg/rep-mask.cxx136
-rw-r--r--bpkg/rep-mask.hxx21
4 files changed, 150 insertions, 26 deletions
diff --git a/bpkg/pkg-build.cli b/bpkg/pkg-build.cli
index 3db6e9f..a365082 100644
--- a/bpkg/pkg-build.cli
+++ b/bpkg/pkg-build.cli
@@ -411,6 +411,19 @@ namespace bpkg
mask multiple repositories."
}
+ strings --mask-repository-uuid
+ {
+ "<v>",
+ "For the duration of the command execution pretend the specified
+ repository was removed from the specified configuration. Similar to
+ \cb{--mask-repository} but only masks the repository in a single
+ configuration. The option value is a key-value pair in the form:
+
+ \c{\i{config-uuid}\b{=}\i{rep}}
+
+ 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 6101826..848dc39 100644
--- a/bpkg/pkg-build.cxx
+++ b/bpkg/pkg-build.cxx
@@ -2000,8 +2000,10 @@ namespace bpkg
// Now, as repo_configs is filled and the repositories are fetched mask
// the repositories, if any.
//
- if (o.mask_repository_specified ())
- rep_mask (o.mask_repository ());
+ if (o.mask_repository_specified () || o.mask_repository_uuid_specified ())
+ rep_mask (o.mask_repository (),
+ o.mask_repository_uuid (),
+ current_configs);
// Expand the package specs into individual package args, parsing them
// into the package scheme, name, and version constraint components, and
diff --git a/bpkg/rep-mask.cxx b/bpkg/rep-mask.cxx
index 79aef42..d7f9c6a 100644
--- a/bpkg/rep-mask.cxx
+++ b/bpkg/rep-mask.cxx
@@ -26,16 +26,26 @@ namespace bpkg
const shared_ptr<repository>&,
bool mask);
- // The idea here is to start the transaction, remove all the specified
- // repositories recursively in all the configurations specified by
- // repo_configs, collect the remaining repositories and repository fragments
- // as unmasked, and rollback the transaction. Later on, the rep_masked*()
- // functions will refer to the configuration-specific unmasked repositories
- // and repository fragments lists to decide if the repository is masked or
- // not in the specific configuration.
+ // The overall plan is as follows:
+ //
+ // - Start the transaction.
+ //
+ // - Remove all the specified repositories recursively in all the
+ // configurations specified by repo_configs (repos) and/or configurations
+ // specified explicitly via UUIDs (config_uuid_repos).
+ //
+ // - Collect the remaining repositories and repository fragments as unmasked.
+ //
+ // - Rollback the transaction.
+ //
+ // Later on, the rep_masked*() functions will refer to the configuration-
+ // specific unmasked repositories and repository fragments lists to decide
+ // if the repository/fragment is masked or not in the specific configuration.
//
void
- rep_mask (const strings& repos)
+ rep_mask (const strings& repos,
+ const strings& config_uuid_repos,
+ linked_databases& current_configs)
{
tracer trace ("rep_mask");
@@ -55,22 +65,31 @@ namespace bpkg
transaction t (mdb);
+ // Add a repository from a database, suppressing duplicates.
+ //
+ auto add_repo = [&rs] (database& db, shared_ptr<repository>&& r)
+ {
+ if (find_if (rs.begin (), rs.end (),
+ [&db, &r] (const lazy_weak_ptr<repository>& lr)
+ {
+ return lr.database () == db && lr.object_id () == r->name;
+ }) == rs.end ())
+ rs.emplace_back (db, move (r));
+ };
+
+ // Collect the repositories masked in all configurations.
+ //
for (database& db: repo_configs)
{
for (size_t i (0); i != repos.size (); ++i)
{
// Add a repository, suppressing duplicates, and mark it as found.
//
- auto add = [&db, &rs, &found_repos, i] (shared_ptr<repository>&& r)
+ auto add = [&db,
+ &found_repos, i,
+ &add_repo] (shared_ptr<repository>&& r)
{
- if (find_if (rs.begin (), rs.end (),
- [&db, &r] (const lazy_weak_ptr<repository>& lr)
- {
- return lr.database () == db &&
- lr.object_id () == r->name;
- }) == rs.end ())
- rs.emplace_back (db, move (r));
-
+ add_repo (db, move (r));
found_repos[i] = true;
};
@@ -114,6 +133,89 @@ namespace bpkg
fail << "repository '" << repos[i] << "' cannot be masked: not found";
}
+ // Collect the repositories masked in specific configurations.
+ //
+ for (const string& cr: config_uuid_repos)
+ {
+ auto bad = [&cr] (const string& d)
+ {
+ fail << "configuration repository '" << cr << "' cannot be masked: "
+ << d;
+ };
+
+ size_t p (cr.find ('='));
+
+ if (p == string::npos)
+ bad ("missing '='");
+
+ uuid uid;
+ string uid_str (cr, 0, p);
+
+ try
+ {
+ uid = uuid (uid_str);
+ }
+ catch (const invalid_argument& e)
+ {
+ bad ("invalid configuration uuid '" + uid_str + "': " + e.what ());
+ }
+
+ database* db (nullptr);
+
+ for (database& cdb: current_configs)
+ {
+ if ((db = cdb.try_find_dependency_config (uid)) != nullptr)
+ break;
+ }
+
+ if (db == nullptr)
+ bad ("no configuration with uuid " + uid.string () +
+ " is linked with " +
+ (current_configs.size () == 1
+ ? mdb.config_orig.representation ()
+ : "specified current configurations"));
+
+ string rp (cr, p + 1);
+
+ if (repository_name (rp))
+ {
+ if (shared_ptr<repository> r = db->find<repository> (rp))
+ add_repo (*db, move (r));
+ else
+ bad ("repository name '" + rp + "' not found in configuration " +
+ uid.string ());
+ }
+ else
+ {
+ using query = query<repository>;
+
+ // Verify that the repository URL is not misspelled or empty.
+ //
+ try
+ {
+ repository_url u (rp);
+ assert (!u.empty ());
+ }
+ catch (const invalid_argument& e)
+ {
+ bad ("invalid repository location '" + rp + "': " + e.what ());
+ }
+
+ bool found (false);
+ for (shared_ptr<repository> r:
+ pointer_result (
+ db->query<repository> (query::location.url == rp)))
+ {
+ add_repo (*db, move (r));
+ found = true;
+ }
+
+ if (!found)
+ bad ("repository location '" + rp + "' not found in configuration " +
+ uid.string ());
+ }
+ }
+
// First, remove the repository references from the dependent repository
// fragments. Note that rep_remove() removes the dangling repositories.
//
diff --git a/bpkg/rep-mask.hxx b/bpkg/rep-mask.hxx
index dd9cedf..2185af2 100644
--- a/bpkg/rep-mask.hxx
+++ b/bpkg/rep-mask.hxx
@@ -13,15 +13,20 @@ namespace bpkg
// Note: not a command (at least not yet).
//
// Mask repositories to pretend they don't exist in the configurations that
- // are used as the repository information sources (repo_configs). Also mask
- // their complement and prerequisite repositories, recursively, excluding
- // those which are complements and/or prerequisites of other unmasked
- // repositories. The repositories can be specified either as repository
- // location canonical names or URLs. Issue diagnostics and fail if any of
- // the specified repositories don't exist in any configuration.
+ // are used as the repository information sources (repo_configs;
+ // repositories argument) and/or specific configurations
+ // (config_uuid_repositories argument). Also mask their complement and
+ // prerequisite repositories, recursively, excluding those which are
+ // complements and/or prerequisites of other unmasked repositories. The
+ // repositories can be specified either as repository location canonical
+ // names or URLs. Issue diagnostics and fail if any of the specified
+ // repositories don't exist in any configuration.
//
// Notes:
//
+ // - The current configurations are only used to resolve the configuration
+ // UUIDs, if any.
+ //
// - A repository may end up being masked in one configuration but not in
// another.
//
@@ -36,7 +41,9 @@ namespace bpkg
// NOTE: repo_configs needs to be filled prior to the function call.
//
void
- rep_mask (const strings&);
+ rep_mask (const strings& repositories, // <rep>
+ const strings& config_uuid_repositories, // <config-uuid>=<rep>
+ linked_databases& current_configs);
// Return true if a repository is masked in the specified configuration.
//