diff --git a/modules/files.nix b/modules/files.nix index f2495f5b..45aa9965 100644 --- a/modules/files.nix +++ b/modules/files.nix @@ -225,11 +225,26 @@ in install -m "$mode" "$source" "$target" else [[ -x $source ]] && isExecutable=1 || isExecutable="" - if [[ $executable == inherit || $isExecutable == $executable ]]; then + + # Link the file into the home file directory if possible, + # i.e., if the executable bit of the source is the same we + # expect for the target. Otherwise, we copy the file and + # set the executable bit to the expected value. + # + # Note, as a special case we always copy systemd units + # because it derives the unit name from the ultimate link + # target, which may be a store path with the hash + # included. + if [[ ($executable == inherit || $isExecutable == $executable) \ + && $relTarget != *"/systemd/user/"* ]]; then ln -s "$source" "$target" else cp "$source" "$target" - if [[ $executable ]]; then + + if [[ $executable == inherit ]]; then + # Don't change file mode if it should match the source. + : + elif [[ $executable ]]; then chmod +x "$target" else chmod -x "$target" diff --git a/modules/systemd.nix b/modules/systemd.nix index 939dc832..8ee2db65 100644 --- a/modules/systemd.nix +++ b/modules/systemd.nix @@ -24,17 +24,17 @@ let buildService = style: name: serviceCfg: let - source = pkgs.writeScript "${name}.${style}" (toSystemdIni serviceCfg); + source = pkgs.writeText "${name}.${style}" (toSystemdIni serviceCfg); wantedBy = target: { name = "systemd/user/${target}.wants/${name}.${style}"; - value = { inherit source; executable = false; }; + value = { inherit source; }; }; in singleton { name = "systemd/user/${name}.${style}"; - value = { inherit source; executable = false; }; + value = { inherit source; }; } ++ map wantedBy (serviceCfg.Install.WantedBy or []);