aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bpkg/pkg-command.cxx2
-rw-r--r--bpkg/pkg-drop.cli33
-rw-r--r--bpkg/pkg-drop.cxx102
-rw-r--r--tests/pkg-drop.testscript61
4 files changed, 170 insertions, 28 deletions
diff --git a/bpkg/pkg-command.cxx b/bpkg/pkg-command.cxx
index e07d801..5788e11 100644
--- a/bpkg/pkg-command.cxx
+++ b/bpkg/pkg-command.cxx
@@ -310,7 +310,7 @@ namespace bpkg
{
using query = query<selected_package>;
- query q (query::hold_package &&
+ query q (query::hold_package &&
query::state == "configured" &&
query::substate != "system");
diff --git a/bpkg/pkg-drop.cli b/bpkg/pkg-drop.cli
index ac282d6..7c2b0bd 100644
--- a/bpkg/pkg-drop.cli
+++ b/bpkg/pkg-drop.cli
@@ -14,17 +14,21 @@ namespace bpkg
"\h|SYNOPSIS|
- \c{\b{bpkg pkg-drop}|\b{drop} [<options>] <pkg>...}
+ \c{\b{bpkg pkg-drop}|\b{drop} [<options>] <pkg>...\n
+ \b{bpkg pkg-drop}|\b{drop} [<options>] \b{--all}|\b{-a}\n
+ \b{bpkg pkg-drop}|\b{drop} [<options>] (\b{--all-pattern} <pattern>)...}
\h|DESCRIPTION|
- The \cb{pkg-drop} command drops one or more packages from the
- configuration. If the packages being dropped still have dependent
- packages, then those will have to be dropped as well and you will be
- prompted to confirm. And if the packages being dropped have dependency
- packages that would otherwise no longer be used, then they will be
- dropped as well unless the \c{\b{--keep-unused}|\b{-K}} option is
- specified.
+ The \cb{pkg-drop} command drops from the configuration the specified
+ packages (the first form), all the held packages (the second form, see
+ \l{bpkg-pkg-status(1)}), or all the held packages that match any of the
+ specified wildcard patterns (the third form). If the packages being
+ dropped still have dependent packages, then those will have to be dropped
+ as well and you will be prompted to confirm. And if the packages being
+ dropped have dependency packages that would otherwise no longer be used,
+ then they will be dropped as well unless the \c{\b{--keep-unused}|\b{-K}}
+ option is specified.
The \cb{pkg-drop} command also supports several options (described below)
that allow you to control the amount of work that will be done."
@@ -34,6 +38,19 @@ namespace bpkg
{
"\h|PKG-DROP OPTIONS|"
+ bool --all|-a
+ {
+ "Drop all held packages."
+ }
+
+ strings --all-pattern
+ {
+ "<pattern>",
+ "Drop held packages that match the specified wildcard pattern. Repeat
+ this option to match multiple patterns. Note that you may need to quote
+ the pattern to prevent expansion by your shell."
+ }
+
bool --yes|-y
{
"Assume the answer to all prompts is \cb{yes}. Note that this option
diff --git a/bpkg/pkg-drop.cxx b/bpkg/pkg-drop.cxx
index 0aadaa7..7def795 100644
--- a/bpkg/pkg-drop.cxx
+++ b/bpkg/pkg-drop.cxx
@@ -7,6 +7,8 @@
#include <list>
#include <iostream> // cout
+#include <libbutl/path-pattern.hxx>
+
#include <bpkg/package.hxx>
#include <bpkg/package-odb.hxx>
#include <bpkg/database.hxx>
@@ -506,17 +508,40 @@ namespace bpkg
const dir_path& c (o.directory ());
l4 ([&]{trace << "configuration: " << c;});
- if (o.yes () && o.no ())
- fail << "both --yes|-y and --no|-n specified";
+ {
+ diag_record dr;
- if (o.drop_dependent () && o.keep_dependent ())
- fail << "both --drop-dependent and --keep-dependent|-K "
- << "specified" <<
- info << "run 'bpkg help pkg-drop' for more information";
+ if (o.yes () && o.no ())
+ {
+ dr << fail << "both --yes|-y and --no|-n specified";
+ }
+ else if (o.drop_dependent () && o.keep_dependent ())
+ {
+ dr << fail << "both --drop-dependent and --keep-dependent|-K "
+ << "specified";
+ }
+ else if (o.all ())
+ {
+ if (o.all_pattern_specified ())
+ dr << fail << "both --all|-a and --all-pattern specified";
+
+ if (args.more ())
+ dr << fail << "both --all|-a and package argument specified";
+ }
+ else if (o.all_pattern_specified ())
+ {
+ if (args.more ())
+ dr << fail << "both --all-pattern and package argument specified";
+ }
+ else if (!args.more ())
+ {
+ dr << fail << "package name argument expected";
+ }
+
+ if (!dr.empty ())
+ dr << info << "run 'bpkg help pkg-drop' for more information";
+ }
- if (!args.more ())
- fail << "package name argument expected" <<
- info << "run 'bpkg help pkg-drop' for more information";
database db (c, trace, true /* pre_attach */);
@@ -546,17 +571,10 @@ namespace bpkg
// by the user.
//
vector<package_name> names;
- while (args.more ())
- {
- package_name n (parse_package_name (args.next (),
- false /* allow_version */));
- l4 ([&]{trace << "package " << n;});
-
- shared_ptr<selected_package> p (db.find<selected_package> (n));
-
- if (p == nullptr)
- fail << "package " << n << " does not exist in configuration " << c;
+ auto add = [&names, &pkgs, &db] (shared_ptr<selected_package>&& p)
+ {
+ package_name n (p->name);
if (p->state == package_state::broken)
fail << "unable to drop broken package " << n <<
@@ -564,6 +582,52 @@ namespace bpkg
if (pkgs.collect (db, move (p)))
names.push_back (move (n));
+ };
+
+ if (o.all () || o.all_pattern_specified ())
+ {
+ using query = query<selected_package>;
+
+ for (shared_ptr<selected_package> p:
+ pointer_result (
+ db.query<selected_package> (query::hold_package)))
+ {
+ l4 ([&]{trace << *p;});
+
+ if (o.all_pattern_specified ())
+ {
+ for (const string& pat: o.all_pattern ())
+ {
+ if (path_match (p->name.string (), pat))
+ {
+ add (move (p));
+ break;
+ }
+ }
+ }
+ else // --all
+ add (move (p));
+ }
+
+ if (names.empty ())
+ info << "nothing to drop";
+ }
+ else
+ {
+ while (args.more ())
+ {
+ package_name n (parse_package_name (args.next (),
+ false /* allow_version */));
+
+ l4 ([&]{trace << "package " << n;});
+
+ shared_ptr<selected_package> p (db.find<selected_package> (n));
+
+ if (p == nullptr)
+ fail << "package " << n << " does not exist in configuration " << c;
+
+ add (move (p));
+ }
}
// The next step is to see if there are any dependents that are not
diff --git a/tests/pkg-drop.testscript b/tests/pkg-drop.testscript
index 9029970..577c5fb 100644
--- a/tests/pkg-drop.testscript
+++ b/tests/pkg-drop.testscript
@@ -39,6 +39,22 @@ $* 2>>EOE != 0
info: run 'bpkg help pkg-drop' for more information
EOE
+: all-all-pattern
+:
+$clone_cfg;
+$* --all --all-pattern 'lib*' 2>>EOE != 0
+ error: both --all|-a and --all-pattern specified
+ info: run 'bpkg help pkg-drop' for more information
+ EOE
+
+: all-pattern-name
+:
+$clone_cfg;
+$* --all-pattern 'lib*' libbaz 2>>EOE != 0
+ error: both --all-pattern and package argument specified
+ info: run 'bpkg help pkg-drop' for more information
+ EOE
+
: unknown-package
:
$clone_cfg;
@@ -765,3 +781,48 @@ $* libfoo/1.0.0 2>>~%EOE% != 0
EOE
}
}
+
+: all-options
+:
+{
+ +$clone_cfg && $rep_add $rep/t4b $rep/t4c && $rep_fetch
+
+ test.arguments += --yes
+
+ : all
+ :
+ {
+ $clone_cfg;
+
+ $pkg_build libbaz libbar;
+
+ $* --all 2>>EOO
+ disfigured libbaz
+ disfigured libbar
+ disfigured libfoo
+ purged libbaz
+ purged libbar
+ purged libfoo
+ EOO
+ }
+
+ : all-pattern
+ :
+ {
+ $clone_cfg;
+
+ $pkg_build libbaz libbar libfoo;
+
+ $* --all-pattern 'libb*' 2>>EOO;
+ disfigured libbaz
+ disfigured libbar
+ purged libbaz
+ purged libbar
+ EOO
+
+ $* --all-pattern '*' 2>>EOO
+ disfigured libfoo
+ purged libfoo
+ EOO
+ }
+}