-
Notifications
You must be signed in to change notification settings - Fork 1
/
flake.nix
247 lines (226 loc) · 9.37 KB
/
flake.nix
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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
{
description = "purescript-cip30-typesafe";
# Allow IFD in `nix flake check`.
nixConfig.allow-import-from-derivation = "true";
nixConfig = {
extra-substituters = [ "https://plutonomicon.cachix.org" ];
extra-trusted-public-keys = [ "plutonomicon.cachix.org-1:evUxtNULjCjOipxwAnYhNFeF/lyYU1FeNGaVAnm+QQw=" ];
bash-prompt = "\\[\\e[0m\\][\\[\\e[0;2m\\]nix-develop \\[\\e[0;1m\\]ps-cip30-typesafe@\\[\\033[33m\\]$(git rev-parse --abbrev-ref HEAD) \\[\\e[0;32m\\]\\w\\[\\e[0m\\]]\\[\\e[0m\\]$ \\[\\e[0m\\]";
};
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
flake-parts.url = github:hercules-ci/flake-parts;
hercules-ci-effects.url = github:hercules-ci/hercules-ci-effects;
easy-purescript-nix = {
url = "github:justinwoo/easy-purescript-nix";
flake = false;
};
};
outputs = inputs @ { self, flake-parts, hercules-ci-effects, ... }:
flake-parts.lib.mkFlake { inherit inputs; } ({ ... }: {
imports = [
# Hercules CI effects module used to deploy to GitHub Pages
hercules-ci-effects.flakeModule
];
# Systems supported by this flake
systems = [ "x86_64-linux" "aarch64-linux" "x86_64-darwin" "aarch64-darwin" ];
perSystem = { self', pkgs, system, ... }:
let
easy-ps = (import inputs.easy-purescript-nix { inherit pkgs; });
spagoPkgs = import ./spago-packages.nix { inherit pkgs; };
# building/testing machinery is taken from cardano-transaction-lib.
# TODO: migrate it to a separate repo
# Compiles the dependencies of a Purescript project and copies the `output`
# and `.spago` directories into the Nix store.
# Intended to be used in `buildPursProject` to not recompile the entire
# package set every time.
buildPursDependencies =
{
# If warnings generated from project source files will trigger a build error.
# Controls `--strict` purescript-psa flag
strictComp ? true
# Warnings from `purs` to silence during compilation, independent of `strictComp`
# Controls `--censor-codes` purescript-psa flag
, censorCodes ? [ "UserDefinedWarning" ]
, ...
}:
pkgs.stdenv.mkDerivation {
name = "ps-deps";
buildInputs = [
];
nativeBuildInputs = [
spagoPkgs.installSpagoStyle
easy-ps.psa
easy-ps.purs
easy-ps.spago
];
# Make the derivation independent of the source files.
# `src` is not needed
unpackPhase = "true";
buildPhase = ''
install-spago-style
psa ${pkgs.lib.optionalString strictComp "--strict" } \
--censor-lib \
--is-lib=.spago ".spago/*/*/src/**/*.purs" \
--censor-codes=${builtins.concatStringsSep "," censorCodes} \
-gsourcemaps,js
'';
installPhase = ''
mkdir $out
mv output $out/
mv .spago $out/
'';
};
# Compiles your Purescript project and copies the `output` directory into the
# Nix store. Also copies the local sources to be made available later as `purs`
# does not include any external files to its `output` (if we attempted to refer
# to absolute paths from the project-wide `src` argument, they would be wrong)
buildPursProject =
{
# If warnings generated from project source files will trigger a build error.
# Controls `--strict` purescript-psa flag
strictComp ? true
# Warnings from `purs` to silence during compilation, independent of `strictComp`
# Controls `--censor-codes` purescript-psa flag
, censorCodes ? [ "UserDefinedWarning" ]
, pursDependencies ? buildPursDependencies {
inherit strictComp censorCodes;
}
, ...
}:
pkgs.stdenv.mkDerivation {
name = "ps-project";
src = ./.;
buildInputs = [
];
nativeBuildInputs = [
spagoPkgs.installSpagoStyle
easy-ps.psa
easy-ps.purs
easy-ps.spago
];
unpackPhase = ''
export HOME="$TMP"
# copy the dependency build artifacts and sources
# preserve the modification date so that we don't rebuild them
mkdir -p output .spago
cp -rp ${pursDependencies}/.spago/* .spago
cp -rp ${pursDependencies}/output/* output
# note that we copy the entire source directory, not just $src/src,
# because we need sources in ./examples and ./test
cp -rp $src ./src
# add write permissions for the PS compiler to use
# `output/cache-db.json`
chmod -R +w output/
'';
buildPhase = ''
psa ${pkgs.lib.optionalString strictComp "--strict" } \
--censor-lib \
--is-lib=.spago ".spago/*/*/src/**/*.purs" \
--censor-codes=${builtins.concatStringsSep "," censorCodes} "./src/**/*.purs" \
-gsourcemaps,js
'';
# We also need to copy all of `src` here, since compiled modules in `output`
# might refer to paths that will point to nothing if we use `src` directly
# in other derivations (e.g. when using `fs.readFileSync` inside an FFI
# module)
installPhase = ''
mkdir $out
cp -r output $out/
'';
};
# Runs a test written in Purescript using NodeJS.
runPursTest =
{
# The main Purescript module
testMain
# The entry point function in the main PureScript module
, psEntryPoint ? "main"
# Additional variables to pass to the test environment
, env ? { }
# Passed through to the `buildInputs` of the derivation. Use this to add
# additional packages to the test environment
, buildInputs ? [ ]
, builtProject ? buildPursProject { main = testMain; }
, ...
}: pkgs.runCommand "ps-test"
(
{
src = ./.;
buildInputs = [ pkgs.nodejs ];
} // env
)
''
# Copy the purescript project files
cp -r ${builtProject}/* .
# The tests may depend on sources
cp -r $src/* .
# Call the main module and execute the entry point function
node --enable-source-maps -e 'import("./output/${testMain}/index.js").then(m => m.${psEntryPoint}())'
# Create output file to tell Nix we succeeded
touch $out
'';
in
{
devShells = {
default = pkgs.mkShell {
buildInputs = with pkgs; [
nixpkgs-fmt
easy-ps.purs
easy-ps.purs-tidy
easy-ps.spago
easy-ps.pscid
easy-ps.psa
easy-ps.spago2nix
nodePackages.eslint
nodePackages.prettier
fd
git
nodejs-18_x
];
};
};
packages = {
# Example package. Build with `nix build` or `nix build .#myapp`.
default = self'.packages.myapp;
myapp = pkgs.writeShellScriptBin "myapp" ''
echo "Hello, World!"
'';
};
# Example flake checks. Run with `nix flake check --keep-going`
checks = {
tests = runPursTest { testMain = "Test.Main"; psEntryPoint = "main"; };
formatting-check = pkgs.runCommand "formatting-check"
{
nativeBuildInputs = with pkgs; [
easy-ps.purs-tidy
nixpkgs-fmt
nodePackages.prettier
nodePackages.eslint
fd
];
}
''
cd ${self}
purs-tidy check './src/**/*.purs' './test/**/*.purs'
nixpkgs-fmt --check "$(fd --no-ignore-parent -enix --exclude='spago*')"
prettier --log-level warn -c $(fd --no-ignore-parent -ejs -ecjs)
eslint --quiet $(fd --no-ignore-parent -ejs -ecjs) --parser-options 'sourceType: module'
touch $out
'';
};
};
# On CI, build only on available systems, to avoid errors about systems without agents.
# Please use aarch64-linux and x86_64-darwin sparingly as they run on smaller hardware.
herculesCI.ciSystems = [ "x86_64-linux" ];
# Schedule task to run `nix flake update`, run CI, and open a PR with changes
hercules-ci.flake-update = {
enable = true;
when = {
dayOfWeek = "Sun";
hour = 12;
minute = 45;
};
};
});
}