diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2023-03-13 13:25:08 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2023-03-13 14:08:15 +0200 |
commit | 3cc61ab4a6275428520cb0fb2f18dc3e09aef28a (patch) | |
tree | 98e4de2fc914c3510668d29879de30a483712c40 | |
parent | 5bdce34d722233ea81557d02ebe213cc83cf4d7a (diff) |
Move os-release facility to libbutl
-rw-r--r-- | bpkg/host-os-release.cxx | 121 | ||||
-rw-r--r-- | bpkg/host-os-release.hxx | 59 | ||||
-rw-r--r-- | bpkg/host-os-release.test.cxx | 55 | ||||
-rw-r--r-- | bpkg/host-os-release.test.testscript | 178 | ||||
-rw-r--r-- | bpkg/system-package-manager.cxx | 15 | ||||
-rw-r--r-- | bpkg/system-package-manager.hxx | 4 |
6 files changed, 16 insertions, 416 deletions
diff --git a/bpkg/host-os-release.cxx b/bpkg/host-os-release.cxx deleted file mode 100644 index 1a5a980..0000000 --- a/bpkg/host-os-release.cxx +++ /dev/null @@ -1,121 +0,0 @@ -// file : bpkg/host-os-release.cxx -*- C++ -*- -// license : MIT; see accompanying LICENSE file - -#include <bpkg/host-os-release.hxx> - -#include <libbutl/string-parser.hxx> // parse_quoted() - -#include <bpkg/diagnostics.hxx> - -using namespace butl; - -namespace bpkg -{ - // Note: not static for access from the unit test. - // - os_release - host_os_release_linux (path f = {}) - { - os_release r; - - // According to os-release(5), we should use /etc/os-release and fallback - // to /usr/lib/os-release if the former does not exist. It also lists the - // fallback values for individual variables, in case some are not present. - // - if (!f.empty () - ? exists (f) - : (exists (f = path ("/etc/os-release")) || - exists (f = path ("/usr/lib/os-release")))) - { - try - { - ifdstream ifs (f, ifdstream::badbit); - - string l; - for (uint64_t ln (1); !eof (getline (ifs, l)); ++ln) - { - trim (l); - - // Skip blanks lines and comments. - // - if (l.empty () || l[0] == '#') - continue; - - // The variable assignments are in the "shell style" and so can be - // quoted/escaped. For now we only handle quoting, which is what all - // the instances seen in the wild seems to use. - // - size_t p (l.find ('=')); - if (p == string::npos) - continue; - - string n (l, 0, p); - l.erase (0, p + 1); - - using string_parser::parse_quoted; - using string_parser::invalid_string; - - try - { - if (n == "ID_LIKE") - { - r.like_ids.clear (); - - vector<string> vs (parse_quoted (l, true /* unquote */)); - for (const string& v: vs) - { - for (size_t b (0), e (0); next_word (v, b, e); ) - { - r.like_ids.push_back (string (v, b, e - b)); - } - } - } - else if (string* p = (n == "ID" ? &r.name_id : - n == "VERSION_ID" ? &r.version_id : - n == "VARIANT_ID" ? &r.variant_id : - n == "NAME" ? &r.name : - n == "VERSION_CODENAME" ? &r.version_codename : - n == "VARIANT" ? &r.variant : - nullptr)) - { - vector<string> vs (parse_quoted (l, true /* unquote */)); - switch (vs.size ()) - { - case 0: *p = ""; break; - case 1: *p = move (vs.front ()); break; - default: throw invalid_string (0, "multiple values"); - } - } - } - catch (const invalid_string& e) - { - location loc (move (f).string (), ln); - fail (loc) << "invalid " << n << " value: " << e; - } - } - - ifs.close (); - } - catch (const io_error& e) - { - fail << "unable to read from " << f << ": " << e; - } - } - - // Assign fallback values. - // - if (r.name_id.empty ()) r.name_id = "linux"; - if (r.name.empty ()) r.name = "Linux"; - - return r; - } - - optional<os_release> - host_os_release (const target_triplet& host) - { - if (host.class_ == "linux") - return host_os_release_linux (); - else - return nullopt; - } -} diff --git a/bpkg/host-os-release.hxx b/bpkg/host-os-release.hxx deleted file mode 100644 index 3f85cb2..0000000 --- a/bpkg/host-os-release.hxx +++ /dev/null @@ -1,59 +0,0 @@ -// file : bpkg/host-os-release.hxx -*- C++ -*- -// license : MIT; see accompanying LICENSE file - -#ifndef BPKG_HOST_OS_RELEASE_HXX -#define BPKG_HOST_OS_RELEASE_HXX - -#include <bpkg/types.hxx> -#include <bpkg/utility.hxx> - -namespace bpkg -{ - // Information extracted from /etc/os-release on Linux. See os-release(5) - // for background. For other platforms we derive the equivalent information - // from other sources. Some examples: - // - // {"debian", {}, "10", "", - // "Debian GNU/Linux", "buster", ""} - // - // {"fedora", {}, "35", "workstation", - // "Fedora Linux", "", "Workstation Edition"} - // - // {"ubuntu", {"debian"}, "20.04", "", - // "Ubuntu", "focal", ""} - // - // {"windows", {}, "10", "", - // "Windows", "", ""} - // - // Note that version_id may be empty, for example, on Debian testing: - // - // {"debian", {}, "", "", - // "Debian GNU/Linux", "", ""} - // - // Note also that we don't extract PRETTY_NAME because its content is - // unpredictable. For example, it may include variant, as in "Fedora Linux - // 35 (Workstation Edition)". Instead, construct it from the individual - // components as appropriate, normally "$name $version ($version_codename)". - // - struct os_release - { - string name_id; // ID - vector<string> like_ids; // ID_LIKE - string version_id; // VERSION_ID - string variant_id; // VARIANT_ID - - string name; // NAME - string version_codename; // VERSION_CODENAME - string variant; // VARIANT - }; - - // Return the release information for the specified host or nullopt if the - // specific host is unknown/unsupported. Note that "host" here implies that - // we may be examining files, environment variables, etc., of the machine we - // are running on. - // - optional<os_release> - host_os_release (const target_triplet& host); -} - -#endif // BPKG_HOST_OS_RELEASE_HXX diff --git a/bpkg/host-os-release.test.cxx b/bpkg/host-os-release.test.cxx deleted file mode 100644 index e65c3ca..0000000 --- a/bpkg/host-os-release.test.cxx +++ /dev/null @@ -1,55 +0,0 @@ -// file : bpkg/host-os-release.test.cxx -*- C++ -*- -// license : MIT; see accompanying LICENSE file - -#include <bpkg/host-os-release.hxx> - -#include <bpkg/types.hxx> -#include <bpkg/utility.hxx> - -#include <iostream> - -#undef NDEBUG -#include <cassert> - -using namespace std; - -namespace bpkg -{ - extern os_release - host_os_release_linux (path f = {}); - - int - main (int argc, char* argv[]) - { - assert (argc >= 2); // <host-target-triplet> - - target_triplet host (argv[1]); - - os_release r; - if (host.class_ == "linux") - { - assert (argc == 3); // <host-target-triplet> <file-path> - r = host_os_release_linux (path (argv[2])); - } - else - assert (false); - - cout << r.name_id << '\n'; - for (auto b (r.like_ids.begin ()), i (b); i != r.like_ids.end (); ++i) - cout << (i != b ? "|" : "") << *i; - cout << '\n' - << r.version_id << '\n' - << r.variant_id << '\n' - << r.name << '\n' - << r.version_codename << '\n' - << r.variant << '\n'; - - return 0; - } -} - -int -main (int argc, char* argv[]) -{ - return bpkg::main (argc, argv); -} diff --git a/bpkg/host-os-release.test.testscript b/bpkg/host-os-release.test.testscript deleted file mode 100644 index b32c477..0000000 --- a/bpkg/host-os-release.test.testscript +++ /dev/null @@ -1,178 +0,0 @@ -# file : bpkg/host-os-release.test.testscript -# license : MIT; see accompanying LICENSE file - -: linux -: -$* x86_64-linux-gnu os-release >>EOO - linux - - - - Linux - - - EOO - -: debian-10 -: -cat <<EOI >=os-release; - PRETTY_NAME="Debian GNU/Linux 10 (buster)" - NAME="Debian GNU/Linux" - VERSION_ID="10" - VERSION="10 (buster)" - VERSION_CODENAME=buster - ID=debian - HOME_URL="https://www.debian.org/" - SUPPORT_URL="https://www.debian.org/support" - BUG_REPORT_URL="https://bugs.debian.org/" - EOI -$* x86_64-linux-gnu os-release >>EOO - debian - - 10 - - Debian GNU/Linux - buster - - EOO - -: debian-testing -: -cat <<EOI >=os-release; - PRETTY_NAME="Debian GNU/Linux bookworm/sid" - NAME="Debian GNU/Linux" - ID=debian - HOME_URL="https://www.debian.org/" - SUPPORT_URL="https://www.debian.org/support" - BUG_REPORT_URL="https://bugs.debian.org/" - EOI -$* x86_64-linux-gnu os-release >>EOO - debian - - - - Debian GNU/Linux - - - EOO - -: ubuntu-20.04 -: -cat <<EOI >=os-release; - NAME="Ubuntu" - VERSION="20.04.1 LTS (Focal Fossa)" - ID=ubuntu - ID_LIKE=debian - PRETTY_NAME="Ubuntu 20.04.1 LTS" - VERSION_ID="20.04" - HOME_URL="https://www.ubuntu.com/" - SUPPORT_URL="https://help.ubuntu.com/" - BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/" - PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy" - VERSION_CODENAME=focal - UBUNTU_CODENAME=focal - EOI -$* x86_64-linux-gnu os-release >>EOO - ubuntu - debian - 20.04 - - Ubuntu - focal - - EOO - -: fedora-35 -: -cat <<EOI >=os-release; - NAME="Fedora Linux" - VERSION="35 (Workstation Edition)" - ID=fedora - VERSION_ID=35 - VERSION_CODENAME="" - PLATFORM_ID="platform:f35" - PRETTY_NAME="Fedora Linux 35 (Workstation Edition)" - ANSI_COLOR="0;38;2;60;110;180" - LOGO=fedora-logo-icon - CPE_NAME="cpe:/o:fedoraproject:fedora:35" - HOME_URL="https://fedoraproject.org/" - DOCUMENTATION_URL="https://docs.fedoraproject.org/en-US/fedora/f35/system-administrators-guide/" - SUPPORT_URL="https://ask.fedoraproject.org/" - BUG_REPORT_URL="https://bugzilla.redhat.com/" - REDHAT_BUGZILLA_PRODUCT="Fedora" - REDHAT_BUGZILLA_PRODUCT_VERSION=35 - REDHAT_SUPPORT_PRODUCT="Fedora" - REDHAT_SUPPORT_PRODUCT_VERSION=35 - PRIVACY_POLICY_URL="https://fedoraproject.org/wiki/Legal:PrivacyPolicy" - VARIANT="Workstation Edition" - VARIANT_ID=workstation - EOI -$* x86_64-linux-gnu os-release >>EOO - fedora - - 35 - workstation - Fedora Linux - - Workstation Edition - EOO - -: rhel-8.2 -: -cat <<EOI >=os-release; - NAME="Red Hat Enterprise Linux" - VERSION="8.2 (Ootpa)" - ID="rhel" - ID_LIKE="fedora" - VERSION_ID="8.2" - PLATFORM_ID="platform:el8" - PRETTY_NAME="Red Hat Enterprise Linux 8.2 (Ootpa)" - ANSI_COLOR="0;31" - CPE_NAME="cpe:/o:redhat:enterprise_linux:8.2:GA" - HOME_URL="https://www.redhat.com/" - BUG_REPORT_URL="https://bugzilla.redhat.com/" - - REDHAT_BUGZILLA_PRODUCT="Red Hat Enterprise Linux 8" - REDHAT_BUGZILLA_PRODUCT_VERSION=8.2 - REDHAT_SUPPORT_PRODUCT="Red Hat Enterprise Linux" - REDHAT_SUPPORT_PRODUCT_VERSION="8.2" - EOI -$* x86_64-linux-gnu os-release >>EOO - rhel - fedora - 8.2 - - Red Hat Enterprise Linux - - - EOO - -: centos-8 -: -cat <<EOI >=os-release; - NAME="CentOS Linux" - VERSION="8 (Core)" - ID="centos" - ID_LIKE="rhel fedora" - VERSION_ID="8" - PLATFORM_ID="platform:el8" - PRETTY_NAME="CentOS Linux 8 (Core)" - ANSI_COLOR="0;31" - CPE_NAME="cpe:/o:centos:centos:8" - HOME_URL="https://www.centos.org/" - BUG_REPORT_URL="https://bugs.centos.org/" - - CENTOS_MANTISBT_PROJECT="CentOS-8" - CENTOS_MANTISBT_PROJECT_VERSION="8" - REDHAT_SUPPORT_PRODUCT="centos" - REDHAT_SUPPORT_PRODUCT_VERSION="8" - EOI -$* x86_64-linux-gnu os-release >>EOO - centos - rhel|fedora - 8 - - CentOS Linux - - - EOO diff --git a/bpkg/system-package-manager.cxx b/bpkg/system-package-manager.cxx index 793dec6..9e54418 100644 --- a/bpkg/system-package-manager.cxx +++ b/bpkg/system-package-manager.cxx @@ -30,6 +30,17 @@ namespace bpkg // vtable } + static optional<os_release> + host_release (const target_triplet& host) + try + { + return butl::host_os_release (host); + } + catch (const runtime_error& e) + { + fail << "unable to determine host operating system release: " << e << endf; + } + // Return true if the specified operating system is or like the specified // id. // @@ -66,7 +77,7 @@ namespace bpkg unique_ptr<system_package_manager> r; - if (optional<os_release> oos = host_os_release (host)) + if (optional<os_release> oos = host_release (host)) { os_release& os (*oos); @@ -138,7 +149,7 @@ namespace bpkg unique_ptr<system_package_manager> r; - if (optional<os_release> oos = host_os_release (host)) + if (optional<os_release> oos = host_release (host)) { os_release& os (*oos); diff --git a/bpkg/system-package-manager.hxx b/bpkg/system-package-manager.hxx index 4549fba..4ae2e07 100644 --- a/bpkg/system-package-manager.hxx +++ b/bpkg/system-package-manager.hxx @@ -8,13 +8,15 @@ #include <bpkg/utility.hxx> #include <libbutl/path-map.hxx> +#include <libbutl/host-os-release.hxx> #include <bpkg/package.hxx> #include <bpkg/common-options.hxx> -#include <bpkg/host-os-release.hxx> namespace bpkg { + using os_release = butl::os_release; + // The system/distribution package manager interface. Used by both pkg-build // (to query and install system packages) and by pkg-bindist (to generate // them). |