From e035fbaf5e5ae862191dc3d9eb047ac0abba6dbb Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Fri, 11 May 2018 14:41:12 +0300 Subject: Add support for recursive pkg-test --- bpkg/pkg-clean.hxx | 7 ++- bpkg/pkg-command.cxx | 68 +++++++++++++++++++++---- bpkg/pkg-command.hxx | 5 ++ bpkg/pkg-install.hxx | 7 ++- bpkg/pkg-test.cli | 17 ++++++- bpkg/pkg-test.hxx | 2 +- bpkg/pkg-uninstall.hxx | 6 ++- bpkg/pkg-update.hxx | 7 ++- bpkg/rep-fetch.cxx | 13 ++--- tests/common/satisfy/libbaz-0.0.3.tar.gz | Bin 363 -> 368 bytes tests/common/satisfy/libfix-0.0.1.tar.gz | Bin 345 -> 355 bytes tests/common/satisfy/libfoo-0.0.1.tar.gz | Bin 362 -> 364 bytes tests/pkg-test.test | 82 +++++++++++++++++++++++++++++++ tests/pkg-test/t0a | 1 + 14 files changed, 191 insertions(+), 24 deletions(-) create mode 100644 tests/pkg-test.test create mode 120000 tests/pkg-test/t0a diff --git a/bpkg/pkg-clean.hxx b/bpkg/pkg-clean.hxx index 3a8fcf1..363563e 100644 --- a/bpkg/pkg-clean.hxx +++ b/bpkg/pkg-clean.hxx @@ -16,7 +16,12 @@ namespace bpkg inline int pkg_clean (const pkg_clean_options& o, cli::scanner& args) { - return pkg_command ("clean", o, "", args); + return pkg_command ("clean", + o, + "" /* cmd_variant */, + false /* recursive */, + false /* immediate */, + args); } } diff --git a/bpkg/pkg-command.cxx b/bpkg/pkg-command.cxx index 4475ea7..b28c99a 100644 --- a/bpkg/pkg-command.cxx +++ b/bpkg/pkg-command.cxx @@ -4,6 +4,8 @@ #include +#include // find_if() + #include #include #include @@ -86,31 +88,69 @@ namespace bpkg run (); } + static void + collect_dependencies (const shared_ptr& p, + bool recursive, + vector& ps) + { + for (const auto& pr: p->prerequisites) + { + shared_ptr d (pr.first.load ()); + + // The selected package can only be configured if all its dependencies + // are configured. + // + assert (d->state == package_state::configured); + + // Skip configured as system and duplicate dependencies. + // + if (d->substate != package_substate::system && + find_if (ps.begin (), ps.end (), + [&d] (const pkg_command_vars& i) {return i.pkg == d;}) == + ps.end ()) + { + // Note: no package-specific variables (global ones still apply). + // + ps.push_back (pkg_command_vars {d, strings () /* vars */}); + + if (recursive) + collect_dependencies (d, recursive, ps); + } + } + } + int pkg_command (const string& cmd, const configuration_options& o, const string& cmd_v, + bool recursive, + bool immediate, cli::scanner& args) { tracer trace ("pkg_command"); + // We can as well count on the immediate/recursive option names. + // + if (immediate && recursive) + fail << "both --immediate|-i and --recursive|-r specified"; + const dir_path& c (o.directory ()); l4 ([&]{trace << "configuration: " << c;}); // First read the common variables. // auto read_vars = [&args](strings& v) + { + for (; args.more (); args.next ()) { - for (; args.more (); args.next ()) - { - string a (args.peek ()); + string a (args.peek ()); - if (a.find ('=') == string::npos) - break; + if (a.find ('=') == string::npos) + break; - v.push_back (move (a)); - } - }; + v.push_back (move (a)); + } + }; strings cvars; read_vars (cvars); @@ -124,6 +164,11 @@ namespace bpkg database db (open (c, trace)); transaction t (db); + // We need to suppress duplicate dependencies for the recursive command + // execution. + // + session ses; + while (args.more ()) { string n (args.next ()); @@ -146,7 +191,12 @@ namespace bpkg strings vars; read_vars (vars); - ps.push_back (pkg_command_vars {move (p), move (vars)}); + ps.push_back (pkg_command_vars {p, move (vars)}); + + // Note that it can only be recursive or immediate but not both. + // + if (recursive || immediate) + collect_dependencies (p, recursive, ps); } t.commit (); diff --git a/bpkg/pkg-command.hxx b/bpkg/pkg-command.hxx index 329360d..ea07b09 100644 --- a/bpkg/pkg-command.hxx +++ b/bpkg/pkg-command.hxx @@ -18,10 +18,15 @@ namespace bpkg // If cmd_variant is not empty, then the -for- is performed // instead. // + // The command can also be performed recursively for all or immediate + // dependencies of the specified packages. + // int pkg_command (const string& cmd, // Without the 'pkg-' prefix. const configuration_options&, const string& cmd_variant, + bool recursive, + bool immediate, cli::scanner& args); struct pkg_command_vars diff --git a/bpkg/pkg-install.hxx b/bpkg/pkg-install.hxx index 9102dda..35dc52b 100644 --- a/bpkg/pkg-install.hxx +++ b/bpkg/pkg-install.hxx @@ -17,7 +17,12 @@ namespace bpkg inline int pkg_install (const pkg_install_options& o, cli::scanner& args) { - return pkg_command ("install", o, "", args); + return pkg_command ("install", + o, + "" /* cmd_variant */, + false /* recursive */, + false /* immediate */, + args); } } diff --git a/bpkg/pkg-test.cli b/bpkg/pkg-test.cli index 0373820..78018be 100644 --- a/bpkg/pkg-test.cli +++ b/bpkg/pkg-test.cli @@ -20,8 +20,11 @@ namespace bpkg \h|DESCRIPTION| The \cb{pkg-test} command tests the previously configured (via - \l{bpkg-pkg-build(1)} or \l{bpkg-pkg-configure(1)}) package. Underneath, - this command doesn't do much more than run \cb{b test}. + \l{bpkg-pkg-build(1)} or \l{bpkg-pkg-configure(1)}) packages. + Additionally, immediate or all dependencies of the specified packages can + be tested by specifying the \c{\b{--immediate}|\b{-i}} or + \c{\b{--recursive}|\b{-r}} options, respectively. Underneath, this + command doesn't do much more than run \cb{b test}. Additional command line variables (, normally \cb{config.*}) can be passed to the build system by either specifying them before the packages, @@ -32,5 +35,15 @@ namespace bpkg class pkg_test_options: configuration_options { "\h|PKG-TEST OPTIONS|" + + bool --immediate|-i + { + "Also test immediate dependencies." + } + + bool --recursive|-r + { + "Also test all dependencies, recursively." + } }; } diff --git a/bpkg/pkg-test.hxx b/bpkg/pkg-test.hxx index b9af98b..460edc0 100644 --- a/bpkg/pkg-test.hxx +++ b/bpkg/pkg-test.hxx @@ -16,7 +16,7 @@ namespace bpkg inline int pkg_test (const pkg_test_options& o, cli::scanner& args) { - return pkg_command ("test", o, "", args); + return pkg_command ("test", o, "", o.recursive (), o.immediate (), args); } } diff --git a/bpkg/pkg-uninstall.hxx b/bpkg/pkg-uninstall.hxx index 10122f4..c4359af 100644 --- a/bpkg/pkg-uninstall.hxx +++ b/bpkg/pkg-uninstall.hxx @@ -17,7 +17,11 @@ namespace bpkg inline int pkg_uninstall (const pkg_uninstall_options& o, cli::scanner& args) { - return pkg_command ("uninstall", o, "", args); + return pkg_command ("uninstall", o, + "" /* cmd_variant */, + false /* recursive */, + false /* immediate */, + args); } } diff --git a/bpkg/pkg-update.hxx b/bpkg/pkg-update.hxx index 94d4dad..c2fc982 100644 --- a/bpkg/pkg-update.hxx +++ b/bpkg/pkg-update.hxx @@ -17,7 +17,12 @@ namespace bpkg inline int pkg_update (const pkg_update_options& o, cli::scanner& args) { - return pkg_command ("update", o, o.for_ (), args); + return pkg_command ("update", + o, + o.for_ (), + false /* recursive */, + false /* immediate */, + args); } inline void diff --git a/bpkg/rep-fetch.cxx b/bpkg/rep-fetch.cxx index 412a745..92c5854 100644 --- a/bpkg/rep-fetch.cxx +++ b/bpkg/rep-fetch.cxx @@ -358,12 +358,6 @@ namespace bpkg // - If repositories.manifest file doesn't exist, then synthesize the // repository list with just the base repository. // - // - Save the repositories into the resulting list. - // - // @@ Currently we just save ones from the first commit, assuming them - // to be the same for others. However, this is not very practical - // and must be fixed. - // // - If packages.manifest file exists then load it into the "skeleton" // packages list. Otherwise, synthesize it with the single: // @@ -372,8 +366,11 @@ namespace bpkg // - If any of the package locations point to non-existent directory, then // assume it to be in a submodule and checkout submodules, recursively. // - // - For each package location parse the package manifest and add it to - // the resulting list. + // - For each package location parse the package manifest. + // + // - Save the fragment identified by the commit id and containing the + // parsed repository and package manifest lists into the resulting + // fragment list. // rep_fetch_data r; diff --git a/tests/common/satisfy/libbaz-0.0.3.tar.gz b/tests/common/satisfy/libbaz-0.0.3.tar.gz index 2044988..ae3a337 100644 Binary files a/tests/common/satisfy/libbaz-0.0.3.tar.gz and b/tests/common/satisfy/libbaz-0.0.3.tar.gz differ diff --git a/tests/common/satisfy/libfix-0.0.1.tar.gz b/tests/common/satisfy/libfix-0.0.1.tar.gz index f7c81d5..d58fa18 100644 Binary files a/tests/common/satisfy/libfix-0.0.1.tar.gz and b/tests/common/satisfy/libfix-0.0.1.tar.gz differ diff --git a/tests/common/satisfy/libfoo-0.0.1.tar.gz b/tests/common/satisfy/libfoo-0.0.1.tar.gz index 946c6b4..7c11b79 100644 Binary files a/tests/common/satisfy/libfoo-0.0.1.tar.gz and b/tests/common/satisfy/libfoo-0.0.1.tar.gz differ diff --git a/tests/pkg-test.test b/tests/pkg-test.test new file mode 100644 index 0000000..26a3fd6 --- /dev/null +++ b/tests/pkg-test.test @@ -0,0 +1,82 @@ +# file : tests/pkg-test.test +# copyright : Copyright (c) 2014-2017 Code Synthesis Ltd +# license : MIT; see accompanying LICENSE file + +.include common.test config.test remote.test + +# Source repository: +# +# pkg-build +# | +# `-- t0a +# |-- libbar-0.0.1.tar.gz -> libbaz == 0.0.1 +# |-- libbaz-0.0.1.tar.gz -> libfox +# |-- libbaz-0.0.3.tar.gz -> libfoo +# |-- libbox-0.0.1.tar.gz -> libbaz +# |-- libfix-0.0.1.tar.gz +# |-- libfoo-0.0.1.tar.gz -> libfix +# |-- libfox-0.0.1.tar.gz +# `-- repositories.manifest + +# Prepare repositories used by tests if running in the local mode. +# ++if ($remote != true) + rep_create += 2>! + + cp -r $src/t0a $out/t0a && $rep_create $out/t0a &$out/t0a/packages.manifest +end + +pkg_build += --yes --auth all --trust-yes -d cfg 2>! + ++$pkg_build "libbaz@$rep/t0a" + +test.options += --build-option -s + +: non-recursive +: +{ + $clone_cfg; + + $* libbaz 2>>~%EOE% + %info: .+libbaz-0.0.3.+ has nothing to test% + tested libbaz/0.0.3 + EOE +} + +: immediate +: +{ + $clone_cfg; + + $* libbaz --immediate 2>>~%EOE% + %info: .+libbaz-0.0.3.+ has nothing to test% + %info: .+libfoo-0.0.1.+ has nothing to test% + tested libbaz/0.0.3 + tested libfoo/0.0.1 + EOE +} + +: recursive +: +{ + $clone_cfg; + + $* libbaz --recursive 2>>~%EOE% + %info: .+libbaz-0.0.3.+ has nothing to test% + %info: .+libfoo-0.0.1.+ has nothing to test% + %info: .+libfix-0.0.1.+ has nothing to test% + tested libbaz/0.0.3 + tested libfoo/0.0.1 + tested libfix/0.0.1 + EOE +} + +: recursive-immediate +: +{ + $clone_cfg; + + $* libbaz --recursive --immediate 2>>~%EOE% != 0 + error: both --immediate|-i and --recursive|-r specified + EOE +} diff --git a/tests/pkg-test/t0a b/tests/pkg-test/t0a new file mode 120000 index 0000000..1c643ee --- /dev/null +++ b/tests/pkg-test/t0a @@ -0,0 +1 @@ +../common/satisfy/t0a \ No newline at end of file -- cgit v1.1