git.iko.soy/typeable/stackage2nix
on master help sign in
Parse stack.yaml
commitd8bcd31431b0d2ace7edf77f0c920dc58eaf9a6e authorDmitry Bushev <bushevdv@gmail.com> dateSun 21 May 2017, 21:06 (9 years ago) parent7eeb0a6
7 files changed+174−22
app/Main.hs+2−1 src/Distribution/Nixpkgs/Haskell/Stack.hs+54−16 src/Stack/Yaml.hs+54 stack.yaml+1−1 stack2nix.cabal+14−2 test/Spec.hs+1−2 test/Stack/YamlSpec.hs+48
app/Main.hs+2−1
@@ -27,7 +27,8 @@ pinfo = info
2727 ( fullDesc
2828 <> header "stack2nix converts Stack files into build instructions for Nix." )
2929
30+
3031main :: IO ()
3132main = do
3233 Options {..} <- execParser pinfo
33− print nixpkgsOverride
34+ print $ nixpkgsOverride overrideConfigFixture
src/Distribution/Nixpkgs/Haskell/Stack.hs+54−16
@@ -1,22 +1,60 @@
1+{-# LANGUAGE OverloadedStrings, GeneralizedNewtypeDeriving #-}
2+{-# LANGUAGE RecordWildCards #-}
3+
14module Distribution.Nixpkgs.Haskell.Stack where
25
3−import Text.PrettyPrint
6+import Language.Nix
7+import Language.Nix.PrettyPrinting
8+
9+data StackConfig = StackConfig
10+ { stackageVersion :: String }
11+
12+data OverrideConfig = OverrideConfig
13+ { stackageCompilerConfig :: FilePath
14+ -- ^ Nixpkgs compiler config for Stackage packages set
15+ , stackagePackagesConfig :: FilePath
16+ -- ^ Nixpkgs packages config for Stackage packages set
17+ , haskellPackagesOverride :: Identifier
18+ -- ^ 'pkgs.haskell.packages.<compiler>' to override
19+ }
20+
21+overrideConfigFixture :: OverrideConfig
22+overrideConfigFixture = OverrideConfig
23+ { stackageCompilerConfig = "./haskell-modules/configuration-6_30.nix"
24+ , stackagePackagesConfig = "./haskell-modules/packages-6_30.nix"
25+ , haskellPackagesOverride = "ghc7103" }
26+
27+stackageCompilerConfigFun :: FilePath -> Doc
28+stackageCompilerConfigFun p =
29+ funargs [text "superPkgs"] $$ "import" <+> string p
30+ <+> lbrace
31+ <+> text "inherit (superPkgs) pkgs;"
32+ <+> rbrace
33+
34+nixLet :: [Doc] -> Doc
35+nixLet ls = vcat
36+ [ text "let"
37+ , nest 2 $ vcat ls
38+ ]
439
5−nixpkgsOverride :: Doc
6−nixpkgsOverride = vcat
40+nixpkgsOverride :: OverrideConfig -> Doc
41+nixpkgsOverride OverrideConfig {..} = vcat
742 [ text "{ nixpkgs ? import <nixpkgs> {}, compiler ? \"default\" }: "
843 , text ""
9− , text "let"
10− , text " inherit (nixpkgs.stdenv.lib) extends;"
11− , text " packageOverrides = super: let self = super.pkgs; in"
12− , text " {"
13− , text " pkgs = super.pkgs // {"
14− , text " haskell = super.pkgs.haskell // {"
15− , text " packages = super.pkgs.haskell.packages // {"
16− , text " ${compiler} = super.pkgs.haskell.packages.ghc7103.override {};"
17− , text " };"
18− , text " };"
19− , text " };"
20− , text " };"
21− , text "in packageOverrides nixpkgs"
44+ , nixLet
45+ [ text "inherit (nixpkgs.stdenv.lib) extends;"
46+ , attr "stackageCompilerConfig" $ stackageCompilerConfigFun stackageCompilerConfig
47+ , attr "stackagePackagesConfig" $ stackageCompilerConfigFun stackagePackagesConfig
48+ , text "packageOverrides = super: let self = super.pkgs; in"
49+ , text "{"
50+ , text " pkgs = super.pkgs // {"
51+ , text " haskell = super.pkgs.haskell // {"
52+ , text " packages = super.pkgs.haskell.packages // {"
53+ , text " \"${compiler}\" = super.pkgs.haskell.packages." <> disp haskellPackagesOverride <> ".override {};"
54+ , text " };"
55+ , text " };"
56+ , text " };"
57+ , text "};"
58+ , text "in packageOverrides nixpkgs"
59+ ]
2260 ]
src/Stack/Yaml.hsnew file+54
@@ -0,0 +1,54 @@
1+{-# LANGUAGE OverloadedStrings #-}
2+
3+module Stack.Yaml where
4+
5+import Control.Applicative
6+import Data.Aeson
7+import Data.Text as T
8+
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+
21+data Location a = Location
22+ { _lLocation :: a
23+ , _lExtraDep :: Maybe Bool
24+ } deriving (Eq, Show)
25+
26+instance FromJSON a => FromJSON (Location a) where
27+ parseJSON = withObject "Location" $ \v ->
28+ Location <$>
29+ v .: "location" <*>
30+ v .:? "extra-dep"
31+
32+data Git = Git
33+ { _rGit :: Text
34+ , _rCommit :: Text
35+ } deriving (Eq, Show)
36+
37+instance FromJSON Git where
38+ parseJSON = withObject "Git" $ \v ->
39+ Git <$>
40+ v .: "git" <*>
41+ v .: "commit"
42+
43+data Config = Config
44+ { _cResolver :: Text
45+ , _cPackages :: [Package]
46+ , _cExtraDeps :: [Text]
47+ } deriving (Eq, Show)
48+
49+instance FromJSON Config where
50+ parseJSON = withObject "Config" $ \v ->
51+ Config <$>
52+ v .: "resolver" <*>
53+ v .: "packages" <*>
54+ v .: "extra-deps"
stack.yaml+1−1
@@ -1,3 +1,3 @@
1−resolver: lts-8.12
1+resolver: lts-8.15
22packages:
33- '.'
stack2nix.cabal+14−2
@@ -14,9 +14,16 @@ cabal-version: >=1.10
1414library
1515 hs-source-dirs: src
1616 exposed-modules: Distribution.Nixpkgs.Haskell.Stack
17− build-depends: base > 4.7 && < 5
18− , pretty > 1.1 && < 2
17+ , Stack.Yaml
18+ build-depends: aeson > 1.0 && < 1.1
19+ , base > 4.7 && < 5
20+ , distribution-nixpkgs > 1 && < 1.1
21+ , language-nix > 2.1 && < 2.2
22+ , pretty > 1.1 && < 1.2
23+ , text > 1.2 && < 1.3
24+ , yaml > 0.8 && < 0.9
1925 default-language: Haskell2010
26+ ghc-options: -Wall
2027
2128executable stack2nix
2229 hs-source-dirs: app
@@ -32,7 +39,12 @@ test-suite spec
3239 hs-source-dirs: test
3340 main-is: Spec.hs
3441 build-depends: base
42+ , bytestring > 0.10 && < 0.11
43+ , hspec
44+ , shakespeare
3545 , stack2nix
46+ , text
47+ , yaml
3648 ghc-options: -threaded -rtsopts -with-rtsopts=-N
3749 default-language: Haskell2010
3850
test/Spec.hs+1−2
@@ -1,2 +1 @@
1−main :: IO ()
2−main = putStrLn "Test suite not yet implemented"
1+{-# OPTIONS_GHC -F -pgmF hspec-discover #-}
test/Stack/YamlSpec.hsnew file+48
@@ -0,0 +1,48 @@
1+{-# LANGUAGE OverloadedStrings #-}
2+{-# LANGUAGE QuasiQuotes #-}
3+
4+module Stack.YamlSpec where
5+
6+import Data.ByteString
7+import Data.Text.Encoding as T
8+import Data.Yaml as Y
9+import Stack.Yaml
10+import Test.Hspec
11+import Text.Shakespeare.Text
12+
13+configYaml :: ByteString
14+configYaml = T.encodeUtf8 [st|
15+resolver: lts-3.7
16+packages:
17+ - .
18+ - location: dir1/dir2
19+ - location: https://example.com/foo/bar/baz-0.0.2.tar.gz
20+ extra-dep: true
21+ - location:
22+ git: git@github.com:commercialhaskell/stack.git
23+ commit: 6a86ee32e5b869a877151f74064572225e1a0398
24+# Comment
25+extra-deps:
26+- acme-missiles-0.3
27+|]
28+
29+config :: Config
30+config = Config
31+ { _cResolver = "lts-3.7"
32+ , _cPackages =
33+ [ Simple "."
34+ , LocationSimple (Location "dir1/dir2" Nothing)
35+ , LocationSimple (Location "https://example.com/foo/bar/baz-0.0.2.tar.gz" (Just True))
36+ , LocationGit $ Location
37+ (Git
38+ "git@github.com:commercialhaskell/stack.git"
39+ "6a86ee32e5b869a877151f74064572225e1a0398")
40+ Nothing]
41+ , _cExtraDeps =
42+ ["acme-missiles-0.3"]
43+ }
44+
45+spec :: Spec
46+spec = describe "Config" $
47+ it "parsed" $
48+ (Y.decode configYaml :: Maybe Config) `shouldBe` Just config