From 9731235285e20aee5dcf470bba3d9a0478480e07 Mon Sep 17 00:00:00 2001 From: Ruud van Asseldonk Date: Tue, 8 Nov 2016 13:04:53 +0100 Subject: [PATCH 1/7] Do not special-case programs directory on Windows Just use $STACK_ROOT/programs, like on other platforms. This enables the directory to be configurable by setting $STACK_ROOT, and it removes the hard-coded path. When downloading GHC, the archive is downloaded to this directory as well before extraction. (This was the case anyway.) This is perhaps less idiomatic, but $STACK_ROOT exists on Windows regardless, so it seems better to keep everything in one place. Fixes #1644. --- src/Stack/Config.hs | 27 +++------------------------ 1 file changed, 3 insertions(+), 24 deletions(-) diff --git a/src/Stack/Config.hs b/src/Stack/Config.hs index b94ec17873..f6c0544751 100644 --- a/src/Stack/Config.hs +++ b/src/Stack/Config.hs @@ -65,7 +65,7 @@ import Data.Monoid.Extra import qualified Data.Text as T import Data.Text.Encoding (encodeUtf8, decodeUtf8) import qualified Data.Yaml as Yaml -import Distribution.System (OS (..), Platform (..), buildPlatform) +import Distribution.System (Platform (..), buildPlatform) import qualified Distribution.Text import Distribution.Version (simplifyVersionRange) import GHC.Conc (getNumProcessors) @@ -295,15 +295,8 @@ configFromConfigMonoid configStackRoot configUserConfigPath mresolver mproject C let configEnvOverride _ = return origEnv platformOnlyDir <- runReaderT platformOnlyRelDir (configPlatform,configPlatformVariant) - configLocalProgramsBase <- - case configPlatform of - Platform _ Windows -> do - progsDir <- getWindowsProgsDir configStackRoot origEnv - return $ progsDir $(mkRelDir stackProgName) - _ -> - return $ - configStackRoot $(mkRelDir "programs") - let configLocalPrograms = configLocalProgramsBase platformOnlyDir + let configLocalProgramsBase = configStackRoot $(mkRelDir "programs") + configLocalPrograms = configLocalProgramsBase platformOnlyDir configLocalBin <- case getFirst configMonoidLocalBinPath of @@ -352,20 +345,6 @@ configFromConfigMonoid configStackRoot configUserConfigPath mresolver mproject C return Config {..} --- | Get the directory on Windows where we should install extra programs. For --- more information, see discussion at: --- https://github.com/fpco/minghc/issues/43#issuecomment-99737383 -getWindowsProgsDir :: MonadThrow m - => Path Abs Dir - -> EnvOverride - -> m (Path Abs Dir) -getWindowsProgsDir stackRoot m = - case Map.lookup "LOCALAPPDATA" $ unEnvOverride m of - Just t -> do - lad <- parseAbsDir $ T.unpack t - return $ lad $(mkRelDir "Programs") - Nothing -> return $ stackRoot $(mkRelDir "Programs") - -- | An environment with a subset of BuildConfig used for setup. data MiniConfig = MiniConfig GHCVariant Config instance HasConfig MiniConfig where From 1ee35c99f44478f7fa62975861e74bb33901e371 Mon Sep 17 00:00:00 2001 From: Ruud van Asseldonk Date: Tue, 8 Nov 2016 13:13:30 +0100 Subject: [PATCH 2/7] Update changelog with Windows stack setup change --- ChangeLog.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ChangeLog.md b/ChangeLog.md index ed0adfed0e..160cd3584d 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -32,6 +32,10 @@ Behavior changes: * If a remote package is specified (such as a Git repo) without an explicit `extra-dep` setting, a warning is given to the user to provide one explicitly. +* On Windows, `stack setup` will now download and extract additional programs + such as GHC to `$STACK_ROOT\programs`, like on other platforms. You may need + to remove programs in `$LOCALAPPDATA\Programs\stack` manually. + [#1644](https://github.com/commercialhaskell/stack/issues/1644). Other enhancements: From 750ad04b992b5df305bf031265d68c8d7e97f095 Mon Sep 17 00:00:00 2001 From: Ruud van Asseldonk Date: Tue, 8 Nov 2016 13:22:52 +0100 Subject: [PATCH 3/7] Update outdated FAQ entry on temp dirs As far as I can git grep, Stack does not use TMP or TEMP or TEMPDIR any more. As of #996, stack setup does not download to the system temp directory any more. --- doc/faq.md | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/doc/faq.md b/doc/faq.md index f82aba3623..006d799c66 100644 --- a/doc/faq.md +++ b/doc/faq.md @@ -324,22 +324,18 @@ Cf. issue [#425](https://github.com/commercialhaskell/stack/issues/425). ## Can I change stack's default temporary directory? -Stack makes use of a temporary directory for some commands (/tmp by default on -linux). If there is not enough free space in this directory, stack may fail -(see issue [#429](https://github.com/commercialhaskell/stack/issues/429) ). For -instance `stack setup` with a GHC installation requires roughly 1GB free. +Stack downloads and extracts files to `$STACK_ROOT`, which defaults to +`~/.stack`. If there is not enough free space in this directory, Stack may fail. +For instance, `stack setup` with a GHC installation requires roughly 1GB free. +If this is an issue, you can change `$STACK_ROOT` to be on a file system with +more free space. -A custom temporary directory can be forced: - -* on Linux by setting the environment variable TMPDIR (eg `$ TMPDIR=path-to-tmp stack setup`) -* on Windows by setting one of the environment variable (given in priority order), TMP, TEMP, USERPROFILE - -If you use Stack with Nix integration, be aware that Nix _also_ uses that TMPDIR +If you use Stack with Nix integration, be aware that Nix uses a `TMPDIR` variable, and if it is not set Nix sets it to some subdirectory of `/run`, which -on most Linuxes is a Ramdir. Nix will run the builds in TMPDIR, therefore if you -don't have enough RAM you will get errors about disk space. If this happens to -you, please _manually_ set TMPDIR before launching Stack to some directory on the -disk. +on most Linuxes is a Ramdir. Nix will run the builds in `TMPDIR`, therefore if +you don't have enough RAM you will get errors about disk space. If this happens +to you, please _manually_ set `TMPDIR` before launching Stack to some directory +on the disk. ## Why doesn't stack rebuild my project when I specify `--ghc-options` on the command line? From 49da106492cba36055bf4db5cce4c4167c9c2535 Mon Sep 17 00:00:00 2001 From: Ruud van Asseldonk Date: Sat, 26 Nov 2016 15:25:51 +0100 Subject: [PATCH 4/7] Restore LOCALAPPDATA progs dir on Windows This is still a slightly different from the old behavior: the default location in STACK_ROOT is used when the environment variable cannot be read (which should never be the case anyway). The only difference is that in that case the "programs" directory inside STACK_ROOT is not capitalized. --- src/Stack/Config.hs | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/src/Stack/Config.hs b/src/Stack/Config.hs index f6c0544751..c38df572a7 100644 --- a/src/Stack/Config.hs +++ b/src/Stack/Config.hs @@ -65,7 +65,7 @@ import Data.Monoid.Extra import qualified Data.Text as T import Data.Text.Encoding (encodeUtf8, decodeUtf8) import qualified Data.Yaml as Yaml -import Distribution.System (Platform (..), buildPlatform) +import Distribution.System (OS (..), Platform (..), buildPlatform) import qualified Distribution.Text import Distribution.Version (simplifyVersionRange) import GHC.Conc (getNumProcessors) @@ -294,9 +294,9 @@ configFromConfigMonoid configStackRoot configUserConfigPath mresolver mproject C origEnv <- mkEnvOverride configPlatform pathsEnv let configEnvOverride _ = return origEnv - platformOnlyDir <- runReaderT platformOnlyRelDir (configPlatform,configPlatformVariant) - let configLocalProgramsBase = configStackRoot $(mkRelDir "programs") - configLocalPrograms = configLocalProgramsBase platformOnlyDir + configLocalProgramsBase <- getDefaultLocalProgramsBase configStackRoot configPlatform origEnv + platformOnlyDir <- runReaderT platformOnlyRelDir (configPlatform, configPlatformVariant) + let configLocalPrograms = configLocalProgramsBase platformOnlyDir configLocalBin <- case getFirst configMonoidLocalBinPath of @@ -345,6 +345,29 @@ configFromConfigMonoid configStackRoot configUserConfigPath mresolver mproject C return Config {..} +-- | Get the default location of the local programs directory. +getDefaultLocalProgramsBase :: MonadThrow m + => Path Abs Dir + -> Platform + -> EnvOverride + -> m (Path Abs Dir) +getDefaultLocalProgramsBase configStackRoot configPlatform override = + let + defaultBase = configStackRoot $(mkRelDir "programs") + in + case configPlatform of + -- For historical reasons, on Windows a subdirectory of LOCALAPPDATA is + -- used instead of a subdirectory of STACK_ROOT. Unifying the defaults would + -- mean that Windows users would manually have to move data from the old + -- location to the new one, which is undesirable. + Platform _ Windows -> + case Map.lookup "LOCALAPPDATA" $ unEnvOverride override of + Just t -> do + lad <- parseAbsDir $ T.unpack t + return $ lad $(mkRelDir "Programs") $(mkRelDir stackProgName) + Nothing -> return defaultBase + _ -> return defaultBase + -- | An environment with a subset of BuildConfig used for setup. data MiniConfig = MiniConfig GHCVariant Config instance HasConfig MiniConfig where From 98207fdb17dda10ec9e47d77c2e6aeccac566db9 Mon Sep 17 00:00:00 2001 From: Ruud van Asseldonk Date: Sat, 26 Nov 2016 21:02:14 +0100 Subject: [PATCH 5/7] Add local-programs-path config option This option overrides the localProgramsBase path. Ideally the base path would be removed entirely, but it is also used for Docker- related things. --- src/Stack/Config.hs | 4 +++- src/Stack/Types/Config.hs | 6 ++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/Stack/Config.hs b/src/Stack/Config.hs index c38df572a7..570f58d9c3 100644 --- a/src/Stack/Config.hs +++ b/src/Stack/Config.hs @@ -294,7 +294,9 @@ configFromConfigMonoid configStackRoot configUserConfigPath mresolver mproject C origEnv <- mkEnvOverride configPlatform pathsEnv let configEnvOverride _ = return origEnv - configLocalProgramsBase <- getDefaultLocalProgramsBase configStackRoot configPlatform origEnv + configLocalProgramsBase <- case getFirst configMonoidLocalProgramsBase of + Nothing -> getDefaultLocalProgramsBase configStackRoot configPlatform origEnv + Just path -> return path platformOnlyDir <- runReaderT platformOnlyRelDir (configPlatform, configPlatformVariant) let configLocalPrograms = configLocalProgramsBase platformOnlyDir diff --git a/src/Stack/Types/Config.hs b/src/Stack/Types/Config.hs index fc9c09b724..dafd508d94 100644 --- a/src/Stack/Types/Config.hs +++ b/src/Stack/Types/Config.hs @@ -783,6 +783,8 @@ data ConfigMonoid = -- ^ Additional paths to search for executables in ,configMonoidSetupInfoLocations :: ![SetupInfoLocation] -- ^ Additional setup info (inline or remote) to use for installing tools + ,configMonoidLocalProgramsBase :: !(First (Path Abs Dir)) + -- ^ Override the default local programs dir, where e.g. GHC is installed. ,configMonoidPvpBounds :: !(First PvpBounds) -- ^ See 'configPvpBounds' ,configMonoidModifyCodePage :: !(First Bool) @@ -860,6 +862,7 @@ parseConfigMonoidJSON obj = do configMonoidExtraPath <- obj ..:? configMonoidExtraPathName ..!= [] configMonoidSetupInfoLocations <- maybeToList <$> jsonSubWarningsT (obj ..:? configMonoidSetupInfoLocationsName) + configMonoidLocalProgramsBase <- First <$> obj ..:? configMonoidLocalProgramsBaseName configMonoidPvpBounds <- First <$> obj ..:? configMonoidPvpBoundsName configMonoidModifyCodePage <- First <$> obj ..:? configMonoidModifyCodePageName configMonoidExplicitSetupDeps <- @@ -974,6 +977,9 @@ configMonoidExtraPathName = "extra-path" configMonoidSetupInfoLocationsName :: Text configMonoidSetupInfoLocationsName = "setup-info" +configMonoidLocalProgramsBaseName :: Text +configMonoidLocalProgramsBaseName = "local-programs-path" + configMonoidPvpBoundsName :: Text configMonoidPvpBoundsName = "pvp-bounds" From 8a81de56df44b3a6d703530f72865b477a304402 Mon Sep 17 00:00:00 2001 From: Ruud van Asseldonk Date: Sat, 26 Nov 2016 21:12:05 +0100 Subject: [PATCH 6/7] Update FAQ to mention local-programs-path config --- doc/faq.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/doc/faq.md b/doc/faq.md index 006d799c66..87711ff60f 100644 --- a/doc/faq.md +++ b/doc/faq.md @@ -324,11 +324,12 @@ Cf. issue [#425](https://github.com/commercialhaskell/stack/issues/425). ## Can I change stack's default temporary directory? -Stack downloads and extracts files to `$STACK_ROOT`, which defaults to -`~/.stack`. If there is not enough free space in this directory, Stack may fail. +Stack downloads and extracts files to `$STACK_ROOT/programs` on most platforms, +which defaults to `~/.stack/programs`. On Windows `$LOCALAPPDATA\Programs\stack` +is used. If there is not enough free space in this directory, Stack may fail. For instance, `stack setup` with a GHC installation requires roughly 1GB free. -If this is an issue, you can change `$STACK_ROOT` to be on a file system with -more free space. +If this is an issue, you can set `local-programs-path` in your +`~/.stack/config.yaml` to a directory on a file system with more free space. If you use Stack with Nix integration, be aware that Nix uses a `TMPDIR` variable, and if it is not set Nix sets it to some subdirectory of `/run`, which From 449d6611d7393f61b34a458a2fa75603c23e2106 Mon Sep 17 00:00:00 2001 From: Ruud van Asseldonk Date: Sat, 26 Nov 2016 21:15:07 +0100 Subject: [PATCH 7/7] Update changelog for local-programs-path config --- ChangeLog.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/ChangeLog.md b/ChangeLog.md index 160cd3584d..6ba3c8bbc0 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -32,10 +32,6 @@ Behavior changes: * If a remote package is specified (such as a Git repo) without an explicit `extra-dep` setting, a warning is given to the user to provide one explicitly. -* On Windows, `stack setup` will now download and extract additional programs - such as GHC to `$STACK_ROOT\programs`, like on other platforms. You may need - to remove programs in `$LOCALAPPDATA\Programs\stack` manually. - [#1644](https://github.com/commercialhaskell/stack/issues/1644). Other enhancements: @@ -83,6 +79,9 @@ Other enhancements: [#2235](https://github.com/commercialhaskell/stack/issues/2235) * Replace enclosed-exceptions with safe-exceptions. [#2768](https://github.com/commercialhaskell/stack/issues/2768) +* The install location for GHC and other programs can now be configured with the + `local-programs-path` option in `config.yaml`. + [#1644](https://github.com/commercialhaskell/stack/issues/1644) Bug fixes: