query
On this page

linkFarm

pkgs.linkFarm

Docs pulled from | This Revision | 16 minutes ago


Nixpkgs manual

Quickly create a set of symlinks to derivations.

This creates a simple derivation with symlinks to all inputs.

entries can be a list of attribute sets like

[ { name = "name" ; path = "/nix/store/..."; } ]

or an attribute set name -> path like:

{ name = "/nix/store/..."; other = "/nix/store/..."; }

Example

Symlinks hello and stack paths in store to the current $out/hello-test and $out/foobar:

linkFarm "myexample" [ { name = "hello-test"; path = pkgs.hello; } { name = "foobar"; path = pkgs.stack; } ]

This creates a derivation with a directory structure like the following:

/nix/store/qc5728m4sa344mbks99r3q05mymwm4rw-myexample
|-- foobar -> /nix/store/6lzdpxshx78281vy056lbk553ijsdr44-stack-2.1.3.1
`-- hello-test -> /nix/store/qy93dp4a3rqyn2mz63fbxjg228hffwyw-hello-2.10

See the note on symlinkJoin for the difference between linkFarm and symlinkJoin.

Noogle detected

Implementation

The following is the current implementation of this function.

linkFarm =
    name: entries:
    let
      entries' =
        if (lib.isAttrs entries) then
          entries
        else if (lib.isList entries) then
          # listToAttrs takes the first attribute with a given name, so we
          # reverse the list to get last-wins semantics in case of repeated entries
          lib.listToAttrs (
            lib.reverseList (
              map (entry: {
                inherit (entry) name;
                value = entry.path;
              }) entries
            )
          )
        else
          throw "linkFarm entries must be either attrs or a list!";

      linkCommands = lib.mapAttrsToList (name: path: ''
        mkdir -p -- "$(dirname -- ${lib.escapeShellArg "${name}"})"
        ln -s -- ${lib.escapeShellArg "${path}"} ${lib.escapeShellArg "${name}"}
      '') entries';
    in
    runCommand name
      {
        # Get the position from the `entries` attrset if it exists.
        # This is the best we can do since the other attrs are either defined here, or curried values that
        # we cannot extract a position from
        pos =
          if (lib.isAttrs entries) && (entries != { }) then
            builtins.unsafeGetAttrPos (builtins.head (builtins.attrNames entries)) entries
          else
            null;
        preferLocalBuild = true;
        allowSubstitutes = false;
        passthru.entries = entries';
      }
      ''
        mkdir -p $out
        cd $out
        ${lib.concatStrings linkCommands}
      '';