[kdesrc-build] /: Add support library for handling /etc/os-release.
Michael Pyne
null at kde.org
Sun Oct 14 23:44:34 BST 2018
Git commit f3f100de6410d5ad9b84bef2d237ee2540e0f043 by Michael Pyne.
Committed on 14/10/2018 at 22:41.
Pushed by mpyne into branch 'master'.
Add support library for handling /etc/os-release.
This gets me just that little itty bitty step farther towards
implementing support for distro-specific things (like listing Perl
dependencies, build dependencies, etc.)
See also https://phabricator.kde.org/T9507
M +1 -0 CMakeLists.txt
M +10 -0 doc/index.docbook
M +14 -0 doc/man-kdesrc-build.1.docbook
M +4 -1 modules/ksb/Application.pm
A +130 -0 modules/ksb/OSSupport.pm
A +10 -0 t/data/os-release
A +30 -0 t/os-release-basics.t
https://commits.kde.org/kdesrc-build/f3f100de6410d5ad9b84bef2d237ee2540e0f043
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 8e762ae..1ea5bca 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -45,6 +45,7 @@ if (KDESRC_BUILD_INSTALL_MODULES)
modules/ksb/ModuleResolver.pm
modules/ksb/ModuleSet.pm
modules/ksb/OptionsBase.pm
+ modules/ksb/OSSupport.pm
modules/ksb/PhaseList.pm
modules/ksb/RecursiveFH.pm
modules/ksb/StatusView.pm
diff --git a/doc/index.docbook b/doc/index.docbook
index 64dc4c7..6e8c40c 100644
--- a/doc/index.docbook
+++ b/doc/index.docbook
@@ -3001,6 +3001,16 @@ Display the program version.
</para></listitem>
</varlistentry>
+<varlistentry id="cmdline-show-info">
+<term><parameter>--show-info</parameter></term>
+<listitem><para>
+Displays information about &kdesrc-build; and the operating system, that may
+prove useful in bug reports or when asking for help in forums or mailing lists.
+</para>
+<para>Available since version 18.11.</para>
+</listitem>
+</varlistentry>
+
<varlistentry id="cmdline-author">
<term><parameter>--author</parameter></term>
<listitem><para>
diff --git a/doc/man-kdesrc-build.1.docbook b/doc/man-kdesrc-build.1.docbook
index 539b54a..4872534 100644
--- a/doc/man-kdesrc-build.1.docbook
+++ b/doc/man-kdesrc-build.1.docbook
@@ -102,6 +102,20 @@ combining short options into one at this point. (E.g. running
</listitem>
</varlistentry>
+<varlistentry>
+<term>
+<option>--show-info</option>
+</term>
+
+<listitem>
+<para>
+ Shows information about &kdesrc-build; and the operating system which may
+ be useful in bug reports or when requesting help on forums or mailing
+ lists.
+</para>
+</listitem>
+</varlistentry>
+
<varlistentry>
<term>
<option>-p, --pretend</option>
diff --git a/modules/ksb/Application.pm b/modules/ksb/Application.pm
index 8e720b9..259be35 100644
--- a/modules/ksb/Application.pm
+++ b/modules/ksb/Application.pm
@@ -19,6 +19,7 @@ use ksb::Module;
use ksb::ModuleResolver 0.20;
use ksb::ModuleSet 0.20;
use ksb::ModuleSet::KDEProjects;
+use ksb::OSSupport;
use ksb::RecursiveFH;
use ksb::DependencyResolver 0.20;
use ksb::IPC::Pipe 0.20;
@@ -133,6 +134,7 @@ sub _readCommandLineOptionsAndSelectors
my ($cmdlineOptionsRef, $selectorsRef, $ctx, @options) = @_;
my $phases = $ctx->phases();
my @savedOptions = @options; # Copied for use in debugging.
+ my $os = ksb::OSSupport->new;
my $version = "kdesrc-build " . scriptVersion();
my $author = <<DONE;
$version was written (mostly) by:
@@ -152,6 +154,7 @@ DONE
%foundOptions = (
version => sub { say $version; exit },
author => sub { say $author; exit },
+ 'show-info' => sub { say $version; say "OS: ", $os->vendorID(); exit },
help => sub { _showHelpMessage(); exit 0 },
install => sub {
$self->{run_mode} = 'install';
@@ -276,7 +279,7 @@ DONE
# Actually read the options.
my $optsSuccess = GetOptionsFromArray(\@options, \%foundOptions,
- 'version', 'author', 'help', 'disable-snapshots|no-snapshots',
+ 'version', 'author', 'help', 'show-info', 'disable-snapshots|no-snapshots',
'install', 'uninstall', 'no-src|no-svn', 'no-install', 'no-build',
'no-tests', 'build-when-unchanged|force-build', 'no-metadata',
'verbose|v', 'quiet|quite|q', 'really-quiet', 'debug',
diff --git a/modules/ksb/OSSupport.pm b/modules/ksb/OSSupport.pm
new file mode 100644
index 0000000..c7414f8
--- /dev/null
+++ b/modules/ksb/OSSupport.pm
@@ -0,0 +1,130 @@
+package ksb::OSSupport 0.10;
+
+use ksb::Util qw(croak_runtime);
+
+use Text::ParseWords qw(nested_quotewords);
+use List::Util qw(first);
+
+=head1 NAME
+
+ksb::OSSupport
+
+=head1 DESCRIPTION
+
+Provides support code for handling distro-specific functionality, such as lists
+of package dependencies, command lines to update packages in the first place,
+and so on.
+
+See L<https://www.freedesktop.org/software/systemd/man/os-release.html> for the
+relevant specification.
+
+=head1 SYNOPSIS
+
+ my $os = ksb::OSSupport->new; # Autodetects info on running system
+ say "Current OS is: ", $os->vendorID;
+
+=cut
+
+=head1 METHODS
+
+=head2 new
+
+ $os = ksb::OSSupport->new;
+
+ # Manually point to os-release
+ $os = ksb::OSSupport->new('/usr/lib/os-release');
+
+Creates a new object. Required for other methods.
+
+=cut
+
+sub new
+{
+ my ($class, $file) = @_;
+
+ my $self = bless {
+ }, $class;
+
+ # $file might be undef
+ my @kvListRef = $self->_readOSRelease($file);
+
+ # Result comes in a listref which itself contains 2-elem
+ # lists... flatten list so it can be assigned to the hash
+ %{$self} = map { @{$_}[0,1] } @kvListRef;
+
+ return $self;
+}
+
+=head2 vendorID
+
+ my $vendor = $os->vendorID; # 'gentoo', 'debian', etc.
+
+Returns the vendor ID from the I<os-release> specification.
+
+=cut
+
+sub vendorID
+{
+ my $self = shift;
+ return $self->{ID} // 'unknown';
+}
+
+=head2 bestDistroMatch
+
+ # Might return 'fedora' if running on Scientific Linux
+ my $distro = $os->bestDistroMatch(qw/ubuntu fedora arch debian/);
+
+This uses the ID (and if needed, ID_LIKE) parameter in
+/etc/os-release to find the best possible match amongst the
+provided distro IDs. The list of distros should be ordered with
+most specific distro first.
+
+If no match is found, returns 'linux' (B<not> undef, '', or
+similar)
+
+=cut
+
+sub bestDistroMatch
+{
+ my ($self, @distros) = @_;
+ my @ids = $self->vendorID;
+
+ if (my $likeDistros = $self->{ID_LIKE} // '') {
+ push @ids, split(' ', $likeDistros);
+ }
+
+ foreach my $distro (@distros) {
+ return $distro if first { $distro eq $_ } @ids;
+ }
+
+ return 'linux';
+}
+
+sub _readOSRelease
+{
+ my ($self, $fileName) = @_;
+ my @files = $fileName ? $fileName : qw(/etc/os-release /usr/lib/os-release);
+ my ($fh, $error);
+
+ while (!$fh && @files) {
+ my $file = shift @files;
+ open $fh, '<:encoding(UTF-8)', $file and last;
+ $error = $!;
+ }
+
+ croak_runtime("Can't open os-release! $error")
+ unless $fh;
+
+ # skip comments and blank lines, and whitespace-only lines
+ my @lines = grep { ! /^\s*(?:#.*)?\s*$/ }
+ map { chomp; $_ }
+ <$fh>;
+ close $fh;
+
+ # 0 allows discarding the delimiter and any quotes
+ # Return should be one list per line, hopefully each list has
+ # exactly 2 values ([$key, $value]).
+ return nested_quotewords('=', 0, @lines);
+}
+
+1;
diff --git a/t/data/os-release b/t/data/os-release
new file mode 100644
index 0000000..16f282e
--- /dev/null
+++ b/t/data/os-release
@@ -0,0 +1,10 @@
+# See https://www.freedesktop.org/software/systemd/man/os-release.html for format
+NAME="Totally Valid Name"
+
+# inline comments are not allowed, a comment must be alone on a line
+ID=kdesrc-build
+
+ID_LIKE="sabayon gentoo-hardened gentoo"
+
+# Test shell quoting
+SPECIAL="\$VAR \\ \` \" is set"
diff --git a/t/os-release-basics.t b/t/os-release-basics.t
new file mode 100644
index 0000000..afe87bf
--- /dev/null
+++ b/t/os-release-basics.t
@@ -0,0 +1,30 @@
+use 5.014;
+use strict;
+use warnings;
+
+# Test ksb::OSSupport
+
+use Test::More;
+
+use ksb::OSSupport;
+
+# Unit test of _readOSRelease
+my @kvPairs = ksb::OSSupport->_readOSRelease('t/data/os-release');
+
+is(scalar @kvPairs, 4, 'Right number of key/value pairs');
+
+my %opts = map { @{$_}[0,1] } @kvPairs;
+
+is($opts{NAME}, 'Totally Valid Name', 'Right NAME');
+is($opts{ID}, 'kdesrc-build', 'Right ID');
+is($opts{ID_LIKE}, 'sabayon gentoo-hardened gentoo', 'Right ID_LIKE');
+is($opts{SPECIAL}, '$VAR \\ ` " is set', 'Right SPECIAL');
+
+# Use tests
+my $os = new_ok('ksb::OSSupport', ['t/data/os-release']);
+is($os->bestDistroMatch(qw/arch kdesrc-build sabayon/), 'kdesrc-build', 'ID preferred');
+is($os->bestDistroMatch(qw/ubuntu fedora gentoo/), 'gentoo', 'ID_LIKE respected');
+is($os->bestDistroMatch(qw/fedora gentoo gentoo-hardened sabayon/), 'gentoo', 'ID_LIKE preference order proper');
+is($os->vendorID, 'kdesrc-build', 'Right ID');
+
+done_testing();
More information about the kde-doc-english
mailing list