summary refs log tree commit diff
path: root/pkgs/build-support/buildenv
diff options
context:
space:
mode:
authorVladimír Čunát <vcunat@gmail.com>2016-02-03 16:54:03 +0100
committerVladimír Čunát <vcunat@gmail.com>2016-02-03 16:57:19 +0100
commitae74c356d94b795eb07dfe9978788b49b70f5959 (patch)
treec13c6894b75f95d3a4dc4627efef508bb03dfba8 /pkgs/build-support/buildenv
parentc9790126312119ce5a2a8ac946d9f086e7ea9f55 (diff)
parent53e0f8b1cdf36574bfede6e62e2ac2739c3ef804 (diff)
downloadnixpkgs-ae74c356d94b795eb07dfe9978788b49b70f5959.tar
nixpkgs-ae74c356d94b795eb07dfe9978788b49b70f5959.tar.gz
nixpkgs-ae74c356d94b795eb07dfe9978788b49b70f5959.tar.bz2
nixpkgs-ae74c356d94b795eb07dfe9978788b49b70f5959.tar.lz
nixpkgs-ae74c356d94b795eb07dfe9978788b49b70f5959.tar.xz
nixpkgs-ae74c356d94b795eb07dfe9978788b49b70f5959.tar.zst
nixpkgs-ae74c356d94b795eb07dfe9978788b49b70f5959.zip
Merge recent 'staging' into closure-size
Let's get rid of those merge conflicts.
Diffstat (limited to 'pkgs/build-support/buildenv')
-rwxr-xr-xpkgs/build-support/buildenv/builder.pl41
-rw-r--r--pkgs/build-support/buildenv/default.nix8
2 files changed, 39 insertions, 10 deletions
diff --git a/pkgs/build-support/buildenv/builder.pl b/pkgs/build-support/buildenv/builder.pl
index 155af314397..f6cfe52dc31 100755
--- a/pkgs/build-support/buildenv/builder.pl
+++ b/pkgs/build-support/buildenv/builder.pl
@@ -5,6 +5,7 @@ use Cwd 'abs_path';
 use IO::Handle;
 use File::Path;
 use File::Basename;
+use File::Compare;
 use JSON::PP;
 
 STDOUT->autoflush(1);
@@ -38,7 +39,7 @@ for my $p (@pathsToLink) {
 sub findFiles;
 
 sub findFilesInDir {
-    my ($relName, $target, $ignoreCollisions, $priority) = @_;
+    my ($relName, $target, $ignoreCollisions, $checkCollisionContents, $priority) = @_;
 
     opendir DIR, "$target" or die "cannot open `$target': $!";
     my @names = readdir DIR or die;
@@ -46,12 +47,28 @@ sub findFilesInDir {
 
     foreach my $name (@names) {
         next if $name eq "." || $name eq "..";
-        findFiles("$relName/$name", "$target/$name", $name, $ignoreCollisions, $priority);
+        findFiles("$relName/$name", "$target/$name", $name, $ignoreCollisions, $checkCollisionContents, $priority);
     }
 }
 
+sub checkCollision {
+    my ($path1, $path2) = @_;
+
+    my $stat1 = (stat($path1))[2];
+    my $stat2 = (stat($path2))[2];
+
+    if ($stat1 != $stat2) {
+        warn "different permissions in `$path1' and `$path2': "
+           . sprintf("%04o", $stat1 & 07777) . " <-> "
+           . sprintf("%04o", $stat2 & 07777);
+        return 0;
+    }
+
+    return compare($path1, $path2) == 0;
+}
+
 sub findFiles {
-    my ($relName, $target, $baseName, $ignoreCollisions, $priority) = @_;
+    my ($relName, $target, $baseName, $ignoreCollisions, $checkCollisionContents, $priority) = @_;
 
     # Urgh, hacky...
     return if
@@ -82,13 +99,15 @@ sub findFiles {
         if ($ignoreCollisions) {
             warn "collision between `$target' and `$oldTarget'\n" if $ignoreCollisions == 1;
             return;
+        } elsif ($checkCollisionContents && checkCollision($oldTarget, $target)) {
+            return;
         } else {
             die "collision between `$target' and `$oldTarget'\n";
         }
     }
 
-    findFilesInDir($relName, $oldTarget, $ignoreCollisions, $oldPriority) unless $oldTarget eq "";
-    findFilesInDir($relName, $target, $ignoreCollisions, $priority);
+    findFilesInDir($relName, $oldTarget, $ignoreCollisions, $checkCollisionContents, $oldPriority) unless $oldTarget eq "";
+    findFilesInDir($relName, $target, $ignoreCollisions, $checkCollisionContents, $priority);
 
     $symlinks{$relName} = ["", $priority]; # denotes directory
 }
@@ -98,12 +117,12 @@ my %done;
 my %postponed;
 
 sub addPkg {
-    my ($pkgDir, $ignoreCollisions, $priority)  = @_;
+    my ($pkgDir, $ignoreCollisions, $checkCollisionContents, $priority)  = @_;
 
     return if (defined $done{$pkgDir});
     $done{$pkgDir} = 1;
 
-    findFiles("", $pkgDir, "", $ignoreCollisions, $priority);
+    findFiles("", $pkgDir, "", $ignoreCollisions, $checkCollisionContents, $priority);
 
     my $propagatedFN = "$pkgDir/nix-support/propagated-user-env-packages";
     if (-e $propagatedFN) {
@@ -132,7 +151,11 @@ if (exists $ENV{"pkgsPath"}) {
 # user.
 for my $pkg (@{decode_json $pkgs}) {
     for my $path (@{$pkg->{paths}}) {
-        addPkg($path, $ENV{"ignoreCollisions"} eq "1", $pkg->{priority}) if -e $path;
+        addPkg($path,
+               $ENV{"ignoreCollisions"} eq "1",
+               $ENV{"checkCollisionContents"} eq "1",
+               $pkg->{priority})
+           if -e $path;
     }
 }
 
@@ -146,7 +169,7 @@ while (scalar(keys %postponed) > 0) {
     my @pkgDirs = keys %postponed;
     %postponed = ();
     foreach my $pkgDir (sort @pkgDirs) {
-        addPkg($pkgDir, 2, $priorityCounter++);
+        addPkg($pkgDir, 2, $ENV{"checkCollisionContents"} eq "1", $priorityCounter++);
     }
 }
 
diff --git a/pkgs/build-support/buildenv/default.nix b/pkgs/build-support/buildenv/default.nix
index 1a0726d1543..5de02c8ed25 100644
--- a/pkgs/build-support/buildenv/default.nix
+++ b/pkgs/build-support/buildenv/default.nix
@@ -16,6 +16,10 @@
 , # Whether to ignore collisions or abort.
   ignoreCollisions ? false
 
+, # If there is a collision, check whether the contents and permissions match
+  # and only if not, throw a collision error.
+  checkCollisionContents ? true
+
 , # The paths (relative to each element of `paths') that we want to
   # symlink (e.g., ["/bin"]).  Any file not inside any of the
   # directories in the list is not symlinked.
@@ -35,7 +39,9 @@
 }:
 
 runCommand name
-  rec { inherit manifest ignoreCollisions passthru meta pathsToLink extraPrefix postBuild buildInputs;
+  rec {
+    inherit manifest ignoreCollisions checkCollisionContents passthru
+            meta pathsToLink extraPrefix postBuild buildInputs;
     pkgs = builtins.toJSON (map (drv: {
       paths = [ drv ];
       priority = drv.meta.priority or 5;