Modular, context-aware and aspect-oriented dendritic Nix configurations. Discussions: https://oeiuwq.zulipchat.com/join/nqp26cd4kngon6mo3ncgnuap/ den.oeiuwq.com
configurations den dendritic nix aspect oriented
8
fork

Configure Feed

Select the types of activity you want to include in your feed.

fix: preserve unresolvable includes in applyDeep (#463)

## Summary
- `applyDeep` eagerly replaced sub-aspect includes it couldn't resolve
with the current context (`{host,user}`) with `{}`, destroying
parametric includes like `den._.unfree` that need `{class,
aspect-chain}`
- Preserve the original include when `applyDeep` returns `{}` so the
statics path can resolve it with the correct context

## Test plan
- [x] `deadbugs-issue-460` tests: parametric wrapper around unfree calls
on both fx and legacy pipelines
- [x] Full CI suite passes (491/491)

Fixes #460

authored by

Jason Bowman and committed by
GitHub
68f9acc5 6310761f

+121 -1
+12 -1
nix/lib/parametric.nix
··· 74 74 if canTake.upTo ctx sub then 75 75 carryMeta sub (take.upTo sub ctx) 76 76 else if builtins.isAttrs sub && sub ? __functor && sub ? includes then 77 - sub // { includes = map (applyDeep takeFn ctx) (sub.includes or [ ]); } 77 + sub 78 + // { 79 + includes = map ( 80 + i: 81 + let 82 + r = applyDeep takeFn ctx i; 83 + in 84 + # Preserve includes that applyDeep couldn't resolve (wrong context). 85 + # They'll be resolved later by the statics path with { class, aspect-chain }. 86 + if r == { } then i else r 87 + ) (sub.includes or [ ]); 88 + } 78 89 else 79 90 sub 80 91 ) rRaw.includes;
+109
templates/ci/modules/features/deadbugs/issue-460-parametric-dedup.nix
··· 1 + # Issue #460: Parametric aspects with non-context args (like unfree) were 2 + # silently dropped when included via a parametric wrapper function. 3 + # 4 + # Root cause: applyDeep eagerly replaced includes it couldn't resolve with 5 + # the current context ({host,user}) with {}, destroying them before the 6 + # statics path could resolve them with {class, aspect-chain}. 7 + { denTest, ... }: 8 + { 9 + flake.tests.deadbugs-issue-460 = { 10 + 11 + # Baseline: static includes work (never broken). 12 + test-unfree-static-includes = denTest ( 13 + { 14 + den, 15 + lib, 16 + tuxHm, 17 + ... 18 + }: 19 + { 20 + den.hosts.x86_64-linux.igloo.users.tux = { }; 21 + 22 + den.aspects.apps._.app-a.includes = [ (den._.unfree [ "drawio" ]) ]; 23 + den.aspects.apps._.app-b.includes = [ (den._.unfree [ "obsidian" ]) ]; 24 + 25 + den.aspects.tux.includes = [ 26 + den.aspects.apps._.app-a 27 + den.aspects.apps._.app-b 28 + ]; 29 + 30 + expr = lib.sort (a: b: a < b) tuxHm.unfree.packages; 31 + expected = [ 32 + "drawio" 33 + "obsidian" 34 + ]; 35 + } 36 + ); 37 + 38 + # Regression: parametric wrapper { host, ... }: { includes = [...] } 39 + # around sub-aspects whose includes need { class, aspect-chain }. 40 + test-unfree-parametric-wrapper-fx = denTest ( 41 + { 42 + den, 43 + lib, 44 + tuxHm, 45 + ... 46 + }: 47 + { 48 + den.hosts.x86_64-linux.igloo.users.tux = { }; 49 + 50 + den.aspects.apps._.app-a.includes = [ (den._.unfree [ "drawio" ]) ]; 51 + den.aspects.apps._.app-b.includes = [ (den._.unfree [ "obsidian" ]) ]; 52 + 53 + den.aspects.tux.includes = [ 54 + ( 55 + { host, ... }: 56 + { 57 + includes = [ 58 + den.aspects.apps._.app-a 59 + den.aspects.apps._.app-b 60 + ]; 61 + } 62 + ) 63 + ]; 64 + 65 + expr = lib.sort (a: b: a < b) tuxHm.unfree.packages; 66 + expected = [ 67 + "drawio" 68 + "obsidian" 69 + ]; 70 + } 71 + ); 72 + 73 + # Same regression on legacy pipeline. 74 + test-unfree-parametric-wrapper-legacy = denTest ( 75 + { 76 + den, 77 + lib, 78 + tuxHm, 79 + ... 80 + }: 81 + { 82 + den.fxPipeline = false; 83 + den.hosts.x86_64-linux.igloo.users.tux = { }; 84 + 85 + den.aspects.apps._.app-a.includes = [ (den._.unfree [ "drawio" ]) ]; 86 + den.aspects.apps._.app-b.includes = [ (den._.unfree [ "obsidian" ]) ]; 87 + 88 + den.aspects.tux.includes = [ 89 + ( 90 + { host, ... }: 91 + { 92 + includes = [ 93 + den.aspects.apps._.app-a 94 + den.aspects.apps._.app-b 95 + ]; 96 + } 97 + ) 98 + ]; 99 + 100 + expr = lib.sort (a: b: a < b) tuxHm.unfree.packages; 101 + expected = [ 102 + "drawio" 103 + "obsidian" 104 + ]; 105 + } 106 + ); 107 + 108 + }; 109 + }