From 6b610aea9096ce64ae769708a53041653333e155 Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Wed, 30 Sep 2020 21:39:50 +0300 Subject: Add --output-{root,purge} options to pkg-checkout --- bpkg/pkg-checkout.cli | 23 ++++++++++ bpkg/pkg-checkout.cxx | 99 ++++++++++++++++++++++++++++++++++++------- bpkg/pkg-checkout.hxx | 18 +++++++- bpkg/pkg-fetch.cxx | 2 +- bpkg/pkg-fetch.hxx | 6 +-- bpkg/pkg-unpack.cxx | 4 +- bpkg/pkg-unpack.hxx | 8 ++-- tests/pkg-checkout.testscript | 55 ++++++++++++++++++++---- 8 files changed, 180 insertions(+), 35 deletions(-) diff --git a/bpkg/pkg-checkout.cli b/bpkg/pkg-checkout.cli index 5efb5e2..b653fa8 100644 --- a/bpkg/pkg-checkout.cli +++ b/bpkg/pkg-checkout.cli @@ -22,6 +22,15 @@ namespace bpkg from one of the version control-based repositories (\l{bpkg-rep-add(1)}). The resulting package state is \cb{unpacked} (\l{bpkg-pkg-status(1)}). + If the \cb{--output-root} option is passed, then the package is checked + out into the specified directory rather than into the configuration + directory. In this case, \cb{bpkg} uses the package (source) directory in + place, similar to the \cb{pkg-unpack --existing|-e} mode. Also, unless + the \cb{--output-purge} option is specified, \cb{bpkg} will not attempt + to remove this directory when the package is later purged with the + \l{bpkg-pkg-purge(1)} command. Note also that such a package is not + \i{external} (see \l{bpkg-pkg-unpack(1)} for details). + If the \cb{--replace|-r} option is specified, then \cb{pkg-checkout} will replace the archive and/or source directory of a package that is already in the \cb{unpacked} or \cb{fetched} state." @@ -36,6 +45,20 @@ namespace bpkg "Replace the source directory if the package is already fetched or unpacked." } + + dir_path --output-root + { + "", + "Check out the package into the specified directory rather than into the + configuration directory. Note that the package source is placed into + the \c{\i{package}\b{-}\i{version}} subdirectory of this directory." + } + + bool --output-purge + { + "Remove the checked out package (source) directory when the package is + purged." + } }; " diff --git a/bpkg/pkg-checkout.cxx b/bpkg/pkg-checkout.cxx index 9be09c8..3b99496 100644 --- a/bpkg/pkg-checkout.cxx +++ b/bpkg/pkg-checkout.cxx @@ -80,13 +80,17 @@ namespace bpkg return r; } - shared_ptr + // Return the selected package object which may replace the existing one. + // + static shared_ptr pkg_checkout (const common_options& o, - const dir_path& c, + dir_path c, transaction& t, package_name n, version v, + const optional& output_root, bool replace, + bool purge, bool simulate) { tracer trace ("pkg_checkout"); @@ -158,7 +162,9 @@ namespace bpkg auto_rmdir rmd; optional mc; - dir_path d (c / dir_path (n.string () + '-' + v.string ())); + + const dir_path& ord (output_root ? *output_root : c); + dir_path d (ord / dir_path (n.string () + '-' + v.string ())); // An incomplete checkout may result in an unusable repository state // (submodule fetch is interrupted, working tree fix up failed in the @@ -258,7 +264,7 @@ namespace bpkg verb_b::progress, "--no-external-modules", "!config.dist.bootstrap=true", - "config.dist.root='" + c.representation () + "'", + "config.dist.root='" + ord.representation () + "'", bspec); // Revert the fix-ups. @@ -309,13 +315,23 @@ namespace bpkg } } + // Make the package and configuration paths absolute and normalized. + // If the package is inside the configuration, use the relative path. + // This way we can move the configuration around. + // + normalize (c, "configuration"); + normalize (d, "package"); + + if (d.sub (c)) + d = d.leaf (c); + if (p != nullptr) { p->version = move (v); p->state = package_state::unpacked; p->repository_fragment = rl; - p->src_root = d.leaf (); - p->purge_src = true; + p->src_root = move (d); + p->purge_src = purge; p->manifest_checksum = move (mc); db.update (p); @@ -334,8 +350,8 @@ namespace bpkg rl, nullopt, // No archive false, - d.leaf (), // Source root. - true, // Purge directory. + move (d), // Source root. + purge, // Purge directory. move (mc), nullopt, // No output directory yet. {}}); // No prerequisites captured yet. @@ -349,6 +365,48 @@ namespace bpkg return p; } + shared_ptr + pkg_checkout (const common_options& o, + const dir_path& c, + transaction& t, + package_name n, + version v, + const dir_path& d, + bool replace, + bool purge, + bool simulate) + { + return pkg_checkout (o, + c, + t, + move (n), + move (v), + optional (d), + replace, + purge, + simulate); + } + + shared_ptr + pkg_checkout (const common_options& o, + const dir_path& c, + transaction& t, + package_name n, + version v, + bool replace, + bool simulate) + { + return pkg_checkout (o, + c, + t, + move (n), + move (v), + nullopt /* output_root */, + replace, + true /* purge */, + simulate); + } + int pkg_checkout (const pkg_checkout_options& o, cli::scanner& args) { @@ -377,13 +435,24 @@ namespace bpkg // Commits the transaction. // - p = pkg_checkout (o, - c, - t, - move (n), - move (v), - o.replace (), - false /* simulate */); + if (o.output_root_specified ()) + p = pkg_checkout (o, + c, + t, + move (n), + move (v), + o.output_root (), + o.replace (), + o.output_purge (), + false /* simulate */); + else + p = pkg_checkout (o, + c, + t, + move (n), + move (v), + o.replace (), + false /* simulate */); if (verb && !o.no_result ()) text << "checked out " << *p; diff --git a/bpkg/pkg-checkout.hxx b/bpkg/pkg-checkout.hxx index 8e106dd..47b1ad0 100644 --- a/bpkg/pkg-checkout.hxx +++ b/bpkg/pkg-checkout.hxx @@ -18,8 +18,24 @@ namespace bpkg int pkg_checkout (const pkg_checkout_options&, cli::scanner& args); + // Check out the package from a version control-based repository into a + // directory other than the configuration directory and commit the + // transaction. Return the selected package object which may replace the + // existing one. + // + shared_ptr + pkg_checkout (const common_options&, + const dir_path& configuration, + transaction&, + package_name, + version, + const dir_path& output_root, + bool replace, + bool purge, + bool simulate); + // Check out the package from a version control-based repository and commit - // the transaction. Can return a new selected package object, replacing the + // the transaction. Return the selected package object which may replace the // existing one. // shared_ptr diff --git a/bpkg/pkg-fetch.cxx b/bpkg/pkg-fetch.cxx index 75bf1fa..24883c5 100644 --- a/bpkg/pkg-fetch.cxx +++ b/bpkg/pkg-fetch.cxx @@ -21,7 +21,7 @@ using namespace butl; namespace bpkg { - // Can return a new selected package object, replacing the existing one. + // Return the selected package object which may replace the existing one. // static shared_ptr pkg_fetch (dir_path c, diff --git a/bpkg/pkg-fetch.hxx b/bpkg/pkg-fetch.hxx index f66d00b..e9d753b 100644 --- a/bpkg/pkg-fetch.hxx +++ b/bpkg/pkg-fetch.hxx @@ -18,8 +18,8 @@ namespace bpkg int pkg_fetch (const pkg_fetch_options&, cli::scanner& args); - // Fetch the package as an archive file and commit the transaction. Can - // return a new selected package object, replacing the existing one. + // Fetch the package as an archive file and commit the transaction. Return + // the selected package object which may replace the existing one. // shared_ptr pkg_fetch (const common_options&, @@ -31,7 +31,7 @@ namespace bpkg bool simulate); // Fetch the package from an archive-based repository and commit the - // transaction. Can return a new selected package object, replacing the + // transaction. Return the selected package object which may replace the // existing one. // shared_ptr diff --git a/bpkg/pkg-unpack.cxx b/bpkg/pkg-unpack.cxx index b8ac08e..9685f3e 100644 --- a/bpkg/pkg-unpack.cxx +++ b/bpkg/pkg-unpack.cxx @@ -54,8 +54,8 @@ namespace bpkg } } - // Select the external package in this configuration. Can return a new - // selected package object, replacing the existing one. + // Select the external package in this configuration. Return the selected + // package object which may replace the existing one. // static shared_ptr pkg_unpack (const common_options& o, diff --git a/bpkg/pkg-unpack.hxx b/bpkg/pkg-unpack.hxx index 373b72b..107322b 100644 --- a/bpkg/pkg-unpack.hxx +++ b/bpkg/pkg-unpack.hxx @@ -18,8 +18,8 @@ namespace bpkg int pkg_unpack (const pkg_unpack_options&, cli::scanner& args); - // Unpack the package as a source directory and commit the transaction. Can - // return a new selected package object, replacing the existing one. + // Unpack the package as a source directory and commit the transaction. + // Return the selected package object which may replace the existing one. // shared_ptr pkg_unpack (const common_options&, @@ -40,8 +40,8 @@ namespace bpkg bool simulate); // Unpack the package as a source directory from a directory-based - // repository and commit the transaction. Can return a new selected package - // object, replacing the existing one. + // repository and commit the transaction. Return the selected package object + // which may replace the existing one. // shared_ptr pkg_unpack (const common_options&, diff --git a/tests/pkg-checkout.testscript b/tests/pkg-checkout.testscript index 9fc1e64..8f3ff92 100644 --- a/tests/pkg-checkout.testscript +++ b/tests/pkg-checkout.testscript @@ -19,7 +19,6 @@ posix = ($cxx.target.class != 'windows') # $git_extract $src/git/libbar.tar $git_extract $src/git/style-basic0.tar &$out_git/state0/*** - $git_extract $src/git/style-basic1.tar &$out_git/state1/*** if $posix $git_extract $src/git/style.tar @@ -96,15 +95,8 @@ else : replacement : { - # @@ Reduce to a single repository when multiple revisions can be specified - # in the repository URL fragment. - # - rep0 = "$rep_git/state0"; - rep1 = "$rep_git/state1"; - $clone_root_cfg; - $rep_add "$rep0/style-basic.git#master"; - $rep_add "$rep1/style-basic.git#stable"; + $rep_add "$rep/style-basic.git#master,stable"; $rep_fetch; $pkg_status style-basic | \ @@ -216,4 +208,49 @@ else EOE end } + + : output-root + : + { + : no-purge + : + { + $clone_root_cfg; + $rep_add "$rep/libbar.git#master"; + $rep_fetch; + + $* --output-root $~ libmbar/1.0.0 &libmbar-1.0.0/*** 2>>~%EOE%; + checking out libmbar/1.0.0 + %.+ + distributing libmbar/1.0.0 + checked out libmbar/1.0.0 + EOE + + test -f libmbar-1.0.0/manifest; + + # While at it, test that the package is buildable. + # + $pkg_build libmbar -d cfg/ --yes 2>!; + $pkg_drop libmbar -d cfg/ --yes 2>! + } + + : purge + : + { + $clone_root_cfg; + $rep_add "$rep/libbar.git#master"; + $rep_fetch; + + $* --output-root $~ libmbar/1.0.0 --output-purge 2>>~%EOE%; + checking out libmbar/1.0.0 + %.+ + distributing libmbar/1.0.0 + checked out libmbar/1.0.0 + EOE + + test -f libmbar-1.0.0/manifest; + + $pkg_purge libmbar + } + } } -- cgit v1.1