[Git][haskell-team/haskell-devscripts][master] Better handle packages with internal libraries

Scott Talbert (@swt2c) gitlab at salsa.debian.org
Sat Jan 31 02:00:59 GMT 2026



Scott Talbert pushed to branch master at Debian Haskell Group / haskell-devscripts


Commits:
773dcc9c by Scott Talbert at 2026-01-30T20:57:38-05:00
Better handle packages with internal libraries

- - - - -


6 changed files:

- debian/changelog
- dh_haskell_depends_cabal
- dh_haskell_extra_depends_ghc
- dh_haskell_install_ghc_registration
- dh_haskell_provides_ghc
- lib/Debian/Debhelper/Buildsystem/Haskell/Recipes.pm


Changes:

=====================================
debian/changelog
=====================================
@@ -1,3 +1,14 @@
+haskell-devscripts (0.16.46) unstable; urgency=medium
+
+  [ Clint Adams ]
+  * Revert "Attempt to handle more complexity in ghc-pkg configs."
+
+  [ Scott Talbert ]
+  * Better handle packages with internal libraries (Closes: #1016650,
+    #1126033)
+
+ -- Scott Talbert <swt at techie.net>  Fri, 30 Jan 2026 20:49:19 -0500
+
 haskell-devscripts (0.16.45) unstable; urgency=medium
 
   * Attempt to handle more complexity in ghc-pkg configs.


=====================================
dh_haskell_depends_cabal
=====================================
@@ -29,6 +29,7 @@ use Unicode::UTF8 qw(encode_utf8);
 
 use Debian::Debhelper::Buildsystem::Haskell::Recipes qw(
   run
+  run_quiet
   init_hs_env
   installable_type
   installable_hc
@@ -38,6 +39,7 @@ use Debian::Debhelper::Buildsystem::Haskell::Recipes qw(
   load_ghc_database
   hashed_id_to_virtual_installable
   config_to_package_id
+  is_package_exposed
 );
 use Debian::Debhelper::Dh_Lib;
 
@@ -170,12 +172,26 @@ sub cabal_depends {
     # the versions should probably be dropped by the caller
     s{ - [0-9] [.0-9a-zA-Z]* $}{}x for @exclude_patterns;
 
+    my $locals
+        = run_quiet($ghc_pkg, '--package-db', $tmp_db, '--simple-output',
+                    '--show-unit-ids', 'list');
+    my @local_pkgs = uniq(split($SPACE, $locals // $EMPTY));
+
     my @retained;
     for my $prerequisite (@have) {
 
         next
           if any { $prerequisite =~ m{\Q$_\E} } @exclude_patterns;
 
+        # Exclude packages that are local and are not exposed (hidden).
+        # These are usually internal libraries so we don't want external deps
+        # for them.
+        if (grep(/^$prerequisite$/, @local_pkgs)) {
+            my $exposed = is_package_exposed($prerequisite, $ghc_pkg, $tmp_db);
+            next
+                if !$exposed;
+        }
+
         push(@retained, $prerequisite);
     }
 


=====================================
dh_haskell_extra_depends_ghc
=====================================
@@ -32,8 +32,6 @@ use Debian::Debhelper::Buildsystem::Haskell::Recipes qw(
   init_hs_env
   installable_hc
   installable_type
-  ghc_pkg_command
-  load_ghc_database
   own_cabal_prerequisites
 );
 use Debian::Debhelper::Dh_Lib;


=====================================
dh_haskell_install_ghc_registration
=====================================
@@ -25,6 +25,7 @@ use File::Temp;
 use Unicode::UTF8 qw(encode_utf8);
 
 use Debian::Debhelper::Buildsystem::Haskell::Recipes qw(
+  config_to_package_name_version
   run
   init_hs_env
   installable_hc
@@ -65,17 +66,28 @@ for my $installable (@{ $dh{DOPACKAGES} }) {
         my $pkg_config = $2;
 
         if (-d $path) {
-            # https://downloads.haskell.org/cabal/Cabal-3.0.0.0/doc/users-guide/installing-packages.html#cmdoption-setup-register-gen-pkg-config
-            # If the package registration is a directory, choose the first one since the other(s) will be internal libraries that we don't want to install.
+            # If the package registration is a directory, install all of the
+            # files after renaming them to the name-version.conf format.
             my @pkg_configs = glob("$path/*");
-            $path = $pkg_configs[0];
-        }
+            for my $pkg_config_src (@pkg_configs) {
+                my ($pkg_name, $pkg_ver) = config_to_package_name_version($pkg_config_src);
+                my $pkg_config_dst = "$pkg_name-$pkg_ver.conf";
+
+                run(qw{sed -i}, 's/^exposed: True$/exposed: False/', "$pkg_config_src")
+                    if length $ENV{HASKELL_HIDE_PACKAGES};
 
-        run(qw{sed -i}, 's/^exposed: True$/exposed: False/', $path)
-            if length $ENV{HASKELL_HIDE_PACKAGES};
+                run(qw{install -D --mode=644},
+                    $pkg_config_src,
+                    "debian/$installable/$pkgdir/$pkg_config_dst");
+            }
+        } else {
 
-        run(qw{install -D --mode=644},
-            $path, "debian/$installable/$pkgdir/$pkg_config");
+            run(qw{sed -i}, 's/^exposed: True$/exposed: False/', $path)
+                if length $ENV{HASKELL_HIDE_PACKAGES};
+
+            run(qw{install -D --mode=644},
+                $path, "debian/$installable/$pkgdir/$pkg_config");
+        }
 
         run(qw{rm -rf}, $pkg_config);
 


=====================================
dh_haskell_provides_ghc
=====================================
@@ -39,6 +39,7 @@ use Debian::Debhelper::Buildsystem::Haskell::Recipes qw(
   load_ghc_database
   hashed_id_to_virtual_installable
   config_to_package_id
+  is_package_exposed
 );
 use Debian::Debhelper::Dh_Lib;
 
@@ -82,6 +83,12 @@ for my $installable (@{ $dh{DOPACKAGES} }) {
     my @hashed_ids;
     for my $config (@configs) {
         my $package_id = config_to_package_id($config, $ghc_pkg, $ENV{DEB_GHC_DATABASE});
+
+        # Exclude packages that are not exposed.
+        my $exposed = is_package_exposed($package_id, $ghc_pkg, $ENV{DEB_GHC_DATABASE});
+        next
+            if !$exposed;
+
         push(@hashed_ids, $package_id);
     }
 


=====================================
lib/Debian/Debhelper/Buildsystem/Haskell/Recipes.pm
=====================================
@@ -45,6 +45,8 @@ BEGIN {
       own_cabal_prerequisites
       hashed_id_to_virtual_installable
       config_to_package_id
+      config_to_package_name_version
+      is_package_exposed
       init_hs_env
       clean_recipe
       make_setup_recipe
@@ -412,11 +414,31 @@ sub own_cabal_prerequisites {
         my $pkg_config = $2;
 
         if (-d $pkg_config) {
-            # https://downloads.haskell.org/cabal/Cabal-3.0.0.0/doc/users-guide/installing-packages.html#cmdoption-setup-register-gen-pkg-config
-            # If the package registration is a directory, choose the first one since the other(s) will be internal libraries that we don't want to install.
+            # If the package registration is a directory, load all .conf files
             my @pkg_configs = glob("$pkg_config/*");
-            $pkg_config = "$pkg_config/$pkg_config";
-            run('mv', $pkg_configs[0], $pkg_config);
+            my $ghc_pkg = ghc_pkg_command();
+            load_ghc_database($ghc_pkg, $tmp_db, @pkg_configs);
+
+            # Gather all the depends from all the libraries
+            my $locals
+                = run_quiet($ghc_pkg, '--package-db', $tmp_db,
+                            '--simple-output', '--show-unit-ids', 'list');
+            my @local_pkgs = uniq(split($SPACE, $locals // $EMPTY));
+            for my $pkg (@local_pkgs) {
+                my $depends = run($ghc_pkg, '--package-db', $tmp_db, 'field',
+                                  '--unit-id', '--simple-output', $pkg,
+                                  'depends');
+                push(@hashed_ids, split($SPACE, $depends // $EMPTY));
+            }
+
+            # Filter out those depends that are internal
+            @hashed_ids = uniq(@hashed_ids);
+            my %local_hash = map { $_ => 1 } @local_pkgs;
+            @hashed_ids = grep { !$local_hash{$_} } @hashed_ids;
+
+            run(qw{rm -rf}, $pkg_config);
+
+            return @hashed_ids;
         }
 
         my $ghc_pkg = ghc_pkg_command();
@@ -523,6 +545,44 @@ sub config_to_package_id {
     return $package_id;
 }
 
+=item config_to_package_name_version
+
+=cut
+
+sub config_to_package_name_version {
+    my ($config) = @_;
+
+    my $cabal_contents = path($config)->slurp_utf8;
+
+    die encode_utf8('Cannot get package name from config file')
+        unless $cabal_contents =~ /^ name \s* : \s* (\S*) \s* $/imx;
+
+    my $package_name = $1;
+
+    die encode_utf8('Cannot get package version from config file')
+        unless $cabal_contents =~ /^ version \s* : \s* (\S*) \s* $/imx;
+
+    my $package_version = $1;
+
+    return ($package_name, $package_version);
+}
+
+=item is_pkg_internal
+
+=cut
+
+sub is_package_exposed {
+    my ($package_id, $ghc_pkg, $package_db) = @_;
+
+    my $exposed
+        = run_quiet($ghc_pkg, '--package-db', $package_db, 'field',
+                    '--unit-id', '--simple-output', $package_id, 'exposed');
+    return 1
+        if $exposed eq 'True';
+
+    return 0;
+}
+
 =item init_hs_env
 
 =cut



View it on GitLab: https://salsa.debian.org/haskell-team/haskell-devscripts/-/commit/773dcc9c2ce1070ec5b8d39b7e800d225a3c543d

-- 
View it on GitLab: https://salsa.debian.org/haskell-team/haskell-devscripts/-/commit/773dcc9c2ce1070ec5b8d39b7e800d225a3c543d
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/20260131/8dac97cd/attachment-0001.htm>


More information about the Pkg-haskell-commits mailing list