#! @perl@ -w use strict; my $rootsDir = "@localstatedir@/nix/gcroots/channels"; # 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 () { 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); # 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"; my $hash = `@bindir@/nix-prefetch-url '$fullURL' 2> /dev/null` or die "cannot fetch `$fullURL'"; chomp $hash; # !!! escaping $nixExpr .= "((import @datadir@/nix/corepkgs/fetchurl) " . "{url = $fullURL; md5 = \"$hash\"; system = \"@system@\";}) " } $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 = `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 <