Support tarballs in nix channel URLs
This commit is contained in:
parent
4d652875bd
commit
8a84bd8c8b
2 changed files with 77 additions and 35 deletions
|
@ -6,6 +6,7 @@ use File::Basename;
|
|||
use File::Path qw(mkpath);
|
||||
use Nix::Config;
|
||||
use Nix::Manifest;
|
||||
use File::Temp qw(tempdir);
|
||||
|
||||
binmode STDERR, ":encoding(utf8)";
|
||||
|
||||
|
@ -98,42 +99,14 @@ sub update {
|
|||
my $url = $channels{$name};
|
||||
my $origUrl = "$url/MANIFEST";
|
||||
|
||||
# Check if $url is a redirect. If so, follow it now to ensure
|
||||
# consistency if the redirection is changed between
|
||||
# downloading the manifest and the tarball.
|
||||
my $headers = `$Nix::Config::curl --silent --head '$url'`;
|
||||
# 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`;
|
||||
die "$0: unable to check ‘$url’\n" if $? != 0;
|
||||
$headers =~ s/\r//g;
|
||||
$url = $1 if $headers =~ /^Location:\s*(.*)\s*$/m;
|
||||
|
||||
# Check if the channel advertises a binary cache.
|
||||
my $binaryCacheURL = `$Nix::Config::curl --silent '$url'/binary-cache-url`;
|
||||
my $extraAttrs = "";
|
||||
my $getManifest = ($Nix::Config::config{"force-manifest"} // "false") eq "true";
|
||||
if ($? == 0 && $binaryCacheURL ne "") {
|
||||
$extraAttrs .= "binaryCacheURL = \"$binaryCacheURL\"; ";
|
||||
deleteOldManifests($origUrl, undef);
|
||||
} else {
|
||||
$getManifest = 1;
|
||||
}
|
||||
|
||||
if ($getManifest) {
|
||||
# No binary cache, so pull the channel manifest.
|
||||
mkdir $manifestDir, 0755 unless -e $manifestDir;
|
||||
die "$0: you do not have write permission to ‘$manifestDir’!\n" unless -W $manifestDir;
|
||||
$ENV{'NIX_ORIG_URL'} = $origUrl;
|
||||
system("$Nix::Config::binDir/nix-pull", "--skip-wrong-store", "$url/MANIFEST") == 0
|
||||
or die "cannot pull manifest from ‘$url’\n";
|
||||
}
|
||||
|
||||
# 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;
|
||||
chomp $url;
|
||||
|
||||
# If the URL contains a version number, append it to the name
|
||||
# attribute (so that "nix-env -q" on the channels profile
|
||||
|
@ -141,6 +114,52 @@ sub update {
|
|||
my $cname = $name;
|
||||
$cname .= $1 if basename($url) =~ /(-\d.*)$/;
|
||||
|
||||
my $path;
|
||||
my $ret = -1;
|
||||
if (-e "$tmpdir/$filename") {
|
||||
# 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`;
|
||||
my $getManifest = ($Nix::Config::config{"force-manifest"} // "false") eq "true";
|
||||
if ($? == 0 && $binaryCacheURL ne "") {
|
||||
$extraAttrs .= "binaryCacheURL = \"$binaryCacheURL\"; ";
|
||||
deleteOldManifests($origUrl, undef);
|
||||
} else {
|
||||
$getManifest = 1;
|
||||
}
|
||||
|
||||
if ($getManifest) {
|
||||
# No binary cache, so pull the channel manifest.
|
||||
mkdir $manifestDir, 0755 unless -e $manifestDir;
|
||||
die "$0: you do not have write permission to ‘$manifestDir’!\n" unless -W $manifestDir;
|
||||
$ENV{'NIX_ORIG_URL'} = $origUrl;
|
||||
system("$Nix::Config::binDir/nix-pull", "--skip-wrong-store", "$url/MANIFEST") == 0
|
||||
or die "cannot pull manifest from ‘$url’\n";
|
||||
}
|
||||
|
||||
# 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 }' ";
|
||||
}
|
||||
|
||||
|
|
|
@ -41,3 +41,26 @@ grep -q 'item.*attrPath="foo".*name="dependencies"' $TEST_ROOT/meta.xml
|
|||
# Do an install.
|
||||
nix-env -i dependencies
|
||||
[ -e $TEST_ROOT/var/nix/profiles/default/foobar ]
|
||||
|
||||
|
||||
|
||||
clearProfiles
|
||||
clearManifests
|
||||
rm -f $TEST_ROOT/.nix-channels
|
||||
|
||||
# Test updating from a tarball
|
||||
nix-channel --add file://$TEST_ROOT/foo/nixexprs.tar.bz2
|
||||
nix-channel --update
|
||||
|
||||
# Do a query.
|
||||
nix-env -qa \* --meta --xml --out-path > $TEST_ROOT/meta.xml
|
||||
if [ "$xmllint" != false ]; then
|
||||
$xmllint --noout $TEST_ROOT/meta.xml || fail "malformed XML"
|
||||
fi
|
||||
grep -q 'meta.*description.*Random test package' $TEST_ROOT/meta.xml
|
||||
grep -q 'item.*attrPath="foo".*name="dependencies"' $TEST_ROOT/meta.xml
|
||||
|
||||
# Do an install.
|
||||
nix-env -i dependencies
|
||||
[ -e $TEST_ROOT/var/nix/profiles/default/foobar ]
|
||||
|
||||
|
|
Loading…
Reference in a new issue