about summary refs log tree commit diff
path: root/scripts/nix-channel.in
diff options
context:
space:
mode:
authorEelco Dolstra <e.dolstra@tudelft.nl>2004-04-21T14·54+0000
committerEelco Dolstra <e.dolstra@tudelft.nl>2004-04-21T14·54+0000
commit21655a70f5a6e80b477d8bf758aa24eb0fcbdbfe (patch)
tree6a322bfa5291ede4d00d5d07c4d2c5a3ae395dac /scripts/nix-channel.in
parentf79e9c2d22345eeb0c721a8cf5375101d33dc4c9 (diff)
* Channels. These allow you to stay current with an evolving set of
  Nix expressions.

  To subscribe to a channel (needs to be done only once):

    nix-channel --add \
      http://catamaran.labs.cs.uu.nl/dist/nix/channels/nixpkgs-unstable

  This just adds the given URL to ~/.nix-channels (which can also be
  edited manually).

  To update from all channels:

    nix-channel --update

  This fetches the latest expressions and pulls cache manifests.  The
  default Nix expression (~/.nix-defexpr) is made to point to the
  conjunction of the expressions downloaded from all channels.

  So to update all installed derivations in the current user
  environment:

    nix-channel --update
    nix-env --upgrade '*'

  If you are really courageous, you can put this in a cronjob or
  something.

  You can subscribe to multiple channels.  It is not entirely clear
  what happens when there are name clashes between derivations from
  different channels.  From nix-env/main.cc it appears that the one
  with the lowest (highest?) hash will be used, which is pretty
  meaningless.

Diffstat (limited to 'scripts/nix-channel.in')
-rwxr-xr-xscripts/nix-channel.in115
1 files changed, 115 insertions, 0 deletions
diff --git a/scripts/nix-channel.in b/scripts/nix-channel.in
new file mode 100755
index 0000000000..f554380e28
--- /dev/null
+++ b/scripts/nix-channel.in
@@ -0,0 +1,115 @@
+#! @perl@ -w
+
+use strict;
+
+
+# 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;
+}
+
+
+# Fetch Nix expressions and pull cache manifests from the subscribed
+# channels.
+sub update {
+    readChannels;
+
+    # 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@\";}";
+
+    # Instantiate and realise it.
+    my $storeExpr = `echo '$nixExpr' | @bindir@/nix-instantiate -`
+        or die "cannot instantiate Nix expression";
+    chomp $storeExpr;
+
+    my $outPath = `nix-store -qnfB '$storeExpr'`
+        or die "cannot realise store expression";
+    chomp $outPath;
+
+    # 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);
+}
+
+
+while (scalar @ARGV) {
+    my $arg = shift @ARGV;
+
+    if ($arg eq "--add") {
+        die "syntax: nix-channel --add URL" if (scalar @ARGV != 1);
+        addChannel (shift @ARGV);
+        last;
+    }
+
+    elsif ($arg eq "--update") {
+        die "syntax: nix-channel --update" if (scalar @ARGV != 0);
+        update;
+        last;
+    }
+
+    else {
+        die "unknown argument `$arg'";
+    }
+}