Nix (language): Difference between revisions
imported>Profpatsch m importable -> import-able |
imported>Profpatsch Add Update Scripts section to Tips & Tricks |
||
| Line 408: | Line 408: | ||
This trick might be helpful in combination with [https://nixos.org/nix/manual/#builtin-getEnv <code>builtins.getEnv</code>], which returns a string (which might be a path). Be careful, depending on environment variables introduces heavy non-determinism and might lead to rebuilds! | This trick might be helpful in combination with [https://nixos.org/nix/manual/#builtin-getEnv <code>builtins.getEnv</code>], which returns a string (which might be a path). Be careful, depending on environment variables introduces heavy non-determinism and might lead to rebuilds! | ||
=== Writing update scripts / Referencing a relative path as string === | |||
Nix has relative path syntax that describes files relative to the current nix file, for example | |||
<syntaxHighlight lang=nix> | |||
with import <nixpkgs> {}; | |||
let textdata = ../foo.txt; | |||
in runCommand "alldata" {} '' | |||
echo "=this is a header=" >> $out | |||
cat ${textdata} >> $out | |||
'' | |||
</syntaxHighlight> | |||
If the file <code>../foo.txt</code> are needed by evaluation, it is copied to the nix store first, so the script in the resulting <code>drv</code> file looks like this: | |||
<code> | |||
"echo \"=this is a header=\" >> $out\ncat /nix/store/dcaph3ib0vq0c27bqzw2vhrakk272mga-foo.txt >> $out\n" | |||
</code> | |||
Notice the <code>/nix/store</code> path of <code>foo.txt</code>. When we build the file: | |||
<pre> | |||
$ nix-build code.nix | |||
these derivations will be built: | |||
/nix/store/bfv13hxqlwll398y5vi3wn44raw48yva-alldata.drv | |||
building '/nix/store/bfv13hxqlwll398y5vi3wn44raw48yva-alldata.drv'... | |||
/nix/store/9fav4aw2fs8ybaj06gg6cjzz7bkqf461-alldata | |||
$ cat /nix/store/9fav4aw2fs8ybaj06gg6cjzz7bkqf461-alldata | |||
=this is a header= | |||
this | |||
is | |||
some | |||
data | |||
</pre> | |||
Now, what if we don’t want to import the data file into the store, but still reference the absolute path of that file? We use <code>toString</code>: | |||
<syntaxHighlight lang=nix> | |||
with import <nixpkgs> {}; | |||
let textdata = toString ../foo.txt; | |||
in writeScript "update-foo.sh" '' | |||
echo "updating foo.txt!" | |||
cat "additional new data" >> ${lib.escapeShellArg textdata} | |||
'' | |||
</syntaxHighlight> | |||
In this example we use the actual absolute path of the file to write a script (notice the change from <code>runCommand</code> to <code>writeScript</code>, which are both helper functions from <code>nixpkgs</code>). This script can update the <code>foo.txt</code> file when it is run by bash: | |||
<pre> | |||
$ cat $(nix-build code.nix) | |||
echo "updating foo.txt!" | |||
echo "additional new data" >> '/home/philip/tmp/foo.txt' | |||
$ bash $(nix-build code.nix) | |||
updating foo.txt! | |||
$ cat foo.txt | |||
this | |||
is | |||
some | |||
data | |||
additional new data | |||
</pre> | |||
Bear in mind that this makes the absolute path vary between different systems. The users Bob and Alice are going to get different scripts, because the paths of their home folders differ: <code>/home/bob/foo.txt</code> and <code>/home/alice/foo.txt</code>; so it’s not reproducible. | |||
We can use this trick to update the sources of nix expressions (for example by generating a script which updates a json file with the software’s hashes). | |||
[[Category:Discussion]] | [[Category:Discussion]] | ||
[[Category:Nix Language]] | [[Category:Nix Language]] | ||
[[Category:Incomplete]] | [[Category:Incomplete]] | ||