Skip to content

Commit 0ea6d9c

Browse files
committed
Merge pull request #1646 from commercialhaskell/nix-abstract-resolver
Nix: select the right GHC version in more cases.
2 parents de5c5ed + 58e6d54 commit 0ea6d9c

File tree

8 files changed

+54
-32
lines changed

8 files changed

+54
-32
lines changed

ChangeLog.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ Bug fixes:
2323
[Mailing list discussion](https://groups.google.com/d/msg/haskell-stack/iVGDG5OHYxs/FjUrR5JsDQAJ)
2424
- Gracefully handle invalid paths in error/warning messages
2525
[#1561](https://github.com/commercialhaskell/stack/issues/1561)
26+
- Nix: select the correct GHC version corresponding to the snapshot
27+
even when an abstract resolver is passed via `--resolver` on the
28+
command-line.
29+
[#1641](https://github.com/commercialhaskell/stack/issues/1641)
2630

2731
## 1.0.0
2832

src/Stack/Config.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,7 @@ configFromConfigMonoid configStackRoot configUserConfigPath mresolver mproject c
234234

235235
configDocker <-
236236
dockerOptsFromMonoid (fmap fst mproject) configStackRoot mresolver configMonoidDockerOpts
237-
configNix <- nixOptsFromMonoid (fmap fst mproject) mresolver configMonoidNixOpts os
237+
configNix <- nixOptsFromMonoid (fmap fst mproject) configMonoidNixOpts os
238238

239239
rawEnv <- liftIO getEnvironment
240240
pathsEnv <- augmentPathMap (map toFilePath configMonoidExtraPath)

src/Stack/Config/Nix.hs

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6,49 +6,49 @@ module Stack.Config.Nix
66
,StackNixException(..)
77
) where
88

9-
import Control.Monad (when)
9+
import Control.Applicative
10+
import Control.Monad (join, when)
1011
import qualified Data.Text as T
1112
import Data.Maybe
1213
import Data.Typeable
1314
import Distribution.System (OS (..))
1415
import Stack.Types
1516
import Control.Exception.Lifted
1617
import Control.Monad.Catch (throwM,MonadCatch)
17-
18+
import Prelude
1819

1920
-- | Interprets NixOptsMonoid options.
2021
nixOptsFromMonoid
2122
:: (Monad m, MonadCatch m)
2223
=> Maybe Project
23-
-> Maybe AbstractResolver
2424
-> NixOptsMonoid
2525
-> OS
2626
-> m NixOpts
27-
nixOptsFromMonoid mproject maresolver NixOptsMonoid{..} os = do
27+
nixOptsFromMonoid mproject NixOptsMonoid{..} os = do
2828
let nixEnable = fromMaybe nixMonoidDefaultEnable nixMonoidEnable
2929
defaultPure = case os of
3030
OSX -> False
3131
_ -> True
3232
nixPureShell = fromMaybe defaultPure nixMonoidPureShell
33-
mresolver = case maresolver of
34-
Just (ARResolver resolver) -> Just resolver
35-
Just _ -> Nothing
36-
Nothing -> fmap projectResolver mproject
37-
pkgs = fromMaybe [] nixMonoidPackages
38-
nixPackages = case mproject of
39-
Nothing -> pkgs
40-
Just _ -> pkgs ++ [case mresolver of
41-
Just (ResolverSnapshot (LTS x y)) ->
42-
T.pack ("haskell.packages.lts-" ++ show x ++ "_" ++ show y ++ ".ghc")
43-
_ -> T.pack "ghc"]
33+
nixPackages = fromMaybe [] nixMonoidPackages
4434
nixInitFile = nixMonoidInitFile
4535
nixShellOptions = fromMaybe [] nixMonoidShellOptions
4636
++ prefixAll (T.pack "-I") (fromMaybe [] nixMonoidPath)
47-
when (not (null pkgs) && isJust nixInitFile) $
37+
nixCompiler resolverOverride compilerOverride =
38+
let mresolver = resolverOverride <|> fmap projectResolver mproject
39+
mcompiler = compilerOverride <|> join (fmap projectCompiler mproject)
40+
in case (mresolver, mcompiler) of
41+
(_, Just (GhcVersion v)) -> nixCompilerFromVersion v
42+
(Just (ResolverCompiler (GhcVersion v)), _) -> nixCompilerFromVersion v
43+
(Just (ResolverSnapshot (LTS x y)), _) ->
44+
T.pack ("haskell.packages.lts-" ++ show x ++ "_" ++ show y ++ ".ghc")
45+
_ -> T.pack "ghc"
46+
when (not (null nixPackages) && isJust nixInitFile) $
4847
throwM NixCannotUseShellFileAndPackagesException
4948
return NixOpts{..}
5049
where prefixAll p (x:xs) = p : x : prefixAll p xs
5150
prefixAll _ _ = []
51+
nixCompilerFromVersion v = T.filter (/= '.') $ T.append (T.pack "haskell.compiler.ghc") (versionText v)
5252

5353
-- Exceptions thown specifically by Stack.Nix
5454
data StackNixException

src/Stack/Nix.hs

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ module Stack.Nix
1414
import Control.Applicative
1515
import Control.Arrow ((***))
1616
import Control.Exception (Exception,throw)
17-
import Control.Monad
17+
import Control.Monad hiding (mapM)
1818
import Control.Monad.Catch (try,MonadCatch)
1919
import Control.Monad.IO.Class (MonadIO,liftIO)
2020
import Control.Monad.Logger (MonadLogger,logDebug)
@@ -33,8 +33,9 @@ import Network.HTTP.Client.Conduit (HasHttpManager)
3333
import Path
3434
import Path.IO
3535
import qualified Paths_stack as Meta
36-
import Prelude -- Fix redundant import warnings
36+
import Prelude hiding (mapM) -- Fix redundant import warnings
3737
import Stack.Constants (stackProgName,platformVariantEnvVar)
38+
import Stack.Config (makeConcreteResolver)
3839
import Stack.Docker (reExecArgName)
3940
import Stack.Exec (exec)
4041
import System.Process.Read (getEnvOverride)
@@ -43,20 +44,21 @@ import Stack.Types.Internal
4344
import System.Environment (lookupEnv,getArgs,getExecutablePath)
4445
import System.Exit (exitSuccess, exitWith)
4546

46-
4747
-- | If Nix is enabled, re-runs the currently running OS command in a Nix container.
4848
-- Otherwise, runs the inner action.
4949
reexecWithOptionalShell
5050
:: M env m
5151
=> Maybe (Path Abs Dir)
52+
-> Maybe AbstractResolver
53+
-> Maybe CompilerVersion
5254
-> IO ()
5355
-> m ()
54-
reexecWithOptionalShell mprojectRoot inner =
56+
reexecWithOptionalShell mprojectRoot maresolver mcompiler inner =
5557
do config <- asks getConfig
5658
inShell <- getInShell
5759
isReExec <- asks getReExec
5860
if nixEnable (configNix config) && not inShell && not isReExec
59-
then runShellAndExit mprojectRoot getCmdArgs
61+
then runShellAndExit mprojectRoot maresolver mcompiler getCmdArgs
6062
else liftIO inner
6163
where
6264
getCmdArgs = do
@@ -70,30 +72,34 @@ reexecWithOptionalShell mprojectRoot inner =
7072
runShellAndExit
7173
:: M env m
7274
=> Maybe (Path Abs Dir)
75+
-> Maybe AbstractResolver
76+
-> Maybe CompilerVersion
7377
-> m (String, [String])
7478
-> m ()
75-
runShellAndExit mprojectRoot getCmdArgs = do
79+
runShellAndExit mprojectRoot maresolver mcompiler getCmdArgs = do
7680
config <- asks getConfig
81+
mresolver <- mapM makeConcreteResolver maresolver
7782
envOverride <- getEnvOverride (configPlatform config)
7883
(cmnd,args) <- fmap (escape *** map escape) getCmdArgs
7984
mshellFile <-
8085
traverse (resolveFile (fromMaybeProjectRoot mprojectRoot)) $
8186
nixInitFile (configNix config)
8287
let pkgsInConfig = nixPackages (configNix config)
88+
pkgs = pkgsInConfig ++ [nixCompiler (configNix config) mresolver mcompiler]
8389
pureShell = nixPureShell (configNix config)
8490
nixopts = case mshellFile of
8591
Just fp -> [toFilePath fp]
8692
Nothing -> ["-E", T.unpack $ T.intercalate " " $ concat
8793
[["with (import <nixpkgs> {});"
8894
,"runCommand \"myEnv\" {"
89-
,"buildInputs=lib.optional stdenv.isLinux glibcLocales ++ ["],pkgsInConfig,["];"
95+
,"buildInputs=lib.optional stdenv.isLinux glibcLocales ++ ["],pkgs,["];"
9096
,T.pack platformVariantEnvVar <> "=''nix'';"
9197
,T.pack inShellEnvVar <> "=1;"
9298
,"STACK_IN_NIX_EXTRA_ARGS=''"]
9399
, (map (\p -> T.concat
94100
["--extra-lib-dirs=${",p,"}/lib"
95101
," --extra-include-dirs=${",p,"}/include "])
96-
pkgsInConfig), ["'' ;"
102+
pkgs), ["'' ;"
97103
,"} \"\""]]]
98104
-- glibcLocales is necessary on Linux to avoid warnings about GHC being incapable to set the locale.
99105
fullArgs = concat [if pureShell then ["--pure"] else [],
@@ -105,7 +111,7 @@ runShellAndExit mprojectRoot getCmdArgs = do
105111
$logDebug $
106112
"Using a nix-shell environment " <> (case mshellFile of
107113
Just path -> "from file: " <> (T.pack (toFilePath path))
108-
Nothing -> "with nix packages: " <> (T.intercalate ", " pkgsInConfig))
114+
Nothing -> "with nix packages: " <> (T.intercalate ", " pkgs))
109115
e <- try (exec envOverride "nix-shell" fullArgs)
110116
case e of
111117
Left (ProcessExitedUnsuccessfully _ ec) -> liftIO (exitWith ec)

src/Stack/Types/Config.hs-boot

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
module Stack.Types.Config where
2+
3+
data AbstractResolver
4+
data Resolver
5+
data Config

src/Stack/Types/Nix.hs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,13 @@ import Control.Applicative
1010
import Data.Aeson.Extended
1111
import Data.Text (Text)
1212
import Data.Monoid
13-
1413
import Prelude
14+
import Stack.Types.Compiler (CompilerVersion)
15+
import {-# SOURCE #-} Stack.Types.Config (Resolver)
16+
import Text.Show.Functions ()
1517

16-
-- | Nix configuration.
18+
-- | Nix configuration. Parameterize by resolver type to avoid cyclic
19+
-- dependency.
1720
data NixOpts = NixOpts
1821
{nixEnable :: !Bool
1922
,nixPureShell :: !Bool
@@ -23,6 +26,8 @@ data NixOpts = NixOpts
2326
-- ^ The path of a file containing preconfiguration of the environment (e.g shell.nix)
2427
,nixShellOptions :: ![Text]
2528
-- ^ Options to be given to the nix-shell command line
29+
,nixCompiler :: !(Maybe Resolver -> Maybe CompilerVersion -> Text)
30+
-- ^ Yield a compiler attribute name given a resolver override.
2631
}
2732
deriving (Show)
2833

src/main/Main.hs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -698,7 +698,7 @@ setupCmd SetupCmdOpts{..} go@GlobalOpts{..} = do
698698
(lcProjectRoot lc)
699699
Nothing
700700
(runStackTGlobal manager (lcConfig lc) go $
701-
Nix.reexecWithOptionalShell (lcProjectRoot lc) $
701+
Nix.reexecWithOptionalShell (lcProjectRoot lc) globalResolver globalCompiler $
702702
runStackLoggingTGlobal manager go $ do
703703
(wantedCompiler, compilerCheck, mstack) <-
704704
case scoCompilerVersion of
@@ -864,7 +864,7 @@ withBuildConfigExt go@GlobalOpts{..} mbefore inner mafter = do
864864
(lcProjectRoot lc)
865865
mbefore
866866
(runStackTGlobal manager (lcConfig lc) go $
867-
Nix.reexecWithOptionalShell (lcProjectRoot lc) (inner'' lk0))
867+
Nix.reexecWithOptionalShell (lcProjectRoot lc) globalResolver globalCompiler (inner'' lk0))
868868
mafter
869869
(Just $ liftIO $
870870
do lk' <- readIORef curLk
@@ -1007,6 +1007,8 @@ execCmd ExecOpts {..} go@GlobalOpts{..} =
10071007
menv <- liftIO $ configEnvOverride config plainEnvSettings
10081008
Nix.reexecWithOptionalShell
10091009
(lcProjectRoot lc)
1010+
globalResolver
1011+
globalCompiler
10101012
(runStackTGlobal manager (lcConfig lc) go $
10111013
exec menv cmd args))
10121014
Nothing

src/test/Stack/NixSpec.hs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,5 +63,5 @@ spec = beforeAll setup $ afterAll teardown $ do
6363
it "sees that the only package asked for is glpk and adds GHC from nixpkgs mirror of LTS resolver" $ \T{..} -> inTempDir $ do
6464
writeFile (toFilePath stackDotYaml) sampleConfig
6565
lc <- loadConfig' manager
66-
(nixPackages $ configNix $ lcConfig lc) `shouldBe` ["glpk", "haskell.packages.lts-2_10.ghc"]
67-
66+
(nixPackages $ configNix $ lcConfig lc) `shouldBe` ["glpk"]
67+
(nixCompiler $ configNix $ lcConfig lc) Nothing Nothing `shouldBe` "haskell.packages.lts-2_10.ghc"

0 commit comments

Comments
 (0)