Skip to content

Commit c2d89d4

Browse files
committed
Reformat Stack.Nix
1 parent 9430eb5 commit c2d89d4

File tree

1 file changed

+118
-90
lines changed

1 file changed

+118
-90
lines changed

src/Stack/Nix.hs

Lines changed: 118 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -7,24 +7,27 @@
77

88
-- | Run commands in a nix-shell
99
module Stack.Nix
10-
(nixCmdName
11-
,nixHelpOptName
12-
,runShellAndExit
10+
( nixCmdName
11+
, nixHelpOptName
12+
, runShellAndExit
1313
) where
1414

15-
import Stack.Prelude
1615
import qualified Data.Text as T
17-
import Path.IO
18-
import Stack.Config (getInContainer, withBuildConfig)
19-
import Stack.Config.Nix (nixCompiler, nixCompilerVersion)
20-
import Stack.Constants (platformVariantEnvVar,inNixShellEnvVar,inContainerEnvVar)
16+
import Path.IO ( resolveFile )
17+
import RIO.Process ( exec, processContextL )
18+
import Stack.Config ( getInContainer, withBuildConfig )
19+
import Stack.Config.Nix ( nixCompiler, nixCompilerVersion )
20+
import Stack.Constants
21+
( inContainerEnvVar, inNixShellEnvVar
22+
, platformVariantEnvVar
23+
)
24+
import Stack.Prelude
2125
import Stack.Types.Config
2226
import Stack.Types.Docker
2327
import Stack.Types.Nix
2428
import Stack.Types.Version ( showStackVersion )
25-
import System.Environment (getArgs,getExecutablePath,lookupEnv)
26-
import qualified System.FilePath as F
27-
import RIO.Process (processContextL, exec)
29+
import System.Environment ( getArgs, getExecutablePath, lookupEnv )
30+
import qualified System.FilePath as F
2831

2932
-- | Type representing exceptions thrown by functions exported by the
3033
-- "Stack.Nix" module.
@@ -40,91 +43,116 @@ instance Exception NixException where
4043

4144
runShellAndExit :: RIO Config void
4245
runShellAndExit = do
43-
inContainer <- getInContainer -- TODO we can probably assert that this is False based on Stack.Runners now
44-
origArgs <- liftIO getArgs
45-
let args | inContainer = origArgs -- internal-re-exec version already passed
46-
-- first stack when restarting in the container
47-
| otherwise =
48-
("--" ++ reExecArgName ++ "=" ++ showStackVersion) : origArgs
49-
exePath <- liftIO getExecutablePath
50-
config <- view configL
51-
envOverride <- view processContextL
52-
local (set processContextL envOverride) $ do
53-
let cmnd = escape exePath
54-
args' = map escape args
46+
inContainer <- getInContainer -- TODO we can probably assert that this is False based on Stack.Runners now
47+
origArgs <- liftIO getArgs
48+
let args | inContainer = origArgs -- internal-re-exec version already passed
49+
-- first stack when restarting in the container
50+
| otherwise =
51+
("--" ++ reExecArgName ++ "=" ++ showStackVersion) : origArgs
52+
exePath <- liftIO getExecutablePath
53+
config <- view configL
54+
envOverride <- view processContextL
55+
local (set processContextL envOverride) $ do
56+
let cmnd = escape exePath
57+
args' = map escape args
58+
59+
mshellFile <- case configProjectRoot config of
60+
Just projectRoot ->
61+
traverse (resolveFile projectRoot) $ nixInitFile (configNix config)
62+
Nothing -> pure Nothing
5563

56-
mshellFile <- case configProjectRoot config of
57-
Just projectRoot ->
58-
traverse (resolveFile projectRoot) $ nixInitFile (configNix config)
59-
Nothing -> pure Nothing
64+
-- This will never result in double loading the build config, since:
65+
--
66+
-- 1. This function explicitly takes a Config, not a HasConfig
67+
--
68+
-- 2. This function ends up exiting before running other code
69+
-- (thus the void return type)
70+
compilerVersion <- withBuildConfig $ view wantedCompilerVersionL
6071

61-
-- This will never result in double loading the build config, since:
62-
--
63-
-- 1. This function explicitly takes a Config, not a HasConfig
64-
--
65-
-- 2. This function ends up exiting before running other code
66-
-- (thus the void return type)
67-
compilerVersion <- withBuildConfig $ view wantedCompilerVersionL
72+
ghc <- either throwIO pure $ nixCompiler compilerVersion
73+
ghcVersion <- either throwIO pure $ nixCompilerVersion compilerVersion
74+
let pkgsInConfig = nixPackages (configNix config)
75+
pkgs = pkgsInConfig ++ [ghc, "git", "gcc", "gmp"]
76+
pkgsStr = "[" <> T.intercalate " " pkgs <> "]"
77+
pureShell = nixPureShell (configNix config)
78+
addGCRoots = nixAddGCRoots (configNix config)
79+
nixopts = case mshellFile of
80+
Just fp ->
81+
[ toFilePath fp
82+
, "--arg"
83+
, "ghc"
84+
, "with (import <nixpkgs> {}); " ++ T.unpack ghc
85+
, "--argstr", "ghcVersion", T.unpack ghcVersion
86+
]
87+
Nothing ->
88+
[ "-E"
89+
, T.unpack $ T.concat
90+
[ "with (import <nixpkgs> {}); "
91+
, "let inputs = ",pkgsStr,"; "
92+
, "libPath = lib.makeLibraryPath inputs; "
93+
, "stackExtraArgs = lib.concatMap (pkg: "
94+
, "[ ''--extra-lib-dirs=${lib.getLib pkg}/lib'' "
95+
, " ''--extra-include-dirs=${lib.getDev pkg}/include'' ]"
96+
, ") inputs; in "
97+
, "runCommand ''myEnv'' { "
98+
, "buildInputs = lib.optional stdenv.isLinux glibcLocales ++ inputs; "
99+
-- glibcLocales is necessary on Linux to avoid warnings about
100+
-- GHC being incapable to set the locale.
101+
, T.pack platformVariantEnvVar <> "=''nix''; "
102+
, T.pack inNixShellEnvVar <> "=1; "
103+
, if inContainer
104+
-- If shell is pure, this env var would not
105+
-- be seen by stack inside nix
106+
then T.pack inContainerEnvVar <> "=1; "
107+
else ""
108+
, "LD_LIBRARY_PATH = libPath;"
109+
-- LD_LIBRARY_PATH is set because for now it's needed by
110+
-- builds using Template Haskell
111+
, "STACK_IN_NIX_EXTRA_ARGS = stackExtraArgs; "
112+
-- overriding default locale so Unicode output using base
113+
-- won't be broken
114+
, "LANG=\"en_US.UTF-8\";"
115+
, "} \"\""
116+
]
117+
]
68118

69-
ghc <- either throwIO pure $ nixCompiler compilerVersion
70-
ghcVersion <- either throwIO pure $ nixCompilerVersion compilerVersion
71-
let pkgsInConfig = nixPackages (configNix config)
72-
pkgs = pkgsInConfig ++ [ghc, "git", "gcc", "gmp"]
73-
pkgsStr = "[" <> T.intercalate " " pkgs <> "]"
74-
pureShell = nixPureShell (configNix config)
75-
addGCRoots = nixAddGCRoots (configNix config)
76-
nixopts = case mshellFile of
77-
Just fp -> [toFilePath fp
78-
,"--arg", "ghc", "with (import <nixpkgs> {}); " ++ T.unpack ghc
79-
,"--argstr", "ghcVersion", T.unpack ghcVersion]
80-
Nothing -> ["-E", T.unpack $ T.concat
81-
["with (import <nixpkgs> {}); "
82-
,"let inputs = ",pkgsStr,"; "
83-
, "libPath = lib.makeLibraryPath inputs; "
84-
, "stackExtraArgs = lib.concatMap (pkg: "
85-
, "[ ''--extra-lib-dirs=${lib.getLib pkg}/lib'' "
86-
, " ''--extra-include-dirs=${lib.getDev pkg}/include'' ]"
87-
, ") inputs; in "
88-
,"runCommand ''myEnv'' { "
89-
,"buildInputs = lib.optional stdenv.isLinux glibcLocales ++ inputs; "
90-
,T.pack platformVariantEnvVar <> "=''nix''; "
91-
,T.pack inNixShellEnvVar <> "=1; "
92-
,if inContainer
93-
-- If shell is pure, this env var would not
94-
-- be seen by stack inside nix
95-
then T.pack inContainerEnvVar <> "=1; "
96-
else ""
97-
,"LD_LIBRARY_PATH = libPath;" -- LD_LIBRARY_PATH is set because for now it's
98-
-- needed by builds using Template Haskell
99-
,"STACK_IN_NIX_EXTRA_ARGS = stackExtraArgs; "
100-
-- overriding default locale so Unicode output using base won't be broken
101-
,"LANG=\"en_US.UTF-8\";"
102-
,"} \"\""]]
103-
-- glibcLocales is necessary on Linux to avoid warnings about GHC being incapable to set the locale.
104-
fullArgs = concat [if pureShell then ["--pure"] else []
105-
,if addGCRoots then ["--indirect", "--add-root"
106-
,toFilePath (configWorkDir config)
107-
F.</> "nix-gc-symlinks" F.</> "gc-root"] else []
108-
,map T.unpack (nixShellOptions (configNix config))
109-
,nixopts
110-
,["--run", unwords (cmnd:"$STACK_IN_NIX_EXTRA_ARGS":args')]
111-
]
112-
-- Using --run instead of --command so we cannot
113-
-- end up in the nix-shell if stack build is Ctrl-C'd
114-
pathVar <- liftIO $ lookupEnv "PATH"
115-
logDebug $ "PATH is: " <> displayShow pathVar
116-
logDebug $
117-
"Using a nix-shell environment " <> (case mshellFile of
118-
Just path -> "from file: " <> fromString (toFilePath path)
119-
Nothing -> "with nix packages: " <> display (T.intercalate ", " pkgs))
120-
exec "nix-shell" fullArgs
119+
fullArgs = concat
120+
[ if pureShell then ["--pure"] else []
121+
, if addGCRoots
122+
then [ "--indirect"
123+
, "--add-root"
124+
, toFilePath
125+
(configWorkDir config)
126+
F.</> "nix-gc-symlinks"
127+
F.</> "gc-root"
128+
]
129+
else []
130+
, map T.unpack (nixShellOptions (configNix config))
131+
, nixopts
132+
, ["--run", unwords (cmnd:"$STACK_IN_NIX_EXTRA_ARGS":args')]
133+
-- Using --run instead of --command so we cannot end up in the
134+
-- nix-shell if stack build is Ctrl-C'd
135+
]
136+
pathVar <- liftIO $ lookupEnv "PATH"
137+
logDebug $ "PATH is: " <> displayShow pathVar
138+
logDebug $
139+
"Using a nix-shell environment "
140+
<> ( case mshellFile of
141+
Just path ->
142+
"from file: "
143+
<> fromString (toFilePath path)
144+
Nothing ->
145+
"with nix packages: "
146+
<> display (T.intercalate ", " pkgs)
147+
)
148+
exec "nix-shell" fullArgs
121149

122150
-- | Shell-escape quotes inside the string and enclose it in quotes.
123151
escape :: String -> String
124-
escape str = "'" ++ foldr (\c -> if c == '\'' then
125-
("'\"'\"'"++)
126-
else (c:)) "" str
127-
++ "'"
152+
escape str =
153+
"'"
154+
++ foldr (\c -> if c == '\'' then ("'\"'\"'"++) else (c:)) "" str
155+
++ "'"
128156

129157
-- | Command-line argument for "nix"
130158
nixCmdName :: String

0 commit comments

Comments
 (0)