@@ -10,9 +10,12 @@ import Data.Aeson
10
10
import Data.Char ( isDigit )
11
11
import Data.HashMap.Strict ( HashMap )
12
12
import qualified Data.HashMap.Strict as Map
13
+ import Data.HashSet ( HashSet )
14
+ import qualified Data.HashSet as Set
13
15
import Data.Maybe ( mapMaybe
14
16
, isJust
15
17
, fromMaybe
18
+ , maybeToList
16
19
)
17
20
import Data.List.NonEmpty ( NonEmpty (.. ) )
18
21
import qualified Data.Text as Text
@@ -76,7 +79,7 @@ writeDoc file doc =
76
79
hClose handle
77
80
78
81
plan2nix :: Args -> Plan -> IO NExpr
79
- plan2nix args (Plan { packages, extras, compilerVersion, compilerPackages }) = do
82
+ plan2nix args (Plan { packages, extras, components, compilerVersion, compilerPackages }) = do
80
83
-- TODO: this is an aweful hack and expects plan-to-nix to be
81
84
-- called from the toplevel project directory.
82
85
cwd <- getCurrentDirectory
@@ -108,6 +111,9 @@ plan2nix args (Plan { packages, extras, compilerVersion, compilerPackages }) = d
108
111
let flags = concatMap (\ case
109
112
(name, Just (Package _v _r f _)) -> flags2nix name f
110
113
_ -> [] ) $ Map. toList extras
114
+ -- Set the `planned` option for all components in the plan.
115
+ planned = map (\ name -> name <> " .planned" $=
116
+ (" lib" @. " mkOverride" @@ mkInt 900 @@ mkBool True )) $ Set. toList components
111
117
112
118
return $ mkNonRecSet [
113
119
" pkgs" $= (" hackage" ==> mkNonRecSet (
@@ -121,6 +127,7 @@ plan2nix args (Plan { packages, extras, compilerVersion, compilerPackages }) = d
121
127
, " extras" $= (" hackage" ==> mkNonRecSet [ " packages" $= extrasNix ])
122
128
, " modules" $= mkList [
123
129
mkParamset [(" lib" , Nothing )] True ==> mkNonRecSet [ " packages" $= mkNonRecSet flags ]
130
+ , mkParamset [(" lib" , Nothing )] True ==> mkNonRecSet [ " packages" $= mkNonRecSet planned ]
124
131
]
125
132
]
126
133
where
@@ -176,7 +183,7 @@ flags2nix pkgName pkgFlags =
176
183
]
177
184
178
185
value2plan :: Value -> Plan
179
- value2plan plan = Plan { packages, extras, compilerVersion, compilerPackages }
186
+ value2plan plan = Plan { packages, components, extras, compilerVersion, compilerPackages }
180
187
where
181
188
packages = fmap Just $ filterInstallPlan $ \ pkg -> case ( pkg ^. key " type" . _String
182
189
, pkg ^. key " style" . _String) of
@@ -239,7 +246,39 @@ value2plan plan = Plan { packages, extras, compilerVersion, compilerPackages }
239
246
$ mapMaybe (\ pkg -> (,) (pkg ^. key " pkg-name" . _String) <$> f pkg)
240
247
$ Vector. toList (plan ^. key " install-plan" . _Array)
241
248
249
+ -- Set of components that are included in the plan.
250
+ components :: HashSet Text
251
+ components =
252
+ Set. fromList
253
+ $ concatMap (\ pkg ->
254
+ let pkgName = pkg ^. key " pkg-name" . _String
255
+ nixComponentAttr = Text. pack . componentNameToHaskellNixAttr pkgName . Text. unpack
256
+ in
257
+ map ((quoted pkgName <> " .components." ) <> ) $
258
+ case (pkg ^. key " type" . _String, Map. keys (pkg ^. key " components" . _Object)) of
259
+ (" pre-existing" , _) -> [ " library" ]
260
+ (_, [] ) -> [ nixComponentAttr $ pkg ^. key " component-name" . _String ]
261
+ (_, c) -> map nixComponentAttr c)
262
+ $ Vector. toList (plan ^. key " install-plan" . _Array)
263
+
264
+ -- Convert a cabal style component name to the haskell.nix attribute path.
265
+ componentNameToHaskellNixAttr :: Text -> String -> String
266
+ componentNameToHaskellNixAttr pkgName n =
267
+ case span (/= ' :' ) n of
268
+ (" setup" , " " ) -> " setup"
269
+ (" lib" , " " ) -> " library"
270
+ (prefix, ' :' : rest) -> componentPrefixToHaskellNix prefix <> " ." <> quoted rest
271
+ _ -> error (" unknown component name format " <> show n <> " for package " <> show pkgName)
272
+
273
+ componentPrefixToHaskellNix :: String -> String
274
+ componentPrefixToHaskellNix " lib" = " sublibs"
275
+ componentPrefixToHaskellNix " flib" = " foreignlibs"
276
+ componentPrefixToHaskellNix " exe" = " exes"
277
+ componentPrefixToHaskellNix " test" = " tests"
278
+ componentPrefixToHaskellNix " bench" = " benchmarks"
279
+ componentPrefixToHaskellNix x = error (" unknown component prefix " <> x)
242
280
281
+ defaultNixContents :: String
243
282
defaultNixContents = unlines $
244
283
[ " { haskellNixSrc ? builtins.fetchTarball https://github.com/input-output-hk/haskell.nix/archive/master.tar.gz"
245
284
, " , haskellNix ? import haskellNixSrc {}"
0 commit comments