summary refs log tree commit diff
path: root/pkgs/build-support
diff options
context:
space:
mode:
authorDomen Kožar <domen@dev.si>2016-01-19 01:00:09 +0100
committerDomen Kožar <domen@dev.si>2016-01-19 01:00:09 +0100
commit3b381d37ee7d9a70e6e5f668966b7927353091f6 (patch)
tree7ec48fa37698c566ec79c8b72a50320a6e48f69c /pkgs/build-support
parenta79040f3605c894a295abc50693abc8598fb86c2 (diff)
parentbfb11fd0301c1c583319bd2e8211ef434e078792 (diff)
downloadnixlib-3b381d37ee7d9a70e6e5f668966b7927353091f6.tar
nixlib-3b381d37ee7d9a70e6e5f668966b7927353091f6.tar.gz
nixlib-3b381d37ee7d9a70e6e5f668966b7927353091f6.tar.bz2
nixlib-3b381d37ee7d9a70e6e5f668966b7927353091f6.tar.lz
nixlib-3b381d37ee7d9a70e6e5f668966b7927353091f6.tar.xz
nixlib-3b381d37ee7d9a70e6e5f668966b7927353091f6.tar.zst
nixlib-3b381d37ee7d9a70e6e5f668966b7927353091f6.zip
Merge pull request #5096 from aszlig/buildenv-check-collision-contents
buildEnv: Check the content of colliding paths.
Diffstat (limited to 'pkgs/build-support')
-rwxr-xr-xpkgs/build-support/buildenv/builder.pl39
-rw-r--r--pkgs/build-support/buildenv/default.nix8
2 files changed, 38 insertions, 9 deletions
diff --git a/pkgs/build-support/buildenv/builder.pl b/pkgs/build-support/buildenv/builder.pl
index 155af314397b..c505473ee722 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;
     }
 }
 
diff --git a/pkgs/build-support/buildenv/default.nix b/pkgs/build-support/buildenv/default.nix
index 9b8b9daad94d..a9a4d95d7d8f 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.
@@ -39,7 +43,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 ]