aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2016-06-18 20:44:17 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2016-06-18 20:44:17 +0200
commit31421516334f8e41a04c75a1fed86b4cecd11526 (patch)
tree208efa3d67968e324cf11156341a8163744a9ecc
parentd84926cdaa7a5afffd620475f7deb13bbe3c2311 (diff)
Offer to update dependents in pkg-build, add options to pkg-{build,drop}
-rw-r--r--NEWS11
-rw-r--r--bpkg/pkg-build.cli39
-rw-r--r--bpkg/pkg-build.cxx70
-rw-r--r--bpkg/pkg-drop5
-rw-r--r--bpkg/pkg-drop.cli21
-rw-r--r--bpkg/pkg-drop.cxx41
-rwxr-xr-xtests/test.sh12
7 files changed, 167 insertions, 32 deletions
diff --git a/NEWS b/NEWS
index dcb6845..b561411 100644
--- a/NEWS
+++ b/NEWS
@@ -1,5 +1,16 @@
Version 0.4.0
+ * The pkg-build command now offers to automatically update dependent
+ packages that were reconfigured.
+
+ It also supports the following new options: --drop-prerequisite|-D,
+ --update-dependent|-U, --leave-dependent|-L, as well as the -K alias for
+ --keep-prerequisite. See the command's man page for details.
+
+ * The pkg-drop command now supports the following new options:
+ --keep-dependent|-K, --drop-prerequisite|-D, and --keep-prerequisite. See
+ the command's man page for details.
+
* Add support for repository authentication. The rep-create command can now
sign the repository, and cfg-fetch and rep-info commands can authenticate
the repository being fetched.
diff --git a/bpkg/pkg-build.cli b/bpkg/pkg-build.cli
index 9de38f2..e0ec9b1 100644
--- a/bpkg/pkg-build.cli
+++ b/bpkg/pkg-build.cli
@@ -20,11 +20,16 @@ namespace bpkg
\h|DESCRIPTION|
The \cb{pkg-build} command builds one or more packages including all their
- prerequisites. Each package can be specified as just the name (<pkg>) with
- optional package version (<ver>) in which case the package will be
- automatically fetched from one of the repositories. See the
- \l{bpkg-cfg-add(1)} and \l{bpkg-cfg-fetch(1)} commands for more
- information on package repositories.
+ prerequisites. Besides building new packages, this command is also used to
+ upgrade or downgrade packages that already exists in the configuration.
+
+ Each package can be specified as just the name (<pkg>) with optional
+ package version (<ver>) in which case the package will be automatically
+ fetched from one of the repositories. See the \l{bpkg-cfg-add(1)} and
+ \l{bpkg-cfg-fetch(1)} commands for more information on package
+ repositories. If <ver> is not specified, then the latest available
+ version will be built. To downgrade, the desired version must be
+ specified explicitly.
Alternatively, the package can be specified as either the path to the
package archive (<file>) or to the package directory (<dir>/; note that
@@ -39,8 +44,8 @@ namespace bpkg
addition, have their versions held, that is, they will not be
automatically upgraded.
- The \cb{pkg-build} command also supports several \cb{--*-only} options
- that allow you to limit the amount of work that will be done."
+ The \cb{pkg-build} command also supports several options (described
+ below) that allow you to control the amount of work that will be done."
}
class pkg_build_options: configuration_options
@@ -52,12 +57,30 @@ namespace bpkg
"Assume the answer to all prompts is \cb{yes}."
}
- bool --keep-prerequisite
+ bool --drop-prerequisite|-D
+ {
+ "Drop without confirmation prerequsite packages that were automatically
+ built and will no longer be necessary."
+ }
+
+ bool --keep-prerequisite|-K
{
"Don't offer to drop prerequsite packages that were automatically built
and will no longer be necessary."
}
+ bool --update-dependent|-U
+ {
+ "Update without confirmation dependent packages that are reconfigured
+ due to their prerequisites being upgraded or downgraded."
+ }
+
+ bool --leave-dependent|-L
+ {
+ "Don't offer to update dependent packages that are reconfigured due to
+ their prerequisites being upgraded or downgraded."
+ }
+
bool --print-only|-p
{
"Print to \cb{STDOUT} what would be done without actually doing
diff --git a/bpkg/pkg-build.cxx b/bpkg/pkg-build.cxx
index 9dc58c4..efb708b 100644
--- a/bpkg/pkg-build.cxx
+++ b/bpkg/pkg-build.cxx
@@ -807,6 +807,16 @@ namespace bpkg
const dir_path& c (o.directory ());
l4 ([&]{trace << "configuration: " << c;});
+ if (o.drop_prerequisite () && o.keep_prerequisite ())
+ fail << "both --drop-prerequisite|-D and --keep-prerequisite|-K "
+ << "specified" <<
+ info << "run 'bpkg help pkg-build' for more information";
+
+ if (o.update_dependent () && o.leave_dependent ())
+ fail << "both --update-dependent|-U and --leave-dependent|-L "
+ << "specified" <<
+ info << "run 'bpkg help pkg-build' for more information";
+
if (!args.more ())
fail << "package name argument expected" <<
info << "run 'bpkg help pkg-build' for more information";
@@ -1098,7 +1108,11 @@ namespace bpkg
}
// Print what we are going to do, then ask for the user's confirmation.
+ // While at it, detect if we have any dependents that the user may want to
+ // update.
//
+ bool update_dependents (false);
+
if (o.print_only () || !o.yes ())
{
for (const build_package& p: reverse_iterate (pkgs))
@@ -1107,12 +1121,15 @@ namespace bpkg
const shared_ptr<available_package>& ap (p.available);
string act;
+ string cause;
if (ap == nullptr)
{
// This is a dependent needing reconfiguration.
//
assert (sp != nullptr && p.reconfigure ());
+ update_dependents = true;
act = "reconfigure " + sp->name;
+ cause = "dependent of";
}
else
{
@@ -1139,6 +1156,7 @@ namespace bpkg
act = sp->version < ap->version ? "upgrade " : "downgrade ";
act += ap->id.name + ' ' + ap->version.string ();
+ cause = "required by";
}
string rb;
@@ -1149,7 +1167,7 @@ namespace bpkg
}
if (!rb.empty ())
- act += " (required by" + rb + ')';
+ act += " (" + cause + rb + ')';
if (o.print_only ())
cout << act << endl;
@@ -1166,6 +1184,15 @@ namespace bpkg
if (!(o.yes () || yn_prompt ("continue? [Y/n]", 'y')))
return 1;
+ // Figure out if we also should update dependents.
+ //
+ if (o.leave_dependent ())
+ update_dependents = false;
+ else if (o.yes () || o.update_dependent ())
+ update_dependents = true;
+ else if (update_dependents) // Don't prompt if there aren't any.
+ update_dependents = yn_prompt ("update dependent packages? [Y/n]", 'y');
+
// Ok, we have "all systems go". The overall action plan is as follows.
//
// 1. disfigure up/down-graded, reconfigured [left to right]
@@ -1197,6 +1224,11 @@ namespace bpkg
// established, we will pass them to pkg_drop() whose job will be to
// figure out which ones can be dropped, prompt the user, etc.
//
+ // We also have the other side of this logic: dependent packages that we
+ // reconfigure because their prerequsites got upgraded/downgraded and that
+ // the user may want to in addition update (that update_dependents flag
+ // above). This case we handle in house.
+ //
set<shared_ptr<selected_package>> drop_pkgs;
// disfigure
@@ -1362,6 +1394,15 @@ namespace bpkg
db.update (sp);
t.commit ();
+ // Clean up if this package ended up in the potention drop set.
+ //
+ if (hp)
+ {
+ auto i (drop_pkgs.find (sp));
+ if (i != drop_pkgs.end ())
+ drop_pkgs.erase (i);
+ }
+
if (verb > 1)
{
if (hp)
@@ -1377,7 +1418,8 @@ namespace bpkg
// packages that are no longer necessary.
//
if (!drop_pkgs.empty ())
- pkg_drop (c, o, db, drop_pkgs, !o.yes ());
+ drop_pkgs = pkg_drop (
+ c, o, db, drop_pkgs, !(o.yes () || o.drop_prerequisite ()));
if (o.configure_only ())
return 0;
@@ -1389,16 +1431,36 @@ namespace bpkg
//
vector<pkg_command_vars> upkgs;
+ // First add the user selection.
+ //
for (const build_package& p: reverse_iterate (pkgs))
{
const shared_ptr<selected_package>& sp (p.selected);
- // Update the user selection only.
- //
if (find (names.begin (), names.end (), sp->name) != names.end ())
upkgs.push_back (pkg_command_vars {sp, strings ()});
}
+ // Then add dependents. We do it as a separate step so that they are
+ // updated after the user selection.
+ //
+ if (update_dependents)
+ {
+ for (const build_package& p: reverse_iterate (pkgs))
+ {
+ const shared_ptr<selected_package>& sp (p.selected);
+
+ if (p.reconfigure () && p.available == nullptr)
+ {
+ // Note that it is entirely possible this package got dropped so
+ // we need to check for that.
+ //
+ if (drop_pkgs.find (sp) == drop_pkgs.end ())
+ upkgs.push_back (pkg_command_vars {sp, strings ()});
+ }
+ }
+ }
+
pkg_update (c, o, strings (), upkgs);
if (verb)
diff --git a/bpkg/pkg-drop b/bpkg/pkg-drop
index 4b7931e..23974af 100644
--- a/bpkg/pkg-drop
+++ b/bpkg/pkg-drop
@@ -19,9 +19,10 @@ namespace bpkg
pkg_drop (const pkg_drop_options&, cli::scanner& args);
// Examine the list of prerequisite packages and drop those that don't
- // have any dependents. Note that it should be called in session.
+ // have any dependents. Return the set of packages that were actually
+ // dropped. Note that it should be called in session.
//
- void
+ std::set<shared_ptr<selected_package>>
pkg_drop (const dir_path& configuration,
const common_options&,
database&,
diff --git a/bpkg/pkg-drop.cli b/bpkg/pkg-drop.cli
index 7737d15..49d4f98 100644
--- a/bpkg/pkg-drop.cli
+++ b/bpkg/pkg-drop.cli
@@ -26,8 +26,8 @@ namespace bpkg
packages that would otherwise no longer be needed, you will be offered to
drop those as well.
- The \cb{pkg-drop} command also supports several \cb{--*-only} options that
- allow you to limit the amount of work that will be done."
+ The \cb{pkg-drop} command also supports several options (described below)
+ that allow you to control the amount of work that will be done."
}
class pkg_drop_options: configuration_options
@@ -53,6 +53,23 @@ namespace bpkg
packages."
}
+ bool --keep-dependent|-K
+ {
+ "Issue an error if attempting to drop dependent packages."
+ }
+
+ bool --drop-prerequisite|-D
+ {
+ "Drop without confirmation prerequsite packages that were automatically
+ built and will no longer be necessary."
+ }
+
+ bool --keep-prerequisite
+ {
+ "Don't offer to drop prerequsite packages that were automatically built
+ and will no longer be necessary."
+ }
+
bool --print-only|-p
{
"Print to \cb{STDOUT} what would be done without actually doing
diff --git a/bpkg/pkg-drop.cxx b/bpkg/pkg-drop.cxx
index 07717ed..79a4870 100644
--- a/bpkg/pkg-drop.cxx
+++ b/bpkg/pkg-drop.cxx
@@ -390,11 +390,21 @@ namespace bpkg
{
tracer trace ("pkg_drop");
+ const dir_path& c (o.directory ());
+ l4 ([&]{trace << "configuration: " << c;});
+
if (o.yes () && o.no ())
fail << "both --yes|-y and --no|-n specified";
- const dir_path& c (o.directory ());
- l4 ([&]{trace << "configuration: " << c;});
+ 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.drop_prerequisite () && o.keep_prerequisite ())
+ fail << "both --drop-prerequisite|-D and --keep-prerequisite "
+ << "specified" <<
+ info << "run 'bpkg help pkg-drop' for more information";
if (!args.more ())
fail << "package name argument expected" <<
@@ -447,7 +457,12 @@ namespace bpkg
if (!dnames.empty () && !o.drop_dependent ())
{
{
- diag_record dr (text);
+ diag_record dr;
+
+ if (o.keep_dependent ())
+ dr << fail;
+ else
+ dr << text;
dr << "following dependent packages will have to be dropped "
<< "as well:";
@@ -497,7 +512,10 @@ namespace bpkg
// have dependents other than the ones we are dropping). If there are
// some that we can drop, ask the user for confirmation.
//
- if (pkgs.filter_prerequisites (db) && !(drop_prq = o.yes ()) && !o.no ())
+ if (pkgs.filter_prerequisites (db) &&
+ !o.keep_prerequisite () &&
+ !(drop_prq = o.drop_prerequisite ()) &&
+ !(drop_prq = o.yes ()) && !o.no ())
{
{
diag_record dr (text);
@@ -529,10 +547,7 @@ namespace bpkg
o.no ());
}
- // Examine the list of prerequsite packages and drop those that don't
- // have any dependents.
- //
- void
+ set<shared_ptr<selected_package>>
pkg_drop (const dir_path& c,
const common_options& o,
database& db,
@@ -571,7 +586,7 @@ namespace bpkg
t.commit ();
if (!r)
- return; // Nothing can be dropped.
+ return {}; // Nothing can be dropped.
}
if (prompt)
@@ -587,7 +602,7 @@ namespace bpkg
}
if (!yn_prompt ("drop prerequisite packages? [Y/n]", 'y'))
- return;
+ return {};
}
pkg_drop (c,
@@ -599,5 +614,11 @@ namespace bpkg
false, // Disfigure-only (could be an option).
true, // Yes (don't print the plan or prompt).
false); // No (we already said yes).
+
+ set<shared_ptr<selected_package>> r;
+ for (const drop_package& dp: pkgs)
+ r.insert (dp.package);
+
+ return r;
}
}
diff --git a/tests/test.sh b/tests/test.sh
index 369e1d4..de40ed8 100755
--- a/tests/test.sh
+++ b/tests/test.sh
@@ -1203,30 +1203,30 @@ test cfg-fetch --trust-yes
test pkg-build -p libbar <<EOF
upgrade libfoo 1.1.0 (required by libbar libbaz)
upgrade libbar 1.1.0
-reconfigure libbaz (required by libbar)
+reconfigure libbaz (dependent of libbar)
EOF
test pkg-build -p libfoo <<EOF
upgrade libfoo 1.1.0
-reconfigure libbar (required by libfoo)
-reconfigure libbaz (required by libbar)
+reconfigure libbar (dependent of libfoo)
+reconfigure libbaz (dependent of libbar)
EOF
test pkg-build -p libfoo libbar/1.0.0 <<EOF
upgrade libfoo 1.1.0
reconfigure/build libbar 1.0.0
-reconfigure libbaz (required by libbar)
+reconfigure libbaz (dependent of libbar)
EOF
test pkg-build -p libbar/1.0.0 libfoo <<EOF
upgrade libfoo 1.1.0
reconfigure/build libbar 1.0.0
-reconfigure libbaz (required by libbar)
+reconfigure libbaz (dependent of libbar)
EOF
test pkg-build -p libbaz libfoo <<EOF
upgrade libfoo 1.1.0
-reconfigure libbar (required by libbaz libfoo)
+reconfigure libbar (dependent of libbaz libfoo)
reconfigure/build libbaz 1.1.0
EOF