Skip to content

Commit 8619824

Browse files
authored
Merge pull request commercialhaskell#2514 from commercialhaskell/nix-add-gc-roots
Added option to add nix dependencies as nix GC roots
2 parents f7f1e4d + d7acb64 commit 8619824

6 files changed

Lines changed: 30 additions & 3 deletions

File tree

ChangeLog.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ Other enhancements:
2727
See [#2243](https://github.com/commercialhaskell/stack/issues/2243)
2828
* Stack/Nix: Sets `LD_LIBRARY_PATH` so packages using C libs for Template Haskell can work
2929
(See _e.g._ [this HaskellR issue](https://github.com/tweag/HaskellR/issues/253))
30-
30+
* Stack/nix: Dependencies can be added as nix GC roots, so they are not removed
31+
when running `nix-collect-garbage`
3132
* Parse CLI arguments and configuration files into less permissive types,
3233
improving error messages for bad inputs.
3334
[#2267](https://github.com/commercialhaskell/stack/issues/2267)

doc/nix_integration.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,14 @@ nix:
186186
# `[nixpkgs=/my/local/nixpkgs/clone]` that will be used to override
187187
# NIX_PATH.
188188
path: []
189+
190+
# false by default. Whether to add your nix dependencies as nix garbage
191+
# collection roots. This way, calling nix-collect-garbage will not remove
192+
# those packages from the nix store, saving you some time when running
193+
# stack build again with nix support activated.
194+
# This creates a `nix-gc-symlinks` directory in the project `.stack-work`.
195+
# To revert that, just delete this `nix-gc-symlinks` directory.
196+
add-gc-roots: false
189197
```
190198
191199
## Using a custom shell.nix file

src/Stack/Config/Nix.hs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ nixOptsFromMonoid NixOptsMonoid{..} os = do
3636
nixInitFile = getFirst nixMonoidInitFile
3737
nixShellOptions = fromFirst [] nixMonoidShellOptions
3838
++ prefixAll (T.pack "-I") (fromFirst [] nixMonoidPath)
39+
nixAddGCRoots = fromFirst False nixMonoidAddGCRoots
3940
when (not (null nixPackages) && isJust nixInitFile) $
4041
throwM NixCannotUseShellFileAndPackagesException
4142
return NixOpts{..}

src/Stack/Nix.hs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ import Stack.Types.Nix
4242
import Stack.Types.Compiler
4343
import Stack.Types.Internal
4444
import System.Environment (lookupEnv,getArgs,getExecutablePath)
45+
import qualified System.FilePath as F
4546
import System.Process.Read (getEnvOverride)
4647

4748
-- | If Nix is enabled, re-runs the currently running OS command in a Nix container.
@@ -87,6 +88,7 @@ runShellAndExit mprojectRoot getCompilerVersion getCmdArgs = do
8788
pkgs = pkgsInConfig ++ [ghc]
8889
pkgsStr = "[" <> T.intercalate " " pkgs <> "]"
8990
pureShell = nixPureShell (configNix config)
91+
addGCRoots = nixAddGCRoots (configNix config)
9092
nixopts = case mshellFile of
9193
Just fp -> [toFilePath fp, "--arg", "ghc"
9294
,"with (import <nixpkgs> {}); " ++ T.unpack ghc]
@@ -109,8 +111,11 @@ runShellAndExit mprojectRoot getCompilerVersion getCmdArgs = do
109111
,"STACK_IN_NIX_EXTRA_ARGS = stackExtraArgs; "
110112
,"} \"\""]]
111113
-- glibcLocales is necessary on Linux to avoid warnings about GHC being incapable to set the locale.
112-
fullArgs = concat [if pureShell then ["--pure"] else [],
113-
map T.unpack (nixShellOptions (configNix config))
114+
fullArgs = concat [if pureShell then ["--pure"] else []
115+
,if addGCRoots then ["--indirect", "--add-root"
116+
,toFilePath (configWorkDir config)
117+
F.</> "nix-gc-symlinks" F.</> "gc-root"] else []
118+
,map T.unpack (nixShellOptions (configNix config))
114119
,nixopts
115120
,["--run", intercalate " " (cmnd:"$STACK_IN_NIX_EXTRA_ARGS":args)]
116121
]

src/Stack/Options.hs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -484,6 +484,9 @@ nixOptsParser hide0 = overrideActivation <$>
484484
metavar "PATH_OPTIONS" <>
485485
help "Additional options to override NIX_PATH parts (notably 'nixpkgs')" <>
486486
hide))
487+
<*> firstBoolFlags "nix-add-gc-roots"
488+
"addition of packages to the nix GC roots so nix-collect-garbage doesn't remove them"
489+
hide
487490
)
488491
where
489492
hide = hideMods hide0

src/Stack/Types/Nix.hs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ data NixOpts = NixOpts
2626
-- ^ The path of a file containing preconfiguration of the environment (e.g shell.nix)
2727
,nixShellOptions :: ![Text]
2828
-- ^ Options to be given to the nix-shell command line
29+
,nixAddGCRoots :: !Bool
30+
-- ^ Should we register gc roots so running nix-collect-garbage doesn't remove nix dependencies
2931
}
3032
deriving (Show)
3133

@@ -46,6 +48,8 @@ data NixOptsMonoid = NixOptsMonoid
4648
-- ^ Options to be given to the nix-shell command line
4749
,nixMonoidPath :: !(First [Text])
4850
-- ^ Override parts of NIX_PATH (notably 'nixpkgs')
51+
,nixMonoidAddGCRoots :: !(First Bool)
52+
-- ^ Should we register gc roots so running nix-collect-garbage doesn't remove nix dependencies
4953
}
5054
deriving (Eq, Show, Generic)
5155

@@ -59,6 +63,7 @@ instance FromJSON (WithJSONWarnings NixOptsMonoid) where
5963
nixMonoidInitFile <- First <$> o ..:? nixInitFileArgName
6064
nixMonoidShellOptions <- First <$> o ..:? nixShellOptsArgName
6165
nixMonoidPath <- First <$> o ..:? nixPathArgName
66+
nixMonoidAddGCRoots <- First <$> o ..:? nixAddGCRootsArgName
6267
return NixOptsMonoid{..})
6368

6469
-- | Left-biased combine Nix options
@@ -89,3 +94,7 @@ nixShellOptsArgName = "nix-shell-options"
8994
-- | NIX_PATH override argument name
9095
nixPathArgName :: Text
9196
nixPathArgName = "path"
97+
98+
-- | Add GC roots arg name
99+
nixAddGCRootsArgName :: Text
100+
nixAddGCRootsArgName = "add-gc-roots"

0 commit comments

Comments
 (0)