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();
