Skip to content

Instantly share code, notes, and snippets.

@mcdonc
Created December 27, 2023 21:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mcdonc/978487ae51fa1cf4d305bbebcdf40f86 to your computer and use it in GitHub Desktop.
Save mcdonc/978487ae51fa1cf4d305bbebcdf40f86 to your computer and use it in GitHub Desktop.

writeTextFile, writeText, writeTextDir, writeScript, writeScriptBin {#trivial-builder-writeText}

These functions write text to a file within the Nix store. This is useful for creating files from Nix expressions, which may be scripts or just non-executable text files, depending on the function used and its arguments.

writeTextFile takes an attribute set and expects two arguments, name and text. name corresponds to the name used in the Nix store path. text will be the contents of the file. You can also set executable to true to make this file have the executable bit set.

Many more commands wrap writeTextFile including writeText, writeTextDir, writeScript, and writeScriptBin. These are convenience functions over writeTextFile.

Here are a few examples:

# Writes my-file to /nix/store/<store path>
writeTextFile {
  name = "my-file";
  text = ''
    Contents of File
  '';
}
# See also the `writeText` helper function below.

# Writes executable my-file to /nix/store/<store path>/bin/my-file
writeTextFile {
  name = "my-file";
  text = ''
    Contents of File
  '';
  executable = true;
  destination = "/bin/my-file";
}
# Writes contents of file to /nix/store/<store path>
writeText "my-file"
  ''
  Contents of File
  '';
# Writes contents of file to /nix/store/<store path>/share/my-file
writeTextDir "share/my-file"
  ''
  Contents of File
  '';
# Writes my-file to /nix/store/<store path> and makes executable
writeScript "my-file"
  ''
  Contents of File
  '';
# Writes my-file to /nix/store/<store path>/bin/my-file and makes executable.
writeScriptBin "my-file"
  ''
  Contents of File
  '';
# Writes my-file to /nix/store/<store path> and makes executable.
writeShellScript "my-file"
  ''
  Contents of File
  '';
# Writes my-file to /nix/store/<store path>/bin/my-file and makes executable.
writeShellScriptBin "my-file"
  ''
  Contents of File
  '';

The result of each of these functions will be a derivation. When you coerce a derivation to text, it will evaluate to the store path. Importantly, it will disinclude any of the subpath produced by the particular function. So, for example, given the following expression:

my-file = writeTextFile {
  name = "my-file";
  text = ''
    Contents of File
  '';
  destination = "/share/my-file";
}

If are were to evaluate my-file elsewhere in your configuration, it will resolve to /nix/store/<store-path>, like any other derivation. It will not evaluate to /nix/store/<store-path>/share/my-file. So to use it elsewhere, as an example (in this case, within a shell script you're writing in a Nix expression via writeShellScript), you might do:

writeShellScript "evaluate-my-file.sh" ''
  cat ${my-file}/share/my/file
'';

This will produce the desired result. However, this will not, it will fail because the store path is a directory:

writeShellScript "evaluate-my-file.sh" ''
  cat ${my-file}
'';
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment