From e0130883f64cc8898d4aa43a39ec739ffc09ea1f Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Tue, 24 Jan 2023 13:30:31 +0200 Subject: Add --sys-* options --- bpkg/pkg-build.cli | 64 ++++++++++++++++++++++++++++++---- bpkg/pkg-build.cxx | 36 ++++++++++--------- bpkg/system-package-manager-debian.cxx | 20 ++++------- bpkg/system-package-manager-debian.hxx | 12 ++----- bpkg/system-package-manager.cxx | 11 +++--- bpkg/system-package-manager.hxx | 48 ++++++++++++++++++------- 6 files changed, 129 insertions(+), 62 deletions(-) diff --git a/bpkg/pkg-build.cli b/bpkg/pkg-build.cli index 493ffbe..d2844c2 100644 --- a/bpkg/pkg-build.cli +++ b/bpkg/pkg-build.cli @@ -95,12 +95,19 @@ namespace bpkg A package name () can be prefixed with a package scheme (). Currently the only recognized scheme is \cb{sys} which instructs \cb{pkg-build} to configure the package as available from the - system rather than building it from source. If the system package version - () is not specified or is '\cb{/*}', then it is considered to - be unknown but satisfying any version constraint. If specified, - may not be a version constraint. If the version is not - explicitly specified, then at least a stub package must be available from - one of the repositories. + system rather than building it from source. + + The system package version () may not be a version constraint + but may be the special '\cb{/*}' value, which indicates that the version + should be considered unknown but satisfying any version constraint. If + unspecified, then \cb{pkg-build} will attempt to query the system package + manager for the installed version unless the system package manager is + unsupported or this functionality is disabled with \cb{--sys-no-query}, + in which case '\cb{/*}' is assumed. If the system package + manager is supported, then the automatic installation of an available + package can be requested with the \cb{--sys-install} option. If the + version is not explicitly specified, then at least a stub package must be + available from one of the repositories. Finally, a package can be specified as either the path to the package archive () or to the package directory (\cb{/}; note that it @@ -293,7 +300,8 @@ namespace bpkg bool --yes|-y { - "Assume the answer to all prompts is \cb{yes}." + "Assume the answer to all prompts is \cb{yes}. Note that this excludes + the system package manager prompts; see \cb{--sys-yes} for details." } string --for|-f @@ -408,6 +416,48 @@ namespace bpkg See \l{bpkg-cfg-create(1)} for details on linked configurations." } + bool --sys-no-query + { + "Do not query the system package manager for the installed versions of + packages specified with the \cb{sys} scheme." + } + + bool --sys-install + { + "Automatically instruct the system package manager to install + available versions of packages specified with the \cb{sys} scheme + that are not already installed. See also the \cb{--sys-no-fetch}, + \cb{--sys-yes}, and \cb{--sys-sudo} options." + } + + bool --sys-no-fetch + { + "Do not automatically fetch the system package manager metadata + before querying for available version. This option only makes + sense together with \cb{--sys-install}." + } + + bool --sys-yes + { + "Assume the answer to the system package manager prompts is \cb{yes}. + Note that system package manager interactions may break your system + and you should normally only use this option on throw-away systems + (test virtual machines, etc)." + } + + string --sys-sudo = "sudo" + { + "", + + "The \cb{sudo} program to use for system package manager interactions + that normally require administrative privileges (fetch package + metadata, install packages, etc). If unspecified, \cb{sudo} is used + by default. Pass empty or the special \cb{false} value to disable the + use of the \cb{sudo} program. Note that the \cb{sudo} program is + normally only needed if the system package installation is enabled + (\cb{--sys-install})." + } + dir_paths --directory|-d { "", diff --git a/bpkg/pkg-build.cxx b/bpkg/pkg-build.cxx index b564787..0628f6f 100644 --- a/bpkg/pkg-build.cxx +++ b/bpkg/pkg-build.cxx @@ -1072,6 +1072,10 @@ namespace bpkg << "specified" << info << "run 'bpkg help pkg-build' for more information"; + if (o.sys_no_query () && o.sys_install ()) + fail << "both --sys-no-query and --sys-install specified" << + info << "run 'bpkg help pkg-build' for more information"; + if (!args.more () && !o.upgrade () && !o.patch ()) fail << "package name argument expected" << info << "run 'bpkg help pkg-build' for more information"; @@ -1681,18 +1685,16 @@ namespace bpkg // See if we should query the system package manager. // - // @@ TODO: --sys-no-query - // --sys-no-fetch - // --sys-install - // - bool query (!/*ops.sys_no_query ()*/ false); - bool fetch (!/*ops.sys_no_fetch ()*/ false); - bool install (/*ops.sys_install ()*/ false); - if (!sys_pkg_mgr) - sys_pkg_mgr = query - ? make_system_package_manager (o, host_triplet, "" /* name */) - : nullptr; + sys_pkg_mgr = o.sys_no_query () + ? nullptr + : make_system_package_manager (o, + host_triplet, + o.sys_install (), + !o.sys_no_fetch (), + o.sys_yes (), + o.sys_sudo (), + "" /* name */); if (*sys_pkg_mgr != nullptr) { @@ -1701,7 +1703,7 @@ namespace bpkg // First check the cache. // optional os ( - spm.pkg_status (nm, nullptr, install, fetch)); + spm.pkg_status (nm, nullptr)); if (!os) { @@ -1717,7 +1719,7 @@ namespace bpkg fail << "unknown package " << nm << info << "consider specifying " << nm << "/*"; - os = spm.pkg_status (nm, &aps, install, fetch); + os = spm.pkg_status (nm, &aps); assert (os); } @@ -1728,10 +1730,10 @@ namespace bpkg { diag_record dr (fail); - dr << "no installed " << (install ? " or available " : "") + dr << "no installed " << (o.sys_install () ? " or available " : "") << "system package for " << nm; - if (!install) + if (!o.sys_install ()) dr << info << "specify --sys-install to try to install it"; } } @@ -4858,7 +4860,7 @@ namespace bpkg // Install the system/distribution packages required by the respective // system packages (see build_package::system_install() for details). // - if (!simulate) + if (!simulate && o.sys_install ()) { // Collect the names of all the system packages being managed by the // system package manager (as opposed to user/fallback), suppressing @@ -4883,7 +4885,7 @@ namespace bpkg // assert (sys_pkg_mgr && *sys_pkg_mgr != nullptr); - (*sys_pkg_mgr)->pkg_install (ps, /*&& ops.sys_install ()*/ false); + (*sys_pkg_mgr)->pkg_install (ps); } } diff --git a/bpkg/system-package-manager-debian.cxx b/bpkg/system-package-manager-debian.cxx index 660fd2d..f885e2d 100644 --- a/bpkg/system-package-manager-debian.cxx +++ b/bpkg/system-package-manager-debian.cxx @@ -785,10 +785,7 @@ namespace bpkg optional system_package_manager_debian:: - pkg_status (const package_name& pn, - const available_packages* aps, - bool install, - bool fetch) + pkg_status (const package_name& pn, const available_packages* aps) { // For now we ignore -doc and -dbg package components (but we may want to // have options controlling this later). Note also that we assume -common @@ -988,15 +985,15 @@ namespace bpkg // Next look for available versions if we are allowed to install. // - if (!r && install) + if (!r && install_) { // If we weren't instructed to fetch or we already fetched, then we // don't need to re-run apt_cache_policy(). // bool requery; - if ((requery = fetch && !fetched_)) + if ((requery = fetch_ && !fetched_)) { - apt_get_update ("sudo" /* --sys-sudo */, progress_, false /* --sys-yes */); + apt_get_update (sudo_, progress_, yes_); fetched_ = true; } @@ -1127,11 +1124,11 @@ namespace bpkg } void system_package_manager_debian:: - pkg_install (const vector& pns, bool /* @@ install */) + pkg_install (const vector& pns) { assert (!pns.empty ()); - assert (!installed_); + assert (install_ && !installed_); installed_ = true; // Collect and merge all the Debian packages/version for the specified @@ -1211,10 +1208,7 @@ namespace bpkg specs.push_back (move (s)); } - apt_get_install (specs, - "sudo" /* --sys-sudo */, - progress_, - false /* --sys-yes */); + apt_get_install (specs, sudo_, progress_, yes_); } // Verify that versions we have promised in pkg_status() match what diff --git a/bpkg/system-package-manager-debian.hxx b/bpkg/system-package-manager-debian.hxx index 4c17413..fc4aeb7 100644 --- a/bpkg/system-package-manager-debian.hxx +++ b/bpkg/system-package-manager-debian.hxx @@ -85,22 +85,16 @@ namespace bpkg { public: virtual optional - pkg_status (const package_name&, - const available_packages*, - bool install, - bool fetch) override; + pkg_status (const package_name&, const available_packages*) override; virtual void - pkg_install (const vector&, - bool install) override; + pkg_install (const vector&) override; public: // Note: expects os_release::name_id to be "debian" or os_release::like_id // to contain "debian". // - explicit - system_package_manager_debian (const common_options& co, os_release&& osr) - : system_package_manager (co, move (osr)) {} + using system_package_manager::system_package_manager; protected: bool fetched_ = false; // True if already fetched metadata. diff --git a/bpkg/system-package-manager.cxx b/bpkg/system-package-manager.cxx index 670cae6..aa71284 100644 --- a/bpkg/system-package-manager.cxx +++ b/bpkg/system-package-manager.cxx @@ -27,8 +27,12 @@ namespace bpkg } unique_ptr - make_system_package_manager (const common_options&, + make_system_package_manager (const common_options& co, const target_triplet& host, + bool install, + bool fetch, + bool yes, + const string& sudo, const string& name) { unique_ptr r; @@ -58,9 +62,8 @@ namespace bpkg // @@ TODO: verify name if specified. - // @@ TMP - // - //r.reset (new system_package_manager_debian (co, move (*osr))); + r.reset (new system_package_manager_debian ( + co, move (*osr), install, fetch, yes, sudo)); } } } diff --git a/bpkg/system-package-manager.hxx b/bpkg/system-package-manager.hxx index cfe5576..be55176 100644 --- a/bpkg/system-package-manager.hxx +++ b/bpkg/system-package-manager.hxx @@ -119,20 +119,17 @@ namespace bpkg // The returned status can be NULL, which indicates that no such package // is available from the system package manager. Note that empty is also // returned if no fully installed package is available from the system and - // the install argument is false. + // package installation is not enabled (see the constructor below). // - // If fetch is false, then do not re-fetch the system package repository - // metadata (that is, available packages/versions) before querying for the - // available version of the not yet installed or partially installed - // packages. + // Note also that the implementation is expected to issue appropriate + // progress and diagnostics if fetching package metadata. // virtual optional - pkg_status (const package_name&, - const available_packages*, - bool install, - bool fetch) = 0; + pkg_status (const package_name&, const available_packages*) = 0; // Install the specified subset of the previously-queried packages. + // Should only be called if installation is enabled (see the constructor + // below). // // Note that this function should be called only once after the final set // of the necessary system packages has been determined. And the specified @@ -149,17 +146,33 @@ namespace bpkg // progress and diagnostics. // virtual void - pkg_install (const vector&, bool install) = 0; + pkg_install (const vector&) = 0; public: virtual ~system_package_manager (); - system_package_manager (const common_options& co, os_release&& osr) + // If install is true, then enable package installation. + // + // If fetch is false, then do not re-fetch the system package repository + // metadata (that is, available packages/versions) before querying for the + // available version of the not yet installed or partially installed + // packages. + // + system_package_manager (const common_options& co, + os_release&& osr, + bool install, + bool fetch, + bool yes, + string sudo) : os_release_ (osr), progress_ (co.progress () ? true : co.no_progress () ? false : - optional ()) {} + optional ()), + install_ (install), + fetch_ (fetch), + yes_ (yes), + sudo_ (sudo != "false" ? move (sudo) : string ()) {} protected: // Given the available packages (as returned by find_available_all()) @@ -219,6 +232,13 @@ namespace bpkg protected: os_release os_release_; optional progress_; // --[no]-progress (see also stderr_term) + + // The --sys-* option values. + // + bool install_; + bool fetch_; + bool yes_; + string sudo_; }; // Create a package manager instance corresponding to the specified host @@ -234,6 +254,10 @@ namespace bpkg unique_ptr make_system_package_manager (const common_options&, const target_triplet&, + bool install, + bool fetch, + bool yes, + const string& sudo, const string& name); } -- cgit v1.1