From 7b392d155e58d8de26cd09a23b62ebac55b1ff79 Mon Sep 17 00:00:00 2001 From: Michael Snoyman Date: Sun, 7 Apr 2019 18:47:33 +0300 Subject: [PATCH] Modify the GHC_ENVIRONMENT env var in Stack.Setup This fixes #4706. Since GHC 8.0, GHC will now implicitly read in from a .ghc.environment.* file, which can cause commands like `stack exec ghci` to fail. Due to the use case of `stack exec`, it doesn't make sense to try to create our own environment file, but instead tell GHC to ignore it. Unfortunately, the ability to ignore environment files was only added in GHC 8.4.4. This patch: * Unsets any `GHC_ENVIRONMENT` variable already set outside of Stack * When using GHC 8.4.4 or later, sets the variable to `-` This will help work around situations where `cabal new-build` creates an environment file without the user's awareness. This may be somewhat superfluous in the future depending on changes to either GHC or cabal-install, but shouldn't present any harm for the foreseeable future (unless GHC changes its understanding of `GHC_ENVIRONMENT`). --- ChangeLog.md | 9 ++++++- src/Stack/Setup.hs | 14 +++++++++- .../tests/4706-ignore-ghc-env-files/Main.hs | 27 +++++++++++++++++++ .../files/.gitignore | 2 ++ .../4706-ignore-ghc-env-files/files/Main.hs | 2 ++ .../files/package.yaml | 7 +++++ 6 files changed, 59 insertions(+), 2 deletions(-) create mode 100644 test/integration/tests/4706-ignore-ghc-env-files/Main.hs create mode 100644 test/integration/tests/4706-ignore-ghc-env-files/files/.gitignore create mode 100644 test/integration/tests/4706-ignore-ghc-env-files/files/Main.hs create mode 100644 test/integration/tests/4706-ignore-ghc-env-files/files/package.yaml diff --git a/ChangeLog.md b/ChangeLog.md index 8e61afd805..c4b89a6dbc 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -160,7 +160,7 @@ Other enhancements: * Include default values for most command line flags in the `--help` output. See [#893](https://github.com/commercialhaskell/stack/issues/893). -* environment variable `GHC_ENVIRONMENT` is set to specify dependency +* Set the `GHC_ENVIRONMENT` environment variable to specify dependency packages explicitly when running test. This is done to prevent ambiguous module name errors in `doctest` tests. - Document the way stack interacts with the Cabal library. @@ -181,6 +181,13 @@ Other enhancements: * User config files are respected for the script command. See [#3705](https://github.com/commercialhaskell/stack/issues/3705), [#3887](https://github.com/commercialhaskell/stack/issues/3887). +* Set the `GHC_ENVIRONMENT` environment variable to `-` to tell GHC to + ignore any such files when GHC is new enough (>= 8.4.4), otherwise + simply unset the variable. This allows Stack to have control of + package databases when running commands like `stack exec ghci`, even + in the presence of implicit environment files created by `cabal + new-build`. See + [#4706](https://github.com/commercialhaskell/stack/issues/4706). Bug fixes: diff --git a/src/Stack/Setup.hs b/src/Stack/Setup.hs index 7434a7b10f..bb83346359 100644 --- a/src/Stack/Setup.hs +++ b/src/Stack/Setup.hs @@ -345,7 +345,18 @@ setupEnv needTargets boptsCLI mResolveMissingGHC = do [ toFilePathNoTrailingSep deps , "" ]) - $ Map.insert "HASKELL_DIST_DIR" (T.pack $ toFilePathNoTrailingSep distDir) env + $ Map.insert "HASKELL_DIST_DIR" (T.pack $ toFilePathNoTrailingSep distDir) + + -- Make sure that any .ghc.environment files + -- are ignored, since we're settting up our + -- own package databases. See + -- https://github.com/commercialhaskell/stack/issues/4706 + $ (case cpCompilerVersion compilerPaths of + ACGhc version | version >= mkVersion [8, 4, 4] -> + Map.insert "GHC_ENVIRONMENT" "-" + _ -> id) + + env () <- atomicModifyIORef envRef $ \m' -> (Map.insert es eo m', ()) @@ -1773,6 +1784,7 @@ removeHaskellEnvVars :: Map Text Text -> Map Text Text removeHaskellEnvVars = Map.delete "GHCJS_PACKAGE_PATH" . Map.delete "GHC_PACKAGE_PATH" . + Map.delete "GHC_ENVIRONMENT" . Map.delete "HASKELL_PACKAGE_SANDBOX" . Map.delete "HASKELL_PACKAGE_SANDBOXES" . Map.delete "HASKELL_DIST_DIR" . diff --git a/test/integration/tests/4706-ignore-ghc-env-files/Main.hs b/test/integration/tests/4706-ignore-ghc-env-files/Main.hs new file mode 100644 index 0000000000..7c963b085b --- /dev/null +++ b/test/integration/tests/4706-ignore-ghc-env-files/Main.hs @@ -0,0 +1,27 @@ +import StackTest +import Control.Exception (bracket_) +import Control.Monad (when) +import System.Environment +import System.Directory +import System.Info (arch, os) + +main :: IO () +main = when False $ do -- skip this test until we start using GHC 8.4.4 or later for integration tests + let ghcVer = "8.4.4" + fp = concat + [ ".ghc.environment." + , arch + , "-" + , os + , "-" + , ghcVer + ] + writeFile "stack.yaml" $ "resolver: ghc-" ++ ghcVer + bracket_ + (writeFile fp "This is an invalid GHC environment file") + (removeFile fp) $ do + envFile <- canonicalizePath fp + setEnv "GHC_ENVIRONMENT" envFile + stack ["clean"] + stack ["build"] + stack ["runghc", "Main.hs"] diff --git a/test/integration/tests/4706-ignore-ghc-env-files/files/.gitignore b/test/integration/tests/4706-ignore-ghc-env-files/files/.gitignore new file mode 100644 index 0000000000..0afaa560b3 --- /dev/null +++ b/test/integration/tests/4706-ignore-ghc-env-files/files/.gitignore @@ -0,0 +1,2 @@ +foo.cabal +stack.yaml diff --git a/test/integration/tests/4706-ignore-ghc-env-files/files/Main.hs b/test/integration/tests/4706-ignore-ghc-env-files/files/Main.hs new file mode 100644 index 0000000000..d582e1e36a --- /dev/null +++ b/test/integration/tests/4706-ignore-ghc-env-files/files/Main.hs @@ -0,0 +1,2 @@ +main :: IO () +main = pure () diff --git a/test/integration/tests/4706-ignore-ghc-env-files/files/package.yaml b/test/integration/tests/4706-ignore-ghc-env-files/files/package.yaml new file mode 100644 index 0000000000..9bd223a0a0 --- /dev/null +++ b/test/integration/tests/4706-ignore-ghc-env-files/files/package.yaml @@ -0,0 +1,7 @@ +name: foo +version: 0 + +dependencies: +- base + +library: {}