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 File::Path qw(mkpath);
|
||||||
use Nix::Config;
|
use Nix::Config;
|
||||||
use Nix::Manifest;
|
use Nix::Manifest;
|
||||||
|
use File::Temp qw(tempdir);
|
||||||
|
|
||||||
binmode STDERR, ":encoding(utf8)";
|
binmode STDERR, ":encoding(utf8)";
|
||||||
|
|
||||||
|
@ -98,42 +99,14 @@ sub update {
|
||||||
my $url = $channels{$name};
|
my $url = $channels{$name};
|
||||||
my $origUrl = "$url/MANIFEST";
|
my $origUrl = "$url/MANIFEST";
|
||||||
|
|
||||||
# Check if $url is a redirect. If so, follow it now to ensure
|
# We want to download the url to a file to see if it's a tarball while also checking if we
|
||||||
# consistency if the redirection is changed between
|
# got redirected in the process, so that we can grab the various parts of a nix channel
|
||||||
# downloading the manifest and the tarball.
|
# definition from a consistent location if the redirect changes mid-download.
|
||||||
my $headers = `$Nix::Config::curl --silent --head '$url'`;
|
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;
|
die "$0: unable to check ‘$url’\n" if $? != 0;
|
||||||
$headers =~ s/\r//g;
|
chomp $url;
|
||||||
$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;
|
|
||||||
|
|
||||||
# If the URL contains a version number, append it to the name
|
# If the URL contains a version number, append it to the name
|
||||||
# attribute (so that "nix-env -q" on the channels profile
|
# attribute (so that "nix-env -q" on the channels profile
|
||||||
|
@ -141,6 +114,52 @@ sub update {
|
||||||
my $cname = $name;
|
my $cname = $name;
|
||||||
$cname .= $1 if basename($url) =~ /(-\d.*)$/;
|
$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 }' ";
|
$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.
|
# Do an install.
|
||||||
nix-env -i dependencies
|
nix-env -i dependencies
|
||||||
[ -e $TEST_ROOT/var/nix/profiles/default/foobar ]
|
[ -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