Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: --granular-output flag #624

Draft
wants to merge 18 commits into
base: master
Choose a base branch
from
Draft
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
4 changes: 4 additions & 0 deletions cabal2nix/cabal2nix.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -44,7 +46,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
Expand Down
29 changes: 16 additions & 13 deletions cabal2nix/hackage2nix/Main.hs
Original file line number Diff line number Diff line change
Expand Up @@ -155,21 +155,24 @@ main = do
attr :: String
attr = if isInDefaultPackageSet then unPackageName name else mangle pkgId

drv :: Derivation
drv = fromGenericPackageDescription haskellResolver nixpkgsResolver targetPlatform (compilerInfo config) flagAssignment [] descr
& src .~ urlDerivationSource ("mirror://hackage/" ++ display pkgId ++ ".tar.gz") tarballSHA256
& editedCabalFile .~ cabalSHA256
-- If a list of platforms is set in the hackage2nix configuration file, prefer that.
-- Otherwise a list defined by PostProcess or Nothing is used.
& metaSection.platforms %~ (Map.lookup name (supportedPlatforms config) <|>)
& metaSection.badPlatforms %~ (Map.lookup name (unsupportedPlatforms config) <|>)
& metaSection.hydraPlatforms %~ (if isHydraEnabled then id else const (Just Set.empty))
& metaSection.broken ||~ isBroken
& metaSection.maintainers .~ Map.findWithDefault Set.empty name globalPackageMaintainers
& metaSection.homepage .~ ""
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 :: PackageNix
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)

Expand Down
54 changes: 31 additions & 23 deletions cabal2nix/src/Cabal2nix.hs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ data Options = Options
, optHackageDb :: Maybe FilePath
, optNixShellOutput :: Bool
, optFlags :: [String]
, optOutputGranularity :: OutputGranularity
, optCompiler :: CompilerId
, optSystem :: Platform
, optSubpath :: Maybe FilePath
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -173,7 +176,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 PackageNix)
cabal2nix' opts@Options{..} = do
pkg <- getPackage optHpack optFetchSubmodules optHackageDb optHackageSnapshot $
Source {
Expand All @@ -186,7 +189,7 @@ cabal2nix' opts@Options{..} = do
}
processPackage opts pkg

cabal2nixWithDB :: DB.HackageDB -> Options -> IO (Either Doc Derivation)
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"
Expand All @@ -201,7 +204,7 @@ cabal2nixWithDB db opts@Options{..} = do
}
processPackage opts pkg

processPackage :: Options -> Package -> IO (Either Doc Derivation)
processPackage :: Options -> Package -> IO (Either Doc PackageNix)
processPackage Options{..} pkg = do
let
withHpackOverrides :: Derivation -> Derivation
Expand All @@ -210,26 +213,31 @@ 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 :: PackageNix
deriv = fromGenericPackageDescription overrideDrv
(const True)
optNixpkgsIdentifier
optSystem
(unknownCompilerInfo optCompiler NoAbiTag)
flags
optOutputGranularity
[]
(pkgCabal pkg)

shell :: Doc
shell = vcat
Expand Down
4 changes: 4 additions & 0 deletions cabal2nix/src/Distribution/Nixpkgs/Haskell.hs
Original file line number Diff line number Diff line change
@@ -1,8 +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
32 changes: 32 additions & 0 deletions cabal2nix/src/Distribution/Nixpkgs/Haskell/ComponentDerivations.hs
Original file line number Diff line number Diff line change
@@ -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.

61 changes: 43 additions & 18 deletions cabal2nix/src/Distribution/Nixpkgs/Haskell/Derivation.hs
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,14 @@
{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses #-}

module Distribution.Nixpkgs.Haskell.Derivation
( Derivation, nullDerivation, pkgid, revision, src, subpath, isLibrary, isExecutable
( Derivation, SingleDerivation
, singleDerivation, 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, inputs
)
where

Expand Down Expand Up @@ -56,6 +59,7 @@ data Derivation = MkDerivation
, _jailbreak :: Bool
, _doCheck :: Bool
, _doBenchmark :: Bool
, _buildTarget :: String
, _testTarget :: String
, _hyperlinkSource :: Bool
, _enableLibraryProfiling :: Bool
Expand All @@ -79,16 +83,17 @@ 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"
, _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"
Expand All @@ -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)
Expand All @@ -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)
Expand All @@ -144,16 +150,35 @@ 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
{ _singleDerivation :: Derivation }
deriving (Show, Generic)

makeLenses ''SingleDerivation

nullSingleDerivation :: SingleDerivation
nullSingleDerivation = SingleDerivation
{ _singleDerivation = error "undefined SingleDerivation.derivation"
}

instance NFData SingleDerivation

instance Pretty SingleDerivation where
pPrint SingleDerivation {..} = funargs (map text ("mkDerivation" : toAscList (inputs _singleDerivation))) $$
pPrint _singleDerivation
Loading
Loading