summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--doc/builders/trivial-builders.chapter.md102
-rw-r--r--nixos/modules/config/networking.nix4
-rw-r--r--pkgs/build-support/trivial-builders.nix61
-rw-r--r--pkgs/build-support/trivial-builders/test/concat-test.nix12
-rw-r--r--pkgs/test/default.nix1
5 files changed, 177 insertions, 3 deletions
diff --git a/doc/builders/trivial-builders.chapter.md b/doc/builders/trivial-builders.chapter.md
index c3a3572cd9f..779a0a801b4 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/<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
+  '';
+
+```
+
+## `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/<store path>
+concatTextFile {
+  name = "my-file";
+  files = [ drv1 "${drv2}/path/to/file" ];
+}
+# See also the `concatText` helper function below.
+
+# Writes executable my-file to /nix/store/<store path>/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/<store path>
+concatText "my-file" [ file1 file2 ]
+
+# Writes contents of files to /nix/store/<store path>
+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 133a150df82..bebfeb352c0 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 3c9f3189d2c..a7120e33433 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/<store path>
+   * concatTextFile {
+   *   name = "my-file";
+   *   files = [ drv1 "${drv2}/path/to/file" ];
+   * }
+   * # See also the `concatText` helper function below.
+   *
+   * # Writes executable my-file to /nix/store/<store path>/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/<store path>
+   * 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/<store path>
+   * 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 00000000000..5ce43561906
--- /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 caed950c576..b7980c478c6 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 {};