diff options
author | Shea Levy <shea@shealevy.com> | 2016-08-11T15·34-0400 |
---|---|---|
committer | Shea Levy <shea@shealevy.com> | 2016-08-11T15·34-0400 |
commit | 59124228b3ac6120e73bc6a88b2c633a70bdf0fc (patch) | |
tree | 7c1c780875b29a86acbf667513376751655af46b /scripts/nix-channel.in | |
parent | a6eed133c5a3602037bc48675ca783185cca5454 (diff) |
nix-channel: implement in c++
Diffstat (limited to 'scripts/nix-channel.in')
-rwxr-xr-x | scripts/nix-channel.in | 228 |
1 files changed, 0 insertions, 228 deletions
diff --git a/scripts/nix-channel.in b/scripts/nix-channel.in deleted file mode 100755 index 65084ff1f34a..000000000000 --- a/scripts/nix-channel.in +++ /dev/null @@ -1,228 +0,0 @@ -#! @perl@ -w @perlFlags@ - -use utf8; -use strict; -use File::Basename; -use File::Path qw(mkpath); -use Nix::Config; -use Nix::Manifest; -use File::Temp qw(tempdir); - -binmode STDERR, ":encoding(utf8)"; - -Nix::Config::readConfig; - - -# Turn on caching in nix-prefetch-url. -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"} or die '$HOME not set\n'; -my $channelsList = "$home/.nix-channels"; -my $nixDefExpr = "$home/.nix-defexpr"; - -# Figure out the name of the channels profile. -my $userName = getpwuid($<) || $ENV{"USER"} or die "cannot figure out user name"; -my $profile = "$Nix::Config::stateDir/profiles/per-user/$userName/channels"; -mkpath(dirname $profile, 0, 0755); - -my %channels; - - -# 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*\#/; - 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. -sub writeChannels { - open CHANNELS, ">$channelsList" or die "cannot open ‘$channelsList’: $!"; - foreach my $name (keys %channels) { - print CHANNELS "$channels{$name} $name\n"; - } - close CHANNELS; -} - - -# Adds a channel. -sub addChannel { - my ($url, $name) = @_; - die "invalid channel URL ‘$url’" unless $url =~ /^(file|http|https):\/\//; - die "invalid channel identifier ‘$name’" unless $name =~ /^[a-zA-Z0-9_][a-zA-Z0-9_\-\.]*$/; - readChannels; - $channels{$name} = $url; - writeChannels; -} - - -# Remove a channel. -sub removeChannel { - my ($name) = @_; - readChannels; - my $url = $channels{$name}; - delete $channels{$name}; - writeChannels; - - system("$Nix::Config::binDir/nix-env --profile '$profile' -e '$name'") == 0 - or die "cannot remove channel ‘$name’\n"; -} - - -# Fetch Nix expressions and binary cache URLs from the subscribed channels. -sub update { - my @channelNames = @_; - - readChannels; - - # Download each channel. - my $exprs = ""; - foreach my $name (keys %channels) { - next if scalar @channelNames > 0 && ! grep { $_ eq $name } @{channelNames}; - - my $url = $channels{$name}; - - # 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`; - chomp $url; - die "$0: unable to check ‘$url’\n" if $? != 0; - - # 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 $path; - my $ret = -1; - if (-e "$tmpdir/$filename" && $filename =~ /\.tar\.(gz|bz2|xz)$/) { - # 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`; - $extraAttrs .= "binaryCacheURL = \"$binaryCacheURL\"; " - if $? == 0 && $binaryCacheURL ne ""; - - # 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 }' "; - } - - # 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($profile, $channelLink) or die "cannot symlink ‘$channelLink’ to ‘$profile’"; -} - - -die "$0: argument expected\n" if scalar @ARGV == 0; - - -while (scalar @ARGV) { - my $arg = shift @ARGV; - - if ($arg eq "--add") { - die "$0: ‘--add’ requires one or two arguments\n" 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") { - die "$0: ‘--remove’ requires one argument\n" if scalar @ARGV != 1; - removeChannel(shift @ARGV); - last; - } - - if ($arg eq "--list") { - die "$0: ‘--list’ requires one argument\n" if scalar @ARGV != 0; - readChannels; - foreach my $name (keys %channels) { - print "$name $channels{$name}\n"; - } - last; - } - - elsif ($arg eq "--update") { - update(@ARGV); - last; - } - - elsif ($arg eq "--rollback") { - die "$0: ‘--rollback’ has at most one argument\n" if scalar @ARGV > 1; - my $generation = shift @ARGV; - my @args = ("$Nix::Config::binDir/nix-env", "--profile", $profile); - if (defined $generation) { - die "invalid channel generation number ‘$generation’" unless $generation =~ /^[0-9]+$/; - push @args, "--switch-generation", $generation; - } else { - push @args, "--rollback"; - } - system(@args) == 0 or exit 1; - last; - } - - elsif ($arg eq "--help") { - exec "man nix-channel" or die; - } - - elsif ($arg eq "--version") { - print "nix-channel (Nix) $Nix::Config::version\n"; - exit 0; - } - - else { - die "unknown argument ‘$arg’; try ‘--help’\n"; - } -} |