about summary refs log tree commit diff
path: root/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'scripts')
-rw-r--r--scripts/local.mk1
-rwxr-xr-xscripts/nix-build.in2
-rwxr-xr-xscripts/nix-channel.in89
-rwxr-xr-xscripts/nix-collect-garbage.in65
-rw-r--r--scripts/nix-profile.sh.in1
5 files changed, 56 insertions, 102 deletions
diff --git a/scripts/local.mk b/scripts/local.mk
index f4c5e8097de4..39e1df611c5c 100644
--- a/scripts/local.mk
+++ b/scripts/local.mk
@@ -1,7 +1,6 @@
 nix_bin_scripts := \
   $(d)/nix-build \
   $(d)/nix-channel \
-  $(d)/nix-collect-garbage \
   $(d)/nix-copy-closure \
   $(d)/nix-generate-patches \
   $(d)/nix-install-package \
diff --git a/scripts/nix-build.in b/scripts/nix-build.in
index 19de6feb6080..5745a1e06e48 100755
--- a/scripts/nix-build.in
+++ b/scripts/nix-build.in
@@ -44,7 +44,7 @@ $SIG{'INT'} = sub { exit 1 };
 # Heuristic to see if we're invoked as a shebang script, namely, if we
 # have a single argument, it's the name of an executable file, and it
 # starts with "#!".
-if ($runEnv && $ARGV[0] !~ /nix-shell/) {
+if ($runEnv && defined $ARGV[0] && $ARGV[0] !~ /nix-shell/) {
     $script = $ARGV[0];
     if (-f $script && -x $script) {
         open SCRIPT, "<$script" or die "$0: cannot open ‘$script’: $!\n";
diff --git a/scripts/nix-channel.in b/scripts/nix-channel.in
index b8c93df18c32..0b499c3f7927 100755
--- a/scripts/nix-channel.in
+++ b/scripts/nix-channel.in
@@ -6,6 +6,7 @@ use File::Basename;
 use File::Path qw(mkpath);
 use Nix::Config;
 use Nix::Manifest;
+use File::Temp qw(tempdir);
 
 binmode STDERR, ":encoding(utf8)";
 
@@ -98,42 +99,14 @@ sub update {
         my $url = $channels{$name};
         my $origUrl = "$url/MANIFEST";
 
-        # Check if $url is a redirect.  If so, follow it now to ensure
-        # consistency if the redirection is changed between
-        # downloading the manifest and the tarball.
-        my $headers = `$Nix::Config::curl --silent --head '$url'`;
+        # We want to download the url to a file to see if it's a tarball while also checking if we
+        # got redirected in the process, so that we can grab the various parts of a nix channel
+        # definition from a consistent location if the redirect changes mid-download.
+        my $tmpdir = tempdir( CLEANUP => 1 );
+        my $filename;
+        ($url, $filename) = `cd $tmpdir && $Nix::Config::curl --silent --write-out '%{url_effective}\n%{filename_effective}' -L '$url' -O`;
         die "$0: unable to check ‘$url’\n" if $? != 0;
-        $headers =~ s/\r//g;
-        $url = $1 if $headers =~ /^Location:\s*(.*)\s*$/m;
-
-        # Check if the channel advertises a binary cache.
-        my $binaryCacheURL = `$Nix::Config::curl --silent '$url'/binary-cache-url`;
-        my $extraAttrs = "";
-        my $getManifest = ($Nix::Config::config{"force-manifest"} // "false") eq "true";
-        if ($? == 0 && $binaryCacheURL ne "") {
-            $extraAttrs .= "binaryCacheURL = \"$binaryCacheURL\"; ";
-            deleteOldManifests($origUrl, undef);
-        } else {
-            $getManifest = 1;
-        }
-
-        if ($getManifest) {
-            # No binary cache, so pull the channel manifest.
-            mkdir $manifestDir, 0755 unless -e $manifestDir;
-            die "$0: you do not have write permission to ‘$manifestDir’!\n" unless -W $manifestDir;
-            $ENV{'NIX_ORIG_URL'} = $origUrl;
-            system("$Nix::Config::binDir/nix-pull", "--skip-wrong-store", "$url/MANIFEST") == 0
-                or die "cannot pull manifest from ‘$url’\n";
-        }
-
-        # Download the channel tarball.
-        my $fullURL = "$url/nixexprs.tar.xz";
-        system("$Nix::Config::curl --fail --silent --head '$fullURL' > /dev/null") == 0 or
-            $fullURL = "$url/nixexprs.tar.bz2";
-        print STDERR "downloading Nix expressions from ‘$fullURL’...\n";
-        my ($hash, $path) = `PRINT_PATH=1 QUIET=1 $Nix::Config::binDir/nix-prefetch-url '$fullURL'`;
-        die "cannot fetch ‘$fullURL’\n" if $? != 0;
-        chomp $path;
+        chomp $url;
 
         # If the URL contains a version number, append it to the name
         # attribute (so that "nix-env -q" on the channels profile
@@ -141,6 +114,52 @@ sub update {
         my $cname = $name;
         $cname .= $1 if basename($url) =~ /(-\d.*)$/;
 
+        my $path;
+        my $ret = -1;
+        if (-e "$tmpdir/$filename") {
+            # Get our temporary download into the store
+            (my $hash, $path) = `PRINT_PATH=1 QUIET=1 $Nix::Config::binDir/nix-prefetch-url 'file://$tmpdir/$filename'`;
+            chomp $path;
+
+            # Try unpacking the expressions to see if they'll be valid for us to process later.
+            # Like anything in nix, this will cache the result so we don't do it again outside of the loop below
+            $ret = system("$Nix::Config::binDir/nix-build --no-out-link -E 'import <nix/unpack-channel.nix> " .
+                          "{ name = \"$cname\"; channelName = \"$name\"; src = builtins.storePath \"$path\"; }'");
+        }
+
+        # The URL doesn't unpack directly, so let's try treating it like a full channel folder with files in it
+        my $extraAttrs = "";
+        if ($ret != 0) {
+            # Check if the channel advertises a binary cache.
+            my $binaryCacheURL = `$Nix::Config::curl --silent '$url'/binary-cache-url`;
+            my $getManifest = ($Nix::Config::config{"force-manifest"} // "false") eq "true";
+            if ($? == 0 && $binaryCacheURL ne "") {
+                $extraAttrs .= "binaryCacheURL = \"$binaryCacheURL\"; ";
+                deleteOldManifests($origUrl, undef);
+            } else {
+                $getManifest = 1;
+            }
+
+            if ($getManifest) {
+                # No binary cache, so pull the channel manifest.
+                mkdir $manifestDir, 0755 unless -e $manifestDir;
+                die "$0: you do not have write permission to ‘$manifestDir’!\n" unless -W $manifestDir;
+                $ENV{'NIX_ORIG_URL'} = $origUrl;
+                system("$Nix::Config::binDir/nix-pull", "--skip-wrong-store", "$url/MANIFEST") == 0
+                    or die "cannot pull manifest from ‘$url’\n";
+            }
+
+            # Download the channel tarball.
+            my $fullURL = "$url/nixexprs.tar.xz";
+            system("$Nix::Config::curl --fail --silent --head '$fullURL' > /dev/null") == 0 or
+                $fullURL = "$url/nixexprs.tar.bz2";
+            print STDERR "downloading Nix expressions from ‘$fullURL’...\n";
+            (my $hash, $path) = `PRINT_PATH=1 QUIET=1 $Nix::Config::binDir/nix-prefetch-url '$fullURL'`;
+            die "cannot fetch ‘$fullURL’\n" if $? != 0;
+            chomp $path;
+        }
+
+        # Regardless of where it came from, add the expression representing this channel to accumulated expression
         $exprs .= "'f: f { name = \"$cname\"; channelName = \"$name\"; src = builtins.storePath \"$path\"; $extraAttrs }' ";
     }
 
diff --git a/scripts/nix-collect-garbage.in b/scripts/nix-collect-garbage.in
deleted file mode 100755
index 55e0ba7a6fab..000000000000
--- a/scripts/nix-collect-garbage.in
+++ /dev/null
@@ -1,65 +0,0 @@
-#! @perl@ -w @perlFlags@
-
-use strict;
-use Nix::Config;
-
-my $profilesDir = "@localstatedir@/nix/profiles";
-
-
-# Process the command line arguments.
-my @args = ();
-my $arg;
-
-my $removeOld = 0;
-my $gen;
-my $dryRun = 0;
-
-while ($arg = shift) {
-    if ($arg eq "--delete-old" || $arg eq "-d") {
-        $removeOld = 1;
-        $gen = "old";
-    } elsif ($arg eq "--delete-older-than") {
-        $removeOld = 1;
-        $gen = shift;
-    } elsif ($arg eq "--dry-run") {
-        $dryRun = 1;
-    } elsif ($arg eq "--help") {
-        exec "man nix-collect-garbage" or die;
-    } else {
-        push @args, $arg;
-    }
-}
-
-
-# If `-d' was specified, remove all old generations of all profiles.
-# Of course, this makes rollbacks to before this point in time
-# impossible.
-
-sub removeOldGenerations;
-sub removeOldGenerations {
-    my $dir = shift;
-
-    my $dh;
-    opendir $dh, $dir or die;
-
-    foreach my $name (sort (readdir $dh)) {
-        next if $name eq "." || $name eq "..";
-        $name = $dir . "/" . $name;
-        if (-l $name && (readlink($name) =~ /link/)) {
-            print STDERR "removing old generations of profile $name\n";
-
-            system("$Nix::Config::binDir/nix-env", "-p", $name, "--delete-generations", $gen, $dryRun ? "--dry-run" : ());
-        }
-        elsif (! -l $name && -d $name) {
-            removeOldGenerations $name;
-        }
-    }
-
-    closedir $dh or die;
-}
-
-removeOldGenerations $profilesDir if $removeOld;
-
-
-# Run the actual garbage collector.
-exec "$Nix::Config::binDir/nix-store", "--gc", @args unless $dryRun;
diff --git a/scripts/nix-profile.sh.in b/scripts/nix-profile.sh.in
index a91b54bd589f..eb34fcd75129 100644
--- a/scripts/nix-profile.sh.in
+++ b/scripts/nix-profile.sh.in
@@ -9,6 +9,7 @@ if [ -n "$HOME" ]; then
     fi
 
     export PATH=$NIX_LINK/bin:$NIX_LINK/sbin:$PATH
+    export MANPATH=$NIX_LINK/share/man:$MANPATH
 
     # Subscribe the user to the Nixpkgs channel by default.
     if [ ! -e $HOME/.nix-channels ]; then