Skip to content

Commit 4bca7bb

Browse files
authored
Add module setting planned to the output of plan-to-nix (input-output-hk#108)
So that we can avoid attempting to build components that were not in the `plan.json` file we need to identify those that were. Changes `plan-to-nix` so it sets a `planned` option for all components in the `plan.json`. For stack projects it marks everything as `planned`.
1 parent 57939eb commit 4bca7bb

File tree

4 files changed

+50
-9
lines changed

4 files changed

+50
-9
lines changed

default.nix

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,12 @@ let
44
sources = import ./nix/sources.nix {};
55
haskellNix = import sources."haskell.nix" {};
66
pkgs = import haskellNix.sources.nixpkgs-unstable haskellNix.nixpkgsArgs;
7-
project = pkgs.haskell-nix.cabalProject {
7+
in
8+
pkgs.haskell-nix.cabalProject {
89
inherit compiler-nix-name;
910
src = pkgs.haskell-nix.haskellLib.cleanGit { src = ./.; name = "nix-tools"; };
10-
};
11-
in
12-
project // {
13-
shell = project.shellFor {
14-
tools = { cabal = "latest"; };
11+
shell = {
12+
tools.cabal = {};
1513
buildInputs = [
1614
pkgs.nix-prefetch-git
1715
];

lib/Stack2nix.hs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,9 @@ stack2nix args (Stack resolver compiler pkgs pkgFlags ghcOpts) =
8989
, "resolver" $= fromString (quoted resolver)
9090
, "modules" $= mkList [
9191
mkParamset [("lib", Nothing)] True ==> mkNonRecSet [ "packages" $= mkNonRecSet flags ]
92-
, mkNonRecSet [ "packages" $= mkNonRecSet ghcOptions ] ]
92+
, mkNonRecSet [ "packages" $= mkNonRecSet ghcOptions ]
93+
-- Mark all packages as planned (stack projects do not have planned/unplanned components).
94+
, mkParamset [("lib", Nothing)] True ==> mkNonRecSet [ "planned" $= ("lib" @. "mkOverride" @@ mkInt 900 @@ mkBool True) ] ]
9395
] ++ [
9496
"compiler" $= fromString (quoted c) | (Just c) <- [compiler]
9597
]

plan2nix/Plan2Nix.hs

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,12 @@ import Data.Aeson
1010
import Data.Char ( isDigit )
1111
import Data.HashMap.Strict ( HashMap )
1212
import qualified Data.HashMap.Strict as Map
13+
import Data.HashSet ( HashSet )
14+
import qualified Data.HashSet as Set
1315
import Data.Maybe ( mapMaybe
1416
, isJust
1517
, fromMaybe
18+
, maybeToList
1619
)
1720
import Data.List.NonEmpty ( NonEmpty (..) )
1821
import qualified Data.Text as Text
@@ -76,7 +79,7 @@ writeDoc file doc =
7679
hClose handle
7780

7881
plan2nix :: Args -> Plan -> IO NExpr
79-
plan2nix args (Plan { packages, extras, compilerVersion, compilerPackages }) = do
82+
plan2nix args (Plan { packages, extras, components, compilerVersion, compilerPackages }) = do
8083
-- TODO: this is an aweful hack and expects plan-to-nix to be
8184
-- called from the toplevel project directory.
8285
cwd <- getCurrentDirectory
@@ -108,6 +111,9 @@ plan2nix args (Plan { packages, extras, compilerVersion, compilerPackages }) = d
108111
let flags = concatMap (\case
109112
(name, Just (Package _v _r f _)) -> flags2nix name f
110113
_ -> []) $ 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
111117

112118
return $ mkNonRecSet [
113119
"pkgs" $= ("hackage" ==> mkNonRecSet (
@@ -121,6 +127,7 @@ plan2nix args (Plan { packages, extras, compilerVersion, compilerPackages }) = d
121127
, "extras" $= ("hackage" ==> mkNonRecSet [ "packages" $= extrasNix ])
122128
, "modules" $= mkList [
123129
mkParamset [("lib", Nothing)] True ==> mkNonRecSet [ "packages" $= mkNonRecSet flags ]
130+
, mkParamset [("lib", Nothing)] True ==> mkNonRecSet [ "packages" $= mkNonRecSet planned ]
124131
]
125132
]
126133
where
@@ -176,7 +183,7 @@ flags2nix pkgName pkgFlags =
176183
]
177184

178185
value2plan :: Value -> Plan
179-
value2plan plan = Plan { packages, extras, compilerVersion, compilerPackages }
186+
value2plan plan = Plan { packages, components, extras, compilerVersion, compilerPackages }
180187
where
181188
packages = fmap Just $ filterInstallPlan $ \pkg -> case ( pkg ^. key "type" . _String
182189
, pkg ^. key "style" . _String) of
@@ -239,7 +246,39 @@ value2plan plan = Plan { packages, extras, compilerVersion, compilerPackages }
239246
$ mapMaybe (\pkg -> (,) (pkg ^. key "pkg-name" . _String) <$> f pkg)
240247
$ Vector.toList (plan ^. key "install-plan" . _Array)
241248

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)
242280

281+
defaultNixContents :: String
243282
defaultNixContents = unlines $
244283
[ "{ haskellNixSrc ? builtins.fetchTarball https://github.com/input-output-hk/haskell.nix/archive/master.tar.gz"
245284
, ", haskellNix ? import haskellNixSrc {}"

plan2nix/Plan2Nix/Plan.hs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ module Plan2Nix.Plan
1414

1515
import Data.Text ( Text )
1616
import Data.HashMap.Strict ( HashMap )
17+
import Data.HashSet ( HashSet )
1718

1819
type Version = Text
1920
type Revision = Text -- Can be: rNUM, cabal file sha256, or "default"
@@ -29,6 +30,7 @@ data Location
2930
data Plan = Plan
3031
{ packages :: HashMap Text (Maybe Package)
3132
, extras :: HashMap Text (Maybe Package)
33+
, components :: HashSet Text
3234
, compilerVersion :: Text
3335
, compilerPackages :: HashMap Text (Maybe Version)
3436
} deriving (Show)

0 commit comments

Comments
 (0)