diff --git a/doc/builders/trivial-builders.chapter.md b/doc/builders/trivial-builders.chapter.md index c3a3572cd9f4..779a0a801b4e 100644 --- a/doc/builders/trivial-builders.chapter.md +++ b/doc/builders/trivial-builders.chapter.md @@ -47,6 +47,88 @@ These functions write `text` to the Nix store. This is useful for creating scrip Many more commands wrap `writeTextFile` including `writeText`, `writeTextDir`, `writeScript`, and `writeScriptBin`. These are convenience functions over `writeTextFile`. +Here are a few examples: +```nix +# Writes my-file to /nix/store/ +writeTextFile { + name = "my-file"; + text = '' + Contents of File + ''; +} +# See also the `writeText` helper function below. + +# Writes executable my-file to /nix/store//bin/my-file +writeTextFile { + name = "my-file"; + text = '' + Contents of File + ''; + executable = true; + destination = "/bin/my-file"; +} +# Writes contents of file to /nix/store/ +writeText "my-file" + '' + Contents of File + ''; +# Writes contents of file to /nix/store//share/my-file +writeTextDir "share/my-file" + '' + Contents of File + ''; +# Writes my-file to /nix/store/ and makes executable +writeScript "my-file" + '' + Contents of File + ''; +# Writes my-file to /nix/store//bin/my-file and makes executable. +writeScriptBin "my-file" + '' + Contents of File + ''; +# Writes my-file to /nix/store/ and makes executable. +writeShellScript "my-file" + '' + Contents of File + ''; +# Writes my-file to /nix/store//bin/my-file and makes executable. +writeShellScriptBin "my-file" + '' + Contents of File + ''; + +``` + +## `concatTextFile`, `concatText`, `concatScript` {#trivial-builder-concatText} + +These functions concatenate `files` to the Nix store in a single file. This is useful for configuration files structured in lines of text. `concatTextFile` takes an attribute set and expects two arguments, `name` and `files`. `name` corresponds to the name used in the Nix store path. `files` will be the files to be concatenated. You can also set `executable` to true to make this file have the executable bit set. +`concatText` and`concatScript` are simple wrappers over `concatTextFile`. + +Here are a few examples: +```nix + +# Writes my-file to /nix/store/ +concatTextFile { + name = "my-file"; + files = [ drv1 "${drv2}/path/to/file" ]; +} +# See also the `concatText` helper function below. + +# Writes executable my-file to /nix/store//bin/my-file +concatTextFile { + name = "my-file"; + files = [ drv1 "${drv2}/path/to/file" ]; + executable = true; + destination = "/bin/my-file"; +} +# Writes contents of files to /nix/store/ +concatText "my-file" [ file1 file2 ] + +# Writes contents of files to /nix/store/ +concatScript "my-file" [ file1 file2 ] +``` + ## `writeShellApplication` {#trivial-builder-writeShellApplication} This can be used to easily produce a shell script that has some dependencies (`runtimeInputs`). It automatically sets the `PATH` of the script to contain all of the listed inputs, sets some sanity shellopts (`errexit`, `nounset`, `pipefail`), and checks the resulting script with [`shellcheck`](https://github.com/koalaman/shellcheck). @@ -72,6 +154,26 @@ validation. ## `symlinkJoin` {#trivial-builder-symlinkJoin} This can be used to put many derivations into the same directory structure. It works by creating a new derivation and adding symlinks to each of the paths listed. It expects two arguments, `name`, and `paths`. `name` is the name used in the Nix store path for the created derivation. `paths` is a list of paths that will be symlinked. These paths can be to Nix store derivations or any other subdirectory contained within. +Here is an example: +```nix +# adds symlinks of hello and stack to current build and prints "links added" +symlinkJoin { name = "myexample"; paths = [ pkgs.hello pkgs.stack ]; postBuild = "echo links added"; } +``` +This creates a derivation with a directory structure like the following: +``` +/nix/store/sglsr5g079a5235hy29da3mq3hv8sjmm-myexample +|-- bin +| |-- hello -> /nix/store/qy93dp4a3rqyn2mz63fbxjg228hffwyw-hello-2.10/bin/hello +| `-- stack -> /nix/store/6lzdpxshx78281vy056lbk553ijsdr44-stack-2.1.3.1/bin/stack +`-- share + |-- bash-completion + | `-- completions + | `-- stack -> /nix/store/6lzdpxshx78281vy056lbk553ijsdr44-stack-2.1.3.1/share/bash-completion/completions/stack + |-- fish + | `-- vendor_completions.d + | `-- stack.fish -> /nix/store/6lzdpxshx78281vy056lbk553ijsdr44-stack-2.1.3.1/share/fish/vendor_completions.d/stack.fish +... +``` ## `writeReferencesToFile` {#trivial-builder-writeReferencesToFile} diff --git a/nixos/modules/config/networking.nix b/nixos/modules/config/networking.nix index 133a150df82c..bebfeb352c01 100644 --- a/nixos/modules/config/networking.nix +++ b/nixos/modules/config/networking.nix @@ -196,9 +196,7 @@ in protocols.source = pkgs.iana-etc + "/etc/protocols"; # /etc/hosts: Hostname-to-IP mappings. - hosts.source = pkgs.runCommand "hosts" {} '' - cat ${escapeShellArgs cfg.hostFiles} > $out - ''; + hosts.source = pkgs.concatText "hosts" cfg.hostFiles; # /etc/netgroup: Network-wide groups. netgroup.text = mkDefault ""; diff --git a/pkgs/build-support/trivial-builders.nix b/pkgs/build-support/trivial-builders.nix index 3c9f3189d2cf..a7120e334333 100644 --- a/pkgs/build-support/trivial-builders.nix +++ b/pkgs/build-support/trivial-builders.nix @@ -322,6 +322,67 @@ rec { $CC -x c code.c -o "$n" ''; + + /* concat a list of files to the nix store. + * The contents of files are added to the file in the store. + * + * Examples: + * # Writes my-file to /nix/store/ + * concatTextFile { + * name = "my-file"; + * files = [ drv1 "${drv2}/path/to/file" ]; + * } + * # See also the `concatText` helper function below. + * + * # Writes executable my-file to /nix/store//bin/my-file + * concatTextFile { + * name = "my-file"; + * files = [ drv1 "${drv2}/path/to/file" ]; + * executable = true; + * destination = "/bin/my-file"; + * } + */ + concatTextFile = + { name # the name of the derivation + , files + , executable ? false # run chmod +x ? + , destination ? "" # relative path appended to $out eg "/bin/foo" + , checkPhase ? "" # syntax checks, e.g. for scripts + , meta ? { } + }: + runCommandLocal name + { inherit files executable checkPhase meta destination; } + '' + file=$out$destination + mkdir -p "$(dirname "$file")" + cat $files > "$file" + + (test -n "$executable" && chmod +x "$file") || true + eval "$checkPhase" + ''; + + + /* + * Writes a text file to nix store with no optional parameters available. + * + * Example: + * # Writes contents of files to /nix/store/ + * concatText "my-file" [ file1 file2 ] + * + */ + concatText = name: files: concatTextFile { inherit name files; }; + + /* + * Writes a text file to nix store with and mark it as executable. + * + * Example: + * # Writes contents of files to /nix/store/ + * concatScript "my-file" [ file1 file2 ] + * + */ + concatScript = name: files: concatTextFile { inherit name files; executable = true; }; + + /* * Create a forest of symlinks to the files in `paths'. * diff --git a/pkgs/build-support/trivial-builders/test/concat-test.nix b/pkgs/build-support/trivial-builders/test/concat-test.nix new file mode 100644 index 000000000000..5ce435619069 --- /dev/null +++ b/pkgs/build-support/trivial-builders/test/concat-test.nix @@ -0,0 +1,12 @@ +{ callPackage, lib, pkgs, runCommand, concatText, writeText, hello, emptyFile }: +let + stri = writeText "pathToTest"; + txt1 = stri "abc"; + txt2 = stri hello; + res = concatText "textToTest" [ txt1 txt2 ]; +in +runCommand "test-concatPaths" { } '' + diff -U3 <(cat ${txt1} ${txt2}) ${res} + diff -U3 ${concatText "void" []} ${emptyFile} + touch $out +'' diff --git a/pkgs/test/default.nix b/pkgs/test/default.nix index caed950c5764..b7980c478c66 100644 --- a/pkgs/test/default.nix +++ b/pkgs/test/default.nix @@ -61,6 +61,7 @@ with pkgs; writeStringReferencesToFile = callPackage ../build-support/trivial-builders/test/writeStringReferencesToFile.nix {}; references = callPackage ../build-support/trivial-builders/test/references.nix {}; overriding = callPackage ../build-support/trivial-builders/test-overriding.nix {}; + concat = callPackage ../build-support/trivial-builders/test/concat-test.nix {}; }; writers = callPackage ../build-support/writers/test.nix {};