From 0cd4419e58916f67b8ee78f9d5fbb835b17146da Mon Sep 17 00:00:00 2001 From: NightRa Date: Thu, 12 Sep 2019 23:13:24 +0300 Subject: [PATCH 01/14] [setup-info]: Prioritize CmdArgs & Config over default, --setup-info-yaml as top level CmdArg --- src/Stack/Options/ConfigParser.hs | 17 +++++++++++++++-- src/Stack/Setup.hs | 13 +++++-------- src/Stack/SetupCmd.hs | 16 ---------------- 3 files changed, 20 insertions(+), 26 deletions(-) diff --git a/src/Stack/Options/ConfigParser.hs b/src/Stack/Options/ConfigParser.hs index 7d5f5509f6..fcdf37eb6b 100644 --- a/src/Stack/Options/ConfigParser.hs +++ b/src/Stack/Options/ConfigParser.hs @@ -21,8 +21,8 @@ configOptsParser :: FilePath -> GlobalOptsContext -> Parser ConfigMonoid configOptsParser currentDir hide0 = (\stackRoot workDir buildOpts dockerOpts nixOpts systemGHC installGHC arch ghcVariant ghcBuild jobs includes libs overrideGccPath overrideHpack - skipGHCCheck skipMsys localBin modifyCodePage allowDifferentUser - dumpLogs colorWhen -> mempty + skipGHCCheck skipMsys localBin setupInfoLocations modifyCodePage + allowDifferentUser dumpLogs colorWhen -> mempty { configMonoidStackRoot = stackRoot , configMonoidWorkDir = workDir , configMonoidBuildOpts = buildOpts @@ -41,6 +41,7 @@ configOptsParser currentDir hide0 = , configMonoidOverrideHpack = overrideHpack , configMonoidSkipMsys = skipMsys , configMonoidLocalBinPath = localBin + , configMonoidSetupInfoLocations = setupInfoLocations , configMonoidModifyCodePage = modifyCodePage , configMonoidAllowDifferentUser = allowDifferentUser , configMonoidDumpLogs = dumpLogs @@ -128,6 +129,18 @@ configOptsParser currentDir hide0 = <> help "Install binaries to DIR" <> hide )) + <*> many (SetupInfoFileOrURL <$> ( + ( strOption + ( long "stack-setup-yaml" + <> help "DEPRECATED: Use 'setup-info-yaml' instead" + <> metavar "URL" + <> hidden ) + ) <|> + ( strOption + ( long "setup-info-yaml" + <> help "Alternate URL or absolute path for stack dependencies" + <> metavar "URL" ) + ))) <*> firstBoolFlagsTrue "modify-code-page" "setting the codepage to support UTF-8 (Windows only)" diff --git a/src/Stack/Setup.hs b/src/Stack/Setup.hs index 0fd7ee59ff..a598d77223 100644 --- a/src/Stack/Setup.hs +++ b/src/Stack/Setup.hs @@ -121,8 +121,6 @@ data SetupOpts = SetupOpts -- ^ Do not use a custom msys installation on Windows , soptsResolveMissingGHC :: !(Maybe Text) -- ^ Message shown to user for how to resolve the missing GHC - , soptsSetupInfoYaml :: !FilePath - -- ^ Location of the main stack-setup.yaml file , soptsGHCBindistURL :: !(Maybe String) -- ^ Alternate GHC binary distribution (requires custom GHCVariant) , soptsGHCJSBootOpts :: [String] @@ -225,7 +223,6 @@ setupEnv needTargets boptsCLI mResolveMissingGHC = do , soptsSkipGhcCheck = configSkipGHCCheck config , soptsSkipMsys = configSkipMsys config , soptsResolveMissingGHC = mResolveMissingGHC - , soptsSetupInfoYaml = defaultSetupInfoYaml , soptsGHCBindistURL = Nothing , soptsGHCJSBootOpts = ["--clean"] } @@ -456,7 +453,7 @@ ensureCompilerAndMsys ensureCompilerAndMsys sopts = do didWarn <- warnUnsupportedCompiler $ getGhcVersion $ wantedToActual $ soptsWantedCompiler sopts - getSetupInfo' <- memoizeRef (getSetupInfo (soptsSetupInfoYaml sopts)) + getSetupInfo' <- memoizeRef getSetupInfo (cp, ghcPaths) <- ensureCompiler sopts getSetupInfo' warnUnsupportedCompilerCabal cp didWarn @@ -1070,14 +1067,14 @@ sourceSystemCompilers wanted = do | otherwise = id -- | Download the most recent SetupInfo -getSetupInfo :: HasConfig env => String -> RIO env SetupInfo -getSetupInfo stackSetupYaml = do +getSetupInfo :: HasConfig env => RIO env SetupInfo +getSetupInfo = do config <- view configL setupInfos <- mapM loadSetupInfo - (SetupInfoFileOrURL stackSetupYaml : - configSetupInfoLocations config) + (configSetupInfoLocations config ++ + [SetupInfoFileOrURL defaultSetupInfoYaml]) return (mconcat setupInfos) where loadSetupInfo (SetupInfoInline si) = return si diff --git a/src/Stack/SetupCmd.hs b/src/Stack/SetupCmd.hs index bf010243ec..a166b6bf10 100644 --- a/src/Stack/SetupCmd.hs +++ b/src/Stack/SetupCmd.hs @@ -27,25 +27,11 @@ import Stack.Types.Version data SetupCmdOpts = SetupCmdOpts { scoCompilerVersion :: !(Maybe WantedCompiler) , scoForceReinstall :: !Bool - , scoSetupInfoYaml :: !String , scoGHCBindistURL :: !(Maybe String) , scoGHCJSBootOpts :: ![String] , scoGHCJSBootClean :: !Bool } -setupYamlCompatParser :: OA.Parser String -setupYamlCompatParser = stackSetupYaml <|> setupInfoYaml - where stackSetupYaml = OA.strOption ( - OA.long "stack-setup-yaml" - <> OA.help "DEPRECATED: Use 'setup-info-yaml' instead" - <> OA.metavar "URL" - <> OA.hidden ) - setupInfoYaml = OA.strOption ( - OA.long "setup-info-yaml" - <> OA.help "Alternate URL or absolute path for stack dependencies" - <> OA.metavar "URL" - <> OA.value defaultSetupInfoYaml ) - setupParser :: OA.Parser SetupCmdOpts setupParser = SetupCmdOpts <$> OA.optional (OA.argument readVersion @@ -56,7 +42,6 @@ setupParser = SetupCmdOpts "reinstall" "reinstalling GHC, even if available (incompatible with --system-ghc)" OA.idm - <*> setupYamlCompatParser <*> OA.optional (OA.strOption (OA.long "ghc-bindist" <> OA.metavar "URL" @@ -99,7 +84,6 @@ setup SetupCmdOpts{..} wantedCompiler compilerCheck mstack = do , soptsSkipGhcCheck = False , soptsSkipMsys = configSkipMsys , soptsResolveMissingGHC = Nothing - , soptsSetupInfoYaml = scoSetupInfoYaml , soptsGHCBindistURL = scoGHCBindistURL , soptsGHCJSBootOpts = scoGHCJSBootOpts ++ ["--clean" | scoGHCJSBootClean] } From 0d9e58e2d7382f1311ba401c9a02d7a9d11d7685 Mon Sep 17 00:00:00 2001 From: NightRa Date: Fri, 13 Sep 2019 01:04:30 +0300 Subject: [PATCH 02/14] [setup-info]: Proper support for multiple setup info locations, use default if none specified. --- src/Stack/Config.hs | 1 + src/Stack/Options/ConfigParser.hs | 4 +-- src/Stack/Setup.hs | 31 +++++++++++------------ src/Stack/Types/Config.hs | 42 +++++++++++++------------------ 4 files changed, 35 insertions(+), 43 deletions(-) diff --git a/src/Stack/Config.hs b/src/Stack/Config.hs index 7008c33e77..eef5b56b09 100644 --- a/src/Stack/Config.hs +++ b/src/Stack/Config.hs @@ -320,6 +320,7 @@ configFromConfigMonoid configGhcOptionsByName = coerce configMonoidGhcOptionsByName configGhcOptionsByCat = coerce configMonoidGhcOptionsByCat configSetupInfoLocations = configMonoidSetupInfoLocations + configSetupInfoInline = configMonoidSetupInfoInline configPvpBounds = fromFirst (PvpBounds PvpBoundsNone False) configMonoidPvpBounds configModifyCodePage = fromFirstTrue configMonoidModifyCodePage configExplicitSetupDeps = configMonoidExplicitSetupDeps diff --git a/src/Stack/Options/ConfigParser.hs b/src/Stack/Options/ConfigParser.hs index fcdf37eb6b..d1b2f26ad5 100644 --- a/src/Stack/Options/ConfigParser.hs +++ b/src/Stack/Options/ConfigParser.hs @@ -129,7 +129,7 @@ configOptsParser currentDir hide0 = <> help "Install binaries to DIR" <> hide )) - <*> many (SetupInfoFileOrURL <$> ( + <*> many ( ( strOption ( long "stack-setup-yaml" <> help "DEPRECATED: Use 'setup-info-yaml' instead" @@ -140,7 +140,7 @@ configOptsParser currentDir hide0 = ( long "setup-info-yaml" <> help "Alternate URL or absolute path for stack dependencies" <> metavar "URL" ) - ))) + )) <*> firstBoolFlagsTrue "modify-code-page" "setting the codepage to support UTF-8 (Windows only)" diff --git a/src/Stack/Setup.hs b/src/Stack/Setup.hs index a598d77223..c5f1c13d56 100644 --- a/src/Stack/Setup.hs +++ b/src/Stack/Setup.hs @@ -1070,23 +1070,22 @@ sourceSystemCompilers wanted = do getSetupInfo :: HasConfig env => RIO env SetupInfo getSetupInfo = do config <- view configL - setupInfos <- - mapM - loadSetupInfo - (configSetupInfoLocations config ++ - [SetupInfoFileOrURL defaultSetupInfoYaml]) - return (mconcat setupInfos) + let inlineSetupInfo = configSetupInfoInline config + locations' = configSetupInfoLocations config + locations = if null locations' then [defaultSetupInfoYaml] else locations' + + resolvedSetupInfos <- mapM loadSetupInfo locations + return (inlineSetupInfo <> mconcat resolvedSetupInfos) where - loadSetupInfo (SetupInfoInline si) = return si - loadSetupInfo (SetupInfoFileOrURL urlOrFile) = do - bs <- - case parseUrlThrow urlOrFile of - Just req -> liftM (LBS.toStrict . getResponseBody) $ httpLbs req - Nothing -> liftIO $ S.readFile urlOrFile - WithJSONWarnings si warnings <- either throwM return (Yaml.decodeEither' bs) - when (urlOrFile /= defaultSetupInfoYaml) $ - logJSONWarnings urlOrFile warnings - return si + loadSetupInfo urlOrFile = do + bs <- + case parseUrlThrow urlOrFile of + Just req -> liftM (LBS.toStrict . getResponseBody) $ httpLbs req + Nothing -> liftIO $ S.readFile urlOrFile + WithJSONWarnings si warnings <- either throwM return (Yaml.decodeEither' bs) + when (urlOrFile /= defaultSetupInfoYaml) $ + logJSONWarnings urlOrFile warnings + return si getInstalledTool :: [Tool] -- ^ already installed -> PackageName -- ^ package to find diff --git a/src/Stack/Types/Config.hs b/src/Stack/Types/Config.hs index 8ccdae83d7..159001ff9c 100644 --- a/src/Stack/Types/Config.hs +++ b/src/Stack/Types/Config.hs @@ -140,7 +140,6 @@ module Stack.Types.Config ,VersionedDownloadInfo(..) ,GHCDownloadInfo(..) ,SetupInfo(..) - ,SetupInfoLocation(..) -- ** Docker entrypoint ,DockerEntrypoint(..) ,DockerUser(..) @@ -182,7 +181,7 @@ import Pantry.Internal.AesonExtended (ToJSON, toJSON, FromJSON, FromJSONKey (..), parseJSON, withText, object, (.=), (..:), (...:), (..:?), (..!=), Value(Bool), withObjectWarnings, WarningParser, Object, jsonSubWarnings, - jsonSubWarningsT, jsonSubWarningsTT, WithJSONWarnings(..), noJSONWarnings, + jsonSubWarningsT, jsonSubWarningsTT, WithJSONWarnings(..), FromJSONKeyFunction (FromJSONKeyTextParser)) import Data.Attoparsec.Args (parseArgs, EscapingMode (Escaping)) import qualified Data.ByteArray.Encoding as Mem (convertToBase, Base(Base16)) @@ -333,8 +332,11 @@ data Config = -- ^ Additional GHC options to apply to categories of packages ,configCabalConfigOpts :: !(Map CabalConfigKey [Text]) -- ^ Additional options to be passed to ./Setup.hs configure - ,configSetupInfoLocations :: ![SetupInfoLocation] - -- ^ Additional SetupInfo (inline or remote) to use to find tools. + ,configSetupInfoLocations :: ![String] + -- ^ URLs or paths to setup-info.yaml files, for finding tools. + -- If none present, the default setup-info is used. + ,configSetupInfoInline :: !SetupInfo + -- ^ Additional SetupInfo to use to find tools. ,configPvpBounds :: !PvpBounds -- ^ How PVP upper bounds should be added to packages ,configModifyCodePage :: !Bool @@ -820,8 +822,11 @@ data ConfigMonoid = -- ^ See 'configCabalConfigOpts'. ,configMonoidExtraPath :: ![Path Abs Dir] -- ^ Additional paths to search for executables in - ,configMonoidSetupInfoLocations :: ![SetupInfoLocation] - -- ^ Additional setup info (inline or remote) to use for installing tools + ,configMonoidSetupInfoLocations :: ![String] + -- ^ URLs or paths to setup-info.yaml files, for finding tools. + -- If none present, the default setup-info is used. + ,configMonoidSetupInfoInline :: !SetupInfo + -- ^ Additional SetupInfo to use to find tools. ,configMonoidLocalProgramsBase :: !(First (Path Abs Dir)) -- ^ Override the default local programs dir, where e.g. GHC is installed. ,configMonoidPvpBounds :: !(First PvpBounds) @@ -947,8 +952,8 @@ parseConfigMonoidObject rootDir obj = do let configMonoidCabalConfigOpts = coerce (configMonoidCabalConfigOpts' :: Map CabalConfigKey [Text]) configMonoidExtraPath <- obj ..:? configMonoidExtraPathName ..!= [] - configMonoidSetupInfoLocations <- - maybeToList <$> jsonSubWarningsT (obj ..:? configMonoidSetupInfoLocationsName) + configMonoidSetupInfoLocations <- obj ..:? configMonoidSetupInfoLocationsName ..!= [] + configMonoidSetupInfoInline <- jsonSubWarningsT (obj ..:? configMonoidSetupInfoInlineName) ..!= mempty configMonoidLocalProgramsBase <- First <$> obj ..:? configMonoidLocalProgramsBaseName configMonoidPvpBounds <- First <$> obj ..:? configMonoidPvpBoundsName configMonoidModifyCodePage <- FirstTrue <$> obj ..:? configMonoidModifyCodePageName @@ -1080,7 +1085,10 @@ configMonoidExtraPathName :: Text configMonoidExtraPathName = "extra-path" configMonoidSetupInfoLocationsName :: Text -configMonoidSetupInfoLocationsName = "setup-info" +configMonoidSetupInfoLocationsName = "setup-info-locations" + +configMonoidSetupInfoInlineName :: Text +configMonoidSetupInfoInlineName = "setup-info" configMonoidLocalProgramsBaseName :: Text configMonoidLocalProgramsBaseName = "local-programs-path" @@ -1710,22 +1718,6 @@ instance Monoid SetupInfo where } mappend = (<>) --- | Remote or inline 'SetupInfo' -data SetupInfoLocation - = SetupInfoFileOrURL String - | SetupInfoInline SetupInfo - deriving (Show) - -instance FromJSON (WithJSONWarnings SetupInfoLocation) where - parseJSON v = - (noJSONWarnings <$> - withText "SetupInfoFileOrURL" (pure . SetupInfoFileOrURL . T.unpack) v) <|> - inline - where - inline = do - WithJSONWarnings si w <- parseJSON v - return $ WithJSONWarnings (SetupInfoInline si) w - -- | How PVP bounds should be added to .cabal files data PvpBoundsType = PvpBoundsNone From 282f376b4412fa7b473ea427db4d3753c311cf66 Mon Sep 17 00:00:00 2001 From: NightRa Date: Fri, 13 Sep 2019 02:05:28 +0300 Subject: [PATCH 03/14] [setup-info]: Clear up docs in Config --- src/Stack/Types/Config.hs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/Stack/Types/Config.hs b/src/Stack/Types/Config.hs index 159001ff9c..7b40ba1b93 100644 --- a/src/Stack/Types/Config.hs +++ b/src/Stack/Types/Config.hs @@ -333,7 +333,7 @@ data Config = ,configCabalConfigOpts :: !(Map CabalConfigKey [Text]) -- ^ Additional options to be passed to ./Setup.hs configure ,configSetupInfoLocations :: ![String] - -- ^ URLs or paths to setup-info.yaml files, for finding tools. + -- ^ URLs or paths to stack-setup.yaml files, for finding tools. -- If none present, the default setup-info is used. ,configSetupInfoInline :: !SetupInfo -- ^ Additional SetupInfo to use to find tools. @@ -823,10 +823,9 @@ data ConfigMonoid = ,configMonoidExtraPath :: ![Path Abs Dir] -- ^ Additional paths to search for executables in ,configMonoidSetupInfoLocations :: ![String] - -- ^ URLs or paths to setup-info.yaml files, for finding tools. - -- If none present, the default setup-info is used. + -- ^ See 'configSetupInfoLocations' ,configMonoidSetupInfoInline :: !SetupInfo - -- ^ Additional SetupInfo to use to find tools. + -- ^ See 'configSetupInfoInline' ,configMonoidLocalProgramsBase :: !(First (Path Abs Dir)) -- ^ Override the default local programs dir, where e.g. GHC is installed. ,configMonoidPvpBounds :: !(First PvpBounds) From 44c197306a726f53817d36b243d87f338579a8a9 Mon Sep 17 00:00:00 2001 From: NightRa Date: Fri, 13 Sep 2019 02:06:01 +0300 Subject: [PATCH 04/14] [setup-info]: Fix precedence of SetupInfo --- src/Stack/Types/Config.hs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Stack/Types/Config.hs b/src/Stack/Types/Config.hs index 7b40ba1b93..bcc30c977b 100644 --- a/src/Stack/Types/Config.hs +++ b/src/Stack/Types/Config.hs @@ -1694,15 +1694,15 @@ instance FromJSON (WithJSONWarnings SetupInfo) where return SetupInfo {..} -- | For @siGHCs@ and @siGHCJSs@ fields maps are deeply merged. --- For all fields the values from the last @SetupInfo@ win. +-- For all fields the values from the first @SetupInfo@ win. instance Semigroup SetupInfo where l <> r = SetupInfo - { siSevenzExe = siSevenzExe r <|> siSevenzExe l - , siSevenzDll = siSevenzDll r <|> siSevenzDll l - , siMsys2 = siMsys2 r <> siMsys2 l - , siGHCs = Map.unionWith (<>) (siGHCs r) (siGHCs l) - , siGHCJSs = Map.unionWith (<>) (siGHCJSs r) (siGHCJSs l) + { siSevenzExe = siSevenzExe l <|> siSevenzExe r + , siSevenzDll = siSevenzDll l <|> siSevenzDll r + , siMsys2 = siMsys2 l <> siMsys2 r + , siGHCs = Map.unionWith (<>) (siGHCs l) (siGHCs r) + , siGHCJSs = Map.unionWith (<>) (siGHCJSs l) (siGHCJSs r) , siStack = Map.unionWith (<>) (siStack l) (siStack r) } instance Monoid SetupInfo where From 2de1549d74e4aaf7ce07ff3c300be3991045532a Mon Sep 17 00:00:00 2001 From: NightRa Date: Fri, 13 Sep 2019 13:03:23 +0300 Subject: [PATCH 05/14] [setup-info]: Document the recent changes to the yaml configuration --- doc/install_and_upgrade.md | 5 ++- doc/yaml_configuration.md | 63 ++++++++++++++++++++++++++++---------- 2 files changed, 49 insertions(+), 19 deletions(-) diff --git a/doc/install_and_upgrade.md b/doc/install_and_upgrade.md index 23c3dea5a7..1fda7f7671 100644 --- a/doc/install_and_upgrade.md +++ b/doc/install_and_upgrade.md @@ -319,11 +319,10 @@ If you're attempting to install stack from within China: ``` ###ADD THIS IF YOU LIVE IN CHINA -setup-info: "http://mirrors.tuna.tsinghua.edu.cn/stackage/stack-setup.yaml" +setup-info-locations: +- "http://mirrors.tuna.tsinghua.edu.cn/stackage/stack-setup.yaml" urls: latest-snapshot: http://mirrors.tuna.tsinghua.edu.cn/stackage/snapshots.json - lts-build-plans: http://mirrors.tuna.tsinghua.edu.cn/stackage/lts-haskell/ - nightly-build-plans: http://mirrors.tuna.tsinghua.edu.cn/stackage/stackage-nightly/ package-indices: - name: Tsinghua download-prefix: http://mirrors.tuna.tsinghua.edu.cn/hackage/package/ diff --git a/doc/yaml_configuration.md b/doc/yaml_configuration.md index 51e63b9385..fcedc0c91a 100644 --- a/doc/yaml_configuration.md +++ b/doc/yaml_configuration.md @@ -617,8 +617,9 @@ Specify a variant binary distribution of GHC to use. Known values: * `integersimple`: Use a GHC bindist that uses [integer-simple instead of GMP](https://ghc.haskell.org/trac/ghc/wiki/ReplacingGMPNotes) * any other value: Use a custom GHC bindist. You should specify - [setup-info](#setup-info) so `stack setup` knows where to download it, or - pass the `stack setup --ghc-bindist` argument on the command-line + [setup-info](#setup-info) or [setup-info-locations](#setup-info-locations) + so `stack setup` knows where to download it, + or pass the `stack setup --ghc-bindist` argument on the command-line This option is incompatible with `system-ghc: true`. @@ -630,13 +631,54 @@ Specify a specialized architecture bindist to use. Normally this is determined automatically, but you can override the autodetected value here. Possible arguments include `standard`, `gmp4`, `tinfo6`, and `nopie`. +### setup-info-locations + +(Since 2.3) + +Possible usages of this config are: +1. Using `stack` offline or behind a firewall +2. Extending the tools known to `stack` such as cutting-edge versions of `ghc` or builds for custom linux distributions. + +The `setup-info` dictionary specifies locations for installation of Haskell-related tooling - it maps `(Tool, Platform, Version)` to the location where it can be obtained, such as `(GHC, Windows64, 8.6.5)` to the url hosting the `*.tar.xz` for GHC's installation. + +By default, it's obtained from [stack-setup-2.yaml](https://github.com/commercialhaskell/stackage-content/raw/master/stack/stack-setup-2.yaml). + +The `setup-info` dictionary is constructed in the following order: +1. `setup-info` yaml configuration - inline config +2. `--setup-info-yaml` command line arguments - urls or paths, multiple locations may be specified. +3. `setup-info-locations` yaml configuration - urls or paths + +The first location which specifies the location of a tool `(Tool, Platform, Version)` takes precedence, so one can extend the default tools with a fallback to the default `setup-info` location: + +```yaml +setup-info-locations: +- C:/stack-offline/my-stack-setup.yaml +- \\smbServer\stack\my-stack-setup.yaml +- http://stack-mirror.com/stack-setup.yaml +- https://github.com/commercialhaskell/stackage-content/raw/master/stack/stack-setup-2.yaml +``` + +The default `setup-info` location is included only if no locations in the `setup-info-locations` config or the `--setup-info-yaml` command line argument were specified. + +Thus the following will cause `stack setup` not to consult github for the `setup-info`: +```yaml +setup-info-locations: +- C:/stack-offline/my-stack-setup.yaml +``` + +```yaml +setup-info-locations: [] +``` + ### setup-info (Since 0.1.5) -Allows augmenting from where tools like GHC and msys2 (on Windows) are +Allows specifying from where tools like GHC and msys2 (on Windows) are downloaded. Most useful for specifying locations of custom GHC binary -distributions (for use with the [ghc-variant](#ghc-variant) option): +distributions (for use with the [ghc-variant](#ghc-variant) option). + +The format of this field is the same as in the default [stack-setup-2.yaml](https://github.com/commercialhaskell/stackage-content/raw/master/stack/stack-setup-2.yaml): ```yaml setup-info: @@ -646,18 +688,7 @@ setup-info: url: "https://example.com/ghc-7.10.2-i386-unknown-mingw32-foo.tar.xz" ``` -Or you can point to external setup-info: - -```yaml -setup-info: "https://example.com/my-stack-setup-info.yaml" -``` - -This may be either URL or (since 1.2.0) absolute file path. - -Note that this **adds** the specified setup info metadata to the default. -If you need to **replace** it, use the `stack --setup-info-yaml` command-line -argument instead. The default setup metadata is in -[stack-setup-2.yaml](https://github.com/commercialhaskell/stackage-content/raw/master/stack/stack-setup-2.yaml). +Note that specifying this config *does not* the default `stack-setup-2.yaml` from being consulted as a fallback. ### pvp-bounds From f45093421b2f441824fc1cc71ff6216b9c21c3c2 Mon Sep 17 00:00:00 2001 From: NightRa Date: Fri, 13 Sep 2019 13:29:06 +0300 Subject: [PATCH 06/14] [setup-info]: Add changes to CHANGELOG --- ChangeLog.md | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/ChangeLog.md b/ChangeLog.md index 4fe0c51837..f5a8af46a7 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -8,11 +8,21 @@ Release notes: Major changes: +* `setup-info-locations` yaml configuration now allows overwriting the default locations of `stack-setup-2.yaml`. + [#2983](https://github.com/commercialhaskell/stack/issues/2983) + [#2913](https://github.com/commercialhaskell/stack/issues/2913) + +* The `setup-info` configuration key now allows overwriting parts of the default `setup-info` + +* The `--setup-info-yaml` command line flag now may be used in all stack commands such as `stack build`, and not only in `stack setup` + +* The `--setup-info-yaml` may specify multiple locations for `stack-setup.yaml` files. Behavior changes: +* Remove the deprecated `--stack-setup-yaml` command line argument in favor of `--setup-info-yaml` + [#2647](https://github.com/commercialhaskell/stack/issues/2647) Other enhancements: - * Add `build-output-timestamps` flag in yaml. Setting it to true prefixes each build log output line with a timestamp. From d72dd6fff7cbc16ae7b027e70e9926bf94e5b153 Mon Sep 17 00:00:00 2001 From: NightRa Date: Fri, 13 Sep 2019 14:22:33 +0300 Subject: [PATCH 07/14] [setup-info]: Add PR link to changelog --- ChangeLog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/ChangeLog.md b/ChangeLog.md index f5a8af46a7..113ea49170 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -9,6 +9,7 @@ Release notes: Major changes: * `setup-info-locations` yaml configuration now allows overwriting the default locations of `stack-setup-2.yaml`. + [#5031](https://github.com/commercialhaskell/stack/pull/5031) [#2983](https://github.com/commercialhaskell/stack/issues/2983) [#2913](https://github.com/commercialhaskell/stack/issues/2913) From f9bb0c0c00d03b39012fda3ab359eb0258a32d7b Mon Sep 17 00:00:00 2001 From: NightRa Date: Fri, 13 Sep 2019 14:27:18 +0300 Subject: [PATCH 08/14] [setup-info]: Remove deprecated CmdArg -- stack-setup-yaml --- src/Stack/Options/ConfigParser.hs | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/src/Stack/Options/ConfigParser.hs b/src/Stack/Options/ConfigParser.hs index d1b2f26ad5..801d2b67f7 100644 --- a/src/Stack/Options/ConfigParser.hs +++ b/src/Stack/Options/ConfigParser.hs @@ -130,17 +130,10 @@ configOptsParser currentDir hide0 = <> hide )) <*> many ( - ( strOption - ( long "stack-setup-yaml" - <> help "DEPRECATED: Use 'setup-info-yaml' instead" - <> metavar "URL" - <> hidden ) - ) <|> - ( strOption + strOption ( long "setup-info-yaml" <> help "Alternate URL or absolute path for stack dependencies" - <> metavar "URL" ) - )) + <> metavar "URL" )) <*> firstBoolFlagsTrue "modify-code-page" "setting the codepage to support UTF-8 (Windows only)" From de17a60aecd33ca8c2c9e7884947ffc2e654b4a7 Mon Sep 17 00:00:00 2001 From: NightRa Date: Fri, 22 Nov 2019 10:47:32 +0200 Subject: [PATCH 09/14] [setup-info]: Fix typo in documentation --- doc/yaml_configuration.md | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/doc/yaml_configuration.md b/doc/yaml_configuration.md index fcedc0c91a..8f29f59c43 100644 --- a/doc/yaml_configuration.md +++ b/doc/yaml_configuration.md @@ -674,7 +674,7 @@ setup-info-locations: [] (Since 0.1.5) -Allows specifying from where tools like GHC and msys2 (on Windows) are +Allows augmenting from where tools like GHC and msys2 (on Windows) are downloaded. Most useful for specifying locations of custom GHC binary distributions (for use with the [ghc-variant](#ghc-variant) option). @@ -688,7 +688,14 @@ setup-info: url: "https://example.com/ghc-7.10.2-i386-unknown-mingw32-foo.tar.xz" ``` -Note that specifying this config *does not* the default `stack-setup-2.yaml` from being consulted as a fallback. +This configuration **adds** the specified setup info metadata to the default; +Specifying this config **does not** prevent the default `stack-setup-2.yaml` from being consulted as a fallback. + +If you need to **replace** the default setup-info, add the following: + +```yaml +setup-info-locations: [] +``` ### pvp-bounds From e7561d30a67014780f3ee683135a85080003e99d Mon Sep 17 00:00:00 2001 From: NightRa Date: Fri, 22 Nov 2019 17:13:45 +0200 Subject: [PATCH 10/14] [setup-info]: Allow local setup-info yaml & ghc location --- src/Stack/Setup.hs | 49 +++++++++++++++++++++++-------------------- src/Stack/SetupCmd.hs | 2 +- src/main/Main.hs | 4 ++-- 3 files changed, 29 insertions(+), 26 deletions(-) diff --git a/src/Stack/Setup.hs b/src/Stack/Setup.hs index c5f1c13d56..76c4e01917 100644 --- a/src/Stack/Setup.hs +++ b/src/Stack/Setup.hs @@ -447,7 +447,7 @@ addIncludeLib (ExtraDirs _bins includes libs) config = config -- | Ensure both the compiler and the msys toolchain are installed and -- provide the PATHs to add if necessary ensureCompilerAndMsys - :: (HasConfig env, HasGHCVariant env) + :: (HasBuildConfig env, HasGHCVariant env) => SetupOpts -> RIO env (CompilerPaths, ExtraDirs) ensureCompilerAndMsys sopts = do @@ -516,7 +516,7 @@ warnUnsupportedCompilerCabal cp didWarn = do -- | Ensure that the msys toolchain is installed if necessary and -- provide the PATHs to add if necessary ensureMsys - :: HasConfig env + :: HasBuildConfig env => SetupOpts -> Memoized SetupInfo -> RIO env (Maybe Tool) @@ -546,7 +546,7 @@ ensureMsys sopts getSetupInfo' = do _ -> return Nothing installGhcBindist - :: HasConfig env + :: HasBuildConfig env => SetupOpts -> Memoized SetupInfo -> [Tool] @@ -607,7 +607,7 @@ installGhcBindist sopts getSetupInfo' installed = do -- | Ensure compiler (ghc or ghcjs) is installed, without worrying about msys ensureCompiler - :: forall env. (HasConfig env, HasGHCVariant env) + :: forall env. (HasBuildConfig env, HasGHCVariant env) => SetupOpts -> Memoized SetupInfo -> RIO env (CompilerPaths, ExtraDirs) @@ -649,7 +649,7 @@ ensureCompiler sopts getSetupInfo' = do pure (cp, paths) ensureSandboxedCompiler - :: HasConfig env + :: HasBuildConfig env => SetupOpts -> Memoized SetupInfo -> RIO env (CompilerPaths, ExtraDirs) @@ -823,7 +823,7 @@ pathsFromCompiler wc compilerBuild isSandboxed compiler = withCache $ handleAny buildGhcFromSource :: forall env. ( HasTerm env , HasProcessContext env - , HasConfig env + , HasBuildConfig env ) => Memoized SetupInfo -> [Tool] -> CompilerRepository -> Text -> Text -> RIO env (Tool, CompilerBuild) buildGhcFromSource getSetupInfo' installed (CompilerRepository url) commitId flavour = do @@ -1104,7 +1104,7 @@ getInstalledTool installed name goodVersion = else Nothing goodPackage _ = Nothing -downloadAndInstallTool :: HasTerm env +downloadAndInstallTool :: (HasTerm env, HasBuildConfig env) => Path Abs Dir -> DownloadInfo -> Tool @@ -1123,7 +1123,7 @@ downloadAndInstallTool programsDir downloadInfo tool installer = do liftIO $ ignoringAbsence (removeDirRecur tempDir) return tool -downloadAndInstallCompiler :: (HasConfig env, HasGHCVariant env) +downloadAndInstallCompiler :: (HasBuildConfig env, HasGHCVariant env) => CompilerBuild -> SetupInfo -> WantedCompiler @@ -1195,7 +1195,7 @@ getWantedCompilerInfo key versionCheck wanted toCV pairs_ = -- | Download and install the first available compiler build. downloadAndInstallPossibleCompilers - :: (HasGHCVariant env, HasConfig env) + :: (HasGHCVariant env, HasBuildConfig env) => [CompilerBuild] -> SetupInfo -> WantedCompiler @@ -1263,7 +1263,7 @@ getOSKey platform = Platform arch os -> throwM $ UnsupportedSetupCombo os arch downloadFromInfo - :: HasTerm env + :: (HasTerm env, HasBuildConfig env) => Path Abs Dir -> DownloadInfo -> Tool -> RIO env (Path Abs File, ArchiveType) downloadFromInfo programsDir downloadInfo tool = do at <- @@ -1281,21 +1281,14 @@ downloadFromInfo programsDir downloadInfo tool = do chattyDownload (T.pack (toolString tool)) downloadInfo path return path (parseAbsFile -> Just path) -> do - let DownloadInfo{downloadInfoContentLength=contentLength, downloadInfoSha1=sha1, - downloadInfoSha256=sha256} = - downloadInfo - when (isJust contentLength) $ - logWarn ("`content-length` in not checked \n" <> - "and should not be specified when `url` is a file path") - when (isJust sha1) $ - logWarn ("`sha1` is not checked and \n" <> - "should not be specified when `url` is a file path") - when (isJust sha256) $ - logWarn ("`sha256` is not checked and \n" <> - "should not be specified when `url` is a file path") + warnOnIgnoredChecks return path + (parseRelFile -> Just path) -> do + warnOnIgnoredChecks + root <- view projectRootL + return (root path) _ -> - throwString $ "Error: `url` must be either an HTTP URL or absolute file path: " ++ url + throwString $ "Error: `url` must be either an HTTP URL or a file path: " ++ url return (path, at) where url = T.unpack $ downloadInfoUrl downloadInfo @@ -1306,6 +1299,16 @@ downloadFromInfo programsDir downloadInfo tool = do | otherwise = "" where (fp', ext) = FP.splitExtension fp + warnOnIgnoredChecks = do + let DownloadInfo{downloadInfoContentLength=contentLength, downloadInfoSha1=sha1, + downloadInfoSha256=sha256} = downloadInfo + when (isJust contentLength) $ + logWarn "`content-length` is not checked and should not be specified when `url` is a file path" + when (isJust sha1) $ + logWarn "`sha1` is not checked and should not be specified when `url` is a file path" + when (isJust sha256) $ + logWarn "`sha256` is not checked and should not be specified when `url` is a file path" + data ArchiveType = TarBz2 diff --git a/src/Stack/SetupCmd.hs b/src/Stack/SetupCmd.hs index a166b6bf10..d4ad51b45d 100644 --- a/src/Stack/SetupCmd.hs +++ b/src/Stack/SetupCmd.hs @@ -65,7 +65,7 @@ setupParser = SetupCmdOpts Right x -> return x setup - :: (HasConfig env, HasGHCVariant env) + :: (HasBuildConfig env, HasGHCVariant env) => SetupCmdOpts -> WantedCompiler -> VersionCheck diff --git a/src/main/Main.hs b/src/main/Main.hs index 7c302b0baf..6c707bcb48 100644 --- a/src/main/Main.hs +++ b/src/main/Main.hs @@ -539,11 +539,11 @@ interpreterHandler currentDir args f = do return (a,(b,mempty)) setupCmd :: SetupCmdOpts -> RIO Runner () -setupCmd sco@SetupCmdOpts{..} = withConfig YesReexec $ do +setupCmd sco@SetupCmdOpts{..} = withConfig YesReexec $ withBuildConfig $ do (wantedCompiler, compilerCheck, mstack) <- case scoCompilerVersion of Just v -> return (v, MatchMinor, Nothing) - Nothing -> withBuildConfig $ (,,) + Nothing -> (,,) <$> view wantedCompilerVersionL <*> view (configL.to configCompilerCheck) <*> (Just <$> view stackYamlL) From 36be41a6e89a2d5b4f265c52c171878856eb628e Mon Sep 17 00:00:00 2001 From: NightRa Date: Sat, 23 Nov 2019 14:16:32 +0200 Subject: [PATCH 11/14] [setup-info]: Allow relative paths to ghc & 7z, and allow local 7z binaries --- .gitignore | 2 +- src/Stack/Setup.hs | 80 ++++++++++++++++++++++++++-------------------- 2 files changed, 46 insertions(+), 36 deletions(-) diff --git a/.gitignore b/.gitignore index 435ea3258a..4ed120413f 100644 --- a/.gitignore +++ b/.gitignore @@ -9,7 +9,7 @@ .stack-root/ /.cabal-sandbox/ TAGS -Setup +/Setup/ cabal-dev/ cabal.sandbox.config dist/ diff --git a/src/Stack/Setup.hs b/src/Stack/Setup.hs index 76c4e01917..df2314b7b7 100644 --- a/src/Stack/Setup.hs +++ b/src/Stack/Setup.hs @@ -1262,34 +1262,53 @@ getOSKey platform = Platform AArch64 Cabal.Linux -> return "linux-aarch64" Platform arch os -> throwM $ UnsupportedSetupCombo os arch +downloadOrUseLocal + :: (HasTerm env, HasBuildConfig env) + => Text -> DownloadInfo -> Path Abs File -> RIO env (Path Abs File) +downloadOrUseLocal downloadLabel downloadInfo destination = + case url of + (parseUrlThrow -> Just _) -> do + ensureDir (parent destination) + chattyDownload downloadLabel downloadInfo destination + return destination + (parseAbsFile -> Just path) -> do + warnOnIgnoredChecks + return path + (parseRelFile -> Just path) -> do + warnOnIgnoredChecks + root <- view projectRootL + return (root path) + _ -> + throwString $ "Error: `url` must be either an HTTP URL or a file path: " ++ url + where + url = T.unpack $ downloadInfoUrl downloadInfo + warnOnIgnoredChecks = do + let DownloadInfo{downloadInfoContentLength=contentLength, downloadInfoSha1=sha1, + downloadInfoSha256=sha256} = downloadInfo + when (isJust contentLength) $ + logWarn "`content-length` is not checked and should not be specified when `url` is a file path" + when (isJust sha1) $ + logWarn "`sha1` is not checked and should not be specified when `url` is a file path" + when (isJust sha256) $ + logWarn "`sha256` is not checked and should not be specified when `url` is a file path" + downloadFromInfo :: (HasTerm env, HasBuildConfig env) => Path Abs Dir -> DownloadInfo -> Tool -> RIO env (Path Abs File, ArchiveType) downloadFromInfo programsDir downloadInfo tool = do - at <- + archiveType <- case extension of ".tar.xz" -> return TarXz ".tar.bz2" -> return TarBz2 ".tar.gz" -> return TarGz ".7z.exe" -> return SevenZ _ -> throwString $ "Error: Unknown extension for url: " ++ url + relativeFile <- parseRelFile $ toolString tool ++ extension - path <- case url of - (parseUrlThrow -> Just _) -> do - let path = programsDir relativeFile - ensureDir programsDir - chattyDownload (T.pack (toolString tool)) downloadInfo path - return path - (parseAbsFile -> Just path) -> do - warnOnIgnoredChecks - return path - (parseRelFile -> Just path) -> do - warnOnIgnoredChecks - root <- view projectRootL - return (root path) - _ -> - throwString $ "Error: `url` must be either an HTTP URL or a file path: " ++ url - return (path, at) + let destinationPath = programsDir relativeFile + localPath <- downloadOrUseLocal (T.pack (toolString tool)) downloadInfo destinationPath + return (localPath, archiveType) + where url = T.unpack $ downloadInfoUrl downloadInfo extension = loop url @@ -1299,15 +1318,6 @@ downloadFromInfo programsDir downloadInfo tool = do | otherwise = "" where (fp', ext) = FP.splitExtension fp - warnOnIgnoredChecks = do - let DownloadInfo{downloadInfoContentLength=contentLength, downloadInfoSha1=sha1, - downloadInfoSha256=sha256} = downloadInfo - when (isJust contentLength) $ - logWarn "`content-length` is not checked and should not be specified when `url` is a file path" - when (isJust sha1) $ - logWarn "`sha1` is not checked and should not be specified when `url` is a file path" - when (isJust sha256) $ - logWarn "`sha256` is not checked and should not be specified when `url` is a file path" data ArchiveType @@ -1437,7 +1447,7 @@ instance Alternative (CheckDependency env) where Left _ -> y Right x' -> return $ Right x' -installGHCWindows :: HasConfig env +installGHCWindows :: HasBuildConfig env => Maybe Version -> SetupInfo -> Path Abs File @@ -1450,7 +1460,7 @@ installGHCWindows mversion si archiveFile archiveType _tempDir destDir = do withUnpackedTarball7z "GHC" si archiveFile archiveType tarComponent destDir logInfo $ "GHC installed to " <> fromString (toFilePath destDir) -installMsys2Windows :: HasConfig env +installMsys2Windows :: HasBuildConfig env => Text -- ^ OS Key -> SetupInfo -> Path Abs File @@ -1491,7 +1501,7 @@ installMsys2Windows osKey si archiveFile archiveType _tempDir destDir = do -- | Unpack a compressed tarball using 7zip. Expects a single directory in -- the unpacked results, which is renamed to the destination directory. -withUnpackedTarball7z :: HasConfig env +withUnpackedTarball7z :: HasBuildConfig env => String -- ^ Name of tool, used in error messages -> SetupInfo -> Path Abs File -- ^ Path to archive file @@ -1532,20 +1542,20 @@ expectSingleUnpackedDir archiveFile destDir = do -- | Download 7z as necessary, and get a function for unpacking things. -- -- Returned function takes an unpack directory and archive. -setup7z :: (HasConfig env, MonadIO m) +setup7z :: (HasBuildConfig env, MonadIO m) => SetupInfo -> RIO env (Path Abs Dir -> Path Abs File -> m ()) setup7z si = do dir <- view $ configL.to configLocalPrograms ensureDir dir - let exe = dir relFile7zexe - dll = dir relFile7zdll + let exeDestination = dir relFile7zexe + dllDestination = dir relFile7zdll case (siSevenzDll si, siSevenzExe si) of (Just sevenzDll, Just sevenzExe) -> do - chattyDownload "7z.dll" sevenzDll dll - chattyDownload "7z.exe" sevenzExe exe + _ <- downloadOrUseLocal "7z.dll" sevenzDll dllDestination + exePath <- downloadOrUseLocal "7z.exe" sevenzExe exeDestination withRunInIO $ \run -> return $ \outdir archive -> liftIO $ run $ do - let cmd = toFilePath exe + let cmd = toFilePath exePath args = [ "x" , "-o" ++ toFilePath outdir From 1ff7514378f8be234ebd70466beec175636b8e6c Mon Sep 17 00:00:00 2001 From: NightRa Date: Sat, 23 Nov 2019 14:31:49 +0200 Subject: [PATCH 12/14] [setup-info]: Document relative tool paths behavior & usage --- doc/yaml_configuration.md | 39 ++++++++++++++++++++++++++++++- src/Stack/Options/ConfigParser.hs | 2 +- 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/doc/yaml_configuration.md b/doc/yaml_configuration.md index 8f29f59c43..f596268342 100644 --- a/doc/yaml_configuration.md +++ b/doc/yaml_configuration.md @@ -653,7 +653,8 @@ The first location which specifies the location of a tool `(Tool, Platform, Vers ```yaml setup-info-locations: - C:/stack-offline/my-stack-setup.yaml -- \\smbServer\stack\my-stack-setup.yaml +- relative/inside/my/project/setup-info.yaml +- \\smbShare\stack\my-stack-setup.yaml - http://stack-mirror.com/stack-setup.yaml - https://github.com/commercialhaskell/stackage-content/raw/master/stack/stack-setup-2.yaml ``` @@ -670,6 +671,42 @@ setup-info-locations: setup-info-locations: [] ``` +Relative paths are resolved relative to the `stack.yaml` file - either in the local project or the global `stack.yaml` in the stack directory. + +Relative paths may also be used inside paths to tool installs - such as for ghc or 7z, which allows vendoring the tools inside a monorepo. +For example: + +Directory structure: +``` +- src/ +- installs/ + - my-stack-setup.yaml + - 7z.exe + - 7z.dll + - ghc-8.2.2.tar.xz +- stack.yaml +``` + +In the project's `stack.yaml`: +```yaml +setup-info-locations: +- installs/my-stack-setup.yaml +``` + +In `installs/my-stack-setup.yaml`: +```yaml +sevenzexe-info: + url: "installs/7z.exe" + +sevenzdll-info: + url: "installs/7z.dll" + +ghc: + windows64: + 8.2.2: + url: "installs/ghc-8.2.2.tar.xz" +``` + ### setup-info (Since 0.1.5) diff --git a/src/Stack/Options/ConfigParser.hs b/src/Stack/Options/ConfigParser.hs index 801d2b67f7..e1874c8787 100644 --- a/src/Stack/Options/ConfigParser.hs +++ b/src/Stack/Options/ConfigParser.hs @@ -132,7 +132,7 @@ configOptsParser currentDir hide0 = <*> many ( strOption ( long "setup-info-yaml" - <> help "Alternate URL or absolute path for stack dependencies" + <> help "Alternate URL or relative / absolute path for stack dependencies" <> metavar "URL" )) <*> firstBoolFlagsTrue "modify-code-page" From d4dfa68f424a829299d4513b17f741f83c27e682 Mon Sep 17 00:00:00 2001 From: NightRa Date: Sat, 23 Nov 2019 14:39:08 +0200 Subject: [PATCH 13/14] [setup-info]: Update Changelog --- ChangeLog.md | 3 +++ doc/yaml_configuration.md | 2 ++ 2 files changed, 5 insertions(+) diff --git a/ChangeLog.md b/ChangeLog.md index 113ea49170..3a5ee352de 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -37,6 +37,9 @@ Other enhancements: * Remove warning for using Stack with GHC 8.8 and Cabal 3.0. +* Allow relative paths in `--setup-info-yaml` and tool paths + [#3394](https://github.com/commercialhaskell/stack/issues/3394) + Bug fixes: * Upgrade `pantry`: module mapping insertions into the database are now atomic. diff --git a/doc/yaml_configuration.md b/doc/yaml_configuration.md index f596268342..2461e48c5f 100644 --- a/doc/yaml_configuration.md +++ b/doc/yaml_configuration.md @@ -707,6 +707,8 @@ ghc: url: "installs/ghc-8.2.2.tar.xz" ``` +Executing `stack setup` outside of a project will use the global `stack.yaml` to determine the relevant `setup-info` information and locations. + ### setup-info (Since 0.1.5) From e6e34089d1fa3c7143f702ae38c5ea92f49bd198 Mon Sep 17 00:00:00 2001 From: NightRa Date: Sat, 23 Nov 2019 21:38:25 +0200 Subject: [PATCH 14/14] [setup-info]: Remove comment about unsupported global setup-info config --- doc/yaml_configuration.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/doc/yaml_configuration.md b/doc/yaml_configuration.md index 2461e48c5f..f596268342 100644 --- a/doc/yaml_configuration.md +++ b/doc/yaml_configuration.md @@ -707,8 +707,6 @@ ghc: url: "installs/ghc-8.2.2.tar.xz" ``` -Executing `stack setup` outside of a project will use the global `stack.yaml` to determine the relevant `setup-info` information and locations. - ### setup-info (Since 0.1.5)