-
-
Save piousdeer/b29c272eaeba398b864da6abf6cb5daa to your computer and use it in GitHub Desktop.
{ | |
home.file."test-file" = { | |
text = "Hello world"; | |
force = true; | |
mutable = true; | |
}; | |
} |
# This module extends home.file, xdg.configFile and xdg.dataFile with the `mutable` option. | |
{ config, lib, ... }: | |
let | |
fileOptionAttrPaths = | |
[ [ "home" "file" ] [ "xdg" "configFile" ] [ "xdg" "dataFile" ] ]; | |
in { | |
options = let | |
mergeAttrsList = builtins.foldl' (lib.mergeAttrs) { }; | |
fileAttrsType = lib.types.attrsOf (lib.types.submodule ({ config, ... }: { | |
options.mutable = lib.mkOption { | |
type = lib.types.bool; | |
default = false; | |
description = '' | |
Whether to copy the file without the read-only attribute instead of | |
symlinking. If you set this to `true`, you must also set `force` to | |
`true`. Mutable files are not removed when you remove them from your | |
configuration. | |
This option is useful for programs that don't have a very good | |
support for read-only configurations. | |
''; | |
}; | |
})); | |
in mergeAttrsList (map (attrPath: | |
lib.setAttrByPath attrPath (lib.mkOption { type = fileAttrsType; })) | |
fileOptionAttrPaths); | |
config = { | |
home.activation.mutableFileGeneration = let | |
allFiles = (builtins.concatLists (map | |
(attrPath: builtins.attrValues (lib.getAttrFromPath attrPath config)) | |
fileOptionAttrPaths)); | |
filterMutableFiles = builtins.filter (file: | |
(file.mutable or false) && lib.assertMsg file.force | |
"if you specify `mutable` to `true` on a file, you must also set `force` to `true`"); | |
mutableFiles = filterMutableFiles allFiles; | |
toCommand = (file: | |
let | |
source = lib.escapeShellArg file.source; | |
target = lib.escapeShellArg file.target; | |
in '' | |
$VERBOSE_ECHO "${source} -> ${target}" | |
$DRY_RUN_CMD cp --remove-destination --no-preserve=mode ${source} ${target} | |
''); | |
command = '' | |
echo "Copying mutable home files for $HOME" | |
'' + lib.concatLines (map toCommand mutableFiles); | |
in (lib.hm.dag.entryAfter [ "linkGeneration" ] command); | |
}; | |
} |
{ config, pkgs, lib, ... }: | |
let | |
# Path logic from: | |
# https://github.com/nix-community/home-manager/blob/3876cc613ac3983078964ffb5a0c01d00028139e/modules/programs/vscode.nix | |
cfg = config.programs.vscode; | |
vscodePname = cfg.package.pname; | |
configDir = { | |
"vscode" = "Code"; | |
"vscode-insiders" = "Code - Insiders"; | |
"vscodium" = "VSCodium"; | |
}.${vscodePname}; | |
userDir = if pkgs.stdenv.hostPlatform.isDarwin then | |
"Library/Application Support/${configDir}/User" | |
else | |
"${config.xdg.configHome}/${configDir}/User"; | |
configFilePath = "${userDir}/settings.json"; | |
tasksFilePath = "${userDir}/tasks.json"; | |
keybindingsFilePath = "${userDir}/keybindings.json"; | |
snippetDir = "${userDir}/snippets"; | |
pathsToMakeWritable = lib.flatten [ | |
(lib.optional (cfg.userTasks != { }) tasksFilePath) | |
(lib.optional (cfg.userSettings != { }) configFilePath) | |
(lib.optional (cfg.keybindings != [ ]) keybindingsFilePath) | |
(lib.optional (cfg.globalSnippets != { }) | |
"${snippetDir}/global.code-snippets") | |
(lib.mapAttrsToList (language: _: "${snippetDir}/${language}.json") | |
cfg.languageSnippets) | |
]; | |
in { | |
home.file = lib.genAttrs pathsToMakeWritable (_: { | |
force = true; | |
mutable = true; | |
}); | |
} |
@j4t1nd3r It's the expected behavior because the file is copied, not symlinked. I believe mkOutOfStoreSymlink
achieves exactly what you want
Thank you, I saw this in places but without context. I am struggling to find good documentation on commands / options.
Even for home.file in the home-manager documentation. It seems looking at nix related github issues, searching discord history in nix related channels is the way to go or reaching out directly.
Since a few days, I'm getting the following errors when trying to nixos-rebuild
:
error:
… while calling the 'head' builtin
at /nix/store/z7j461v8da67nwrad4xz50dx2l5wk0wz-source/lib/attrsets.nix:1575:11:
1574| || pred here (elemAt values 1) (head values) then
1575| head values
| ^
1576| else
… while evaluating the attribute 'value'
at /nix/store/z7j461v8da67nwrad4xz50dx2l5wk0wz-source/lib/modules.nix:809:9:
808| in warnDeprecation opt //
809| { value = builtins.addErrorContext "while evaluating the option `${showOption loc}':" value;
| ^
810| inherit (res.defsFinal') highestPrio;
(stack trace truncated; use '--show-trace' to show the full trace)
error: getting status of '/nix/store/34ww4vpn116rriqbhzh4snayh7837k7v-mutability.nix': No such file or directory
I have no clue why this is happening, since I haven't changed anything related to this part of the system for a while. Does anybody have an idea?
To help solve the issue, I suggest sharing your nix configuration, ideally a public repository link if your configuration is saved in a repo.
@j4t1nd3r My intention was to reach people having this snippet in their config, since my problem might also be caused by something else.
If you want to take a look anyways: https://github.com/becknik/dotfiles.nix
Every help is greatly appreciated :)
@becknik I can reproduce this issue, specifically with
xdg.configFile
only. Though I don't currently have time to investigate, so I'm hoping someone else will chip in