From 406c999626199322e0e17e3b8fc5d28ed4e2945a Mon Sep 17 00:00:00 2001 From: WorldSEnder Date: Fri, 31 Jul 2020 16:27:06 +0200 Subject: [PATCH 01/14] allow specifying a stack.yaml for stack configurations --- src/HIE/Bios/Config.hs | 90 ++++++++++++++++++++++++++++++------------ src/HIE/Bios/Cradle.hs | 36 ++++++++--------- 2 files changed, 82 insertions(+), 44 deletions(-) diff --git a/src/HIE/Bios/Config.hs b/src/HIE/Bios/Config.hs index 49c7e6b83..5b85fa863 100644 --- a/src/HIE/Bios/Config.hs +++ b/src/HIE/Bios/Config.hs @@ -2,12 +2,18 @@ {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE TupleSections #-} {-# LANGUAGE DeriveFunctor #-} +{-# LANGUAGE PatternSynonyms #-} +{-# LANGUAGE LambdaCase #-} -- | Logic and datatypes for parsing @hie.yaml@ files. module HIE.Bios.Config( readConfig, Config(..), CradleConfig(..), + CabalType(..), + StackType(..), CradleType(..), + pattern Cabal, + pattern Stack, Callable(..) ) where @@ -43,11 +49,25 @@ data CradleConfig a = data Callable = Program FilePath | Command String deriving (Show, Eq) +data CabalType + = CabalType { cabalComponent :: Maybe String } + deriving (Eq) + +instance Show CabalType where + show = show . Cabal_ + +data StackType + = StackType { stackComponent :: Maybe String , stackYaml :: Maybe String } + deriving (Eq) + +instance Show StackType where + show = show . Stack_ + data CradleType a - = Cabal { component :: Maybe String } - | CabalMulti [ (FilePath, String) ] - | Stack { component :: Maybe String } - | StackMulti [ (FilePath, String) ] + = Cabal_ { cabalType :: !CabalType } + | CabalMulti [ (FilePath, CabalType) ] + | Stack_ { stackType :: !StackType } + | StackMulti [ (FilePath, StackType) ] -- Bazel and Obelisk used to be supported but bit-rotted and no users have complained. -- They can be added back if a user -- | Bazel @@ -66,6 +86,14 @@ data CradleType a | Other { otherConfig :: a, originalYamlValue :: Value } deriving (Eq, Functor) +pattern Cabal :: Maybe String -> CradleType a +pattern Cabal cm = Cabal_ (CabalType cm) + +pattern Stack :: Maybe String -> Maybe String -> CradleType a +pattern Stack cm yml = Stack_ (StackType cm yml) + +{-# COMPLETE Cabal, CabalMulti, Stack, StackMulti, Bios, Direct, None, Multi, Other :: CradleType #-} + instance FromJSON a => FromJSON (CradleType a) where parseJSON (Object o) = parseCradleType o parseJSON _ = fail "Not a known cradle type. Possible are: cabal, stack, bios, direct, default, none, multi" @@ -73,7 +101,7 @@ instance FromJSON a => FromJSON (CradleType a) where instance Show (CradleType a) where show (Cabal comp) = "Cabal {component = " ++ show comp ++ "}" show (CabalMulti a) = "CabalMulti " ++ show a - show (Stack comp) = "Stack {component = " ++ show comp ++ "}" + show (Stack comp yaml) = "Stack {component = " ++ show comp ++ ", stackYaml = " ++ show yaml ++ "}" show (StackMulti a) = "StackMulti " ++ show a show Bios { call, depsCall } = "Bios {call = " ++ show call ++ ", depsCall = " ++ show depsCall ++ "}" show (Direct args) = "Direct {arguments = " ++ show args ++ "}" @@ -94,38 +122,48 @@ parseCradleType o | Just val <- Map.lookup "other" o = Other <$> parseJSON val <*> pure val parseCradleType o = fail $ "Unknown cradle type: " ++ show o -parseStackOrCabal - :: (Maybe String -> CradleType a) - -> ([(FilePath, String)] -> CradleType a) +parseSingleOrMultiple + :: (x -> CradleType a) + -> ([(FilePath, x)] -> CradleType a) + -> (Map.HashMap T.Text Value -> Parser x) -> Value -> Parser (CradleType a) -parseStackOrCabal singleConstructor _ (Object x) - | Map.size x == 1, Just (String stackComponent) <- Map.lookup "component" x - = return $ singleConstructor $ Just $ T.unpack stackComponent - | Map.null x - = return $ singleConstructor Nothing - | otherwise - = fail "Not a valid Configuration type, following keys are allowed: component" -parseStackOrCabal _ multiConstructor (Array x) = do +parseSingleOrMultiple single _ parse (Object v) = single <$> parse v +parseSingleOrMultiple _ multiple parse (Array x) = do let parseOne e | Object v <- e , Just (String prefix) <- Map.lookup "path" v - , Just (String comp) <- Map.lookup "component" v - , Map.size v == 2 - = return (T.unpack prefix, T.unpack comp) + = (T.unpack prefix,) <$> parse (Map.delete "path" v) | otherwise - = fail "Expected an object with path and component keys" - + = fail "Expected an object with a path key" xs <- foldrM (\v cs -> (: cs) <$> parseOne v) [] x - return $ multiConstructor xs -parseStackOrCabal singleConstructor _ Null = return $ singleConstructor Nothing -parseStackOrCabal _ _ _ = fail "Configuration is expected to be an object." + return $ multiple xs +parseSingleOrMultiple single _ parse Null = single <$> parse Map.empty +parseSingleOrMultiple _ _ _ _ = fail "Configuration is expected to be an object or an array of objects." parseStack :: Value -> Parser (CradleType a) -parseStack = parseStackOrCabal Stack StackMulti +parseStack = parseSingleOrMultiple Stack_ StackMulti $ + \case x | Map.size x == 2 + , Just (String component) <- Map.lookup "component" x + , Just (String stackYaml) <- Map.lookup "stackYaml" x + -> return $ StackType (Just $ T.unpack component) (Just $ T.unpack stackYaml) + | Map.size x == 1, Just (String component) <- Map.lookup "component" x + -> return $ StackType (Just $ T.unpack component) Nothing + | Map.size x == 1, Just (String stackYaml) <- Map.lookup "stackYaml" x + -> return $ StackType Nothing (Just $ T.unpack stackYaml) + | Map.null x + -> return $ StackType Nothing Nothing + | otherwise + -> fail "Not a valid Stack configuration, following keys are allowed: component, stackYaml" parseCabal :: Value -> Parser (CradleType a) -parseCabal = parseStackOrCabal Cabal CabalMulti +parseCabal = parseSingleOrMultiple Cabal_ CabalMulti $ + \case x | Map.size x == 1, Just (String component) <- Map.lookup "component" x + -> return $ CabalType (Just $ T.unpack component) + | Map.null x + -> return $ CabalType Nothing + | otherwise + -> fail "Not a valid Cabal configuration, following keys are allowed: component" parseBios :: Value -> Parser (CradleType a) parseBios (Object x) diff --git a/src/HIE/Bios/Cradle.hs b/src/HIE/Bios/Cradle.hs index f7f63a4c4..152ac5395 100644 --- a/src/HIE/Bios/Cradle.hs +++ b/src/HIE/Bios/Cradle.hs @@ -96,13 +96,13 @@ getCradle buildCustomCradle (cc, wdir) = addCradleDeps cradleDeps $ case cradleT CabalMulti ms -> getCradle buildCustomCradle $ (CradleConfig cradleDeps - (Multi [(p, CradleConfig [] (Cabal (Just c))) | (p, c) <- ms]) + (Multi [(p, CradleConfig [] (Cabal_ c)) | (p, c) <- ms]) , wdir) - Stack mc -> stackCradle wdir mc + Stack mc syaml -> stackCradle wdir mc (maybe "stack.yaml" id syaml) StackMulti ms -> getCradle buildCustomCradle $ (CradleConfig cradleDeps - (Multi [(p, CradleConfig [] (Stack (Just c))) | (p, c) <- ms]) + (Multi [(p, CradleConfig [] (Stack_ c)) | (p, c) <- ms]) , wdir) -- Bazel -> rulesHaskellCradle wdir -- Obelisk -> obeliskCradle wdir @@ -142,7 +142,7 @@ implicitConfig' fp = (\wdir -> (Bios (Program $ wdir ".hie-bios") Nothing, wdir)) <$> biosWorkDir fp -- <|> (Obelisk,) <$> obeliskWorkDir fp -- <|> (Bazel,) <$> rulesHaskellWorkDir fp - <|> (stackExecutable >> (Stack Nothing,) <$> stackWorkDir fp) + <|> (stackExecutable >> (Stack Nothing Nothing,) <$> stackWorkDir fp) <|> ((Cabal Nothing,) <$> cabalWorkDir fp) @@ -552,16 +552,16 @@ cabalWorkDir wdir = ------------------------------------------------------------------------ -- | Stack Cradle -- Works for by invoking `stack repl` with a wrapper script -stackCradle :: FilePath -> Maybe String -> Cradle a -stackCradle wdir mc = +stackCradle :: FilePath -> Maybe String -> FilePath -> Cradle a +stackCradle wdir mc syaml = Cradle { cradleRootDir = wdir , cradleOptsProg = CradleAction { actionName = Types.Stack - , runCradle = stackAction wdir mc + , runCradle = stackAction wdir mc syaml , runGhcCmd = \args -> readProcessWithCwd - wdir "stack" (["exec", "--silent", "ghc", "--"] <> args) "" + wdir "stack" (["--stack-yaml", syaml, "exec", "--silent", "ghc", "--"] <> args) "" } } @@ -574,32 +574,32 @@ stackCradle wdir mc = -- a '.cabal' file. -- -- Found dependencies are relative to 'rootDir'. -stackCradleDependencies :: FilePath -> FilePath -> IO [FilePath] -stackCradleDependencies wdir componentDir = do +stackCradleDependencies :: FilePath -> FilePath -> FilePath -> IO [FilePath] +stackCradleDependencies wdir componentDir syaml = do let relFp = makeRelative wdir componentDir cabalFiles' <- findCabalFiles componentDir let cabalFiles = map (relFp ) cabalFiles' - return $ map normalise $ cabalFiles ++ [relFp "package.yaml", "stack.yaml"] + return $ map normalise $ cabalFiles ++ [relFp "package.yaml", syaml] -stackAction :: FilePath -> Maybe String -> LoggingFunction -> FilePath -> IO (CradleLoadResult ComponentOptions) -stackAction work_dir mc l _fp = do - let ghcProcArgs = ("stack", ["exec", "ghc", "--"]) +stackAction :: FilePath -> Maybe String -> FilePath -> LoggingFunction -> FilePath -> IO (CradleLoadResult ComponentOptions) +stackAction work_dir mc syaml l _fp = do + let ghcProcArgs = ("stack", ["--stack-yaml", syaml, "exec", "ghc", "--"]) -- Same wrapper works as with cabal withCabalWrapperTool ghcProcArgs work_dir $ \wrapper_fp -> do (ex1, _stdo, stde, args) <- readProcessWithOutputFile l work_dir $ - proc "stack" $ ["repl", "--no-nix-pure", "--with-ghc", wrapper_fp] + proc "stack" $ ["--stack-yaml", syaml, "repl", "--no-nix-pure", "--with-ghc", wrapper_fp] ++ [ comp | Just comp <- [mc] ] (ex2, pkg_args, stdr, _) <- readProcessWithOutputFile l work_dir $ - proc "stack" ["path", "--ghc-package-path"] + proc "stack" ["--stack-yaml", syaml, "path", "--ghc-package-path"] let split_pkgs = concatMap splitSearchPath pkg_args pkg_ghc_args = concatMap (\p -> ["-package-db", p] ) split_pkgs case processCabalWrapperArgs args of Nothing -> do -- Best effort. Assume the working directory is the -- the root of the component, so we are right in trivial cases at least. - deps <- stackCradleDependencies work_dir work_dir + deps <- stackCradleDependencies work_dir work_dir syaml pure $ CradleFail (CradleError deps ex1 $ [ "Failed to parse result of calling stack" ] @@ -608,7 +608,7 @@ stackAction work_dir mc l _fp = do ) Just (componentDir, ghc_args) -> do - deps <- stackCradleDependencies work_dir componentDir + deps <- stackCradleDependencies work_dir componentDir syaml pure $ makeCradleResult ( combineExitCodes [ex1, ex2] , stde ++ stdr, componentDir From 0e6e8931c8907dc8d1a17eccb15eeed1b88867f5 Mon Sep 17 00:00:00 2001 From: WorldSEnder Date: Fri, 31 Jul 2020 17:07:03 +0200 Subject: [PATCH 02/14] fix test cases --- tests/ParserTests.hs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/tests/ParserTests.hs b/tests/ParserTests.hs index 37cc968fd..2a724bea5 100644 --- a/tests/ParserTests.hs +++ b/tests/ParserTests.hs @@ -18,7 +18,7 @@ main :: IO () main = defaultMain $ testCase "Parser Tests" $ do assertParser "cabal-1.yaml" (noDeps (Cabal (Just "lib:hie-bios"))) - assertParser "stack-config.yaml" (noDeps (Stack Nothing)) + assertParser "stack-config.yaml" (noDeps (Stack Nothing Nothing)) --assertParser "bazel.yaml" (noDeps Bazel) assertParser "bios-1.yaml" (noDeps (Bios (Program "program") Nothing)) assertParser "bios-2.yaml" (noDeps (Bios (Program "program") (Just (Program "dep-program")))) @@ -32,21 +32,21 @@ main = defaultMain $ assertParser "multi.yaml" (noDeps (Multi [("./src", CradleConfig [] (Cabal (Just "lib:hie-bios"))) , ("./test", CradleConfig [] (Cabal (Just "test")) ) ])) - assertParser "cabal-multi.yaml" (noDeps (CabalMulti [("./src", "lib:hie-bios") - ,("./", "lib:hie-bios")])) + assertParser "cabal-multi.yaml" (noDeps (CabalMulti [("./src", CabalType $ Just "lib:hie-bios") + ,("./", CabalType $ Just "lib:hie-bios")])) - assertParser "stack-multi.yaml" (noDeps (StackMulti [("./src", "lib:hie-bios") - ,("./", "lib:hie-bios")])) + assertParser "stack-multi.yaml" (noDeps (StackMulti [("./src", StackType (Just "lib:hie-bios") Nothing) + ,("./", StackType (Just"lib:hie-bios") Nothing)])) assertParser "nested-cabal-multi.yaml" (noDeps (Multi [("./test/testdata", CradleConfig [] None) ,("./", CradleConfig [] ( - CabalMulti [("./src", "lib:hie-bios") - ,("./tests", "parser-tests")]))])) + CabalMulti [("./src", CabalType $ Just "lib:hie-bios") + ,("./tests", CabalType $ Just "parser-tests")]))])) assertParser "nested-stack-multi.yaml" (noDeps (Multi [("./test/testdata", CradleConfig [] None) ,("./", CradleConfig [] ( - StackMulti [("./src", "lib:hie-bios") - ,("./tests", "parser-tests")]))])) + StackMulti [("./src", StackType (Just "lib:hie-bios") Nothing) + ,("./tests", StackType (Just "parser-tests") Nothing)]))])) assertCustomParser "ch-cabal.yaml" (noDeps (Other CabalHelperCabal $ simpleCabalHelperYaml "cabal")) From eff2a8ba772f8ca7aca21813e9566ee8995fed43 Mon Sep 17 00:00:00 2001 From: WorldSEnder Date: Fri, 31 Jul 2020 21:35:09 +0200 Subject: [PATCH 03/14] add test cases for stack with custom yaml --- .gitignore | 4 +-- tests/BiosTests.hs | 29 ++++++++++++------- .../multi-stack-with-yaml/appA/Setup.hs | 2 ++ .../multi-stack-with-yaml/appA/appA.cabal | 12 ++++++++ .../multi-stack-with-yaml/appA/src/Lib.hs | 1 + .../multi-stack-with-yaml/appB/Setup.hs | 2 ++ .../multi-stack-with-yaml/appB/appB.cabal | 12 ++++++++ .../multi-stack-with-yaml/appB/src/Lib.hs | 1 + tests/projects/multi-stack-with-yaml/hie.yaml | 16 ++++++++++ tests/projects/stack-with-yaml/Setup.hs | 2 ++ tests/projects/stack-with-yaml/app/Main.hs | 4 +++ tests/projects/stack-with-yaml/hie.yaml | 9 ++++++ .../stack-with-yaml/multi-stack.cabal | 23 +++++++++++++++ tests/projects/stack-with-yaml/src/Lib.hs | 5 ++++ 14 files changed, 110 insertions(+), 12 deletions(-) create mode 100644 tests/projects/multi-stack-with-yaml/appA/Setup.hs create mode 100644 tests/projects/multi-stack-with-yaml/appA/appA.cabal create mode 100644 tests/projects/multi-stack-with-yaml/appA/src/Lib.hs create mode 100644 tests/projects/multi-stack-with-yaml/appB/Setup.hs create mode 100644 tests/projects/multi-stack-with-yaml/appB/appB.cabal create mode 100644 tests/projects/multi-stack-with-yaml/appB/src/Lib.hs create mode 100644 tests/projects/multi-stack-with-yaml/hie.yaml create mode 100644 tests/projects/stack-with-yaml/Setup.hs create mode 100644 tests/projects/stack-with-yaml/app/Main.hs create mode 100644 tests/projects/stack-with-yaml/hie.yaml create mode 100644 tests/projects/stack-with-yaml/multi-stack.cabal create mode 100644 tests/projects/stack-with-yaml/src/Lib.hs diff --git a/.gitignore b/.gitignore index 150b05c88..d5e1219f4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,7 @@ dist/ dist-newstyle/ .stack-work/ -stack.yaml -stack.yaml.lock +stack*.yaml +stack*.yaml.lock cabal.project.local* .vscode/ diff --git a/tests/BiosTests.hs b/tests/BiosTests.hs index 09c86be8e..5d76579f7 100644 --- a/tests/BiosTests.hs +++ b/tests/BiosTests.hs @@ -114,6 +114,12 @@ main = do , testCaseSteps "multi-cabal" {- tests if both components can be loaded -} $ testDirectory isCabalCradle "./tests/projects/multi-cabal" "app/Main.hs" >> testDirectory isCabalCradle "./tests/projects/multi-cabal" "src/Lib.hs" + , testCaseSteps "stack-with-yaml" {- tests if both components can be loaded -} + $ testDirectory isStackCradle "./tests/projects/stack-with-yaml" "app/Main.hs" + >> testDirectory isStackCradle "./tests/projects/stack-with-yaml" "src/Lib.hs" + , testCaseSteps "multi-stack-with-yaml" {- tests if both components can be loaded -} + $ testDirectory isStackCradle "./tests/projects/multi-stack-with-yaml" "appA/src/Lib.hs" + >> testDirectory isStackCradle "./tests/projects/multi-stack-with-yaml" "appB/src/Lib.hs" , testCaseSteps "monorepo-cabal" {- issue https://github.com/mpickering/hie-bios/issues/200 -} $ testDirectory isCabalCradle "./tests/projects/monorepo-cabal" "A/Main.hs" >> testDirectory isCabalCradle "./tests/projects/monorepo-cabal" "B/MyLib.hs" @@ -313,18 +319,21 @@ copyDir src dst = do writeStackYamlFiles :: IO () writeStackYamlFiles = - forM_ stackProjects $ \(proj, pkgs) -> - writeFile (proj "stack.yaml") (stackYaml stackYamlResolver pkgs) + forM_ stackProjects $ \(proj, syaml, pkgs) -> + writeFile (proj syaml) (stackYaml stackYamlResolver pkgs) -stackProjects :: [(FilePath, [FilePath])] +stackProjects :: [(FilePath, FilePath, [FilePath])] stackProjects = - [ ("tests" "projects" "multi-stack", ["."]) - , ("tests" "projects" "failing-stack", ["."]) - , ("tests" "projects" "simple-stack", ["."]) - , ("tests" "projects" "nested-stack", [".", "./sub-comp"]) - , ("tests" "projects" "space stack", ["."]) - , ("tests" "projects" "implicit-stack", ["."]) - , ("tests" "projects" "implicit-stack-multi", ["."]) + [ ("tests" "projects" "multi-stack", "stack.yaml", ["."]) + , ("tests" "projects" "failing-stack", "stack.yaml", ["."]) + , ("tests" "projects" "simple-stack", "stack.yaml", ["."]) + , ("tests" "projects" "nested-stack", "stack.yaml", [".", "./sub-comp"]) + , ("tests" "projects" "space stack", "stack.yaml", ["."]) + , ("tests" "projects" "implicit-stack", "stack.yaml", ["."]) + , ("tests" "projects" "implicit-stack-multi", "stack.yaml", ["."]) + , ("tests" "projects" "implicit-stack-multi", "stack.yaml", ["."]) + , ("tests" "projects" "multi-stack-with-yaml", "stack-8.8.3.yaml", ["appA", "appB"]) + , ("tests" "projects" "stack-with-yaml", "stack-8.8.3.yaml", ["."]) ] stackYaml :: String -> [FilePath] -> String diff --git a/tests/projects/multi-stack-with-yaml/appA/Setup.hs b/tests/projects/multi-stack-with-yaml/appA/Setup.hs new file mode 100644 index 000000000..9a994af67 --- /dev/null +++ b/tests/projects/multi-stack-with-yaml/appA/Setup.hs @@ -0,0 +1,2 @@ +import Distribution.Simple +main = defaultMain diff --git a/tests/projects/multi-stack-with-yaml/appA/appA.cabal b/tests/projects/multi-stack-with-yaml/appA/appA.cabal new file mode 100644 index 000000000..edc2ea3bf --- /dev/null +++ b/tests/projects/multi-stack-with-yaml/appA/appA.cabal @@ -0,0 +1,12 @@ +cabal-version: >=2.0 +name: appA +version: 0.1.0.0 +build-type: Simple + +library + exposed-modules: Lib + -- other-modules: + -- other-extensions: + build-depends: base >=4.10 && < 5, filepath + hs-source-dirs: src + default-language: Haskell2010 diff --git a/tests/projects/multi-stack-with-yaml/appA/src/Lib.hs b/tests/projects/multi-stack-with-yaml/appA/src/Lib.hs new file mode 100644 index 000000000..6d85a26fe --- /dev/null +++ b/tests/projects/multi-stack-with-yaml/appA/src/Lib.hs @@ -0,0 +1 @@ +module Lib where diff --git a/tests/projects/multi-stack-with-yaml/appB/Setup.hs b/tests/projects/multi-stack-with-yaml/appB/Setup.hs new file mode 100644 index 000000000..9a994af67 --- /dev/null +++ b/tests/projects/multi-stack-with-yaml/appB/Setup.hs @@ -0,0 +1,2 @@ +import Distribution.Simple +main = defaultMain diff --git a/tests/projects/multi-stack-with-yaml/appB/appB.cabal b/tests/projects/multi-stack-with-yaml/appB/appB.cabal new file mode 100644 index 000000000..e9b261c94 --- /dev/null +++ b/tests/projects/multi-stack-with-yaml/appB/appB.cabal @@ -0,0 +1,12 @@ +cabal-version: >=2.0 +name: appB +version: 0.1.0.0 +build-type: Simple + +library + exposed-modules: Lib + -- other-modules: + -- other-extensions: + build-depends: base >=4.10 && < 5, filepath + hs-source-dirs: src + default-language: Haskell2010 diff --git a/tests/projects/multi-stack-with-yaml/appB/src/Lib.hs b/tests/projects/multi-stack-with-yaml/appB/src/Lib.hs new file mode 100644 index 000000000..6d85a26fe --- /dev/null +++ b/tests/projects/multi-stack-with-yaml/appB/src/Lib.hs @@ -0,0 +1 @@ +module Lib where diff --git a/tests/projects/multi-stack-with-yaml/hie.yaml b/tests/projects/multi-stack-with-yaml/hie.yaml new file mode 100644 index 000000000..5c09b53d0 --- /dev/null +++ b/tests/projects/multi-stack-with-yaml/hie.yaml @@ -0,0 +1,16 @@ +cradle: + multi: + - path: "appA" + config: + cradle: + stack: + - path: appA/src + component: appA:lib + stackYaml: stack-8.8.3.yaml + - path: "appB" + config: + cradle: + stack: + - path: appB/src + component: appB:lib + stackYaml: stack-8.8.3.yaml diff --git a/tests/projects/stack-with-yaml/Setup.hs b/tests/projects/stack-with-yaml/Setup.hs new file mode 100644 index 000000000..9a994af67 --- /dev/null +++ b/tests/projects/stack-with-yaml/Setup.hs @@ -0,0 +1,2 @@ +import Distribution.Simple +main = defaultMain diff --git a/tests/projects/stack-with-yaml/app/Main.hs b/tests/projects/stack-with-yaml/app/Main.hs new file mode 100644 index 000000000..f1d7ec280 --- /dev/null +++ b/tests/projects/stack-with-yaml/app/Main.hs @@ -0,0 +1,4 @@ + +import System.Directory (getCurrentDirectory) + +main = return () \ No newline at end of file diff --git a/tests/projects/stack-with-yaml/hie.yaml b/tests/projects/stack-with-yaml/hie.yaml new file mode 100644 index 000000000..c868e2594 --- /dev/null +++ b/tests/projects/stack-with-yaml/hie.yaml @@ -0,0 +1,9 @@ +cradle: + stack: + - path: ./src + component: "multi-stack:lib" + stackYaml: "stack-8.8.3.yaml" + + - path: ./app + component: "multi-stack:exe:multi-stack" + stackYaml: "stack-8.8.3.yaml" diff --git a/tests/projects/stack-with-yaml/multi-stack.cabal b/tests/projects/stack-with-yaml/multi-stack.cabal new file mode 100644 index 000000000..c55b7c1bb --- /dev/null +++ b/tests/projects/stack-with-yaml/multi-stack.cabal @@ -0,0 +1,23 @@ +cabal-version: >=2.0 +name: multi-stack +version: 0.1.0.0 +build-type: Simple + +library + exposed-modules: Lib + -- other-modules: + -- other-extensions: + build-depends: base >=4.10 && < 5, filepath + hs-source-dirs: src + default-language: Haskell2010 + + + +executable multi-stack + main-is: app/Main.hs + -- other-modules: + -- other-extensions: + build-depends: base >=4.10 && < 5, directory + -- hs-source-dirs: + default-language: Haskell2010 + ghc-options: +RTS -A1m -N -RTS -Wall \ No newline at end of file diff --git a/tests/projects/stack-with-yaml/src/Lib.hs b/tests/projects/stack-with-yaml/src/Lib.hs new file mode 100644 index 000000000..9341bdebe --- /dev/null +++ b/tests/projects/stack-with-yaml/src/Lib.hs @@ -0,0 +1,5 @@ +module Lib where + +import System.FilePath (()) + +foo = "test" "me" \ No newline at end of file From 2eb14ea70359409b9101386b68c2e43e5e947683 Mon Sep 17 00:00:00 2001 From: WorldSEnder Date: Fri, 31 Jul 2020 21:58:26 +0200 Subject: [PATCH 04/14] add parser test cases --- .gitignore | 4 ++-- tests/ParserTests.hs | 7 +++++++ tests/configs/multi-stack-with-yaml.yaml | 6 ++++++ tests/configs/stack-with-both.yaml | 4 ++++ tests/configs/stack-with-yaml.yaml | 3 +++ 5 files changed, 22 insertions(+), 2 deletions(-) create mode 100644 tests/configs/multi-stack-with-yaml.yaml create mode 100644 tests/configs/stack-with-both.yaml create mode 100644 tests/configs/stack-with-yaml.yaml diff --git a/.gitignore b/.gitignore index d5e1219f4..d72d73737 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,7 @@ dist/ dist-newstyle/ .stack-work/ -stack*.yaml -stack*.yaml.lock +tests/projects/**/stack*.yaml +tests/projects/**/stack*.yaml.lock cabal.project.local* .vscode/ diff --git a/tests/ParserTests.hs b/tests/ParserTests.hs index 2a724bea5..5cff97feb 100644 --- a/tests/ParserTests.hs +++ b/tests/ParserTests.hs @@ -47,6 +47,13 @@ main = defaultMain $ ,("./", CradleConfig [] ( StackMulti [("./src", StackType (Just "lib:hie-bios") Nothing) ,("./tests", StackType (Just "parser-tests") Nothing)]))])) + assertParser "stack-with-yaml.yaml" + (noDeps (Stack Nothing (Just "stack-8.8.3.yaml"))) + assertParser "stack-with-both.yaml" + (noDeps (Stack (Just "hie-bios:hie") (Just "stack-8.8.3.yaml"))) + assertParser "multi-stack-with-yaml.yaml" + (noDeps (StackMulti [("./src", StackType Nothing $ Just "stack-8.8.3.yaml") + ,("./vendor", StackType Nothing $ Just "./vendor/stack-8.8.3.yaml")])) assertCustomParser "ch-cabal.yaml" (noDeps (Other CabalHelperCabal $ simpleCabalHelperYaml "cabal")) diff --git a/tests/configs/multi-stack-with-yaml.yaml b/tests/configs/multi-stack-with-yaml.yaml new file mode 100644 index 000000000..f54344be9 --- /dev/null +++ b/tests/configs/multi-stack-with-yaml.yaml @@ -0,0 +1,6 @@ +cradle: + stack: + - path: "./src" + stackYaml: "stack-8.8.3.yaml" + - path: "./vendor" + stackYaml: "./vendor/stack-8.8.3.yaml" diff --git a/tests/configs/stack-with-both.yaml b/tests/configs/stack-with-both.yaml new file mode 100644 index 000000000..202d67661 --- /dev/null +++ b/tests/configs/stack-with-both.yaml @@ -0,0 +1,4 @@ +cradle: + stack: + stackYaml: "stack-8.8.3.yaml" + component: "hie-bios:hie" diff --git a/tests/configs/stack-with-yaml.yaml b/tests/configs/stack-with-yaml.yaml new file mode 100644 index 000000000..8155c9fa3 --- /dev/null +++ b/tests/configs/stack-with-yaml.yaml @@ -0,0 +1,3 @@ +cradle: + stack: + stackYaml: "stack-8.8.3.yaml" From 5c36ecbc4bdb3c912ad54b550ae56d2e810e1742 Mon Sep 17 00:00:00 2001 From: WorldSEnder Date: Fri, 31 Jul 2020 22:17:58 +0200 Subject: [PATCH 05/14] whitespace --- tests/projects/multi-stack/multi-stack.cabal | 2 +- tests/projects/stack-with-yaml/app/Main.hs | 2 +- tests/projects/stack-with-yaml/src/Lib.hs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/projects/multi-stack/multi-stack.cabal b/tests/projects/multi-stack/multi-stack.cabal index c55b7c1bb..b6eb67fdf 100644 --- a/tests/projects/multi-stack/multi-stack.cabal +++ b/tests/projects/multi-stack/multi-stack.cabal @@ -20,4 +20,4 @@ executable multi-stack build-depends: base >=4.10 && < 5, directory -- hs-source-dirs: default-language: Haskell2010 - ghc-options: +RTS -A1m -N -RTS -Wall \ No newline at end of file + ghc-options: +RTS -A1m -N -RTS -Wall diff --git a/tests/projects/stack-with-yaml/app/Main.hs b/tests/projects/stack-with-yaml/app/Main.hs index f1d7ec280..0efdb0b52 100644 --- a/tests/projects/stack-with-yaml/app/Main.hs +++ b/tests/projects/stack-with-yaml/app/Main.hs @@ -1,4 +1,4 @@ import System.Directory (getCurrentDirectory) -main = return () \ No newline at end of file +main = return () diff --git a/tests/projects/stack-with-yaml/src/Lib.hs b/tests/projects/stack-with-yaml/src/Lib.hs index 9341bdebe..a709c5ea9 100644 --- a/tests/projects/stack-with-yaml/src/Lib.hs +++ b/tests/projects/stack-with-yaml/src/Lib.hs @@ -2,4 +2,4 @@ module Lib where import System.FilePath (()) -foo = "test" "me" \ No newline at end of file +foo = "test" "me" From de64b9b3f0cf459f65e2cd1e93ff25d454f8f4ad Mon Sep 17 00:00:00 2001 From: WorldSEnder Date: Fri, 31 Jul 2020 23:42:32 +0200 Subject: [PATCH 06/14] change suggestive name --- tests/BiosTests.hs | 4 ++-- tests/projects/multi-stack-with-yaml/hie.yaml | 4 ++-- tests/projects/stack-with-yaml/hie.yaml | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/BiosTests.hs b/tests/BiosTests.hs index 5d76579f7..223fd0370 100644 --- a/tests/BiosTests.hs +++ b/tests/BiosTests.hs @@ -332,8 +332,8 @@ stackProjects = , ("tests" "projects" "implicit-stack", "stack.yaml", ["."]) , ("tests" "projects" "implicit-stack-multi", "stack.yaml", ["."]) , ("tests" "projects" "implicit-stack-multi", "stack.yaml", ["."]) - , ("tests" "projects" "multi-stack-with-yaml", "stack-8.8.3.yaml", ["appA", "appB"]) - , ("tests" "projects" "stack-with-yaml", "stack-8.8.3.yaml", ["."]) + , ("tests" "projects" "multi-stack-with-yaml", "stack-alt.yaml", ["appA", "appB"]) + , ("tests" "projects" "stack-with-yaml", "stack-alt.yaml", ["."]) ] stackYaml :: String -> [FilePath] -> String diff --git a/tests/projects/multi-stack-with-yaml/hie.yaml b/tests/projects/multi-stack-with-yaml/hie.yaml index 5c09b53d0..46cbb53df 100644 --- a/tests/projects/multi-stack-with-yaml/hie.yaml +++ b/tests/projects/multi-stack-with-yaml/hie.yaml @@ -6,11 +6,11 @@ cradle: stack: - path: appA/src component: appA:lib - stackYaml: stack-8.8.3.yaml + stackYaml: stack-alt.yaml - path: "appB" config: cradle: stack: - path: appB/src component: appB:lib - stackYaml: stack-8.8.3.yaml + stackYaml: stack-alt.yaml diff --git a/tests/projects/stack-with-yaml/hie.yaml b/tests/projects/stack-with-yaml/hie.yaml index c868e2594..6003ae4e8 100644 --- a/tests/projects/stack-with-yaml/hie.yaml +++ b/tests/projects/stack-with-yaml/hie.yaml @@ -2,8 +2,8 @@ cradle: stack: - path: ./src component: "multi-stack:lib" - stackYaml: "stack-8.8.3.yaml" + stackYaml: "stack-alt.yaml" - path: ./app component: "multi-stack:exe:multi-stack" - stackYaml: "stack-8.8.3.yaml" + stackYaml: "stack-alt.yaml" From d67fd55e7e84837de034ae108b52e2a232de2761 Mon Sep 17 00:00:00 2001 From: WorldSEnder Date: Sat, 1 Aug 2020 17:09:14 +0200 Subject: [PATCH 07/14] fix test cases (again) --- src/HIE/Bios/Cradle.hs | 14 ++++++++++++-- tests/BiosTests.hs | 12 ++++++------ 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/src/HIE/Bios/Cradle.hs b/src/HIE/Bios/Cradle.hs index 152ac5395..c1e76a588 100644 --- a/src/HIE/Bios/Cradle.hs +++ b/src/HIE/Bios/Cradle.hs @@ -54,6 +54,7 @@ import qualified Data.Conduit.Combinators as C import qualified Data.Conduit as C import qualified Data.Conduit.Text as C import qualified Data.Text as T +import qualified Data.HashMap.Strict as Map import Data.Maybe (fromMaybe, maybeToList) import GHC.Fingerprint (fingerprintString) @@ -735,6 +736,14 @@ findFile p dir = do getFiles = filter p <$> getDirectoryContents dir doesPredFileExist file = doesFileExist $ dir file +-- Some environments (e.g. stack exec) include GHC_PACKAGE_PATH. +-- Cabal v2 *will* complain, even though or precisely because it ignores them +-- Unset them from the environment to sidestep this +getCleanEnvironment :: IO [(String, String)] +getCleanEnvironment = do + e <- getEnvironment + return $ Map.toList $ Map.delete "GHC_PACKAGE_PATH" $ Map.fromList e + -- | Call a given process. -- * A special file is created for the process to write to, the process can discover the name of -- the file by reading the @HIE_BIOS_OUTPUT@ environment variable. The contents of this file is @@ -748,7 +757,7 @@ readProcessWithOutputFile -> CreateProcess -- ^ Parameters for the process to be executed. -> IO (ExitCode, [String], [String], [String]) readProcessWithOutputFile l work_dir cp = do - old_env <- getEnvironment + old_env <- getCleanEnvironment withHieBiosOutput old_env $ \output_file -> do -- Pipe stdout directly into the logger @@ -796,7 +805,8 @@ runGhcCmdOnPath wdir args = readProcessWithCwd wdir "ghc" args "" -- | Wrapper around 'readCreateProcess' that sets the working directory readProcessWithCwd :: FilePath -> FilePath -> [String] -> String -> IO (CradleLoadResult String) readProcessWithCwd dir cmd args stdi = do - let createProc = (proc cmd args) { cwd = Just dir } + cleanEnv <- getCleanEnvironment + let createProc = (proc cmd args) { cwd = Just dir, env = Just cleanEnv } mResult <- optional $ readCreateProcessWithExitCode createProc stdi case mResult of Just (ExitSuccess, stdo, _) -> pure $ CradleSuccess stdo diff --git a/tests/BiosTests.hs b/tests/BiosTests.hs index 223fd0370..874de7994 100644 --- a/tests/BiosTests.hs +++ b/tests/BiosTests.hs @@ -114,12 +114,6 @@ main = do , testCaseSteps "multi-cabal" {- tests if both components can be loaded -} $ testDirectory isCabalCradle "./tests/projects/multi-cabal" "app/Main.hs" >> testDirectory isCabalCradle "./tests/projects/multi-cabal" "src/Lib.hs" - , testCaseSteps "stack-with-yaml" {- tests if both components can be loaded -} - $ testDirectory isStackCradle "./tests/projects/stack-with-yaml" "app/Main.hs" - >> testDirectory isStackCradle "./tests/projects/stack-with-yaml" "src/Lib.hs" - , testCaseSteps "multi-stack-with-yaml" {- tests if both components can be loaded -} - $ testDirectory isStackCradle "./tests/projects/multi-stack-with-yaml" "appA/src/Lib.hs" - >> testDirectory isStackCradle "./tests/projects/multi-stack-with-yaml" "appB/src/Lib.hs" , testCaseSteps "monorepo-cabal" {- issue https://github.com/mpickering/hie-bios/issues/200 -} $ testDirectory isCabalCradle "./tests/projects/monorepo-cabal" "A/Main.hs" >> testDirectory isCabalCradle "./tests/projects/monorepo-cabal" "B/MyLib.hs" @@ -144,6 +138,12 @@ main = do , testCaseSteps "nested-stack2" $ testLoadCradleDependencies isStackCradle "./tests/projects/nested-stack" "MyLib.hs" (\deps -> deps `shouldMatchList` ["nested-stack.cabal", "package.yaml", "stack.yaml"] ) + , testCaseSteps "stack-with-yaml" {- tests if both components can be loaded -} + $ testDirectory isStackCradle "./tests/projects/stack-with-yaml" "app/Main.hs" + >> testDirectory isStackCradle "./tests/projects/stack-with-yaml" "src/Lib.hs" + , testCaseSteps "multi-stack-with-yaml" {- tests if both components can be loaded -} + $ testDirectory isStackCradle "./tests/projects/multi-stack-with-yaml" "appA/src/Lib.hs" + >> testDirectory isStackCradle "./tests/projects/multi-stack-with-yaml" "appB/src/Lib.hs" , -- Test for special characters in the path for parsing of the ghci-scripts. -- Issue https://github.com/mpickering/hie-bios/issues/162 From ef228fb230b708306566a8d3617d0658d3dcecdc Mon Sep 17 00:00:00 2001 From: WorldSEnder Date: Sat, 1 Aug 2020 18:43:33 +0200 Subject: [PATCH 08/14] add missing files to distribution --- hie-bios.cabal | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/hie-bios.cabal b/hie-bios.cabal index fadd4de30..eba9c5cf6 100644 --- a/hie-bios.cabal +++ b/hie-bios.cabal @@ -31,12 +31,15 @@ Extra-Source-Files: ChangeLog.md tests/configs/direct.yaml tests/configs/multi.yaml tests/configs/multi-ch.yaml + tests/configs/multi-stack-with-yaml.yaml tests/configs/nested-cabal-multi.yaml tests/configs/nested-stack-multi.yaml tests/configs/none.yaml tests/configs/obelisk.yaml tests/configs/stack-config.yaml tests/configs/stack-multi.yaml + tests/configs/stack-with-both.yaml + tests/configs/stack-with-yaml.yaml tests/projects/symlink-test/a/A.hs tests/projects/symlink-test/hie.yaml tests/projects/multi-direct/A.hs @@ -138,7 +141,18 @@ Extra-Source-Files: ChangeLog.md tests/projects/implicit-stack-multi/other-package/Setup.hs tests/projects/implicit-stack-multi/other-package/other-package.cabal tests/projects/implicit-stack-multi/other-package/Main.hs - + tests/projects/multi-stack-with-yaml/appA/Setup.hs + tests/projects/multi-stack-with-yaml/appA/appA.cabal + tests/projects/multi-stack-with-yaml/appA/src/Lib.hs + tests/projects/multi-stack-with-yaml/appB/Setup.hs + tests/projects/multi-stack-with-yaml/appB/appB.cabal + tests/projects/multi-stack-with-yaml/appB/src/Lib.hs + tests/projects/multi-stack-with-yaml/hie.yaml + tests/projects/stack-with-yaml/Setup.hs + tests/projects/stack-with-yaml/app/Main.hs + tests/projects/stack-with-yaml/hie.yaml + tests/projects/stack-with-yaml/multi-stack.cabal + tests/projects/stack-with-yaml/src/Lib.hs tested-with: GHC==8.10.1, GHC==8.8.3, GHC==8.6.5, GHC==8.4.4 From bdd9b2b49c3ce7706c9f849a0ca87cd0ad2b6b0c Mon Sep 17 00:00:00 2001 From: WorldSEnder Date: Sat, 1 Aug 2020 19:34:34 +0200 Subject: [PATCH 09/14] fix typo --- hie-bios.cabal | 2 +- tests/projects/stack-with-yaml/hie.yaml | 4 ++-- .../{multi-stack.cabal => stack-with-yaml.cabal} | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) rename tests/projects/stack-with-yaml/{multi-stack.cabal => stack-with-yaml.cabal} (80%) diff --git a/hie-bios.cabal b/hie-bios.cabal index eba9c5cf6..e338fa3e2 100644 --- a/hie-bios.cabal +++ b/hie-bios.cabal @@ -151,7 +151,7 @@ Extra-Source-Files: ChangeLog.md tests/projects/stack-with-yaml/Setup.hs tests/projects/stack-with-yaml/app/Main.hs tests/projects/stack-with-yaml/hie.yaml - tests/projects/stack-with-yaml/multi-stack.cabal + tests/projects/stack-with-yaml/stack-with-yaml.cabal tests/projects/stack-with-yaml/src/Lib.hs tested-with: GHC==8.10.1, GHC==8.8.3, GHC==8.6.5, GHC==8.4.4 diff --git a/tests/projects/stack-with-yaml/hie.yaml b/tests/projects/stack-with-yaml/hie.yaml index 6003ae4e8..2c996c4cd 100644 --- a/tests/projects/stack-with-yaml/hie.yaml +++ b/tests/projects/stack-with-yaml/hie.yaml @@ -1,9 +1,9 @@ cradle: stack: - path: ./src - component: "multi-stack:lib" + component: "stack-with-yaml:lib" stackYaml: "stack-alt.yaml" - path: ./app - component: "multi-stack:exe:multi-stack" + component: "stack-with-yaml:exe:stack-with-yaml" stackYaml: "stack-alt.yaml" diff --git a/tests/projects/stack-with-yaml/multi-stack.cabal b/tests/projects/stack-with-yaml/stack-with-yaml.cabal similarity index 80% rename from tests/projects/stack-with-yaml/multi-stack.cabal rename to tests/projects/stack-with-yaml/stack-with-yaml.cabal index c55b7c1bb..538314132 100644 --- a/tests/projects/stack-with-yaml/multi-stack.cabal +++ b/tests/projects/stack-with-yaml/stack-with-yaml.cabal @@ -1,5 +1,5 @@ cabal-version: >=2.0 -name: multi-stack +name: stack-with-yaml version: 0.1.0.0 build-type: Simple @@ -13,11 +13,11 @@ library -executable multi-stack +executable stack-with-yaml main-is: app/Main.hs -- other-modules: -- other-extensions: build-depends: base >=4.10 && < 5, directory -- hs-source-dirs: default-language: Haskell2010 - ghc-options: +RTS -A1m -N -RTS -Wall \ No newline at end of file + ghc-options: +RTS -A1m -N -RTS -Wall From 570280753bc05bcabed4f438289c2908919eaaca Mon Sep 17 00:00:00 2001 From: WorldSEnder Date: Sat, 1 Aug 2020 22:18:55 +0200 Subject: [PATCH 10/14] default settings for configurations --- README.md | 28 ++++++ src/HIE/Bios/Config.hs | 121 +++++++++++++++-------- src/HIE/Bios/Cradle.hs | 16 +-- tests/ParserTests.hs | 35 ++++--- tests/configs/multi-stack-with-yaml.yaml | 10 +- tests/projects/stack-with-yaml/hie.yaml | 12 +-- 6 files changed, 149 insertions(+), 73 deletions(-) diff --git a/README.md b/README.md index e44ff5623..00d51f32b 100644 --- a/README.md +++ b/README.md @@ -73,6 +73,16 @@ cradle: This configuration suffices if your whole project can be loaded by the command `stack repl`. As a rule of thumb, this works if the project consists of only one executable, one library and one test-suite. +Some projects have multiple `stack-*.yaml` files for multiple versions of ghc/resolvers. In this case you +can specify an alternate relative file to use by using the `stackYaml` option. The path is relative to the +configuration file. + +```yaml +cradle: + stack: + stackYaml: "./stack-8.8.3.yaml" +``` + If your project is more complicated, you need to specify which [components](https://docs.haskellstack.org/en/stable/build_command/#components) you want to load. A component is, roughly speaking, a library/executable/test-suite or benchmark in `stack`. You can view the components/targets of a stack project by executing the command: ``` sh $ stack ide targets @@ -126,6 +136,24 @@ Here you can see two important features: This way we specified which component needs to be compiled given a source file for our whole project. +If you use both, multiple components and an alternate `stack.yaml` file, there is a way to specify defaults +for the path-specific configurations. + +```yaml +cradle: + stack: + stackYaml: "stack-8.3.3.yaml" + components: + - path: "./src" + component: "hie-bios:lib" + - path: "./exe" + component: "hie-bios:exe:hie-bios" + - path: "./tests/BiosTests.hs" + component: "hie-bios:test:hie-bios" + - path: "./tests/ParserTests.hs" + component: "hie-bios:test:parser-tests" +``` + #### Debugging a `stack` cradle If you find that `hie-bios` can't load a certain component or file, run `stack repl` and `stack repl ` to see if `stack` succeeds in building your project. Chances are that there is a problem in your project and if you fix that, `hie-bios` will succeed to load it. diff --git a/src/HIE/Bios/Config.hs b/src/HIE/Bios/Config.hs index 5b85fa863..e752b4381 100644 --- a/src/HIE/Bios/Config.hs +++ b/src/HIE/Bios/Config.hs @@ -3,26 +3,42 @@ {-# LANGUAGE TupleSections #-} {-# LANGUAGE DeriveFunctor #-} {-# LANGUAGE PatternSynonyms #-} +{-# LANGUAGE ViewPatterns #-} {-# LANGUAGE LambdaCase #-} -- | Logic and datatypes for parsing @hie.yaml@ files. module HIE.Bios.Config( readConfig, Config(..), CradleConfig(..), - CabalType(..), - StackType(..), + CabalType, + pattern CabalType, + cabalComponent, + StackType, + pattern StackType, + stackComponent, + stackYaml, CradleType(..), - pattern Cabal, - pattern Stack, Callable(..) ) where import qualified Data.Text as T import qualified Data.Vector as V import qualified Data.HashMap.Strict as Map +import Data.Semigroup import Data.Foldable (foldrM) import Data.Yaml +type MLast a = Maybe (Last a) + +viewLast :: MLast a -> Maybe a +viewLast (Just l) = Just $ getLast l +viewLast Nothing = Nothing + +pattern MLast :: Maybe a -> MLast a +pattern MLast m <- (viewLast -> m) where + MLast (Just l) = Just $ Last l + MLast Nothing = Nothing + -- | Configuration that can be used to load a 'Cradle'. -- A configuration has roughly the following form: -- @@ -50,24 +66,44 @@ data Callable = Program FilePath | Command String deriving (Show, Eq) data CabalType - = CabalType { cabalComponent :: Maybe String } + = CabalType_ { _cabalComponent :: !(MLast String) } deriving (Eq) +instance Semigroup CabalType where + CabalType_ cr <> CabalType_ cl = CabalType_ (cr <> cl) + +instance Monoid CabalType where + mempty = CabalType_ mempty + +pattern CabalType :: Maybe String -> CabalType +pattern CabalType { cabalComponent } = CabalType_ (MLast cabalComponent) +{-# COMPLETE CabalType #-} + instance Show CabalType where - show = show . Cabal_ + show = show . Cabal data StackType - = StackType { stackComponent :: Maybe String , stackYaml :: Maybe String } + = StackType_ { _stackComponent :: !(MLast String) , _stackYaml :: !(MLast String) } deriving (Eq) +instance Semigroup StackType where + StackType_ cr yr <> StackType_ cl yl = StackType_ (cr <> cl) (yr <> yl) + +instance Monoid StackType where + mempty = StackType_ mempty mempty + +pattern StackType :: Maybe String -> Maybe String -> StackType +pattern StackType { stackComponent, stackYaml } = StackType_ (MLast stackComponent) (MLast stackYaml) +{-# COMPLETE StackType #-} + instance Show StackType where - show = show . Stack_ + show = show . Stack data CradleType a - = Cabal_ { cabalType :: !CabalType } - | CabalMulti [ (FilePath, CabalType) ] - | Stack_ { stackType :: !StackType } - | StackMulti [ (FilePath, StackType) ] + = Cabal { cabalType :: !CabalType } + | CabalMulti { defaultCabal :: !CabalType, subCabalComponents :: [ (FilePath, CabalType) ] } + | Stack { stackType :: !StackType } + | StackMulti { defaultStack :: !StackType, subStackComponents :: [ (FilePath, StackType) ] } -- Bazel and Obelisk used to be supported but bit-rotted and no users have complained. -- They can be added back if a user -- | Bazel @@ -86,23 +122,15 @@ data CradleType a | Other { otherConfig :: a, originalYamlValue :: Value } deriving (Eq, Functor) -pattern Cabal :: Maybe String -> CradleType a -pattern Cabal cm = Cabal_ (CabalType cm) - -pattern Stack :: Maybe String -> Maybe String -> CradleType a -pattern Stack cm yml = Stack_ (StackType cm yml) - -{-# COMPLETE Cabal, CabalMulti, Stack, StackMulti, Bios, Direct, None, Multi, Other :: CradleType #-} - instance FromJSON a => FromJSON (CradleType a) where parseJSON (Object o) = parseCradleType o parseJSON _ = fail "Not a known cradle type. Possible are: cabal, stack, bios, direct, default, none, multi" instance Show (CradleType a) where - show (Cabal comp) = "Cabal {component = " ++ show comp ++ "}" - show (CabalMulti a) = "CabalMulti " ++ show a - show (Stack comp yaml) = "Stack {component = " ++ show comp ++ ", stackYaml = " ++ show yaml ++ "}" - show (StackMulti a) = "StackMulti " ++ show a + show (Cabal comp) = "Cabal {component = " ++ show (cabalComponent comp) ++ "}" + show (CabalMulti d a) = "CabalMulti {defaultCabal = " ++ show d ++ ", subCabalComponents = " ++ show a ++ "}" + show (Stack comp) = "Stack {component = " ++ show (stackComponent comp) ++ ", stackYaml = " ++ show (stackYaml comp) ++ "}" + show (StackMulti d a) = "StackMulti {defaultStack = " ++ show d ++ ", subStackComponents = " ++ show a ++ "}" show Bios { call, depsCall } = "Bios {call = " ++ show call ++ ", depsCall = " ++ show depsCall ++ "}" show (Direct args) = "Direct {arguments = " ++ show args ++ "}" show None = "None" @@ -123,41 +151,54 @@ parseCradleType o parseCradleType o = fail $ "Unknown cradle type: " ++ show o parseSingleOrMultiple - :: (x -> CradleType a) - -> ([(FilePath, x)] -> CradleType a) + :: Monoid x + => (x -> CradleType a) + -> (x -> [(FilePath, x)] -> CradleType a) -> (Map.HashMap T.Text Value -> Parser x) -> Value -> Parser (CradleType a) -parseSingleOrMultiple single _ parse (Object v) = single <$> parse v -parseSingleOrMultiple _ multiple parse (Array x) = do - let parseOne e +parseSingleOrMultiple single multiple parse = doParse where + parseOne e | Object v <- e , Just (String prefix) <- Map.lookup "path" v = (T.unpack prefix,) <$> parse (Map.delete "path" v) | otherwise = fail "Expected an object with a path key" - xs <- foldrM (\v cs -> (: cs) <$> parseOne v) [] x - return $ multiple xs -parseSingleOrMultiple single _ parse Null = single <$> parse Map.empty -parseSingleOrMultiple _ _ _ _ = fail "Configuration is expected to be an object or an array of objects." + parseArray = foldrM (\v cs -> (: cs) <$> parseOne v) [] + doParse (Object v) + | Just (Array x) <- Map.lookup "components" v + = do + d <- parse (Map.delete "components" v) + xs <- parseArray x + return $ multiple d xs + | Just _ <- Map.lookup "components" v + = fail "Expected components to be an array of subcomponents" + | Nothing <- Map.lookup "components" v + = single <$> parse v + doParse (Array x) + = do + xs <- parseArray x + return $ multiple mempty xs + doParse Null = single <$> parse Map.empty + doParse _ = fail "Configuration is expected to be an object or an array of objects." parseStack :: Value -> Parser (CradleType a) -parseStack = parseSingleOrMultiple Stack_ StackMulti $ +parseStack = parseSingleOrMultiple Stack StackMulti $ \case x | Map.size x == 2 , Just (String component) <- Map.lookup "component" x - , Just (String stackYaml) <- Map.lookup "stackYaml" x - -> return $ StackType (Just $ T.unpack component) (Just $ T.unpack stackYaml) + , Just (String syaml) <- Map.lookup "stackYaml" x + -> return $ StackType (Just $ T.unpack component) (Just $ T.unpack syaml) | Map.size x == 1, Just (String component) <- Map.lookup "component" x -> return $ StackType (Just $ T.unpack component) Nothing - | Map.size x == 1, Just (String stackYaml) <- Map.lookup "stackYaml" x - -> return $ StackType Nothing (Just $ T.unpack stackYaml) + | Map.size x == 1, Just (String syaml) <- Map.lookup "stackYaml" x + -> return $ StackType Nothing (Just $ T.unpack syaml) | Map.null x -> return $ StackType Nothing Nothing | otherwise -> fail "Not a valid Stack configuration, following keys are allowed: component, stackYaml" parseCabal :: Value -> Parser (CradleType a) -parseCabal = parseSingleOrMultiple Cabal_ CabalMulti $ +parseCabal = parseSingleOrMultiple Cabal CabalMulti $ \case x | Map.size x == 1, Just (String component) <- Map.lookup "component" x -> return $ CabalType (Just $ T.unpack component) | Map.null x @@ -239,4 +280,4 @@ instance FromJSON a => FromJSON (Config a) where -- If the contents of the file is not a valid 'Config a', -- an 'Control.Exception.IOException' is thrown. readConfig :: FromJSON a => FilePath -> IO (Config a) -readConfig = decodeFileThrow \ No newline at end of file +readConfig = decodeFileThrow diff --git a/src/HIE/Bios/Cradle.hs b/src/HIE/Bios/Cradle.hs index c1e76a588..6a543356f 100644 --- a/src/HIE/Bios/Cradle.hs +++ b/src/HIE/Bios/Cradle.hs @@ -93,17 +93,17 @@ loadCradleWithOpts _copts buildCustomCradle wfile = do getCradle :: (b -> Cradle a) -> (CradleConfig b, FilePath) -> Cradle a getCradle buildCustomCradle (cc, wdir) = addCradleDeps cradleDeps $ case cradleType cc of - Cabal mc -> cabalCradle wdir mc - CabalMulti ms -> + Cabal CabalType{ cabalComponent = mc } -> cabalCradle wdir mc + CabalMulti dc ms -> getCradle buildCustomCradle $ (CradleConfig cradleDeps - (Multi [(p, CradleConfig [] (Cabal_ c)) | (p, c) <- ms]) + (Multi [(p, CradleConfig [] (Cabal $ dc <> c)) | (p, c) <- ms]) , wdir) - Stack mc syaml -> stackCradle wdir mc (maybe "stack.yaml" id syaml) - StackMulti ms -> + Stack StackType{ stackComponent = mc, stackYaml = syaml} -> stackCradle wdir mc (maybe "stack.yaml" id syaml) + StackMulti ds ms -> getCradle buildCustomCradle $ (CradleConfig cradleDeps - (Multi [(p, CradleConfig [] (Stack_ c)) | (p, c) <- ms]) + (Multi [(p, CradleConfig [] (Stack $ ds <> c)) | (p, c) <- ms]) , wdir) -- Bazel -> rulesHaskellCradle wdir -- Obelisk -> obeliskCradle wdir @@ -143,8 +143,8 @@ implicitConfig' fp = (\wdir -> (Bios (Program $ wdir ".hie-bios") Nothing, wdir)) <$> biosWorkDir fp -- <|> (Obelisk,) <$> obeliskWorkDir fp -- <|> (Bazel,) <$> rulesHaskellWorkDir fp - <|> (stackExecutable >> (Stack Nothing Nothing,) <$> stackWorkDir fp) - <|> ((Cabal Nothing,) <$> cabalWorkDir fp) + <|> (stackExecutable >> (Stack $ StackType Nothing Nothing,) <$> stackWorkDir fp) + <|> ((Cabal $ CabalType Nothing,) <$> cabalWorkDir fp) yamlConfig :: FilePath -> MaybeT IO FilePath diff --git a/tests/ParserTests.hs b/tests/ParserTests.hs index 5cff97feb..6b2511216 100644 --- a/tests/ParserTests.hs +++ b/tests/ParserTests.hs @@ -17,43 +17,48 @@ configDir = "tests/configs" main :: IO () main = defaultMain $ testCase "Parser Tests" $ do - assertParser "cabal-1.yaml" (noDeps (Cabal (Just "lib:hie-bios"))) - assertParser "stack-config.yaml" (noDeps (Stack Nothing Nothing)) + assertParser "cabal-1.yaml" (noDeps (Cabal $ CabalType (Just "lib:hie-bios"))) + assertParser "stack-config.yaml" (noDeps (Stack $ StackType Nothing Nothing)) --assertParser "bazel.yaml" (noDeps Bazel) assertParser "bios-1.yaml" (noDeps (Bios (Program "program") Nothing)) assertParser "bios-2.yaml" (noDeps (Bios (Program "program") (Just (Program "dep-program")))) assertParser "bios-3.yaml" (noDeps (Bios (Command "shellcommand") Nothing)) assertParser "bios-4.yaml" (noDeps (Bios (Command "shellcommand") (Just (Command "dep-shellcommand")))) assertParser "bios-5.yaml" (noDeps (Bios (Command "shellcommand") (Just (Program "dep-program")))) - assertParser "dependencies.yaml" (Config (CradleConfig ["depFile"] (Cabal (Just "lib:hie-bios")))) + assertParser "dependencies.yaml" (Config (CradleConfig ["depFile"] (Cabal $ CabalType (Just "lib:hie-bios")))) assertParser "direct.yaml" (noDeps (Direct ["list", "of", "arguments"])) assertParser "none.yaml" (noDeps None) --assertParser "obelisk.yaml" (noDeps Obelisk) - assertParser "multi.yaml" (noDeps (Multi [("./src", CradleConfig [] (Cabal (Just "lib:hie-bios"))) - , ("./test", CradleConfig [] (Cabal (Just "test")) ) ])) + assertParser "multi.yaml" (noDeps (Multi [("./src", CradleConfig [] (Cabal $ CabalType (Just "lib:hie-bios"))) + ,("./test", CradleConfig [] (Cabal $ CabalType (Just "test")) ) ])) - assertParser "cabal-multi.yaml" (noDeps (CabalMulti [("./src", CabalType $ Just "lib:hie-bios") + assertParser "cabal-multi.yaml" (noDeps (CabalMulti (CabalType Nothing) + [("./src", CabalType $ Just "lib:hie-bios") ,("./", CabalType $ Just "lib:hie-bios")])) - assertParser "stack-multi.yaml" (noDeps (StackMulti [("./src", StackType (Just "lib:hie-bios") Nothing) + assertParser "stack-multi.yaml" (noDeps (StackMulti (StackType Nothing Nothing) + [("./src", StackType (Just "lib:hie-bios") Nothing) ,("./", StackType (Just"lib:hie-bios") Nothing)])) assertParser "nested-cabal-multi.yaml" (noDeps (Multi [("./test/testdata", CradleConfig [] None) ,("./", CradleConfig [] ( - CabalMulti [("./src", CabalType $ Just "lib:hie-bios") + CabalMulti (CabalType Nothing) + [("./src", CabalType $ Just "lib:hie-bios") ,("./tests", CabalType $ Just "parser-tests")]))])) assertParser "nested-stack-multi.yaml" (noDeps (Multi [("./test/testdata", CradleConfig [] None) ,("./", CradleConfig [] ( - StackMulti [("./src", StackType (Just "lib:hie-bios") Nothing) - ,("./tests", StackType (Just "parser-tests") Nothing)]))])) + StackMulti (StackType Nothing Nothing) + [("./src", StackType (Just "lib:hie-bios") Nothing) + ,("./tests", StackType (Just "parser-tests") Nothing)]))])) assertParser "stack-with-yaml.yaml" - (noDeps (Stack Nothing (Just "stack-8.8.3.yaml"))) + (noDeps (Stack $ StackType Nothing (Just "stack-8.8.3.yaml"))) assertParser "stack-with-both.yaml" - (noDeps (Stack (Just "hie-bios:hie") (Just "stack-8.8.3.yaml"))) + (noDeps (Stack $ StackType (Just "hie-bios:hie") (Just "stack-8.8.3.yaml"))) assertParser "multi-stack-with-yaml.yaml" - (noDeps (StackMulti [("./src", StackType Nothing $ Just "stack-8.8.3.yaml") - ,("./vendor", StackType Nothing $ Just "./vendor/stack-8.8.3.yaml")])) + (noDeps (StackMulti (StackType Nothing (Just "stack-8.8.3.yaml")) + [("./src", StackType (Just "lib:hie-bios") Nothing) + ,("./vendor", StackType (Just "parser-tests") Nothing)])) assertCustomParser "ch-cabal.yaml" (noDeps (Other CabalHelperCabal $ simpleCabalHelperYaml "cabal")) @@ -63,7 +68,7 @@ main = defaultMain $ (noDeps (Multi [ ("./src", CradleConfig [] (Other CabalHelperStack $ simpleCabalHelperYaml "stack")) , ("./input", CradleConfig [] (Other CabalHelperCabal $ simpleCabalHelperYaml "cabal")) - , ("./test", CradleConfig [] (Cabal (Just "test"))) + , ("./test", CradleConfig [] (Cabal $ CabalType (Just "test"))) , (".", CradleConfig [] None) ])) diff --git a/tests/configs/multi-stack-with-yaml.yaml b/tests/configs/multi-stack-with-yaml.yaml index f54344be9..8c83efbef 100644 --- a/tests/configs/multi-stack-with-yaml.yaml +++ b/tests/configs/multi-stack-with-yaml.yaml @@ -1,6 +1,8 @@ cradle: stack: - - path: "./src" - stackYaml: "stack-8.8.3.yaml" - - path: "./vendor" - stackYaml: "./vendor/stack-8.8.3.yaml" + stackYaml: "stack-8.8.3.yaml" + components: + - path: "./src" + component: "lib:hie-bios" + - path: "./vendor" + component: "parser-tests" diff --git a/tests/projects/stack-with-yaml/hie.yaml b/tests/projects/stack-with-yaml/hie.yaml index 2c996c4cd..a5f7431f6 100644 --- a/tests/projects/stack-with-yaml/hie.yaml +++ b/tests/projects/stack-with-yaml/hie.yaml @@ -1,9 +1,9 @@ cradle: stack: - - path: ./src - component: "stack-with-yaml:lib" - stackYaml: "stack-alt.yaml" + stackYaml: "stack-alt.yaml" + components: + - path: ./src + component: "stack-with-yaml:lib" - - path: ./app - component: "stack-with-yaml:exe:stack-with-yaml" - stackYaml: "stack-alt.yaml" + - path: ./app + component: "stack-with-yaml:exe:stack-with-yaml" From 98ad7f730159330433b2e36472cbc1a86468f02d Mon Sep 17 00:00:00 2001 From: WorldSEnder Date: Tue, 11 Aug 2020 07:49:55 +0200 Subject: [PATCH 11/14] add warning about multiple stackYamls --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 00d51f32b..fd71ff1c1 100644 --- a/README.md +++ b/README.md @@ -154,6 +154,8 @@ cradle: component: "hie-bios:test:parser-tests" ``` +A word of warning: Due to current restrictions in the language server, as mentioned in [this bug report](https://github.com/haskell/haskell-language-server/issues/268#issuecomment-667640809) all referenced stack.yaml files must specify the same version of GHC, as only one version of ghcide is loaded at a time. This restriction might be lifted in the future. + #### Debugging a `stack` cradle If you find that `hie-bios` can't load a certain component or file, run `stack repl` and `stack repl ` to see if `stack` succeeds in building your project. Chances are that there is a problem in your project and if you fix that, `hie-bios` will succeed to load it. From 9e1fa2fdcb42d0f9fa757cff8d5335c1894d5642 Mon Sep 17 00:00:00 2001 From: WorldSEnder Date: Wed, 19 Aug 2020 14:40:09 +0200 Subject: [PATCH 12/14] review fixes --- README.md | 2 +- hie-bios.cabal | 2 ++ src/HIE/Bios/Config.hs | 19 ++++++++++++++++++- tests/ParserTests.hs | 10 ++++++++++ tests/configs/keys-not-unique-fails.yaml | 12 ++++++++++++ 5 files changed, 43 insertions(+), 2 deletions(-) create mode 100644 tests/configs/keys-not-unique-fails.yaml diff --git a/README.md b/README.md index c5fb441e2..ee40019a0 100644 --- a/README.md +++ b/README.md @@ -154,7 +154,7 @@ cradle: component: "hie-bios:test:parser-tests" ``` -A word of warning: Due to current restrictions in the language server, as mentioned in [this bug report](https://github.com/haskell/haskell-language-server/issues/268#issuecomment-667640809) all referenced stack.yaml files must specify the same version of GHC, as only one version of ghcide is loaded at a time. This restriction might be lifted in the future. +A word of warning: Due to current restrictions in the language server, as mentioned in [this bug report](https://github.com/haskell/haskell-language-server/issues/268#issuecomment-667640809) all referenced stack.yaml files must specify the same version of GHC, as only one version of ghcide is loaded at a time per workspace root. This restriction might be lifted in the future. #### Debugging a `stack` cradle diff --git a/hie-bios.cabal b/hie-bios.cabal index 35bc4a280..36f3d596b 100644 --- a/hie-bios.cabal +++ b/hie-bios.cabal @@ -32,6 +32,7 @@ Extra-Source-Files: ChangeLog.md tests/configs/multi.yaml tests/configs/multi-ch.yaml tests/configs/multi-stack-with-yaml.yaml + tests/configs/keys-not-unique-fails.yaml tests/configs/nested-cabal-multi.yaml tests/configs/nested-stack-multi.yaml tests/configs/none.yaml @@ -230,6 +231,7 @@ test-suite parser-tests base, filepath, hie-bios, + hspec-expectations, tasty, tasty-hunit, text, diff --git a/src/HIE/Bios/Config.hs b/src/HIE/Bios/Config.hs index 36f6c5cf6..995d7b6d6 100644 --- a/src/HIE/Bios/Config.hs +++ b/src/HIE/Bios/Config.hs @@ -21,12 +21,16 @@ module HIE.Bios.Config( Callable(..) ) where +import Control.Exception import qualified Data.Text as T import qualified Data.Vector as V import qualified Data.HashMap.Strict as Map +import Data.Maybe (mapMaybe) import Data.Semigroup import Data.Foldable (foldrM) +import Data.Aeson (JSONPath) import Data.Yaml +import Data.Yaml.Internal (Warning(..)) type MLast a = Maybe (Last a) @@ -285,4 +289,17 @@ instance FromJSON a => FromJSON (Config a) where -- If the contents of the file is not a valid 'Config a', -- an 'Control.Exception.IOException' is thrown. readConfig :: FromJSON a => FilePath -> IO (Config a) -readConfig = decodeFileThrow +readConfig fp = do + result <- decodeFileWithWarnings fp + either throwIO failOnAnyDuplicate result + where + failOnAnyDuplicate :: ([Warning], Config a) -> IO (Config a) + failOnAnyDuplicate (warnings, config) = do + _ <- case mapMaybe failOnDuplicate warnings of + dups@(_:_) -> throwIO $ InvalidYaml $ Just $ YamlException + $ "Duplicate keys are not allowed, found: " ++ show dups + _ -> return () + return config + -- future proofing in case more warnings are added + failOnDuplicate :: Warning -> Maybe JSONPath + failOnDuplicate (DuplicateKey a) = Just a diff --git a/tests/ParserTests.hs b/tests/ParserTests.hs index 006e85c7d..f4f60f73d 100644 --- a/tests/ParserTests.hs +++ b/tests/ParserTests.hs @@ -1,6 +1,7 @@ {-# LANGUAGE OverloadedStrings #-} module Main where +import Test.Hspec.Expectations import Test.Tasty import Test.Tasty.HUnit import HIE.Bios.Config @@ -10,6 +11,7 @@ import Data.Yaml import qualified Data.Text as T import System.FilePath import Control.Applicative ( (<|>) ) +import Control.Exception configDir :: FilePath configDir = "tests/configs" @@ -71,6 +73,7 @@ main = defaultMain $ , ("./test", CradleConfig [] (Cabal $ CabalType (Just "test"))) , (".", CradleConfig [] None) ])) + assertParserFails "keys-not-unique-fails.yaml" invalidYamlException assertParser :: FilePath -> Config Void -> Assertion assertParser fp cc = do @@ -79,6 +82,13 @@ assertParser fp cc = do , "Expected: " ++ show cc , "Actual: " ++ show conf ]) +invalidYamlException :: Selector ParseException +invalidYamlException (InvalidYaml (Just _)) = True +invalidYamlException _ = False + +assertParserFails :: Exception e => FilePath -> Selector e -> Assertion +assertParserFails fp es = (readConfig (configDir fp) :: IO (Config Void)) `shouldThrow` es + assertCustomParser :: FilePath -> Config CabalHelper -> Assertion assertCustomParser fp cc = do conf <- readConfig (configDir fp) diff --git a/tests/configs/keys-not-unique-fails.yaml b/tests/configs/keys-not-unique-fails.yaml new file mode 100644 index 000000000..7a99aa23b --- /dev/null +++ b/tests/configs/keys-not-unique-fails.yaml @@ -0,0 +1,12 @@ +cradle: + cabal: + components: + - path: "./src" + component: "lib:hie-bios" + - path: "./" + component: "lib:hie-bios" + components: + - path: "./src" + component: "exe:hie-bios" + - path: "./" + component: "exe:hie-bios" From 05f4462b778861b9cdeefc3ad6855f1c6adce9eb Mon Sep 17 00:00:00 2001 From: WorldSEnder Date: Wed, 19 Aug 2020 15:14:26 +0200 Subject: [PATCH 13/14] [ci skip] document changes to cabal configurations --- README.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/README.md b/README.md index ee40019a0..1a6ed7d6f 100644 --- a/README.md +++ b/README.md @@ -297,6 +297,25 @@ Here you can see two important features: * The filepath can be a file. * This is convenient if components are overlapping. +Similarly to `multi-stack` configurations, you can also specify multiple components using a `components` subkey. +While this is currently not used for anything, this syntax gives you a place to put defaults, directly under +the `cabal` entry. + +```yaml +cradle: + cabal: + # Reserved for future default options + components: + - path: "./src" + component: "lib:hie-bios" + - path: "./exe" + component: "exe:hie-bios" + - path: "./tests/BiosTests.hs" + component: "test:hie-bios" + - path: "./tests/ParserTests.hs" + component: "test:parser-tests" +``` + This way we specified which component needs to be compiled given a certain source file for our whole project. #### Debugging a `cabal` cradle From 8969b59107bc228ed417b125bc1fd8481d96360a Mon Sep 17 00:00:00 2001 From: WorldSEnder Date: Sat, 22 Aug 2020 16:07:32 +0200 Subject: [PATCH 14/14] Use suggested changes Co-authored-by: fendor --- src/HIE/Bios/Cradle.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/HIE/Bios/Cradle.hs b/src/HIE/Bios/Cradle.hs index 472b4e74c..63043e52e 100644 --- a/src/HIE/Bios/Cradle.hs +++ b/src/HIE/Bios/Cradle.hs @@ -99,7 +99,7 @@ getCradle buildCustomCradle (cc, wdir) = addCradleDeps cradleDeps $ case cradleT (CradleConfig cradleDeps (Multi [(p, CradleConfig [] (Cabal $ dc <> c)) | (p, c) <- ms]) , wdir) - Stack StackType{ stackComponent = mc, stackYaml = syaml} -> stackCradle wdir mc (maybe "stack.yaml" id syaml) + Stack StackType{ stackComponent = mc, stackYaml = syaml} -> stackCradle wdir mc (fromMaybe "stack.yaml" syaml) StackMulti ds ms -> getCradle buildCustomCradle $ (CradleConfig cradleDeps