Is it possible to write to an arbitrary file from nix config?

Is it possible to use configuration.nix to write text to an arbitrary file?
Specifically I’m trying to write to /root/.gitconfig :

[safe]
   directory = /path/to/my/nixconfig
[user]
    email = root@${hostname}
    name = autoupgrade

so that auto-upgrade can update and commit flake.lock : Flake auto-upgrade fails because git-repo not owned by current user

Previously when I needed to declare a specific file, I wrote an ad-hoc oneshot systemd service script to echo the content and chmod the file. But this feels very janky.

After some hours of searching and trying, the closest I have gotten is

environment.systemPackages = [ 
    ...
   (pkgs.writeTextFile {
        name = "gitconfig";
        text = ''
          [safe]
                directory = /path/to/my/nixconfig
           [user]
                email = root@$hostname
                name = autoupgrade
             '';
        destination = "/root/.gitconfig";
      } 
   )
];
environment.pathsToLink = [ "/root" ] ;

which creates the file in the in the nix-store , and symlinks to the nix-store file from /run/current-system/sw/root/.gitignore , but still nothing in /root/.gitignore. I thought nixos-rebuild would also place a symlink in /root/

There is etc.environment for files in /etc and home-managers home.file for files in $HOME, and various other specialised options, but I haven’t found a generic way to write to any arbitrary file. I’m very new to nix, so maybe I’m not using the search term

Is there a proper way to write to arbitrary files?

1 Like

There isn’t really. The closest thing is systemd-tmpfiles, but if you remove the tmpfiles entry later on, the file will still be present, so I don’t consider it a great solution.

I don’t know of a non-janky way to do this.

systemd-tmpfiles to symlink to the Nix store is probably the most general solution.

home-manager as a NixOS module to configure it for root is probably how I would first try to handle this.

How would that work? h-m is only meant to configure files within the $HOME of the corresponding user (/root in this case).

That is correct.
I was referring to the specific case of the OP, writing to /root/.gitconfig

1 Like