Skip to content

Commit 55de37d

Browse files
committed
chore: DRY calls
1 parent cad24d5 commit 55de37d

1 file changed

Lines changed: 34 additions & 23 deletions

File tree

flake.nix

Lines changed: 34 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@
2525
"aarch64-darwin"
2626
];
2727

28-
forAllSystems = f: nixpkgs.lib.genAttrs systems (system: f system);
28+
# nixpkgs.lib.genAttrs already takes a list and a function — no wrapper needed.
29+
forAllSystems = nixpkgs.lib.genAttrs systems;
2930

3031
lib = rec {
3132
inherit versionMap;
@@ -61,40 +62,45 @@
6162
}
6263
else
6364
throw "Node.js version ${version} not found in versionMap";
64-
65-
getNodejs =
66-
{ system, version }:
67-
let
68-
pkgs = getNixpkgs { inherit system version; };
69-
attrName = versionMap.${version}.attr or "nodejs";
70-
attrPath = nixpkgs.lib.splitString "." attrName;
71-
in
72-
nixpkgs.lib.attrByPath attrPath (throw "Attribute ${attrName} not found") pkgs;
7365
};
7466

7567
packagesForSystem =
7668
system:
7769
let
7870
pkgs = nixpkgs.legacyPackages.${system};
7971

80-
basePackages = builtins.mapAttrs (
81-
version: versionInfo: lib.getNodejs { inherit system version; }
72+
# Import each pinned nixpkgs exactly once per version.
73+
# All package sets below (base, yarn, pnpm) read from this map,
74+
# so getNixpkgs is never called more than once per version per system.
75+
perVersionPkgs = builtins.mapAttrs (
76+
version: _: lib.getNixpkgs { inherit system version; }
8277
) versionMap;
8378

79+
basePackages = builtins.mapAttrs (
80+
version: versionPkgs:
81+
let
82+
attrName = versionMap.${version}.attr or "nodejs";
83+
attrPath = nixpkgs.lib.splitString "." attrName;
84+
in
85+
nixpkgs.lib.attrByPath attrPath (throw "Attribute ${attrName} not found") versionPkgs
86+
) perVersionPkgs;
87+
8488
# Create aliases like nodejs_20_18 for 20.18
8589
aliases = nixpkgs.lib.mapAttrs' (
8690
version: pkg:
8791
nixpkgs.lib.nameValuePair ("nodejs_" + (builtins.replaceStrings [ "." ] [ "_" ] version)) pkg
8892
) basePackages;
8993

90-
# Create yarn packages bundled with the specific node version
94+
# Create yarn packages bundled with the specific node version.
9195
# Uses the version-pinned nixpkgs to ensure yarn/node compatibility
9296
# (e.g. Node 16 gets yarn 1.x, avoiding OpenSSL/API mismatches with newer yarn).
9397
# Falls back to latest nixpkgs if yarn is absent from the pinned rev.
98+
# yarn has consistently accepted a nodejs override argument across all nixpkgs
99+
# versions in the supported range, so no __functionArgs guard is needed here.
94100
yarnPackages = nixpkgs.lib.mapAttrs' (
95101
version: pkg:
96102
let
97-
versionPkgs = lib.getNixpkgs { inherit system version; };
103+
versionPkgs = perVersionPkgs.${version};
98104
yarnPkgs = if builtins.hasAttr "yarn" versionPkgs then versionPkgs else pkgs;
99105
in
100106
nixpkgs.lib.nameValuePair ("yarn_" + (builtins.replaceStrings [ "." ] [ "_" ] version)) (
@@ -110,26 +116,29 @@
110116

111117
# Create pnpm packages bundled with the specific node version.
112118
# Strategy: use the pnpm that ships in the same pinned nixpkgs as the Node
113-
# version
119+
# version — it is already era-compatible (e.g. pnpm 8 with Node 18.16).
114120
#
115121
# Older nixpkgs keep pnpm under nodePackages.pnpm; newer ones promote it to
116-
# pkgs.pnpm with a callable-attrset override that accepts a nodejs argument.
117-
# When that override is available we thread
122+
# pkgs.pnpm with a callable-attrset override that accepts a nodejs argument
123+
# (detectable via .__functionArgs). When that override is available we thread
118124
# our exact Node derivation through it; otherwise we use pnpm as-is.
119125
#
120126
# Falls back to latest nixpkgs pnpm only when the pinned rev has no pnpm at
121127
# all (rare, but guards against evaluation errors).
122128
pnpmPackages = nixpkgs.lib.mapAttrs' (
123129
version: pkg:
124130
let
125-
versionPkgs = lib.getNixpkgs { inherit system version; };
131+
versionPkgs = perVersionPkgs.${version};
126132

133+
# Prefer top-level pkgs.pnpm (pnpm 10+ era); fall back to nodePackages.pnpm
127134
pinnedPnpm =
128135
if builtins.hasAttr "pnpm" versionPkgs then
129136
versionPkgs.pnpm
130137
else
131138
versionPkgs.nodePackages.pnpm or null;
132139

140+
# In newer nixpkgs pnpm.override is a callable attrset whose __functionArgs
141+
# mirror the original package function — check for nodejs there.
133142
pnpmOverride = if builtins.isNull pinnedPnpm then null else pinnedPnpm.override or null;
134143
canOverrideNodejs =
135144
builtins.isAttrs pnpmOverride
@@ -158,22 +167,24 @@
158167
basePackages // aliases // yarnPackages // pnpmPackages;
159168
in
160169
{
170+
# Standard Flake Outputs
161171
packages = forAllSystems (
162172
system:
163-
(packagesForSystem system)
164-
// {
165-
# Default to latest LTS (22.22)
166-
default = (packagesForSystem system)."22.22";
167-
}
173+
let
174+
allPkgs = packagesForSystem system;
175+
in
176+
allPkgs // { default = allPkgs."22.22"; }
168177
);
169178

179+
# Overlay allows users to use these packages in their own nixpkgs instance
170180
overlays.default =
171181
final: prev:
172182
let
173183
pkgsForSystem = packagesForSystem final.system;
174184
in
175185
pkgsForSystem;
176186

187+
# Formatter for the project
177188
formatter = forAllSystems (system: nixpkgs.legacyPackages.${system}.nixpkgs-fmt);
178189

179190
# Library functions for integration (compatible with asdf2nix API)

0 commit comments

Comments
 (0)