about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEelco Dolstra <eelco.dolstra@logicblox.com>2012-12-04T13·20+0100
committerEelco Dolstra <eelco.dolstra@logicblox.com>2012-12-04T13·20+0100
commit5ad89398d12bf8bc83426036dedc2c601ff8f795 (patch)
tree3a23c3fb7347a2e2a2774bef566733a98287211a
parent21c2d8d102add45b8eda61c084aa072f8861a0ff (diff)
nix-env: Install all outputs of a derivation
If you explicitly install a package, presumably you want all of it.
So symlink all outputs in the user environment.
-rw-r--r--corepkgs/buildenv.nix14
-rw-r--r--corepkgs/buildenv.pl33
-rw-r--r--src/nix-env/user-env.cc35
3 files changed, 50 insertions, 32 deletions
diff --git a/corepkgs/buildenv.nix b/corepkgs/buildenv.nix
index 50c9923af79f..923778379263 100644
--- a/corepkgs/buildenv.nix
+++ b/corepkgs/buildenv.nix
@@ -2,18 +2,22 @@ with import <nix/config.nix>;
 
 { derivations, manifest }:
 
-derivation { 
+derivation {
   name = "user-environment";
   system = builtins.currentSystem;
   builder = perl;
   args = [ "-w" ./buildenv.pl ];
-  
+
   manifest = manifest;
 
   # !!! grmbl, need structured data for passing this in a clean way.
-  paths = derivations;
-  active = map (x: if x ? meta && x.meta ? active then x.meta.active else "true") derivations;
-  priority = map (x: if x ? meta && x.meta ? priority then x.meta.priority else "5") derivations;
+  derivations =
+    map (d:
+      [ (if d.meta.active or true then "1" else "0")
+        (d.meta.priority or 5)
+        (builtins.length d.outputs)
+      ] ++ map (output: builtins.getAttr output d) d.outputs)
+      derivations;
 
   # Building user environments remotely just causes huge amounts of
   # network traffic, so don't do that.
diff --git a/corepkgs/buildenv.pl b/corepkgs/buildenv.pl
index 52a703c0668f..3d79e50316fd 100644
--- a/corepkgs/buildenv.pl
+++ b/corepkgs/buildenv.pl
@@ -43,12 +43,12 @@ sub createLinks {
             $srcFile =~ /\/log$/)
         {
             # Do nothing.
-	}
+        }
 
         elsif (-d $srcFile) {
 
             lstat $dstFile;
-            
+
             if (-d _) {
                 createLinks($srcFile, $dstFile, $priority);
             }
@@ -59,7 +59,7 @@ sub createLinks {
                     die "collission between directory `$srcFile' and non-directory `$target'";
                 }
                 unlink $dstFile or die "error unlinking `$dstFile': $!";
-                mkdir $dstFile, 0755 || 
+                mkdir $dstFile, 0755 ||
                     die "error creating directory `$dstFile': $!";
                 createLinks($target, $dstFile, $priorities{$dstFile});
                 createLinks($srcFile, $dstFile, $priority);
@@ -86,7 +86,7 @@ sub createLinks {
                 next if $prevPriority < $priority;
                 unlink $dstFile or die;
             }
-            
+
             symlink($srcFile, $dstFile) ||
                 die "error creating link `$dstFile': $!";
             $priorities{$dstFile} = $priority;
@@ -125,19 +125,18 @@ sub addPkg {
 
 # Convert the stuff we get from the environment back into a coherent
 # data type.
-my @paths = split ' ', $ENV{"paths"};
-my @active = split ' ', $ENV{"active"};
-my @priority = split ' ', $ENV{"priority"};
-
-die if scalar @paths != scalar @active;
-die if scalar @paths != scalar @priority;
-
 my %pkgs;
-
-for (my $n = 0; $n < scalar @paths; $n++) {
-    $pkgs{$paths[$n]} =
-        { active => $active[$n]
-        , priority => $priority[$n] };
+my @derivations = split ' ', $ENV{"derivations"};
+while (scalar @derivations) {
+    my $active = shift @derivations;
+    my $priority = shift @derivations;
+    my $outputs = shift @derivations;
+    for (my $n = 0; $n < $outputs; $n++) {
+        my $path = shift @derivations;
+        $pkgs{$path} =
+            { active => int($active)
+            , priority => int($priority) };
+    }
 }
 
 
@@ -145,7 +144,7 @@ for (my $n = 0; $n < scalar @paths; $n++) {
 # user.
 foreach my $pkg (sort (keys %pkgs)) {
     #print $pkg, " ", $pkgs{$pkg}->{priority}, "\n";
-    addPkg($pkg, $pkgs{$pkg}->{priority}) if $pkgs{$pkg}->{active} ne "false";
+    addPkg($pkg, $pkgs{$pkg}->{priority}) if $pkgs{$pkg}->{active};
 }
 
 
diff --git a/src/nix-env/user-env.cc b/src/nix-env/user-env.cc
index 0a50493fd153..727c4bd44d69 100644
--- a/src/nix-env/user-env.cc
+++ b/src/nix-env/user-env.cc
@@ -54,21 +54,42 @@ bool createUserEnv(EvalState & state, DrvInfos & elems,
     unsigned int n = 0;
     foreach (DrvInfos::iterator, i, elems) {
         /* Create a pseudo-derivation containing the name, system,
-           output path, and optionally the derivation path, as well as
-           the meta attributes. */
+           output paths, and optionally the derivation path, as well
+           as the meta attributes. */
         Path drvPath = keepDerivations ? i->queryDrvPath(state) : "";
 
         Value & v(*state.allocValue());
         manifest.list.elems[n++] = &v;
-        state.mkAttrs(v, 8);
+        state.mkAttrs(v, 16);
 
         mkString(*state.allocAttr(v, state.sType), "derivation");
         mkString(*state.allocAttr(v, state.sName), i->name);
-        mkString(*state.allocAttr(v, state.sSystem), i->system);
+        if (!i->system.empty())
+            mkString(*state.allocAttr(v, state.sSystem), i->system);
         mkString(*state.allocAttr(v, state.sOutPath), i->queryOutPath(state));
         if (drvPath != "")
             mkString(*state.allocAttr(v, state.sDrvPath), i->queryDrvPath(state));
 
+        // Copy each output.
+        DrvInfo::Outputs outputs = i->queryOutputs(state);
+        Value & vOutputs = *state.allocAttr(v, state.sOutputs);
+        state.mkList(vOutputs, outputs.size());
+        unsigned int m = 0;
+        foreach (DrvInfo::Outputs::iterator, j, outputs) {
+            mkString(*(vOutputs.list.elems[m++] = state.allocValue()), j->first);
+            Value & vOutputs = *state.allocAttr(v, state.symbols.create(j->first));
+            state.mkAttrs(vOutputs, 2);
+            mkString(*state.allocAttr(vOutputs, state.sOutPath), j->second);
+
+            /* This is only necessary when installing store paths, e.g.,
+               `nix-env -i /nix/store/abcd...-foo'. */
+            store->addTempRoot(j->second);
+            store->ensurePath(j->second);
+
+            references.insert(j->second);
+        }
+
+        // Copy the meta attributes.
         Value & vMeta = *state.allocAttr(v, state.sMeta);
         state.mkAttrs(vMeta, 16);
 
@@ -95,12 +116,6 @@ bool createUserEnv(EvalState & state, DrvInfos & elems,
         vMeta.attrs->sort();
         v.attrs->sort();
 
-        /* This is only necessary when installing store paths, e.g.,
-           `nix-env -i /nix/store/abcd...-foo'. */
-        store->addTempRoot(i->queryOutPath(state));
-        store->ensurePath(i->queryOutPath(state));
-
-        references.insert(i->queryOutPath(state));
         if (drvPath != "") references.insert(drvPath);
     }