Skip to content

Conversation

sternenseemann
Copy link
Member

@sternenseemann sternenseemann commented Sep 23, 2025

While we can quote attribute names, we can't use quoting to use arbitrary strings as function arguments in Nix unfortunately. This means we couldn't previously generate expressions for packages that depend on packages that start with numbers or clash with keywords.

To fix this, we simply prefix the offending packages with an underscore. This mirrors an existing Nixpkgs convention (see e.g. pkgs._2bwm). This mapping work for all Hackage packages and is easily reversible by just removing the underscore. We can never introduce ambiguity this way since Cabal doesn't allow underscores in package names.

Cabal packages not conforming to Hackage's restrictions won't work yet. For this, we would need to implement some kind of encoding.

Resolves #163.
Resolves #164.

Nixpkgs diff

Note that I removed the addition of acme-everything which accounts for most of the diff so that it fits in the github comment. We should probably put acme-everything in exclude packages or a similar mechanism.

diff --git a/pkgs/development/haskell-modules/hackage-packages.nix b/pkgs/development/haskell-modules/hackage-packages.nix
index 48d422015484..bcef4a210b05 100644
--- a/pkgs/development/haskell-modules/hackage-packages.nix
+++ b/pkgs/development/haskell-modules/hackage-packages.nix
@@ -8,7 +8,7 @@
 
 self: {
 
-  "2captcha" = callPackage (
+  _2captcha = callPackage (
     {
       mkDerivation,
       aeson,
@@ -49,7 +49,7 @@ self: {
     }
   ) { };
 
-  "3d-graphics-examples" = callPackage (
+  _3d-graphics-examples = callPackage (
     {
       mkDerivation,
       base,
@@ -76,7 +76,7 @@ self: {
     }
   ) { };
 
-  "3dmodels" = callPackage (
+  _3dmodels = callPackage (
     {
       mkDerivation,
       attoparsec,
@@ -103,7 +103,7 @@ self: {
     }
   ) { };
 
-  "4Blocks" = callPackage (
+  _4Blocks = callPackage (
     {
       mkDerivation,
       base,
@@ -7855,6 +7855,49 @@ self: {
     }
   ) { };
 
+  ConcurrentUtils = callPackage (
+    {
+      mkDerivation,
+      _assert,
+      array,
+      atl,
+      base,
+      containers,
+      extra,
+      list-extras,
+      monad-loops,
+      monads-tf,
+      parallel,
+      profunctors,
+      strict,
+      time,
+      vector,
+    }:
+    mkDerivation {
+      pname = "ConcurrentUtils";
+      version = "0.5.0.0";
+      sha256 = "1caixp7gdhjsnlr79kmc4pd4ky663x9kid9i998qrd6anbrm2i8b";
+      libraryHaskellDepends = [
+        _assert
+        array
+        atl
+        base
+        containers
+        extra
+        list-extras
+        monad-loops
+        monads-tf
+        parallel
+        profunctors
+        strict
+        time
+        vector
+      ];
+      description = "Concurrent utilities";
+      license = lib.licenses.gpl2Only;
+    }
+  ) { };
+
   Concurrential = callPackage (
     {
       mkDerivation,
@@ -85619,9 +100755,10 @@ self: {
     }
   ) { ghc-binary = null; };
 
-  "assert" = callPackage (
+  _assert = callPackage (
     {
       mkDerivation,
+      _assert,
       base,
       bytestring,
       Cabal,
@@ -85635,6 +100772,7 @@ self: {
       sha256 = "0pycrpa9m8kif31jsbmb2cb4rbvm6qinmzhkdam1b5mbmmmg5q96";
       libraryHaskellDepends = [ base ];
       testHaskellDepends = [
+        _assert
         base
         bytestring
         Cabal
@@ -94258,10 +109396,8 @@ self: {
       ];
       description = "Specify axioms for type classes and quickCheck all available instances";
       license = lib.licenses.mit;
-      hydraPlatforms = lib.platforms.none;
-      broken = true;
     }
-  ) { control-invariants = null; };
+  ) { };
 
   azimuth-hs = callPackage (
     {
@@ -160901,6 +176037,51 @@ self: {
     }
   ) { };
 
+  control-invariants = callPackage (
+    {
+      mkDerivation,
+      _assert,
+      base,
+      containers,
+      data-default,
+      deepseq,
+      either,
+      lens,
+      mtl,
+      QuickCheck,
+      semigroups,
+      template-haskell,
+      th-lift,
+      th-printf,
+      transformers,
+    }:
+    mkDerivation {
+      pname = "control-invariants";
+      version = "0.1.0.0";
+      sha256 = "0qfw2g04k3jd9dqj1m46rf9dz767y3lkny8pj4zp3mnr704wnwwr";
+      revision = "1";
+      editedCabalFile = "0f8px9rf0d6bz0hm52iw5v89ada7jgj5lydpsr6x542hbq953wz3";
+      libraryHaskellDepends = [
+        _assert
+        base
+        containers
+        data-default
+        deepseq
+        either
+        lens
+        mtl
+        QuickCheck
+        semigroups
+        template-haskell
+        th-lift
+        th-printf
+        transformers
+      ];
+      description = "Invariants and contract monitoring";
+      license = lib.licenses.mit;
+    }
+  ) { };
+
   control-iso = callPackage (
     {
       mkDerivation,
@@ -223023,10 +238204,8 @@ self: {
       ];
       description = "Existential types with lens-like accessors";
       license = lib.licenses.mit;
-      hydraPlatforms = lib.platforms.none;
-      broken = true;
     }
-  ) { control-invariants = null; };
+  ) { };
 
   exists = callPackage (
     {
@@ -372041,7 +387220,7 @@ self: {
     }
   ) { };
 
-  "if" = callPackage (
+  _if = callPackage (
     { mkDerivation, base }:
     mkDerivation {
       pname = "if";
@@ -688658,6 +703837,27 @@ self: {
     }
   ) { };
 
+  _type = callPackage (
+    {
+      mkDerivation,
+      base,
+      containers,
+      template-haskell,
+    }:
+    mkDerivation {
+      pname = "type";
+      version = "0.2.0";
+      sha256 = "13xkbj1nimgs9cm5mdqx52m1qzjgkzcxxjibqb1g8rmjgy17yj5m";
+      libraryHaskellDepends = [
+        base
+        containers
+        template-haskell
+      ];
+      description = "Dynamic casting library with support for arbitrary rank type kinds";
+      license = lib.licenses.bsd3;
+    }
+  ) { };
+
   type-aligned = callPackage (
     { mkDerivation, base }:
     mkDerivation {
@@ -723731,6 +738931,17 @@ self: {
     }
   ) { };
 
+  _with = callPackage (
+    { mkDerivation }:
+    mkDerivation {
+      pname = "with";
+      version = "0.1.0";
+      sha256 = "0jgm6w1xisyww81ak9rrrqmhgaiwdgk5rgvzax72rknzg9rb6701";
+      description = "Simple open product type";
+      license = lib.licenses.bsd3;
+    }
+  ) { };
+
   with-index = callPackage (
     { mkDerivation, base }:
     mkDerivation {

@sternenseemann
Copy link
Member Author

Seems this currently generates broken expressions since _assert will gain a dependency on _assert for the test suite when it shouldn't. I'll have to look into that.

@sternenseemann
Copy link
Member Author

Resolved that, but there may be similar issues lurking!

@maralorn
Copy link
Member

Love it!

@wolfgangwalther
Copy link
Contributor

Seems this currently generates broken expressions since _assert will gain a dependency on _assert for the test suite when it shouldn't. I'll have to look into that.

Is the nixpkgs diff in the PR description from before or after that fix?

@sternenseemann
Copy link
Member Author

Before.

Copy link
Contributor

@wolfgangwalther wolfgangwalther left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you!

@sternenseemann
Copy link
Member Author

Do we want to do this for 25.11? I think it's basically ready and we could even add aliases for the attributes that would get changed.

@wolfgangwalther
Copy link
Contributor

Do we want to do this for 25.11?

I'd say yes, let's do it.

While we can quote attribute names, we can't use quoting to use
arbitrary strings as function arguments in Nix unfortunately. This means
we couldn't previously generate expressions for packages that depend on
packages that start with numbers or clash with keywords.

To fix this, we simply prefix the offending packages with an underscore.
This mirrors an existing Nixpkgs convention (see e.g. pkgs._2bwm). This
mapping work for all Hackage packages and is easily reversible by just
removing the underscore. We can never introduce ambiguity this way since
Cabal doesn't allow underscores in package names.

Cabal packages not conforming to Hackage's restrictions won't work yet.
For this, we would need to implement some kind of encoding.

Resolves #163.
Resolves #164.
The package expression for acme-everything is huge since it has to
list all packages released to Hackage as of 2018 twice. As this package
isn't actually useful and probably doesn't even have a valid install
plan, we can remove it to keep the size of hackage-packages.nix in
check.

In the future, such exclusions should be decided by configurable
exclusions as proposed in #667.
It may be a prudent idea to use the spam and acme categories of Hackage
as a baseline for package exclusions.

This partially reverts commit d105bfc.
nixpkgs <- readNixpkgPackageMap nixpkgsRepository (Just "{ config = { allowAliases = false; }; }")
preferredVersions <- readPreferredVersions (fromMaybe (hackageRepository </> "preferred-versions") preferredVersionsFile)
let fixup = over (at "hermes") (fmap (set (contains "1.3.4.3") False)) -- TODO: https://github.com/haskell/hackage-server/issues/436
let fixup = Map.delete "acme-everything" -- TODO(@wolfgangwalther): remove after https://github.com/NixOS/cabal2nix/pull/667
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🫡

@sternenseemann
Copy link
Member Author

NixOS/nixpkgs#453366

sternenseemann added a commit that referenced this pull request Oct 21, 2025
- In general, one should Identifier and its instances to render and
  parse Identifiers. quote has been relegated to an Internals section
  since it is only required by the test suite at the moment. It may be
  nice to remove it at some point.
- needsQuoting deals with arbitrary strings and would normally be used
  to judge whether a given String should be converted to an Identifier
  directly or first be subject to some kind of substitution so that it
  does not need to be quoted (see #672). nixKeywords is an internal
  definition involved with this which is also used in the test suites.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

How to deal with packages who's name is not a valid Nix identifier? The attribute "type" has special meaning in Nix

3 participants