Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion cabal2nix/src/Cabal2nix.hs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion cabal2nix/src/Distribution/Nixpkgs/Haskell/BuildInfo.hs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
37 changes: 27 additions & 10 deletions cabal2nix/src/Distribution/Nixpkgs/Haskell/Derivation.hs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
{-# LANGUAGE CPP #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TupleSections #-}
{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses #-}

module Distribution.Nixpkgs.Haskell.Derivation
Expand All @@ -9,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 )
Expand Down Expand Up @@ -46,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
Expand Down Expand Up @@ -102,7 +109,14 @@ nullDerivation = MkDerivation

makeLenses ''Derivation

makeLensesFor [("_setupDepends", "dependencies"), ("_libraryDepends", "dependencies"), ("_executableDepends", "dependencies"), ("_testDepends", "dependencies"), ("_benchmarkDepends", "dependencies")] ''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
Expand All @@ -123,11 +137,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
Expand All @@ -144,6 +158,9 @@ instance Pretty Derivation where
, rbrace
]
where
pPrintBuildInfo' :: String -> [(BuildInfo, Bool)] -> Doc
pPrintBuildInfo' name = pPrintBuildInfo name . foldMap fst . filter snd
Copy link
Copy Markdown
Member Author

@alexfmpe alexfmpe Mar 19, 2026

Choose a reason for hiding this comment

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

The filter snd coincidentally doesn't seem to have effect due to the way finalizePD works (see below comment), but I think it'd be very confusing not having it


inputs :: Set String
inputs = Set.unions [ Set.map (view (localName . ident)) _extraFunctionArgs
, setOf (dependencies . each . folded . localName . ident) drv
Expand Down
17 changes: 10 additions & 7 deletions cabal2nix/src/Distribution/Nixpkgs/Haskell/FromCabal.hs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{-# LANGUAGE CPP #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE TupleSections #-}

module Distribution.Nixpkgs.Haskell.FromCabal
( HaskellResolver, NixpkgsResolver
Expand Down Expand Up @@ -124,10 +125,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
Expand Down Expand Up @@ -163,6 +164,9 @@ 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)

xrev = maybe 0 read (lookup "x-revision" customFieldsPD)

nixLicense :: Nix.License
Expand Down Expand Up @@ -208,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
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Surprisingly this line seems to have no effect, because finalizePD silently drops buildable: false components

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) ]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RankNTypes #-}

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
Expand All @@ -13,12 +14,15 @@ 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 :: Lens' Derivation [(BuildInfo, Bool)] -> Derivation -> Derivation
deps f = over (focusBuildInfo f) $ normalizeBuildInfo (packageName drv)

normalizeBuildInfo :: PackageName -> BuildInfo -> BuildInfo
normalizeBuildInfo pname bi = bi
Expand Down
Loading
Loading