diff options
-rw-r--r-- | Makefile | 1 | ||||
-rw-r--r-- | doc/manual/command-ref/nix-env.xml | 4 | ||||
-rw-r--r-- | doc/manual/command-ref/nix-prefetch-url.xml | 28 | ||||
-rw-r--r-- | local.mk | 3 | ||||
-rw-r--r-- | perl/local.mk | 4 | ||||
-rw-r--r-- | release.nix | 2 | ||||
-rw-r--r-- | scripts/download-from-binary-cache.pl.in | 7 | ||||
-rw-r--r-- | scripts/local.mk | 1 | ||||
-rwxr-xr-x | scripts/nix-prefetch-url.in | 132 | ||||
-rw-r--r-- | src/libexpr/local.mk | 2 | ||||
-rw-r--r-- | src/libmain/shared.hh | 2 | ||||
-rw-r--r-- | src/libstore/build.cc | 8 | ||||
-rw-r--r-- | src/libstore/local-store.hh | 58 | ||||
-rw-r--r-- | src/libstore/remote-store.hh | 59 | ||||
-rw-r--r-- | src/libutil/hash.cc | 1 | ||||
-rw-r--r-- | src/libutil/util.hh | 1 | ||||
-rw-r--r-- | src/nix-env/nix-env.cc | 22 | ||||
-rw-r--r-- | src/nix-prefetch-url/local.mk | 7 | ||||
-rw-r--r-- | src/nix-prefetch-url/nix-prefetch-url.cc | 168 |
19 files changed, 288 insertions, 222 deletions
diff --git a/Makefile b/Makefile index fe2e88a995aa..3a204de888cc 100644 --- a/Makefile +++ b/Makefile @@ -13,6 +13,7 @@ makefiles = \ src/nix-collect-garbage/local.mk \ src/download-via-ssh/local.mk \ src/nix-log2xml/local.mk \ + src/nix-prefetch-url/local.mk \ src/bsdiff-4.3/local.mk \ perl/local.mk \ scripts/local.mk \ diff --git a/doc/manual/command-ref/nix-env.xml b/doc/manual/command-ref/nix-env.xml index 5e40317f189d..e9a5f0e097c4 100644 --- a/doc/manual/command-ref/nix-env.xml +++ b/doc/manual/command-ref/nix-env.xml @@ -378,7 +378,7 @@ number of possible ways: <variablelist> - <varlistentry><term><option>--prebuild-only</option> / <option>-b</option></term> + <varlistentry><term><option>--prebuilt-only</option> / <option>-b</option></term> <listitem><para>Use only derivations for which a substitute is registered, i.e., there is a pre-built binary available that can @@ -1012,7 +1012,7 @@ user environment elements, etc. --> </varlistentry> - <varlistentry><term><option>--prebuild-only</option> / <option>-b</option></term> + <varlistentry><term><option>--prebuilt-only</option> / <option>-b</option></term> <listitem><para>Show only derivations for which a substitute is registered, i.e., there is a pre-built binary available that can diff --git a/doc/manual/command-ref/nix-prefetch-url.xml b/doc/manual/command-ref/nix-prefetch-url.xml index 5d1ab6931cd3..9cbaa42a1b1f 100644 --- a/doc/manual/command-ref/nix-prefetch-url.xml +++ b/doc/manual/command-ref/nix-prefetch-url.xml @@ -3,7 +3,7 @@ xmlns:xi="http://www.w3.org/2001/XInclude" version="5.0" xml:id="sec-nix-prefetch-url"> - + <refmeta> <refentrytitle>nix-prefetch-url</refentrytitle> <manvolnum>1</manvolnum> @@ -20,6 +20,7 @@ <cmdsynopsis> <command>nix-prefetch-url</command> <arg><option>--type</option> <replaceable>hashAlgo</replaceable></arg> + <arg><option>--print-path</option></arg> <arg choice='plain'><replaceable>url</replaceable></arg> <arg><replaceable>hash</replaceable></arg> </cmdsynopsis> @@ -54,8 +55,8 @@ error if signaled if the actual hash of the file does not match the specified hash.</para> <para>This command prints the hash on standard output. Additionally, -if the environment variable <envar>PRINT_PATH</envar> is set, the path -of the downloaded file in the Nix store is also printed.</para> +if the option <option>--print-path</option> is used, the path of the +downloaded file in the Nix store is also printed.</para> </refsection> @@ -63,7 +64,7 @@ of the downloaded file in the Nix store is also printed.</para> <refsection><title>Options</title> <variablelist> - + <varlistentry><term><option>--type</option> <replaceable>hashAlgo</replaceable></term> <listitem><para>Use the specified cryptographic hash algorithm, @@ -73,6 +74,13 @@ of the downloaded file in the Nix store is also printed.</para> </varlistentry> + <varlistentry><term><option>--print-path</option></term> + + <listitem><para>Print the store path of the downloaded file on + standard output.</para></listitem> + + </varlistentry> + </variablelist> </refsection> @@ -81,14 +89,14 @@ of the downloaded file in the Nix store is also printed.</para> <refsection><title>Examples</title> <screen> -$ nix-prefetch-url ftp://ftp.nluug.nl/pub/gnu/make/make-3.80.tar.bz2 -0bbd1df101bc0294d440471e50feca71 +$ nix-prefetch-url ftp://ftp.gnu.org/pub/gnu/hello/hello-2.10.tar.gz +0ssi1wpaf7plaswqqjwigppsg5fyh99vdlb9kzl7c9lng89ndq1i -$ PRINT_PATH=1 nix-prefetch-url ftp://ftp.nluug.nl/pub/gnu/make/make-3.80.tar.bz2 -0bbd1df101bc0294d440471e50feca71 -/nix/store/wvyz8ifdn7wyz1p3pqyn0ra45ka2l492-make-3.80.tar.bz2</screen> +$ nix-prefetch-url --print-path mirror://gnu/hello/hello-2.10.tar.gz +0ssi1wpaf7plaswqqjwigppsg5fyh99vdlb9kzl7c9lng89ndq1i +/nix/store/3x7dwzq014bblazs7kq20p9hyzz0qh8g-hello-2.10.tar.gz</screen> </refsection> - + </refentry> diff --git a/local.mk b/local.mk index 25957d92a659..160057ad2625 100644 --- a/local.mk +++ b/local.mk @@ -6,7 +6,8 @@ dist-files += configure config.h.in nix.spec clean-files += Makefile.config -GLOBAL_CXXFLAGS += -I . -I src -I src/libutil -I src/libstore -I src/libmain -I src/libexpr +GLOBAL_CXXFLAGS += -I . -I src -I src/libutil -I src/libstore -I src/libmain -I src/libexpr \ + -Wno-unneeded-internal-declaration $(foreach i, config.h $(call rwildcard, src/lib*, *.hh) src/nix-store/serve-protocol.hh, \ $(eval $(call install-file-in, $(i), $(includedir)/nix, 0644))) diff --git a/perl/local.mk b/perl/local.mk index 132676f53341..ed49e3e6685e 100644 --- a/perl/local.mk +++ b/perl/local.mk @@ -24,7 +24,9 @@ ifeq ($(perlbindings), yes) Store_CXXFLAGS = \ -I$(shell $(perl) -e 'use Config; print $$Config{archlibexp};')/CORE \ - -D_FILE_OFFSET_BITS=64 -Wno-unused-variable -Wno-literal-suffix -Wno-reserved-user-defined-literal + -D_FILE_OFFSET_BITS=64 \ + -Wno-unknown-warning-option -Wno-unused-variable -Wno-literal-suffix \ + -Wno-reserved-user-defined-literal -Wno-duplicate-decl-specifier -Wno-pointer-bool-conversion Store_LIBS = libstore libutil diff --git a/release.nix b/release.nix index cfec7b9e774c..5a5a1226fe2c 100644 --- a/release.nix +++ b/release.nix @@ -24,7 +24,7 @@ let buildInputs = [ curl bison flex perl libxml2 libxslt bzip2 - tetex dblatex nukeReferences pkgconfig sqlite libsodium + dblatex (dblatex.tex or tetex) nukeReferences pkgconfig sqlite libsodium docbook5 docbook5_xsl ] ++ lib.optional (!lib.inNixShell) git; diff --git a/scripts/download-from-binary-cache.pl.in b/scripts/download-from-binary-cache.pl.in index bb63eafca522..ea053bf14da4 100644 --- a/scripts/download-from-binary-cache.pl.in +++ b/scripts/download-from-binary-cache.pl.in @@ -80,7 +80,12 @@ sub addRequest { $curl->setopt(CURLOPT_WRITEDATA, $fh); $curl->setopt(CURLOPT_FOLLOWLOCATION, 1); $curl->setopt(CURLOPT_CAINFO, $caBundle) if defined $caBundle; - $curl->setopt(CURLOPT_SSL_VERIFYPEER, 0) unless isTrue($Nix::Config::config{"verify-https-binary-caches"} // "1"); + + unless (isTrue($Nix::Config::config{"verify-https-binary-caches"} // "1")) { + $curl->setopt(CURLOPT_SSL_VERIFYPEER, 0); + $curl->setopt(CURLOPT_SSL_VERIFYHOST, 0); + } + $curl->setopt(CURLOPT_USERAGENT, $userAgent); $curl->setopt(CURLOPT_NOBODY, 1) if $head; $curl->setopt(CURLOPT_FAILONERROR, 1); diff --git a/scripts/local.mk b/scripts/local.mk index 39e1df611c5c..3fb47676fa54 100644 --- a/scripts/local.mk +++ b/scripts/local.mk @@ -4,7 +4,6 @@ nix_bin_scripts := \ $(d)/nix-copy-closure \ $(d)/nix-generate-patches \ $(d)/nix-install-package \ - $(d)/nix-prefetch-url \ $(d)/nix-pull \ $(d)/nix-push diff --git a/scripts/nix-prefetch-url.in b/scripts/nix-prefetch-url.in deleted file mode 100755 index 6effbe208146..000000000000 --- a/scripts/nix-prefetch-url.in +++ /dev/null @@ -1,132 +0,0 @@ -#! @perl@ -w @perlFlags@ - -use utf8; -use strict; -use File::Basename; -use File::stat; -use Nix::Store; -use Nix::Config; -use Nix::Utils; - -binmode STDERR, ":encoding(utf8)"; - - -my $hashType = $ENV{'NIX_HASH_ALGO'} || "sha256"; # obsolete -my $cacheDir = $ENV{'NIX_DOWNLOAD_CACHE'}; - -my @args; -my $arg; -while ($arg = shift) { - if ($arg eq "--help") { - exec "man nix-prefetch-url" or die; - } elsif ($arg eq "--type") { - $hashType = shift; - die "$0: ‘$arg’ requires an argument\n" unless defined $hashType; - } elsif (substr($arg, 0, 1) eq "-") { - die "$0: unknown flag ‘$arg’\n"; - } else { - push @args, $arg; - } -} - -my $url = $args[0]; -my $expHash = $args[1]; - - -if (!defined $url || $url eq "") { - print STDERR <<EOF -Usage: nix-prefetch-url URL [EXPECTED-HASH] -EOF - ; - exit 1; -} - -my $tmpDir = mkTempDir("nix-prefetch-url"); - -# Hack to support the mirror:// scheme from Nixpkgs. -if ($url =~ /^mirror:\/\//) { - system("$Nix::Config::binDir/nix-build '<nixpkgs>' -A resolveMirrorURLs --argstr url '$url' -o $tmpDir/urls > /dev/null") == 0 - or die "$0: nix-build failed; maybe \$NIX_PATH is not set properly\n"; - my @expanded = split ' ', readFile("$tmpDir/urls"); - die "$0: cannot resolve ‘$url’" unless scalar @expanded > 0; - print STDERR "$url expands to $expanded[0]\n"; - $url = $expanded[0]; -} - -# Handle escaped characters in the URI. `+', `=' and `?' are the only -# characters that are valid in Nix store path names but have a special -# meaning in URIs. -my $name = basename $url; -die "cannot figure out file name for ‘$url’\n" if $name eq ""; -$name =~ s/%2b/+/g; -$name =~ s/%3d/=/g; -$name =~ s/%3f/?/g; - -my $finalPath; -my $hash; - -# If the hash was given, a file with that hash may already be in the -# store. -if (defined $expHash) { - $finalPath = makeFixedOutputPath(0, $hashType, $expHash, $name); - if (isValidPath($finalPath)) { $hash = $expHash; } else { $finalPath = undef; } -} - -# If we don't know the hash or a file with that hash doesn't exist, -# download the file and add it to the store. -if (!defined $finalPath) { - - my $tmpFile = "$tmpDir/$name"; - - # Optionally do timestamp-based caching of the download. - # Actually, the only thing that we cache in $NIX_DOWNLOAD_CACHE is - # the hash and the timestamp of the file at $url. The caching of - # the file *contents* is done in Nix store, where it can be - # garbage-collected independently. - my ($cachedTimestampFN, $cachedHashFN, @cacheFlags); - if (defined $cacheDir) { - my $urlHash = hashString("sha256", 1, $url); - writeFile "$cacheDir/$urlHash.url", $url; - $cachedHashFN = "$cacheDir/$urlHash.$hashType"; - $cachedTimestampFN = "$cacheDir/$urlHash.stamp"; - @cacheFlags = ("--time-cond", $cachedTimestampFN) if -f $cachedHashFN && -f $cachedTimestampFN; - } - - # Perform the download. - my @curlFlags = ("curl", $url, "-o", $tmpFile, "--fail", "--location", "--max-redirs", "20", "--disable-epsv", "--cookie-jar", "$tmpDir/cookies", "--remote-time", (split " ", ($ENV{NIX_CURL_FLAGS} || ""))); - (system $Nix::Config::curl @curlFlags, @cacheFlags) == 0 or die "$0: download of ‘$url’ failed\n"; - - if (defined $cacheDir && ! -e $tmpFile) { - # Curl didn't create $tmpFile, so apparently there's no newer - # file on the server. - $hash = readFile $cachedHashFN or die; - $finalPath = makeFixedOutputPath(0, $hashType, $hash, $name); - unless (isValidPath $finalPath) { - print STDERR "cached contents of ‘$url’ disappeared, redownloading...\n"; - $finalPath = undef; - (system $Nix::Config::curl @curlFlags) == 0 or die "$0: download of ‘$url’ failed\n"; - } - } - - if (!defined $finalPath) { - - # Compute the hash. - $hash = hashFile($hashType, $hashType ne "md5", $tmpFile); - - if (defined $cacheDir) { - writeFile $cachedHashFN, $hash; - my $st = stat($tmpFile) or die; - open STAMP, ">$cachedTimestampFN" or die; close STAMP; - utime($st->atime, $st->mtime, $cachedTimestampFN) or die; - } - - # Add the downloaded file to the Nix store. - $finalPath = addToStore($tmpFile, 0, $hashType); - } - - die "$0: hash mismatch for ‘$url’\n" if defined $expHash && $expHash ne $hash; -} - -print STDERR "path is ‘$finalPath’\n" unless $ENV{'QUIET'}; -print "$hash\n"; -print "$finalPath\n" if $ENV{'PRINT_PATH'}; diff --git a/src/libexpr/local.mk b/src/libexpr/local.mk index 4c1f4de19187..d1b1987fb037 100644 --- a/src/libexpr/local.mk +++ b/src/libexpr/local.mk @@ -6,6 +6,8 @@ libexpr_DIR := $(d) libexpr_SOURCES := $(wildcard $(d)/*.cc) $(d)/lexer-tab.cc $(d)/parser-tab.cc +libexpr_CXXFLAGS := -Wno-deprecated-register + libexpr_LIBS = libutil libstore libformat libexpr_LDFLAGS = -ldl diff --git a/src/libmain/shared.hh b/src/libmain/shared.hh index a7e6ef762120..65b288e1ff3e 100644 --- a/src/libmain/shared.hh +++ b/src/libmain/shared.hh @@ -88,7 +88,7 @@ extern volatile ::sig_atomic_t blockInt; string showBytes(unsigned long long bytes); -class GCResults; +struct GCResults; struct PrintFreed { diff --git a/src/libstore/build.cc b/src/libstore/build.cc index c1163e63d90f..70278a8785d6 100644 --- a/src/libstore/build.cc +++ b/src/libstore/build.cc @@ -806,7 +806,7 @@ public: void timedOut() override; - string key() + string key() override { /* Ensure that derivations get built in order of their name, i.e. a derivation named "aardvark" always comes before @@ -815,7 +815,7 @@ public: return "b$" + storePathToName(drvPath) + "$" + drvPath; } - void work(); + void work() override; Path getDrvPath() { @@ -863,8 +863,8 @@ private: void deleteTmpDir(bool force); /* Callback used by the worker to write to the log. */ - void handleChildOutput(int fd, const string & data); - void handleEOF(int fd); + void handleChildOutput(int fd, const string & data) override; + void handleEOF(int fd) override; /* Return the set of (in)valid paths. */ PathSet checkPathValidity(bool returnValid, bool checkHash); diff --git a/src/libstore/local-store.hh b/src/libstore/local-store.hh index 105f3592c685..ebdf19bf1359 100644 --- a/src/libstore/local-store.hh +++ b/src/libstore/local-store.hh @@ -98,41 +98,41 @@ public: /* Implementations of abstract store API methods. */ - bool isValidPath(const Path & path); + bool isValidPath(const Path & path) override; - PathSet queryValidPaths(const PathSet & paths); + PathSet queryValidPaths(const PathSet & paths) override; - PathSet queryAllValidPaths(); + PathSet queryAllValidPaths() override; - ValidPathInfo queryPathInfo(const Path & path); + ValidPathInfo queryPathInfo(const Path & path) override; - Hash queryPathHash(const Path & path); + Hash queryPathHash(const Path & path) override; - void queryReferences(const Path & path, PathSet & references); + void queryReferences(const Path & path, PathSet & references) override; - void queryReferrers(const Path & path, PathSet & referrers); + void queryReferrers(const Path & path, PathSet & referrers) override; - Path queryDeriver(const Path & path); + Path queryDeriver(const Path & path) override; - PathSet queryValidDerivers(const Path & path); + PathSet queryValidDerivers(const Path & path) override; - PathSet queryDerivationOutputs(const Path & path); + PathSet queryDerivationOutputs(const Path & path) override; - StringSet queryDerivationOutputNames(const Path & path); + StringSet queryDerivationOutputNames(const Path & path) override; - Path queryPathFromHashPart(const string & hashPart); + Path queryPathFromHashPart(const string & hashPart) override; - PathSet querySubstitutablePaths(const PathSet & paths); + PathSet querySubstitutablePaths(const PathSet & paths) override; void querySubstitutablePathInfos(const Path & substituter, PathSet & paths, SubstitutablePathInfos & infos); void querySubstitutablePathInfos(const PathSet & paths, - SubstitutablePathInfos & infos); + SubstitutablePathInfos & infos) override; Path addToStore(const string & name, const Path & srcPath, bool recursive = true, HashType hashAlgo = htSHA256, - PathFilter & filter = defaultPathFilter, bool repair = false); + PathFilter & filter = defaultPathFilter, bool repair = false) override; /* Like addToStore(), but the contents of the path are contained in `dump', which is either a NAR serialisation (if recursive == @@ -142,43 +142,43 @@ public: bool recursive = true, HashType hashAlgo = htSHA256, bool repair = false); Path addTextToStore(const string & name, const string & s, - const PathSet & references, bool repair = false); + const PathSet & references, bool repair = false) override; void exportPath(const Path & path, bool sign, - Sink & sink); + Sink & sink) override; - Paths importPaths(bool requireSignature, Source & source); + Paths importPaths(bool requireSignature, Source & source) override; - void buildPaths(const PathSet & paths, BuildMode buildMode); + void buildPaths(const PathSet & paths, BuildMode buildMode) override; BuildResult buildDerivation(const Path & drvPath, const BasicDerivation & drv, BuildMode buildMode) override; - void ensurePath(const Path & path); + void ensurePath(const Path & path) override; - void addTempRoot(const Path & path); + void addTempRoot(const Path & path) override; - void addIndirectRoot(const Path & path); + void addIndirectRoot(const Path & path) override; - void syncWithGC(); + void syncWithGC() override; - Roots findRoots(); + Roots findRoots() override; - void collectGarbage(const GCOptions & options, GCResults & results); + void collectGarbage(const GCOptions & options, GCResults & results) override; /* Optimise the disk space usage of the Nix store by hard-linking files with the same contents. */ void optimiseStore(OptimiseStats & stats); /* Generic variant of the above method. */ - void optimiseStore(); + void optimiseStore() override; /* Optimise a single store path. */ void optimisePath(const Path & path); /* Check the integrity of the Nix store. Returns true if errors remain. */ - bool verifyStore(bool checkContents, bool repair); + bool verifyStore(bool checkContents, bool repair) override; /* Register the validity of a path, i.e., that `path' exists, that the paths referenced by it exists, and in the case of an output @@ -197,9 +197,9 @@ public: /* Query whether `path' previously failed to build. */ bool hasPathFailed(const Path & path); - PathSet queryFailedPaths(); + PathSet queryFailedPaths() override; - void clearFailedPaths(const PathSet & paths); + void clearFailedPaths(const PathSet & paths) override; void vacuumDB(); diff --git a/src/libstore/remote-store.hh b/src/libstore/remote-store.hh index 09e250386c5c..b0787c072904 100644 --- a/src/libstore/remote-store.hh +++ b/src/libstore/remote-store.hh @@ -24,71 +24,72 @@ public: /* Implementations of abstract store API methods. */ - bool isValidPath(const Path & path); + bool isValidPath(const Path & path) override; - PathSet queryValidPaths(const PathSet & paths); + PathSet queryValidPaths(const PathSet & paths) override; - PathSet queryAllValidPaths(); + PathSet queryAllValidPaths() override; - ValidPathInfo queryPathInfo(const Path & path); + ValidPathInfo queryPathInfo(const Path & path) override; - Hash queryPathHash(const Path & path); + Hash queryPathHash(const Path & path) override; - void queryReferences(const Path & path, PathSet & references); + void queryReferences(const Path & path, PathSet & references) override; - void queryReferrers(const Path & path, PathSet & referrers); + void queryReferrers(const Path & path, PathSet & referrers) override; - Path queryDeriver(const Path & path); + Path queryDeriver(const Path & path) override; - PathSet queryValidDerivers(const Path & path); + PathSet queryValidDerivers(const Path & path) override; - PathSet queryDerivationOutputs(const Path & path); + PathSet queryDerivationOutputs(const Path & path) override; - StringSet queryDerivationOutputNames(const Path & path); + StringSet queryDerivationOutputNames(const Path & path) override; - Path queryPathFromHashPart(const string & hashPart); + Path queryPathFromHashPart(const string & hashPart) override; - PathSet querySubstitutablePaths(const PathSet & paths); + PathSet querySubstitutablePaths(const PathSet & paths) override; void querySubstitutablePathInfos(const PathSet & paths, - SubstitutablePathInfos & infos); + SubstitutablePathInfos & infos) override; Path addToStore(const string & name, const Path & srcPath, bool recursive = true, HashType hashAlgo = htSHA256, - PathFilter & filter = defaultPathFilter, bool repair = false); + PathFilter & filter = defaultPathFilter, bool repair = false) override; Path addTextToStore(const string & name, const string & s, - const PathSet & references, bool repair = false); + const PathSet & references, bool repair = false) override; void exportPath(const Path & path, bool sign, - Sink & sink); + Sink & sink) override; - Paths importPaths(bool requireSignature, Source & source); + Paths importPaths(bool requireSignature, Source & source) override; - void buildPaths(const PathSet & paths, BuildMode buildMode); + void buildPaths(const PathSet & paths, BuildMode buildMode) override; BuildResult buildDerivation(const Path & drvPath, const BasicDerivation & drv, BuildMode buildMode) override; - void ensurePath(const Path & path); + void ensurePath(const Path & path) override; - void addTempRoot(const Path & path); + void addTempRoot(const Path & path) override; - void addIndirectRoot(const Path & path); + void addIndirectRoot(const Path & path) override; - void syncWithGC(); + void syncWithGC() override; - Roots findRoots(); + Roots findRoots() override; - void collectGarbage(const GCOptions & options, GCResults & results); + void collectGarbage(const GCOptions & options, GCResults & results) override; - PathSet queryFailedPaths(); + PathSet queryFailedPaths() override; - void clearFailedPaths(const PathSet & paths); + void clearFailedPaths(const PathSet & paths) override; - void optimiseStore(); + void optimiseStore() override; + + bool verifyStore(bool checkContents, bool repair) override; - bool verifyStore(bool checkContents, bool repair); private: AutoCloseFD fdSocket; FdSink to; diff --git a/src/libutil/hash.cc b/src/libutil/hash.cc index a83ba0a81817..1d973e7c8f14 100644 --- a/src/libutil/hash.cc +++ b/src/libutil/hash.cc @@ -115,7 +115,6 @@ const string base32Chars = "0123456789abcdfghijklmnpqrsvwxyz"; string printHash32(const Hash & hash) { - Hash hash2(hash); unsigned int len = hashLength32(hash); string s; diff --git a/src/libutil/util.hh b/src/libutil/util.hh index b2fb59d6f2d7..a05a4cb88093 100644 --- a/src/libutil/util.hh +++ b/src/libutil/util.hh @@ -202,6 +202,7 @@ public: AutoDelete(const Path & p, bool recursive = true); ~AutoDelete(); void cancel(); + operator Path() const { return path; } }; diff --git a/src/nix-env/nix-env.cc b/src/nix-env/nix-env.cc index 97a2bbdb7de0..313f8a8a8f35 100644 --- a/src/nix-env/nix-env.cc +++ b/src/nix-env/nix-env.cc @@ -570,14 +570,16 @@ static void upgradeDerivations(Globals & globals, constraints specified by upgradeType. If there are multiple matches, take the one with the highest priority. If there are still multiple matches, - take the one with the highest version. */ + take the one with the highest version. + Do not upgrade if it would decrease the priority. */ DrvInfos::iterator bestElem = availElems.end(); - DrvName bestName; + string bestVersion; for (auto j = availElems.begin(); j != availElems.end(); ++j) { + if (comparePriorities(*globals.state, i, *j) > 0) + continue; DrvName newName(j->name); if (newName.name == drvName.name) { - int d = comparePriorities(*globals.state, i, *j); - if (d == 0) d = compareVersions(drvName.version, newName.version); + int d = compareVersions(drvName.version, newName.version); if ((upgradeType == utLt && d < 0) || (upgradeType == utLeq && d <= 0) || (upgradeType == utEq && d == 0) || @@ -586,11 +588,11 @@ static void upgradeDerivations(Globals & globals, int d2 = -1; if (bestElem != availElems.end()) { d2 = comparePriorities(*globals.state, *bestElem, *j); - if (d2 == 0) d2 = compareVersions(bestName.version, newName.version); + if (d2 == 0) d2 = compareVersions(bestVersion, newName.version); } if (d2 < 0 && (!globals.prebuiltOnly || isPrebuilt(*globals.state, *j))) { bestElem = j; - bestName = newName; + bestVersion = newName.version; } } } @@ -600,9 +602,11 @@ static void upgradeDerivations(Globals & globals, i.queryOutPath() != bestElem->queryOutPath()) { + const char * action = compareVersions(drvName.version, bestVersion) <= 0 + ? "upgrading" : "downgrading"; printMsg(lvlInfo, - format("upgrading ‘%1%’ to ‘%2%’") - % i.name % bestElem->name); + format("%1% ‘%2%’ to ‘%3%’") + % action % i.name % bestElem->name); newElems.push_back(*bestElem); } else newElems.push_back(i); @@ -1273,7 +1277,7 @@ static void opDeleteGenerations(Globals & globals, Strings opFlags, Strings opAr std::set<unsigned int> gens; for (auto & i : opArgs) { unsigned int n; - if (!string2Int(i, n) || n < 0) + if (!string2Int(i, n)) throw UsageError(format("invalid generation number ‘%1%’") % i); gens.insert(n); } diff --git a/src/nix-prefetch-url/local.mk b/src/nix-prefetch-url/local.mk new file mode 100644 index 000000000000..3e7735406af0 --- /dev/null +++ b/src/nix-prefetch-url/local.mk @@ -0,0 +1,7 @@ +programs += nix-prefetch-url + +nix-prefetch-url_DIR := $(d) + +nix-prefetch-url_SOURCES := $(d)/nix-prefetch-url.cc + +nix-prefetch-url_LIBS = libmain libexpr libstore libutil libformat diff --git a/src/nix-prefetch-url/nix-prefetch-url.cc b/src/nix-prefetch-url/nix-prefetch-url.cc new file mode 100644 index 000000000000..112d303e0c16 --- /dev/null +++ b/src/nix-prefetch-url/nix-prefetch-url.cc @@ -0,0 +1,168 @@ +#include "hash.hh" +#include "shared.hh" +#include "download.hh" +#include "store-api.hh" +#include "eval.hh" +#include "eval-inline.hh" +#include "common-opts.hh" +#include "attr-path.hh" + +#include <iostream> + +using namespace nix; + + +/* If ‘uri’ starts with ‘mirror://’, then resolve it using the list of + mirrors defined in Nixpkgs. */ +string resolveMirrorUri(EvalState & state, string uri) +{ + if (string(uri, 0, 9) != "mirror://") return uri; + + string s(uri, 9); + auto p = s.find('/'); + if (p == string::npos) throw Error("invalid mirror URI"); + string mirrorName(s, 0, p); + + Value vMirrors; + state.eval(state.parseExprFromString("import <nixpkgs/pkgs/build-support/fetchurl/mirrors.nix>", "."), vMirrors); + state.forceAttrs(vMirrors); + + auto mirrorList = vMirrors.attrs->find(state.symbols.create(mirrorName)); + if (mirrorList == vMirrors.attrs->end()) + throw Error(format("unknown mirror name ‘%1%’") % mirrorName); + state.forceList(*mirrorList->value); + + if (mirrorList->value->listSize() < 1) + throw Error(format("mirror URI ‘%1%’ did not expand to anything") % uri); + + string mirror = state.forceString(*mirrorList->value->listElems()[0]); + return mirror + (hasSuffix(mirror, "/") ? "" : "/") + string(s, p + 1); +} + + +int main(int argc, char * * argv) +{ + return handleExceptions(argv[0], [&]() { + initNix(); + initGC(); + + HashType ht = htSHA256; + std::vector<string> args; + Strings searchPath; + bool printPath = getEnv("PRINT_PATH") != ""; + bool fromExpr = false; + string attrPath; + std::map<string, string> autoArgs_; + + parseCmdLine(argc, argv, [&](Strings::iterator & arg, const Strings::iterator & end) { + if (*arg == "--help") + showManPage("nix-prefetch-url"); + else if (*arg == "--version") + printVersion("nix-prefetch-url"); + else if (*arg == "--type") { + string s = getArg(*arg, arg, end); + ht = parseHashType(s); + if (ht == htUnknown) + throw UsageError(format("unknown hash type ‘%1%’") % s); + } + else if (*arg == "--print-path") + printPath = true; + else if (*arg == "--attr" || *arg == "-A") { + fromExpr = true; + attrPath = getArg(*arg, arg, end); + } + else if (parseAutoArgs(arg, end, autoArgs_)) + ; + else if (parseSearchPathArg(arg, end, searchPath)) + ; + else if (*arg != "" && arg->at(0) == '-') + return false; + else + args.push_back(*arg); + return true; + }); + + if (args.size() > 2) + throw UsageError("too many arguments"); + + store = openStore(); + EvalState state(searchPath); + + Bindings & autoArgs(*evalAutoArgs(state, autoArgs_)); + + /* If -A is given, get the URI from the specified Nix + expression. */ + string uri; + if (!fromExpr) { + if (args.empty()) + throw UsageError("you must specify a URI"); + uri = args[0]; + } else { + Path path = resolveExprPath(lookupFileArg(state, args.empty() ? "." : args[0])); + Value vRoot; + state.evalFile(path, vRoot); + Value & v(*findAlongAttrPath(state, attrPath, autoArgs, vRoot)); + state.forceAttrs(v); + auto urls = v.attrs->find(state.symbols.create("urls")); + if (urls == v.attrs->end()) + throw Error("attribute set does not contain a ‘urls’ attribute"); + state.forceList(*urls->value); + if (urls->value->listSize() < 1) + throw Error("‘urls’ list is empty"); + uri = state.forceString(*urls->value->listElems()[0]); + } + + /* Figure out a name in the Nix store. */ + auto name = baseNameOf(uri); + if (name.empty()) + throw Error(format("cannot figure out file name for ‘%1%’") % uri); + + /* If an expected hash is given, the file may already exist in + the store. */ + Hash hash, expectedHash(ht); + Path storePath; + if (args.size() == 2) { + expectedHash = parseHash16or32(ht, args[1]); + storePath = makeFixedOutputPath(false, ht, expectedHash, name); + if (store->isValidPath(storePath)) + hash = expectedHash; + else + storePath.clear(); + } + + if (storePath.empty()) { + + auto actualUri = resolveMirrorUri(state, uri); + + if (uri != actualUri) + printMsg(lvlInfo, format("‘%1%’ expands to ‘%2%’") % uri % actualUri); + + /* Download the file. */ + auto result = downloadFile(actualUri); + + /* Copy the file to the Nix store. FIXME: if RemoteStore + implemented addToStoreFromDump() and downloadFile() + supported a sink, we could stream the download directly + into the Nix store. */ + AutoDelete tmpDir(createTempDir(), true); + Path tmpFile = (Path) tmpDir + "/tmp"; + writeFile(tmpFile, result.data); + + /* FIXME: inefficient; addToStore() will also hash + this. */ + hash = hashString(ht, result.data); + + if (expectedHash != Hash(ht) && expectedHash != hash) + throw Error(format("hash mismatch for ‘%1%’") % uri); + + storePath = store->addToStore(name, tmpFile, false, ht); + } + + if (!printPath) + printMsg(lvlInfo, format("path is ‘%1%’") % storePath); + + std::cout << printHash16or32(hash) << std::endl; + if (printPath) + std::cout << storePath << std::endl; + }); +} |