[Nix-dev] User environment hooks - proposal - review this patch, please
Marc Weber
marco-oweber at gmx.de
Thu May 21 10:44:39 CEST 2009
I finally got around implementing a proposal.
Sorry for the bad perl style. I don't know the language very well. :-)
Maybe you can give me some hints how to improve the code?
So what does it do?
The builder.pl (which can be found in the nix repo) gets passed a list of store
paths to form a profile (user env) you install by using nix-env ..
Till now it created all the symlinks. This patch adds additional code which
is run at the end of the original builder scanning all paths for
nix-support/post-profile-hook. If such a script is found its run and passed
the profile directory and the list of package paths to be installed.
Very simple example:
packageList = pkgs.writeTextFile {
name = "pkgsList";
executable = true;
destination = "/nix-support/post-profile-hook";
text=''
#!/bin/sh
profile=$1
paths=$2
echo "$paths" > "$profile/all-paths"
'';
};
Use cases:
Create some hooks creating or ammending to
~/.nix-prfile/env which you can source in your .bashrc / .zshrc
exporting stuff like includes, libs, INFOPATH, pkg-config information etc.
Another use case is create some scripts based on installed packages adding the
dependencies to various build systems (eg vim, emacs, eclipse-cdt, ..)
Marc Weber
diff --git a/corepkgs/buildenv/builder.pl.in b/corepkgs/buildenv/builder.pl.in
index 9932ea5..78acf18 100755
--- a/corepkgs/buildenv/builder.pl.in
+++ b/corepkgs/buildenv/builder.pl.in
@@ -147,17 +147,45 @@ foreach my $pkg (sort (keys %pkgs)) {
# installed by the user (i.e., package X declares that it want Y
# installed as well). We do these later because they have a lower
# priority in case of collisions.
+my @allPostponed = ();
my $priorityCounter = 1000; # don't care about collisions
while (scalar(keys %postponed) > 0) {
my @pkgDirs = keys %postponed;
+ @allPostponed = (@allPostponed, @pkgDirs);
%postponed = ();
foreach my $pkgDir (sort @pkgDirs) {
addPkg($pkgDir, $priorityCounter++);
}
}
+# run post hooks. A post hook is a script
+# $out/nix-support/post-profile-hook out allUniq
+# out : profile dir
+# allUniq: list of all paths which have already been installed to
+# the profile
+#
+# post hooks should be unobtrusive. This means: Don't add post-profile hooks
+# to normal derivations. Make them optional so that they must be installed
+# explicitely
+# TODO: think about security
+my @allPkgDirs = (keys %pkgs, @allPostponed);
+
+# get uniq list, is there an easier way?
+my %seen = ();
+my @allUniq = ();
+foreach my $item (@allPkgDirs) {
+ push(@allUniq, $item) unless $seen{$item}++;
+}
-print STDERR "created $symlinks symlinks in user environment\n";
+my $numHooks = 0;
+foreach my $path (@allUniq) {
+ my $hook = "$path/nix-support/post-profile-hook";
+ if (-x $hook){
+ system(($hook, $out, "@allUniq")) == 0 or die "profile-post-hook $hook failed with $? ";
+ $numHooks ++;
+ }
+}
+print STDERR "created $symlinks symlinks in user environment, $numHooks run\n";
symlink($ENV{"manifest"}, "$out/manifest") or die "cannot create manifest";
More information about the nix-dev
mailing list