From 3307042c3c5ef024a9d3d1e3030a3ae654f863d6 Mon Sep 17 00:00:00 2001 From: Marc Jakobi Date: Wed, 29 May 2024 09:04:06 +0200 Subject: [PATCH 01/18] refactor: extract SingleDerivation --- cabal2nix/hackage2nix/Main.hs | 26 ++- cabal2nix/src/Cabal2nix.hs | 50 ++--- .../Nixpkgs/Haskell/Derivation.hs | 73 +++++-- .../Distribution/Nixpkgs/Haskell/FromCabal.hs | 190 +++++++++++++----- cabal2nix/test/Main.hs | 23 ++- 5 files changed, 251 insertions(+), 111 deletions(-) diff --git a/cabal2nix/hackage2nix/Main.hs b/cabal2nix/hackage2nix/Main.hs index 5c0b7f643..b02d3aee3 100644 --- a/cabal2nix/hackage2nix/Main.hs +++ b/cabal2nix/hackage2nix/Main.hs @@ -155,18 +155,22 @@ main = do attr :: String attr = if isInDefaultPackageSet then unPackageName name else mangle pkgId + overrideDrv :: Derivation -> Derivation + overrideDrv drv' = drv' + & 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 :: 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 = drvFromGenericPackageDescription overrideDrv haskellResolver nixpkgsResolver targetPlatform (compilerInfo config) flagAssignment [] descr + ^. derivation 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 47799be1b..1eb4ebaa1 100644 --- a/cabal2nix/src/Cabal2nix.hs +++ b/cabal2nix/src/Cabal2nix.hs @@ -173,7 +173,7 @@ hpackOverrides :: Derivation -> Derivation hpackOverrides = over phaseOverrides (++ "prePatch = \"hpack\";") . set (libraryDepends . tool . contains (PP.pkg "hpack")) True -cabal2nix' :: Options -> IO (Either Doc Derivation) +cabal2nix' :: Options -> IO (Either Doc SingleDerivation) cabal2nix' opts@Options{..} = do pkg <- getPackage optHpack optFetchSubmodules optHackageDb optHackageSnapshot $ Source { @@ -186,7 +186,7 @@ cabal2nix' opts@Options{..} = do } processPackage opts pkg -cabal2nixWithDB :: DB.HackageDB -> Options -> IO (Either Doc Derivation) +cabal2nixWithDB :: DB.HackageDB -> Options -> IO (Either Doc SingleDerivation) cabal2nixWithDB db opts@Options{..} = do when (isJust optHackageDb) $ hPutStrLn stderr "WARN: HackageDB provided directly; ignoring --hackage-db" when (isJust optHackageSnapshot) $ hPutStrLn stderr "WARN: HackageDB provided directly; ignoring --hackage-snapshot" @@ -201,7 +201,7 @@ cabal2nixWithDB db opts@Options{..} = do } processPackage opts pkg -processPackage :: Options -> Package -> IO (Either Doc Derivation) +processPackage :: Options -> Package -> IO (Either Doc SingleDerivation) processPackage Options{..} pkg = do let withHpackOverrides :: Derivation -> Derivation @@ -210,26 +210,30 @@ processPackage Options{..} pkg = do flags :: FlagAssignment flags = configureCabalFlags (packageId (pkgCabal pkg)) `mappend` readFlagList optFlags - deriv :: Derivation - deriv = withHpackOverrides $ fromGenericPackageDescription (const True) - optNixpkgsIdentifier - optSystem - (unknownCompilerInfo optCompiler NoAbiTag) - flags - [] - (pkgCabal pkg) - & src .~ pkgSource pkg - & subpath .~ fromMaybe "." optSubpath - & runHaddock %~ (optHaddock &&) - & jailbreak .~ optJailbreak - & hyperlinkSource .~ optHyperlinkSource - & enableLibraryProfiling .~ (fromMaybe False optEnableProfiling || optEnableLibraryProfiling) - & enableExecutableProfiling .~ (fromMaybe False optEnableProfiling || optEnableExecutableProfiling) - & metaSection.maintainers .~ Set.fromList (map (review ident) optMaintainer) --- & metaSection.platforms .~ Set.fromList optPlatform - & doCheck &&~ optDoCheck - & doBenchmark ||~ optDoBenchmark - & extraFunctionArgs %~ Set.union (Set.fromList ("inherit lib":map (fromString . ("inherit " ++)) optExtraArgs)) + overrideDrv :: Derivation -> Derivation + overrideDrv drv = withHpackOverrides $ drv + & src .~ pkgSource pkg + & subpath .~ fromMaybe "." optSubpath + & runHaddock %~ (optHaddock &&) + & jailbreak .~ optJailbreak + & hyperlinkSource .~ optHyperlinkSource + & enableLibraryProfiling .~ (fromMaybe False optEnableProfiling || optEnableLibraryProfiling) + & enableExecutableProfiling .~ (fromMaybe False optEnableProfiling || optEnableExecutableProfiling) + & metaSection.maintainers .~ Set.fromList (map (review ident) optMaintainer) + -- & metaSection.platforms .~ Set.fromList optPlatform + & doCheck &&~ optDoCheck + & doBenchmark ||~ optDoBenchmark + & extraFunctionArgs %~ Set.union (Set.fromList ("inherit lib":map (fromString . ("inherit " ++)) optExtraArgs)) + + deriv :: SingleDerivation + deriv = drvFromGenericPackageDescription overrideDrv + (const True) + optNixpkgsIdentifier + optSystem + (unknownCompilerInfo optCompiler NoAbiTag) + flags + [] + (pkgCabal pkg) shell :: Doc shell = vcat diff --git a/cabal2nix/src/Distribution/Nixpkgs/Haskell/Derivation.hs b/cabal2nix/src/Distribution/Nixpkgs/Haskell/Derivation.hs index aa489f6cf..345342843 100644 --- a/cabal2nix/src/Distribution/Nixpkgs/Haskell/Derivation.hs +++ b/cabal2nix/src/Distribution/Nixpkgs/Haskell/Derivation.hs @@ -4,11 +4,14 @@ {-# LANGUAGE FlexibleInstances, MultiParamTypeClasses #-} module Distribution.Nixpkgs.Haskell.Derivation - ( Derivation, nullDerivation, pkgid, revision, src, subpath, isLibrary, isExecutable + ( Derivation, SingleDerivation + , derivation, nullSingleDerivation + , nullDerivation, pkgid, revision, src, subpath, isLibrary, isExecutable , extraFunctionArgs, libraryDepends, executableDepends, testDepends, configureFlags - , cabalFlags, runHaddock, jailbreak, doCheck, doBenchmark, testTarget, hyperlinkSource, enableSplitObjs - , enableLibraryProfiling, enableExecutableProfiling, phaseOverrides, editedCabalFile, metaSection - , dependencies, setupDepends, benchmarkDepends, enableSeparateDataOutput, extraAttributes + , cabalFlags, runHaddock, jailbreak, doCheck, doBenchmark, buildTarget, testTarget, hyperlinkSource + , enableSplitObjs , enableLibraryProfiling, enableExecutableProfiling, phaseOverrides + , editedCabalFile, metaSection , dependencies, setupDepends, benchmarkDepends, enableSeparateDataOutput + , extraAttributes ) where @@ -56,6 +59,7 @@ data Derivation = MkDerivation , _jailbreak :: Bool , _doCheck :: Bool , _doBenchmark :: Bool + , _buildTarget :: String , _testTarget :: String , _hyperlinkSource :: Bool , _enableLibraryProfiling :: Bool @@ -89,6 +93,7 @@ nullDerivation = MkDerivation , _jailbreak = error "undefined Derivation.jailbreak" , _doCheck = error "undefined Derivation.doCheck" , _doBenchmark = error "undefined Derivation.doBenchmark" + , _buildTarget = error "undefined Derivation.buildTarget" , _testTarget = error "undefined Derivation.testTarget" , _hyperlinkSource = error "undefined Derivation.hyperlinkSource" , _enableLibraryProfiling = error "undefined Derivation.enableLibraryProfiling" @@ -110,7 +115,7 @@ instance Package Derivation where instance NFData Derivation instance Pretty Derivation where - pPrint drv@MkDerivation {..} = funargs (map text ("mkDerivation" : toAscList inputs)) $$ vcat + pPrint MkDerivation {..} = vcat [ text "mkDerivation" <+> lbrace , nest 2 $ vcat [ attr "pname" $ doubleQuotes $ pPrint (packageName _pkgid) @@ -135,6 +140,7 @@ instance Pretty Derivation where , boolattr "jailbreak" _jailbreak _jailbreak , boolattr "doCheck" (not _doCheck) _doCheck , boolattr "doBenchmark" _doBenchmark _doBenchmark + , onlyIf (not (null _buildTarget)) $ attr "buildTarget" $ string _buildTarget , onlyIf (not (null _testTarget)) $ attr "testTarget" $ string _testTarget , boolattr "hyperlinkSource" (not _hyperlinkSource) _hyperlinkSource , onlyIf (not (null _phaseOverrides)) $ vcat ((map text . lines) _phaseOverrides) @@ -144,16 +150,55 @@ instance Pretty Derivation where , rbrace ] where - inputs :: Set String - inputs = Set.unions [ Set.map (view (localName . ident)) _extraFunctionArgs - , setOf (dependencies . each . folded . localName . ident) drv - , case derivKind _src of - Nothing -> mempty - Just derivKind' -> Set.fromList [derivKindFunction derivKind' | not isHackagePackage] - ] - 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" + +inputs :: Derivation -> Set String +inputs drv@MkDerivation {..} = Set.unions + [ Set.map (view (localName . ident)) _extraFunctionArgs + , setOf (dependencies . each . folded . localName . ident) drv + , case derivKind _src of + Nothing -> mempty + Just derivKind' -> Set.fromList [derivKindFunction derivKind' | not isHackagePackage] + ] + where + isHackagePackage = "mirror://hackage/" `isPrefixOf` derivUrl _src + +newtype SingleDerivation = SingleDerivation + { _derivation :: Derivation } + deriving (Show, Generic) + +makeLenses ''SingleDerivation + +nullSingleDerivation :: SingleDerivation +nullSingleDerivation = SingleDerivation + { _derivation = error "undefined SingleDerivation.derivation" + } + +instance NFData SingleDerivation + +instance Pretty SingleDerivation where + pPrint SingleDerivation {..} = funargs (map text ("mkDerivation" : toAscList (inputs _derivation))) $$ + pPrint _derivation + +-- data DefaultNix +-- = SingleDerivation +-- { _derivation :: Derivation } +-- | ComponentDerivations +-- { _libraries :: [Derivation] +-- , _executables :: [Derivation] +-- , _testExecutables :: [Derivation] +-- , _benchExecutables :: [Derivation] +-- } +-- deriving (Show, Generic) +-- +-- makeLenses ''DefaultNix +-- +-- instance NFData DefaultNix +-- +-- -- instance Pretty DefaultNix where +-- -- pPrint drv@ComponentDerivations {..} = funargs (map text ("mkDerivation" : toAscList inputs)) $$ vcat +-- +-- diff --git a/cabal2nix/src/Distribution/Nixpkgs/Haskell/FromCabal.hs b/cabal2nix/src/Distribution/Nixpkgs/Haskell/FromCabal.hs index 7f278b593..ccdad9b99 100644 --- a/cabal2nix/src/Distribution/Nixpkgs/Haskell/FromCabal.hs +++ b/cabal2nix/src/Distribution/Nixpkgs/Haskell/FromCabal.hs @@ -4,7 +4,7 @@ module Distribution.Nixpkgs.Haskell.FromCabal ( HaskellResolver, NixpkgsResolver - , fromGenericPackageDescription , finalizeGenericPackageDescription , fromPackageDescription + , drvFromGenericPackageDescription , finalizeGenericPackageDescription , fromPackageDescription ) where import Control.Lens @@ -36,13 +36,29 @@ import Distribution.Types.UnqualComponentName as Cabal import Distribution.Utils.ShortText ( fromShortText ) import Distribution.Version import Language.Nix +import Distribution.Nixpkgs.Fetch (DerivKind(DerivKindHg)) +import Text.PrettyPrint (render) 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 = - fromPackageDescription haskellResolver nixpkgsResolver missingDeps flags descr +data OutputGranularity + = SingleDerivation + -- One derivation per component, where libraries are not excluded from executables' libraryDepends + | PerComponent + +drvFromGenericPackageDescription + :: (Derivation -> Derivation) + -> HaskellResolver + -> NixpkgsResolver + -> Platform + -> CompilerInfo + -> FlagAssignment + -> [Constraint] + -> GenericPackageDescription + -> SingleDerivation +drvFromGenericPackageDescription overrideDrv haskellResolver nixpkgsResolver arch compiler flags constraints genDesc = + fromPackageDescription overrideDrv haskellResolver nixpkgsResolver missingDeps flags descr where (descr, missingDeps) = finalizeGenericPackageDescription haskellResolver arch compiler flags constraints genDesc @@ -92,54 +108,116 @@ finalizeGenericPackageDescription haskellResolver arch compiler flags constraint Right (d,_) -> (d,m) Right (d,_) -> (d,[]) -fromPackageDescription :: HaskellResolver -> NixpkgsResolver -> [Dependency] -> FlagAssignment -> PackageDescription -> Derivation -fromPackageDescription haskellResolver nixpkgsResolver missingDeps flags PackageDescription {..} = normalize $ postProcess $ nullDerivation - & isLibrary .~ isJust library - & pkgid .~ package - & revision .~ xrev - & isLibrary .~ isJust library - & 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) - & Nix.setupDepends .~ maybe mempty convertSetupBuildInfo setupBuildInfo - & configureFlags .~ mempty - & cabalFlags .~ flags - & runHaddock .~ doHaddockPhase - & jailbreak .~ False - & doCheck .~ True - & doBenchmark .~ False - & testTarget .~ mempty - & hyperlinkSource .~ True - & enableSplitObjs .~ True - & enableLibraryProfiling .~ False - & enableExecutableProfiling .~ False - & enableSeparateDataOutput .~ not (null dataFiles) - & subpath .~ "." - & phaseOverrides .~ mempty - & editedCabalFile .~ (if xrev > 0 - then fromMaybe (error (display package ++ ": X-Cabal-File-Hash field is missing")) (lookup "X-Cabal-File-Hash" customFieldsPD) - else "") - & metaSection .~ ( Nix.nullMeta +fromPackageDescription + :: (Derivation -> Derivation) + -> HaskellResolver + -> NixpkgsResolver + -> [Dependency] + -> FlagAssignment + -> PackageDescription + -> SingleDerivation +fromPackageDescription overrideDrv haskellResolver nixpkgsResolver missingDeps flags PackageDescription {..} = singleDerivation + where + singleDerivation :: SingleDerivation + singleDerivation = nullSingleDerivation & derivation .~ overrideDrv (normalize $ postProcess $ baseDerivation + & isLibrary .~ isJust library + & isExecutable .~ not (null executables) + & libraryDepends .~ foldMap (convertSingleDerivationBuildInfo . libBuildInfo) allLibraries + & executableDepends .~ mconcat (map (convertSingleDerivationBuildInfo . buildInfo) executables) + & testDepends .~ mconcat (map (convertSingleDerivationBuildInfo . testBuildInfo) testSuites) + & benchmarkDepends .~ mconcat (map (convertSingleDerivationBuildInfo . benchmarkBuildInfo) benchmarks)) + + libraryDerivations :: [Derivation] + libraryDerivations = fmap (normalize . postProcess . toLibraryDerivation) allLibraries + + executableDerivations :: [Derivation] + executableDerivations = fmap (normalize . postProcess . toExecutableDerivation) executables + + testDerivations :: [Derivation] + testDerivations = fmap (normalize . postProcess . toTestDerivation) testSuites + + benchDerivations :: [Derivation] + benchDerivations = fmap (normalize . postProcess . toBenchDerivation) benchmarks + + toLibraryDerivation :: Library -> Derivation + toLibraryDerivation lib = baseDerivation + & pkgid .~ case libName lib of + LMainLibName -> baseDerivation^.pkgid + LSubLibName subLibName -> (baseDerivation^.pkgid) { pkgName = unqualComponentNameToPackageName subLibName } + & isLibrary .~ True + & isExecutable .~ False + & libraryDepends .~ convertComponentDerivationBuildInfo (libBuildInfo lib) + & buildTarget .~ render (prettyLibraryNameComponent $ libName lib) + + toExecutableDerivation :: Executable -> Derivation + toExecutableDerivation executable = baseDerivation + & pkgid .~ (baseDerivation^.pkgid) { pkgName = unqualComponentNameToPackageName (exeName executable) } + & isLibrary .~ False + & isExecutable .~ True + & executableDepends .~ convertComponentDerivationBuildInfo (buildInfo executable) + & buildTarget .~ unUnqualComponentName (exeName executable) + + toTestDerivation :: TestSuite -> Derivation + toTestDerivation testSuite = baseDerivation + & pkgid .~ (baseDerivation^.pkgid) { pkgName = unqualComponentNameToPackageName (testName testSuite) } + & isLibrary .~ False + & isExecutable .~ True + & testDepends .~ convertComponentDerivationBuildInfo (testBuildInfo testSuite) + & buildTarget .~ unUnqualComponentName (testName testSuite) + + toBenchDerivation :: Benchmark -> Derivation + toBenchDerivation benchmark = baseDerivation + & pkgid .~ (baseDerivation^.pkgid) { pkgName = unqualComponentNameToPackageName (benchmarkName benchmark) } + & isLibrary .~ False + & isExecutable .~ True + & doBenchmark .~ True + & benchmarkDepends .~ convertComponentDerivationBuildInfo (benchmarkBuildInfo benchmark) + & buildTarget .~ unUnqualComponentName (benchmarkName benchmark) + + baseDerivation :: Derivation + baseDerivation = nullDerivation + & pkgid .~ package + & revision .~ xrev + & extraFunctionArgs .~ mempty + & extraAttributes .~ mempty + & Nix.setupDepends .~ maybe mempty convertSetupBuildInfo setupBuildInfo + & configureFlags .~ mempty + & cabalFlags .~ flags + & runHaddock .~ doHaddockPhase + & jailbreak .~ False + & doCheck .~ True + & doBenchmark .~ False + & buildTarget .~ mempty + & testTarget .~ mempty + & hyperlinkSource .~ True + & enableSplitObjs .~ True + & enableLibraryProfiling .~ False + & enableExecutableProfiling .~ False + & enableSeparateDataOutput .~ not (null dataFiles) + & subpath .~ "." + & phaseOverrides .~ mempty + & editedCabalFile .~ (if xrev > 0 + then fromMaybe (error (display package ++ ": X-Cabal-File-Hash field is missing")) (lookup "X-Cabal-File-Hash" customFieldsPD) + else "") + & metaSection .~ ( Nix.nullMeta #if MIN_VERSION_Cabal(3,2,0) - & Nix.homepage .~ stripRedundanceSpaces (fromShortText homepage) - & Nix.description .~ stripRedundanceSpaces (fromShortText synopsis) + & Nix.homepage .~ stripRedundanceSpaces (fromShortText homepage) + & Nix.description .~ stripRedundanceSpaces (fromShortText synopsis) #else - & Nix.homepage .~ stripRedundanceSpaces homepage - & Nix.description .~ stripRedundanceSpaces synopsis + & Nix.homepage .~ stripRedundanceSpaces homepage + & Nix.description .~ stripRedundanceSpaces synopsis #endif - & Nix.license .~ nixLicense - & Nix.platforms .~ Nothing - & Nix.badPlatforms .~ Nothing - & Nix.hydraPlatforms .~ (if isFreeLicense nixLicense then Nothing else Just Set.empty) - & Nix.mainProgram .~ nixMainProgram - & Nix.maintainers .~ mempty - & Nix.broken .~ not (null missingDeps) - ) - where + & Nix.license .~ nixLicense + & Nix.platforms .~ Nothing + & Nix.badPlatforms .~ Nothing + & Nix.hydraPlatforms .~ (if isFreeLicense nixLicense then Nothing else Just Set.empty) + & Nix.mainProgram .~ nixMainProgram + & Nix.maintainers .~ mempty + & Nix.broken .~ not (null missingDeps) + ) + + allLibraries = maybeToList library ++ subLibraries + xrev = maybe 0 read (lookup "x-revision" customFieldsPD) nixLicense :: Nix.License @@ -190,10 +268,16 @@ 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 - & haskell .~ Set.fromList [ resolveInHackage (toNixName x) | (Dependency x _ _) <- targetBuildDepends, x `notElem` internalLibNames ] + convertSingleDerivationBuildInfo :: Cabal.BuildInfo -> Nix.BuildInfo + convertSingleDerivationBuildInfo = convertBuildInfo (`notElem` internalLibNames) + + convertComponentDerivationBuildInfo :: Cabal.BuildInfo -> Nix.BuildInfo + convertComponentDerivationBuildInfo = convertBuildInfo $ const True + + convertBuildInfo :: (PackageName -> Bool) -> Cabal.BuildInfo -> Nix.BuildInfo + convertBuildInfo _ Cabal.BuildInfo {..} | not buildable = mempty + convertBuildInfo buildDependsFilterPredicate Cabal.BuildInfo {..} = mempty + & haskell .~ Set.fromList [ resolveInHackage (toNixName x) | (Dependency x _ _) <- targetBuildDepends, buildDependsFilterPredicate x ] & system .~ Set.fromList [ resolveInNixpkgs y | x <- extraLibs, y <- libNixName x ] & pkgconfig .~ Set.fromList [ resolveInNixpkgs y | PkgconfigDependency x _ <- pkgconfigDepends, y <- libNixName (unPkgconfigName x) ] & tool .~ Set.fromList (map resolveInHackageThenNixpkgs . concatMap buildToolNixName diff --git a/cabal2nix/test/Main.hs b/cabal2nix/test/Main.hs index d4a6e4e96..15e940c62 100644 --- a/cabal2nix/test/Main.hs +++ b/cabal2nix/test/Main.hs @@ -52,8 +52,19 @@ testLibrary cabalFile = do let nixFile = cabalFile `replaceExtension` "nix" goldenFile = nixFile `addExtension` "golden" - cabal2nix :: GenericPackageDescription -> Derivation - cabal2nix gpd = fromGenericPackageDescription + overrideDrv :: Derivation -> Derivation + overrideDrv drv = drv + & src .~ DerivationSource + { derivKind = Just (DerivKindUrl DontUnpackArchive ) + , derivUrl = "mirror://hackage/foo.tar.gz" + , derivRevision = "" + , derivHash = "deadbeef" + , derivSubmodule = Nothing + } + & extraFunctionArgs %~ Set.union (Set.singleton "inherit lib") + cabal2nix :: GenericPackageDescription -> SingleDerivation + cabal2nix gpd = drvFromGenericPackageDescription + overrideDrv (const True) (\i -> Just (binding # (i, path # [ident # "pkgs", i]))) (Platform X86_64 Linux) @@ -61,14 +72,6 @@ testLibrary cabalFile = do (configureCabalFlags (packageId gpd)) [] gpd - & src .~ DerivationSource - { derivKind = Just (DerivKindUrl DontUnpackArchive ) - , derivUrl = "mirror://hackage/foo.tar.gz" - , derivRevision = "" - , derivHash = "deadbeef" - , derivSubmodule = Nothing - } - & extraFunctionArgs %~ Set.union (Set.singleton "inherit lib") goldenVsFileDiff nixFile (\ref new -> ["diff", "-u", ref, new]) From 713f34512d627db850ee706998fdafab529608ce Mon Sep 17 00:00:00 2001 From: Marc Jakobi Date: Wed, 29 May 2024 10:38:00 +0200 Subject: [PATCH 02/18] feat: creat TargetDerivations and PackageNix --- cabal2nix/cabal2nix.cabal | 2 + cabal2nix/hackage2nix/Main.hs | 4 +- cabal2nix/src/Cabal2nix.hs | 10 ++-- cabal2nix/src/Distribution/Nixpkgs/Haskell.hs | 2 + .../Nixpkgs/Haskell/ComponentDerivations.hs | 32 ++++++++++ .../Nixpkgs/Haskell/Derivation.hs | 30 ++-------- .../Distribution/Nixpkgs/Haskell/FromCabal.hs | 30 +++++----- .../Nixpkgs/Haskell/PackageNix.hs | 43 +++++++++++++ .../Nixpkgs/Haskell/TargetDerivations.hs | 60 +++++++++++++++++++ cabal2nix/test/Main.hs | 5 +- 10 files changed, 170 insertions(+), 48 deletions(-) create mode 100644 cabal2nix/src/Distribution/Nixpkgs/Haskell/ComponentDerivations.hs create mode 100644 cabal2nix/src/Distribution/Nixpkgs/Haskell/PackageNix.hs create mode 100644 cabal2nix/src/Distribution/Nixpkgs/Haskell/TargetDerivations.hs diff --git a/cabal2nix/cabal2nix.cabal b/cabal2nix/cabal2nix.cabal index 4f03d3e83..52c2dd13a 100644 --- a/cabal2nix/cabal2nix.cabal +++ b/cabal2nix/cabal2nix.cabal @@ -44,7 +44,9 @@ library Distribution.Nixpkgs.Haskell.FromCabal.PostProcess Distribution.Nixpkgs.Haskell.Hackage Distribution.Nixpkgs.Haskell.OrphanInstances + Distribution.Nixpkgs.Haskell.PackageNix Distribution.Nixpkgs.Haskell.PackageSourceSpec + Distribution.Nixpkgs.Haskell.TargetDerivations Distribution.Nixpkgs.Haskell.Platform other-modules: Paths_cabal2nix hs-source-dirs: src diff --git a/cabal2nix/hackage2nix/Main.hs b/cabal2nix/hackage2nix/Main.hs index b02d3aee3..99634be8a 100644 --- a/cabal2nix/hackage2nix/Main.hs +++ b/cabal2nix/hackage2nix/Main.hs @@ -168,8 +168,8 @@ main = do & metaSection.maintainers .~ Map.findWithDefault Set.empty name globalPackageMaintainers & metaSection.homepage .~ "" - drv :: Derivation - drv = drvFromGenericPackageDescription overrideDrv haskellResolver nixpkgsResolver targetPlatform (compilerInfo config) flagAssignment [] descr + drv :: PackageNix + drv = fromGenericPackageDescription overrideDrv haskellResolver nixpkgsResolver targetPlatform (compilerInfo config) flagAssignment [] descr ^. derivation overrides :: Doc diff --git a/cabal2nix/src/Cabal2nix.hs b/cabal2nix/src/Cabal2nix.hs index 1eb4ebaa1..131ffbfaf 100644 --- a/cabal2nix/src/Cabal2nix.hs +++ b/cabal2nix/src/Cabal2nix.hs @@ -173,7 +173,7 @@ hpackOverrides :: Derivation -> Derivation hpackOverrides = over phaseOverrides (++ "prePatch = \"hpack\";") . set (libraryDepends . tool . contains (PP.pkg "hpack")) True -cabal2nix' :: Options -> IO (Either Doc SingleDerivation) +cabal2nix' :: Options -> IO (Either Doc PackageNix) cabal2nix' opts@Options{..} = do pkg <- getPackage optHpack optFetchSubmodules optHackageDb optHackageSnapshot $ Source { @@ -186,7 +186,7 @@ cabal2nix' opts@Options{..} = do } processPackage opts pkg -cabal2nixWithDB :: DB.HackageDB -> Options -> IO (Either Doc SingleDerivation) +cabal2nixWithDB :: DB.HackageDB -> Options -> IO (Either Doc PackageNix) cabal2nixWithDB db opts@Options{..} = do when (isJust optHackageDb) $ hPutStrLn stderr "WARN: HackageDB provided directly; ignoring --hackage-db" when (isJust optHackageSnapshot) $ hPutStrLn stderr "WARN: HackageDB provided directly; ignoring --hackage-snapshot" @@ -201,7 +201,7 @@ cabal2nixWithDB db opts@Options{..} = do } processPackage opts pkg -processPackage :: Options -> Package -> IO (Either Doc SingleDerivation) +processPackage :: Options -> Package -> IO (Either Doc PackageNix) processPackage Options{..} pkg = do let withHpackOverrides :: Derivation -> Derivation @@ -225,8 +225,8 @@ processPackage Options{..} pkg = do & doBenchmark ||~ optDoBenchmark & extraFunctionArgs %~ Set.union (Set.fromList ("inherit lib":map (fromString . ("inherit " ++)) optExtraArgs)) - deriv :: SingleDerivation - deriv = drvFromGenericPackageDescription overrideDrv + deriv :: PackageNix + deriv = fromGenericPackageDescription overrideDrv (const True) optNixpkgsIdentifier optSystem diff --git a/cabal2nix/src/Distribution/Nixpkgs/Haskell.hs b/cabal2nix/src/Distribution/Nixpkgs/Haskell.hs index c6421a26b..b1b751024 100644 --- a/cabal2nix/src/Distribution/Nixpkgs/Haskell.hs +++ b/cabal2nix/src/Distribution/Nixpkgs/Haskell.hs @@ -1,8 +1,10 @@ module Distribution.Nixpkgs.Haskell ( module Distribution.Nixpkgs.Haskell.BuildInfo , module Distribution.Nixpkgs.Haskell.Derivation + , module Distribution.Nixpkgs.Haskell.PackageNix ) where import Distribution.Nixpkgs.Haskell.BuildInfo import Distribution.Nixpkgs.Haskell.Derivation +import Distribution.Nixpkgs.Haskell.PackageNix diff --git a/cabal2nix/src/Distribution/Nixpkgs/Haskell/ComponentDerivations.hs b/cabal2nix/src/Distribution/Nixpkgs/Haskell/ComponentDerivations.hs new file mode 100644 index 000000000..69471ccd3 --- /dev/null +++ b/cabal2nix/src/Distribution/Nixpkgs/Haskell/ComponentDerivations.hs @@ -0,0 +1,32 @@ +{-# LANGUAGE DeriveGeneric #-} +{-# LANGUAGE RecordWildCards #-} +{-# LANGUAGE TemplateHaskell #-} +{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses #-} + +module Distribution.Nixpkgs.Haskell.ComponentDerivations + ( ComponentDerivations, libraries, executables, testExecutables, benchExecutables, nullComponentDerivations ) + where + +import Prelude hiding ((<>)) + +import Control.DeepSeq +import Control.Lens +import Data.List ( isPrefixOf ) +import Data.Map ( Map ) +import qualified Data.Map as Map +import Data.Set ( Set ) +import qualified Data.Set as Set +import Data.Set.Lens +import Distribution.Nixpkgs.Fetch +import Distribution.Nixpkgs.Haskell.BuildInfo +import Distribution.Nixpkgs.Haskell.Derivation +import Distribution.Nixpkgs.Haskell.OrphanInstances ( ) +import Distribution.Nixpkgs.Meta +import Distribution.Package +import Distribution.PackageDescription ( FlagAssignment, unFlagName, unFlagAssignment ) +import GHC.Generics ( Generic ) +import Language.Nix +import Language.Nix.PrettyPrinting + +-- | A represtation of Nix expressions for building Haskell packages with component granularity. + diff --git a/cabal2nix/src/Distribution/Nixpkgs/Haskell/Derivation.hs b/cabal2nix/src/Distribution/Nixpkgs/Haskell/Derivation.hs index 345342843..fa86cf28d 100644 --- a/cabal2nix/src/Distribution/Nixpkgs/Haskell/Derivation.hs +++ b/cabal2nix/src/Distribution/Nixpkgs/Haskell/Derivation.hs @@ -5,7 +5,7 @@ module Distribution.Nixpkgs.Haskell.Derivation ( Derivation, SingleDerivation - , derivation, nullSingleDerivation + , singleDerivation, nullSingleDerivation , nullDerivation, pkgid, revision, src, subpath, isLibrary, isExecutable , extraFunctionArgs, libraryDepends, executableDepends, testDepends, configureFlags , cabalFlags, runHaddock, jailbreak, doCheck, doBenchmark, buildTarget, testTarget, hyperlinkSource @@ -167,38 +167,18 @@ inputs drv@MkDerivation {..} = Set.unions isHackagePackage = "mirror://hackage/" `isPrefixOf` derivUrl _src newtype SingleDerivation = SingleDerivation - { _derivation :: Derivation } + { _singleDerivation :: Derivation } deriving (Show, Generic) makeLenses ''SingleDerivation nullSingleDerivation :: SingleDerivation nullSingleDerivation = SingleDerivation - { _derivation = error "undefined SingleDerivation.derivation" + { _singleDerivation = error "undefined SingleDerivation.derivation" } instance NFData SingleDerivation instance Pretty SingleDerivation where - pPrint SingleDerivation {..} = funargs (map text ("mkDerivation" : toAscList (inputs _derivation))) $$ - pPrint _derivation - --- data DefaultNix --- = SingleDerivation --- { _derivation :: Derivation } --- | ComponentDerivations --- { _libraries :: [Derivation] --- , _executables :: [Derivation] --- , _testExecutables :: [Derivation] --- , _benchExecutables :: [Derivation] --- } --- deriving (Show, Generic) --- --- makeLenses ''DefaultNix --- --- instance NFData DefaultNix --- --- -- instance Pretty DefaultNix where --- -- pPrint drv@ComponentDerivations {..} = funargs (map text ("mkDerivation" : toAscList inputs)) $$ vcat --- --- + pPrint SingleDerivation {..} = funargs (map text ("mkDerivation" : toAscList (inputs _singleDerivation))) $$ + pPrint _singleDerivation diff --git a/cabal2nix/src/Distribution/Nixpkgs/Haskell/FromCabal.hs b/cabal2nix/src/Distribution/Nixpkgs/Haskell/FromCabal.hs index ccdad9b99..2c87b6f89 100644 --- a/cabal2nix/src/Distribution/Nixpkgs/Haskell/FromCabal.hs +++ b/cabal2nix/src/Distribution/Nixpkgs/Haskell/FromCabal.hs @@ -4,7 +4,7 @@ module Distribution.Nixpkgs.Haskell.FromCabal ( HaskellResolver, NixpkgsResolver - , drvFromGenericPackageDescription , finalizeGenericPackageDescription , fromPackageDescription + , fromGenericPackageDescription , finalizeGenericPackageDescription , fromPackageDescription ) where import Control.Lens @@ -47,7 +47,7 @@ data OutputGranularity -- One derivation per component, where libraries are not excluded from executables' libraryDepends | PerComponent -drvFromGenericPackageDescription +fromGenericPackageDescription :: (Derivation -> Derivation) -> HaskellResolver -> NixpkgsResolver @@ -56,8 +56,8 @@ drvFromGenericPackageDescription -> FlagAssignment -> [Constraint] -> GenericPackageDescription - -> SingleDerivation -drvFromGenericPackageDescription overrideDrv haskellResolver nixpkgsResolver arch compiler flags constraints genDesc = + -> PackageNix +fromGenericPackageDescription overrideDrv haskellResolver nixpkgsResolver arch compiler flags constraints genDesc = fromPackageDescription overrideDrv haskellResolver nixpkgsResolver missingDeps flags descr where (descr, missingDeps) = finalizeGenericPackageDescription haskellResolver arch compiler flags constraints genDesc @@ -115,17 +115,19 @@ fromPackageDescription -> [Dependency] -> FlagAssignment -> PackageDescription - -> SingleDerivation -fromPackageDescription overrideDrv haskellResolver nixpkgsResolver missingDeps flags PackageDescription {..} = singleDerivation + -> PackageNix +fromPackageDescription overrideDrv haskellResolver nixpkgsResolver missingDeps flags PackageDescription {..} = singleDerivationPackage where - singleDerivation :: SingleDerivation - singleDerivation = nullSingleDerivation & derivation .~ overrideDrv (normalize $ postProcess $ baseDerivation - & isLibrary .~ isJust library - & isExecutable .~ not (null executables) - & libraryDepends .~ foldMap (convertSingleDerivationBuildInfo . libBuildInfo) allLibraries - & executableDepends .~ mconcat (map (convertSingleDerivationBuildInfo . buildInfo) executables) - & testDepends .~ mconcat (map (convertSingleDerivationBuildInfo . testBuildInfo) testSuites) - & benchmarkDepends .~ mconcat (map (convertSingleDerivationBuildInfo . benchmarkBuildInfo) benchmarks)) + singleDerivationPackage :: PackageNix + singleDerivationPackage = nullSingleDrvPackage + & derivation .~ overrideDrv (normalize $ postProcess $ + baseDerivation + & isLibrary .~ isJust library + & isExecutable .~ not (null executables) + & libraryDepends .~ foldMap (convertSingleDerivationBuildInfo . libBuildInfo) allLibraries + & executableDepends .~ mconcat (map (convertSingleDerivationBuildInfo . buildInfo) executables) + & testDepends .~ mconcat (map (convertSingleDerivationBuildInfo . testBuildInfo) testSuites) + & benchmarkDepends .~ mconcat (map (convertSingleDerivationBuildInfo . benchmarkBuildInfo) benchmarks)) libraryDerivations :: [Derivation] libraryDerivations = fmap (normalize . postProcess . toLibraryDerivation) allLibraries diff --git a/cabal2nix/src/Distribution/Nixpkgs/Haskell/PackageNix.hs b/cabal2nix/src/Distribution/Nixpkgs/Haskell/PackageNix.hs new file mode 100644 index 000000000..dcb0e3bd6 --- /dev/null +++ b/cabal2nix/src/Distribution/Nixpkgs/Haskell/PackageNix.hs @@ -0,0 +1,43 @@ +{-# LANGUAGE ApplicativeDo #-} +{-# LANGUAGE DeriveGeneric #-} +{-# LANGUAGE RecordWildCards #-} +{-# LANGUAGE TemplateHaskell #-} +{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses #-} + +module Distribution.Nixpkgs.Haskell.PackageNix + ( PackageNix, derivation, singleDrv, targetDrvs, nullSingleDrvPackage, nullTargetDrvsPackage + ) where + +import Control.DeepSeq +import Control.Lens +import GHC.Generics ( Generic ) +import Distribution.Nixpkgs.Haskell.Derivation +import Distribution.Nixpkgs.Haskell.TargetDerivations +import Language.Nix.PrettyPrinting + +data PackageNix + = SingleDerivation { _singleDrv :: SingleDerivation } + | TargetDerivations { _targetDrvs :: TargetDerivations } + deriving (Show, Generic) + +instance NFData PackageNix + +makeLenses ''PackageNix + +derivation :: Traversal' PackageNix Derivation +derivation f (SingleDerivation {..}) = do + singleDrv' <- singleDerivation f _singleDrv + pure SingleDerivation { _singleDrv = singleDrv' } +derivation f (TargetDerivations {..}) = do + targetDrvs' <- targetDerivation f _targetDrvs + pure TargetDerivations { _targetDrvs = targetDrvs' } + +instance Pretty PackageNix where + pPrint SingleDerivation {..} = pPrint _singleDrv + pPrint TargetDerivations {..} = pPrint _targetDrvs + +nullSingleDrvPackage :: PackageNix +nullSingleDrvPackage = SingleDerivation { _singleDrv = nullSingleDerivation } + +nullTargetDrvsPackage :: PackageNix +nullTargetDrvsPackage = SingleDerivation { _singleDrv = nullSingleDerivation } diff --git a/cabal2nix/src/Distribution/Nixpkgs/Haskell/TargetDerivations.hs b/cabal2nix/src/Distribution/Nixpkgs/Haskell/TargetDerivations.hs new file mode 100644 index 000000000..8ac956b5c --- /dev/null +++ b/cabal2nix/src/Distribution/Nixpkgs/Haskell/TargetDerivations.hs @@ -0,0 +1,60 @@ +{-# LANGUAGE ApplicativeDo #-} +{-# LANGUAGE DeriveGeneric #-} +{-# LANGUAGE RecordWildCards #-} +{-# LANGUAGE TemplateHaskell #-} +{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses #-} + +module Distribution.Nixpkgs.Haskell.TargetDerivations + ( TargetDerivations, targetDerivation, derivations, libraries, executables, testExecutables, benchExecutables + , nullTargetDerivations + ) + where + +import Prelude hiding ((<>)) + +import Control.DeepSeq +import Control.Lens +import Distribution.Nixpkgs.Haskell.OrphanInstances ( ) +import GHC.Generics ( Generic ) +import Distribution.Nixpkgs.Haskell.Derivation +import Language.Nix.PrettyPrinting + +-- | A represtation of Nix expressions for building individual targets within a Haskell package. + +data TargetDerivations = TargetDerivations + { _libraries :: [Derivation] + , _executables :: [Derivation] + , _testExecutables :: [Derivation] + , _benchExecutables :: [Derivation] + } + deriving (Show, Generic) + +instance NFData TargetDerivations + +makeLenses ''TargetDerivations + +makeLensesFor [("_libraries", "derivations"), ("_executables", "derivations"), ("_testExecutables", "derivations"), ("_benchExecutables", "derivations")] ''TargetDerivations + +targetDerivation :: Traversal' TargetDerivations Derivation +targetDerivation f (TargetDerivations {..}) = do + libs <- traverse f _libraries + exes <- traverse f _executables + testExes <- traverse f _testExecutables + benchExes <- traverse f _benchExecutables + pure TargetDerivations + { _libraries = libs + , _executables = exes + , _testExecutables = testExes + , _benchExecutables = benchExes + } + +nullTargetDerivations :: TargetDerivations +nullTargetDerivations = TargetDerivations + { _libraries = mempty + , _executables = mempty + , _testExecutables = mempty + , _benchExecutables = mempty + } + +instance Pretty TargetDerivations where + pPrint TargetDerivations {} = undefined -- TODO diff --git a/cabal2nix/test/Main.hs b/cabal2nix/test/Main.hs index 15e940c62..3ada690bc 100644 --- a/cabal2nix/test/Main.hs +++ b/cabal2nix/test/Main.hs @@ -8,6 +8,7 @@ import Distribution.Nixpkgs.Fetch import Distribution.Nixpkgs.Haskell.Derivation import Distribution.Nixpkgs.Haskell.FromCabal import Distribution.Nixpkgs.Haskell.FromCabal.Flags +import Distribution.Nixpkgs.Haskell.PackageNix import Control.Lens import Control.Monad @@ -62,8 +63,8 @@ testLibrary cabalFile = do , derivSubmodule = Nothing } & extraFunctionArgs %~ Set.union (Set.singleton "inherit lib") - cabal2nix :: GenericPackageDescription -> SingleDerivation - cabal2nix gpd = drvFromGenericPackageDescription + cabal2nix :: GenericPackageDescription -> PackageNix + cabal2nix gpd = fromGenericPackageDescription overrideDrv (const True) (\i -> Just (binding # (i, path # [ident # "pkgs", i]))) From 3bdd3040ccdbdfcf24b724ace1045bef29389ae6 Mon Sep 17 00:00:00 2001 From: Marc Jakobi Date: Wed, 29 May 2024 11:21:27 +0200 Subject: [PATCH 03/18] refactor: use `PackageNix` --- cabal2nix/src/Cabal2nix.hs | 1 + cabal2nix/src/Distribution/Nixpkgs/Haskell.hs | 2 + .../Distribution/Nixpkgs/Haskell/FromCabal.hs | 57 ++++++++++--------- .../Nixpkgs/Haskell/PackageNix.hs | 2 +- .../Nixpkgs/Haskell/TargetDerivations.hs | 26 ++++----- cabal2nix/test/Main.hs | 1 + 6 files changed, 47 insertions(+), 42 deletions(-) diff --git a/cabal2nix/src/Cabal2nix.hs b/cabal2nix/src/Cabal2nix.hs index 131ffbfaf..fa04168f4 100644 --- a/cabal2nix/src/Cabal2nix.hs +++ b/cabal2nix/src/Cabal2nix.hs @@ -232,6 +232,7 @@ processPackage Options{..} pkg = do optSystem (unknownCompilerInfo optCompiler NoAbiTag) flags + SingleDerivation [] (pkgCabal pkg) diff --git a/cabal2nix/src/Distribution/Nixpkgs/Haskell.hs b/cabal2nix/src/Distribution/Nixpkgs/Haskell.hs index b1b751024..601fb3b75 100644 --- a/cabal2nix/src/Distribution/Nixpkgs/Haskell.hs +++ b/cabal2nix/src/Distribution/Nixpkgs/Haskell.hs @@ -1,10 +1,12 @@ module Distribution.Nixpkgs.Haskell ( module Distribution.Nixpkgs.Haskell.BuildInfo , module Distribution.Nixpkgs.Haskell.Derivation + , module Distribution.Nixpkgs.Haskell.TargetDerivations , module Distribution.Nixpkgs.Haskell.PackageNix ) where import Distribution.Nixpkgs.Haskell.BuildInfo import Distribution.Nixpkgs.Haskell.Derivation +import Distribution.Nixpkgs.Haskell.TargetDerivations import Distribution.Nixpkgs.Haskell.PackageNix diff --git a/cabal2nix/src/Distribution/Nixpkgs/Haskell/FromCabal.hs b/cabal2nix/src/Distribution/Nixpkgs/Haskell/FromCabal.hs index 2c87b6f89..b46836186 100644 --- a/cabal2nix/src/Distribution/Nixpkgs/Haskell/FromCabal.hs +++ b/cabal2nix/src/Distribution/Nixpkgs/Haskell/FromCabal.hs @@ -3,7 +3,7 @@ {-# LANGUAGE RecordWildCards #-} module Distribution.Nixpkgs.Haskell.FromCabal - ( HaskellResolver, NixpkgsResolver + ( HaskellResolver, NixpkgsResolver, OutputGranularity (..) , fromGenericPackageDescription , finalizeGenericPackageDescription , fromPackageDescription ) where @@ -44,8 +44,8 @@ type NixpkgsResolver = Identifier -> Maybe Binding data OutputGranularity = SingleDerivation - -- One derivation per component, where libraries are not excluded from executables' libraryDepends - | PerComponent + -- One derivation per target, where libraries are not excluded from executables' libraryDepends + | PerTarget fromGenericPackageDescription :: (Derivation -> Derivation) @@ -54,11 +54,12 @@ fromGenericPackageDescription -> Platform -> CompilerInfo -> FlagAssignment + -> OutputGranularity -> [Constraint] -> GenericPackageDescription -> PackageNix -fromGenericPackageDescription overrideDrv haskellResolver nixpkgsResolver arch compiler flags constraints genDesc = - fromPackageDescription overrideDrv haskellResolver nixpkgsResolver missingDeps flags descr +fromGenericPackageDescription overrideDrv haskellResolver nixpkgsResolver arch compiler flags granularity constraints genDesc = + fromPackageDescription overrideDrv haskellResolver nixpkgsResolver missingDeps flags granularity descr where (descr, missingDeps) = finalizeGenericPackageDescription haskellResolver arch compiler flags constraints genDesc @@ -114,32 +115,34 @@ fromPackageDescription -> NixpkgsResolver -> [Dependency] -> FlagAssignment + -> OutputGranularity -> PackageDescription -> PackageNix -fromPackageDescription overrideDrv haskellResolver nixpkgsResolver missingDeps flags PackageDescription {..} = singleDerivationPackage +fromPackageDescription overrideDrv haskellResolver nixpkgsResolver missingDeps flags granularity packageDescription@PackageDescription {..} + = case granularity of + SingleDerivation -> singleDerivationPackage + PerTarget -> multiDerivationPackage where singleDerivationPackage :: PackageNix singleDerivationPackage = nullSingleDrvPackage - & derivation .~ overrideDrv (normalize $ postProcess $ - baseDerivation - & isLibrary .~ isJust library - & isExecutable .~ not (null executables) - & libraryDepends .~ foldMap (convertSingleDerivationBuildInfo . libBuildInfo) allLibraries - & executableDepends .~ mconcat (map (convertSingleDerivationBuildInfo . buildInfo) executables) - & testDepends .~ mconcat (map (convertSingleDerivationBuildInfo . testBuildInfo) testSuites) - & benchmarkDepends .~ mconcat (map (convertSingleDerivationBuildInfo . benchmarkBuildInfo) benchmarks)) - - libraryDerivations :: [Derivation] - libraryDerivations = fmap (normalize . postProcess . toLibraryDerivation) allLibraries - - executableDerivations :: [Derivation] - executableDerivations = fmap (normalize . postProcess . toExecutableDerivation) executables - - testDerivations :: [Derivation] - testDerivations = fmap (normalize . postProcess . toTestDerivation) testSuites - - benchDerivations :: [Derivation] - benchDerivations = fmap (normalize . postProcess . toBenchDerivation) benchmarks + & derivation .~ processDrv (baseDerivation + & isLibrary .~ isJust library + & isExecutable .~ not (null executables) + & libraryDepends .~ foldMap (convertSingleDerivationBuildInfo . libBuildInfo) (allLibraries packageDescription) + & executableDepends .~ mconcat (map (convertSingleDerivationBuildInfo . buildInfo) executables) + & testDepends .~ mconcat (map (convertSingleDerivationBuildInfo . testBuildInfo) testSuites) + & benchmarkDepends .~ mconcat (map (convertSingleDerivationBuildInfo . benchmarkBuildInfo) benchmarks)) + + processDrv :: Derivation -> Derivation + processDrv = overrideDrv . normalize . postProcess + + multiDerivationPackage :: PackageNix + multiDerivationPackage = nullTargetDrvsPackage + & targetDrvs .~ (nullTargetDerivations + & libraries .~ fmap (processDrv . toLibraryDerivation) (allLibraries packageDescription) + & exes .~ fmap (processDrv . toExecutableDerivation) executables + & testExes .~ fmap (processDrv . toTestDerivation) testSuites + & benchExes .~ fmap (processDrv . toBenchDerivation) benchmarks) toLibraryDerivation :: Library -> Derivation toLibraryDerivation lib = baseDerivation @@ -218,8 +221,6 @@ fromPackageDescription overrideDrv haskellResolver nixpkgsResolver missingDeps f & Nix.broken .~ not (null missingDeps) ) - allLibraries = maybeToList library ++ subLibraries - xrev = maybe 0 read (lookup "x-revision" customFieldsPD) nixLicense :: Nix.License diff --git a/cabal2nix/src/Distribution/Nixpkgs/Haskell/PackageNix.hs b/cabal2nix/src/Distribution/Nixpkgs/Haskell/PackageNix.hs index dcb0e3bd6..1f97531ab 100644 --- a/cabal2nix/src/Distribution/Nixpkgs/Haskell/PackageNix.hs +++ b/cabal2nix/src/Distribution/Nixpkgs/Haskell/PackageNix.hs @@ -40,4 +40,4 @@ nullSingleDrvPackage :: PackageNix nullSingleDrvPackage = SingleDerivation { _singleDrv = nullSingleDerivation } nullTargetDrvsPackage :: PackageNix -nullTargetDrvsPackage = SingleDerivation { _singleDrv = nullSingleDerivation } +nullTargetDrvsPackage = TargetDerivations { _targetDrvs = nullTargetDerivations } diff --git a/cabal2nix/src/Distribution/Nixpkgs/Haskell/TargetDerivations.hs b/cabal2nix/src/Distribution/Nixpkgs/Haskell/TargetDerivations.hs index 8ac956b5c..2f40f5c3a 100644 --- a/cabal2nix/src/Distribution/Nixpkgs/Haskell/TargetDerivations.hs +++ b/cabal2nix/src/Distribution/Nixpkgs/Haskell/TargetDerivations.hs @@ -5,7 +5,7 @@ {-# LANGUAGE FlexibleInstances, MultiParamTypeClasses #-} module Distribution.Nixpkgs.Haskell.TargetDerivations - ( TargetDerivations, targetDerivation, derivations, libraries, executables, testExecutables, benchExecutables + ( TargetDerivations, targetDerivation, derivations, libraries, exes, testExes, benchExes , nullTargetDerivations ) where @@ -23,9 +23,9 @@ import Language.Nix.PrettyPrinting data TargetDerivations = TargetDerivations { _libraries :: [Derivation] - , _executables :: [Derivation] - , _testExecutables :: [Derivation] - , _benchExecutables :: [Derivation] + , _exes :: [Derivation] + , _testExes :: [Derivation] + , _benchExes :: [Derivation] } deriving (Show, Generic) @@ -38,22 +38,22 @@ makeLensesFor [("_libraries", "derivations"), ("_executables", "derivations"), ( targetDerivation :: Traversal' TargetDerivations Derivation targetDerivation f (TargetDerivations {..}) = do libs <- traverse f _libraries - exes <- traverse f _executables - testExes <- traverse f _testExecutables - benchExes <- traverse f _benchExecutables + exes' <- traverse f _exes + testExes' <- traverse f _testExes + benchExes' <- traverse f _benchExes pure TargetDerivations { _libraries = libs - , _executables = exes - , _testExecutables = testExes - , _benchExecutables = benchExes + , _exes = exes' + , _testExes = testExes' + , _benchExes = benchExes' } nullTargetDerivations :: TargetDerivations nullTargetDerivations = TargetDerivations { _libraries = mempty - , _executables = mempty - , _testExecutables = mempty - , _benchExecutables = mempty + , _exes = mempty + , _testExes = mempty + , _benchExes = mempty } instance Pretty TargetDerivations where diff --git a/cabal2nix/test/Main.hs b/cabal2nix/test/Main.hs index 3ada690bc..cbb78b144 100644 --- a/cabal2nix/test/Main.hs +++ b/cabal2nix/test/Main.hs @@ -71,6 +71,7 @@ testLibrary cabalFile = do (Platform X86_64 Linux) (unknownCompilerInfo (CompilerId GHC (mkVersion [8,2])) NoAbiTag) (configureCabalFlags (packageId gpd)) + SingleDerivation [] gpd goldenVsFileDiff From 4aebb208ffc13e228de1469a63eedc7875ec719e Mon Sep 17 00:00:00 2001 From: Marc Jakobi Date: Wed, 29 May 2024 13:28:29 +0200 Subject: [PATCH 04/18] feat: implement `Pretty` for `TargetDerivations` --- .../Nixpkgs/Haskell/Derivation.hs | 2 +- .../Nixpkgs/Haskell/TargetDerivations.hs | 27 ++++++++++++++++++- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/cabal2nix/src/Distribution/Nixpkgs/Haskell/Derivation.hs b/cabal2nix/src/Distribution/Nixpkgs/Haskell/Derivation.hs index fa86cf28d..1a6bb7118 100644 --- a/cabal2nix/src/Distribution/Nixpkgs/Haskell/Derivation.hs +++ b/cabal2nix/src/Distribution/Nixpkgs/Haskell/Derivation.hs @@ -11,7 +11,7 @@ module Distribution.Nixpkgs.Haskell.Derivation , cabalFlags, runHaddock, jailbreak, doCheck, doBenchmark, buildTarget, testTarget, hyperlinkSource , enableSplitObjs , enableLibraryProfiling, enableExecutableProfiling, phaseOverrides , editedCabalFile, metaSection , dependencies, setupDepends, benchmarkDepends, enableSeparateDataOutput - , extraAttributes + , extraAttributes, inputs ) where diff --git a/cabal2nix/src/Distribution/Nixpkgs/Haskell/TargetDerivations.hs b/cabal2nix/src/Distribution/Nixpkgs/Haskell/TargetDerivations.hs index 2f40f5c3a..817214247 100644 --- a/cabal2nix/src/Distribution/Nixpkgs/Haskell/TargetDerivations.hs +++ b/cabal2nix/src/Distribution/Nixpkgs/Haskell/TargetDerivations.hs @@ -14,7 +14,10 @@ import Prelude hiding ((<>)) import Control.DeepSeq import Control.Lens +import Data.Set ( Set ) +import qualified Data.Set as Set import Distribution.Nixpkgs.Haskell.OrphanInstances ( ) +import Distribution.Package import GHC.Generics ( Generic ) import Distribution.Nixpkgs.Haskell.Derivation import Language.Nix.PrettyPrinting @@ -56,5 +59,27 @@ nullTargetDerivations = TargetDerivations , _benchExes = mempty } +allInputs :: TargetDerivations -> Set String +allInputs TargetDerivations {..} = Set.unions + [ mconcat $ inputs <$> _libraries + , mconcat $ inputs <$> _exes + , mconcat $ inputs <$> _testExes + , mconcat $ inputs <$> _benchExes + ] + instance Pretty TargetDerivations where - pPrint TargetDerivations {} = undefined -- TODO + pPrint targetDerivations = funargs (map text ("mkDerivation" : toAscList (allInputs targetDerivations))) $$ vcat + [ text "let" + , vcat $ derivationAttr <$> targetDerivations^.derivations + , text "in" <+> lbrace + , nest 2 $ text "inherit" + , nest 2 $ vcat $ pPrint . packageName <$> targetDerivations^.derivations + , semi + , rbrace + ] + +derivationAttr :: Derivation -> Doc +derivationAttr drv = attr (drvName drv) $ pPrint drv + +drvName :: Derivation -> String +drvName drv = unPackageName $ packageName $ drv^.pkgid From 3b04c0a0cf1daa082fbbc90bf471823244639e2d Mon Sep 17 00:00:00 2001 From: Marc Jakobi Date: Wed, 29 May 2024 14:54:17 +0200 Subject: [PATCH 05/18] fix: implement Traversals for hackage2nix --- cabal2nix/hackage2nix/Main.hs | 5 ++-- cabal2nix/src/Cabal2nix.hs | 5 +++- .../Nixpkgs/Haskell/PackageNix.hs | 28 ++++++++++++++++--- .../Nixpkgs/Haskell/TargetDerivations.hs | 14 +++++----- 4 files changed, 37 insertions(+), 15 deletions(-) diff --git a/cabal2nix/hackage2nix/Main.hs b/cabal2nix/hackage2nix/Main.hs index 99634be8a..5ff8f55e3 100644 --- a/cabal2nix/hackage2nix/Main.hs +++ b/cabal2nix/hackage2nix/Main.hs @@ -169,11 +169,10 @@ main = do & metaSection.homepage .~ "" drv :: PackageNix - drv = fromGenericPackageDescription overrideDrv haskellResolver nixpkgsResolver targetPlatform (compilerInfo config) flagAssignment [] descr - ^. derivation + drv = fromGenericPackageDescription overrideDrv haskellResolver nixpkgsResolver targetPlatform (compilerInfo config) flagAssignment SingleDerivation [] descr 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 (allDependencies . each) drv `Set.union` view allExtraFunctionArgs drv), not (isFromHackage b) ] return $ render $ nest 2 $ hang (doubleQuotes (text attr) <+> equals <+> text "callPackage") 2 (parens (pPrint drv)) <+> (braces overrides <> semi) diff --git a/cabal2nix/src/Cabal2nix.hs b/cabal2nix/src/Cabal2nix.hs index fa04168f4..2d90d850e 100644 --- a/cabal2nix/src/Cabal2nix.hs +++ b/cabal2nix/src/Cabal2nix.hs @@ -60,6 +60,7 @@ data Options = Options , optHackageDb :: Maybe FilePath , optNixShellOutput :: Bool , optFlags :: [String] + , optOutputGranularity :: OutputGranularity , optCompiler :: CompilerId , optSystem :: Platform , optSubpath :: Maybe FilePath @@ -111,6 +112,8 @@ options = do <- switch (long "shell" <> help "generate output suitable for nix-shell") optFlags <- many (strOption $ short 'f' <> long "flag" <> help "Cabal flag (may be specified multiple times)") + optOutputGranularity + <- flag SingleDerivation PerTarget $ long "granular-output" <> help "Generate an attrset with a derivation for each build target" optCompiler <- option parseCabal (long "compiler" <> help "compiler to use when evaluating the Cabal file" <> value buildCompilerId <> showDefaultWith prettyShow) optSystem @@ -232,7 +235,7 @@ processPackage Options{..} pkg = do optSystem (unknownCompilerInfo optCompiler NoAbiTag) flags - SingleDerivation + optOutputGranularity [] (pkgCabal pkg) diff --git a/cabal2nix/src/Distribution/Nixpkgs/Haskell/PackageNix.hs b/cabal2nix/src/Distribution/Nixpkgs/Haskell/PackageNix.hs index 1f97531ab..956e8f3bb 100644 --- a/cabal2nix/src/Distribution/Nixpkgs/Haskell/PackageNix.hs +++ b/cabal2nix/src/Distribution/Nixpkgs/Haskell/PackageNix.hs @@ -6,13 +6,17 @@ module Distribution.Nixpkgs.Haskell.PackageNix ( PackageNix, derivation, singleDrv, targetDrvs, nullSingleDrvPackage, nullTargetDrvsPackage + , allDependencies, allExtraFunctionArgs ) where import Control.DeepSeq import Control.Lens -import GHC.Generics ( Generic ) +import Data.Set ( Set ) +import Distribution.Nixpkgs.Haskell.BuildInfo import Distribution.Nixpkgs.Haskell.Derivation import Distribution.Nixpkgs.Haskell.TargetDerivations +import GHC.Generics ( Generic ) +import Language.Nix import Language.Nix.PrettyPrinting data PackageNix @@ -25,11 +29,27 @@ instance NFData PackageNix makeLenses ''PackageNix derivation :: Traversal' PackageNix Derivation -derivation f (SingleDerivation {..}) = do +derivation f SingleDerivation {..} = do singleDrv' <- singleDerivation f _singleDrv pure SingleDerivation { _singleDrv = singleDrv' } -derivation f (TargetDerivations {..}) = do - targetDrvs' <- targetDerivation f _targetDrvs +derivation f TargetDerivations {..} = do + targetDrvs' <- targetDerivations f _targetDrvs + pure TargetDerivations { _targetDrvs = targetDrvs' } + +allDependencies :: Traversal' PackageNix BuildInfo +allDependencies f SingleDerivation {..} = do + singleDrv' <- (singleDerivation . dependencies) f _singleDrv + pure SingleDerivation { _singleDrv = singleDrv' } +allDependencies f TargetDerivations {..} = do + targetDrvs' <- (targetDerivations . dependencies) f _targetDrvs + pure TargetDerivations { _targetDrvs = targetDrvs' } + +allExtraFunctionArgs :: Traversal' PackageNix (Set Binding) +allExtraFunctionArgs f SingleDerivation {..} = do + singleDrv' <- (singleDerivation . extraFunctionArgs) f _singleDrv + pure SingleDerivation { _singleDrv = singleDrv' } +allExtraFunctionArgs f TargetDerivations {..} = do + targetDrvs' <- (targetDerivations . extraFunctionArgs) f _targetDrvs pure TargetDerivations { _targetDrvs = targetDrvs' } instance Pretty PackageNix where diff --git a/cabal2nix/src/Distribution/Nixpkgs/Haskell/TargetDerivations.hs b/cabal2nix/src/Distribution/Nixpkgs/Haskell/TargetDerivations.hs index 817214247..d5d45d6e3 100644 --- a/cabal2nix/src/Distribution/Nixpkgs/Haskell/TargetDerivations.hs +++ b/cabal2nix/src/Distribution/Nixpkgs/Haskell/TargetDerivations.hs @@ -5,7 +5,7 @@ {-# LANGUAGE FlexibleInstances, MultiParamTypeClasses #-} module Distribution.Nixpkgs.Haskell.TargetDerivations - ( TargetDerivations, targetDerivation, derivations, libraries, exes, testExes, benchExes + ( TargetDerivations, targetDerivations, allDerivations, libraries, exes, testExes, benchExes , nullTargetDerivations ) where @@ -36,10 +36,10 @@ instance NFData TargetDerivations makeLenses ''TargetDerivations -makeLensesFor [("_libraries", "derivations"), ("_executables", "derivations"), ("_testExecutables", "derivations"), ("_benchExecutables", "derivations")] ''TargetDerivations +makeLensesFor [("_libraries", "allDerivations"), ("_executables", "allDerivations"), ("_testExecutables", "allDerivations"), ("_benchExecutables", "allDerivations")] ''TargetDerivations -targetDerivation :: Traversal' TargetDerivations Derivation -targetDerivation f (TargetDerivations {..}) = do +targetDerivations :: Traversal' TargetDerivations Derivation +targetDerivations f (TargetDerivations {..}) = do libs <- traverse f _libraries exes' <- traverse f _exes testExes' <- traverse f _testExes @@ -68,12 +68,12 @@ allInputs TargetDerivations {..} = Set.unions ] instance Pretty TargetDerivations where - pPrint targetDerivations = funargs (map text ("mkDerivation" : toAscList (allInputs targetDerivations))) $$ vcat + pPrint targetDerivationss = funargs (map text ("mkDerivation" : toAscList (allInputs targetDerivationss))) $$ vcat [ text "let" - , vcat $ derivationAttr <$> targetDerivations^.derivations + , vcat $ derivationAttr <$> targetDerivationss^.allDerivations , text "in" <+> lbrace , nest 2 $ text "inherit" - , nest 2 $ vcat $ pPrint . packageName <$> targetDerivations^.derivations + , nest 2 $ vcat $ pPrint . packageName <$> targetDerivationss^.allDerivations , semi , rbrace ] From b7ef5bc90c64c6529d1c9f88ca120493e2f1909c Mon Sep 17 00:00:00 2001 From: Marc Jakobi Date: Wed, 29 May 2024 15:08:16 +0200 Subject: [PATCH 06/18] chore: typo --- .../src/Distribution/Nixpkgs/Haskell/TargetDerivations.hs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/cabal2nix/src/Distribution/Nixpkgs/Haskell/TargetDerivations.hs b/cabal2nix/src/Distribution/Nixpkgs/Haskell/TargetDerivations.hs index d5d45d6e3..6710337c4 100644 --- a/cabal2nix/src/Distribution/Nixpkgs/Haskell/TargetDerivations.hs +++ b/cabal2nix/src/Distribution/Nixpkgs/Haskell/TargetDerivations.hs @@ -68,13 +68,13 @@ allInputs TargetDerivations {..} = Set.unions ] instance Pretty TargetDerivations where - pPrint targetDerivationss = funargs (map text ("mkDerivation" : toAscList (allInputs targetDerivationss))) $$ vcat + pPrint targetDerivations = funargs (map text ("mkDerivation" : toAscList (allInputs targetDerivations))) $$ vcat [ text "let" - , vcat $ derivationAttr <$> targetDerivationss^.allDerivations + , vcat $ derivationAttr <$> targetDerivations^.allDerivations , text "in" <+> lbrace , nest 2 $ text "inherit" - , nest 2 $ vcat $ pPrint . packageName <$> targetDerivationss^.allDerivations - , semi + , nest 4 $ vcat $ pPrint . packageName <$> targetDerivations^.allDerivations + , nest 4 semi , rbrace ] From 921f02d51682081bf1b626f245174ba6d184033d Mon Sep 17 00:00:00 2001 From: Marc Jakobi Date: Wed, 29 May 2024 15:18:14 +0200 Subject: [PATCH 07/18] fix: initialise Derivation dependencies as mempty --- cabal2nix/src/Distribution/Nixpkgs/Haskell/Derivation.hs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/cabal2nix/src/Distribution/Nixpkgs/Haskell/Derivation.hs b/cabal2nix/src/Distribution/Nixpkgs/Haskell/Derivation.hs index 1a6bb7118..e435c64aa 100644 --- a/cabal2nix/src/Distribution/Nixpkgs/Haskell/Derivation.hs +++ b/cabal2nix/src/Distribution/Nixpkgs/Haskell/Derivation.hs @@ -83,10 +83,10 @@ nullDerivation = MkDerivation , _extraFunctionArgs = error "undefined Derivation.extraFunctionArgs" , _extraAttributes = error "undefined Derivation.extraAttributes" , _setupDepends = error "undefined Derivation.setupDepends" - , _libraryDepends = error "undefined Derivation.libraryDepends" - , _executableDepends = error "undefined Derivation.executableDepends" - , _testDepends = error "undefined Derivation.testDepends" - , _benchmarkDepends = error "undefined Derivation.benchmarkDepends" + , _libraryDepends = mempty + , _executableDepends = mempty + , _testDepends = mempty + , _benchmarkDepends = mempty , _configureFlags = error "undefined Derivation.configureFlags" , _cabalFlags = error "undefined Derivation.cabalFlags" , _runHaddock = error "undefined Derivation.runHaddock" From 6ffe033527470497d9aea32a1c476784a8efbc4d Mon Sep 17 00:00:00 2001 From: Marc Jakobi Date: Wed, 29 May 2024 15:24:45 +0200 Subject: [PATCH 08/18] fix: allDerivations Traversal --- cabal2nix/src/Distribution/Nixpkgs/Haskell/TargetDerivations.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cabal2nix/src/Distribution/Nixpkgs/Haskell/TargetDerivations.hs b/cabal2nix/src/Distribution/Nixpkgs/Haskell/TargetDerivations.hs index 6710337c4..e41615d20 100644 --- a/cabal2nix/src/Distribution/Nixpkgs/Haskell/TargetDerivations.hs +++ b/cabal2nix/src/Distribution/Nixpkgs/Haskell/TargetDerivations.hs @@ -36,7 +36,7 @@ instance NFData TargetDerivations makeLenses ''TargetDerivations -makeLensesFor [("_libraries", "allDerivations"), ("_executables", "allDerivations"), ("_testExecutables", "allDerivations"), ("_benchExecutables", "allDerivations")] ''TargetDerivations +makeLensesFor [("_libraries", "allDerivations"), ("_exes", "allDerivations"), ("_testExes", "allDerivations"), ("_benchExes", "allDerivations")] ''TargetDerivations targetDerivations :: Traversal' TargetDerivations Derivation targetDerivations f (TargetDerivations {..}) = do From 995412a93b2e7d8e2855bdb5996eb358b8625228 Mon Sep 17 00:00:00 2001 From: Marc Jakobi Date: Wed, 29 May 2024 15:36:01 +0200 Subject: [PATCH 09/18] fix(granular-output): exclude internal libs from callPackage args --- .../Nixpkgs/Haskell/TargetDerivations.hs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/cabal2nix/src/Distribution/Nixpkgs/Haskell/TargetDerivations.hs b/cabal2nix/src/Distribution/Nixpkgs/Haskell/TargetDerivations.hs index e41615d20..0e3f85c10 100644 --- a/cabal2nix/src/Distribution/Nixpkgs/Haskell/TargetDerivations.hs +++ b/cabal2nix/src/Distribution/Nixpkgs/Haskell/TargetDerivations.hs @@ -60,12 +60,15 @@ nullTargetDerivations = TargetDerivations } allInputs :: TargetDerivations -> Set String -allInputs TargetDerivations {..} = Set.unions - [ mconcat $ inputs <$> _libraries - , mconcat $ inputs <$> _exes - , mconcat $ inputs <$> _testExes - , mconcat $ inputs <$> _benchExes +allInputs TargetDerivations {..} = Set.filter (`notElem` internalLibNames) $ Set.unions $ mconcat + [ inputs <$> _libraries + , inputs <$> _exes + , inputs <$> _testExes + , inputs <$> _benchExes ] + where + internalLibNames :: [String] + internalLibNames = drvName <$> _libraries instance Pretty TargetDerivations where pPrint targetDerivations = funargs (map text ("mkDerivation" : toAscList (allInputs targetDerivations))) $$ vcat From 24dac1eca0cab442d6ee6f6ecf01a5e8bcf0dbb8 Mon Sep 17 00:00:00 2001 From: Marc Jakobi Date: Wed, 29 May 2024 16:25:33 +0200 Subject: [PATCH 10/18] tests: add golden test case for granular-output --- cabal2nix/test/Main.hs | 10 +-- .../golden-test-cases-granular/.gitignore | 1 + .../golden-test-cases-granular/ttrie.cabal | 68 +++++++++++++++++++ .../ttrie.nix.golden | 58 ++++++++++++++++ 4 files changed, 133 insertions(+), 4 deletions(-) create mode 100644 cabal2nix/test/golden-test-cases-granular/.gitignore create mode 100644 cabal2nix/test/golden-test-cases-granular/ttrie.cabal create mode 100644 cabal2nix/test/golden-test-cases-granular/ttrie.nix.golden diff --git a/cabal2nix/test/Main.hs b/cabal2nix/test/Main.hs index cbb78b144..a85dd8854 100644 --- a/cabal2nix/test/Main.hs +++ b/cabal2nix/test/Main.hs @@ -43,13 +43,15 @@ main = do Nothing -> fail "cannot find 'cabal2nix' in $PATH" Just exe -> pure exe testCases <- listDirectoryFilesBySuffix ".cabal" "test/golden-test-cases" + granularCases <- listDirectoryFilesBySuffix ".cabal" "test/golden-test-cases-granular" defaultMain $ testGroup "regression-tests" - [ testGroup "cabal2nix library" (map testLibrary testCases) + [ testGroup "cabal2nix library" (map (testLibrary SingleDerivation) testCases) + , testGroup "cabal2nix granular-output" (map (testLibrary PerTarget) granularCases) , testGroup "cabal2nix executable" (map (testExecutable cabal2nix) testCases) ] -testLibrary :: String -> TestTree -testLibrary cabalFile = do +testLibrary :: OutputGranularity -> String -> TestTree +testLibrary outputGranularity cabalFile = do let nixFile = cabalFile `replaceExtension` "nix" goldenFile = nixFile `addExtension` "golden" @@ -71,7 +73,7 @@ testLibrary cabalFile = do (Platform X86_64 Linux) (unknownCompilerInfo (CompilerId GHC (mkVersion [8,2])) NoAbiTag) (configureCabalFlags (packageId gpd)) - SingleDerivation + outputGranularity [] gpd goldenVsFileDiff diff --git a/cabal2nix/test/golden-test-cases-granular/.gitignore b/cabal2nix/test/golden-test-cases-granular/.gitignore new file mode 100644 index 000000000..40c431b6e --- /dev/null +++ b/cabal2nix/test/golden-test-cases-granular/.gitignore @@ -0,0 +1 @@ +/*.nix diff --git a/cabal2nix/test/golden-test-cases-granular/ttrie.cabal b/cabal2nix/test/golden-test-cases-granular/ttrie.cabal new file mode 100644 index 000000000..3d5e3bbb5 --- /dev/null +++ b/cabal2nix/test/golden-test-cases-granular/ttrie.cabal @@ -0,0 +1,68 @@ +name: ttrie +version: 0.1.2.1 +synopsis: Contention-free STM hash map +description: + A contention-free STM hash map. + \"Contention-free\" means that the map will never cause spurious conflicts. + A transaction operating on the map will only ever have to retry if + another transaction is operating on the same key at the same time. + . + This is an implementation of the /transactional trie/, + which is basically a /lock-free concurrent hash trie/ lifted into STM. + For a detailed discussion, including an evaluation of its performance, + see Chapter 4 of . +homepage: http://github.com/mcschroeder/ttrie +bug-reports: http://github.com/mcschroeder/ttrie/issues +license: MIT +license-file: LICENSE +author: Michael Schröder +maintainer: mc.schroeder@gmail.com +copyright: (c) 2014-2015 Michael Schröder +category: Concurrency +build-type: Simple +extra-source-files: README.md, benchmarks/run.sh +cabal-version: >=1.10 + +extra-source-files: changelog.md + +source-repository head + type: git + location: https://github.com/mcschroeder/ttrie.git + +library + hs-source-dirs: src + exposed-modules: Control.Concurrent.STM.Map + other-modules: Data.SparseArray + default-language: Haskell2010 + ghc-options: -Wall + build-depends: base >=4.7 && <5 + , atomic-primops >=0.6 + , hashable >=1.2 + , primitive >=0.5 + , stm >=2 + +test-suite map-properties + hs-source-dirs: tests + main-is: MapProperties.hs + type: exitcode-stdio-1.0 + + build-depends: + base + , QuickCheck >=2.5 + , test-framework >=0.8 + , test-framework-quickcheck2 >=0.3 + , containers >=0.5 + , hashable >=1.2 + , stm + , ttrie + +benchmark bench + hs-source-dirs: benchmarks + main-is: Bench.hs + other-modules: BenchGen + type: exitcode-stdio-1.0 + default-language: Haskell2010 + ghc-options: -O2 -threaded -with-rtsopts=-N + build-depends: + base, async, bifunctors, containers, criterion-plus, deepseq, mwc-random, primitive, stm, stm-containers, stm-stats, text, transformers, ttrie, unordered-containers, vector + diff --git a/cabal2nix/test/golden-test-cases-granular/ttrie.nix.golden b/cabal2nix/test/golden-test-cases-granular/ttrie.nix.golden new file mode 100644 index 000000000..edd1260d5 --- /dev/null +++ b/cabal2nix/test/golden-test-cases-granular/ttrie.nix.golden @@ -0,0 +1,58 @@ +{ mkDerivation, async, atomic-primops, base, bifunctors, containers +, criterion-plus, deepseq, hashable, lib, mwc-random, primitive +, QuickCheck, stm, stm-containers, stm-stats, test-framework +, test-framework-quickcheck2, text, transformers +, unordered-containers, vector +}: +let +ttrie = mkDerivation { + pname = "ttrie"; + version = "0.1.2.1"; + sha256 = "deadbeef"; + libraryHaskellDepends = [ + atomic-primops base hashable primitive stm + ]; + buildTarget = "lib"; + homepage = "http://github.com/mcschroeder/ttrie"; + description = "Contention-free STM hash map"; + license = lib.licenses.mit; + }; +map-properties = mkDerivation { + pname = "map-properties"; + version = "0.1.2.1"; + sha256 = "deadbeef"; + isLibrary = false; + isExecutable = true; + testHaskellDepends = [ + base containers hashable QuickCheck stm test-framework + test-framework-quickcheck2 ttrie + ]; + buildTarget = "map-properties"; + homepage = "http://github.com/mcschroeder/ttrie"; + description = "Contention-free STM hash map"; + license = lib.licenses.mit; + }; +bench = mkDerivation { + pname = "bench"; + version = "0.1.2.1"; + sha256 = "deadbeef"; + isLibrary = false; + isExecutable = true; + benchmarkHaskellDepends = [ + async base bifunctors containers criterion-plus deepseq mwc-random + primitive stm stm-containers stm-stats text transformers ttrie + unordered-containers vector + ]; + doBenchmark = true; + buildTarget = "bench"; + homepage = "http://github.com/mcschroeder/ttrie"; + description = "Contention-free STM hash map"; + license = lib.licenses.mit; + }; +in { + inherit + ttrie + map-properties + bench + ; +} From 8e42e18d04bd0ffbebff66c06764069f1cb9dba8 Mon Sep 17 00:00:00 2001 From: Marc Jakobi Date: Thu, 30 May 2024 10:49:52 +0200 Subject: [PATCH 11/18] fix(granular-output): set `doCheck = false` for libraries --- cabal2nix/src/Distribution/Nixpkgs/Haskell/FromCabal.hs | 1 + 1 file changed, 1 insertion(+) diff --git a/cabal2nix/src/Distribution/Nixpkgs/Haskell/FromCabal.hs b/cabal2nix/src/Distribution/Nixpkgs/Haskell/FromCabal.hs index b46836186..62faaae72 100644 --- a/cabal2nix/src/Distribution/Nixpkgs/Haskell/FromCabal.hs +++ b/cabal2nix/src/Distribution/Nixpkgs/Haskell/FromCabal.hs @@ -151,6 +151,7 @@ fromPackageDescription overrideDrv haskellResolver nixpkgsResolver missingDeps f LSubLibName subLibName -> (baseDerivation^.pkgid) { pkgName = unqualComponentNameToPackageName subLibName } & isLibrary .~ True & isExecutable .~ False + & doCheck .~ False & libraryDepends .~ convertComponentDerivationBuildInfo (libBuildInfo lib) & buildTarget .~ render (prettyLibraryNameComponent $ libName lib) From b4c9c66f9c886a09dbc163c30d216aeb0a4999e2 Mon Sep 17 00:00:00 2001 From: Marc Jakobi Date: Thu, 30 May 2024 11:01:00 +0200 Subject: [PATCH 12/18] fix(granular-output): build-target for main library --- cabal2nix/src/Distribution/Nixpkgs/Haskell/FromCabal.hs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/cabal2nix/src/Distribution/Nixpkgs/Haskell/FromCabal.hs b/cabal2nix/src/Distribution/Nixpkgs/Haskell/FromCabal.hs index 62faaae72..6a628c1a4 100644 --- a/cabal2nix/src/Distribution/Nixpkgs/Haskell/FromCabal.hs +++ b/cabal2nix/src/Distribution/Nixpkgs/Haskell/FromCabal.hs @@ -12,6 +12,7 @@ import Data.Maybe import Data.Set ( Set ) import qualified Data.Set as Set import Distribution.Compiler +import Distribution.Pretty import Distribution.Nixpkgs.Haskell import qualified Distribution.Nixpkgs.Haskell as Nix import Distribution.Nixpkgs.Haskell.Constraint @@ -153,7 +154,9 @@ fromPackageDescription overrideDrv haskellResolver nixpkgsResolver missingDeps f & isExecutable .~ False & doCheck .~ False & libraryDepends .~ convertComponentDerivationBuildInfo (libBuildInfo lib) - & buildTarget .~ render (prettyLibraryNameComponent $ libName lib) + & buildTarget .~ render (case libName lib of + LMainLibName -> pretty $ packageName (baseDerivation^.pkgid) + name@LSubLibName {} -> prettyLibraryNameComponent name) toExecutableDerivation :: Executable -> Derivation toExecutableDerivation executable = baseDerivation From 87390cc7902edb3b708b625572572dcf1688a871 Mon Sep 17 00:00:00 2001 From: Marc Jakobi Date: Thu, 30 May 2024 11:07:25 +0200 Subject: [PATCH 13/18] tests(granular-output): update golden file --- cabal2nix/test/golden-test-cases-granular/ttrie.nix.golden | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cabal2nix/test/golden-test-cases-granular/ttrie.nix.golden b/cabal2nix/test/golden-test-cases-granular/ttrie.nix.golden index edd1260d5..b939c2ab0 100644 --- a/cabal2nix/test/golden-test-cases-granular/ttrie.nix.golden +++ b/cabal2nix/test/golden-test-cases-granular/ttrie.nix.golden @@ -12,7 +12,8 @@ ttrie = mkDerivation { libraryHaskellDepends = [ atomic-primops base hashable primitive stm ]; - buildTarget = "lib"; + doCheck = false; + buildTarget = "ttrie"; homepage = "http://github.com/mcschroeder/ttrie"; description = "Contention-free STM hash map"; license = lib.licenses.mit; From ab95db8d33985f9b75b0205369e63cae3291d4ed Mon Sep 17 00:00:00 2001 From: Marc Jakobi Date: Thu, 30 May 2024 13:03:43 +0200 Subject: [PATCH 14/18] refactor: rename shadowing argument --- .../src/Distribution/Nixpkgs/Haskell/TargetDerivations.hs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cabal2nix/src/Distribution/Nixpkgs/Haskell/TargetDerivations.hs b/cabal2nix/src/Distribution/Nixpkgs/Haskell/TargetDerivations.hs index 0e3f85c10..4d7da9c6d 100644 --- a/cabal2nix/src/Distribution/Nixpkgs/Haskell/TargetDerivations.hs +++ b/cabal2nix/src/Distribution/Nixpkgs/Haskell/TargetDerivations.hs @@ -71,12 +71,12 @@ allInputs TargetDerivations {..} = Set.filter (`notElem` internalLibNames) $ Set internalLibNames = drvName <$> _libraries instance Pretty TargetDerivations where - pPrint targetDerivations = funargs (map text ("mkDerivation" : toAscList (allInputs targetDerivations))) $$ vcat + pPrint targetDrvs = funargs (map text ("mkDerivation" : toAscList (allInputs targetDrvs))) $$ vcat [ text "let" - , vcat $ derivationAttr <$> targetDerivations^.allDerivations + , vcat $ derivationAttr <$> targetDrvs^.allDerivations , text "in" <+> lbrace , nest 2 $ text "inherit" - , nest 4 $ vcat $ pPrint . packageName <$> targetDerivations^.allDerivations + , nest 4 $ vcat $ pPrint . packageName <$> targetDrvs^.allDerivations , nest 4 semi , rbrace ] From 6a175e0b1f52cd6dcf6b95e414538fdc63f863d5 Mon Sep 17 00:00:00 2001 From: Marc Jakobi Date: Thu, 30 May 2024 16:16:18 +0200 Subject: [PATCH 15/18] feat(granular-output): attrsets for exes, testExes and benchExes --- .../Nixpkgs/Haskell/TargetDerivations.hs | 29 +++-- .../ttrie.nix.golden | 101 +++++++++--------- 2 files changed, 74 insertions(+), 56 deletions(-) diff --git a/cabal2nix/src/Distribution/Nixpkgs/Haskell/TargetDerivations.hs b/cabal2nix/src/Distribution/Nixpkgs/Haskell/TargetDerivations.hs index 4d7da9c6d..d6bf7d3f1 100644 --- a/cabal2nix/src/Distribution/Nixpkgs/Haskell/TargetDerivations.hs +++ b/cabal2nix/src/Distribution/Nixpkgs/Haskell/TargetDerivations.hs @@ -73,16 +73,33 @@ allInputs TargetDerivations {..} = Set.filter (`notElem` internalLibNames) $ Set instance Pretty TargetDerivations where pPrint targetDrvs = funargs (map text ("mkDerivation" : toAscList (allInputs targetDrvs))) $$ vcat [ text "let" - , vcat $ derivationAttr <$> targetDrvs^.allDerivations - , text "in" <+> lbrace - , nest 2 $ text "inherit" - , nest 4 $ vcat $ pPrint . packageName <$> targetDrvs^.allDerivations - , nest 4 semi - , rbrace + , nest 2 $ vcat $ derivationAttr <$> targetDrvs^.libraries + , text "in" <+> lbrace $$ nest 2 (vcat + [ attr "libraries" $ hcat + [ lbrace + , text "inherit" + , text " " + , hcat (pPrint . packageName <$> targetDrvs^.libraries) + , semi + , rbrace + ] + , attr "exes" $ derivationAttrs $ targetDrvs^.exes + , attr "testExes" $ derivationAttrs $ targetDrvs^.testExes + , attr "benchExes" $ derivationAttrs $ targetDrvs^.benchExes + , nest (-2) rbrace + ]) ] derivationAttr :: Derivation -> Doc derivationAttr drv = attr (drvName drv) $ pPrint drv +derivationAttrs :: [Derivation] -> Doc +derivationAttrs [] = lbrace <+> rbrace +derivationAttrs drvs = vcat + [ lbrace + , nest (-8) $ vcat (derivationAttr <$> drvs) + , nest (-11) rbrace + ] + drvName :: Derivation -> String drvName drv = unPackageName $ packageName $ drv^.pkgid diff --git a/cabal2nix/test/golden-test-cases-granular/ttrie.nix.golden b/cabal2nix/test/golden-test-cases-granular/ttrie.nix.golden index b939c2ab0..2118e961c 100644 --- a/cabal2nix/test/golden-test-cases-granular/ttrie.nix.golden +++ b/cabal2nix/test/golden-test-cases-granular/ttrie.nix.golden @@ -5,55 +5,56 @@ , unordered-containers, vector }: let -ttrie = mkDerivation { - pname = "ttrie"; - version = "0.1.2.1"; - sha256 = "deadbeef"; - libraryHaskellDepends = [ - atomic-primops base hashable primitive stm - ]; - doCheck = false; - buildTarget = "ttrie"; - homepage = "http://github.com/mcschroeder/ttrie"; - description = "Contention-free STM hash map"; - license = lib.licenses.mit; - }; -map-properties = mkDerivation { - pname = "map-properties"; - version = "0.1.2.1"; - sha256 = "deadbeef"; - isLibrary = false; - isExecutable = true; - testHaskellDepends = [ - base containers hashable QuickCheck stm test-framework - test-framework-quickcheck2 ttrie - ]; - buildTarget = "map-properties"; - homepage = "http://github.com/mcschroeder/ttrie"; - description = "Contention-free STM hash map"; - license = lib.licenses.mit; - }; -bench = mkDerivation { - pname = "bench"; - version = "0.1.2.1"; - sha256 = "deadbeef"; - isLibrary = false; - isExecutable = true; - benchmarkHaskellDepends = [ - async base bifunctors containers criterion-plus deepseq mwc-random - primitive stm stm-containers stm-stats text transformers ttrie - unordered-containers vector - ]; - doBenchmark = true; - buildTarget = "bench"; - homepage = "http://github.com/mcschroeder/ttrie"; - description = "Contention-free STM hash map"; - license = lib.licenses.mit; - }; + ttrie = mkDerivation { + pname = "ttrie"; + version = "0.1.2.1"; + sha256 = "deadbeef"; + libraryHaskellDepends = [ + atomic-primops base hashable primitive stm + ]; + doCheck = false; + buildTarget = "ttrie"; + homepage = "http://github.com/mcschroeder/ttrie"; + description = "Contention-free STM hash map"; + license = lib.licenses.mit; + }; in { - inherit - ttrie - map-properties - bench - ; + libraries = {inherit ttrie;}; + exes = { }; + testExes = { + map-properties = mkDerivation { + pname = "map-properties"; + version = "0.1.2.1"; + sha256 = "deadbeef"; + isLibrary = false; + isExecutable = true; + testHaskellDepends = [ + base containers hashable QuickCheck stm test-framework + test-framework-quickcheck2 ttrie + ]; + buildTarget = "map-properties"; + homepage = "http://github.com/mcschroeder/ttrie"; + description = "Contention-free STM hash map"; + license = lib.licenses.mit; + }; + }; + benchExes = { + bench = mkDerivation { + pname = "bench"; + version = "0.1.2.1"; + sha256 = "deadbeef"; + isLibrary = false; + isExecutable = true; + benchmarkHaskellDepends = [ + async base bifunctors containers criterion-plus deepseq mwc-random + primitive stm stm-containers stm-stats text transformers ttrie + unordered-containers vector + ]; + doBenchmark = true; + buildTarget = "bench"; + homepage = "http://github.com/mcschroeder/ttrie"; + description = "Contention-free STM hash map"; + license = lib.licenses.mit; + }; + }; } From 09899815ffec19111fb9f4b504ce1261e44c822f Mon Sep 17 00:00:00 2001 From: Marc Jakobi Date: Mon, 3 Jun 2024 11:00:09 +0200 Subject: [PATCH 16/18] chore: tweak nesting --- .../src/Distribution/Nixpkgs/Haskell/TargetDerivations.hs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cabal2nix/src/Distribution/Nixpkgs/Haskell/TargetDerivations.hs b/cabal2nix/src/Distribution/Nixpkgs/Haskell/TargetDerivations.hs index d6bf7d3f1..240ba1f06 100644 --- a/cabal2nix/src/Distribution/Nixpkgs/Haskell/TargetDerivations.hs +++ b/cabal2nix/src/Distribution/Nixpkgs/Haskell/TargetDerivations.hs @@ -97,8 +97,8 @@ derivationAttrs :: [Derivation] -> Doc derivationAttrs [] = lbrace <+> rbrace derivationAttrs drvs = vcat [ lbrace - , nest (-8) $ vcat (derivationAttr <$> drvs) - , nest (-11) rbrace + , vcat (derivationAttr <$> drvs) + , rbrace ] drvName :: Derivation -> String From 761250c2c2ae25786da75f59af97cd2f14807398 Mon Sep 17 00:00:00 2001 From: Marc Jakobi Date: Mon, 3 Jun 2024 11:34:16 +0200 Subject: [PATCH 17/18] build: add golden-test-cases-granular to extra-source-files --- cabal2nix/cabal2nix.cabal | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cabal2nix/cabal2nix.cabal b/cabal2nix/cabal2nix.cabal index 52c2dd13a..0a6f8c6cb 100644 --- a/cabal2nix/cabal2nix.cabal +++ b/cabal2nix/cabal2nix.cabal @@ -21,6 +21,8 @@ extra-source-files: README.md CHANGELOG.md test/golden-test-cases/*.cabal test/golden-test-cases/*.nix.golden + test/golden-test-cases-granular/*.cabal + test/golden-test-cases-granular/*.nix.golden cabal-version: 1.24 source-repository head From bbcfeaa1b1fc9e34ec21c658ed061ccf07f2b751 Mon Sep 17 00:00:00 2001 From: Marc Jakobi Date: Mon, 3 Jun 2024 11:46:24 +0200 Subject: [PATCH 18/18] test: update granular/ttrie.nix.golden --- .../ttrie.nix.golden | 50 +++++++++---------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/cabal2nix/test/golden-test-cases-granular/ttrie.nix.golden b/cabal2nix/test/golden-test-cases-granular/ttrie.nix.golden index 2118e961c..044cd4ad8 100644 --- a/cabal2nix/test/golden-test-cases-granular/ttrie.nix.golden +++ b/cabal2nix/test/golden-test-cases-granular/ttrie.nix.golden @@ -22,39 +22,39 @@ in { libraries = {inherit ttrie;}; exes = { }; testExes = { - map-properties = mkDerivation { - pname = "map-properties"; + map-properties = mkDerivation { + pname = "map-properties"; + version = "0.1.2.1"; + sha256 = "deadbeef"; + isLibrary = false; + isExecutable = true; + testHaskellDepends = [ + base containers hashable QuickCheck stm test-framework + test-framework-quickcheck2 ttrie + ]; + buildTarget = "map-properties"; + homepage = "http://github.com/mcschroeder/ttrie"; + description = "Contention-free STM hash map"; + license = lib.licenses.mit; + }; + }; + benchExes = { + bench = mkDerivation { + pname = "bench"; version = "0.1.2.1"; sha256 = "deadbeef"; isLibrary = false; isExecutable = true; - testHaskellDepends = [ - base containers hashable QuickCheck stm test-framework - test-framework-quickcheck2 ttrie + benchmarkHaskellDepends = [ + async base bifunctors containers criterion-plus deepseq mwc-random + primitive stm stm-containers stm-stats text transformers ttrie + unordered-containers vector ]; - buildTarget = "map-properties"; + doBenchmark = true; + buildTarget = "bench"; homepage = "http://github.com/mcschroeder/ttrie"; description = "Contention-free STM hash map"; license = lib.licenses.mit; }; - }; - benchExes = { - bench = mkDerivation { - pname = "bench"; - version = "0.1.2.1"; - sha256 = "deadbeef"; - isLibrary = false; - isExecutable = true; - benchmarkHaskellDepends = [ - async base bifunctors containers criterion-plus deepseq mwc-random - primitive stm stm-containers stm-stats text transformers ttrie - unordered-containers vector - ]; - doBenchmark = true; - buildTarget = "bench"; - homepage = "http://github.com/mcschroeder/ttrie"; - description = "Contention-free STM hash map"; - license = lib.licenses.mit; }; - }; }