Skip to content

Commit 490e42e

Browse files
committed
Move builds for flake projects into a separate nix file
1 parent 786e359 commit 490e42e

File tree

10 files changed

+227
-33
lines changed

10 files changed

+227
-33
lines changed

.last-exported-commit

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
Last exported commit from parent repo: aed9d9e083b67949c214d3cba60c1615b082f9ce
1+
Last exported commit from parent repo: eb9d769ca6f914295b4bf09dcc82bc388a7f9305

nix-bootstrap.cabal

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ cabal-version: 2.0
55
-- see: https://github.com/sol/hpack
66

77
name: nix-bootstrap
8-
version: 1.3.0.4
8+
version: 1.3.1.0
99
author: gchquser
1010
maintainer: [email protected]
1111
copyright: Crown Copyright
@@ -24,6 +24,7 @@ library
2424
Bootstrap.Cli
2525
Bootstrap.Data.Bootstrappable
2626
Bootstrap.Data.Bootstrappable.BootstrapState
27+
Bootstrap.Data.Bootstrappable.BuildNix
2728
Bootstrap.Data.Bootstrappable.DefaultNix
2829
Bootstrap.Data.Bootstrappable.DevContainer
2930
Bootstrap.Data.Bootstrappable.Envrc
@@ -147,6 +148,7 @@ test-suite nix-bootstrap-test
147148
main-is: Spec.hs
148149
other-modules:
149150
Bootstrap.Data.Bootstrappable.BootstrapStateSpec
151+
Bootstrap.Data.Bootstrappable.BuildNixSpec
150152
Bootstrap.Data.Bootstrappable.DefaultNixSpec
151153
Bootstrap.Data.Bootstrappable.DevContainerSpec
152154
Bootstrap.Data.Bootstrappable.EnvrcSpec

package.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414
name: nix-bootstrap
15-
version: 1.3.0.4
15+
version: 1.3.1.0
1616
author: gchquser
1717
maintainer: [email protected]
1818
copyright: Crown Copyright

src/Bootstrap.hs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import Bootstrap.Cli
1515
import Bootstrap.Data.Bootstrappable
1616
( Bootstrappable (bootstrapName),
1717
)
18+
import Bootstrap.Data.Bootstrappable.BuildNix (buildNixFor)
1819
import Bootstrap.Data.Bootstrappable.DefaultNix (defaultNixFor)
1920
import Bootstrap.Data.Bootstrappable.DevContainer
2021
( devContainerDockerComposeFor,
@@ -395,6 +396,7 @@ makeBuildPlan MakeBuildPlanArgs {..} = do
395396
if unPreCommitHooksConfig mbpPreCommitHooksConfig
396397
then Just $ nixPreCommitHookConfigFor mbpRunConfig mbpProjectType
397398
else Nothing
399+
buildNix = buildNixFor mbpRunConfig mbpProjectName mbpProjectType
398400
goModfile <-
399401
case mbpProjectType of
400402
Go (SetUpGoBuild True) ->
@@ -411,7 +413,8 @@ makeBuildPlan MakeBuildPlanArgs {..} = do
411413
~: Envrc mbpPreCommitHooksConfig (rcUseFlakes mbpRunConfig)
412414
~: gitignoreFor mbpRunConfig mbpProjectType mbpPreCommitHooksConfig
413415
~: initialReadme
414-
~: flakeNixFor mbpRunConfig mbpProjectName mbpProjectType mbpPreCommitHooksConfig nixPreCommitHookConfig
416+
~: buildNix
417+
~: flakeNixFor mbpRunConfig mbpProjectName mbpProjectType mbpPreCommitHooksConfig nixPreCommitHookConfig buildNix
415418
~: ( if rcUseFlakes mbpRunConfig
416419
then Nothing
417420
else Just $ nixShellFor mbpRunConfig mbpProjectType mbpPreCommitHooksConfig nixPreCommitHookConfig

src/Bootstrap/Data/Bootstrappable.hs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,15 @@ bootstrapContentNix a = do
6464
<$> writeExprFormatted expr
6565
Left (i1 :| iRest) ->
6666
pure . Left $
67-
"Nix expression is incorrectly scoped; it references the out of scope identifiers "
68-
<> toString (foldr (\i acc -> unIdentifier i <> ", " <> acc) ("and " <> unIdentifier i1) iRest)
67+
"Nix expression is incorrectly scoped; it references the out of scope "
68+
<> ( if null iRest
69+
then "identifier " <> toString (unIdentifier i1)
70+
else
71+
"identifiers "
72+
<> toString
73+
( foldr (\i acc -> unIdentifier i <> ", " <> acc) ("and " <> unIdentifier i1) iRest
74+
)
75+
)
6976
<> ". This is a bug in nix-bootstrap; please "
7077
<> "contact the nix-bootstrap team to report it."
7178

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
{-# LANGUAGE QuasiQuotes #-}
2+
3+
-- |
4+
-- Copyright : (c) Crown Copyright GCHQ
5+
-- Description : The code for build.nix
6+
module Bootstrap.Data.Bootstrappable.BuildNix (BuildNix, buildNixFor) where
7+
8+
import Bootstrap.Cli (RunConfig (RunConfig, rcUseFlakes))
9+
import Bootstrap.Data.Bootstrappable
10+
( Bootstrappable (bootstrapContent, bootstrapName, bootstrapReason),
11+
bootstrapContentNix,
12+
)
13+
import Bootstrap.Data.Bootstrappable.DefaultNix
14+
( DefaultNix (defaultNixInBlockExpr),
15+
defaultNixFor,
16+
)
17+
import Bootstrap.Data.ProjectName (ProjectName)
18+
import Bootstrap.Data.ProjectType (ProjectType)
19+
import Bootstrap.Nix.Expr (Expr (EFunc), IsNixExpr (toNixExpr), nixargs)
20+
21+
-- | A separate nix file defining reproducible builds for flake projects,
22+
-- to save it all being kept in flake.nix
23+
newtype BuildNix = BuildNix {unBuildNix :: Expr}
24+
deriving stock (Eq, Show)
25+
26+
instance Bootstrappable BuildNix where
27+
bootstrapName = const "nix/build.nix"
28+
bootstrapReason = const "This configures your reproducible project builds."
29+
bootstrapContent = bootstrapContentNix
30+
31+
instance IsNixExpr BuildNix where
32+
toNixExpr = EFunc [nixargs|{ nixpkgs }:|] . unBuildNix
33+
34+
-- | Gives a `BuildNix` (or `Nothing`) as appropriate for the project details
35+
-- given.
36+
buildNixFor :: RunConfig -> ProjectName -> ProjectType -> Maybe BuildNix
37+
buildNixFor RunConfig {rcUseFlakes} flakeNixProjectName flakeNixProjectType =
38+
let buildExpr =
39+
defaultNixInBlockExpr
40+
<$> defaultNixFor flakeNixProjectName flakeNixProjectType
41+
in if rcUseFlakes
42+
then BuildNix <$> buildExpr
43+
else Nothing

src/Bootstrap/Data/Bootstrappable/FlakeNix.hs

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import Bootstrap.Data.Bootstrappable
1313
),
1414
bootstrapContentNix,
1515
)
16-
import Bootstrap.Data.Bootstrappable.DefaultNix (DefaultNix (defaultNixInBlockExpr), defaultNixFor)
16+
import Bootstrap.Data.Bootstrappable.BuildNix (BuildNix)
1717
import Bootstrap.Data.Bootstrappable.NixPreCommitHookConfig (NixPreCommitHookConfig)
1818
import Bootstrap.Data.Bootstrappable.NixShell (NixShell (NixShell, nixShellBuildInputs, nixShellHooksRequireNixpkgs), nixShellFor)
1919
import Bootstrap.Data.PreCommitHook
@@ -26,7 +26,7 @@ import Bootstrap.Nix.Expr
2626
Expr (EGrouping, ELetIn, ELit, ESet),
2727
FunctionArgs (FASet),
2828
IsNixExpr (toNixExpr),
29-
Literal (LString),
29+
Literal (LPath, LString),
3030
nix,
3131
nixargs,
3232
nixbinding,
@@ -53,16 +53,15 @@ data FlakeNix = FlakeNix
5353
flakeNixProjectName :: ProjectName,
5454
flakeNixProjectType :: ProjectType,
5555
flakeNixBuildInputs :: [Expr],
56-
flakeNixBuildExpr :: Maybe Expr,
56+
flakeNixBuildNix :: Maybe BuildNix,
5757
-- | Used to determine whether to pass the nixpkgs argument to the pre-commit-hooks config
5858
flakeNixHooksRequireNixpkgs :: Bool
5959
}
6060

6161
instance Bootstrappable FlakeNix where
6262
bootstrapName = const "flake.nix"
63-
bootstrapReason FlakeNix {flakeNixPreCommitHooksConfig, flakeNixBuildExpr} =
63+
bootstrapReason FlakeNix {flakeNixPreCommitHooksConfig} =
6464
"This configures what tools are available in your development environment"
65-
<> maybe "" (const ", configures reproducible builds,") flakeNixBuildExpr
6665
<> if unPreCommitHooksConfig flakeNixPreCommitHooksConfig
6766
then " and links in the pre-commit hooks."
6867
else "."
@@ -74,18 +73,17 @@ flakeNixFor ::
7473
ProjectType ->
7574
PreCommitHooksConfig ->
7675
Maybe NixPreCommitHookConfig ->
76+
Maybe BuildNix ->
7777
Maybe FlakeNix
7878
flakeNixFor
7979
rc@RunConfig {rcUseFlakes}
8080
flakeNixProjectName
8181
flakeNixProjectType
8282
flakeNixPreCommitHooksConfig
83-
nixPreCommitHookConfig =
83+
nixPreCommitHookConfig
84+
flakeNixBuildNix =
8485
let NixShell {nixShellBuildInputs, nixShellHooksRequireNixpkgs} =
8586
nixShellFor rc flakeNixProjectType flakeNixPreCommitHooksConfig nixPreCommitHookConfig
86-
flakeNixBuildExpr =
87-
defaultNixInBlockExpr
88-
<$> defaultNixFor flakeNixProjectName flakeNixProjectType
8987
in if rcUseFlakes
9088
then
9189
Just
@@ -158,10 +156,14 @@ instance IsNixExpr FlakeNix where
158156
bisProjectType = flakeNixProjectType
159157
}
160158
]
161-
<> case flakeNixBuildExpr of
162-
Just buildExpr ->
159+
<> case flakeNixBuildNix of
160+
Just buildNix ->
163161
[ [nixbinding|defaultPackage = self.packages.${system}.default;|],
164-
[nixproperty|packages.default|] |= buildExpr
162+
[nixproperty|packages.default|]
163+
|= ( [nix|import|]
164+
|* ELit (LPath . toText $ bootstrapName buildNix)
165+
|* [nix|{ inherit nixpkgs; }|]
166+
)
165167
]
166168
<> (if usingHooks then runChecksDerivation else [])
167169
Nothing -> if usingHooks then runChecksDerivation else []
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
{-# LANGUAGE QuasiQuotes #-}
2+
{-# OPTIONS_GHC -Wno-missing-import-lists #-}
3+
4+
-- | Copyright : (c) Crown Copyright GCHQ
5+
module Bootstrap.Data.Bootstrappable.BuildNixSpec (spec) where
6+
7+
import Bootstrap.Data.Bootstrappable (Bootstrappable (bootstrapContent))
8+
import Bootstrap.Data.Bootstrappable.BuildNix (buildNixFor)
9+
import Bootstrap.Data.ProjectName (ProjectName, mkProjectName)
10+
import Bootstrap.Data.ProjectType
11+
( ArtefactId (ArtefactId),
12+
InstallLombok (InstallLombok),
13+
InstallMinishift (InstallMinishift),
14+
JavaOptions (JavaOptions),
15+
ProjectType (Go, Java),
16+
SetUpGoBuild (SetUpGoBuild),
17+
SetUpJavaBuild (SetUpJavaBuild),
18+
)
19+
import qualified Relude.Unsafe as Unsafe
20+
import Test.Hspec (Spec, describe, it)
21+
import Test.Hspec.Expectations.Pretty (shouldBe)
22+
import Test.Util.RunConfig (rcDefault, rcWithFlakes)
23+
import Text.RawString.QQ (r)
24+
25+
spec :: Spec
26+
spec = describe "build.nix rendering" do
27+
it "renders nothing for a non-flake project" do
28+
buildNixFor rcDefault projectName (Go $ SetUpGoBuild True)
29+
`shouldBe` Nothing
30+
it "renders correctly for a Go project" do
31+
case buildNixFor rcWithFlakes projectName (Go $ SetUpGoBuild True) of
32+
Just buildNix ->
33+
bootstrapContent buildNix
34+
>>= ( `shouldBe`
35+
Right
36+
[r|{nixpkgs}:
37+
nixpkgs.buildGoModule {
38+
pname = "test-project";
39+
version = "0.1.0";
40+
src = ./.;
41+
vendorSha256 = null;
42+
# Swap out the line above for the one below once you start adding dependencies.
43+
# After your dependencies change, builds will fail until you update the hash below.
44+
# When the build fails, it will tell you what the expected hash is.
45+
# vendorSha256 = "sha256-00000000000000000000000000000000000000000000";
46+
}
47+
|]
48+
)
49+
Nothing -> fail "Gave nothing for a project which should've had a build.nix generated."
50+
51+
it "renders correctly for a Java project" do
52+
case buildNixFor
53+
rcWithFlakes
54+
projectName
55+
( Java $
56+
JavaOptions
57+
(InstallMinishift True)
58+
(InstallLombok True)
59+
(SetUpJavaBuild $ ArtefactId "testId")
60+
) of
61+
Just buildNix ->
62+
bootstrapContent buildNix
63+
>>= ( `shouldBe`
64+
Right
65+
[r|{nixpkgs}: let
66+
projectName = "test-project";
67+
artefactId = "testId";
68+
repository = nixpkgs.stdenv.mkDerivation {
69+
name = "${projectName}-repository";
70+
buildInputs = [nixpkgs.maven];
71+
src = ./.;
72+
buildPhase = "mvn package -Dmaven.repo.local=$out";
73+
# keep only *.{pom,jar,sha1,nbm} and delete all ephemeral files with lastModified timestamps inside
74+
installPhase = ''
75+
find $out -type f \
76+
-name \*.lastUpdated -or \
77+
-name resolver-status.properties -or \
78+
-name _remote.repositories \
79+
-delete
80+
'';
81+
dontFixup = true;
82+
outputHashAlgo = "sha256";
83+
outputHashMode = "recursive";
84+
# This hash will need updating when changing your dependencies; the correct
85+
# hash will be displayed when the build fails if so.
86+
outputHash = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=";
87+
};
88+
builtJar = nixpkgs.stdenv.mkDerivation rec {
89+
pname = projectName;
90+
version = "0.0.1-SNAPSHOT";
91+
src = ./.;
92+
buildInputs = [nixpkgs.maven];
93+
buildPhase = ''
94+
echo "Using repository ${repository}"
95+
mvn --offline -Dmaven.repo.local=${repository} package;
96+
'';
97+
installPhase = ''
98+
install -Dm644 target/${artefactId}-${version}.jar $out/${projectName}
99+
'';
100+
};
101+
fromImage = nixpkgs.dockerTools.pullImage {
102+
imageName = "eclipse-temurin";
103+
imageDigest = "sha256:4cc7dfdfb7837f35c3820bcfbc5f666521364e2198960322848ab7d3e2ca3e88";
104+
finalImageName = "eclipse-temurin";
105+
finalImageTag = "17.0.4.1_1-jre";
106+
sha256 = "sha256-OIib6PQJc1xX+Xu2xtaFEo/jZtxypkg8Y9RFMcJf39w=";
107+
};
108+
in
109+
nixpkgs.dockerTools.buildLayeredImage {
110+
inherit fromImage;
111+
name = projectName;
112+
enableFakechroot = true;
113+
fakeRootCommands = ''
114+
cp ${builtJar}/${projectName} /${projectName}
115+
chown root:root /${projectName}
116+
chmod 774 /${projectName}
117+
'';
118+
config = {
119+
Entrypoint = [
120+
"/bin/sh"
121+
"-c"
122+
"java $JAVA_OPTS -jar /${projectName}"
123+
];
124+
};
125+
}
126+
|]
127+
)
128+
Nothing -> fail "Gave nothing for a project which should've had a build.nix generated."
129+
130+
projectName :: ProjectName
131+
projectName = Unsafe.fromJust (mkProjectName "test-project")

0 commit comments

Comments
 (0)