* 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.
			
			
This commit is contained in:
		
							parent
							
								
									f79e9c2d22
								
							
						
					
					
						commit
						21655a70f5
					
				
					 10 changed files with 194 additions and 52 deletions
				
			
		|  | @ -140,6 +140,7 @@ AC_CONFIG_FILES([Makefile | |||
|    corepkgs/fetchurl/Makefile | ||||
|    corepkgs/nar/Makefile | ||||
|    corepkgs/buildenv/Makefile | ||||
|    corepkgs/channels/Makefile | ||||
|    doc/Makefile | ||||
|    doc/manual/Makefile | ||||
|   ]) | ||||
|  |  | |||
|  | @ -1 +1 @@ | |||
| SUBDIRS = fetchurl nar buildenv | ||||
| SUBDIRS = fetchurl nar buildenv channels | ||||
|  |  | |||
							
								
								
									
										11
									
								
								corepkgs/channels/Makefile.am
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								corepkgs/channels/Makefile.am
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,11 @@ | |||
| all-local: unpack.sh | ||||
| 
 | ||||
| install-exec-local: | ||||
| 	$(INSTALL) -d $(DESTDIR)$(datadir)/nix/corepkgs | ||||
| 	$(INSTALL) -d $(DESTDIR)$(datadir)/nix/corepkgs/channels | ||||
| 	$(INSTALL_DATA) unpack.nix $(DESTDIR)$(datadir)/nix/corepkgs/channels | ||||
| 	$(INSTALL_PROGRAM) unpack.sh $(DESTDIR)$(datadir)/nix/corepkgs/channels | ||||
| 
 | ||||
| include ../../substitute.mk | ||||
| 
 | ||||
| EXTRA_DIST = default.nix unpack.sh.in | ||||
							
								
								
									
										7
									
								
								corepkgs/channels/unpack.nix
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								corepkgs/channels/unpack.nix
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,7 @@ | |||
| {system, inputs}: | ||||
| 
 | ||||
| derivation { | ||||
|   name = "channels"; | ||||
|   builder = ./unpack.sh; | ||||
|   inherit system inputs; | ||||
| } | ||||
							
								
								
									
										24
									
								
								corepkgs/channels/unpack.sh.in
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								corepkgs/channels/unpack.sh.in
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,24 @@ | |||
| #! @shell@ -e | ||||
| 
 | ||||
| export PATH=/bin:/usr/bin # !!! impure | ||||
| 
 | ||||
| mkdir $out | ||||
| mkdir $out/tmp | ||||
| cd $out/tmp | ||||
| 
 | ||||
| expr=$out/default.nix | ||||
| echo '[' > $expr | ||||
| 
 | ||||
| nr=0 | ||||
| for i in $inputs; do | ||||
|     echo "unpacking $i" | ||||
|     @bunzip2@ < $i | tar xvf - | ||||
|     mv * ../$nr # !!! hacky | ||||
|     echo "(import ./$nr)" >> $expr | ||||
|     nr=$(($nr + 1)) | ||||
| done | ||||
| 
 | ||||
| echo ']' >> $expr | ||||
| 
 | ||||
| cd .. | ||||
| rmdir tmp | ||||
|  | @ -1,8 +1,8 @@ | |||
| {system, url, md5}: derivation { | ||||
| {system, url, md5}: | ||||
| 
 | ||||
| derivation { | ||||
|   name = baseNameOf (toString url); | ||||
|   system = system; | ||||
|   builder = ./builder.sh; | ||||
|   url = url; | ||||
|   md5 = md5; | ||||
|   id = md5; | ||||
|   inherit system url md5; | ||||
| } | ||||
|  |  | |||
|  | @ -1,6 +1,6 @@ | |||
| bin_SCRIPTS = nix-collect-garbage \ | ||||
|  nix-pull nix-push nix-prefetch-url \ | ||||
|  nix-install-package | ||||
|  nix-install-package nix-channel | ||||
| 
 | ||||
| noinst_SCRIPTS = nix-profile.sh | ||||
| 
 | ||||
|  | @ -20,4 +20,5 @@ include ../substitute.mk | |||
| EXTRA_DIST = nix-collect-garbage.in \ | ||||
|  nix-pull.in nix-push.in nix-profile.sh.in \ | ||||
|  nix-prefetch-url.in nix-install-package.in \ | ||||
|  nix-channel.in \ | ||||
|  prebuilts.conf readmanifest.pm.in | ||||
|  |  | |||
							
								
								
									
										115
									
								
								scripts/nix-channel.in
									
										
									
									
									
										Executable file
									
								
							
							
						
						
									
										115
									
								
								scripts/nix-channel.in
									
										
									
									
									
										Executable file
									
								
							|  | @ -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'"; | ||||
|     } | ||||
| } | ||||
|  | @ -1,56 +1,37 @@ | |||
| #! @perl@ -w | ||||
| #! @shell@ -e | ||||
| 
 | ||||
| use strict; | ||||
| use IPC::Open2; | ||||
| url=$1 | ||||
| 
 | ||||
| my $url = shift @ARGV; | ||||
| defined $url or die; | ||||
| if test -z "$url"; then | ||||
|     echo "syntax: nix-prefetch-url URL" >&2 | ||||
|     exit 1 | ||||
| fi | ||||
| 
 | ||||
| print "fetching $url...\n"; | ||||
| # !!! race? should be relatively safe, `svn export' barfs if $tmpPath exists. | ||||
| tmpPath1=@storedir@/nix-prefetch-url-$$ | ||||
| 
 | ||||
| my $out = "@storedir@/nix-prefetch-url-$$"; | ||||
| # Perform the checkout. | ||||
| @curl@ --fail --location --max-redirs 20 "$url" > $tmpPath1 | ||||
| 
 | ||||
| system "@curl@ --fail --location --max-redirs 20 \"$url\" > \"$out\""; | ||||
| $? == 0 or die "unable to fetch $url"; | ||||
| # Compute the hash. | ||||
| hash=$(@bindir@/nix-hash --flat $tmpPath1) | ||||
| echo "hash is $hash" >&2 | ||||
| 
 | ||||
| my $hash=`@bindir@/nix-hash --flat $out`; | ||||
| $? == 0 or die "unable to hash $out"; | ||||
| chomp $hash; | ||||
| # Rename it so that the fetchsvn builder can find it. | ||||
| tmpPath2=@storedir@/nix-prefetch-url-$hash | ||||
| test -e $tmpPath2 || mv $tmpPath1 $tmpPath2 # !!! race | ||||
| 
 | ||||
| print "file has hash $hash\n"; | ||||
| # Create a Nix expression that does a fetchsvn. | ||||
| storeExpr=$( \ | ||||
|   echo "(import @datadir@/nix/corepkgs/fetchurl) \ | ||||
|         {url = $url; md5 = \"$hash\"; system = \"@system@\";}" \ | ||||
|   | nix-instantiate -) | ||||
| 
 | ||||
| my $out2 = "@storedir@/nix-prefetch-url-$hash"; | ||||
| rename $out, $out2; | ||||
| # Realise it. | ||||
| finalPath=$(nix-store -qnB --force-realise $storeExpr) | ||||
| 
 | ||||
| # Create a Nix expression. | ||||
| my $nixexpr = | ||||
|     "(import @datadir@/nix/corepkgs/fetchurl) " . | ||||
|     "{url = $url; md5 = \"$hash\"; system = \"@system@\";}"; | ||||
| echo "path is $finalPath" >&2 | ||||
| 
 | ||||
| #print STDERR "expr: $nixexpr\n"; | ||||
| rm -rf $tmpPath2 || true | ||||
| 
 | ||||
| # Instantiate a Nix expression. | ||||
| #print STDERR "instantiating Nix expression...\n"; | ||||
| my $pid = open2(\*READ, \*WRITE, "@bindir@/nix-instantiate -") | ||||
|     or die "cannot run nix-instantiate"; | ||||
| 
 | ||||
| print WRITE $nixexpr; | ||||
| close WRITE; | ||||
| 
 | ||||
| my $drvpath = <READ>; | ||||
| chomp $drvpath; | ||||
| 
 | ||||
| waitpid $pid, 0; | ||||
| $? == 0 or die "nix-instantiate failed"; | ||||
| 
 | ||||
| # Run Nix. | ||||
| #print STDERR "realising store expression $drvpath...\n"; | ||||
| system "@bindir@/nix-store --realise $drvpath > /dev/null"; | ||||
| $? == 0 or die "realisation failed"; | ||||
| 
 | ||||
| my $path = `@bindir@/nix-store -qn $drvpath`; | ||||
| $? == 0 or die "query failed"; | ||||
| 
 | ||||
| print "path is $path"; | ||||
| 
 | ||||
| unlink $out2; | ||||
| echo $hash | ||||
|  |  | |||
|  | @ -12,7 +12,9 @@ my $manifest = "$tmpdir/MANIFEST"; | |||
| 
 | ||||
| END { unlink $manifest; unlink $nixfile; rmdir $tmpdir; } | ||||
| 
 | ||||
| my $curl = "@curl@ --fail --silent ${ENV{'CURL_FLAGS'}}"; | ||||
| my $curl = "@curl@ --fail --silent"; | ||||
| my $extraCurlFlags = ${ENV{'CURL_FLAGS'}}; | ||||
| $curl = "$curl $extraCurlFlags" if defined $extraCurlFlags; | ||||
| 
 | ||||
| 
 | ||||
| # Parse the command line. | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue