aboutsummaryrefslogtreecommitdiff
path: root/bpkg/manifest-utility.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'bpkg/manifest-utility.cxx')
-rw-r--r--bpkg/manifest-utility.cxx92
1 files changed, 92 insertions, 0 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,