-
Notifications
You must be signed in to change notification settings - Fork 35
Expand file tree
/
Copy pathflake.nix
More file actions
440 lines (360 loc) · 12.8 KB
/
flake.nix
File metadata and controls
440 lines (360 loc) · 12.8 KB
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
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
{
description = "DFeed - D news aggregator, newsgroup client, web newsreader and IRC bot";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
flake-utils.url = "github:numtide/flake-utils";
self.submodules = true;
};
outputs = { self, nixpkgs, flake-utils }:
flake-utils.lib.eachDefaultSystem (system:
let
pkgs = nixpkgs.legacyPackages.${system};
# Helper to download compressors (for minification)
htmlcompressor = pkgs.fetchurl {
url = "https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/htmlcompressor/htmlcompressor-1.5.3.jar";
sha256 = "1ydh1hqndnvw0d8kws5339mj6qn2yhjd8djih27423nv1hrlx2c8";
};
yuicompressor = pkgs.fetchurl {
url = "https://github.com/yui/yuicompressor/releases/download/v2.4.8/yuicompressor-2.4.8.jar";
sha256 = "1qjxlak9hbl9zd3dl5ks0w4zx5z64wjsbk7ic73r1r45fasisdrh";
};
# Filter source to only include files needed for D build
dfeedSrc = pkgs.lib.cleanSourceWith {
src = self;
filter = path: type:
let
baseName = baseNameOf path;
relPath = pkgs.lib.removePrefix (toString self + "/") (toString path);
in
# Include D source directories
pkgs.lib.hasPrefix "src/" relPath ||
pkgs.lib.hasPrefix "lib/" relPath ||
# Include root-level build files
baseName == "dub.sdl" ||
baseName == "dub.selections.json" ||
# Allow traversing directories
type == "directory";
};
# Shared test configuration generation
generateTestConfig = ''
# Create test environment
mkdir -p site/config/apis data/db
# Create minimal site.ini
cat > site/config/site.ini << 'SITEINI'
name = DFeed Test Instance
host = localhost
proto = http
SITEINI
# Create web.ini with test port
cat > site/config/web.ini << 'WEBINI'
[listen]
port = 8080
WEBINI
# Disable StopForumSpam in sandbox (no network access)
cat > site/config/apis/stopforumspam.ini << 'SPAMINI'
enabled = false
SPAMINI
# Configure user authentication with a test salt
cat > site/config/user.ini << 'USERINI'
salt = test-salt-for-playwright-tests-only
USERINI
# Configure test group with dummy captcha and disabled rate limiting for testing
cat > site/config/groups.ini << 'GROUPSINI'
[sets.test]
name=Test
shortName=Test
visible=true
[groups.test]
internalName=test
publicName=Test Forum
navName=Test
urlName=test
groupSet=test
description=A test forum for trying out posting
sinkType=local
announce=false
captcha=dummy
postThrottleRejectCount=0
postThrottleCaptchaCount=0
GROUPSINI
# Database is automatically created and migrated by dfeed
'';
# Shared server startup/shutdown logic
startServer = ''
# Start dfeed server in background
${self.packages.${system}.default}/bin/dfeed --no-sources &
DFEED_PID=$!
# Wait for server to be ready (up to 30 seconds)
echo "Waiting for DFeed server to start..."
for i in $(seq 1 30); do
if curl -s http://localhost:8080/ > /dev/null 2>&1; then
echo "Server is ready!"
break
fi
if ! kill -0 $DFEED_PID 2>/dev/null; then
echo "Server process died unexpectedly"
exit 1
fi
sleep 1
done
# Verify server is actually responding
if ! curl -s http://localhost:8080/ > /dev/null 2>&1; then
echo "Server failed to start within 30 seconds"
kill $DFEED_PID 2>/dev/null || true
exit 1
fi
'';
stopServer = ''
# Stop server
kill $DFEED_PID 2>/dev/null || true
wait $DFEED_PID 2>/dev/null || true
'';
# Reference site-defaults separately (not part of D source)
siteDefaultsSrc = "${self}/site-defaults";
in
{
packages.default = pkgs.stdenv.mkDerivation {
pname = "dfeed";
version = "unstable";
src = dfeedSrc;
# Don't strip debug symbols (we build with -g)
dontStrip = true;
nativeBuildInputs = with pkgs; [
dmd
dtools # Provides rdmd
jre_minimal # For htmlcompressor and yuicompressor
git
which
];
buildInputs = with pkgs; [
curl
sqlite
openssl
];
# Setup build environment
preConfigure = ''
# Make compressors available
cp ${htmlcompressor} htmlcompressor-1.5.3.jar
cp ${yuicompressor} yuicompressor-2.4.8.jar
# Copy site-defaults for minification (not part of D source)
cp -r ${siteDefaultsSrc} site-defaults
chmod -R u+w site-defaults
'';
buildPhase = ''
runHook preBuild
# Set rdmd to use dmd by default
export DCOMPILER=dmd
# Detect OpenSSL version
if [ -f lib/deimos-openssl/scripts/generate_version.d ]; then
echo "Generating OpenSSL version detection..."
rdmd --compiler=dmd lib/deimos-openssl/scripts/generate_version.d
fi
# Set up D compiler flags
flags=(
-m64
-g
-Isrc
-Ilib
-L-lcurl
-L-lsqlite3
-L-lssl
-L-lcrypto
)
# Add version flag for OpenSSL auto-detection
if [ -f lib/deimos-openssl/scripts/generate_version.d ]; then
flags+=(-version=DeimosOpenSSLAutoDetect)
fi
# Build all programs
for fn in src/dfeed/progs/*.d; do
name=$(basename "$fn" .d)
echo "Building $name..."
rdmd --compiler=dmd --build-only -of"$name" "''${flags[@]}" "$fn"
done
# Minify site-defaults resources (if not already minified)
HTMLTOOL="java -jar htmlcompressor-1.5.3.jar --compress-css"
JSTOOL="java -jar yuicompressor-2.4.8.jar --type js"
CSSTOOL="java -jar yuicompressor-2.4.8.jar --type css"
for htt in site-defaults/web/*.htt; do
min="''${htt%.htt}.min.htt"
if [ ! -f "$min" ] || [ "$htt" -nt "$min" ]; then
echo "Minifying $htt..."
$HTMLTOOL < "$htt" > "$min" || cp "$htt" "$min"
fi
done
for css in site-defaults/web/static/css/*.css; do
[[ "$css" == *.min.css ]] && continue
min="''${css%.css}.min.css"
if [ ! -f "$min" ] || [ "$css" -nt "$min" ]; then
echo "Minifying $css..."
$CSSTOOL < "$css" > "$min" || cp "$css" "$min"
fi
done
for js in site-defaults/web/static/js/*.js; do
[[ "$js" == *.min.js ]] && continue
min="''${js%.js}.min.js"
if [ ! -f "$min" ] || [ "$js" -nt "$min" ]; then
echo "Minifying $js..."
$JSTOOL < "$js" > "$min" || cp "$js" "$min"
fi
done
runHook postBuild
'';
installPhase = ''
runHook preInstall
mkdir -p $out/bin
mkdir -p $out/share/dfeed
# Install binaries
for prog in dfeed nntpdownload sendspamfeedback unban; do
if [ -f "$prog" ]; then
install -Dm755 "$prog" $out/bin/"$prog"
fi
done
# Install site-defaults (generic resources)
cp -r site-defaults $out/share/dfeed/
runHook postInstall
'';
meta = with pkgs.lib; {
description = "D news aggregator, newsgroup client, web newsreader and IRC bot";
homepage = "https://github.com/CyberShadow/DFeed";
license = licenses.agpl3Plus;
platforms = platforms.linux;
maintainers = [ ];
};
};
# Generate screenshots from Playwright tests
packages.screenshots = pkgs.stdenv.mkDerivation {
pname = "dfeed-screenshots";
version = "unstable";
src = self;
nativeBuildInputs = with pkgs; [
playwright-test
curl
sqlite
# Fonts for proper rendering in screenshots
liberation_ttf
dejavu_fonts
freefont_ttf
];
HOME = "/tmp/playwright-home";
FONTCONFIG_FILE = pkgs.makeFontsConf {
fontDirectories = with pkgs; [
liberation_ttf
dejavu_fonts
freefont_ttf
];
};
buildPhase = ''
runHook preBuild
${generateTestConfig}
${startServer}
cd tests
playwright test --project=screenshots --reporter=list || true
cd ..
${stopServer}
runHook postBuild
'';
installPhase = ''
mkdir -p $out
cp tests/screenshot-*.png $out/ 2>/dev/null || echo "No screenshots found"
ls -la $out/
'';
};
# Development shell for working on the project
devShells.default = pkgs.mkShell {
buildInputs = with pkgs; [
dmd
dtools
dub
curl
sqlite
openssl
jre_minimal
gnumake
git
];
shellHook = ''
echo "DFeed development environment"
echo "DMD version: $(dmd --version | head -1)"
'';
};
# Checks to run with 'nix flake check'
checks = {
# Verify that the package builds successfully
build = self.packages.${system}.default;
# Run Playwright end-to-end tests
playwright = pkgs.stdenv.mkDerivation {
pname = "dfeed-playwright-tests";
version = "unstable";
src = self;
nativeBuildInputs = with pkgs; [
playwright-test
curl
sqlite
];
# Playwright needs writable home for cache
HOME = "/tmp/playwright-home";
buildPhase = ''
runHook preBuild
${generateTestConfig}
${startServer}
# Run Playwright tests
cd tests
playwright test --project=default --reporter=list || TEST_RESULT=$?
cd ..
${stopServer}
# Check test result
if [ "''${TEST_RESULT:-0}" != "0" ]; then
echo "Playwright tests failed"
exit 1
fi
runHook postBuild
'';
installPhase = ''
mkdir -p $out
echo "Playwright tests passed" > $out/result
'';
};
# Run D unittests
unittests = pkgs.stdenv.mkDerivation {
pname = "dfeed-unittests";
version = "unstable";
src = self;
nativeBuildInputs = with pkgs; [
dmd
dtools
];
buildInputs = with pkgs; [
curl
sqlite
openssl
];
buildPhase = ''
runHook preBuild
export DCOMPILER=dmd
# Detect OpenSSL version
if [ -f lib/deimos-openssl/scripts/generate_version.d ]; then
echo "Generating OpenSSL version detection..."
rdmd --compiler=dmd lib/deimos-openssl/scripts/generate_version.d
fi
# Compile library with unittests
echo "Compiling and running unittests..."
dmd -unittest -main -i -Isrc -Ilib -L-lcurl -L-lsqlite3 -L-lssl -L-lcrypto \
$(find src -name "*.d" | grep -v "src/dfeed/progs/") \
-version=DeimosOpenSSLAutoDetect \
-od=unittest-obj -of=unittest-runner
runHook postBuild
'';
checkPhase = ''
echo "Running unittests..."
./unittest-runner
'';
installPhase = ''
mkdir -p $out
echo "Unittests passed" > $out/result
'';
doCheck = true;
};
};
}
);
}