[Git][haskell-team/haskell-devscripts][master] 5 commits: Suppress from logs all URLs found in documentation; too noisy.

Felix Lechner (@lechner) gitlab at salsa.debian.org
Thu Apr 14 01:30:44 BST 2022



Felix Lechner pushed to branch master at Debian Haskell Group / haskell-devscripts


Commits:
c3aa8d4f by Felix Lechner at 2022-04-13T07:11:17-07:00
Suppress from logs all URLs found in documentation; too noisy.

- - - - -
dce7df05 by Felix Lechner at 2022-04-13T07:22:26-07:00
Do not install automatic Lintian overrides; will use Lintian's screens instead.

- - - - -
5fc2ddec by Felix Lechner at 2022-04-13T15:57:01-07:00
Simplify and rationalize Perl recipes; use environmental variables at higher levels.

- - - - -
8fb2844b by Felix Lechner at 2022-04-13T17:25:42-07:00
Allow building documentation even when HTML anchors for files cannot be resolved.

In an archive-wide rebuild 53 Haskell sources (out of 102) FTBFS because
dpkg-query cannot resolve docuentation references te other packages.

Examples are haskell-base-compat, haskell-monad-memo, and haskell-validity.

The errors look like that:

dpkg-query: no path found matching pattern /usr/share/doc/ghc-doc/html/libraries/base-4.13.0.0/Data-Semigroup-Internal.html
dpkg-query: no path found matching pattern /usr/share/doc/ghc-doc/html/libraries/base-4.13.0.0/Control-Monad-ST-Lazy-Imp.html
 at /usr/share/perl5/Debian/Debhelper/Buildsystem/Haskell/Recipes.pm line 103.
        Debian::Debhelper::Buildsystem::Haskell::Recipes::run_quiet("dh_haskell_depends") called
 at /usr/share/perl5/Debian/Debhelper/Buildsystem/Haskell/Recipes.pm line 127
        Debian::Debhelper::Buildsystem::Haskell::Recipes::run("dh_haskell_depends") called
 at /usr/share/perl5/Debian/Debhelper/Buildsystem/Haskell/Recipes.pm line 801
        Debian::Debhelper::Buildsystem::Haskell::Recipes::install_recipe("debian/tmp-inst-ghc") called
 at -e line 1
make: *** [/usr/share/cdbs/1/class/hlibrary.mk:156: debian/tmp-inst-ghc] Error 25
dpkg-buildpackage: error: debian/rules binary subprocess returned exit status 2
debuild: fatal error at line 1182:
dpkg-buildpackage -rfakeroot -us -uc -ui failed

Looking at ghc-doc, the installation paths currently have an extra '/src/'
segment. Should those files be installed without it?

/usr/share/doc/ghc-doc/html/libraries/base-4.13.0.0/src/Data-Semigroup-Internal.html
/usr/share/doc/ghc-doc/html/libraries/base-4.13.0.0/src/Control-Monad-ST-Lazy-Imp.html

- - - - -
d6321a34 by Felix Lechner at 2022-04-13T17:25:42-07:00
Use d/tmp as a uniform intermediate location; multiple compilers are not supported, anyway.

Provide compatibility links for sources with custom rules.

- - - - -


7 changed files:

- debian/control
- dh_haskell_blurbs
- dh_haskell_depends
- dh_haskell_provides
- dh_haskell_shlibdeps
- hlibrary.mk
- lib/Debian/Debhelper/Buildsystem/Haskell/Recipes.pm


Changes:

=====================================
debian/control
=====================================
@@ -33,7 +33,7 @@ Depends: dctrl-tools
   , ${misc:Depends}
   , ${perl:Depends}
 Breaks: haskell-devscripts (<= 0.10.2.3)
- , dh-haskell (<= 0.6.1)
+ , dh-haskell (<= 0.6.5)
 Replaces: haskell-devscripts (<= 0.10.2.3)
 Suggests: haskell-devscripts
 Description: Tools to help Debian developers build Haskell packages


=====================================
dh_haskell_blurbs
=====================================
@@ -30,8 +30,8 @@ use Unicode::UTF8 qw(encode_utf8);
 
 use Debian::Debhelper::Buildsystem::Haskell::Recipes qw(
   run
-  package_ext
-  packages_hc
+  installable_type
+  source_hc
 );
 
 const my $EMPTY => q{};
@@ -66,7 +66,7 @@ die encode_utf8('grep-dctrl is missing')
   unless system('command -v grep-dctrl > /dev/null') == 0;
 
 $ENV{DEB_DEFAULT_COMPILER} = $default_compiler;
-my $compiler = packages_hc();
+my $compiler = source_hc() || $ENV{DEB_DEFAULT_COMPILER};
 
 my $output = run('dh_listpackages', @args_bytes);
 chomp $output;
@@ -80,8 +80,8 @@ for my $installable (@installables) {
     my $short_blurb;
     my $blurb;
 
-    my $extension = package_ext($installable);
-    if ($extension eq 'dev') {
+    my $type = installable_type($installable);
+    if ($type eq 'dev') {
 
         $short_blurb = $EMPTY;
         $blurb
@@ -89,7 +89,7 @@ for my $installable (@installables) {
 
     }
 
-    if ($extension eq 'prof') {
+    if ($type eq 'prof') {
 
         $short_blurb = '; profiling libraries';
         $blurb
@@ -97,7 +97,7 @@ for my $installable (@installables) {
 
     }
 
-    if ($extension eq 'doc') {
+    if ($type eq 'doc') {
 
         $short_blurb = '; documentation';
         $blurb


=====================================
dh_haskell_depends
=====================================
@@ -31,18 +31,20 @@ use Path::Tiny;
 use Unicode::UTF8 qw(encode_utf8);
 
 use Debian::Debhelper::Buildsystem::Haskell::Recipes qw(
+  run_quiet
   run
-  package_ext
-  packages_hc
+  installable_type
+  source_hc
   find_config_for_ghc
-  cabal_depends
-  ghc_depends
-  hugs_depends
+  ghc_pkg_command
+  load_ghc_database
+  hashed_id_to_virtual_installable
 );
 
 const my $EMPTY => q{};
 const my $SPACE => q{ };
 const my $COMMA => q{,};
+const my $PLUS => q{+};
 
 const my $NEWLINE => qq{\n};
 const my $NULL => qq{\0};
@@ -63,19 +65,22 @@ Getopt::Long::GetOptions(%options)
   or die encode_utf8("error parsing options\n");
 
 my @args_bytes = grep { /^-/ } @ARGV;
-my @configs = grep { !/^-/ } @ARGV;
+my @ghc_configs = grep { !/^-/ } @ARGV;
 
 die encode_utf8("Installed package description file $_ can not be found")
-  for grep { !-e } @configs;
+  for grep { !-e } @ghc_configs;
 
 $ENV{DH_EXCLUDES} = join($SPACE, @excludes);
 
 die encode_utf8('grep-dctrl is missing')
   unless system('command -v grep-dctrl > /dev/null') == 0;
 
-my $haskell_compiler = packages_hc();
+my $haskell_compiler = source_hc() || $ENV{DEB_DEFAULT_COMPILER};
+my $haskell_ghc_pkg = ghc_pkg_command();
 
-my @extra_depends = get_extra_depends($haskell_compiler);
+my @extra_depends
+  = get_extra_depends($haskell_compiler, $haskell_ghc_pkg,
+    $ENV{DEB_GHC_DATABASE});
 
 my $package_list = run('dh_listpackages', @args_bytes);
 chomp $package_list;
@@ -88,7 +93,7 @@ for my $installable (@installables) {
     replace_line($substvars_path, 'haskell:Extra-Depends',
         join($COMMA . $SPACE, @extra_depends));
 
-    my $extension = package_ext($installable);
+    my $type = installable_type($installable);
 
     my @depends;
     my @recommends;
@@ -96,19 +101,73 @@ for my $installable (@installables) {
 
     if (any { $haskell_compiler eq $_ } qw{ghc ghcjs}) {
 
-        if (any { $extension eq $_ } qw{dev prof}) {
+        if (any { $type eq $_ } qw{dev prof}) {
 
-            @configs = find_config_for_ghc($installable)
-              unless @configs;
+            @ghc_configs = find_config_for_ghc($installable)
+              unless @ghc_configs;
 
             die encode_utf8(
 'dh_haskell_depends - no installed package description files found'
-            )unless @configs;
+            )unless @ghc_configs;
 
-            if ($extension eq 'dev') {
+            my @hashed_ids
+              = cabal_depends($haskell_ghc_pkg, $ENV{DEB_GHC_DATABASE},
+                @ghc_configs);
 
-                push(@depends,
-                    ghc_depends($haskell_compiler, $extension, @configs));
+            my @ghc_depends;
+            for my $hashed_id (@hashed_ids) {
+
+                # look in normal database
+                my $prerequisite
+                  =hashed_id_to_virtual_installable($haskell_compiler,
+                    $hashed_id, $type, $haskell_ghc_pkg, '--global');
+
+      # as a transition measure, check if dpkg knows about this virtual package
+                next
+                  unless system(
+                    "dpkg-query --show $prerequisite > /dev/null 2> /dev/null")
+                  == 0;
+
+                if (!length $prerequisite) {
+
+                    my $installable
+                      = providing_package_for_ghc($haskell_compiler,
+                        $hashed_id, $type);
+
+                    if (!length $installable) {
+
+                        warn encode_utf8(
+"WARNING: No Debian package provides the hashed Hackage id $hashed_id."
+                        );
+                        next;
+                    }
+
+                    my $version
+                      = run(qw{dpkg-query --showformat=${Version} --show},
+                        $installable);
+
+                    if (!length $version) {
+
+                        warn encode_utf8(
+"WARNING: No Debian version available for installable $installable."
+                        );
+                        next;
+                    }
+
+                    my $next_upstream_version = $version;
+                    $next_upstream_version =~ s{ - [^-]* $}{}x;
+                    $next_upstream_version .= $PLUS;
+
+                    $prerequisite
+                      ="$installable (>= $version), $installable (<< $next_upstream_version)";
+                }
+
+                push(@ghc_depends, $prerequisite);
+            }
+
+            if ($type eq 'dev') {
+
+                push(@depends, @ghc_depends);
 
                 my $prof = $installable;
                 $prof =~ s{ - [^-]+ $}{-prof}x;
@@ -125,27 +184,29 @@ for my $installable (@installables) {
                     $prof, 'debian/control') == 0;
             }
 
-            if ($extension eq 'prof') {
+            if ($type eq 'prof') {
 
                 my $dev = $installable;
                 $dev =~ s{ - [^-]+ $}{-dev}x;
 
                 push(@depends, "$dev (=\${binary:Version})");
-                push(@depends,
-                    ghc_depends($haskell_compiler, $extension, @configs));
+                push(@depends, @ghc_depends);
             }
         }
 
-        if ($extension eq 'doc') {
+        if ($type eq 'doc') {
 
             my $haddock_version = qx{haddock --interface-version};
             chomp $haddock_version;
 
             push(@depends, "haddock-interface-$haddock_version");
 
+            say encode_utf8(
+"Finding all links in the documentation in installable $installable."
+            );
             my @links =split(
                 m{\n}x,
-                run(
+                run_quiet(
                     'find', "debian/$installable",
                     qw{-name *.html -exec hxwls -r \{\} ;}
                 ));
@@ -177,9 +238,8 @@ for my $installable (@installables) {
             my $status = ($exitcode >> $WAIT_STATUS_SHIFT);
 
             # already in UTF-8
-            die encode_utf8("Non-zero exit code $exitcode.")
+            warn encode_utf8("Non-zero exit code $exitcode.")
               . $NEWLINE
-              . $stdout_bytes
               . $stderr_bytes
               if $exitcode;
 
@@ -208,7 +268,11 @@ for my $installable (@installables) {
 
     if ($haskell_compiler eq 'hugs') {
 
-        push(@depends, hugs_depends());
+        my $version= run(qw{dpkg-query --showformat=${Version} --show hugs});
+        my $upstream_version = $version;
+        $upstream_version =~ s{ - [^-]* $}{}x;
+
+        push(@depends, "hugs (>= $upstream_version)");
     }
 
     local $ENV{LC_ALL} = 'C.UTF-8';
@@ -223,8 +287,81 @@ for my $installable (@installables) {
 
 exit;
 
+sub cabal_depends {
+    my ($ghc_pkg, $tmp_db, @configs) = @_;
+
+    # fix sort order
+    local $ENV{LC_ALL} = 'C.UTF-8';
+
+    load_ghc_database($ghc_pkg, $tmp_db, @configs);
+
+    my @prerequisites;
+    for my $config (@configs) {
+
+        my $name = path($config)->basename(qr{ [.]conf $}x);
+        my $depends
+          = run($ghc_pkg, '--package-db', $tmp_db, qw{--simple-output field},
+            $name, 'depends');
+        push(@prerequisites, split($SPACE, $depends // $EMPTY));
+    }
+
+    my @have = sort +uniq @prerequisites;
+    my @exclude_patterns = split($SPACE, $ENV{DH_EXCLUDES} // $EMPTY);
+
+    # not sure this complies with Debhelper expectations
+    # excluded installables matching the patterns with or without version
+    # the versions should probably be dropped by the caller
+    s{ - [0-9] [.0-9a-zA-Z]* $}{}x for @exclude_patterns;
+
+    my @retained;
+    for my $prerequisite (@have) {
+
+        next
+          if any { $prerequisite =~ m{\Q$_\E} } @exclude_patterns;
+
+        push(@retained, $prerequisite);
+    }
+
+    return @retained;
+}
+
+sub providing_package_for_ghc {
+    my ($compiler, $hashed_id, $type) = @_;
+
+    my $extension = $EMPTY;
+    $extension = '_p'
+      if $type eq 'prof';
+
+    my $ghc_version= run(qw{dpkg-query --showformat=${Version} --show ghc});
+
+    my $directory_line= ghc_pkg_field($compiler, $hashed_id, 'library-dirs');
+    my (undef, $directory_list) = split(m{ \s* : \s* }x, $directory_line, 2);
+    my @library_dirs = split(m{ \s* , \s* }x, $directory_list);
+
+    my $library_line = ghc_pkg_field($compiler, $hashed_id, 'hs-libraries');
+    my (undef, $library_list) = split(m{ \s* : \s* }x, $library_line, 2);
+    my @libraries = split(m{ \s* , \s* }x, $library_list);
+
+    # look only at the first one
+    my $library = $libraries[0];
+
+    for my $directory (@library_dirs) {
+
+        my $library_path = "$directory/lib$library$extension.a";
+        next
+          unless -e $library_path;
+
+        my $line = run(qw{dpkg-query --search}, $library_path);
+        my ($installable) = split(m{ \s* : \s* }x, $line, 2);
+
+        return $installable;
+    }
+
+    return ();
+}
+
 sub get_extra_depends {
-    my ($compiler) = @_;
+    my ($compiler, $ghc_pkg, $tmp_db) = @_;
 
     local $ENV{LC_ALL} = 'C.UTF-8';
 
@@ -241,7 +378,7 @@ sub get_extra_depends {
 
         my $pkg_config = $1;
 
-        my @hackages = cabal_depends($pkg_config);
+        my @hackages = cabal_depends($ghc_pkg, $tmp_db, $pkg_config);
 
         run(qw{rm -f}, $pkg_config);
 
@@ -270,6 +407,17 @@ sub get_extra_depends {
     return @prerequisites;
 }
 
+sub ghc_pkg_field {
+    my ($compiler, $hashed_id, $field) = @_;
+
+    my $output= run("$compiler-pkg", qw{--global field}, $hashed_id, $field);
+
+    # may not process multi-line fields correctly
+    my ($value) = split($NEWLINE, $output, 2);
+
+    return ($value // $EMPTY);
+}
+
 sub replace_line {
     my ($path, $field, $value) = @_;
 


=====================================
dh_haskell_provides
=====================================
@@ -32,11 +32,12 @@ use Unicode::UTF8 qw(encode_utf8);
 
 use Debian::Debhelper::Buildsystem::Haskell::Recipes qw(
   run
-  package_ext
-  package_hc
+  installable_type
+  installable_hc
   find_config_for_ghc
-  cabal_package_ids
-  ghc_provides
+  ghc_pkg_command
+  load_ghc_database
+  hashed_id_to_virtual_installable
 );
 
 const my $SPACE => q{ };
@@ -45,7 +46,9 @@ const my $NEWLINE => qq{\n};
 
 my $program_name = basename($0);
 
+# for a call from ghc's d/rules
 $ENV{DEB_DEFAULT_COMPILER} ||= 'ghc';
+$ENV{DEB_GHC_DATABASE} ||= 'debian/tmp-db';
 
 my @excludes;
 
@@ -72,7 +75,7 @@ chomp $output;
 my @installables = split($SPACE, $output);
 for my $installable (@installables) {
 
-    my $extension = package_ext($installable);
+    my $type = installable_type($installable);
 
     @configs = find_config_for_ghc($installable)
       unless @configs;
@@ -81,18 +84,39 @@ for my $installable (@installables) {
         "$program_name: No installed package description files found")
       unless @configs;
 
-    my $compiler = package_hc($installable);
-    my @provides = ghc_provides($compiler, $extension, @configs);
+    my $compiler = installable_hc($installable) || $ENV{DEB_DEFAULT_COMPILER};
+
+    my $ghc_pkg = ghc_pkg_command();
+    load_ghc_database($ghc_pkg, $ENV{DEB_GHC_DATABASE}, @configs);
+
+    my @hashed_ids;
+    for my $config (@configs) {
+
+        my $name = path($config)->basename(qr{ [.]conf $}x);
+        push(
+            @hashed_ids,
+            run(
+                $ghc_pkg, '--package-db', $ENV{DEB_GHC_DATABASE},
+                qw{--simple-output field},
+                $name, 'id'
+            ));
+    }
+
+    my @provides;
+    push(
+        @provides,
+        hashed_id_to_virtual_installable(
+            $compiler, $_, $type,
+            $ghc_pkg, '--package-db', $ENV{DEB_GHC_DATABASE}))for @hashed_ids;
 
     my $substvars_path = "debian/$installable.substvars";
     replace_line($substvars_path, 'haskell:Provides',
         join($COMMA . $SPACE, @provides));
 
-    if ($extension eq 'dev') {
+    if ($type eq 'dev') {
 
-        my @package_ids = cabal_package_ids(@configs);
         replace_line($substvars_path, "haskell:$compiler-package",
-            join($SPACE, @package_ids));
+            join($SPACE, @hashed_ids));
     }
 }
 


=====================================
dh_haskell_shlibdeps
=====================================
@@ -33,9 +33,10 @@ use Unicode::UTF8 qw(encode_utf8 decode_utf8);
 
 use Debian::Debhelper::Buildsystem::Haskell::Recipes qw(
   run
-  package_ext
+  installable_type
   find_config_for_ghc
-  tmp_package_db
+  ghc_pkg_command
+  load_ghc_database
 );
 
 const my $SPACE => q{ };
@@ -68,9 +69,9 @@ chomp $output;
 my @installables = split($SPACE, $output);
 for my $installable (@installables) {
 
-    my $extension = package_ext($installable);
+    my $type = installable_type($installable);
     next
-      unless $extension eq 'dev';
+      unless $type eq 'dev';
 
     @configs = find_config_for_ghc($installable)
       unless @configs;
@@ -84,18 +85,27 @@ path($T_DIR)->mkpath;
 
 my @hackages = map { path($_)->basename(qr{ [.]conf $}x) } @configs;
 
-my @ghc_pkg = tmp_package_db(@configs);
+my $ghc_pkg = ghc_pkg_command();
+load_ghc_database($ghc_pkg, $ENV{DEB_GHC_DATABASE}, @configs);
 
 my @gcc_args;
 for my $hackage (@hackages) {
 
     my $libdir_string = decode_utf8(
-        run(@ghc_pkg, qw{--simple-output field}, $hackage, 'library-dirs'));
+        run(
+            $ghc_pkg, '--package-db',
+            $ENV{DEB_GHC_DATABASE}, qw{--simple-output field},
+            $hackage, 'library-dirs'
+        ));
     my @lib_dirs = split($SPACE, $libdir_string);
     push(@gcc_args, (map { "-L$_" } @lib_dirs));
 
     my $library_string = decode_utf8(
-        run(@ghc_pkg, qw{--simple-output field}, $hackage, 'extra-libraries'));
+        run(
+            $ghc_pkg, '--package-db',
+            $ENV{DEB_GHC_DATABASE}, qw{--simple-output field},
+            $hackage, 'extra-libraries'
+        ));
     my @libraries = split($SPACE, $library_string);
     push(@gcc_args, (map { "-l$_" } @libraries));
 }
@@ -110,9 +120,9 @@ run('gcc', @gcc_args_bytes, $source_path, '-o', $probe_path);
 
 for my $installable (@installables) {
 
-    my $extension = package_ext($installable);
+    my $type = installable_type($installable);
     next
-      unless $extension eq 'dev';
+      unless $type eq 'dev';
 
     my $substvars_path = "debian/$installable.substvars";
 


=====================================
hlibrary.mk
=====================================
@@ -33,6 +33,8 @@ export HOME = /homedoesnotexistatbuildtime
 # we can safely assume the desired compiler is ghc.
 DEB_DEFAULT_COMPILER ?= ghc
 
+DEB_GHC_DATABASE = debian/tmp-db
+
 DEB_CABAL_PACKAGE ?= $(shell cat *.cabal |\
  perl -ne \
  'if (/^name\s*:\s*(.*?)\s*$$/i) {$$_ = $$1; tr/A-Z/a-z/; print; exit 0;}')
@@ -112,8 +114,6 @@ endif
 
 DEB_BUILD_DEPENDENCIES = build-arch
 
-DEB_LINTIAN_OVERRIDES_FILE = debian/libghc-$(CABAL_PACKAGE)-dev.lintian-overrides
-
 # We call the shell for most things, so make our variables available to it
 export DEB_SETUP_BIN_NAME
 export CABAL_PACKAGE
@@ -125,11 +125,11 @@ export DEB_SETUP_GHC_CONFIGURE_ARGS
 export OPTIMIZATION
 export TESTS
 export DEB_DEFAULT_COMPILER
+export DEB_GHC_DATABASE
 export DEB_PACKAGES
 export DEB_HADDOCK_OPTS
 export HASKELL_HIDE_PACKAGES
 export DEB_GHC_EXTRA_PACKAGES
-export DEB_LINTIAN_OVERRIDES_FILE
 export DEB_ENABLE_HOOGLE
 export MAKEFILE
 export GHC_HAS_SMP 
@@ -138,7 +138,9 @@ clean::
 	perl -d:Confess -MDebian::Debhelper::Buildsystem::Haskell::Recipes=/.*/ \
 		-E 'clean_recipe'
 	rm -f build-ghc-stamp build-hugs-stamp
-	rm -rf debian/tmp-inst-ghc debian/tmp-inst-ghcjs
+	rm -f debian/tmp-inst-ghc debian/tmp-inst-ghcjs
+	rm -rf debian/tmp
+	rm -rf $(DEB_GHC_DATABASE)
 
 $(DEB_SETUP_BIN_NAME):
 	perl -d:Confess -MDebian::Debhelper::Buildsystem::Haskell::Recipes=/.*/ \
@@ -151,7 +153,7 @@ build-ghc-stamp: $(DEB_SETUP_BIN_NAME)
 
 build/%-dev build/%-prof build/%-doc:: build-ghc-stamp
 
-debian/tmp-inst-%: $(DEB_SETUP_BIN_NAME) build-ghc-stamp
+debian/tmp: $(DEB_SETUP_BIN_NAME) build-ghc-stamp
 	perl -d:Confess -MDebian::Debhelper::Buildsystem::Haskell::Recipes=/.*/ \
 		-E 'install_recipe($$ARGV[0])' "$@"
 
@@ -162,9 +164,11 @@ dist-hugs: $(DEB_SETUP_BIN_NAME)
 build/libhugs-$(CABAL_PACKAGE):: dist-hugs
 	$(DEB_SETUP_BIN_NAME) build --builddir=dist-hugs
 
-install/libghc-$(CABAL_PACKAGE)-dev install/libghc-$(CABAL_PACKAGE)-prof install/libghc-$(CABAL_PACKAGE)-doc:: debian/tmp-inst-ghc
+install/libghc-$(CABAL_PACKAGE)-dev install/libghc-$(CABAL_PACKAGE)-prof install/libghc-$(CABAL_PACKAGE)-doc:: debian/tmp
+	ln --symbolic --force debian/tmp debian/tmp-inst-ghc
 
-install/libghcjs-$(CABAL_PACKAGE)-dev install/libghcjs-$(CABAL_PACKAGE)-prof install/libghcjs-$(CABAL_PACKAGE)-doc:: debian/tmp-inst-ghcjs
+install/libghcjs-$(CABAL_PACKAGE)-dev install/libghcjs-$(CABAL_PACKAGE)-prof install/libghcjs-$(CABAL_PACKAGE)-doc:: debian/tmp
+	ln --symbolic --force debian/tmp debian/tmp-inst-ghcjs
 
 install/libhugs-$(CABAL_PACKAGE):: $(DEB_SETUP_BIN_NAME) dist-hugs
 	$(DEB_SETUP_BIN_NAME) copy --destdir=debian/libhugs-$(CABAL_PACKAGE) --builddir=dist-hugs


=====================================
lib/Debian/Debhelper/Buildsystem/Haskell/Recipes.pm
=====================================
@@ -28,17 +28,15 @@ our @EXPORT_OK;
 BEGIN {
 
     @EXPORT_OK = qw(
+      run_quiet
       run
-      package_hc
-      package_ext
-      packages_hc
-      cabal_package_ids
-      cabal_depends
+      installable_hc
+      installable_type
+      source_hc
       hashed_dependency
-      ghc_depends
-      tmp_package_db
-      ghc_provides
-      hugs_depends
+      ghc_pkg_command
+      load_ghc_database
+      hashed_id_to_virtual_installable
       find_config_for_ghc
       clean_recipe
       make_setup_recipe
@@ -50,6 +48,7 @@ BEGIN {
     );
 }
 
+use Carp qw(croak);
 use Const::Fast;
 use Cwd;
 use Date::Parse qw(str2time);
@@ -61,15 +60,11 @@ use Unicode::UTF8 qw(encode_utf8 decode_utf8);
 
 const my $EMPTY => q{};
 const my $SPACE => q{ };
-const my $PLUS => q{+};
 const my $SEMICOLON => q{;};
-const my $LESS_THAN => q{<};
-const my $DOUBLE_LESS_THAN => $LESS_THAN x 2;
 const my $NEWLINE => qq{\n};
 
 const my $WAIT_STATUS_SHIFT => 8;
 
-const my $MINIMUM_GHC_VERSION => 8;
 const my $CABAL_VERSION_IMPLYING_SIMPLE_BUILDS => 2.2;
 
 =head1 NAME
@@ -138,35 +133,32 @@ sub run {
     return $output;
 }
 
-=item package_hc
+=item installable_hc
 
 =cut
 
-sub package_hc {
+sub installable_hc {
     my ($installable) = @_;
 
     return 'ghc'
       if $installable =~ m{^ ghc (:? -prof )? $};
 
-    my $compiler = $installable;
+    # get compiler from lib prefix, if possible
+    if ($installable =~ m{^ lib ( [^-]+ ) - }x) {
 
-    # strip hackage name
-    $compiler =~ s{ - .* $}{}x;
+        my $compiler = $1;
 
-    # strip lib prefix, if any, and use result
-    if ($compiler =~ s{^ lib }{}x) {
         return $compiler;
     }
 
-    # default if there is no lib prefix
-    return $ENV{DEB_DEFAULT_COMPILER};
+    return $EMPTY;
 }
 
-=item package_ext
+=item installable_type
 
 =cut
 
-sub package_ext {
+sub installable_type {
     my ($installable) = @_;
 
     return 'dev'
@@ -175,40 +167,41 @@ sub package_ext {
     return 'prof'
       if $installable eq 'ghc-prof';
 
-    my $suffix = $installable;
+    # look at suffix
+    if ($installable =~ m{^ lib .* - ( [^-]+) $}x) {
 
-    # strip hackage name
-    $suffix =~ s{^ .* - }{}x;
+        my $suffix = $1;
 
-    return $suffix;
+        return $suffix;
+    }
+
+    return $EMPTY;
 }
 
-=item packages_hc
+=item source_hc
 
 =cut
 
-sub packages_hc {
+sub source_hc {
     my () = @_;
 
-    # fix sort order
-    local $ENV{LC_ALL} = 'C.UTF-8';
-
     # should be in UTF-8
     my $package_list = run('dh_listpackages');
     chomp $package_list;
 
     my @installables = split($SPACE, $package_list);
 
-    my @compilers = uniq map { package_hc($_) } @installables;
+    my @compilers
+      = uniq grep { length } map { installable_hc($_) } @installables;
 
-    die encode_utf8(
+    croak encode_utf8(
         'Multiple compilers not supported: ' . join($SPACE, (sort @compilers)))
       if @compilers > 1;
 
-    return $ENV{DEB_DEFAULT_COMPILER}
-      if !@compilers;
+    return $compilers[0]
+      if @compilers;
 
-    return $compilers[0];
+    return $EMPTY;
 }
 
 =item hc_libdir
@@ -224,19 +217,7 @@ sub hc_libdir {
     return 'usr/lib/ghcjs/.cabal/lib'
       if $compiler eq 'ghcjs';
 
-    die encode_utf8("Don't know package_libdir for $compiler");
-}
-
-=item package_libdir
-
-=cut
-
-sub package_libdir {
-    my ($installable) = @_;
-
-    my $compiler = package_hc($installable);
-
-    return hc_libdir($compiler);
+    croak encode_utf8("Don't know libdir for $compiler");
 }
 
 =item hc_pkgdir
@@ -261,19 +242,7 @@ sub hc_pkgdir {
         return "usr/lib/ghcjs/.ghcjs/$quadruplet/ghcjs/package.conf.d";
     }
 
-    die encode_utf8("Don't know pkgdir for $compiler");
-}
-
-=item package_pkgdir
-
-=cut
-
-sub package_pkgdir {
-    my ($installable) = @_;
-
-    my $compiler = package_hc($installable);
-
-    return hc_pkgdir($compiler);
+    croak encode_utf8("Don't know pkgdir for $compiler");
 }
 
 =item hc_prefix
@@ -289,7 +258,7 @@ sub hc_prefix {
     return 'usr/lib/ghcjs'
       if $compiler eq 'ghcjs';
 
-    die encode_utf8("Don't know prefix for $compiler");
+    croak encode_utf8("Don't know prefix for $compiler");
 }
 
 =item hc_haddock
@@ -305,7 +274,7 @@ sub hc_haddock {
     return 'haddock-ghcjs'
       if $compiler eq 'ghcjs';
 
-    die encode_utf8("Don't know haddock command for $compiler");
+    croak encode_utf8("Don't know haddock command for $compiler");
 }
 
 =item hc_docdir
@@ -313,9 +282,9 @@ sub hc_haddock {
 =cut
 
 sub hc_docdir {
-    my ($compiler, $hackage_name_version) = @_;
+    my ($compiler, $hackage_name, $hackage_version) = @_;
 
-    return "usr/lib/$compiler-doc/haddock/$hackage_name_version/";
+    return "usr/lib/$compiler-doc/haddock/$hackage_name-$hackage_version/";
 }
 
 =item hc_htmldir
@@ -325,302 +294,93 @@ sub hc_docdir {
 sub hc_htmldir {
     my ($compiler, $hackage_name) = @_;
 
-    $ENV{CABAL_PACKAGE} = $hackage_name;
-
     return "usr/share/doc/lib$compiler-$hackage_name-doc/html/";
 }
 
-=item dependency
-
-=cut
-
-sub dependency {
-    my ($installable) = @_;
-
-    my $version
-      = run(qw{dpkg-query --showformat=${Version} --show}, $installable);
-
-    my $next_upstream_version = $version;
-    $next_upstream_version =~ s{ - [^-]* $}{}x;
-    $next_upstream_version .= $PLUS;
-
-    return
-      "$installable (>= $version), $installable (<< $next_upstream_version)";
-}
-
-=item ghc_pkg_field
-
-=cut
-
-sub ghc_pkg_field {
-    my ($compiler, $hackage_name, $field) = @_;
-
-    my $output
-      = run("$compiler-pkg", qw{--global field}, $hackage_name, $field);
-
-    # may not process multi-line fields correctly
-    my ($value) = split($NEWLINE, $output, 2);
-
-    return ($value // $EMPTY);
-}
-
-=item providing_package_for_ghc
-
-=cut
-
-sub providing_package_for_ghc {
-    my ($compiler, $type, $package_id) = @_;
-
-    my $extension = $EMPTY;
-    $extension = '_p'
-      if $type eq 'prof';
-
-    my $ghc_version= run(qw{dpkg-query --showformat=${Version} --show ghc});
-
-    my $hackage_name = $package_id;
-    $hackage_name =~ s{ - [^-]{32} $}{}x
-      if system(qw{dpkg --compare-versions},
-        $ghc_version,$DOUBLE_LESS_THAN, $MINIMUM_GHC_VERSION) == 0;
-
-    my $directory_line
-      = ghc_pkg_field($compiler, $hackage_name, 'library-dirs');
-    my (undef, $directory_list) = split(m{ \s* : \s* }x, $directory_line, 2);
-    my @library_dirs = split(m{ \s* , \s* }x, $directory_list);
-
-    my $library_line = ghc_pkg_field($compiler, $hackage_name, 'hs-libraries');
-    my (undef, $library_list) = split(m{ \s* : \s* }x, $library_line, 2);
-    my @libraries = split(m{ \s* , \s* }x, $library_list);
-
-    # look only at the first one
-    my $library = $libraries[0];
-
-    for my $directory (@library_dirs) {
-
-        my $library_path = "$directory/lib$library$extension.a";
-        next
-          unless -e $library_path;
-
-        my $line = run(qw{dpkg-query --search}, $library_path);
-        my ($installable) = split(m{ \s* : \s* }x, $line, 2);
-
-        return $installable;
-    }
-
-    return ();
-}
-
-=item cabal_package_ids
-
-=cut
-
-sub cabal_package_ids {
-    my (@configs) = @_;
-
-    my @ghc_pkg = tmp_package_db(@configs);
-
-    my @package_ids;
-    for my $config (@configs) {
-
-        my $name = path($config)->basename(qr{ [.]conf $}x);
-        push(@package_ids,
-            run(@ghc_pkg, qw{--simple-output field}, $name, 'id'));
-    }
-
-    return @package_ids;
-}
-
-=item cabal_depends
-
-=cut
-
-sub cabal_depends {
-    my (@configs) = @_;
-
-    # fix sort order
-    local $ENV{LC_ALL} = 'C.UTF-8';
-
-    my @ghc_pkg = tmp_package_db(@configs);
-
-    my @constraints;
-    for my $config (@configs) {
-
-        my $name = path($config)->basename(qr{ [.]conf $}x);
-        my $depends
-          = run(@ghc_pkg, qw{--simple-output field}, $name, 'depends');
-        push(@constraints, split($SPACE, $depends // $EMPTY));
-    }
-
-    my @have = sort +uniq @constraints;
-    my @exclude_patterns = split($SPACE, $ENV{DH_EXCLUDES} // $EMPTY);
-
-    # not sure this complies with Debhelper expectations
-    # excluded installables matching the patterns with or without version
-    # the versions should probably be dropped by the caller
-    s{ - [0-9] [.0-9a-zA-Z]* $}{}x for @exclude_patterns;
-
-    my @retained;
-    for my $constraint (@have) {
-
-        next
-          if any { $constraint =~ m{\Q$_\E} } @exclude_patterns;
-
-        push(@retained, $constraint);
-    }
-
-    return @retained;
-}
-
 =item hashed_dependency
 
 =cut
 
 sub hashed_dependency {
-    my ($compiler, $type, $package_id) = @_;
+    my ($compiler, $type, $hashed_id) = @_;
 
-    my @ghc_pkg = usable_ghc_pkg();
-    my $virtual_pkg
-      = package_id_to_virtual_package($compiler, $type, $package_id, @ghc_pkg);
+    my $ghc_pkg = ghc_pkg_command();
 
-    # as a transition measure, check if dpkg knows about this virtual package
-    return $virtual_pkg
-      if system("dpkg-query --show $virtual_pkg > /dev/null 2> /dev/null")== 0;
+    # different order of arguments
+    my $installable
+      = hashed_id_to_virtual_installable($compiler, $hashed_id, $type,
+        $ghc_pkg, '--global');
 
-    return ();
+    return $installable;
 }
 
-=item ghc_depends
+=item ghc_pkg_command
 
 =cut
 
-sub ghc_depends {
-    my ($compiler, $type, @configs) = @_;
-
-    my @package_ids = cabal_depends(@configs);
-
-    my @constraints;
-    for my $package_id (@package_ids) {
-
-        my $constraint = hashed_dependency($compiler, $type, $package_id);
-
-        if (!length $constraint) {
-
-            my $installable
-              = providing_package_for_ghc($compiler, $type, $package_id);
-
-            $constraint = dependency($installable);
-            if (!length $constraint) {
-
-                warn encode_utf8(
-"WARNING: No Debian package provides haskell package $package_id.\n"
-                );
-                next;
-            }
-        }
-
-        push(@constraints, $constraint);
-    }
-
-    return @constraints;
-}
-
-=item usable_ghc_pkg
-
-=cut
-
-sub usable_ghc_pkg {
+sub ghc_pkg_command {
     my () = @_;
 
-    my @ghc_pkg;
-    my $version;
-
     my $inplace_ghc_pkg = 'inplace/bin/ghc-pkg';
-    if (-x $inplace_ghc_pkg) {
-
-        # we are building ghc and need to use the new ghc-pkg
-        @ghc_pkg = ($inplace_ghc_pkg);
-        $version = run(qw{dpkg-parsechangelog --show-field Version});
 
-    } else {
-        @ghc_pkg = qw{ghc-pkg};
-        $version= run(qw{dpkg-query --showformat=${Version} --show ghc});
-    }
+    # building ghc; use the new ghc-pkg
+    return $inplace_ghc_pkg
+      if -x $inplace_ghc_pkg;
 
-    # ghc-pkg prior to version 8 is unusable for our purposes.
-    return ()
-      if system(qw{dpkg --compare-versions},
-        $version, $DOUBLE_LESS_THAN, $MINIMUM_GHC_VERSION)== 0;
-
-    return @ghc_pkg;
+    return 'ghc-pkg';
 }
 
-=item tmp_package_db
+=item load_ghc_database
 
 =cut
 
-sub tmp_package_db {
-    my (@configs) = @_;
-
-    my @ghc_pkg = usable_ghc_pkg();
-    return ()
-      unless @ghc_pkg;
-
-    if (!-e 'debian/tmp-db/package.cache') {
-
-        run(qw{mkdir debian/tmp-db});
-        run(qw{cp}, @configs, 'debian/tmp-db/')
-          if @configs;
-
-        # Silence GHC 8.4's warning
-        # "ignoring (possibly broken) abi-depends field for packages"
-        # see also https://ghc.haskell.org/trac/ghc/ticket/14381
-        run(@ghc_pkg, qw{--package-db debian/tmp-db/ recache});
-    }
-
-    return (@ghc_pkg, qw{--package-db debian/tmp-db});
-}
+sub load_ghc_database {
+    my ($ghc_pkg, $tmp_db, @configs) = @_;
 
-=item ghc_provides
+    croak encode_utf8('No ghc-pkg executable')
+      unless length $ghc_pkg;
 
-=cut
+    croak encode_utf8('No folder for temporary GHC package data')
+      unless length $tmp_db;
 
-sub ghc_provides {
-    my ($compiler, $type, @configs) = @_;
+    path($tmp_db)->mkpath
+      unless -e $tmp_db;
 
-    my @ghc_pkg = tmp_package_db(@configs);
-    my @package_ids = cabal_package_ids(@configs);
+    run('cp', @configs, $tmp_db)
+      if @configs;
 
-    my @virtual;
-    push(@virtual,
-        package_id_to_virtual_package($compiler, $type, $_, @ghc_pkg))
-      for @package_ids;
+    # Silence GHC 8.4's warning
+    # "ignoring (possibly broken) abi-depends field for packages"
+    # see also https://ghc.haskell.org/trac/ghc/ticket/14381
+    run($ghc_pkg, '--package-db', $tmp_db, 'recache');
 
-    return @virtual;
+    return;
 }
 
-=item package_id_to_virtual_package
+=item hashed_id_to_virtual_installable
 
 =cut
 
-sub package_id_to_virtual_package {
-    my ($compiler, $type, $package_id, @ghc_pkg) = @_;
+sub hashed_id_to_virtual_installable {
+    my ($compiler, $hashed_id, $type, @command) = @_;
 
     my $name;
     my $version;
     my $long_abi;
 
-    if (@ghc_pkg) {
+    if (@command) {
 
-        $name = run(@ghc_pkg, qw{--simple-output --unit-id field},
-            $package_id, 'name');
-        $version = run(@ghc_pkg, qw{--simple-output --unit-id field},
-            $package_id, 'version');
-        $long_abi = run(@ghc_pkg, qw{--simple-output --unit-id field},
-            $package_id, 'abi');
+        $name = run(@command, qw{--simple-output --unit-id field},
+            $hashed_id, 'name');
+        $version = run(@command, qw{--simple-output --unit-id field},
+            $hashed_id, 'version');
+        $long_abi = run(@command, qw{--simple-output --unit-id field},
+            $hashed_id, 'abi');
 
     } else {
 
         # no usable ghc-pkg; parse package id
-        my $lowercase = lc $package_id;
+        my $lowercase = lc $hashed_id;
 
         ($name, $version, $long_abi)
           = ($lowercase =~ m{^ ([a-z0-9-]+) - ([0-9.]+) - (\S{32}) $}x);
@@ -634,20 +394,6 @@ sub package_id_to_virtual_package {
     return $virtual;
 }
 
-=item hugs_depends
-
-=cut
-
-sub hugs_depends {
-    my () = @_;
-
-    my $version= run(qw{dpkg-query --showformat=${Version} --show hugs});
-    my $upstream_version = $version;
-    $upstream_version =~ s{ - [^-]* $}{}x;
-
-    return ("hugs (>= $upstream_version)");
-}
-
 =item find_config_for_ghc
 
 =cut
@@ -655,7 +401,8 @@ sub hugs_depends {
 sub find_config_for_ghc {
     my ($installable) = @_;
 
-    my $pkgdir = package_pkgdir($installable);
+    my $compiler = installable_hc($installable) || $ENV{DEB_DEFAULT_COMPILER};
+    my $pkgdir = hc_pkgdir($compiler);
 
     if ($installable =~ s{ - prof $}{}x) {
 
@@ -688,16 +435,7 @@ sub clean_recipe {
         qw{Setup.hi Setup.ho Setup.o},
         glob('.*config*'));
 
-    if (-e $ENV{DEB_LINTIAN_OVERRIDES_FILE}) {
-        run(
-            qw{sed -i},
-            '/custom-library-search-path/ d',
-            $ENV{DEB_LINTIAN_OVERRIDES_FILE});
-        run('find',$ENV{DEB_LINTIAN_OVERRIDES_FILE},qw{-empty -delete});
-    }
-
     run(qw{rm -f}, $ENV{MAKEFILE});
-    run(qw{rm -rf debian/tmp-db});
 
     return;
 }
@@ -776,17 +514,17 @@ sub configure_recipe {
         qw{-exec touch -d "1998-01-01 UTC" {} ; }
     );
 
-    my $compiler = packages_hc();
+    my $compiler = source_hc() || $ENV{DEB_DEFAULT_COMPILER};
 
     my $package_list = run('dh_listpackages');
     chomp $package_list;
 
     my @installables = split($SPACE, $package_list);
-    my @extensions = map { package_ext($_) } @installables;
+    my @types = map { installable_type($_) } @installables;
 
     my $profiling;
     $profiling = '--enable-library-profiling'
-      if any { $_ eq 'prof' } @extensions;
+      if any { $_ eq 'prof' } @types;
 
     my $ldflags_line = run(qw{dpkg-buildflags --get LDFLAGS});
     my @ldflags = split($SPACE, $ldflags_line);
@@ -796,7 +534,7 @@ sub configure_recipe {
     my $prefix = hc_prefix($compiler);
     my $libdir = hc_libdir($compiler);
     my $docdir
-      = hc_docdir($compiler, "$ENV{CABAL_PACKAGE}-$ENV{CABAL_VERSION}");
+      = hc_docdir($compiler, $ENV{CABAL_PACKAGE}, $ENV{CABAL_VERSION});
     my $htmldir = hc_htmldir($compiler, $ENV{CABAL_PACKAGE});
 
     # DEB_SETUP_GHC_CONFIGURE_ARGS can contain multiple arguments
@@ -838,7 +576,7 @@ sub configure_recipe {
 sub build_recipe {
     my () = @_;
 
-    my $compiler = packages_hc();
+    my $compiler = source_hc() || $ENV{DEB_DEFAULT_COMPILER};
     my $output
       = run($ENV{DEB_SETUP_BIN_NAME},'build', "--builddir=dist-$compiler");
 
@@ -868,7 +606,7 @@ sub check_recipe {
         return;
     }
 
-    my $compiler = packages_hc();
+    my $compiler = source_hc() || $ENV{DEB_DEFAULT_COMPILER};
     my $output = run($ENV{DEB_SETUP_BIN_NAME},
         'test', "--builddir=dist-$compiler", '--show-details=direct');
 
@@ -882,7 +620,7 @@ sub check_recipe {
 sub haddock_recipe {
     my () = @_;
 
-    my $compiler = packages_hc();
+    my $compiler = source_hc() || $ENV{DEB_DEFAULT_COMPILER};
     my $haddock = hc_haddock($compiler);
 
     return
@@ -910,7 +648,7 @@ sub install_recipe {
     # fix sort order
     local $ENV{LC_ALL} = 'C.UTF-8';
 
-    my $compiler = packages_hc();
+    my $compiler = source_hc() || $ENV{DEB_DEFAULT_COMPILER};
 
     run($ENV{DEB_SETUP_BIN_NAME},
         'copy', "--builddir=dist-$compiler", "--destdir=$destination");
@@ -921,15 +659,15 @@ sub install_recipe {
     my @installables = split($SPACE, $package_list);
     for my $installable (@installables) {
 
-        my $extension = package_ext($installable);
+        my $type = installable_type($installable);
 
-        if ($extension eq 'dev') {
+        if ($type eq 'dev') {
 
             my $savedir = Cwd::getcwd;
             chdir($destination)
               or warn encode_utf8("Cannot change folder to $destination");
 
-            my $libdir = package_libdir($installable);
+            my $libdir = hc_libdir($compiler);
 
             run(qw{mkdir --parents}, $libdir);
             run(
@@ -959,7 +697,7 @@ sub install_recipe {
                     $pkg_config)
                   if length $ENV{HASKELL_HIDE_PACKAGES};
 
-                my $pkgdir = package_pkgdir($installable);
+                my $pkgdir = hc_pkgdir($compiler);
                 run(qw{install -D --mode=644},
                     $pkg_config, "debian/$installable/$pkgdir/$pkg_config");
                 run(qw{rm -f}, $pkg_config);
@@ -981,13 +719,13 @@ sub install_recipe {
             }
         }
 
-        if ($extension eq 'prof') {
+        if ($type eq 'prof') {
 
             my $savedir = Cwd::getcwd;
             chdir($destination)
               or warn encode_utf8("Cannot change folder to $destination");
 
-            my $libdir = package_libdir($installable);
+            my $libdir = hc_libdir($compiler);
 
             run(qw{mkdir --parents}, $libdir);
             run(
@@ -1004,7 +742,7 @@ sub install_recipe {
               or warn encode_utf8("Cannot change folder to $savedir");
         }
 
-        if ($extension eq 'doc') {
+        if ($type eq 'doc') {
 
             my $savedir = Cwd::getcwd;
             chdir($destination)
@@ -1027,7 +765,7 @@ sub install_recipe {
               or warn encode_utf8("Cannot change folder to $savedir");
 
             my $docdir
-              = hc_docdir($compiler,"$ENV{CABAL_PACKAGE}-$ENV{CABAL_VERSION}");
+              = hc_docdir($compiler, $ENV{CABAL_PACKAGE}, $ENV{CABAL_VERSION});
 
             my $tmp_inst_docdir = "$destination/$docdir";
             my $installable_docdir = "debian/$installable/$docdir";
@@ -1059,12 +797,6 @@ sub install_recipe {
         }
     }
 
-    path($ENV{DEB_LINTIAN_OVERRIDES_FILE})
-      ->append_utf8('custom-library-search-path' . $NEWLINE)
-      unless -e $ENV{DEB_LINTIAN_OVERRIDES_FILE}
-      && path($ENV{DEB_LINTIAN_OVERRIDES_FILE})->slurp_utf8
-      =~ m{^ custom-library-search-path }x;
-
     run('dh_haskell_provides');
     run('dh_haskell_depends');
     run('dh_haskell_shlibdeps');



View it on GitLab: https://salsa.debian.org/haskell-team/haskell-devscripts/-/compare/67ecc90cda560f332de10d03488d78113cf3d129...d6321a34a1a39c35670df9bfb0a0ea3084aeb094

-- 
View it on GitLab: https://salsa.debian.org/haskell-team/haskell-devscripts/-/compare/67ecc90cda560f332de10d03488d78113cf3d129...d6321a34a1a39c35670df9bfb0a0ea3084aeb094
You're receiving this email because of your account on salsa.debian.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-haskell-commits/attachments/20220414/a7edaf4a/attachment-0001.htm>


More information about the Pkg-haskell-commits mailing list