diff options
-rw-r--r-- | bpkg/pkg-command.cxx | 2 | ||||
-rw-r--r-- | bpkg/pkg-drop.cli | 33 | ||||
-rw-r--r-- | bpkg/pkg-drop.cxx | 102 | ||||
-rw-r--r-- | tests/pkg-drop.testscript | 61 |
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 + } +} |