Removed pipe operator.

The pipe operator '<|' was added in Nix 2.24 as experimental. In typical
nix community fashion, an eternity has passed, it's still experimental, and
they're still arguing about it. Thus, in order not to burden any users of
this flake, they have been removed.

To get this done quickly a utility function has been added called 'compose'.
It is 'lib.trivial.pipe' written in reverse. This eliminates any bugs and
performance regressions from unnecessary thunk evaluation.
This commit is contained in:
hylodon 2026-02-23 22:08:18 +00:00
parent 0f0c4c7727
commit 2a5ced3905
7 changed files with 115 additions and 89 deletions

View file

@ -13,10 +13,10 @@
{ {
formatter = forAllSystems (system: nixos.legacyPackages.${system}.nixfmt-tree); formatter = forAllSystems (system: nixos.legacyPackages.${system}.nixfmt-tree);
hmModules = import ./modules/home-manager self.lib; hmModules = import ./modules/home-manager self.lib.hylonix;
lib = import ./lib (nixos.lib // self.lib); lib = import ./lib (nixos.lib // self.lib);
nixosModules = import ./modules/nixos self.lib; nixosModules = import ./modules/nixos self.lib.hylonix;
}; };
} }

View file

@ -23,7 +23,9 @@ lib: {
f; f;
recursiveMergeAll = builtins.foldl' lib.hylonix.recursiveMerge null; recursiveMergeAll = builtins.foldl' lib.hylonix.recursiveMerge null;
compose = lib.trivial.flip (lib.foldr lib.trivial.id);
}; };
inherit (lib.hylonix) recursiveMerge recursiveMergeAll; inherit (lib.hylonix) compose recursiveMerge recursiveMergeAll;
} }

View file

@ -1,6 +1,7 @@
{ {
pkgs, pkgs,
lib, lib,
sLib,
info, info,
... ...
}: }:
@ -12,9 +13,13 @@ let
options = { options = {
packages = lib.mkOption { packages = lib.mkOption {
type = type =
sLib.compose
[
lib.types.listOf lib.types.listOf
<| lib.types.either lib.types.package (lib.types.either lib.types.package)
<| lib.types.submodule { (lib.types.submodule)
]
{
options = { options = {
name = lib.mkOption { name = lib.mkOption {
type = lib.types.str; type = lib.types.str;
@ -65,37 +70,37 @@ let
x: x:
x x
// lib.optionalAttrs (x ? adminSettings) { // lib.optionalAttrs (x ? adminSettings) {
adminSettings = adminSettings = sLib.compose [
builtins.toJSON builtins.toJSON
<| ( (
y: y:
y y
// lib.optionalAttrs (y ? userFilters) { // lib.optionalAttrs (y ? userFilters) {
userFilters = builtins.concatStringsSep "\n" y.userFilters; userFilters = builtins.concatStringsSep "\n" y.userFilters;
} }
) )
<| ( (
y: y:
y y
// lib.optionalAttrs (y ? urlFilteringString) { // lib.optionalAttrs (y ? urlFilteringString) {
urlFilteringString = builtins.concatStringsSep "\n" y.urlFilteringString; urlFilteringString = builtins.concatStringsSep "\n" y.urlFilteringString;
} }
) )
<| ( (
y: y:
y y
// lib.optionalAttrs (y ? hostnameSwitchesString) { // lib.optionalAttrs (y ? hostnameSwitchesString) {
hostnameSwitchesString = builtins.concatStringsSep "\n" y.hostnameSwitchesString; hostnameSwitchesString = builtins.concatStringsSep "\n" y.hostnameSwitchesString;
} }
) )
<| ( (
y: y:
y y
// lib.optionalAttrs (y ? dynamicFilteringString) { // lib.optionalAttrs (y ? dynamicFilteringString) {
dynamicFilteringString = builtins.concatStringsSep "\n" y.dynamicFilteringString; dynamicFilteringString = builtins.concatStringsSep "\n" y.dynamicFilteringString;
} }
) )
<| x.adminSettings; ] x.adminSettings;
}; };
}; };
magic = guid: magicInfo.${guid} or lib.trivial.id; magic = guid: magicInfo.${guid} or lib.trivial.id;
@ -123,9 +128,9 @@ in
{ {
policies = { policies = {
"3rdparty".Extensions = extensions.settings; "3rdparty".Extensions = extensions.settings;
ExtensionSettings = ExtensionSettings = sLib.compose [
builtins.listToAttrs builtins.listToAttrs
<| builtins.map ( (builtins.map (
withExtension withExtension
(x: { (x: {
name = x.addonId; name = x.addonId;
@ -143,8 +148,8 @@ in
install_url = "https://addons.mozilla.org/firefox/downloads/latest/${x.name}/latest.xpi"; install_url = "https://addons.mozilla.org/firefox/downloads/latest/${x.name}/latest.xpi";
}; };
}) })
) ))
<| extensions.packages; ] extensions.packages;
}; };
prefs."extensions.autoDisableScopes" = 0; prefs."extensions.autoDisableScopes" = 0;
}; };
@ -152,6 +157,6 @@ in
postprocess = postprocess =
{ policies, ... }: { policies, ... }:
lib.optionalAttrs (policies ? "3rdparty".Extensions) { lib.optionalAttrs (policies ? "3rdparty".Extensions) {
policies."3rdparty".Extensions = builtins.mapAttrs magic <| policies."3rdparty".Extensions or { }; policies."3rdparty".Extensions = builtins.mapAttrs magic (policies."3rdparty".Extensions or { });
}; };
} }

View file

@ -1,6 +1,7 @@
{ {
pkgs, pkgs,
lib, lib,
sLib,
info, info,
... ...
}: }:
@ -35,15 +36,15 @@ in
postprocess = postprocess =
{ lockPref, prefs, ... }: { lockPref, prefs, ... }:
{ {
prefs = prefs = sLib.compose [
builtins.concatStringsSep "\n" (builtins.concatStringsSep "\n")
<| (x: [ "// Generated by ${info.name} module" ] ++ x) (x: [ "// Generated by ${info.name} module" ] ++ x)
<| lib.mapAttrsToList ( (lib.mapAttrsToList (
let let
prefFunc = if lockPref then "lockPref" else "user_pref"; prefFunc = if lockPref then "lockPref" else "user_pref";
in in
key: val: ''${prefFunc}("${key}", ${builtins.toJSON val});'' key: val: ''${prefFunc}("${key}", ${builtins.toJSON val});''
) ))
<| prefs; ] prefs;
}; };
} }

View file

@ -14,9 +14,17 @@ let
builtins.concatMap (y: builtins.concatMap (x: f x y) xs) ys; builtins.concatMap (y: builtins.concatMap (x: f x y) xs) ys;
# (Lib -> Profile -> c) -> ProfileSettings -> [c] # (Lib -> Profile -> c) -> ProfileSettings -> [c]
mapLibAndProfile = f: x: mapProduct f allLibs <| builtins.attrValues <| x; mapLibAndProfile =
f:
sLib.compose [
(mapProduct f allLibs)
builtins.attrValues
];
allLibs = builtins.attrValues <| lib.filterAttrs (k: _: k != "profiles") <| geckoLib; allLibs = sLib.compose [
builtins.attrValues
(lib.filterAttrs (k: _: k != "profiles"))
] geckoLib;
allLibs' = allLibs ++ [ geckoLib.profiles ]; allLibs' = allLibs ++ [ geckoLib.profiles ];
submodule = submodule =
@ -63,9 +71,7 @@ let
writeProfilesIni = configPath: profileSettings: { writeProfilesIni = configPath: profileSettings: {
name = "${configPath}/profiles.ini"; name = "${configPath}/profiles.ini";
value.text = value.text = lib.generators.toINI { } (
lib.generators.toINI { }
<|
lib.mapAttrs' ( lib.mapAttrs' (
_: v: _: v:
lib.nameValuePair "Profile${builtins.toString v.id}" { lib.nameValuePair "Profile${builtins.toString v.id}" {
@ -80,7 +86,8 @@ let
StartWithLastProfile = 1; StartWithLastProfile = 1;
Version = 2; Version = 2;
}; };
}; }
);
}; };
in in
{ {
@ -92,30 +99,31 @@ in
getDefaultProfileName = getDefaultProfileName =
profileSettings: profileSettings:
sLib.compose [
builtins.head builtins.head
<| builtins.filter (x: profileSettings.${x}.isDefault) (builtins.filter (x: profileSettings.${x}.isDefault))
<| builtins.attrNames builtins.attrNames
<| profileSettings; ] profileSettings;
process = process =
{ languagePacks, ... }: { languagePacks, ... }:
let let
extractVersion = extractVersion = sLib.compose [
(x: if x == [ ] then info.base.version else builtins.head x) (x: if x == [ ] then info.base.version else builtins.head x)
<| builtins.match "([^-]*)-.*" (builtins.match "([^-]*)-.*")
<| info.base.version; ] info.base.version;
in in
{ {
policies.ExtensionSettings = policies.ExtensionSettings = sLib.compose [
builtins.listToAttrs builtins.listToAttrs
<| builtins.map (lang: { (builtins.map (lang: {
name = "langpack-${lang}@firefox.mozilla.org"; name = "langpack-${lang}@firefox.mozilla.org";
value = { value = {
installation_mode = "force_installed"; installation_mode = "force_installed";
install_url = "https://releases.mozilla.org/pub/firefox/releases/${extractVersion}/linux-x86_64/xpi/${lang}.xpi"; install_url = "https://releases.mozilla.org/pub/firefox/releases/${extractVersion}/linux-x86_64/xpi/${lang}.xpi";
}; };
}) }))
<| languagePacks; ] languagePacks;
}; };
assertions = profiles: [ assertions = profiles: [
@ -124,12 +132,12 @@ in
message = "No profiles are defined."; message = "No profiles are defined.";
} }
{ {
assertion = assertion = sLib.compose [
(x: x == 1) (x: x == 1)
<| builtins.length builtins.length
<| builtins.filter (x: profiles.${x}.isDefault) (builtins.filter (x: profiles.${x}.isDefault))
<| builtins.attrNames builtins.attrNames
<| profiles; ] profiles;
message = "One, and only one, profile must be marked as 'isDefault'. If you have not set this option on any profile, then one and only one profile must have id '0'."; message = "One, and only one, profile must be marked as 'isDefault'. If you have not set this option on any profile, then one and only one profile must have id '0'.";
} }
]; ];
@ -141,15 +149,21 @@ in
let let
processLevel = processLevel =
level: userConfig: level: userConfig:
sLib.compose [
sLib.recursiveMergeAll sLib.recursiveMergeAll
<| (x: [ userConfig ] ++ x) (x: [ userConfig ] ++ x)
<| builtins.map (myLib: (myLib.${level} or (_: { })) userConfig) (builtins.map (myLib: (myLib.${level} or (_: { })) userConfig))
<| allLibs'; ] allLibs';
# Internal libraries can create their own configuration that needs to be merged # Internal libraries can create their own configuration that needs to be merged
# into the user configuration (the user's takes priority). Generate that config. # into the user configuration (the user's takes priority). Generate that config.
finalConfig = builtins.mapAttrs ( finalConfig = builtins.mapAttrs (
_: v: processLevel "postprocess" <| processLevel "process" <| processLevel "preprocess" <| v _:
sLib.compose [
(processLevel "postprocess")
(processLevel "process")
(processLevel "preprocess")
]
) profiles; ) profiles;
in in
{ {

View file

@ -1,4 +1,4 @@
{ lib, ... }: { lib, sLib, ... }:
let let
submodule = submodule =
@ -80,8 +80,10 @@ let
icon, icon,
}: }:
let let
params = params = sLib.compose [
builtins.concatStringsSep "&" <| builtins.map (x: "${x.key}=${x.value}") <| searchUri.params; (builtins.concatStringsSep "&")
(builtins.map (x: "${x.key}=${x.value}"))
] searchUri.params;
in in
{ {
Name = name; Name = name;

View file

@ -150,15 +150,16 @@ in
filterCookies = filterCookies =
x: x:
sLib.compose [
builtins.concatLists builtins.concatLists
<| lib.mapAttrsToList ( (lib.mapAttrsToList (
k: v: k: v:
if builtins.elem v.cookies x then if builtins.elem v.cookies x then
[ "https://${k}/" ] ++ lib.optional (!v.https-only) "http://${k}/" [ "https://${k}/" ] ++ lib.optional (!v.https-only) "http://${k}/"
else else
[ ] [ ]
) ))
<| site; ] site;
makeUboConf = domain: config: { makeUboConf = domain: config: {
adminSettings = { adminSettings = {
@ -204,7 +205,8 @@ in
true true
]; ];
}; };
extensions.settings."uBlock0@raymondhill.net" = extensions.settings."uBlock0@raymondhill.net" = sLib.recursiveMergeAll (
sLib.recursiveMergeAll <| [ (makeUboConf "*" default) ] ++ lib.mapAttrsToList makeUboConf site; [ (makeUboConf "*" default) ] ++ lib.mapAttrsToList makeUboConf site
);
}; };
} }