Skip to content

Commit 5d4e133

Browse files
siniarnarg
authored andcommitted
refactor: dedupe object intake, filename, and version-enum policy
Three concerns were duplicated across the application modules. Extract each to a single source so they can't drift: - partitionObjects (applications/lib.nix): the GVK-based split of a flat object list into typed `resources` (mkMerge-able) and untyped `objects` was copy-pasted into helm.nix, kustomize.nix and yamls.nix (~35 lines each). All three now call one helper. - objectBaseName (applications/lib.nix): the `<Kind>-<dashed-name>` output filename stem was hand-written in both build.nix (groupBy key) and yamls.nix (raw-passthrough collision check). The collision assertions are only correct while these agree, so the policy now lives in one place. - k8sVersion enum (applications.nix): derive the selectable versions from the generated modules actually present in ./generated/k8s rather than reaching across layers into pkgs/generators/versions.nix. The enum now reflects what can actually be imported. No behavior change; 42/42 module tests and 13/13 lib tests pass.
1 parent e2ba967 commit 5d4e133

6 files changed

Lines changed: 77 additions & 98 deletions

File tree

modules/applications.nix

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,17 @@
44
...
55
}:
66
let
7-
versions = lib.mapAttrsToList (
8-
version: _: builtins.concatStringsSep "." (lib.lists.sublist 0 2 (builtins.splitVersion version))
9-
) (import ../pkgs/generators/versions.nix);
7+
# The selectable Kubernetes versions are exactly the generated resource
8+
# modules present in ./generated/k8s (each `nixidy.k8sVersion` value `X.Y`
9+
# imports `./generated/k8s/vX.Y.nix`). Deriving the enum from the artifacts on
10+
# disk keeps it in sync with what can actually be imported, rather than
11+
# reaching into the generator's `versions.nix` acquisition spec.
12+
versions = lib.pipe ./generated/k8s [
13+
builtins.readDir
14+
builtins.attrNames
15+
(builtins.filter (lib.hasSuffix ".nix"))
16+
(map (n: lib.removeSuffix ".nix" (lib.removePrefix "v" n)))
17+
];
1018
in
1119
{
1220
options = with lib; {

modules/applications/helm.nix

Lines changed: 4 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -116,37 +116,9 @@ in
116116
config =
117117
with lib;
118118
let
119-
groupedObjects = mapAttrs (
120-
_: release:
121-
{
122-
resources = [ ];
123-
objects = [ ];
124-
}
125-
// (groupBy (
126-
object:
127-
let
128-
gvk = helpers.getGVK object;
129-
in
130-
if config.types ? "${gvk.group}/${gvk.version}/${gvk.kind}" then "resources" else "objects"
131-
) (helpers.flattenListObjects release.objects))
132-
) config.helm.releases;
133-
134-
allResources = flatten (mapAttrsToList (_: groups: groups.resources) groupedObjects);
135-
allObjects = flatten (mapAttrsToList (_: groups: groups.objects) groupedObjects);
136-
in
137-
{
138-
resources = mkMerge (
139-
map (
140-
object:
141-
let
142-
gvk = helpers.getGVK object;
143-
in
144-
{
145-
${gvk.group}.${gvk.version}.${gvk.kind}.${object.metadata.name} = object;
146-
}
147-
) allResources
119+
allObjects = concatMap (release: helpers.flattenListObjects release.objects) (
120+
attrValues config.helm.releases
148121
);
149-
150-
objects = allObjects;
151-
};
122+
in
123+
helpers.partitionObjects config.types allObjects;
152124
}

modules/applications/kustomize.nix

Lines changed: 2 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -106,37 +106,7 @@ in
106106
config =
107107
with lib;
108108
let
109-
groupedObjects = mapAttrs (
110-
_: release:
111-
{
112-
resources = [ ];
113-
objects = [ ];
114-
}
115-
// (groupBy (
116-
object:
117-
let
118-
gvk = helpers.getGVK object;
119-
in
120-
if config.types ? "${gvk.group}/${gvk.version}/${gvk.kind}" then "resources" else "objects"
121-
) release.objects)
122-
) config.kustomize.applications;
123-
124-
allResources = flatten (mapAttrsToList (_: groups: groups.resources) groupedObjects);
125-
allObjects = flatten (mapAttrsToList (_: groups: groups.objects) groupedObjects);
109+
allObjects = concatMap (app: app.objects) (attrValues config.kustomize.applications);
126110
in
127-
{
128-
resources = mkMerge (
129-
map (
130-
object:
131-
let
132-
gvk = helpers.getGVK object;
133-
in
134-
{
135-
${gvk.group}.${gvk.version}.${gvk.kind}.${object.metadata.name} = object;
136-
}
137-
) allResources
138-
);
139-
140-
objects = allObjects;
141-
};
111+
helpers.partitionObjects config.types allObjects;
142112
}

modules/applications/lib.nix

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,56 @@ lib: with lib; rec {
1919
else
2020
[ object ]
2121
);
22+
23+
# Partition a flat list of kubernetes objects into typed `resources` and
24+
# untyped `objects`, based on whether each object's GVK is a registered type.
25+
#
26+
# `types` is the application's `config.types` registry (keyed
27+
# `<group>/<version>/<kind>`). Registered objects are returned as an
28+
# `mkMerge`-able attrset path (`<group>.<version>.<kind>.<name>`) so they flow
29+
# back into the typed `resources` option and can be patched; everything else
30+
# is returned as an opaque list. This is the single intake path shared by the
31+
# helm, kustomize and yamls modules.
32+
#
33+
# Type:
34+
# partitionObjects :: AttrSet -> [AttrSet] -> { resources :: Merge; objects :: [AttrSet]; }
35+
partitionObjects =
36+
types: objects:
37+
let
38+
grouped = {
39+
resources = [ ];
40+
objects = [ ];
41+
}
42+
// builtins.groupBy (
43+
object:
44+
let
45+
gvk = getGVK object;
46+
in
47+
if types ? "${gvk.group}/${gvk.version}/${gvk.kind}" then "resources" else "objects"
48+
) objects;
49+
in
50+
{
51+
resources = mkMerge (
52+
map (
53+
object:
54+
let
55+
gvk = getGVK object;
56+
in
57+
{
58+
${gvk.group}.${gvk.version}.${gvk.kind}.${object.metadata.name} = object;
59+
}
60+
) grouped.resources
61+
);
62+
63+
inherit (grouped) objects;
64+
};
65+
66+
# The filename stem for an object's rendered manifest: `<Kind>-<name>` with
67+
# dots in the name replaced by dashes. `build.nix` groups objects by this stem
68+
# (one YAML file per stem) and `yamls.nix` appends `.yaml` to detect collisions
69+
# with raw passthrough files; both MUST agree, so the policy lives here.
70+
#
71+
# Type:
72+
# objectBaseName :: AttrSet -> String
73+
objectBaseName = object: "${object.kind}-${replaceStrings [ "." ] [ "-" ] object.metadata.name}";
2274
}

modules/applications/yamls.nix

Lines changed: 3 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -48,39 +48,17 @@ in
4848
config =
4949
with lib;
5050
let
51-
groupedObjects = {
52-
resources = [ ];
53-
objects = [ ];
54-
}
55-
// (groupBy (
56-
object:
57-
let
58-
gvk = helpers.getGVK object;
59-
in
60-
if config.types ? "${gvk.group}/${gvk.version}/${gvk.kind}" then "resources" else "objects"
61-
) (concatMap kube.fromYAML config.yamls));
51+
partitioned = helpers.partitionObjects config.types (concatMap kube.fromYAML config.yamls);
6252

6353
rawBasenames = map baseNameOf config.extraRawYamls;
6454
duplicateRawBasenames = unique (filter (n: count (m: m == n) rawBasenames > 1) rawBasenames);
6555

66-
typedFilename = obj: "${obj.kind}-${replaceStrings [ "." ] [ "-" ] obj.metadata.name}.yaml";
56+
typedFilename = obj: "${helpers.objectBaseName obj}.yaml";
6757
typedFilenames = map typedFilename config.objects;
6858
typedCollisions = filter (n: elem n typedFilenames) (unique rawBasenames);
6959
in
7060
{
71-
inherit (groupedObjects) objects;
72-
73-
resources = mkMerge (
74-
map (
75-
object:
76-
let
77-
gvk = helpers.getGVK object;
78-
in
79-
{
80-
${gvk.group}.${gvk.version}.${gvk.kind}.${object.metadata.name} = object;
81-
}
82-
) groupedObjects.resources
83-
);
61+
inherit (partitioned) objects resources;
8462

8563
assertions = optionals (config.extraRawYamls != [ ]) [
8664
{

modules/build.nix

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,14 +37,11 @@ let
3737
transformedObjects =
3838
app: applyRewrites app.objectTransforms (applyRewrites config.nixidy.objectTransforms app.objects);
3939

40-
# Sanitize a resource name the same way mkApp does when forming the
41-
# on-disk group key / filename.
42-
sanitize = n: builtins.replaceStrings [ "." ] [ "-" ] n;
43-
4440
# The on-disk group key / filename stem for an object. mkApp groups objects
4541
# under this key; post-process rules resolve the matching path from the same
46-
# helper so the two never drift.
47-
groupKeyOf = obj: "${obj.kind}-${sanitize obj.metadata.name}";
42+
# helper, and yamls.nix reuses it to detect raw-passthrough collisions, so the
43+
# filename policy lives in exactly one place (applications/lib.nix).
44+
groupKeyOf = helpers.objectBaseName;
4845

4946
# All transform rules visible to an app: env rules first, then app rules
5047
# (chained in that order, matching `applyRewrites`).
@@ -323,6 +320,8 @@ let
323320
fi
324321
'';
325322

323+
helpers = import ./applications/lib.nix lib;
324+
326325
mkApp =
327326
app:
328327
let

0 commit comments

Comments
 (0)