aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2023-03-13 13:25:08 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2023-03-13 14:08:15 +0200
commit3cc61ab4a6275428520cb0fb2f18dc3e09aef28a (patch)
tree98e4de2fc914c3510668d29879de30a483712c40
parent5bdce34d722233ea81557d02ebe213cc83cf4d7a (diff)
Move os-release facility to libbutl
-rw-r--r--bpkg/host-os-release.cxx121
-rw-r--r--bpkg/host-os-release.hxx59
-rw-r--r--bpkg/host-os-release.test.cxx55
-rw-r--r--bpkg/host-os-release.test.testscript178
-rw-r--r--bpkg/system-package-manager.cxx15
-rw-r--r--bpkg/system-package-manager.hxx4
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).