Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

linkFarmFromDrvs: Add a trivial builder to create a linkFarm from a list of derivations #70154

Merged
merged 2 commits into from Feb 18, 2020

Conversation

cdepillabout
Copy link
Member

Motivation for this change

This PR adds a trivial builder called linkFarmFromDrvs. It is similar to linkFarm, but it is a easier to use if you just want directory with a bunch of links to derivations, but you're fine with links just being the name of the derivation.

We use this in a couple places in our nix code-base at work, and we thought it could be helpful to other nix users.

Here's an example of using it:

$ nix-build -E 'with (import ./. {}); linkFarmFromDrvs "example" [ pkgs.hello pkgs.gcc pkgs.xterm ]'
...
/nix/store/hsi98apxc80l8r3lpi13hzc3lk8i8623-example
$ ls -l result/
lrwxrwxrwx 1 root root 61 Jan  1  1970 gcc-wrapper-8.3.0 -> /nix/store/7hzmz83nv8khpwsk858yaac7y3idh0a7-gcc-wrapper-8.3.0
lrwxrwxrwx 1 root root 54 Jan  1  1970 hello-2.10 -> /nix/store/rr3y0c6zyk7kjjl8y19s4lsrhn4aiq1z-hello-2.10
lrwxrwxrwx 1 root root 53 Jan  1  1970 xterm-348 -> /nix/store/y0cz7w39v4sb743mix5qps3kc2ra9b72-xterm-348
Things done
  • Tested using sandboxing (nix.useSandbox on NixOS, or option sandbox in nix.conf on non-NixOS)
  • Built on platform(s)
    • NixOS
    • macOS
    • other Linux distributions
  • Tested via one or more NixOS test(s) if existing and applicable for the change (look inside nixos/tests)
  • Tested compilation of all pkgs that depend on this change using nix-shell -p nix-review --run "nix-review wip"
  • Tested execution of all binary files (usually in ./result/bin/)
  • Determined the impact on package closure size (by running nix path-info -S before and after)
  • Ensured that relevant documentation is up to date
  • Fits CONTRIBUTING.md.
Notify maintainers

cc @

@edolstra
Copy link
Member

edolstra commented Oct 1, 2019

What is a "link farm"?

@cdepillabout
Copy link
Member Author

@edolstra Thanks for taking a look at this.

linkFarm is the name of one of the trivial builders currently in nixpkgs:

/*
* Quickly create a set of symlinks to derivations.
* entries is a list of attribute sets like
* { name = "name" ; path = "/nix/store/..."; }
*
* Example:
*
* # Symlinks hello path in store to current $out/hello
* linkFarm "hello" [ { name = "hello"; path = pkgs.hello; } ];
*
*/
linkFarm = name: entries: runCommand name { preferLocalBuild = true; allowSubstitutes = false; }
''mkdir -p $out
cd $out
${lib.concatMapStrings (x: ''
mkdir -p "$(dirname ${lib.escapeShellArg x.name})"
ln -s ${lib.escapeShellArg x.path} ${lib.escapeShellArg x.name}
'') entries}
'';

I'm using linkFarm in the title and description of this PR to describe the output of a derivation created with the linkFarm function. Although I agree that this is not a widely-used term and I'd be happy to change it if it is confusing.

This PR adds an additional helper function called linkFarmFromDrvs that wraps linkFarm and makes it a little easier to use in the common case.

@Profpatsch
Copy link
Member

What’s the difference to symlinkJoin "name" { paths = [ drv1 drv2 … ]; }?

@cdepillabout
Copy link
Member Author

@Profpatsch linkFarmFromDrvs (and the similar linkFarm function), just create a bunch of symlinks in a directory:

$ nix-build -E 'with import ./. {}; linkFarmFromDrvs "example" [ pkgs.hello pkgs.gcc pkgs.xterm ]'
...
/nix/store/hsi98apxc80l8r3lpi13hzc3lk8i8623-example
$ tree /nix/store/hsi98apxc80l8r3lpi13hzc3lk8i8623-example
/nix/store/hsi98apxc80l8r3lpi13hzc3lk8i8623-example
├── gcc-wrapper-8.3.0 -> /nix/store/7hzmz83nv8khpwsk858yaac7y3idh0a7-gcc-wrapper-8.3.0
├── hello-2.10 -> /nix/store/rr3y0c6zyk7kjjl8y19s4lsrhn4aiq1z-hello-2.10
└── xterm-348 -> /nix/store/y0cz7w39v4sb743mix5qps3kc2ra9b72-xterm-348

You can see that the directory /nix/store/hsi98apxc80l8r3lpi13hzc3lk8i8623-example just contains a bunch of symlinks to other derivations.

However, symlinkJoin actually replicates the directory structure from the original derivations:

$ nix-build -E 'with import <nixpkgs> {}; symlinkJoin { name = "example"; paths = [ pkgs.hello pkgs.stack ]; }'
/nix/store/wh0nkyg2qklrlq74z17fpy6yqfbdxc4m-example
$ tree /nix/store/wh0nkyg2qklrlq74z17fpy6yqfbdxc4m-example
/nix/store/wh0nkyg2qklrlq74z17fpy6yqfbdxc4m-example
├── 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
    ├── info
    │   └── hello.info -> /nix/store/qy93dp4a3rqyn2mz63fbxjg228hffwyw-hello-2.10/share/info/hello.info
...

You can see here that symlinkJoin tries to replicate the directory structure from the input derivations, while linkFarmFromDrvs just creates a link directory with symlinks.


We use linkFarmFromDrvs a bunch of places in our code base at work. Normally in CI when we want to test that a bunch of loosely-related derivations (normally tests) are able to be built, but we rarely access the actual output of the derivations.

@Profpatsch
Copy link
Member

Then +1 to that change, but let’s move these three functions together and have an overview of their differences.

@cdepillabout
Copy link
Member Author

@Profpatsch Reorganizing the functions is a good idea.

I just added a new commit that reorders the functions in this file, adds an example output for symlinkJoin and linkFarm, and adds some documentation that explains the difference between symlinkJoin and linkFarm.

I think this should be ready for a final review and hopefully a merge-in.

@nixos-discourse
Copy link

This pull request has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/prs-ready-for-review-may-2019/3032/117

Copy link
Member

@Profpatsch Profpatsch left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fantastic! LGTM

@Profpatsch Profpatsch merged commit 55e1529 into NixOS:master Feb 18, 2020
@cdepillabout cdepillabout deleted the add-linkFarmFromDrvs branch February 19, 2020 05:49
@nixos-discourse
Copy link

This pull request has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/comment-doc-praise-thread/6325/2

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants