git.iko.soy/typeable/stackage2nix
on master help sign in
Add: generate derivation from Stack extra-deps
commit596bf031104956275daa3b97a51086ef35df2acd authorDmitry Bushev <bushevdv@gmail.com> dateTue 23 May 2017, 23:27 (9 years ago) parent14ce143
4 files changed+166−23
src/Distribution/Nixpkgs/Haskell/Stack.hs+54−3 src/Stack/Config.hs+78 src/Stack/Yaml.hs → src/Stack/Config/Yaml.hs+26−17 stack2nix.cabal+8−3
src/Distribution/Nixpkgs/Haskell/Stack.hs+54−3
@@ -1,13 +1,21 @@
1+{-# LANGUAGE TemplateHaskell #-}
12{-# LANGUAGE OverloadedStrings, GeneralizedNewtypeDeriving #-}
23{-# LANGUAGE RecordWildCards #-}
34
45module Distribution.Nixpkgs.Haskell.Stack where
56
7+import Control.Lens
8+import Data.Text as T
9+import Distribution.System as System
10+import Distribution.Compiler as Compiler
11+import Distribution.PackageDescription as PackageDescription
12+import Distribution.Nixpkgs.Fetch
13+import Distribution.Nixpkgs.Haskell.Derivation
14+import Distribution.Nixpkgs.Haskell.FromCabal as FromCabal
15+import Distribution.Nixpkgs.Haskell.PackageSourceSpec as PackageSourceSpec
616import Language.Nix
717import Language.Nix.PrettyPrinting
8−
9−data StackConfig = StackConfig
10− { stackageVersion :: String }
18+import Stack.Config
1119
1220data OverrideConfig = OverrideConfig
1321 { stackageCompilerConfig :: FilePath
@@ -58,3 +66,46 @@ nixpkgsOverride OverrideConfig {..} = vcat
5866 , text "in packageOverrides nixpkgs"
5967 ]
6068 ]
69+
70+-- TODO: maybe move to module Stack.Derivation
71+
72+newtype HackageDb = HackageDb { fromHackageDB :: T.Text }
73+ deriving (Eq, Ord, Show)
74+
75+makePrisms ''HackageDb
76+
77+unHackageDb :: HackageDb -> String
78+unHackageDb = T.unpack . fromHackageDB
79+
80+-- Thin wrapper around private stack2nix 'PackageSourceSpec.fromDB' method.
81+getPackageFromDb
82+ :: Maybe HackageDb
83+ -> StackExtraDep
84+ -> IO Package
85+getPackageFromDb optHackageDb stackExtraDep =
86+ PackageSourceSpec.getPackage (unHackageDb <$> optHackageDb) (extraDepToSource stackExtraDep)
87+
88+extraDepToSource :: StackExtraDep -> Source
89+extraDepToSource sed = Source{..}
90+ where
91+ sourceUrl = "cabal://" ++ unExtraDep sed
92+ sourceRevision = mempty
93+ sourceHash = UnknownHash
94+
95+extraDepDerivation
96+ :: Maybe HackageDb
97+ -> System.Platform
98+ -> Compiler.CompilerInfo
99+ -> PackageDescription.FlagAssignment
100+ -> StackExtraDep
101+ -> IO Derivation
102+extraDepDerivation optHackageDb optPlatform optCompilerInfo optFlagAssignment sed =
103+ FromCabal.fromGenericPackageDescription
104+ (const True)
105+ (\i -> Just (binding # (i, path # [i])))
106+ optPlatform
107+ optCompilerInfo
108+ optFlagAssignment
109+ []
110+ . pkgCabal
111+ <$> getPackageFromDb optHackageDb sed
src/Stack/Config.hsnew file+78
@@ -0,0 +1,78 @@
1+{-# LANGUAGE LambdaCase #-}
2+{-# LANGUAGE RecordWildCards #-}
3+{-# LANGUAGE TemplateHaskell #-}
4+
5+module Stack.Config where
6+
7+import Control.Lens
8+import Data.Coerce
9+import Data.Maybe
10+import Data.Text as T
11+import Stack.Config.Yaml as Yaml
12+
13+newtype StackResolver = StackResolver { fromStackResolver :: Text }
14+ deriving (Eq, Ord, Show)
15+
16+makePrisms ''StackResolver
17+
18+unStackResolver :: StackResolver -> String
19+unStackResolver = T.unpack . fromStackResolver
20+
21+data RepoGit = RepoGit
22+ { _rgUri :: Text
23+ , _rgCommit :: Text
24+ } deriving (Eq, Ord, Show)
25+
26+makeLenses ''RepoGit
27+
28+data StackLocation
29+ = StackPath Text
30+ | StackRepoGit RepoGit
31+ deriving (Eq, Ord, Show)
32+
33+makePrisms ''StackLocation
34+
35+data StackPackage = StackPackage
36+ { _spLocation :: StackLocation
37+ , _spExtraDep :: Bool
38+ } deriving (Eq, Ord, Show)
39+
40+makeLenses ''StackPackage
41+
42+newtype StackExtraDep = StackExtraDep { fromStackExtraDep :: Text }
43+ deriving (Eq, Ord, Show)
44+
45+makePrisms ''StackExtraDep
46+
47+unExtraDep :: StackExtraDep -> String
48+unExtraDep = T.unpack . fromStackExtraDep
49+
50+data StackConfig = StackConfig
51+ { _scResolver :: StackResolver
52+ , _scPackages :: [StackPackage]
53+ , _scExtraDeps :: [StackExtraDep]
54+ } deriving (Eq, Ord, Show)
55+
56+makeLenses ''StackConfig
57+
58+fromYamlConfig :: Yaml.Config -> StackConfig
59+fromYamlConfig c = StackConfig{..}
60+ where
61+ _scResolver = coerce $ c ^. cResolver
62+ _scPackages = fromYamlPackage <$> c ^. cPackages
63+ _scExtraDeps = StackExtraDep <$> c ^. cExtraDeps
64+
65+fromYamlPackage :: Yaml.Package -> StackPackage
66+fromYamlPackage = \case
67+ Yaml.Simple path ->
68+ StackPackage (StackPath path) False
69+ Yaml.LocationSimple (Yaml.Location path extraDep) ->
70+ StackPackage (StackPath path) (fromMaybe False extraDep)
71+ Yaml.LocationGit (Location git extraDep) ->
72+ StackPackage (StackRepoGit $ fromYamlGit git) (fromMaybe False extraDep)
73+
74+fromYamlGit :: Yaml.Git -> RepoGit
75+fromYamlGit yg = RepoGit{..}
76+ where
77+ _rgUri = yg ^. gGit
78+ _rgCommit = yg ^. gCommit
src/Stack/Yaml.hs → src/Stack/Config/Yaml.hsrenamed+26−17
@@ -1,28 +1,20 @@
1+{-# LANGUAGE TemplateHaskell #-}
12{-# LANGUAGE OverloadedStrings #-}
23
3−module Stack.Yaml where
4+module Stack.Config.Yaml where
45
56import Control.Applicative
7+import Control.Lens
68import Data.Aeson
79import Data.Text as T
810
9−data Package
10− = Simple Text
11− | LocationSimple (Location Text)
12− | LocationGit (Location Git)
13− deriving (Eq, Show)
14−
15−instance FromJSON Package where
16− parseJSON v =
17− (Simple <$> parseJSON v) <|>
18− (LocationSimple <$> parseJSON v) <|>
19− (LocationGit <$> parseJSON v)
20−
2111data Location a = Location
2212 { _lLocation :: a
2313 , _lExtraDep :: Maybe Bool
2414 } deriving (Eq, Show)
2515
16+makeLenses ''Location
17+
2618instance FromJSON a => FromJSON (Location a) where
2719 parseJSON = withObject "Location" $ \v ->
2820 Location <$>
@@ -30,22 +22,39 @@ instance FromJSON a => FromJSON (Location a) where
3022 v .:? "extra-dep"
3123
3224data Git = Git
33− { _rGit :: Text
34− , _rCommit :: Text
25+ { _gGit :: Text
26+ , _gCommit :: Text
3527 } deriving (Eq, Show)
3628
29+makeLenses ''Git
30+
3731instance FromJSON Git where
3832 parseJSON = withObject "Git" $ \v ->
3933 Git <$>
4034 v .: "git" <*>
4135 v .: "commit"
4236
37+data Package
38+ = Simple Text
39+ | LocationSimple (Location Text)
40+ | LocationGit (Location Git)
41+ deriving (Eq, Show)
42+makePrisms ''Package
43+
44+instance FromJSON Package where
45+ parseJSON v =
46+ (Simple <$> parseJSON v) <|>
47+ (LocationSimple <$> parseJSON v) <|>
48+ (LocationGit <$> parseJSON v)
49+
4350data Config = Config
44− { _cResolver :: Text
45− , _cPackages :: [Package]
51+ { _cResolver :: Text
52+ , _cPackages :: [Package]
4653 , _cExtraDeps :: [Text]
4754 } deriving (Eq, Show)
4855
56+makeLenses ''Config
57+
4958instance FromJSON Config where
5059 parseJSON = withObject "Config" $ \v ->
5160 Config <$>
stack2nix.cabal+8−3
@@ -14,11 +14,15 @@ cabal-version: >=1.10
1414library
1515 hs-source-dirs: src
1616 exposed-modules: Distribution.Nixpkgs.Haskell.Stack
17− , Stack.Yaml
18− build-depends: aeson > 1.0 && < 1.1
19− , base > 4.7 && < 5
17+ , Stack.Config
18+ , Stack.Config.Yaml
19+ build-depends: base > 4.7 && < 5
20+ , Cabal > 1.24 && < 1.25
21+ , aeson > 1.0 && < 1.1
22+ , cabal2nix > 2.0 && < 2.1
2023 , distribution-nixpkgs > 1 && < 1.1
2124 , language-nix > 2.1 && < 2.2
25+ , lens > 4.15 && < 4.16
2226 , pretty > 1.1 && < 1.2
2327 , text > 1.2 && < 1.3
2428 , yaml > 0.8 && < 0.9
@@ -38,6 +42,7 @@ test-suite spec
3842 type: exitcode-stdio-1.0
3943 hs-source-dirs: test
4044 main-is: Spec.hs
45+ other-modules: Stack.YamlSpec
4146 build-depends: base
4247 , bytestring > 0.10 && < 0.11
4348 , hspec