2
2
lib ,
3
3
lib' ,
4
4
options ,
5
+ nixpkgs ,
5
6
pkgs ,
6
7
projects ,
7
8
self ,
9
+ system ,
8
10
} :
9
11
let
10
12
inherit ( builtins )
14
16
concatStringsSep
15
17
filter
16
18
isList
19
+ isInt
17
20
readFile
18
21
substring
19
22
toJSON
30
33
mapAttrsToList
31
34
optionalString
32
35
recursiveUpdate
36
+ filterAttrs
33
37
mapAttrs'
34
38
nameValuePair
35
39
take
36
40
drop
41
+ splitString
42
+ intersperse
37
43
;
38
44
39
45
empty =
40
46
xs :
41
47
assert isList xs ;
42
48
xs == [ ] ;
43
- heading = i : text : "<h${ toString i } >${ text } </h${ toString i } >" ;
49
+ heading =
50
+ i : anchor : text :
51
+ assert ( isInt i && i > 0 ) ;
52
+ if i == 1 then
53
+ ''
54
+ <h1>${ text } </h1>
55
+ ''
56
+ else
57
+ ''
58
+ <a class="heading" href="#${ anchor } ">
59
+ <h${ toString i } data-url="#${ anchor } ">
60
+ ${ text }
61
+ <span class="anchor"/>
62
+ </h${ toString i } >
63
+ </a>
64
+ '' ;
44
65
45
66
# Splits a compressed date up into ISO 8601
46
67
lastModified =
71
92
) ;
72
93
in
73
94
filter ( option : any ( ( flip hasPrefix ) ( join "." option . loc ) ) spec ) ( attrValues options ) ;
74
- examples = project : attrValues project . nixos . examples ;
95
+ examples = project : attrValues ( filterAttrs ( name : _ : name != "demo" ) project . nixos . examples ) ;
75
96
} ;
76
97
77
98
# This doesn't actually produce a HTML string but a Jinja2 template string
@@ -116,28 +137,26 @@ let
116
137
prefixLength = 2 ;
117
138
in
118
139
optionalString ( ! empty projectOptions ) ''
119
- <section><details><summary>${ heading 3 "Options" } </summary><dl>
140
+ ${ heading 2 "options" "Options" }
141
+ <section><details><summary><code>services.cryptpad</code></summary><dl>
120
142
${ concatLines ( map ( one prefixLength ) projectOptions ) }
121
143
</dl></details></section>
122
144
'' ;
123
145
} ;
124
146
125
147
examples = rec {
126
148
one = example : ''
127
- <li >
149
+ <section><details><summary> ${ example . description } </summary >
128
150
129
- ${ example . description }
151
+ {{ include_code("nix", " ${ example . module } ")} }
130
152
131
- <pre><code>${ readFile example . module } </code></pre>
132
-
133
- </li>
153
+ </details></section>
134
154
'' ;
135
155
many =
136
156
examples :
137
157
optionalString ( ! empty examples ) ''
138
- <section><details><summary> ${ heading 3 " Examples"} </summary><ul>
158
+ ${ heading 2 "examples" " Examples"}
139
159
${ concatLines ( map one examples ) }
140
- </ul></details></section>
141
160
'' ;
142
161
} ;
143
162
176
195
# The indivdual page of a project
177
196
projects . one = name : project : ''
178
197
<article class="page-width">
179
- ${ heading 1 name }
198
+ ${ heading 1 null name }
180
199
${ render . metadata . one project . metadata }
200
+ ${ optionalString ( project . nixos . examples ? demo ) (
201
+ render . serviceDemo . one project . nixos . modules . services project . nixos . examples . demo
202
+ ) }
181
203
${ render . options . many ( pick . options project ) }
182
204
${ render . examples . many ( pick . examples project ) }
183
205
</article>
@@ -221,12 +243,56 @@ let
221
243
'' ;
222
244
many = projects : concatLines ( mapAttrsToList one projects ) ;
223
245
} ;
246
+
247
+ demoGlue . one = exampleText : ''
248
+ # default.nix
249
+ {
250
+ ngipkgs ? import (fetchTarball "https://github.com/ngi-nix/ngipkgs/tarball/main") { },
251
+ }:
252
+ ngipkgs.demo (
253
+ ${ toString ( intersperse "\n " ( splitString "\n " exampleText ) ) }
254
+ )
255
+ '' ;
256
+
257
+ serviceDemo . one =
258
+ services : example :
259
+ let
260
+ demoSystem = import ( nixpkgs + "/nixos/lib/eval-config.nix" ) {
261
+ inherit system ;
262
+ modules = ( attrValues services ) ++ [ example . module ] ;
263
+ } ;
264
+ openPorts = demoSystem . config . networking . firewall . allowedTCPPorts ;
265
+ # The port that is forwarded to the host so that the user can access the demo service.
266
+ servicePort = ( builtins . head openPorts ) + 10000 ;
267
+ in
268
+ ''
269
+ ${ heading 2 "demo" "Run a demo deployment locally" }
270
+
271
+ <ol>
272
+ <li><strong>Install Nix on your platform.</strong></li>
273
+ <li>
274
+ <strong>Download this Nix file to your computer.</strong>
275
+ It obtains the NGIpkgs source code and declares a basic service configuration
276
+ to be run in a virtual machine.
277
+ {{ include_code("nix", "default.nix", relative_path=True) }}
278
+ </li>
279
+ <li>
280
+ <strong>Build the virtual machine</strong> defined in <code>default.nix</code> and run it:
281
+ <pre><code>nix-build && ./result</code></pre>
282
+ Building <strong>will</strong> take a while.
283
+ </li>
284
+ <li>
285
+ <strong>Access the service</strong> with a web browser:
286
+ <a href="http://localhost:${ toString servicePort } ">http://localhost:${ toString servicePort } </a>
287
+ </li>
288
+ </ol>
289
+ '' ;
224
290
} ;
225
291
226
292
# The top-level overview for all projects
227
293
index = ''
228
294
<section class="page-width">
229
- ${ heading 1 "NGIpkgs" }
295
+ ${ heading 1 null "NGIpkgs" }
230
296
231
297
<p>
232
298
NGIpkgs is collection of software applications funded by the <a href="https://www.ngi.eu/ngi-projects/ngi-zero/">Next Generation Internet</a> initiative and packaged for <a href="https://nixos.org">NixOS</a>.
@@ -267,26 +333,30 @@ let
267
333
<footer>Version: ${ version } , Last Modified: ${ lastModified } </footer>
268
334
'' ;
269
335
270
- # Every HTML page that we generate
271
- pages =
272
- {
273
- "index.html" = {
274
- pagetitle = "NGIpkgs software repository" ;
275
- content = index ;
276
- summary = ''
277
- NGIpkgs is collection of software applications funded by the Next
278
- Generation Internet initiative and packaged for NixOS.
279
- '' ;
280
- } ;
336
+ # HTML project pages
337
+ projectPages = mapAttrs' (
338
+ name : project :
339
+ nameValuePair "project/${ name } " {
340
+ pagetitle = "NGIpkgs | ${ name } " ;
341
+ content = render . projects . one name project ;
342
+ summary = project . metadata . summary or null ;
343
+ demoFile =
344
+ if project . nixos . examples ? demo then
345
+ ( pkgs . writeText "default.nix" ( render . demoGlue . one ( readFile project . nixos . examples . demo . module ) ) )
346
+ else
347
+ null ;
281
348
}
282
- // mapAttrs' (
283
- name : project :
284
- nameValuePair "project/${ name } /index.html" {
285
- pagetitle = "NGIpkgs | ${ name } " ;
286
- content = render . projects . one name project ;
287
- summary = project . metadata . summary or null ;
288
- }
289
- ) projects ;
349
+ ) projects ;
350
+
351
+ # The summary page at the overview root
352
+ indexPage = {
353
+ pagetitle = "NGIpkgs software repository" ;
354
+ content = index ;
355
+ summary = ''
356
+ NGIpkgs is collection of software applications funded by the Next
357
+ Generation Internet initiative and packaged for NixOS.
358
+ '' ;
359
+ } ;
290
360
291
361
htmlFile =
292
362
path :
@@ -313,10 +383,19 @@ let
313
383
'' ;
314
384
315
385
# Ensure that directories exist and render the jinja2 template that we composed with Nix so far
316
- writeHtmlCommand = path : htmlFile : ''
317
- mkdir -p "$out/$(dirname '${ path } ')"
318
- python3 ${ ./render-template.py } '${ htmlFile } ' "$out/${ path } "
319
- '' ;
386
+ writeProjectCommand =
387
+ path : page :
388
+ ''
389
+ mkdir -p "$out/${ path } "
390
+ ''
391
+ + optionalString ( page . demoFile != null ) ''
392
+ cp '${ page . demoFile } ' "$out/${ path } /default.nix"
393
+ chmod +w "$out/${ path } /default.nix"
394
+ nixfmt "$out/${ path } /default.nix"
395
+ ''
396
+ + ''
397
+ python3 ${ ./render-template.py } '${ htmlFile path page } ' "$out/${ path } /index.html"
398
+ '' ;
320
399
321
400
fonts =
322
401
pkgs . runCommand "fonts"
331
410
done
332
411
'' ;
333
412
413
+ highlightingCss =
414
+ pkgs . runCommand "pygments-css-rules.css" { nativeBuildInputs = [ pkgs . python3Packages . pygments ] ; }
415
+ ''
416
+ pygmentize -S default -f html -a .code > $out
417
+ '' ;
418
+
334
419
in
335
420
pkgs . runCommand "overview"
336
421
{
@@ -341,17 +426,20 @@ pkgs.runCommand "overview"
341
426
ps : with ps ; [
342
427
jinja2
343
428
markdown-it-py
429
+ pygments
344
430
]
345
431
) )
432
+ nixfmt-rfc-style
346
433
] ;
347
434
}
348
435
(
349
436
''
350
437
mkdir -pv $out
351
- cp -v ${ ./style.css } $out/style.css
438
+ cat ${ ./style.css } ${ highlightingCss } > $out/style.css
352
439
ln -s ${ fonts } $out/fonts
440
+ python3 ${ ./render-template.py } '${ htmlFile "" indexPage } ' "$out/index.html"
353
441
''
354
- + ( concatLines ( mapAttrsToList ( path : v : writeHtmlCommand path ( htmlFile path v ) ) pages ) )
442
+ + ( concatLines ( mapAttrsToList ( path : page : writeProjectCommand path page ) projectPages ) )
355
443
+ ''
356
444
357
445
vnu -Werror --format json $out/*.html | jq
0 commit comments