diff options
Diffstat (limited to 'scripts')
-rwxr-xr-x | scripts/nix-build.in | 28 | ||||
-rwxr-xr-x | scripts/nix-channel.in | 143 | ||||
-rwxr-xr-x | scripts/nix-copy-closure.in | 10 | ||||
-rwxr-xr-x | scripts/nix-generate-patches.in | 10 | ||||
-rwxr-xr-x | scripts/nix-pull.in | 4 | ||||
-rwxr-xr-x | scripts/nix-push.in | 2 |
6 files changed, 121 insertions, 76 deletions
diff --git a/scripts/nix-build.in b/scripts/nix-build.in index b36ec0208b41..35b186bb715d 100755 --- a/scripts/nix-build.in +++ b/scripts/nix-build.in @@ -14,6 +14,10 @@ my @instArgs = (); my @buildArgs = (); my @exprs = (); +my $shell = $ENV{SHELL} || "/bin/sh"; +my $envCommand = "p=\$PATH; source \$stdenv/setup; PATH=\$PATH:\$p; exec $shell"; +my @envExclude = (); + my $tmpDir = tempdir("nix-build.XXXXXX", CLEANUP => 1, TMPDIR => 1) or die "cannot create a temporary directory"; @@ -41,7 +45,12 @@ Flags: --drv-link NAME: create symlink NAME instead of `derivation' --no-out-link: do not create the `result' symlink --out-link / -o NAME: create symlink NAME instead of `result' - --attr ATTR: select a specific attribution from the Nix expression + --attr / -A ATTR: select a specific attribute from the Nix expression + + --run-env: build dependencies of the specified derivation, then start a + shell with the environment of the derivation + --command: command to run with `--run-env' + --exclude: regexp specifying dependencies to be excluded by `--run-env' Any additional flags are passed to `nix-store'. EOF @@ -125,6 +134,18 @@ EOF $runEnv = 1; } + elsif ($arg eq "--command") { + $n++; + die "$0: `$arg' requires an argument\n" unless $n < scalar @ARGV; + $envCommand = $ARGV[$n]; + } + + elsif ($arg eq "--exclude") { + $n++; + die "$0: `$arg' requires an argument\n" unless $n < scalar @ARGV; + push @envExclude, $ARGV[$n]; + } + elsif (substr($arg, 0, 1) eq "-") { push @buildArgs, $arg; } @@ -155,7 +176,8 @@ foreach my $expr (@exprs) { my $drv = derivationFromPath($drvPath); # Build or fetch all dependencies of the derivation. - system("$Nix::Config::binDir/nix-store -r @buildArgs @{$drv->{inputDrvs}} @{$drv->{inputSrcs}} > /dev/null") == 0 + my @inputDrvs = grep { my $x = $_; (grep { $x =~ $_ } @envExclude) == 0 } @{$drv->{inputDrvs}}; + system("$Nix::Config::binDir/nix-store -r @buildArgs @inputDrvs @{$drv->{inputSrcs}} > /dev/null") == 0 or die "$0: failed to build all dependencies\n"; # Set the environment. @@ -168,7 +190,7 @@ foreach my $expr (@exprs) { # convenience, source $stdenv/setup to setup additional # environment variables. Also don't lose the current $PATH # directories. - exec($ENV{SHELL}, "-c", "p=\$PATH; source \$stdenv/setup; PATH=\$PATH:\$p; exec $ENV{SHELL}"); + exec($ENV{SHELL}, "-c", $envCommand); die; } diff --git a/scripts/nix-channel.in b/scripts/nix-channel.in index ebfc246cfa30..524ffa656451 100755 --- a/scripts/nix-channel.in +++ b/scripts/nix-channel.in @@ -1,6 +1,8 @@ #! @perl@ -w @perlFlags@ use strict; +use File::Basename; +use File::Path qw(make_path); use Nix::Config; my $manifestDir = $Nix::Config::manifestDir; @@ -11,67 +13,67 @@ my $channelCache = "$Nix::Config::stateDir/channel-cache"; mkdir $channelCache, 0755 unless -e $channelCache; $ENV{'NIX_DOWNLOAD_CACHE'} = $channelCache if -W $channelCache; - # Figure out the name of the `.nix-channels' file to use. -my $home = $ENV{"HOME"}; -die '$HOME not set' unless defined $home; +my $home = $ENV{"HOME"} or die '$HOME not set\n'; my $channelsList = "$home/.nix-channels"; - my $nixDefExpr = "$home/.nix-defexpr"; - -my @channels; +# Figure out the name of the channels profile. +my $userName = getpwuid($<) or die "cannot figure out user name"; +my $profile = "$Nix::Config::stateDir/profiles/per-user/$userName/channels"; +make_path(dirname $profile, mode => 0755); + +my %channels; -# Reads the list of channels from the file $channelsList; +# Reads the list of channels. sub readChannels { return if (!-f $channelsList); open CHANNELS, "<$channelsList" or die "cannot open `$channelsList': $!"; while (<CHANNELS>) { chomp; next if /^\s*\#/; - push @channels, $_; + my ($url, $name) = split ' ', $_; + $url =~ s/\/*$//; # remove trailing slashes + $name = basename $url unless defined $name; + $channels{$name} = $url; } close CHANNELS; } -# Writes the list of channels to the file $channelsList; +# Writes the list of channels. sub writeChannels { open CHANNELS, ">$channelsList" or die "cannot open `$channelsList': $!"; - foreach my $url (@channels) { - print CHANNELS "$url\n"; + foreach my $name (keys %channels) { + print CHANNELS "$channels{$name} $name\n"; } close CHANNELS; } -# Adds a channel to the file $channelsList; +# Adds a channel. sub addChannel { - my $url = shift; + my ($url, $name) = @_; readChannels; - foreach my $url2 (@channels) { - return if $url eq $url2; - } - push @channels, $url; + $channels{$name} = $url; writeChannels; } -# Remove a channel from the file $channelsList; +# Remove a channel. sub removeChannel { - my $url = shift; - my @left = (); + my ($name) = @_; readChannels; - foreach my $url2 (@channels) { - push @left, $url2 if $url ne $url2; - } - @channels = @left; + delete $channels{$name}; writeChannels; + + system("$Nix::Config::binDir/nix-env --profile '$profile' -e '$name'") == 0 + or die "cannot remove channel `$name'"; } -# Fetch Nix expressions and pull cache manifests from the subscribed +# Fetch Nix expressions and pull manifests from the subscribed # channels. sub update { readChannels; @@ -82,64 +84,62 @@ sub update { # Do we have write permission to the manifests directory? die "$0: you do not have write permission to `$manifestDir'!\n" unless -W $manifestDir; - # Pull cache manifests. - foreach my $url (@channels) { - #print "pulling cache manifest from `$url'\n"; + # Download each channel. + my $exprs = ""; + foreach my $name (keys %channels) { + 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'`; + die "$0: unable to check `$url'\n" if $? != 0; + $headers =~ s/\r//g; + $url = $1 if $headers =~ /^Location:\s*(.*)\s*$/m; + + # Pull the channel manifest. + $ENV{'NIX_ORIG_URL'} = $origUrl; system("$Nix::Config::binDir/nix-pull", "--skip-wrong-store", "$url/MANIFEST") == 0 - or die "cannot pull cache manifest from `$url'"; - } - - # Create a Nix expression that fetches and unpacks the channel Nix - # expressions. - - my $inputs = "["; - foreach my $url (@channels) { - $url =~ /\/([^\/]+)\/?$/; - my $channelName = $1; - $channelName = "unnamed" unless defined $channelName; + or die "cannot pull manifest from `$url'\n"; + # Download the channel tarball. my $fullURL = "$url/nixexprs.tar.bz2"; - print "downloading Nix expressions from `$fullURL'...\n"; - $ENV{"PRINT_PATH"} = 1; - $ENV{"QUIET"} = 1; - my ($hash, $path) = `$Nix::Config::binDir/nix-prefetch-url '$fullURL'`; + 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'" if $? != 0; chomp $path; - $inputs .= '"' . $channelName . '"' . " " . $path . " "; - } - $inputs .= "]"; - # Figure out a name for the GC root. - my $userName = getpwuid($<); - die "who ARE you? go away" unless defined $userName; + # If the URL contains a version number, append it to the name + # attribute (so that "nix-env -q" on the channels profile + # shows something useful). + my $cname = $name; + $cname .= $1 if basename($url) =~ /(-\d.*)$/; - my $rootFile = "$Nix::Config::stateDir/gcroots/per-user/$userName/channels"; - - # Build the Nix expression. - print "unpacking channel Nix expressions...\n"; - my $outPath = `\\ - $Nix::Config::binDir/nix-build --out-link '$rootFile' --drv-link '$rootFile'.tmp \\ - '<nix/unpack-channel.nix>' \\ - --argstr system @system@ --arg inputs '$inputs'` - or die "cannot unpack the channels"; - chomp $outPath; + $exprs .= "'f: f { name = \"$cname\"; channelName = \"$name\"; src = builtins.storePath \"$path\"; }' "; + } - unlink "$rootFile.tmp"; + # Unpack the channel tarballs into the Nix store and install them + # into the channels profile. + print STDERR "unpacking channels...\n"; + system("$Nix::Config::binDir/nix-env --profile '$profile' " . + "-f '<nix/unpack-channel.nix>' -i -E $exprs --quiet") == 0 + or die "cannot unpack the channels"; # Make the channels appear in nix-env. unlink $nixDefExpr if -l $nixDefExpr; # old-skool ~/.nix-defexpr mkdir $nixDefExpr or die "cannot create directory `$nixDefExpr'" if !-e $nixDefExpr; my $channelLink = "$nixDefExpr/channels"; unlink $channelLink; # !!! not atomic - symlink($outPath, $channelLink) or die "cannot symlink `$channelLink' to `$outPath'"; + symlink($profile, $channelLink) or die "cannot symlink `$channelLink' to `$profile'"; } sub usageError { print STDERR <<EOF; Usage: - nix-channel --add URL - nix-channel --remove URL + nix-channel --add URL [CHANNEL-NAME] + nix-channel --remove CHANNEL-NAME nix-channel --list nix-channel --update EOF @@ -154,22 +154,29 @@ while (scalar @ARGV) { my $arg = shift @ARGV; if ($arg eq "--add") { - usageError if scalar @ARGV != 1; - addChannel (shift @ARGV); + usageError if scalar @ARGV < 1 || scalar @ARGV > 2; + my $url = shift @ARGV; + my $name = shift @ARGV; + unless (defined $name) { + $name = basename $url; + $name =~ s/-unstable//; + $name =~ s/-stable//; + } + addChannel($url, $name); last; } if ($arg eq "--remove") { usageError if scalar @ARGV != 1; - removeChannel (shift @ARGV); + removeChannel(shift @ARGV); last; } if ($arg eq "--list") { usageError if scalar @ARGV != 0; readChannels; - foreach my $url (@channels) { - print "$url\n"; + foreach my $name (keys %channels) { + print "$name $channels{$name}\n"; } last; } diff --git a/scripts/nix-copy-closure.in b/scripts/nix-copy-closure.in index 1ed24d285208..12a83cff979c 100755 --- a/scripts/nix-copy-closure.in +++ b/scripts/nix-copy-closure.in @@ -23,6 +23,8 @@ my $sign = 0; my $compressor = ""; my $decompressor = ""; +my $progressViewer = ""; + my $toMode = 1; my $includeOutputs = 0; @@ -60,6 +62,9 @@ while (@ARGV) { elsif ($arg eq "--include-outputs") { $includeOutputs = 1; } + elsif ($arg eq "--show-progress") { + $progressViewer = "@pv@"; + } elsif ($arg eq "--dry-run") { $dryRun = 1; } @@ -76,7 +81,7 @@ openSSHConnection $sshHost or die "$0: unable to start SSH\n"; if ($toMode) { # Copy TO the remote machine. - Nix::CopyClosure::copyTo($sshHost, [ @sshOpts ], [ @storePaths ], $compressor, $decompressor, $includeOutputs, $dryRun, $sign); + Nix::CopyClosure::copyTo($sshHost, [ @sshOpts ], [ @storePaths ], $compressor, $decompressor, $includeOutputs, $dryRun, $sign, $progressViewer); } else { # Copy FROM the remote machine. @@ -101,9 +106,10 @@ else { # Copy FROM the remote machine. print STDERR "copying ", scalar @missing, " missing paths from ‘$sshHost’...\n"; $compressor = "| $compressor" if $compressor ne ""; $decompressor = "$decompressor |" if $decompressor ne ""; + $progressViewer = "$progressViewer |" if $progressViewer ne ""; unless ($dryRun) { my $extraOpts = $sign ? "--sign" : ""; - system("set -f; ssh $sshHost @sshOpts 'nix-store --export $extraOpts @missing $compressor' | $decompressor $Nix::Config::binDir/nix-store --import > /dev/null") == 0 + system("set -f; ssh $sshHost @sshOpts 'nix-store --export $extraOpts @missing $compressor' | $progressViewer $decompressor $Nix::Config::binDir/nix-store --import > /dev/null") == 0 or die "copying store paths from remote machine `$sshHost' failed: $?"; } } diff --git a/scripts/nix-generate-patches.in b/scripts/nix-generate-patches.in index 4cb843382b52..969af916d8e6 100755 --- a/scripts/nix-generate-patches.in +++ b/scripts/nix-generate-patches.in @@ -39,4 +39,14 @@ generatePatches \%srcNarFiles, \%dstNarFiles, \%srcPatches, \%dstPatches, propagatePatches \%srcPatches, \%dstNarFiles, \%dstPatches; +# Optionally add all new patches to the manifest in $NIX_ALL_PATCHES. +my $allPatchesFile = $ENV{"NIX_ALL_PATCHES"}; +if (defined $allPatchesFile) { + my (%dummy, %allPatches); + readManifest("$patchesPath/all-patches", \%dummy, \%allPatches) + if -f $allPatchesFile; + copyPatches \%dstPatches, \%allPatches; + writeManifest($allPatchesFile, {}, \%allPatches, 0); +} + writeManifest $dstManifest, \%dstNarFiles, \%dstPatches; diff --git a/scripts/nix-pull.in b/scripts/nix-pull.in index 136a5c9fa4bd..8d5db2f57c68 100755 --- a/scripts/nix-pull.in +++ b/scripts/nix-pull.in @@ -50,7 +50,7 @@ sub processURL { my $manifest; # First see if a bzipped manifest is available. - if (system("$Nix::Config::curl --fail --silent --head '$url'.bz2 > /dev/null") == 0) { + if (system("$Nix::Config::curl --fail --silent --location --head '$url'.bz2 > /dev/null") == 0) { print "fetching list of Nix archives at `$url.bz2'...\n"; $manifest = downloadFile "$url.bz2"; } @@ -72,7 +72,7 @@ sub processURL { my $urlFile = "$manifestDir/$baseName-$hash.url"; open URL, ">$urlFile" or die "cannot create `$urlFile'"; - print URL "$url"; + print URL ($ENV{'NIX_ORIG_URL'} || $url); close URL; my $finalPath = "$manifestDir/$baseName-$hash.nixmanifest"; diff --git a/scripts/nix-push.in b/scripts/nix-push.in index 1e0918abd6ac..a1c02190bd6c 100755 --- a/scripts/nix-push.in +++ b/scripts/nix-push.in @@ -103,7 +103,7 @@ foreach my $storePath (@storePaths) { # Construct a Nix expression that creates a Nix archive. my $nixexpr = "(import <nix/nar.nix> " . - "{ storePath = builtins.storePath \"$storePath\"; system = \"@system@\"; hashAlgo = \"$hashAlgo\"; }) "; + "{ storePath = builtins.storePath \"$storePath\"; hashAlgo = \"$hashAlgo\"; }) "; print NIX $nixexpr; } |