nix-super/scripts/nix-channel.in
2006-05-08 20:00:28 +00:00

182 lines
4.3 KiB
Text

#! @perl@ -w
use strict;
my $rootsDir = "@localstatedir@/nix/gcroots/channels";
my $stateDir = $ENV{"NIX_STATE_DIR"};
$stateDir = "@localstatedir@/nix" unless defined $stateDir;
# Figure out the name of the `.nix-channels' file to use.
my $home = $ENV{"HOME"};
die '$HOME not set' unless defined $home;
my $channelsList = "$home/.nix-channels";
my @channels;
# Reads the list of channels from the file $channelsList;
sub readChannels {
return if (!-f $channelsList);
open CHANNELS, "<$channelsList" or die "cannot open `$channelsList': $!";
while (<CHANNELS>) {
chomp;
push @channels, $_;
}
close CHANNELS;
}
# Writes the list of channels to the file $channelsList;
sub writeChannels {
open CHANNELS, ">$channelsList" or die "cannot open `$channelsList': $!";
foreach my $url (@channels) {
print CHANNELS "$url\n";
}
close CHANNELS;
}
# Adds a channel to the file $channelsList;
sub addChannel {
my $url = shift;
readChannels;
foreach my $url2 (@channels) {
return if $url eq $url2;
}
push @channels, $url;
writeChannels;
}
# Remove a channel from the file $channelsList;
sub removeChannel {
my $url = shift;
my @left = ();
readChannels;
foreach my $url2 (@channels) {
push @left, $url2 if $url ne $url2;
}
@channels = @left;
writeChannels;
}
# Fetch Nix expressions and pull cache manifests from the subscribed
# channels.
sub update {
readChannels;
# Get rid of all the old substitutes.
system "@bindir@/nix-store --clear-substitutes";
die "cannot clear substitutes" if ($? != 0);
# Remove all the old manifests.
for my $manifest (glob "$stateDir/manifests/*.nixmanifest") {
unlink $manifest or die "cannot remove `$manifest': $!";
}
# Pull cache manifests.
foreach my $url (@channels) {
print "pulling cache manifest from `$url'\n";
system "@bindir@/nix-pull '$url'/MANIFEST";
die "cannot pull cache manifest from `$url'" if ($? != 0);
}
# Create a Nix expression that fetches and unpacks the channel Nix
# expressions.
my $nixExpr = "[";
foreach my $url (@channels) {
my $fullURL = "$url/nixexprs.tar.bz2";
$ENV{"PRINT_PATH"} = 1;
my ($hash, $path) = `@bindir@/nix-prefetch-url '$fullURL' 2> /dev/null`;
die "cannot fetch `$fullURL'" if $? != 0;
chomp $path;
$nixExpr .= $path . " ";
}
$nixExpr .= "]";
$nixExpr =
"(import @datadir@/nix/corepkgs/channels/unpack.nix) " .
"{inputs = $nixExpr; system = \"@system@\";}";
# Figure out a name for the GC root.
my $userName = getpwuid($<);
die "who ARE you? go away" unless defined $userName;
my $rootFile = "$rootsDir/$userName";
# Instantiate the Nix expression.
my $storeExpr = `echo '$nixExpr' | @bindir@/nix-instantiate --add-root '$rootFile'.tmp -`
or die "cannot instantiate Nix expression";
chomp $storeExpr;
# Build the resulting derivation.
my $outPath = `@bindir@/nix-store --add-root '$rootFile' -r '$storeExpr'`
or die "cannot realise store expression";
chomp $outPath;
unlink "$rootFile.tmp";
# Make it the default Nix expression for `nix-env'.
system "@bindir@/nix-env --import '$outPath'";
die "cannot pull set default Nix expression to `$outPath'" if ($? != 0);
}
sub usageError {
print STDERR <<EOF;
Usage:
nix-channel --add URL
nix-channel --remove URL
nix-channel --list
nix-channel --update
EOF
exit 1;
}
usageError if scalar @ARGV == 0;
while (scalar @ARGV) {
my $arg = shift @ARGV;
if ($arg eq "--add") {
usageError if scalar @ARGV != 1;
addChannel (shift @ARGV);
last;
}
if ($arg eq "--remove") {
usageError if scalar @ARGV != 1;
removeChannel (shift @ARGV);
last;
}
if ($arg eq "--list") {
usageError if scalar @ARGV != 0;
readChannels;
foreach my $url (@channels) {
print "$url\n";
}
last;
}
elsif ($arg eq "--update") {
usageError if scalar @ARGV != 0;
update;
last;
}
elsif ($arg eq "--help") {
usageError;
}
else {
die "unknown argument `$arg'; try `--help'";
}
}