packages feed

stackage2nix 0.6.1 → 0.7.0

raw patch · 9 files changed

+477/−106 lines, 9 files

Files

CHANGELOG.md view
@@ -1,13 +1,17 @@-# 0.3.0-- Initial Hackage release-- Add CHANGELOG.md+# 0.7.0+- Add compatibility with nixos-18.03+- Drop compatibility with nixos-17-09+- Add partial support for new stack extra-deps syntax.+  https://docs.haskellstack.org/en/stable/yaml_configuration/#packages-and-extra-deps+  Supported same syntax for packages and extra-deps sections -# 0.4.0-- Add `--resolver` option to generate full stackage packages set-- Add Nix wrapper, see `nix/README.md`-- Upd support cabal2nix >2.5-- Fix honor `--hackage-db` flag+# 0.6.1+- Pass extra `buildHaskellPackages` argument to `makePackageSet` function +# 0.6.0+- Replace call to `<nixpkgs/pkgs/development/haskell-modules>` in generated+  Haskell packages with `makePackageSet` library function+ # 0.5.0 - Add `--with-stackage` and `--with-stackage-closure` flag generates stackage - Add `--extra-deps-revision-latest` flag. Changes generation strategy for the@@ -26,11 +30,12 @@ - Remove `--no-packages-closure` flag (use `--with-stackage-closure`) - Remove `cabal2nix < 2.7.2` support #45 -# 0.6.0--- Replace call to `<nixpkgs/pkgs/development/haskell-modules>` in generated-  Haskell packages with `makePackageSet` library function--# 0.6.1+# 0.4.0+- Add `--resolver` option to generate full stackage packages set+- Add Nix wrapper, see `nix/README.md`+- Upd support cabal2nix >2.5+- Fix honor `--hackage-db` flag -- Pass extra `buildHaskellPackages` argument to `makePackageSet` function+# 0.3.0+- Initial Hackage release+- Add CHANGELOG.md
src/Distribution/Nixpkgs/Haskell/Stack.hs view
@@ -42,22 +42,22 @@   -> Maybe FilePath   -> Source stackLocationToSource pl mCabalDir = case pl of-  HackagePackage p -> Source-    { sourceUrl      = "cabal://" ++ T.unpack p+  PlIndex p    -> Source+    { sourceUrl      = "cabal://" ++ T.unpack (p ^. piNameVersion)     , sourceRevision = mempty     , sourceHash     = UnknownHash     , sourceCabalDir = cabalDir }-  StackFilePath p  -> Source+  PlFilePath p -> Source     { sourceUrl      = p     , sourceRevision = mempty     , sourceHash     = UnknownHash     , sourceCabalDir = cabalDir }-  StackUri uri     -> Source+  PlUri uri    -> Source     { sourceUrl      = URI.uriToString id uri mempty     , sourceRevision = mempty     , sourceHash     = UnknownHash     , sourceCabalDir = cabalDir }-  StackRepo r      -> Source+  PlRepo r     -> Source     { sourceUrl      = T.unpack $ r ^. rUri     , sourceRevision = T.unpack $ r ^. rCommit     , sourceHash     = UnknownHash
src/Distribution/Nixpkgs/Haskell/Stack/PrettyPrinting.hs view
@@ -79,14 +79,16 @@     ]   , "in callPackage (nixpkgs.path + \"/pkgs/development/haskell-modules\") {"   , nest 2 $ vcat-    [ attr "ghc" ("pkgs.haskell.compiler." <> toNixGhcVersion (oc ^. ocGhc))+    [ attr "ghc" ("pkgs.haskell.compiler." <> nixGhc)+    , attr "buildHaskellPackages" ("buildPackages.haskell.packages." <> nixGhc)     , attr "compilerConfig" "self: extends pkgOverrides (stackageConfig self)"     , attr "initialPackages" "stackagePackages"     , attr "configurationCommon" "args: self: super: {}"     , "inherit haskellLib;"     ]   , "}"-  ]+  ] where+        nixGhc = toNixGhcVersion (oc ^. ocGhc)  overrideStackage :: StackResolver -> FilePath -> NonEmpty Derivation -> Doc overrideStackage stackResolver nixpkgsPath packages = vcat@@ -137,7 +139,7 @@     , attr "compilerConfig" . importStackageConfig $ oc ^. ocStackageConfig     , ""     , attr "configurationCommon" "if builtins.pathExists ./configuration-common.nix then import ./configuration-common.nix { inherit pkgs haskellLib; } else self: super: {}"-    , attr "configurationNix" "import <nixpkgs/pkgs/development/haskell-modules/configuration-nix.nix> { inherit pkgs haskellLib; }"+    , attr "configurationNix" "import (pkgs.path + \"/pkgs/development/haskell-modules/configuration-nix.nix\") { inherit pkgs haskellLib; }"     , ""     , attr "extensible-self" "makeExtensible (extends overrides (extends configurationCommon (extends packageSetConfig (extends compilerConfig (extends configurationNix haskellPackages)))))"     ]
src/LtsHaskell.hs view
@@ -52,7 +52,7 @@ getPackageFromDb :: DB.HackageDB -> PackageIdentifier -> IO Package getPackageFromDb hackageDb pkgId =   getStackPackageFromDb hackageDb-  $ StackPackage (HackagePackage (T.pack $ Text.display pkgId)) True Nothing+  $ StackPackage (PlIndex $ PackageIndex (T.pack $ Text.display pkgId) Nothing) True Nothing  loadPackage :: DB.HackageDB -> FilePath -> Maybe SHA1Hash -> PackageIdentifier -> IO Package loadPackage hackageDb allCabalHashesPath mSha1Hash pkgId =
src/Stack/Config.hs view
@@ -9,13 +9,13 @@ import Data.Foldable as F import Data.List.NonEmpty as NE import Data.Maybe-import Data.Semigroup (sconcat)+import Data.Semigroup import Data.Text as T import Data.Yaml import Network.URI import Stack.Config.Yaml as Yaml import Stack.Types-import System.FilePath+import System.FilePath as FilePath   newtype StackResolver = StackResolver { fromStackResolver :: Text }@@ -30,34 +30,48 @@   deriving (Eq, Ord, Show)  data Repo = Repo-  { _rVcs    :: !Vcs-  , _rUri    :: !Text-  , _rCommit :: !Text+  { _rVcs    :: Vcs+  , _rUri    :: Text+  , _rCommit :: Text   } deriving (Eq, Ord, Show)  makeLenses ''Repo +data PackageRevision+  = PrSha256 Text+  | PrRev Text+  deriving (Eq, Ord, Show)++makePrisms ''PackageRevision++data PackageIndex = PackageIndex+  { _piNameVersion :: Text+  , _piRevision    :: Maybe PackageRevision+  } deriving (Eq, Ord, Show)++makeLenses ''PackageIndex+ data PackageLocation-  = HackagePackage Text-  | StackFilePath FilePath-  | StackUri URI-  | StackRepo Repo+  = PlIndex PackageIndex+  | PlFilePath FilePath+  | PlUri URI+  | PlRepo Repo   deriving (Eq, Ord, Show)  makePrisms ''PackageLocation  data StackPackage = StackPackage-  { _spLocation :: !PackageLocation-  , _spExtraDep :: !Bool+  { _spLocation :: PackageLocation+  , _spExtraDep :: Bool     -- | Subdirectory containing the cabal file if any specified.-  , _spDir  :: !(Maybe FilePath)+  , _spDir      :: Maybe FilePath   } deriving (Eq, Ord, Show)  makeLenses ''StackPackage  data StackConfig = StackConfig-  { _scResolver  :: !StackResolver-  , _scPackages  :: !(NonEmpty StackPackage)+  { _scResolver  :: StackResolver+  , _scPackages  :: NonEmpty StackPackage   } deriving (Eq, Ord, Show)  makeLenses ''StackConfig@@ -66,58 +80,101 @@ fromYamlConfig c = StackConfig{..}   where     _scResolver = coerce $ c ^. cResolver-    _scPackages = F.foldr (NE.<|) neYamlPackages yamlExtraDeps-    neYamlPackages = fromMaybe (pure defaultPackage)-                   . fmap sconcat $ NE.nonEmpty yamlPackages-    yamlPackages   = fromYamlPackage <$> (fromMaybe mempty (c ^. cPackages))-    yamlExtraDeps  = fromYamlExtraDep <$> fromMaybe mempty (c ^. cExtraDeps)-    defaultPackage = StackPackage (StackFilePath ".") False Nothing+    -- 'NE.nub' replicates Stack behavior of having a Set of packages rather than list+    _scPackages = NE.nub $ F.foldl' (<>) nePackages yamlExtraDeps+    nePackages = fromMaybe (pure defaultPackage)+      $ fmap sconcat+      $ NE.nonEmpty yamlPackages+    yamlPackages   = fromYamlPackage packagesSimplePath False+      <$> fromMaybe mempty (c ^. cPackages)+    yamlExtraDeps  = fromYamlPackage extraDepsSimplePath True+      <$> fromMaybe mempty (c ^. cExtraDeps)+    defaultPackage = StackPackage (PlFilePath ".") False Nothing +-- | Simple string in a packages section can be an URI or FilePath location+packagesSimplePath :: Text -> StackPackage+packagesSimplePath t = StackPackage (parseSimplePath t) False Nothing +-- | Parse location as URI or a FilePath+parseSimplePath :: Text -> PackageLocation+parseSimplePath (T.unpack -> p) = maybe (PlFilePath p) PlUri $ parseURI p++-- | Simple string in an extra-deps section can be an URI or FilePath or PackageIndex name-version+extraDepsSimplePath :: Text -> StackPackage+extraDepsSimplePath t = StackPackage loc True Nothing+  where+    loc = maybe (parsePackageIndex t) PlUri $ parseURI (T.unpack t)++-- TODO: support new package index format with hash and revision+parsePackageIndex :: Text -> PackageLocation+parsePackageIndex t = if isFilePath t+  then PlFilePath (T.unpack t)+  else PlIndex $ PackageIndex t Nothing++-- Determine wether package is file path+isFilePath :: Text -> Bool+isFilePath = T.any (== FilePath.pathSeparator)++-- | A single 'Yaml.Package' can result in multiple actual+-- packages if it has multiple subdirs specified. fromYamlPackage-  :: Yaml.Package-     -- ^ A single 'Yaml.Package' can result in multiple actual-     -- packages if it has multiple subdirs specified.+  :: (Text -> StackPackage)+  -> Bool+  -> Yaml.Package   -> NonEmpty StackPackage-fromYamlPackage = \case-  Yaml.Simple p                                  ->-    unroll Nothing $ StackPackage (parseSimplePath p) False-  Yaml.LocationSimple (Location p extraDep ms) ->+fromYamlPackage fromSimple isExtraDep = \case+  Yaml.PSimple p                                ->+    pure (fromSimple p)+  Yaml.PLocationSimple (Location p extraDep ms) ->     unroll ms $ StackPackage (parseSimplePath p) (fromMaybe False extraDep)-  Yaml.LocationGit (Location git extraDep ms)       ->-    unroll ms $ StackPackage (StackRepo $ fromYamlGit git) (fromMaybe False extraDep)-  Yaml.LocationHg (Location hg extraDep ms)       ->-    unroll ms $ StackPackage (StackRepo $ fromYamlHg hg) (fromMaybe False extraDep)+  Yaml.PLocationGit loc                         ->+    mkStackPackageRepo fromYamlGit loc+  Yaml.PLocationHg loc                          ->+    mkStackPackageRepo fromYamlHg loc+  Yaml.PArchive a                               ->+    unroll (a ^. aSubdirs) $ StackPackage (a ^. aArchive . to parseSimplePath) isExtraDep+  Yaml.PNewGit ng                               -> unroll (ng ^. ngSubdirs)+    $ StackPackage (PlRepo $ fromYamlNewGit ng) isExtraDep+  Yaml.PNewHg nh                                -> unroll (nh ^. nhSubdirs)+    $ StackPackage (PlRepo $ fromYamlNewHg nh) isExtraDep   where-    parseSimplePath (T.unpack -> p) = maybe (StackFilePath p) StackUri $ parseURI p+    mkStackPackageRepo f loc = unroll (loc ^. lSubdirs)+      $ StackPackage (PlRepo (loc ^. lLocation . to f)) (fromMaybe isExtraDep $ loc ^. lExtraDep)     -- Each package gets a single directory with cabal file in it. If     -- it's not specified, path is empty.     unroll subs p = case subs of       Just (x : xs) -> NE.map (p . Just) (x :| xs)       _ -> p Nothing :| [] -fromYamlExtraDep :: Text -> StackPackage-fromYamlExtraDep t = StackPackage (HackagePackage t) True Nothing- fromYamlGit :: Yaml.Git -> Repo-fromYamlGit yg = Repo{..}-  where-    _rVcs = Vcs "git"-    _rUri = yg ^. gGit-    _rCommit = yg ^. gCommit+fromYamlGit yg = Repo+  { _rVcs    = Vcs "git"+  , _rUri    = yg ^. gGit+  , _rCommit = yg ^. gCommit }  fromYamlHg :: Yaml.Hg -> Repo-fromYamlHg yh = Repo{..}-  where-    _rVcs = Vcs "hg"-    _rUri = yh ^. hHg-    _rCommit = yh ^. hCommit+fromYamlHg yh = Repo+  { _rVcs    = Vcs "hg"+  , _rUri    = yh ^. hHg+  , _rCommit = yh ^. hCommit } +fromYamlNewGit :: NewGit -> Repo+fromYamlNewGit ng = Repo+  { _rVcs    = Vcs "git"+  , _rUri    = ng ^. ngGit+  , _rCommit = ng ^. ngCommit }++fromYamlNewHg :: NewHg -> Repo+fromYamlNewHg nh = Repo+  { _rVcs    = Vcs "hg"+  , _rUri    = nh ^. nhHg+  , _rCommit = nh ^. nhCommit }+ readStackConfig :: StackYaml -> IO (Either String StackConfig) readStackConfig stackYaml = do   let     relativeToStackYaml = \case-      StackFilePath p -> StackFilePath $ stackYaml ^. syDirName </> p+      PlFilePath p -> PlFilePath $ stackYaml ^. syDirName </> p       packageLocation -> packageLocation     mkStackConfig = over (scPackages . traversed . spLocation) relativeToStackYaml       . fromYamlConfig
src/Stack/Config/Yaml.hs view
@@ -8,60 +8,97 @@ import Stack.Config.TH  data Location a = Location-  { _lLocation :: !a-  , _lExtraDep :: !(Maybe Bool)-  , _lSubdirs :: !(Maybe [FilePath])+  { _lLocation :: a+  , _lExtraDep :: Maybe Bool+  , _lSubdirs  :: Maybe [FilePath]   } deriving (Eq, Show)  makeLenses ''Location- deriveJSON jsonOpts ''Location +data Archive = Archive+  { _aArchive :: Text+  , _aSha256  :: Maybe Text+  , _aSubdirs :: Maybe [FilePath]+  } deriving (Eq, Show)++makeLenses ''Archive+deriveJSON jsonOpts ''Archive+ data Git = Git-  { _gGit    :: !Text-  , _gCommit :: !Text+  { _gGit    :: Text+  , _gCommit :: Text   } deriving (Eq, Show)  makeLenses ''Git- deriveJSON jsonOpts ''Git  data Hg = Hg-  { _hHg     :: !Text-  , _hCommit :: !Text+  { _hHg     :: Text+  , _hCommit :: Text   } deriving (Eq, Show)  makeLenses ''Hg- deriveJSON jsonOpts ''Hg +-- New syntax++data NewGit = NewGit+  { _ngGit     :: Text+  , _ngCommit  :: Text+  , _ngSubdirs :: Maybe [FilePath]+  } deriving (Eq, Show)++makeLenses ''NewGit+deriveJSON jsonOpts ''NewGit++data NewHg = NewHg+  { _nhHg      :: Text+  , _nhCommit  :: Text+  , _nhSubdirs :: Maybe [FilePath]+  } deriving (Eq, Show)++makeLenses ''NewHg+deriveJSON jsonOpts ''NewHg+ data Package-  = Simple Text-  | LocationSimple (Location Text)-  | LocationGit (Location Git)-  | LocationHg (Location Hg)+  = PSimple Text+  | PLocationSimple (Location Text)+  | PLocationGit (Location Git)+  | PLocationHg (Location Hg)+  | PArchive Archive+  | PNewGit NewGit+  | PNewHg NewHg   deriving (Eq, Show)  makePrisms ''Package  instance FromJSON Package where   parseJSON v =-    (Simple <$> parseJSON v) <|>-    (LocationSimple <$> parseJSON v) <|>-    (LocationGit <$> parseJSON v) <|>-    (LocationHg <$> parseJSON v)+    (PSimple <$> parseJSON v) <|>+    (PLocationSimple <$> parseJSON v) <|>+    (PLocationGit <$> parseJSON v) <|>+    (PLocationHg <$> parseJSON v) <|>+    (PArchive <$> parseJSON v) <|>+    (PNewGit <$> parseJSON v) <|>+    (PNewHg <$> parseJSON v)  instance ToJSON Package where   toJSON = \case-    Simple t         -> toJSON t-    LocationSimple t -> toJSON t-    LocationGit t    -> toJSON t-    LocationHg t     -> toJSON t+    PSimple t         -> toJSON t+    PLocationSimple t -> toJSON t+    PLocationGit t    -> toJSON t+    PLocationHg t     -> toJSON t+    PArchive t        -> toJSON t+    PNewGit t         -> toJSON t+    PNewHg t          -> toJSON t +-- To support both old and new syntax, we allow all variants of package+-- definitions in "packages" and "extra-deps" sections data Config = Config-  { _cResolver  :: !Text-  , _cPackages  :: !(Maybe [Package])-  , _cExtraDeps :: !(Maybe [Text])+  { _cResolver  :: Text+  , _cPackages  :: Maybe [Package]+  , _cExtraDeps :: Maybe [Package]   } deriving (Eq, Show)  makeLenses ''Config
stackage2nix.cabal view
@@ -1,5 +1,5 @@ name:                stackage2nix-version:             0.6.1+version:             0.7.0 synopsis:            Convert Stack files into Nix build instructions. homepage:            https://github.com/typeable/stackage2nix#readme license:             BSD3@@ -77,6 +77,7 @@                      , Cabal                      , bytestring                      , hspec+                     , network-uri                      , pretty                      , shakespeare                      , stackage2nix@@ -86,6 +87,7 @@   other-modules:       Language.Nix.FilePathSpec                      , PrettyPrintingSpec                      , Stack.Config.YamlSpec+                     , Stack.ConfigSpec   ghc-options:         -Wall -threaded -rtsopts -with-rtsopts=-N   default-language:    Haskell2010 
test/Stack/Config/YamlSpec.hs view
@@ -39,10 +39,48 @@ - acme-missiles-0.3 |] +-- | New yaml config support all package definitions in "extra-deps" section+configNewYaml :: ByteString+configNewYaml = T.encodeUtf8 [st|+resolver: lts-3.7+packages:+  - .+  - location: dir1/dir2+  - location: https://example.com/foo/bar/baz-0.0.2.tar.gz+    extra-dep: true+  - location:+      git: git@github.com:commercialhaskell/stack.git+      commit: 6a86ee32e5b869a877151f74064572225e1a0398+  - location:+      git: git@github.com:example/mega-repo+      commit: 6a86ee32e5b869a877151f74064572225e1a0000+    subdirs:+      - subdir1+      - subdir2+# Comment+extra-deps:+  - acme-missiles-0.3+  - acme-missiles-hash-0.4@sha256:2ba66a092a32593880a87fb00f3213762d7bca65a687d45965778deb8694c5d1+  - acme-missiles-rev-0.5@rev:0+  - git: git@github.com:commercialhaskell/stack.git+    commit: 6a86ee32e5b869a877151f74064572225e1a0398+  - git: git@github.com:example/mega-repo+    commit: 6a86ee32e5b869a877151f74064572225e1a0000+    subdirs:+      - subdir1+      - subdir2+  - archive: http://github.com/yesodweb/wai/archive/2f8a8e1b771829f4a8a77c0111352ce45a14c30f.zip+    subdirs:+    - wai+    - warp+  - archive: ../acme-missiles-0.3.tar.gz+    sha256: e563d8b524017a06b32768c4db8eff1f822f3fb22a90320b7e414402647b735b+|]+ configMinimal :: Config configMinimal = Config   { _cResolver  = "lts-8.15"-  , _cPackages  = Just [ Simple "." ]+  , _cPackages  = Just [ PSimple "." ]   , _cExtraDeps = Nothing   } @@ -50,27 +88,70 @@ config = Config   { _cResolver = "lts-3.7"   , _cPackages = Just-    [ Simple "."-    , LocationSimple (Location "dir1/dir2" Nothing Nothing)-    , LocationSimple (Location "https://example.com/foo/bar/baz-0.0.2.tar.gz" (Just True) Nothing)-    , LocationGit $ Location+    [ PSimple "."+    , PLocationSimple (Location "dir1/dir2" Nothing Nothing)+    , PLocationSimple (Location "https://example.com/foo/bar/baz-0.0.2.tar.gz" (Just True) Nothing)+    , PLocationGit $ Location        (Git         "git@github.com:commercialhaskell/stack.git"         "6a86ee32e5b869a877151f74064572225e1a0398")        Nothing Nothing-    , LocationGit (Location+    , PLocationGit (Location        (Git         "git@github.com:example/mega-repo"         "6a86ee32e5b869a877151f74064572225e1a0000")        Nothing (Just ["subdir1", "subdir2"]))     ]   , _cExtraDeps = Just-    ["acme-missiles-0.3"]+    [PSimple "acme-missiles-0.3"]   } +configNew :: Config+configNew = Config+  { _cResolver = "lts-3.7"+  , _cPackages = Just+    [ PSimple "."+    , PLocationSimple (Location "dir1/dir2" Nothing Nothing)+    , PLocationSimple (Location "https://example.com/foo/bar/baz-0.0.2.tar.gz" (Just True) Nothing)+    , PLocationGit $ Location+       (Git+        "git@github.com:commercialhaskell/stack.git"+        "6a86ee32e5b869a877151f74064572225e1a0398")+       Nothing Nothing+    , PLocationGit (Location+       (Git+        "git@github.com:example/mega-repo"+        "6a86ee32e5b869a877151f74064572225e1a0000")+       Nothing (Just ["subdir1", "subdir2"]))+    ]+  , _cExtraDeps = Just+    [ PSimple "acme-missiles-0.3"+    , PSimple "acme-missiles-hash-0.4@sha256:2ba66a092a32593880a87fb00f3213762d7bca65a687d45965778deb8694c5d1"+    , PSimple "acme-missiles-rev-0.5@rev:0"+    , PNewGit $ NewGit+      "git@github.com:commercialhaskell/stack.git"+      "6a86ee32e5b869a877151f74064572225e1a0398"+      Nothing+    , PNewGit $ NewGit+      "git@github.com:example/mega-repo"+      "6a86ee32e5b869a877151f74064572225e1a0000"+      (Just ["subdir1", "subdir2"])+    , PArchive $ Archive+      "http://github.com/yesodweb/wai/archive/2f8a8e1b771829f4a8a77c0111352ce45a14c30f.zip"+      Nothing+      (Just ["wai", "warp"])+    , PArchive $ Archive+      "../acme-missiles-0.3.tar.gz"+      (Just "e563d8b524017a06b32768c4db8eff1f822f3fb22a90320b7e414402647b735b")+      Nothing+    ]+  }+ spec :: Spec-spec = describe "Parse" $ do-  specify "config-minimal" $+spec = describe "Config" $ do+  specify "minimal" $     (Y.decode configYamlMinimal :: Maybe Config) `shouldBe` Just configMinimal-  specify "config-full" $+  specify "full" $     (Y.decode configYaml :: Maybe Config) `shouldBe` Just config+  specify "new" $+    (Y.decode configNewYaml :: Maybe Config) `shouldBe` Just configNew
+ test/Stack/ConfigSpec.hs view
@@ -0,0 +1,187 @@+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE QuasiQuotes #-}++module Stack.ConfigSpec (spec) where++import Data.ByteString+import Data.List.NonEmpty as NE+import Data.Text.Encoding as T+import Data.Yaml as Y+import Network.URI as URI+import Stack.Config+import Test.Hspec+import Text.Shakespeare.Text+++spec :: Spec+spec = describe "StackConfig" $ do+  specify "minimal"+    $ checkYamlConfig minimalBs minimalConf+  specify "packageDefault"+    $ checkYamlConfig packageDefaultBs packageDefaultConf+  specify "packageSimpleList"+    $ checkYamlConfig packageSimpleListBs packageSimpleListConf+  specify "packageLocations"+    $ checkYamlConfig packageLocationsBs packageLocationsConf+  specify "packageExtraDeps"+    $ checkYamlConfig packageExtraDepsBs packageExtraDepsConf+  specify "packageMixed"+    $ checkYamlConfig packageMixedBs packageMixedConf+  specify "packageExtraDepsNew"+    $ checkYamlConfig packageExtraDepsNewBs packageExtraDepsNewConf++parseYamlConfig :: ByteString -> Maybe StackConfig+parseYamlConfig = fmap fromYamlConfig . Y.decode++checkYamlConfig :: ByteString -> StackConfig -> Expectation+checkYamlConfig bs sc = parseYamlConfig bs `shouldBe` Just sc++stUri :: String -> URI+stUri s =+  let Just uri = parseURI s+  in uri++minimalBs :: ByteString+minimalBs = T.encodeUtf8 [st|+resolver: lts-10.0+|]++minimalConf :: StackConfig+minimalConf = StackConfig+  { _scResolver  = StackResolver "lts-10.0"+  , _scPackages  = NE.fromList+    [ StackPackage (PlFilePath ".") False Nothing]+  }++packageDefaultBs :: ByteString+packageDefaultBs = T.encodeUtf8 [st|+resolver: lts-10.0+packages:+  - .+|]++packageDefaultConf :: StackConfig+packageDefaultConf = minimalConf++packageSimpleListBs :: ByteString+packageSimpleListBs = T.encodeUtf8 [st|+resolver: lts-10.0+packages:+  - client+  - server+|]++packageSimpleListConf :: StackConfig+packageSimpleListConf = StackConfig+  { _scResolver = StackResolver "lts-10.0"+  , _scPackages = NE.fromList+    [ StackPackage (PlFilePath "client") False Nothing+    , StackPackage (PlFilePath "server") False Nothing ]+  }++packageLocationsBs :: ByteString+packageLocationsBs = T.encodeUtf8 [st|+resolver: lts-10.0+packages:+  - location: humble/package+    subdirs:+    - client+    - server+  - location: https://example.com/foo/bar/baz-0.0.2.tar.gz+    extra-dep: true+    subdirs:+    - extra+  - location:+      git: git@github.com:example/mega-repo+      commit: 6a86ee32e5b869a877151f74064572225e1a0000+    subdirs:+      - subdir1+      - subdir2+    extra-dep: true+|]++packageLocationsConf :: StackConfig+packageLocationsConf = StackConfig+  { _scResolver = StackResolver "lts-10.0"+  , _scPackages = NE.fromList+    [ StackPackage (PlFilePath "humble/package") False (Just "client")+    , StackPackage (PlFilePath "humble/package") False (Just "server")+    , StackPackage (PlUri $ stUri "https://example.com/foo/bar/baz-0.0.2.tar.gz") True (Just "extra")+    , StackPackage (PlRepo $ Repo (Vcs "git") "git@github.com:example/mega-repo" "6a86ee32e5b869a877151f74064572225e1a0000") True (Just "subdir1")+    , StackPackage (PlRepo $ Repo (Vcs "git") "git@github.com:example/mega-repo" "6a86ee32e5b869a877151f74064572225e1a0000") True (Just "subdir2")+    ]+  }++packageExtraDepsBs :: ByteString+packageExtraDepsBs = T.encodeUtf8 [st|+resolver: lts-10.0+extra-deps:+  - acme-missiles-0.3+  - humble-package-1+|]++packageExtraDepsConf :: StackConfig+packageExtraDepsConf = StackConfig+  { _scResolver = StackResolver "lts-10.0"+  , _scPackages = NE.fromList+    [ StackPackage (PlFilePath ".") False Nothing+    , StackPackage (PlIndex $ PackageIndex "acme-missiles-0.3" Nothing) True Nothing+    , StackPackage (PlIndex $ PackageIndex "humble-package-1" Nothing) True Nothing ]+  }++packageMixedBs :: ByteString+packageMixedBs = T.encodeUtf8 [st|+resolver: lts-10.0+packages:+  - client+  - server+extra-deps:+  - acme-missiles-0.3+  - humble-package-1+|]++packageMixedConf :: StackConfig+packageMixedConf = StackConfig+  { _scResolver = StackResolver "lts-10.0"+  , _scPackages = NE.fromList+    [ StackPackage (PlFilePath "client") False Nothing+    , StackPackage (PlFilePath "server") False Nothing+    , StackPackage (PlIndex $ PackageIndex "acme-missiles-0.3" Nothing) True Nothing+    , StackPackage (PlIndex $ PackageIndex "humble-package-1" Nothing) True Nothing ]+  }++packageExtraDepsNewBs :: ByteString+packageExtraDepsNewBs = T.encodeUtf8 [st|+resolver: lts-10.0+extra-deps:+  - vendor/lib+  - acme-missiles-0.3+  - git: git@github.com:yesodweb/wai+    commit: 2f8a8e1b771829f4a8a77c0111352ce45a14c30f+    subdirs:+    - auto-update+    - wai+  - https://example.com/foo/bar/baz-0.0.2.tar.gz+  - archive: http://github.com/yesodweb/wai/archive/2f8a8e1b771829f4a8a77c0111352ce45a14c30f.zip+    subdirs:+    - wai+    - warp+  - archive: ../acme-missiles-0.3.tar.gz+    sha256: e563d8b524017a06b32768c4db8eff1f822f3fb22a90320b7e414402647b735b+|]++packageExtraDepsNewConf :: StackConfig+packageExtraDepsNewConf = StackConfig+  { _scResolver = StackResolver "lts-10.0"+  , _scPackages = NE.fromList+    [ StackPackage (PlFilePath ".") False Nothing+    , StackPackage (PlFilePath "vendor/lib") True Nothing+    , StackPackage (PlIndex $ PackageIndex "acme-missiles-0.3" Nothing) True Nothing+    , StackPackage (PlRepo $ Repo (Vcs "git") "git@github.com:yesodweb/wai" "2f8a8e1b771829f4a8a77c0111352ce45a14c30f") True (Just "auto-update")+    , StackPackage (PlRepo $ Repo (Vcs "git") "git@github.com:yesodweb/wai" "2f8a8e1b771829f4a8a77c0111352ce45a14c30f") True (Just "wai")+    , StackPackage (PlUri $ stUri "https://example.com/foo/bar/baz-0.0.2.tar.gz") True Nothing+    , StackPackage (PlUri $ stUri "http://github.com/yesodweb/wai/archive/2f8a8e1b771829f4a8a77c0111352ce45a14c30f.zip") True (Just "wai")+    , StackPackage (PlUri $ stUri "http://github.com/yesodweb/wai/archive/2f8a8e1b771829f4a8a77c0111352ce45a14c30f.zip") True (Just "warp")+    , StackPackage (PlFilePath "../acme-missiles-0.3.tar.gz") True Nothing+    ]+  }