forked from commercialhaskell/stack
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathNix.hs
More file actions
98 lines (87 loc) · 3.6 KB
/
Nix.hs
File metadata and controls
98 lines (87 loc) · 3.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE RecordWildCards, DeriveDataTypeable, OverloadedStrings #-}
-- | Nix configuration
module Stack.Config.Nix
(nixOptsFromMonoid
,nixCompiler
,StackNixException(..)
) where
import Stack.Prelude
import Control.Monad.Extra (ifM)
import qualified Data.Text as T
import qualified Data.Text.IO as TIO
import Distribution.System (OS (..))
import Stack.Constants
import Stack.Types.Version
import Stack.Types.Nix
import Stack.Types.Compiler
import Stack.Types.Runner
import System.Directory (doesFileExist)
-- | Interprets NixOptsMonoid options.
nixOptsFromMonoid
:: HasRunner env
=> NixOptsMonoid
-> OS
-> RIO env NixOpts
nixOptsFromMonoid NixOptsMonoid{..} os = do
let defaultPure = case os of
OSX -> False
_ -> True
nixPureShell = fromFirst defaultPure nixMonoidPureShell
nixPackages = fromFirst [] nixMonoidPackages
nixInitFile = getFirst nixMonoidInitFile
nixShellOptions = fromFirst [] nixMonoidShellOptions
++ prefixAll (T.pack "-I") (fromFirst [] nixMonoidPath)
nixAddGCRoots = fromFirst False nixMonoidAddGCRoots
-- Enable Nix-mode by default on NixOS, unless Docker-mode was specified
osIsNixOS <- isNixOS
let nixEnable0 = fromFirst osIsNixOS nixMonoidEnable
nixEnable <- case () of _
| nixEnable0 && osIsWindows -> do
logInfo "Note: Disabling nix integration, since this is being run in Windows"
return False
| otherwise -> return nixEnable0
when (not (null nixPackages) && isJust nixInitFile) $
throwIO NixCannotUseShellFileAndPackagesException
return NixOpts{..}
where prefixAll p (x:xs) = p : x : prefixAll p xs
prefixAll _ _ = []
nixCompiler :: CompilerVersion a -> Either StringException T.Text
nixCompiler compilerVersion =
case compilerVersion of
GhcVersion version ->
case T.split (== '.') (versionText version) of
x : y : minor ->
Right $
case minor of
[] ->
-- The minor version is not specified. Select the latest minor
-- version in Nixpkgs corresponding to the requested major
-- version.
let major = T.concat [x, y] in
"(let compilers = builtins.filter \
\(name: builtins.match \
\\"ghc" <> major <> "[[:digit:]]*\" name != null) \
\(lib.attrNames haskell.compiler); in \
\if compilers == [] \
\then abort \"No compiler found for GHC "
<> versionText version <> "\"\
\else haskell.compiler.${builtins.head compilers})"
_ -> "haskell.compiler.ghc" <> T.concat (x : y : minor)
_ -> Left $ stringException "GHC major version not specified"
_ -> Left $ stringException "Only GHC is supported by stack --nix"
-- Exceptions thown specifically by Stack.Nix
data StackNixException
= NixCannotUseShellFileAndPackagesException
-- ^ Nix can't be given packages and a shell file at the same time
deriving (Typeable)
instance Exception StackNixException
instance Show StackNixException where
show NixCannotUseShellFileAndPackagesException =
"You cannot have packages and a shell-file filled at the same time in your nix-shell configuration."
isNixOS :: MonadIO m => m Bool
isNixOS = liftIO $ do
let fp = "/etc/os-release"
ifM (doesFileExist fp)
(T.isInfixOf "ID=nixos" <$> TIO.readFile fp)
(return False)