1
0
Fork 0
mirror of https://github.com/nix-community/home-manager.git synced 2025-11-08 19:46:05 +01:00

lib/deprecations: add remapAttrsRecursive

Similar purpose to the `mkSettingsRenamedOptionsModule` for migrating
users configuration to the new format needed by a module. But,
supporting freeform options that shouldn't get option definitions.

Signed-off-by: Austin Horstman <khaneliman12@gmail.com>
This commit is contained in:
Austin Horstman 2025-07-02 19:36:24 -05:00
parent a4fc77c63d
commit 19f0ba9c52

View file

@ -47,4 +47,51 @@
in
lib.mkRenamedOptionModule (oldPrefix ++ finalSpec.old) (newPrefix ++ finalSpec.new)
);
/*
Recursively transforms attribute set keys, issuing a warning for each transformation.
Example:
let
# Renames camelCase keys to snake_case.
migrateCamelCase = lib.hm.deprecations.remapAttrsRecursive {
# A key needs migration if it contains a lowercase letter followed by an uppercase one.
pred = key: builtins.match ".*[a-z][A-Z].*" key != null;
# The transformation to apply.
transform = lib.hm.strings.toSnakeCase;
};
in
# { my-key = { fooBar = 1; }; }
migrateCamelCase "programs.mymodule.settings" { my-key = { fooBar = 1; }; }
# => { my-key = { foo_bar = 1; }; }
# (with a warning about the fooBar -> foo_bar conversion)
*/
remapAttrsRecursive =
{ pred, transform }:
let
migrate =
path: value:
if builtins.isAttrs value then
lib.mapAttrs' (
name: val:
let
newName = if pred name then transform name else name;
warnOrId =
if newName != name then
lib.warn "home-manager: The setting '${name}' in '${path}' was automatically renamed to '${newName}'. Please update your configuration."
else
x: x;
in
warnOrId {
name = newName;
value = migrate "${path}.${name}" val;
}
) value
else if builtins.isList value then
lib.imap0 (index: val: migrate "${path}.[${toString index}]" val) value
else
value;
in
pathStr: attrs: migrate pathStr attrs;
}