From 2ceff8f2c2ce21b5f7a43f5e9070496f7c4f6e19 Mon Sep 17 00:00:00 2001 From: Alexandre Esteves Date: Thu, 19 Mar 2026 00:06:08 +0000 Subject: [PATCH 1/8] Cleanup --- .../Distribution/Nixpkgs/Haskell/BuildInfo.hs | 2 +- .../Nixpkgs/Haskell/Derivation.hs | 13 +++++----- .../Distribution/Nixpkgs/Haskell/FromCabal.hs | 11 +++++--- .../Nixpkgs/Haskell/FromCabal/Normalize.hs | 11 ++++---- .../Nixpkgs/Haskell/FromCabal/PostProcess.hs | 26 ++++++++++--------- 5 files changed, 35 insertions(+), 28 deletions(-) diff --git a/cabal2nix/src/Distribution/Nixpkgs/Haskell/BuildInfo.hs b/cabal2nix/src/Distribution/Nixpkgs/Haskell/BuildInfo.hs index ed367d0ae..25dccac19 100644 --- a/cabal2nix/src/Distribution/Nixpkgs/Haskell/BuildInfo.hs +++ b/cabal2nix/src/Distribution/Nixpkgs/Haskell/BuildInfo.hs @@ -42,7 +42,7 @@ instance Monoid BuildInfo where instance NFData BuildInfo pPrintBuildInfo :: String -> BuildInfo -> Doc -pPrintBuildInfo prefix bi = vcat +pPrintBuildInfo prefix bi = onlyIf (bi /= mempty) $ vcat [ setattr (prefix++"HaskellDepends") empty (setOf (haskell.folded.localName.ident) bi) , setattr (prefix++"SystemDepends") empty (setOf (system.folded.localName.ident) bi) , setattr (prefix++"PkgconfigDepends") empty (setOf (pkgconfig.folded.localName.ident) bi) diff --git a/cabal2nix/src/Distribution/Nixpkgs/Haskell/Derivation.hs b/cabal2nix/src/Distribution/Nixpkgs/Haskell/Derivation.hs index c8c85ef81..4d807900e 100644 --- a/cabal2nix/src/Distribution/Nixpkgs/Haskell/Derivation.hs +++ b/cabal2nix/src/Distribution/Nixpkgs/Haskell/Derivation.hs @@ -1,6 +1,7 @@ {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE TemplateHaskell #-} +{-# LANGUAGE TupleSections #-} {-# LANGUAGE FlexibleInstances, MultiParamTypeClasses #-} module Distribution.Nixpkgs.Haskell.Derivation @@ -102,7 +103,7 @@ nullDerivation = MkDerivation makeLenses ''Derivation -makeLensesFor [("_setupDepends", "dependencies"), ("_libraryDepends", "dependencies"), ("_executableDepends", "dependencies"), ("_testDepends", "dependencies"), ("_benchmarkDepends", "dependencies")] ''Derivation +makeLensesFor (fmap (,"dependencies") ["_setupDepends", "_libraryDepends", "_executableDepends", "_testDepends", "_benchmarkDepends"]) ''Derivation instance Package Derivation where packageId = view pkgid @@ -123,11 +124,11 @@ instance Pretty Derivation where , boolattr "isLibrary" (not _isLibrary || _isExecutable) _isLibrary , boolattr "isExecutable" (not _isLibrary || _isExecutable) _isExecutable , boolattr "enableSeparateDataOutput" _enableSeparateDataOutput _enableSeparateDataOutput - , onlyIf (_setupDepends /= mempty) $ pPrintBuildInfo "setup" _setupDepends - , onlyIf (_libraryDepends /= mempty) $ pPrintBuildInfo "library" _libraryDepends - , onlyIf (_executableDepends /= mempty) $ pPrintBuildInfo "executable" _executableDepends - , onlyIf (_testDepends /= mempty) $ pPrintBuildInfo "test" _testDepends - , onlyIf (_benchmarkDepends /= mempty) $ pPrintBuildInfo "benchmark" _benchmarkDepends + , pPrintBuildInfo "setup" _setupDepends + , pPrintBuildInfo "library" _libraryDepends + , pPrintBuildInfo "executable" _executableDepends + , pPrintBuildInfo "test" _testDepends + , pPrintBuildInfo "benchmark" _benchmarkDepends , boolattr "enableLibraryProfiling" _enableLibraryProfiling _enableLibraryProfiling , boolattr "enableExecutableProfiling" _enableExecutableProfiling _enableExecutableProfiling , boolattr "doHaddock" (not _runHaddock) _runHaddock diff --git a/cabal2nix/src/Distribution/Nixpkgs/Haskell/FromCabal.hs b/cabal2nix/src/Distribution/Nixpkgs/Haskell/FromCabal.hs index 91c9a254b..35ffcb12e 100644 --- a/cabal2nix/src/Distribution/Nixpkgs/Haskell/FromCabal.hs +++ b/cabal2nix/src/Distribution/Nixpkgs/Haskell/FromCabal.hs @@ -124,10 +124,10 @@ fromPackageDescription haskellResolver nixpkgsResolver missingDeps flags Package & isExecutable .~ not (null executables) & extraFunctionArgs .~ mempty & extraAttributes .~ mempty - & libraryDepends .~ foldMap (convertBuildInfo . libBuildInfo) (maybeToList library ++ subLibraries) - & executableDepends .~ mconcat (map (convertBuildInfo . buildInfo) executables) - & testDepends .~ mconcat (map (convertBuildInfo . testBuildInfo) testSuites) - & benchmarkDepends .~ mconcat (map (convertBuildInfo . benchmarkBuildInfo) benchmarks) + & libraryDepends .~ deps libBuildInfo (maybeToList library ++ subLibraries) + & executableDepends .~ deps buildInfo executables + & testDepends .~ deps testBuildInfo testSuites + & benchmarkDepends .~ deps benchmarkBuildInfo benchmarks & Nix.setupDepends .~ maybe mempty convertSetupBuildInfo setupBuildInfo & configureFlags .~ mempty & cabalFlags .~ flags @@ -163,6 +163,9 @@ fromPackageDescription haskellResolver nixpkgsResolver missingDeps flags Package & Nix.broken .~ not (null missingDeps) ) where + deps :: (a -> Cabal.BuildInfo) -> [a] -> Nix.BuildInfo + deps getBuildInfo = foldMap (convertBuildInfo . getBuildInfo) + xrev = maybe 0 read (lookup "x-revision" customFieldsPD) nixLicense :: Nix.License diff --git a/cabal2nix/src/Distribution/Nixpkgs/Haskell/FromCabal/Normalize.hs b/cabal2nix/src/Distribution/Nixpkgs/Haskell/FromCabal/Normalize.hs index a59aafcd4..4720ca5f2 100644 --- a/cabal2nix/src/Distribution/Nixpkgs/Haskell/FromCabal/Normalize.hs +++ b/cabal2nix/src/Distribution/Nixpkgs/Haskell/FromCabal/Normalize.hs @@ -4,7 +4,6 @@ module Distribution.Nixpkgs.Haskell.FromCabal.Normalize ( normalize ) where import Control.Lens import qualified Data.Set as Set -import Data.String import Distribution.Nixpkgs.Haskell import Distribution.Nixpkgs.Haskell.FromCabal.Name (toNixName) import Distribution.Nixpkgs.Meta @@ -13,12 +12,14 @@ import Language.Nix hiding ( quote ) normalize :: Derivation -> Derivation normalize drv = drv - & over libraryDepends (normalizeBuildInfo (packageName drv)) - & over executableDepends (normalizeBuildInfo (packageName drv)) - & over testDepends (normalizeBuildInfo (packageName drv)) - & over benchmarkDepends (normalizeBuildInfo (packageName drv)) + & deps libraryDepends + & deps executableDepends + & deps testDepends + & deps benchmarkDepends & over metaSection normalizeMeta & jailbreak %~ (&& (packageName drv /= "jailbreak-cabal")) + where + deps f = over f $ normalizeBuildInfo (packageName drv) normalizeBuildInfo :: PackageName -> BuildInfo -> BuildInfo normalizeBuildInfo pname bi = bi diff --git a/cabal2nix/src/Distribution/Nixpkgs/Haskell/FromCabal/PostProcess.hs b/cabal2nix/src/Distribution/Nixpkgs/Haskell/FromCabal/PostProcess.hs index 83392fc2d..f7b88816d 100644 --- a/cabal2nix/src/Distribution/Nixpkgs/Haskell/FromCabal/PostProcess.hs +++ b/cabal2nix/src/Distribution/Nixpkgs/Haskell/FromCabal/PostProcess.hs @@ -4,7 +4,6 @@ module Distribution.Nixpkgs.Haskell.FromCabal.PostProcess ( postProcess, pkg ) where import Control.Lens -import Control.Monad.Trans.State import Data.List.Split import Data.Map ( Map ) import qualified Data.Map as Map @@ -58,17 +57,20 @@ fixGtkBuilds drv = drv & dependencies . pkgconfig %~ Set.filter (not . collidesW -- also work for Stack). Until that changes, we provide do this to work around -- those package's brokenness. fixBuildDependsForTools :: Derivation -> Derivation -fixBuildDependsForTools = foldr (.) id - [ fmap snd $ runState $ do - needs <- use $ cloneLens c . haskell . contains p - cloneLens c . tool . contains p ||= needs - | (c :: ALens' Derivation BuildInfo) <- [ testDepends, benchmarkDepends ] - , p <- self <$> [ "hspec-discover" - , "tasty-discover" - , "hsx2hs" - , "markdown-unlit" - ] - ] +fixBuildDependsForTools = foldr (.) id $ fmap go [ testDepends, benchmarkDepends ] + where + go c drv = + over (l . tool) (Set.union needed) drv + where + l :: Lens' Derivation BuildInfo + l = cloneLens c + needed = Set.intersection executables $ view (l . haskell) drv + executables = Set.fromList $ self <$> + [ "hspec-discover" + , "tasty-discover" + , "hsx2hs" + , "markdown-unlit" + ] hooks :: [(PackageVersionConstraint, Derivation -> Derivation)] hooks = From 856a7c651fdb8b03cf9b97592cda8075d98f6364 Mon Sep 17 00:00:00 2001 From: Alexandre Esteves Date: Thu, 19 Mar 2026 00:05:18 +0000 Subject: [PATCH 2/8] Preserve per-component build info until pretty-printing --- cabal2nix/src/Cabal2nix.hs | 2 +- .../Nixpkgs/Haskell/Derivation.hs | 34 ++++-- .../Distribution/Nixpkgs/Haskell/FromCabal.hs | 10 +- .../Nixpkgs/Haskell/FromCabal/Normalize.hs | 5 +- .../Nixpkgs/Haskell/FromCabal/PostProcess.hs | 105 +++++++++--------- 5 files changed, 88 insertions(+), 68 deletions(-) diff --git a/cabal2nix/src/Cabal2nix.hs b/cabal2nix/src/Cabal2nix.hs index ab8537130..1022e4f4f 100644 --- a/cabal2nix/src/Cabal2nix.hs +++ b/cabal2nix/src/Cabal2nix.hs @@ -175,7 +175,7 @@ main = bracket (return ()) (\() -> hFlush stdout >> hFlush stderr) $ \() -> hpackOverrides :: Derivation -> Derivation hpackOverrides = over phaseOverrides (++ "prePatch = \"hpack\";") - . set (libraryDepends . tool . contains (PP.pkg "hpack")) True + . set (focusBuildInfo libraryDepends . tool . contains (PP.pkg "hpack")) True cabal2nix' :: Options -> IO (Either Doc Derivation) cabal2nix' opts@Options{..} = do diff --git a/cabal2nix/src/Distribution/Nixpkgs/Haskell/Derivation.hs b/cabal2nix/src/Distribution/Nixpkgs/Haskell/Derivation.hs index 4d807900e..579da036f 100644 --- a/cabal2nix/src/Distribution/Nixpkgs/Haskell/Derivation.hs +++ b/cabal2nix/src/Distribution/Nixpkgs/Haskell/Derivation.hs @@ -1,4 +1,6 @@ +{-# LANGUAGE CPP #-} {-# LANGUAGE DeriveGeneric #-} +{-# LANGUAGE RankNTypes #-} {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE TupleSections #-} @@ -10,11 +12,15 @@ module Distribution.Nixpkgs.Haskell.Derivation , cabalFlags, runHaddock, jailbreak, doCheck, doBenchmark, testFlags, testTargets, hyperlinkSource , enableLibraryProfiling, enableExecutableProfiling, phaseOverrides, editedCabalFile, metaSection , dependencies, setupDepends, benchmarkDepends, enableSeparateDataOutput, extraAttributes + , focusBuildInfo ) where import Prelude hiding ((<>)) +#if !MIN_VERSION_base(4,18,0) +import Control.Applicative (liftA2) +#endif import Control.DeepSeq import Control.Lens import Data.List ( isPrefixOf ) @@ -47,10 +53,10 @@ data Derivation = MkDerivation , _extraFunctionArgs :: Set Binding , _extraAttributes :: Map String String , _setupDepends :: BuildInfo - , _libraryDepends :: BuildInfo - , _executableDepends :: BuildInfo - , _testDepends :: BuildInfo - , _benchmarkDepends :: BuildInfo + , _libraryDepends :: [(BuildInfo, Bool)] + , _executableDepends :: [(BuildInfo, Bool)] + , _testDepends :: [(BuildInfo, Bool)] + , _benchmarkDepends :: [(BuildInfo, Bool)] , _configureFlags :: Set String , _cabalFlags :: FlagAssignment , _runHaddock :: Bool @@ -103,7 +109,14 @@ nullDerivation = MkDerivation makeLenses ''Derivation -makeLensesFor (fmap (,"dependencies") ["_setupDepends", "_libraryDepends", "_executableDepends", "_testDepends", "_benchmarkDepends"]) ''Derivation +makeLensesFor (fmap (,"nonSetupDependencies") ["_libraryDepends", "_executableDepends", "_testDepends", "_benchmarkDepends"]) ''Derivation + +dependencies :: Traversal' Derivation BuildInfo +dependencies = traversal $ \focus drv -> + liftA2 (set setupDepends) (focus $ view setupDepends drv) ((nonSetupDependencies . traverse . _1) focus drv) + +focusBuildInfo :: Lens' Derivation [(BuildInfo, Bool)] -> Traversal' Derivation BuildInfo +focusBuildInfo l = l . traverse . _1 instance Package Derivation where packageId = view pkgid @@ -125,10 +138,10 @@ instance Pretty Derivation where , boolattr "isExecutable" (not _isLibrary || _isExecutable) _isExecutable , boolattr "enableSeparateDataOutput" _enableSeparateDataOutput _enableSeparateDataOutput , pPrintBuildInfo "setup" _setupDepends - , pPrintBuildInfo "library" _libraryDepends - , pPrintBuildInfo "executable" _executableDepends - , pPrintBuildInfo "test" _testDepends - , pPrintBuildInfo "benchmark" _benchmarkDepends + , pPrintBuildInfo' "library" _libraryDepends + , pPrintBuildInfo' "executable" _executableDepends + , pPrintBuildInfo' "test" _testDepends + , pPrintBuildInfo' "benchmark" _benchmarkDepends , boolattr "enableLibraryProfiling" _enableLibraryProfiling _enableLibraryProfiling , boolattr "enableExecutableProfiling" _enableExecutableProfiling _enableExecutableProfiling , boolattr "doHaddock" (not _runHaddock) _runHaddock @@ -145,6 +158,9 @@ instance Pretty Derivation where , rbrace ] where + pPrintBuildInfo' :: String -> [(BuildInfo, Bool)] -> Doc + pPrintBuildInfo' name = pPrintBuildInfo name . foldMap fst . filter snd + inputs :: Set String inputs = Set.unions [ Set.map (view (localName . ident)) _extraFunctionArgs , setOf (dependencies . each . folded . localName . ident) drv diff --git a/cabal2nix/src/Distribution/Nixpkgs/Haskell/FromCabal.hs b/cabal2nix/src/Distribution/Nixpkgs/Haskell/FromCabal.hs index 35ffcb12e..115de99cc 100644 --- a/cabal2nix/src/Distribution/Nixpkgs/Haskell/FromCabal.hs +++ b/cabal2nix/src/Distribution/Nixpkgs/Haskell/FromCabal.hs @@ -1,6 +1,7 @@ {-# LANGUAGE CPP #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE RecordWildCards #-} +{-# LANGUAGE TupleSections #-} module Distribution.Nixpkgs.Haskell.FromCabal ( HaskellResolver, NixpkgsResolver @@ -163,8 +164,8 @@ fromPackageDescription haskellResolver nixpkgsResolver missingDeps flags Package & Nix.broken .~ not (null missingDeps) ) where - deps :: (a -> Cabal.BuildInfo) -> [a] -> Nix.BuildInfo - deps getBuildInfo = foldMap (convertBuildInfo . getBuildInfo) + deps :: (a -> Cabal.BuildInfo) -> [a] -> [(Nix.BuildInfo, Bool)] + deps getBuildInfo = map (convertBuildInfo . getBuildInfo) xrev = maybe 0 read (lookup "x-revision" customFieldsPD) @@ -211,9 +212,8 @@ fromPackageDescription haskellResolver nixpkgsResolver missingDeps flags Package | Just l <- library = not (null (exposedModules l)) | otherwise = True - convertBuildInfo :: Cabal.BuildInfo -> Nix.BuildInfo - convertBuildInfo Cabal.BuildInfo {..} | not buildable = mempty - convertBuildInfo Cabal.BuildInfo {..} = mempty + convertBuildInfo :: Cabal.BuildInfo -> (Nix.BuildInfo, Bool) + convertBuildInfo Cabal.BuildInfo {..} = (, buildable) $ mempty & haskell .~ Set.fromList [ resolveInHackage (toNixName x) | (Dependency x _ _) <- targetBuildDepends, x `notElem` internalLibNames ] & system .~ Set.fromList [ resolveInNixpkgs y | x <- extraLibs, y <- libNixName x ] & pkgconfig .~ Set.fromList [ resolveInNixpkgs y | PkgconfigDependency x _ <- pkgconfigDepends, y <- libNixName (unPkgconfigName x) ] diff --git a/cabal2nix/src/Distribution/Nixpkgs/Haskell/FromCabal/Normalize.hs b/cabal2nix/src/Distribution/Nixpkgs/Haskell/FromCabal/Normalize.hs index 4720ca5f2..a0fbc7e5a 100644 --- a/cabal2nix/src/Distribution/Nixpkgs/Haskell/FromCabal/Normalize.hs +++ b/cabal2nix/src/Distribution/Nixpkgs/Haskell/FromCabal/Normalize.hs @@ -1,4 +1,6 @@ +{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE OverloadedStrings #-} +{-# LANGUAGE RankNTypes #-} module Distribution.Nixpkgs.Haskell.FromCabal.Normalize ( normalize ) where @@ -19,7 +21,8 @@ normalize drv = drv & over metaSection normalizeMeta & jailbreak %~ (&& (packageName drv /= "jailbreak-cabal")) where - deps f = over f $ normalizeBuildInfo (packageName drv) + deps :: Lens' Derivation [(BuildInfo, Bool)] -> Derivation -> Derivation + deps f = over (focusBuildInfo f) $ normalizeBuildInfo (packageName drv) normalizeBuildInfo :: PackageName -> BuildInfo -> BuildInfo normalizeBuildInfo pname bi = bi diff --git a/cabal2nix/src/Distribution/Nixpkgs/Haskell/FromCabal/PostProcess.hs b/cabal2nix/src/Distribution/Nixpkgs/Haskell/FromCabal/PostProcess.hs index f7b88816d..8fcd1ef26 100644 --- a/cabal2nix/src/Distribution/Nixpkgs/Haskell/FromCabal/PostProcess.hs +++ b/cabal2nix/src/Distribution/Nixpkgs/Haskell/FromCabal/PostProcess.hs @@ -59,11 +59,12 @@ fixGtkBuilds drv = drv & dependencies . pkgconfig %~ Set.filter (not . collidesW fixBuildDependsForTools :: Derivation -> Derivation fixBuildDependsForTools = foldr (.) id $ fmap go [ testDepends, benchmarkDepends ] where + go :: ALens' Derivation [(BuildInfo, Bool)] -> Derivation -> Derivation go c drv = over (l . tool) (Set.union needed) drv where - l :: Lens' Derivation BuildInfo - l = cloneLens c + l :: Traversal' Derivation BuildInfo + l = focusBuildInfo (cloneLens c) needed = Set.intersection executables $ view (l . haskell) drv executables = Set.fromList $ self <$> [ "hspec-discover" @@ -74,13 +75,13 @@ fixBuildDependsForTools = foldr (.) id $ fmap go [ testDepends, benchmarkDepends hooks :: [(PackageVersionConstraint, Derivation -> Derivation)] hooks = - [ ("Agda < 2.5", set (executableDepends . tool . contains (pkg "emacs")) True . set phaseOverrides agdaPostInstall) - , ("Agda >= 2.5 && < 2.6", set (executableDepends . tool . contains (pkg "emacs")) True . set phaseOverrides agda25PostInstall) - , ("Agda >= 2.6", set (executableDepends . tool . contains (pkg "emacs")) True) - , ("alex < 3.1.5", set (testDepends . tool . contains (pkg "perl")) True) - , ("alex", set (executableDepends . tool . contains (self "happy")) True) + [ ("Agda < 2.5", set (focusBuildInfo executableDepends . tool . contains (pkg "emacs")) True . set phaseOverrides agdaPostInstall) + , ("Agda >= 2.5 && < 2.6", set (focusBuildInfo executableDepends . tool . contains (pkg "emacs")) True . set phaseOverrides agda25PostInstall) + , ("Agda >= 2.6", set (focusBuildInfo executableDepends . tool . contains (pkg "emacs")) True) + , ("alex < 3.1.5", set (focusBuildInfo testDepends . tool . contains (pkg "perl")) True) + , ("alex", set (focusBuildInfo executableDepends . tool . contains (self "happy")) True) , ("alsa-core", set (metaSection . platforms) (Just $ Set.singleton (NixpkgsPlatformGroup (ident # "linux")))) - , ("bindings-GLFW", over (libraryDepends . system) (Set.union (Set.fromList [bind "pkgs.libxext", bind "pkgs.libxfixes"]))) + , ("bindings-GLFW", over (focusBuildInfo libraryDepends . system) (Set.union (Set.fromList [bind "pkgs.libxext", bind "pkgs.libxfixes"]))) , ("bindings-lxc", set (metaSection . platforms) (Just $ Set.singleton (NixpkgsPlatformGroup (ident # "linux")))) , ("bustle", bustleOverrides) , ("Cabal", set doCheck False) -- test suite doesn't work in Nix @@ -94,7 +95,7 @@ hooks = , ("dns", set testTargets ["spec"]) -- don't execute tests that try to access the network , ("eventstore", set (metaSection . platforms) (Just $ Set.singleton (NixpkgsPlatformGroup (ident # "x86_64")))) , ("freenect < 1.2.1", over configureFlags (Set.union (Set.fromList ["--extra-include-dirs=${lib.getDev pkgs.freenect}/include/libfreenect", "--extra-lib-dirs=${lib.getLib pkgs.freenect}/lib"]))) - , ("fltkhs", set (libraryDepends . system . contains (pkg "fltk_1_4")) True . over (libraryDepends . pkgconfig) (Set.union (pkgs ["libGLU", "libGL"]))) -- TODO: fltk14 belongs into the *setup* dependencies. + , ("fltkhs", set (focusBuildInfo libraryDepends . system . contains (pkg "fltk_1_4")) True . over (focusBuildInfo libraryDepends . pkgconfig) (Set.union (pkgs ["libGLU", "libGL"]))) -- TODO: fltk14 belongs into the *setup* dependencies. , ("gf", set phaseOverrides gfPhaseOverrides . set doCheck False) , ("gi-cairo", giCairoPhaseOverrides) -- https://github.com/haskell-gi/haskell-gi/issues/36 , ("gi-gdk", set runHaddock True ) @@ -109,75 +110,75 @@ hooks = , ("gi-pango", set runHaddock True ) , ("gi-pangocairo", giCairoPhaseOverrides) -- https://github.com/haskell-gi/haskell-gi/issues/36 , ("gi-vte", set runHaddock True ) - , ("gio", set (libraryDepends . pkgconfig . contains "system-glib = pkgs.glib") True) + , ("gio", set (focusBuildInfo libraryDepends . pkgconfig . contains "system-glib = pkgs.glib") True) , ("git", set doCheck False) -- https://github.com/vincenthz/hit/issues/33 , ("git-annex >= 6.20170925 && < 6.20171214", set doCheck False) -- some versions of git-annex require their test suite to be run inside of a git checkout - , ("github-backup", set (executableDepends . tool . contains (pkg "git")) True) - , ("GLFW", over (libraryDepends . system) (Set.union (Set.fromList [bind "pkgs.libxext", bind "pkgs.libxfixes"]))) - , ("graphviz", set (testDepends . system . contains (pkg "graphviz")) True) + , ("github-backup", set (focusBuildInfo executableDepends . tool . contains (pkg "git")) True) + , ("GLFW", over (focusBuildInfo libraryDepends . system) (Set.union (Set.fromList [bind "pkgs.libxext", bind "pkgs.libxfixes"]))) + , ("graphviz", set (focusBuildInfo testDepends . system . contains (pkg "graphviz")) True) , ("gtk3", gtk3Hook) , ("gtkglext", gtkglextHook) - , ("hakyll", set (testDepends . tool . contains (pkg "util-linux")) True) -- test suite depends on "rev" + , ("hakyll", set (focusBuildInfo testDepends . tool . contains (pkg "util-linux")) True) -- test suite depends on "rev" , ("haskell-src-exts", set doCheck False) , ("hfsevents", hfseventsOverrides) , ("HFuse", set phaseOverrides hfusePreConfigure) - , ("hlibgit2 >= 0.18.0.14", set (testDepends . tool . contains (pkg "git")) True) + , ("hlibgit2 >= 0.18.0.14", set (focusBuildInfo testDepends . tool . contains (pkg "git")) True) , ("hmatrix < 0.18.1.1", set phaseOverrides "preConfigure = \"sed -i hmatrix.cabal -e '/\\\\/usr\\\\//D'\";") , ("holy-project", set doCheck False) -- attempts to access the network , ("hoogle", set testFlags ["--no-net"]) , ("hsignal < 0.2.7.4", set phaseOverrides "prePatch = \"rm -v Setup.lhs\";") -- https://github.com/amcphail/hsignal/issues/1 - , ("hslua < 0.9.3", over (libraryDepends . system) (replace (pkg "lua") (pkg "lua5_1"))) - , ("hslua >= 0.9.3 && < 2.0.0", over (libraryDepends . system) (replace (pkg "lua") (pkg "lua5_3"))) + , ("hslua < 0.9.3", over (focusBuildInfo libraryDepends . system) (replace (pkg "lua") (pkg "lua5_1"))) + , ("hslua >= 0.9.3 && < 2.0.0", over (focusBuildInfo libraryDepends . system) (replace (pkg "lua") (pkg "lua5_3"))) , ("hspec-core >= 2.4.4", hspecCoreOverrides) , ("http-client", set doCheck False) -- attempts to access the network , ("http-client-openssl >= 0.2.0.1", set doCheck False) -- attempts to access the network , ("http-client-tls >= 0.2.2", set doCheck False) -- attempts to access the network , ("http-conduit", set doCheck False) -- attempts to access the network - , ("imagemagick", set (libraryDepends . pkgconfig . contains (pkg "imagemagick")) True) -- https://github.com/NixOS/cabal2nix/issues/136 - , ("include-file <= 0.1.0.2", set (libraryDepends . haskell . contains (self "random")) True) -- https://github.com/Daniel-Diaz/include-file/issues/1 + , ("imagemagick", set (focusBuildInfo libraryDepends . pkgconfig . contains (pkg "imagemagick")) True) -- https://github.com/NixOS/cabal2nix/issues/136 + , ("include-file <= 0.1.0.2", set (focusBuildInfo libraryDepends . haskell . contains (self "random")) True) -- https://github.com/Daniel-Diaz/include-file/issues/1 , ("js-jquery", set doCheck False) -- attempts to access the network - , ("libconfig", over (libraryDepends . system) (replace "config = null" (pkg "libconfig"))) + , ("libconfig", over (focusBuildInfo libraryDepends . system) (replace "config = null" (pkg "libconfig"))) , ("libxml", set (configureFlags . contains "--extra-include-dir=${lib.getDev libxml2}/include/libxml2") True) - , ("liquidhaskell", set (testDepends . system . contains (pkg "z3")) True) - , ("lua >= 2.0.0 && < 2.2.0", over (libraryDepends . system) (replace (pkg "lua") (pkg "lua5_3"))) - , ("lua >= 2.2.0", over (libraryDepends . system) (replace (pkg "lua") (pkg "lua5_4"))) - , ("lzma-clib", set (metaSection . platforms) (Just $ Set.singleton (NixpkgsPlatformGroup (ident # "windows"))) . set (libraryDepends . haskell . contains (self "only-buildable-on-windows")) False) - , ("MFlow < 4.6", set (libraryDepends . tool . contains (self "cpphs")) True) + , ("liquidhaskell", set (focusBuildInfo testDepends . system . contains (pkg "z3")) True) + , ("lua >= 2.0.0 && < 2.2.0", over (focusBuildInfo libraryDepends . system) (replace (pkg "lua") (pkg "lua5_3"))) + , ("lua >= 2.2.0", over (focusBuildInfo libraryDepends . system) (replace (pkg "lua") (pkg "lua5_4"))) + , ("lzma-clib", set (metaSection . platforms) (Just $ Set.singleton (NixpkgsPlatformGroup (ident # "windows"))) . set (focusBuildInfo libraryDepends . haskell . contains (self "only-buildable-on-windows")) False) + , ("MFlow < 4.6", set (focusBuildInfo libraryDepends . tool . contains (self "cpphs")) True) , ("mwc-random", set doCheck False) - , ("mysql", set (libraryDepends . system . contains (pkg "libmysqlclient")) True) + , ("mysql", set (focusBuildInfo libraryDepends . system . contains (pkg "libmysqlclient")) True) , ("network-attoparsec", set doCheck False) -- test suite requires network access , ("numeric-qq", set doCheck False) -- test suite doesn't finish even after 1+ days , ("purescript", set doCheck False) -- test suite doesn't cope with Nix build env - , ("proto-lens-protobuf-types", set (libraryDepends . tool . contains (pkg "protobuf")) True) - , ("proto-lens-protoc", set (libraryDepends . tool . contains (pkg "protobuf")) True) - , ("qtah-cpp-qt5", set (libraryDepends . system . contains (bind "pkgs.qt5.qtbase")) True) - , ("qtah-qt5", set (libraryDepends . tool . contains (bind "pkgs.qt5.qtbase")) True) - , ("readline", over (libraryDepends . system) (Set.union (pkgs ["readline", "ncurses"]))) + , ("proto-lens-protobuf-types", set (focusBuildInfo libraryDepends . tool . contains (pkg "protobuf")) True) + , ("proto-lens-protoc", set (focusBuildInfo libraryDepends . tool . contains (pkg "protobuf")) True) + , ("qtah-cpp-qt5", set (focusBuildInfo libraryDepends . system . contains (bind "pkgs.qt5.qtbase")) True) + , ("qtah-qt5", set (focusBuildInfo libraryDepends . tool . contains (bind "pkgs.qt5.qtbase")) True) + , ("readline", over (focusBuildInfo libraryDepends . system) (Set.union (pkgs ["readline", "ncurses"]))) , ("req", set doCheck False) -- test suite requires network access - , ("rest-rewrite", over (testDepends . system) (Set.union (pkgs ["graphviz", "z3"]))) - , ("sbv > 7", set (testDepends . system . contains (pkg "z3")) True) + , ("rest-rewrite", over (focusBuildInfo testDepends . system) (Set.union (pkgs ["graphviz", "z3"]))) + , ("sbv > 7", set (focusBuildInfo testDepends . system . contains (pkg "z3")) True) , ("sdr", set (metaSection . platforms) (Just $ Set.singleton (NixpkgsPlatformGroup (ident # "x86_64")))) -- https://github.com/adamwalker/sdr/issues/2 , ("shake-language-c", set doCheck False) -- https://github.com/samplecount/shake-language-c/issues/26 , ("ssh", set doCheck False) -- test suite runs forever, probably can't deal with our lack of network access , ("stack", set phaseOverrides stackOverrides . set doCheck False) , ("stripe-http-streams", set doCheck False . set (metaSection . broken) False) - , ("target", set (testDepends . system . contains (pkg "z3")) True) - , ("terminfo", set (libraryDepends . system . contains (pkg "ncurses")) True) + , ("target", set (focusBuildInfo testDepends . system . contains (pkg "z3")) True) + , ("terminfo", set (focusBuildInfo libraryDepends . system . contains (pkg "ncurses")) True) , ("text", set doCheck False) -- break infinite recursion - , ("tensorflow-proto", set (libraryDepends . tool . contains (pkg "protobuf")) True) - , ("thyme", set (libraryDepends . tool . contains (self "cpphs")) True) -- required on Darwin + , ("tensorflow-proto", set (focusBuildInfo libraryDepends . tool . contains (pkg "protobuf")) True) + , ("thyme", set (focusBuildInfo libraryDepends . tool . contains (self "cpphs")) True) -- required on Darwin , ("twilio", set doCheck False) -- attempts to access the network , ("udev", set (metaSection . platforms) (Just $ Set.singleton (NixpkgsPlatformGroup (ident # "linux")))) , ("websockets", set doCheck False) -- https://github.com/jaspervdj/websockets/issues/104 , ("Win32", set (metaSection . platforms) (Just $ Set.singleton (NixpkgsPlatformGroup (ident # "windows")))) , ("Win32-shortcut", set (metaSection . platforms) (Just $ Set.singleton (NixpkgsPlatformGroup (ident # "windows")))) , ("wxc", wxcHook) - , ("wxcore", set (libraryDepends . pkgconfig . contains (pkg "wxGTK")) True) - , ("X11", over (libraryDepends . system) (Set.union (Set.fromList $ map bind ["pkgs.libxinerama","pkgs.libxext","pkgs.libxrender","pkgs.libxscrnsaver"]))) + , ("wxcore", set (focusBuildInfo libraryDepends . pkgconfig . contains (pkg "wxGTK")) True) + , ("X11", over (focusBuildInfo libraryDepends . system) (Set.union (Set.fromList $ map bind ["pkgs.libxinerama","pkgs.libxext","pkgs.libxrender","pkgs.libxscrnsaver"]))) , ("xmonad >= 0.14.2", set phaseOverrides xmonadPostInstall) - , ("zip-archive < 0.3.1", over (testDepends . tool) (replace (self "zip") (pkg "zip"))) - , ("zip-archive >= 0.3.1 && < 0.3.2.3", over (testDepends . tool) (Set.union (Set.fromList [pkg "zip", pkg "unzip"]))) -- https://github.com/jgm/zip-archive/issues/35 - , ("zip-archive >= 0.4", set (testDepends . tool . contains (pkg "which")) True) + , ("zip-archive < 0.3.1", over (focusBuildInfo testDepends . tool) (replace (self "zip") (pkg "zip"))) + , ("zip-archive >= 0.3.1 && < 0.3.2.3", over (focusBuildInfo testDepends . tool) (Set.union (Set.fromList [pkg "zip", pkg "unzip"]))) -- https://github.com/jgm/zip-archive/issues/35 + , ("zip-archive >= 0.4", set (focusBuildInfo testDepends . tool . contains (pkg "which")) True) ] pkg :: Identifier -> Binding @@ -203,8 +204,8 @@ replace :: Binding -> Binding -> Set Binding -> Set Binding replace old new = Set.map (\x -> if x == old then new else x) gtk3Hook :: Derivation -> Derivation -- https://github.com/NixOS/cabal2nix/issues/145 -gtk3Hook = set (libraryDepends . pkgconfig . contains (pkg "gtk3")) True - . over (libraryDepends . pkgconfig) (Set.filter (\b -> view localName b /= "gtk3")) +gtk3Hook = set (focusBuildInfo libraryDepends . pkgconfig . contains (pkg "gtk3")) True + . over (focusBuildInfo libraryDepends . pkgconfig) (Set.filter (\b -> view localName b /= "gtk3")) hfusePreConfigure :: String hfusePreConfigure = unlines @@ -228,8 +229,8 @@ gfPhaseOverrides = unlines ] wxcHook :: Derivation -> Derivation -wxcHook drv = drv & libraryDepends . system %~ Set.union (Set.fromList [pkg "libGL", bind "pkgs.libx11"]) - & libraryDepends . pkgconfig . contains (pkg "wxGTK") .~ True +wxcHook drv = drv & focusBuildInfo libraryDepends . system %~ Set.union (Set.fromList [pkg "libGL", bind "pkgs.libx11"]) + & focusBuildInfo libraryDepends . pkgconfig . contains (pkg "wxGTK") .~ True & phaseOverrides .~ wxcPostInstall (packageVersion drv) & runHaddock .~ False where @@ -299,11 +300,11 @@ stackOverrides = unlines -- Replace a binding for to one to pkgs.gst_all_1. giGstLibOverrides :: String -> Derivation -> Derivation giGstLibOverrides package - = over (libraryDepends . pkgconfig) (replace (nullBinding (ident # package)) (binding # (ident # package, path # ["pkgs","gst_all_1", ident # package]))) + = over (focusBuildInfo libraryDepends . pkgconfig) (replace (nullBinding (ident # package)) (binding # (ident # package, path # ["pkgs","gst_all_1", ident # package]))) giCairoPhaseOverrides :: Derivation -> Derivation giCairoPhaseOverrides = over phaseOverrides (++txt) - . set (libraryDepends . pkgconfig . contains (pkg "cairo")) True + . set (focusBuildInfo libraryDepends . pkgconfig . contains (pkg "cairo")) True where txt = unlines [ "preCompileBuildDriver = ''" , " PKG_CONFIG_PATH+=\":${lib.getDev cairo}/lib/pkgconfig\"" @@ -315,7 +316,7 @@ hfseventsOverrides :: Derivation -> Derivation hfseventsOverrides = set isLibrary True . set (metaSection . platforms) (Just $ Set.singleton (NixpkgsPlatformGroup (ident # "darwin"))) - . over (libraryDepends . haskell) (Set.union (Set.fromList (map bind ["self.base", "self.cereal", "self.mtl", "self.text", "self.bytestring"]))) + . over (focusBuildInfo libraryDepends . haskell) (Set.union (Set.fromList (map bind ["self.base", "self.cereal", "self.mtl", "self.text", "self.bytestring"]))) hspecCoreOverrides :: Derivation -> Derivation -- https://github.com/hspec/hspec/issues/330 hspecCoreOverrides = set testFlags [ "--skip", "'Test.Hspec.Core.Runner.hspecResult runs specs in parallel'" ] @@ -329,7 +330,7 @@ cabal2nixOverrides = set phaseOverrides $ unlines ] gtkglextHook :: Derivation -> Derivation -gtkglextHook = over (libraryDepends . system) (Set.union (Set.fromList deps)) +gtkglextHook = over (focusBuildInfo libraryDepends . system) (Set.union (Set.fromList deps)) where deps :: [Binding] deps = bind <$> [ "pkgs.gtk2" @@ -341,8 +342,8 @@ gtkglextHook = over (libraryDepends . system) (Set.union (Set.fromList deps)) ] bustleOverrides :: Derivation -> Derivation -bustleOverrides = set (libraryDepends . pkgconfig . contains "system-glib = pkgs.glib") True - . set (executableDepends . pkgconfig . contains "gio-unix = null") False +bustleOverrides = set (focusBuildInfo libraryDepends . pkgconfig . contains "system-glib = pkgs.glib") True + . set (focusBuildInfo executableDepends . pkgconfig . contains "gio-unix = null") False . set (metaSection . license) (Known "lib.licenses.lgpl21Plus") . set (metaSection . hydraPlatforms) Nothing From eb01bf05bc49ddaa361b7621eac2e8f66fcd2e44 Mon Sep 17 00:00:00 2001 From: Alexandre Esteves Date: Tue, 24 Mar 2026 04:45:55 +0000 Subject: [PATCH 3/8] Rename --- cabal2nix/src/Distribution/Nixpkgs/Haskell/FromCabal.hs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/cabal2nix/src/Distribution/Nixpkgs/Haskell/FromCabal.hs b/cabal2nix/src/Distribution/Nixpkgs/Haskell/FromCabal.hs index 115de99cc..0dc5273f5 100644 --- a/cabal2nix/src/Distribution/Nixpkgs/Haskell/FromCabal.hs +++ b/cabal2nix/src/Distribution/Nixpkgs/Haskell/FromCabal.hs @@ -50,13 +50,13 @@ type HaskellResolver = PackageVersionConstraint -> Bool type NixpkgsResolver = Identifier -> Maybe Binding fromGenericPackageDescription :: HaskellResolver -> NixpkgsResolver -> Platform -> CompilerInfo -> FlagAssignment -> [Constraint] -> GenericPackageDescription -> Derivation -fromGenericPackageDescription haskellResolver nixpkgsResolver arch compiler flags constraints genDesc = +fromGenericPackageDescription haskellResolver nixpkgsResolver platform compiler flags constraints genDesc = fromPackageDescription haskellResolver nixpkgsResolver missingDeps flags descr where - (descr, missingDeps) = finalizeGenericPackageDescription haskellResolver arch compiler flags constraints genDesc + (descr, missingDeps) = finalizeGenericPackageDescription haskellResolver platform compiler flags constraints genDesc finalizeGenericPackageDescription :: HaskellResolver -> Platform -> CompilerInfo -> FlagAssignment -> [Constraint] -> GenericPackageDescription -> (PackageDescription, [Dependency]) -finalizeGenericPackageDescription haskellResolver arch compiler flags constraints genDesc = +finalizeGenericPackageDescription haskellResolver platform compiler flags constraints genDesc = let -- finalizePD incooperates the 'LibraryName' of a dependency -- which we always ignore, so the Cabal-compatible resolver @@ -86,7 +86,7 @@ finalizeGenericPackageDescription haskellResolver arch compiler flags constraint -- functions, and this convenience function makes our code shorter. finalize :: HaskellResolver -> Either [Dependency] (PackageDescription,FlagAssignment) finalize resolver = - case finalizePD flags requestedComponents (makeCabalResolver resolver) arch compiler (makeCabalConstraints constraints) genDesc of + case finalizePD flags requestedComponents (makeCabalResolver resolver) platform compiler (makeCabalConstraints constraints) genDesc of #if MIN_VERSION_Cabal(3,16,0) Left left -> Left (map (\(MissingDependency dependency _reason) -> dependency) left) #else From 9462be2b0b211f6439a315ad569cc9314d4f8a7d Mon Sep 17 00:00:00 2001 From: Alexandre Esteves Date: Tue, 24 Mar 2026 04:15:36 +0000 Subject: [PATCH 4/8] Cleanup --- cabal2nix/hackage2nix/Main.hs | 25 +++++++------ cabal2nix/src/Cabal2nix.hs | 19 ++++++---- .../Distribution/Nixpkgs/Haskell/BuildInfo.hs | 10 +++-- cabal2nix/test/Main.hs | 37 ++++++++++--------- 4 files changed, 52 insertions(+), 39 deletions(-) diff --git a/cabal2nix/hackage2nix/Main.hs b/cabal2nix/hackage2nix/Main.hs index 284bd264f..04b2c913c 100644 --- a/cabal2nix/hackage2nix/Main.hs +++ b/cabal2nix/hackage2nix/Main.hs @@ -153,17 +153,20 @@ main = do attr = if isInDefaultPackageSet then toNixName name else mangle pkgId drv :: Derivation - drv = fromGenericPackageDescription haskellResolver nixpkgsResolver targetPlatform (compilerInfo config) flagAssignment [] descr - & src .~ urlDerivationSource ("mirror://hackage/" ++ display pkgId ++ ".tar.gz") tarballSHA256 - & editedCabalFile .~ cabalSHA256 - -- If a list of platforms is set in the hackage2nix configuration file, prefer that. - -- Otherwise a list defined by PostProcess or Nothing is used. - & metaSection.platforms %~ (Map.lookup name (supportedPlatforms config) <|>) - & metaSection.badPlatforms %~ (Map.lookup name (unsupportedPlatforms config) <|>) - & metaSection.hydraPlatforms %~ (if isHydraEnabled then id else const (Just Set.empty)) - & metaSection.broken ||~ isBroken - & metaSection.maintainers .~ Map.findWithDefault Set.empty name globalPackageMaintainers - & metaSection.homepage .~ "" + drv = modifiers finalized + where + finalized = fromGenericPackageDescription haskellResolver nixpkgsResolver targetPlatform (compilerInfo config) flagAssignment [] descr + modifiers d = d + & src .~ urlDerivationSource ("mirror://hackage/" ++ display pkgId ++ ".tar.gz") tarballSHA256 + & editedCabalFile .~ cabalSHA256 + -- If a list of platforms is set in the hackage2nix configuration file, prefer that. + -- Otherwise a list defined by PostProcess or Nothing is used. + & metaSection.platforms %~ (Map.lookup name (supportedPlatforms config) <|>) + & metaSection.badPlatforms %~ (Map.lookup name (unsupportedPlatforms config) <|>) + & metaSection.hydraPlatforms %~ (if isHydraEnabled then id else const (Just Set.empty)) + & metaSection.broken ||~ isBroken + & metaSection.maintainers .~ Map.findWithDefault Set.empty name globalPackageMaintainers + & metaSection.homepage .~ "" overrides :: Doc overrides = fcat $ punctuate space [ pPrint b <> semi | b <- Set.toList (view (dependencies . each) drv `Set.union` view extraFunctionArgs drv), not (isFromHackage b) ] diff --git a/cabal2nix/src/Cabal2nix.hs b/cabal2nix/src/Cabal2nix.hs index 1022e4f4f..9d7944381 100644 --- a/cabal2nix/src/Cabal2nix.hs +++ b/cabal2nix/src/Cabal2nix.hs @@ -220,13 +220,17 @@ processPackage Options{..} pkg = do Just customExpr -> (pkgSource pkg) { derivCustomSrc = Just customExpr } deriv :: Derivation - deriv = withHpackOverrides $ fromGenericPackageDescription (const True) - optNixpkgsIdentifier - optSystem - (unknownCompilerInfo optCompiler NoAbiTag) - flags - [] - (pkgCabal pkg) + deriv = withHpackOverrides $ modifiers finalized + where + finalized = fromGenericPackageDescription (const True) + optNixpkgsIdentifier + optSystem + (unknownCompilerInfo optCompiler NoAbiTag) + flags + [] + (pkgCabal pkg) + + modifiers d = d & src .~ finalSource & subpath .~ fromMaybe "." optSubpath & runHaddock %~ (optHaddock &&) @@ -240,6 +244,7 @@ processPackage Options{..} pkg = do & doBenchmark ||~ optDoBenchmark & extraFunctionArgs %~ Set.union (Set.fromList ("inherit lib":map (fromString . ("inherit " ++)) optExtraArgs)) + shell :: Doc shell = vcat [ text "{ nixpkgs ? import {}, compiler ? \"default\", doBenchmark ? false, inNixShell ? false }:" diff --git a/cabal2nix/src/Distribution/Nixpkgs/Haskell/BuildInfo.hs b/cabal2nix/src/Distribution/Nixpkgs/Haskell/BuildInfo.hs index 25dccac19..9e87ae036 100644 --- a/cabal2nix/src/Distribution/Nixpkgs/Haskell/BuildInfo.hs +++ b/cabal2nix/src/Distribution/Nixpkgs/Haskell/BuildInfo.hs @@ -43,8 +43,10 @@ instance NFData BuildInfo pPrintBuildInfo :: String -> BuildInfo -> Doc pPrintBuildInfo prefix bi = onlyIf (bi /= mempty) $ vcat - [ setattr (prefix++"HaskellDepends") empty (setOf (haskell.folded.localName.ident) bi) - , setattr (prefix++"SystemDepends") empty (setOf (system.folded.localName.ident) bi) - , setattr (prefix++"PkgconfigDepends") empty (setOf (pkgconfig.folded.localName.ident) bi) - , setattr (prefix++"ToolDepends") empty (setOf (tool.folded.localName.ident) bi) + [ pp haskell "HaskellDepends" + , pp system "SystemDepends" + , pp pkgconfig "PkgconfigDepends" + , pp tool "ToolDepends" ] + where + pp fld suffix = setattr (prefix++suffix) empty $ setOf (fld.folded.localName.ident) bi diff --git a/cabal2nix/test/Main.hs b/cabal2nix/test/Main.hs index 7e5bbf641..ea4b0f126 100644 --- a/cabal2nix/test/Main.hs +++ b/cabal2nix/test/Main.hs @@ -57,23 +57,26 @@ testLibrary cabalFile = do goldenFile = nixFile `addExtension` "golden" cabal2nix :: GenericPackageDescription -> Derivation - cabal2nix gpd = fromGenericPackageDescription - (const True) - (\i -> Just (binding # (i, path # [ident # "pkgs", i]))) - (Platform X86_64 Linux) - (unknownCompilerInfo (CompilerId GHC (mkVersion [8,2])) NoAbiTag) - (configureCabalFlags (packageId gpd)) - [] - gpd - & src .~ DerivationSource - { derivKind = Just (DerivKindUrl DontUnpackArchive ) - , derivUrl = "mirror://hackage/foo.tar.gz" - , derivRevision = "" - , derivHash = "deadbeef" - , derivSubmodule = Nothing - , derivCustomSrc = Nothing - } - & extraFunctionArgs %~ Set.union (Set.singleton "inherit lib") + cabal2nix gpd = modifiers finalized + where + finalized = fromGenericPackageDescription + (const True) + (\i -> Just (binding # (i, path # [ident # "pkgs", i]))) + (Platform X86_64 Linux) + (unknownCompilerInfo (CompilerId GHC (mkVersion [8,2])) NoAbiTag) + (configureCabalFlags (packageId gpd)) + [] + gpd + modifiers d = d + & src .~ DerivationSource + { derivKind = Just (DerivKindUrl DontUnpackArchive ) + , derivUrl = "mirror://hackage/foo.tar.gz" + , derivRevision = "" + , derivHash = "deadbeef" + , derivSubmodule = Nothing + , derivCustomSrc = Nothing + } + & extraFunctionArgs %~ Set.union (Set.singleton "inherit lib") goldenVsFileDiff nixFile (\ref new -> ["diff", "-u", ref, new]) From 9a44c8f6129a1a1f56e901e6bb739ca3159df8a3 Mon Sep 17 00:00:00 2001 From: Alexandre Esteves Date: Tue, 24 Mar 2026 05:16:05 +0000 Subject: [PATCH 5/8] Preserve finalization arguments until pretty-printing --- cabal2nix/hackage2nix/Main.hs | 6 +++--- cabal2nix/src/Cabal2nix.hs | 10 +++++----- .../Nixpkgs/Haskell/Derivation.hs | 19 +++++++++++++++---- .../Distribution/Nixpkgs/Haskell/FromCabal.hs | 4 ++-- cabal2nix/test/Main.hs | 4 ++-- 5 files changed, 27 insertions(+), 16 deletions(-) diff --git a/cabal2nix/hackage2nix/Main.hs b/cabal2nix/hackage2nix/Main.hs index 04b2c913c..acd89e4c9 100644 --- a/cabal2nix/hackage2nix/Main.hs +++ b/cabal2nix/hackage2nix/Main.hs @@ -152,8 +152,8 @@ main = do attr :: Identifier attr = if isInDefaultPackageSet then toNixName name else mangle pkgId - drv :: Derivation - drv = modifiers finalized + drv :: FinalizedDerivation + drv = over finalized_derivation modifiers finalized where finalized = fromGenericPackageDescription haskellResolver nixpkgsResolver targetPlatform (compilerInfo config) flagAssignment [] descr modifiers d = d @@ -169,7 +169,7 @@ main = do & metaSection.homepage .~ "" overrides :: Doc - overrides = fcat $ punctuate space [ pPrint b <> semi | b <- Set.toList (view (dependencies . each) drv `Set.union` view extraFunctionArgs drv), not (isFromHackage b) ] + overrides = fcat $ punctuate space [ pPrint b <> semi | b <- Set.toList (view (finalized_derivation . dependencies . each) drv `Set.union` view (finalized_derivation . extraFunctionArgs) drv), not (isFromHackage b) ] return $ render $ nest 2 $ hang (pPrint attr <+> equals <+> text "callPackage") 2 (parens (pPrint drv)) <+> (braces overrides <> semi) diff --git a/cabal2nix/src/Cabal2nix.hs b/cabal2nix/src/Cabal2nix.hs index 9d7944381..49abad0c6 100644 --- a/cabal2nix/src/Cabal2nix.hs +++ b/cabal2nix/src/Cabal2nix.hs @@ -177,7 +177,7 @@ hpackOverrides :: Derivation -> Derivation hpackOverrides = over phaseOverrides (++ "prePatch = \"hpack\";") . set (focusBuildInfo libraryDepends . tool . contains (PP.pkg "hpack")) True -cabal2nix' :: Options -> IO (Either Doc Derivation) +cabal2nix' :: Options -> IO (Either Doc FinalizedDerivation) cabal2nix' opts@Options{..} = do pkg <- getPackage optHpack optFetchSubmodules optHackageDb optHackageSnapshot $ Source { @@ -190,7 +190,7 @@ cabal2nix' opts@Options{..} = do } processPackage opts pkg -cabal2nixWithDB :: DB.HackageDB -> Options -> IO (Either Doc Derivation) +cabal2nixWithDB :: DB.HackageDB -> Options -> IO (Either Doc FinalizedDerivation) cabal2nixWithDB db opts@Options{..} = do when (isJust optHackageDb) $ colorStderrLn warningColor "WARN: HackageDB provided directly; ignoring --hackage-db" when (isJust optHackageSnapshot) $ colorStderrLn warningColor "WARN: HackageDB provided directly; ignoring --hackage-snapshot" @@ -205,7 +205,7 @@ cabal2nixWithDB db opts@Options{..} = do } processPackage opts pkg -processPackage :: Options -> Package -> IO (Either Doc Derivation) +processPackage :: Options -> Package -> IO (Either Doc FinalizedDerivation) processPackage Options{..} pkg = do let withHpackOverrides :: Derivation -> Derivation @@ -219,8 +219,8 @@ processPackage Options{..} pkg = do Nothing -> pkgSource pkg Just customExpr -> (pkgSource pkg) { derivCustomSrc = Just customExpr } - deriv :: Derivation - deriv = withHpackOverrides $ modifiers finalized + deriv :: FinalizedDerivation + deriv = over finalized_derivation (withHpackOverrides . modifiers) finalized where finalized = fromGenericPackageDescription (const True) optNixpkgsIdentifier diff --git a/cabal2nix/src/Distribution/Nixpkgs/Haskell/Derivation.hs b/cabal2nix/src/Distribution/Nixpkgs/Haskell/Derivation.hs index 579da036f..1eee19948 100644 --- a/cabal2nix/src/Distribution/Nixpkgs/Haskell/Derivation.hs +++ b/cabal2nix/src/Distribution/Nixpkgs/Haskell/Derivation.hs @@ -7,7 +7,8 @@ {-# LANGUAGE FlexibleInstances, MultiParamTypeClasses #-} module Distribution.Nixpkgs.Haskell.Derivation - ( Derivation, nullDerivation, pkgid, revision, src, subpath, isLibrary, isExecutable + ( FinalizedDerivation(..), finalized_compiler, finalized_derivation, finalized_flags, finalized_platform + , Derivation, nullDerivation, pkgid, revision, src, subpath, isLibrary, isExecutable , extraFunctionArgs, libraryDepends, executableDepends, testDepends, configureFlags , cabalFlags, runHaddock, jailbreak, doCheck, doBenchmark, testFlags, testTargets, hyperlinkSource , enableLibraryProfiling, enableExecutableProfiling, phaseOverrides, editedCabalFile, metaSection @@ -29,12 +30,14 @@ import qualified Data.Map as Map import Data.Set ( Set ) import qualified Data.Set as Set import Data.Set.Lens +import Distribution.Compiler (CompilerInfo) import Distribution.Nixpkgs.Fetch import Distribution.Nixpkgs.Haskell.BuildInfo import Distribution.Nixpkgs.Haskell.OrphanInstances ( ) import Distribution.Nixpkgs.Meta import Distribution.Package -import Distribution.PackageDescription ( FlagAssignment, unFlagName, unFlagAssignment ) +import Distribution.PackageDescription ( FlagAssignment, unFlagName, unFlagAssignment) +import Distribution.System (Platform (..)) import GHC.Generics ( Generic ) import Language.Nix import Language.Nix.PrettyPrinting @@ -42,6 +45,12 @@ import Language.Nix.PrettyPrinting -- | A represtation of Nix expressions for building Haskell packages. -- The data type correspond closely to the definition of -- 'PackageDescription' from Cabal. +data FinalizedDerivation = FinalizedDerivation + { _finalized_flags :: FlagAssignment + , _finalized_platform :: Platform + , _finalized_compiler :: CompilerInfo + , _finalized_derivation :: Derivation + } data Derivation = MkDerivation { _pkgid :: PackageIdentifier @@ -107,6 +116,8 @@ nullDerivation = MkDerivation , _metaSection = error "undefined Derivation.metaSection" } +makeLenses ''FinalizedDerivation + makeLenses ''Derivation makeLensesFor (fmap (,"nonSetupDependencies") ["_libraryDepends", "_executableDepends", "_testDepends", "_benchmarkDepends"]) ''Derivation @@ -123,8 +134,8 @@ instance Package Derivation where instance NFData Derivation -instance Pretty Derivation where - pPrint drv@MkDerivation {..} = funargs (map text ("mkDerivation" : toAscList inputs)) $$ vcat +instance Pretty FinalizedDerivation where + pPrint (FinalizedDerivation _ _ _ (drv@MkDerivation {..})) = funargs (map text ("mkDerivation" : toAscList inputs)) $$ vcat [ text "mkDerivation" <+> lbrace , nest 2 $ vcat [ attr "pname" $ doubleQuotes $ pPrint (packageName _pkgid) diff --git a/cabal2nix/src/Distribution/Nixpkgs/Haskell/FromCabal.hs b/cabal2nix/src/Distribution/Nixpkgs/Haskell/FromCabal.hs index 0dc5273f5..bb408cfbd 100644 --- a/cabal2nix/src/Distribution/Nixpkgs/Haskell/FromCabal.hs +++ b/cabal2nix/src/Distribution/Nixpkgs/Haskell/FromCabal.hs @@ -49,9 +49,9 @@ import Distribution.Types.MissingDependencyReason ( MissingDependencyReason(Wron type HaskellResolver = PackageVersionConstraint -> Bool type NixpkgsResolver = Identifier -> Maybe Binding -fromGenericPackageDescription :: HaskellResolver -> NixpkgsResolver -> Platform -> CompilerInfo -> FlagAssignment -> [Constraint] -> GenericPackageDescription -> Derivation +fromGenericPackageDescription :: HaskellResolver -> NixpkgsResolver -> Platform -> CompilerInfo -> FlagAssignment -> [Constraint] -> GenericPackageDescription -> FinalizedDerivation fromGenericPackageDescription haskellResolver nixpkgsResolver platform compiler flags constraints genDesc = - fromPackageDescription haskellResolver nixpkgsResolver missingDeps flags descr + FinalizedDerivation flags platform compiler $ fromPackageDescription haskellResolver nixpkgsResolver missingDeps flags descr where (descr, missingDeps) = finalizeGenericPackageDescription haskellResolver platform compiler flags constraints genDesc diff --git a/cabal2nix/test/Main.hs b/cabal2nix/test/Main.hs index ea4b0f126..39605fce8 100644 --- a/cabal2nix/test/Main.hs +++ b/cabal2nix/test/Main.hs @@ -56,8 +56,8 @@ testLibrary cabalFile = do let nixFile = cabalFile `replaceExtension` "nix" goldenFile = nixFile `addExtension` "golden" - cabal2nix :: GenericPackageDescription -> Derivation - cabal2nix gpd = modifiers finalized + cabal2nix :: GenericPackageDescription -> FinalizedDerivation + cabal2nix gpd = over finalized_derivation modifiers finalized where finalized = fromGenericPackageDescription (const True) From af8709c160f1664a926e478668129af0d5be144e Mon Sep 17 00:00:00 2001 From: Alexandre Esteves Date: Tue, 24 Mar 2026 05:32:53 +0000 Subject: [PATCH 6/8] Preserve conditionals until pretty-printing --- .../Nixpkgs/Haskell/Derivation.hs | 65 ++++++++++++++----- .../Distribution/Nixpkgs/Haskell/FromCabal.hs | 26 ++++---- .../Nixpkgs/Haskell/FromCabal/Normalize.hs | 3 +- .../Nixpkgs/Haskell/FromCabal/PostProcess.hs | 3 +- 4 files changed, 65 insertions(+), 32 deletions(-) diff --git a/cabal2nix/src/Distribution/Nixpkgs/Haskell/Derivation.hs b/cabal2nix/src/Distribution/Nixpkgs/Haskell/Derivation.hs index 1eee19948..2569d6441 100644 --- a/cabal2nix/src/Distribution/Nixpkgs/Haskell/Derivation.hs +++ b/cabal2nix/src/Distribution/Nixpkgs/Haskell/Derivation.hs @@ -1,5 +1,6 @@ {-# LANGUAGE CPP #-} {-# LANGUAGE DeriveGeneric #-} +{-# LANGUAGE LambdaCase #-} {-# LANGUAGE RankNTypes #-} {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE TemplateHaskell #-} @@ -24,6 +25,7 @@ import Control.Applicative (liftA2) #endif import Control.DeepSeq import Control.Lens +import Data.Foldable import Data.List ( isPrefixOf ) import Data.Map ( Map ) import qualified Data.Map as Map @@ -36,11 +38,13 @@ import Distribution.Nixpkgs.Haskell.BuildInfo import Distribution.Nixpkgs.Haskell.OrphanInstances ( ) import Distribution.Nixpkgs.Meta import Distribution.Package -import Distribution.PackageDescription ( FlagAssignment, unFlagName, unFlagAssignment) +import Distribution.PackageDescription (CondBranch (..), CondTree (..), Condition (..), ConfVar (..), FlagAssignment, FlagName, lookupFlagAssignment, unFlagAssignment, unFlagName) import Distribution.System (Platform (..)) import GHC.Generics ( Generic ) import Language.Nix import Language.Nix.PrettyPrinting +import Data.Maybe (fromMaybe) +import Distribution.PackageDescription.Configuration (simplifyWithSysParams) -- | A represtation of Nix expressions for building Haskell packages. -- The data type correspond closely to the definition of @@ -62,10 +66,10 @@ data Derivation = MkDerivation , _extraFunctionArgs :: Set Binding , _extraAttributes :: Map String String , _setupDepends :: BuildInfo - , _libraryDepends :: [(BuildInfo, Bool)] - , _executableDepends :: [(BuildInfo, Bool)] - , _testDepends :: [(BuildInfo, Bool)] - , _benchmarkDepends :: [(BuildInfo, Bool)] + , _libraryDepends :: [CondTree ConfVar [Dependency] (BuildInfo, Bool)] + , _executableDepends :: [CondTree ConfVar [Dependency] (BuildInfo, Bool)] + , _testDepends :: [CondTree ConfVar [Dependency] (BuildInfo, Bool)] + , _benchmarkDepends :: [CondTree ConfVar [Dependency] (BuildInfo, Bool)] , _configureFlags :: Set String , _cabalFlags :: FlagAssignment , _runHaddock :: Bool @@ -124,10 +128,10 @@ makeLensesFor (fmap (,"nonSetupDependencies") ["_libraryDepends", "_executableDe dependencies :: Traversal' Derivation BuildInfo dependencies = traversal $ \focus drv -> - liftA2 (set setupDepends) (focus $ view setupDepends drv) ((nonSetupDependencies . traverse . _1) focus drv) + liftA2 (set setupDepends) (focus $ view setupDepends drv) ((nonSetupDependencies . traverse . traverse . _1) focus drv) -focusBuildInfo :: Lens' Derivation [(BuildInfo, Bool)] -> Traversal' Derivation BuildInfo -focusBuildInfo l = l . traverse . _1 +focusBuildInfo :: Lens' Derivation [CondTree ConfVar [Dependency] (BuildInfo, Bool)] -> Traversal' Derivation BuildInfo +focusBuildInfo l = l . traverse . traverse . _1 instance Package Derivation where packageId = view pkgid @@ -135,7 +139,7 @@ instance Package Derivation where instance NFData Derivation instance Pretty FinalizedDerivation where - pPrint (FinalizedDerivation _ _ _ (drv@MkDerivation {..})) = funargs (map text ("mkDerivation" : toAscList inputs)) $$ vcat + pPrint (FinalizedDerivation flags (Platform arch os) compiler (MkDerivation {..})) = funargs (map text ("mkDerivation" : toAscList inputs)) $$ vcat [ text "mkDerivation" <+> lbrace , nest 2 $ vcat [ attr "pname" $ doubleQuotes $ pPrint (packageName _pkgid) @@ -149,10 +153,10 @@ instance Pretty FinalizedDerivation where , boolattr "isExecutable" (not _isLibrary || _isExecutable) _isExecutable , boolattr "enableSeparateDataOutput" _enableSeparateDataOutput _enableSeparateDataOutput , pPrintBuildInfo "setup" _setupDepends - , pPrintBuildInfo' "library" _libraryDepends - , pPrintBuildInfo' "executable" _executableDepends - , pPrintBuildInfo' "test" _testDepends - , pPrintBuildInfo' "benchmark" _benchmarkDepends + , pPrintBuildInfo "library" lib + , pPrintBuildInfo "executable" exe + , pPrintBuildInfo "test" test + , pPrintBuildInfo "benchmark" bench , boolattr "enableLibraryProfiling" _enableLibraryProfiling _enableLibraryProfiling , boolattr "enableExecutableProfiling" _enableExecutableProfiling _enableExecutableProfiling , boolattr "doHaddock" (not _runHaddock) _runHaddock @@ -169,19 +173,46 @@ instance Pretty FinalizedDerivation where , rbrace ] where - pPrintBuildInfo' :: String -> [(BuildInfo, Bool)] -> Doc - pPrintBuildInfo' name = pPrintBuildInfo name . foldMap fst . filter snd - inputs :: Set String inputs = Set.unions [ Set.map (view (localName . ident)) _extraFunctionArgs - , setOf (dependencies . each . folded . localName . ident) drv + , setOf (each . folded . localName . ident) $ fold [_setupDepends, lib, exe, test, bench] , case derivKind _src of Nothing -> mempty Just derivKind' -> Set.fromList [derivKindFunction derivKind' | not isHackagePackage] ] + (lib, exe, test, bench) = over each (foldMap eval) + (_libraryDepends, _executableDepends, _testDepends, _benchmarkDepends) + renderedFlags = [ text "-f" <> (if enable then empty else char '-') <> text (unFlagName f) | (f, enable) <- unFlagAssignment _cabalFlags ] ++ map text (toAscList _configureFlags) isHackagePackage = "mirror://hackage/" `isPrefixOf` derivUrl _src postUnpack = string $ "sourceRoot+=/" ++ _subpath ++ "; echo source root reset to $sourceRoot" + + eval :: CondTree ConfVar c (BuildInfo, Bool) -> BuildInfo + eval = fold . evalTree + + evalTree :: CondTree ConfVar c (BuildInfo, Bool) -> Maybe BuildInfo + evalTree (CondNode (bi, buildable) _ branches) = case buildable of + False -> Nothing + True -> do + bs <- traverse evalBranch branches + pure $ fold $ bi : bs + + evalBranch :: CondBranch ConfVar c (BuildInfo, Bool) -> Maybe BuildInfo + evalBranch (CondBranch c t mf) = + if evalCondition c + then evalTree t + else maybe (Just mempty) evalTree mf + + evalCondition :: Condition ConfVar -> Bool + evalCondition = go . fst . simplifyWithSysParams os arch compiler + where + go :: Condition FlagName -> Bool + go = \case + Lit b -> b + CNot c -> not $ go c + COr a b -> go a || go b + CAnd a b -> go a && go b + Var fn -> fromMaybe False $ lookupFlagAssignment fn flags diff --git a/cabal2nix/src/Distribution/Nixpkgs/Haskell/FromCabal.hs b/cabal2nix/src/Distribution/Nixpkgs/Haskell/FromCabal.hs index bb408cfbd..da868dc06 100644 --- a/cabal2nix/src/Distribution/Nixpkgs/Haskell/FromCabal.hs +++ b/cabal2nix/src/Distribution/Nixpkgs/Haskell/FromCabal.hs @@ -51,11 +51,11 @@ type NixpkgsResolver = Identifier -> Maybe Binding fromGenericPackageDescription :: HaskellResolver -> NixpkgsResolver -> Platform -> CompilerInfo -> FlagAssignment -> [Constraint] -> GenericPackageDescription -> FinalizedDerivation fromGenericPackageDescription haskellResolver nixpkgsResolver platform compiler flags constraints genDesc = - FinalizedDerivation flags platform compiler $ fromPackageDescription haskellResolver nixpkgsResolver missingDeps flags descr + FinalizedDerivation finalizedFlags platform compiler $ fromPackageDescription haskellResolver nixpkgsResolver missingDeps flags genDesc descr where - (descr, missingDeps) = finalizeGenericPackageDescription haskellResolver platform compiler flags constraints genDesc + (descr, finalizedFlags, missingDeps) = finalizeGenericPackageDescription haskellResolver platform compiler flags constraints genDesc -finalizeGenericPackageDescription :: HaskellResolver -> Platform -> CompilerInfo -> FlagAssignment -> [Constraint] -> GenericPackageDescription -> (PackageDescription, [Dependency]) +finalizeGenericPackageDescription :: HaskellResolver -> Platform -> CompilerInfo -> FlagAssignment -> [Constraint] -> GenericPackageDescription -> (PackageDescription, FlagAssignment, [Dependency]) finalizeGenericPackageDescription haskellResolver platform compiler flags constraints genDesc = let -- finalizePD incooperates the 'LibraryName' of a dependency @@ -113,11 +113,11 @@ finalizeGenericPackageDescription haskellResolver platform compiler flags constr in case finalize (jailbroken (withInternalLibs haskellResolver)) of Left m -> case finalize (const True) of Left _ -> error ("Cabal cannot finalize " ++ display (packageId genDesc)) - Right (d,_) -> (d,m) - Right (d,_) -> (d,[]) + Right (d,f) -> (d,f,m) + Right (d,f) -> (d,f,[]) -fromPackageDescription :: HaskellResolver -> NixpkgsResolver -> [Dependency] -> FlagAssignment -> PackageDescription -> Derivation -fromPackageDescription haskellResolver nixpkgsResolver missingDeps flags PackageDescription {..} = normalize $ postProcess $ nullDerivation +fromPackageDescription :: HaskellResolver -> NixpkgsResolver -> [Dependency] -> FlagAssignment -> GenericPackageDescription -> PackageDescription -> Derivation +fromPackageDescription haskellResolver nixpkgsResolver missingDeps flags (GenericPackageDescription {..}) (PackageDescription {..}) = normalize $ postProcess $ nullDerivation & isLibrary .~ isJust library & pkgid .~ package & revision .~ xrev @@ -125,10 +125,10 @@ fromPackageDescription haskellResolver nixpkgsResolver missingDeps flags Package & isExecutable .~ not (null executables) & extraFunctionArgs .~ mempty & extraAttributes .~ mempty - & libraryDepends .~ deps libBuildInfo (maybeToList library ++ subLibraries) - & executableDepends .~ deps buildInfo executables - & testDepends .~ deps testBuildInfo testSuites - & benchmarkDepends .~ deps benchmarkBuildInfo benchmarks + & libraryDepends .~ deps libBuildInfo (maybeToList condLibrary ++ fmap snd condSubLibraries) + & executableDepends .~ deps buildInfo (fmap snd condExecutables) + & testDepends .~ deps testBuildInfo (fmap snd condTestSuites) + & benchmarkDepends .~ deps benchmarkBuildInfo (fmap snd condBenchmarks) & Nix.setupDepends .~ maybe mempty convertSetupBuildInfo setupBuildInfo & configureFlags .~ mempty & cabalFlags .~ flags @@ -164,8 +164,8 @@ fromPackageDescription haskellResolver nixpkgsResolver missingDeps flags Package & Nix.broken .~ not (null missingDeps) ) where - deps :: (a -> Cabal.BuildInfo) -> [a] -> [(Nix.BuildInfo, Bool)] - deps getBuildInfo = map (convertBuildInfo . getBuildInfo) + deps :: Functor f => (a -> Cabal.BuildInfo) -> [f a] -> [f (Nix.BuildInfo, Bool)] + deps getBuildInfo = (fmap . fmap) (convertBuildInfo . getBuildInfo) xrev = maybe 0 read (lookup "x-revision" customFieldsPD) diff --git a/cabal2nix/src/Distribution/Nixpkgs/Haskell/FromCabal/Normalize.hs b/cabal2nix/src/Distribution/Nixpkgs/Haskell/FromCabal/Normalize.hs index a0fbc7e5a..9e6e6c9bf 100644 --- a/cabal2nix/src/Distribution/Nixpkgs/Haskell/FromCabal/Normalize.hs +++ b/cabal2nix/src/Distribution/Nixpkgs/Haskell/FromCabal/Normalize.hs @@ -10,6 +10,7 @@ import Distribution.Nixpkgs.Haskell import Distribution.Nixpkgs.Haskell.FromCabal.Name (toNixName) import Distribution.Nixpkgs.Meta import Distribution.Package +import Distribution.PackageDescription (CondTree, ConfVar) import Language.Nix hiding ( quote ) normalize :: Derivation -> Derivation @@ -21,7 +22,7 @@ normalize drv = drv & over metaSection normalizeMeta & jailbreak %~ (&& (packageName drv /= "jailbreak-cabal")) where - deps :: Lens' Derivation [(BuildInfo, Bool)] -> Derivation -> Derivation + deps :: Lens' Derivation [CondTree ConfVar [Dependency] (BuildInfo, Bool)] -> Derivation -> Derivation deps f = over (focusBuildInfo f) $ normalizeBuildInfo (packageName drv) normalizeBuildInfo :: PackageName -> BuildInfo -> BuildInfo diff --git a/cabal2nix/src/Distribution/Nixpkgs/Haskell/FromCabal/PostProcess.hs b/cabal2nix/src/Distribution/Nixpkgs/Haskell/FromCabal/PostProcess.hs index 8fcd1ef26..453957eb9 100644 --- a/cabal2nix/src/Distribution/Nixpkgs/Haskell/FromCabal/PostProcess.hs +++ b/cabal2nix/src/Distribution/Nixpkgs/Haskell/FromCabal/PostProcess.hs @@ -14,6 +14,7 @@ import Distribution.Nixpkgs.Haskell import Distribution.Nixpkgs.Meta import Distribution.Nixpkgs.License import Distribution.Package +import Distribution.PackageDescription (CondTree, ConfVar) import Distribution.Types.PackageVersionConstraint import Distribution.Text import Distribution.Version @@ -59,7 +60,7 @@ fixGtkBuilds drv = drv & dependencies . pkgconfig %~ Set.filter (not . collidesW fixBuildDependsForTools :: Derivation -> Derivation fixBuildDependsForTools = foldr (.) id $ fmap go [ testDepends, benchmarkDepends ] where - go :: ALens' Derivation [(BuildInfo, Bool)] -> Derivation -> Derivation + go :: ALens' Derivation [CondTree ConfVar [Dependency] (BuildInfo, Bool)] -> Derivation -> Derivation go c drv = over (l . tool) (Set.union needed) drv where From a998d790539861ece8685f2c63e95704bd065d58 Mon Sep 17 00:00:00 2001 From: Alexandre Esteves Date: Sat, 11 Apr 2026 18:56:46 +0100 Subject: [PATCH 7/8] Cleanup --- .../Nixpkgs/Haskell/Derivation.hs | 20 ++++++++++--------- .../Nixpkgs/Haskell/FromCabal/Normalize.hs | 3 +-- .../Nixpkgs/Haskell/FromCabal/PostProcess.hs | 3 +-- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/cabal2nix/src/Distribution/Nixpkgs/Haskell/Derivation.hs b/cabal2nix/src/Distribution/Nixpkgs/Haskell/Derivation.hs index 2569d6441..82b95e1be 100644 --- a/cabal2nix/src/Distribution/Nixpkgs/Haskell/Derivation.hs +++ b/cabal2nix/src/Distribution/Nixpkgs/Haskell/Derivation.hs @@ -10,7 +10,7 @@ module Distribution.Nixpkgs.Haskell.Derivation ( FinalizedDerivation(..), finalized_compiler, finalized_derivation, finalized_flags, finalized_platform , Derivation, nullDerivation, pkgid, revision, src, subpath, isLibrary, isExecutable - , extraFunctionArgs, libraryDepends, executableDepends, testDepends, configureFlags + , Component, Components, extraFunctionArgs, libraryDepends, executableDepends, testDepends, configureFlags , cabalFlags, runHaddock, jailbreak, doCheck, doBenchmark, testFlags, testTargets, hyperlinkSource , enableLibraryProfiling, enableExecutableProfiling, phaseOverrides, editedCabalFile, metaSection , dependencies, setupDepends, benchmarkDepends, enableSeparateDataOutput, extraAttributes @@ -56,6 +56,8 @@ data FinalizedDerivation = FinalizedDerivation , _finalized_derivation :: Derivation } +type Components = [Component] +type Component = CondTree ConfVar [Dependency] (BuildInfo, Bool) data Derivation = MkDerivation { _pkgid :: PackageIdentifier , _revision :: Int @@ -66,10 +68,10 @@ data Derivation = MkDerivation , _extraFunctionArgs :: Set Binding , _extraAttributes :: Map String String , _setupDepends :: BuildInfo - , _libraryDepends :: [CondTree ConfVar [Dependency] (BuildInfo, Bool)] - , _executableDepends :: [CondTree ConfVar [Dependency] (BuildInfo, Bool)] - , _testDepends :: [CondTree ConfVar [Dependency] (BuildInfo, Bool)] - , _benchmarkDepends :: [CondTree ConfVar [Dependency] (BuildInfo, Bool)] + , _libraryDepends :: Components + , _executableDepends :: Components + , _testDepends :: Components + , _benchmarkDepends :: Components , _configureFlags :: Set String , _cabalFlags :: FlagAssignment , _runHaddock :: Bool @@ -130,7 +132,7 @@ dependencies :: Traversal' Derivation BuildInfo dependencies = traversal $ \focus drv -> liftA2 (set setupDepends) (focus $ view setupDepends drv) ((nonSetupDependencies . traverse . traverse . _1) focus drv) -focusBuildInfo :: Lens' Derivation [CondTree ConfVar [Dependency] (BuildInfo, Bool)] -> Traversal' Derivation BuildInfo +focusBuildInfo :: Lens' Derivation Components -> Traversal' Derivation BuildInfo focusBuildInfo l = l . traverse . traverse . _1 instance Package Derivation where @@ -190,17 +192,17 @@ instance Pretty FinalizedDerivation where postUnpack = string $ "sourceRoot+=/" ++ _subpath ++ "; echo source root reset to $sourceRoot" - eval :: CondTree ConfVar c (BuildInfo, Bool) -> BuildInfo + eval :: Component -> BuildInfo eval = fold . evalTree - evalTree :: CondTree ConfVar c (BuildInfo, Bool) -> Maybe BuildInfo + evalTree :: Component -> Maybe BuildInfo evalTree (CondNode (bi, buildable) _ branches) = case buildable of False -> Nothing True -> do bs <- traverse evalBranch branches pure $ fold $ bi : bs - evalBranch :: CondBranch ConfVar c (BuildInfo, Bool) -> Maybe BuildInfo + evalBranch :: CondBranch ConfVar [Dependency] (BuildInfo, Bool) -> Maybe BuildInfo evalBranch (CondBranch c t mf) = if evalCondition c then evalTree t diff --git a/cabal2nix/src/Distribution/Nixpkgs/Haskell/FromCabal/Normalize.hs b/cabal2nix/src/Distribution/Nixpkgs/Haskell/FromCabal/Normalize.hs index 9e6e6c9bf..10f69180d 100644 --- a/cabal2nix/src/Distribution/Nixpkgs/Haskell/FromCabal/Normalize.hs +++ b/cabal2nix/src/Distribution/Nixpkgs/Haskell/FromCabal/Normalize.hs @@ -10,7 +10,6 @@ import Distribution.Nixpkgs.Haskell import Distribution.Nixpkgs.Haskell.FromCabal.Name (toNixName) import Distribution.Nixpkgs.Meta import Distribution.Package -import Distribution.PackageDescription (CondTree, ConfVar) import Language.Nix hiding ( quote ) normalize :: Derivation -> Derivation @@ -22,7 +21,7 @@ normalize drv = drv & over metaSection normalizeMeta & jailbreak %~ (&& (packageName drv /= "jailbreak-cabal")) where - deps :: Lens' Derivation [CondTree ConfVar [Dependency] (BuildInfo, Bool)] -> Derivation -> Derivation + deps :: Lens' Derivation Components -> Derivation -> Derivation deps f = over (focusBuildInfo f) $ normalizeBuildInfo (packageName drv) normalizeBuildInfo :: PackageName -> BuildInfo -> BuildInfo diff --git a/cabal2nix/src/Distribution/Nixpkgs/Haskell/FromCabal/PostProcess.hs b/cabal2nix/src/Distribution/Nixpkgs/Haskell/FromCabal/PostProcess.hs index 453957eb9..9f8770eee 100644 --- a/cabal2nix/src/Distribution/Nixpkgs/Haskell/FromCabal/PostProcess.hs +++ b/cabal2nix/src/Distribution/Nixpkgs/Haskell/FromCabal/PostProcess.hs @@ -14,7 +14,6 @@ import Distribution.Nixpkgs.Haskell import Distribution.Nixpkgs.Meta import Distribution.Nixpkgs.License import Distribution.Package -import Distribution.PackageDescription (CondTree, ConfVar) import Distribution.Types.PackageVersionConstraint import Distribution.Text import Distribution.Version @@ -60,7 +59,7 @@ fixGtkBuilds drv = drv & dependencies . pkgconfig %~ Set.filter (not . collidesW fixBuildDependsForTools :: Derivation -> Derivation fixBuildDependsForTools = foldr (.) id $ fmap go [ testDepends, benchmarkDepends ] where - go :: ALens' Derivation [CondTree ConfVar [Dependency] (BuildInfo, Bool)] -> Derivation -> Derivation + go :: ALens' Derivation Components -> Derivation -> Derivation go c drv = over (l . tool) (Set.union needed) drv where From b7db615f75fe1d9ce62fa8cc4b39648b35f8873a Mon Sep 17 00:00:00 2001 From: Alexandre Esteves Date: Sun, 12 Apr 2026 02:35:28 +0100 Subject: [PATCH 8/8] Preserve component names until pretty-printing --- .../src/Distribution/Nixpkgs/Haskell/Derivation.hs | 10 +++++----- .../src/Distribution/Nixpkgs/Haskell/FromCabal.hs | 13 +++++++------ 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/cabal2nix/src/Distribution/Nixpkgs/Haskell/Derivation.hs b/cabal2nix/src/Distribution/Nixpkgs/Haskell/Derivation.hs index 82b95e1be..dd71d9e30 100644 --- a/cabal2nix/src/Distribution/Nixpkgs/Haskell/Derivation.hs +++ b/cabal2nix/src/Distribution/Nixpkgs/Haskell/Derivation.hs @@ -38,7 +38,7 @@ import Distribution.Nixpkgs.Haskell.BuildInfo import Distribution.Nixpkgs.Haskell.OrphanInstances ( ) import Distribution.Nixpkgs.Meta import Distribution.Package -import Distribution.PackageDescription (CondBranch (..), CondTree (..), Condition (..), ConfVar (..), FlagAssignment, FlagName, lookupFlagAssignment, unFlagAssignment, unFlagName) +import Distribution.PackageDescription (CondBranch (..), CondTree (..), Condition (..), ConfVar (..), FlagAssignment, FlagName, UnqualComponentName, lookupFlagAssignment, unFlagAssignment, unFlagName) import Distribution.System (Platform (..)) import GHC.Generics ( Generic ) import Language.Nix @@ -56,7 +56,7 @@ data FinalizedDerivation = FinalizedDerivation , _finalized_derivation :: Derivation } -type Components = [Component] +type Components = [(Maybe UnqualComponentName, Component)] type Component = CondTree ConfVar [Dependency] (BuildInfo, Bool) data Derivation = MkDerivation { _pkgid :: PackageIdentifier @@ -130,10 +130,10 @@ makeLensesFor (fmap (,"nonSetupDependencies") ["_libraryDepends", "_executableDe dependencies :: Traversal' Derivation BuildInfo dependencies = traversal $ \focus drv -> - liftA2 (set setupDepends) (focus $ view setupDepends drv) ((nonSetupDependencies . traverse . traverse . _1) focus drv) + liftA2 (set setupDepends) (focus $ view setupDepends drv) ((nonSetupDependencies . traverse . _2 . traverse . _1) focus drv) focusBuildInfo :: Lens' Derivation Components -> Traversal' Derivation BuildInfo -focusBuildInfo l = l . traverse . traverse . _1 +focusBuildInfo l = l . traverse . _2 . traverse . _1 instance Package Derivation where packageId = view pkgid @@ -183,7 +183,7 @@ instance Pretty FinalizedDerivation where Just derivKind' -> Set.fromList [derivKindFunction derivKind' | not isHackagePackage] ] - (lib, exe, test, bench) = over each (foldMap eval) + (lib, exe, test, bench) = over each (foldMap $ eval . snd) (_libraryDepends, _executableDepends, _testDepends, _benchmarkDepends) renderedFlags = [ text "-f" <> (if enable then empty else char '-') <> text (unFlagName f) | (f, enable) <- unFlagAssignment _cabalFlags ] diff --git a/cabal2nix/src/Distribution/Nixpkgs/Haskell/FromCabal.hs b/cabal2nix/src/Distribution/Nixpkgs/Haskell/FromCabal.hs index da868dc06..4e6d5eb69 100644 --- a/cabal2nix/src/Distribution/Nixpkgs/Haskell/FromCabal.hs +++ b/cabal2nix/src/Distribution/Nixpkgs/Haskell/FromCabal.hs @@ -9,6 +9,7 @@ module Distribution.Nixpkgs.Haskell.FromCabal ) where import Control.Lens +import Data.Bifunctor import Data.Maybe import Data.Set ( Set ) import qualified Data.Set as Set @@ -125,10 +126,10 @@ fromPackageDescription haskellResolver nixpkgsResolver missingDeps flags (Generi & isExecutable .~ not (null executables) & extraFunctionArgs .~ mempty & extraAttributes .~ mempty - & libraryDepends .~ deps libBuildInfo (maybeToList condLibrary ++ fmap snd condSubLibraries) - & executableDepends .~ deps buildInfo (fmap snd condExecutables) - & testDepends .~ deps testBuildInfo (fmap snd condTestSuites) - & benchmarkDepends .~ deps benchmarkBuildInfo (fmap snd condBenchmarks) + & libraryDepends .~ deps libBuildInfo (maybeToList (fmap (Nothing,) condLibrary) ++ fmap (first Just) condSubLibraries) + & executableDepends .~ deps buildInfo (fmap (first Just) condExecutables) + & testDepends .~ deps testBuildInfo (fmap (first Just) condTestSuites) + & benchmarkDepends .~ deps benchmarkBuildInfo (fmap (first Just) condBenchmarks) & Nix.setupDepends .~ maybe mempty convertSetupBuildInfo setupBuildInfo & configureFlags .~ mempty & cabalFlags .~ flags @@ -164,8 +165,8 @@ fromPackageDescription haskellResolver nixpkgsResolver missingDeps flags (Generi & Nix.broken .~ not (null missingDeps) ) where - deps :: Functor f => (a -> Cabal.BuildInfo) -> [f a] -> [f (Nix.BuildInfo, Bool)] - deps getBuildInfo = (fmap . fmap) (convertBuildInfo . getBuildInfo) + deps :: Functor f => (a -> Cabal.BuildInfo) -> [(Maybe name, f a)] -> [(Maybe name, f (Nix.BuildInfo, Bool))] + deps getBuildInfo = (fmap . second . fmap) (convertBuildInfo . getBuildInfo) xrev = maybe 0 read (lookup "x-revision" customFieldsPD)