about summary refs log tree commit homepage
path: root/ci
diff options
context:
space:
mode:
authorEric Wong <e@80x24.org>2023-09-08 13:09:08 +0000
committerEric Wong <e@80x24.org>2023-09-08 20:43:23 +0000
commit053ffb197e57c477bc21c0c4aa71bb3a741cff9a (patch)
treeb8bb1c2a281bd065804f22a5209e13ab3d27278c /ci
parentbb862be465bbacb1b5be183c29693d3ef4c35167 (diff)
downloadpublic-inbox-053ffb197e57c477bc21c0c4aa71bb3a741cff9a.tar.gz
Still a work-in-progress, but OpenBSD's pkg_add/pkg_delete seem
to be working somewhat.  The dependency system seems to need some
extra help to ensure leaf packages with their own dependencies
(e.g.  `xapian-bindings-perl') get uninstalled before their
dependencies (`xapian-core').

Deduplicating the command-line is also required since both
pkg_add and pkg_delete will repeat the installation/removal if
a package is specified multiple times in the same invocation.
Diffstat (limited to 'ci')
-rwxr-xr-xci/deps.perl85
-rwxr-xr-xci/profiles.sh23
2 files changed, 84 insertions, 24 deletions
diff --git a/ci/deps.perl b/ci/deps.perl
index e7d43cd9..ea46b789 100755
--- a/ci/deps.perl
+++ b/ci/deps.perl
@@ -55,12 +55,15 @@ my $profiles = {
 };
 
 # account for granularity differences between package systems and OSes
-my @precious;
-if ($^O eq 'freebsd') {
-        @precious = qw(perl curl Socket6 IO::Compress);
-} elsif ($pkg_fmt eq 'rpm') {
-        @precious = qw(perl curl);
-}
+# curl, TimeDate (Date::Parse) and Socket6 are dependencies of git on
+# some/most OSes
+my @precious = do {
+        if ($^O eq 'freebsd') { qw(curl Socket6) }
+        elsif ($pkg_fmt eq 'rpm') { qw(curl) }
+        # OpenBSD git depends on Date::Parse (p5-Time-TimeDate) indirectly,
+        elsif ($^O eq 'openbsd') { qw(curl Socket6 Date::Parse) }
+        else { () }
+};
 
 if (@precious) {
         my $re = join('|', map { quotemeta($_) } @precious);
@@ -76,11 +79,15 @@ $profiles->{v2essential} = [ @{$profiles->{essential}}, qw(DBD::SQLite DBI) ];
 
 # package names which can't be mapped automatically:
 my $non_auto = {
-        'perl' => { pkg => 'perl5' },
+        'perl' => {
+                pkg => 'perl5',
+                pkg_add => [], # Perl is part of OpenBSD base
+        },
         'Date::Parse' => {
                 deb => 'libtimedate-perl',
                 pkg => 'p5-TimeDate',
                 rpm => 'perl-TimeDate',
+                pkg_add => 'p5-Time-TimeDate',
         },
         'Digest::SHA' => {
                 deb => 'perl', # libperl5.XX, but the XX varies
@@ -99,6 +106,7 @@ my $non_auto = {
                 pkg => 'perl5',
         },
         'Inline::C' => {
+                pkg_add => 'p5-Inline', # tested OpenBSD 7.3
                 rpm => 'perl-Inline', # for CentOS 7.x, at least
         },
         'DBD::SQLite' => { deb => 'libdbd-sqlite3-perl' },
@@ -106,6 +114,11 @@ my $non_auto = {
                 deb => 'libplack-perl',
                 pkg => 'p5-Plack',
         },
+        'Search::Xapian' => {
+                pkg => [qw(xapian-core p5-Xapian)],
+                pkg_add => [qw(xapian-core xapian-bindings-perl)],
+                rpm => 'Search::Xapian', # 3rd-party repo
+        },
         'Test::Simple' => {
                 deb => 'perl', # perl-modules-5.XX, but the XX varies
                 pkg => 'perl5',
@@ -130,11 +143,30 @@ my $non_auto = {
         },
 };
 
+# OpenBSD and FreeBSD both use "p5-".($CPAN_NAME =~ s/::/-/gr)
+if ($pkg_fmt eq 'pkg_add') {
+        for my $name (keys %$non_auto) {
+                my $fbsd_pkg = $non_auto->{$name}->{pkg};
+                $fbsd_pkg = [] if ($fbsd_pkg // '') eq 'perl5';
+                $non_auto->{$name}->{pkg_add} //= $fbsd_pkg if $fbsd_pkg;
+        }
+}
+
+my %inst_check = (
+        pkg => sub { system(qw(pkg info -q), $_[0]) == 0 },
+        deb => sub { system("dpkg -s $_[0] >/dev/null 2>&1") == 0 },
+        pkg_add => sub { system(qw(pkg_info -q -e), "$_[0]->=0") == 0 },
+        rpm => sub { system("rpm -qs $_[0] >/dev/null 2>&1") == 0 },
+);
+
+our $INST_CHECK = $inst_check{$pkg_fmt} || die <<"";
+don't know how to check install status for $pkg_fmt
+
 my (@pkg_install, @pkg_remove, %all);
 for my $ary (values %$profiles) {
         $all{$_} = \@pkg_remove for @$ary;
 }
-if ($^O eq 'freebsd') {
+if ($^O =~ /\A(?:free|open)bsd\z/) {
         $all{'IO::KQueue'} = \@pkg_remove;
 }
 $profiles->{all} = [ keys %all ]; # pseudo-profile for all packages
@@ -154,6 +186,10 @@ while (my ($pkg, $dst_pkg_list) = each %all) {
         push @$dst_pkg_list, list(pkg2ospkg($pkg, $pkg_fmt));
 }
 
+my %inst = map { $_ => 1 } @pkg_install;
+@pkg_remove = grep { !$inst{$_} } @pkg_remove;
+@pkg_install = grep { !$INST_CHECK->($_) } @pkg_install;
+
 my @apt_opts =
         qw(-o APT::Install-Recommends=false -o APT::Install-Suggests=false);
 
@@ -167,9 +203,8 @@ if ($pkg_fmt eq 'deb') {
                 # remove it in an "install" sub-command:
                 map { "$_-" } @pkg_remove);
         root('apt-get', @apt_opts, qw(autoremove --purge -y), @quiet);
-} elsif ($pkg_fmt eq 'pkg') {
+} elsif ($pkg_fmt eq 'pkg') { # FreeBSD
         my @quiet = $ENV{V} ? () : ('-q');
-        # FreeBSD, maybe other *BSDs are similar?
 
         # don't remove stuff that isn't installed:
         exclude_uninstalled(\@pkg_remove);
@@ -182,6 +217,21 @@ if ($pkg_fmt eq 'deb') {
         exclude_uninstalled(\@pkg_remove);
         root(qw(yum remove -y), @quiet, @pkg_remove) if @pkg_remove;
         root(qw(yum install -y), @quiet, @pkg_install) if @pkg_install;
+} elsif ($pkg_fmt eq 'pkg_add') { # OpenBSD
+        exclude_uninstalled(\@pkg_remove);
+        my @quiet = $ENV{V} ? ('-'.('v'x$ENV{V})) : qw(-x); # -x : no progress
+        if (@pkg_remove) {
+                my @lifo = qw(xapian-bindings-perl);
+                for my $dep (@lifo) {
+                        grep(/\A\Q$dep\E\z/, @pkg_remove) or next;
+                        root(qw(pkg_delete -I), @quiet, $dep);
+                        @pkg_remove = grep(!/\A\Q$dep\E\z/, @pkg_remove);
+                }
+                root(qw(pkg_delete -I), @quiet, @pkg_remove);
+        }
+        root(qw(pkg_delete -a), @quiet);
+        @pkg_install = map { "$_--" } @pkg_install; # disambiguate w3m
+        root(qw(pkg_add), @quiet, @pkg_install) if @pkg_install;
 } else {
         die "unsupported package format: $pkg_fmt\n";
 }
@@ -206,7 +256,7 @@ sub pkg2ospkg {
                 } elsif ($fmt eq 'rpm') {
                         $pkg =~ s/::/-/g;
                         return "perl-$pkg"
-                } elsif ($fmt eq 'pkg') {
+                } elsif ($fmt =~ /\Apkg(?:_add)?\z/) {
                         $pkg =~ s/::/-/g;
                         return "p5-$pkg"
                 } else {
@@ -232,18 +282,9 @@ sub profile2dst {
 
 sub exclude_uninstalled {
         my ($list) = @_;
-        my %inst_check = (
-                pkg => sub { system(qw(pkg info -q), $_[0]) == 0 },
-                deb => sub { system("dpkg -s $_[0] >/dev/null 2>&1") == 0 },
-                rpm => sub { system("rpm -qs $_[0] >/dev/null 2>&1") == 0 },
-        );
-
-        my $cb = $inst_check{$pkg_fmt} || die <<"";
-don't know how to check install status for $pkg_fmt
-
-        my @tmp;
+        my (@tmp, %seen);
         for my $pkg (@$list) {
-                push @tmp, $pkg if $cb->($pkg);
+                push @tmp, $pkg if !$seen{$pkg}++ && $INST_CHECK->($pkg);
         }
         @$list = @tmp;
 }
diff --git a/ci/profiles.sh b/ci/profiles.sh
index 55b998d7..04cefa15 100755
--- a/ci/profiles.sh
+++ b/ci/profiles.sh
@@ -1,5 +1,5 @@
 #!/bin/sh
-# Copyright (C) 2019-2021 all contributors <meta@public-inbox.org>
+# Copyright (C) all contributors <meta@public-inbox.org>
 # License: AGPL-3.0+ <https://www.gnu.org/licenses/agpl-3.0.txt>
 
 # Prints OS-specific package profiles to stdout (one per line) to use
@@ -7,7 +7,7 @@
 
 # set by os-release(5) or similar
 ID= VERSION_ID=
-case $(uname -o) in
+case $(uname -o 2>/dev/null || uname -s) in
 GNU/Linux)
         for f in /etc/os-release /usr/lib/os-release
         do
@@ -42,12 +42,22 @@ FreeBSD)
                 echo >&2 "ID=$ID $(uname -r) too old to support";
                 exit 1
         }
+        ;;
+OpenBSD)
+        ID=openbsd
+        VERSION_ID=$(uname -r | cut -d . -f 1)
+        test "$VERSION_ID" -lt 7 && {
+                echo >&2 "ID=$ID $(uname -r) too old to support";
+                exit 1
+        }
+        ;;
 esac
 
 case $ID in
 freebsd) PKG_FMT=pkg ;;
 debian|ubuntu) PKG_FMT=deb ;;
 centos|redhat|fedora) PKG_FMT=rpm ;;
+openbsd) PKG_FMT=pkg_add ;; # unsure about name, but it's not FreeBSD `pkg'
 *) echo >&2 "PKG_FMT undefined for ID=$ID in $0"
 esac
 
@@ -76,4 +86,13 @@ essential devtest
 all Search::Xapian-
 EOF
         ;;
+openbsd-7) sed "s/^/$PKG_FMT /" <<EOF
+all devtest-
+all devtest Inline::C-
+all devtest Inline::C
+v2essential
+essential
+essential devtest-
+EOF
+        ;;
 esac