Writing a text file containing the contents of a nix variable (plus other text)

Hi again,

how can I create a text file, that contains the contents of a variable defined in nix? Without having the whole script in the nix file?

Something like this, except I can use Nix variable my-nix-variable in the file:

{ config, lib, pkgs, ... }:
let
  my-nix-variable = "test";
in {
  home.file = {
    ".config/some-file".source = dotfiles/some-file;
  };
}

I found pkgs.writeText and .writeTextFile and others of that kidney, but all my tries failed to give the results.

Maybe I am missing the right syntax to use the variable in the file. I tried the example here but to no avail…

Thanks in advance!

Kind Regards,
Johannes

For home.file specifically I think you can use .text instead of .source:

{
  home.file = {
    ".config/some-file".text = ''
      ${my-nix-variable}
    '';
  };
}

Yes, but I would like to avoid having the whole script in my nix configuration.

I thought of something like “load the contents from the file and then replace any variables you might find”.

You’d need to make a derivation to achieve that realistically: Nixpkgs Manual

Alternatively you can use environment variables.

2 Likes

Take a look at the various substitution functions in the nixpkgs manual. You could, for instance, do:

{ pkgs, ... }:
let
  my-nix-variable = "test";
in {
  home.file = {
    ".config.some-file".source = pkgs.runCommand "some-drv" {} ''
      substitute ${./dotfiles/some-file} $out \
        --subst-var-by "A_NAME" ${my-nix-variable}
    '';
  };
}

There’s various substitution methods in that section of the manual that may or may not be easier to use for your particular circumstance.

EDIT: Unrelated, but it’s hilarious that this happens so often that @TLATER and I respond with very similar explanations at virtually exactly the same time lol. Thank you for your contributions!

4 Likes

Thanks, any pointer on using environment variables?

Thanks, both to you and TLATER. I’ll give it a try!

This worked (after I noticed I had to use @A_NAME@ in the file, just A_NAME is not enough… :slight_smile:
Thanks to both of you for the quick help!

1 Like

You could instead use home.sessionVariables to set an environment variable and use that in the script instead and just write a normal script accessing that with e.g. $A_NAME.

Writing a derivation that uses substitute is probably preferable, though if you wanted the script to work in non-NixOS contexts doing the above can make a lot of sense.

:slight_smile:

1 Like

I am late to the party, but I use substituteAll and I thought I’d share an example: nixos-config/home.nix at 6ff4df4a2598c766cd94a930701283f56017f04b · waxlamp/nixos-config · GitHub. You can open the various files mentioned in the src arguments to see what those look like (you will recognize the whole @foobar@ pattern.

While I’m here, I will mention: I really like how this makes my dotfiles quite declarative and “integrated” with NixOS; on the other hand, I don’t like that my path to deploying a new version of a dotfile that I’m tinkering with now includes doing a full rebuild of my system. Not sure if there’s any advice out there about this tradeoff.

roni