From 06f29fafe8496ae751e84a8ded0cc1041740cfe0 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 1 Oct 2015 18:07:56 +0200 Subject: [PATCH] nix-prefetch-url: Support prefetching from a Nix expression MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For example, $ nix-prefetch-url -A hello.src will prefetch the file specified by the fetchurl call in the attribute ‘hello.src’ from the Nix expression in the current directory. This differs from ‘nix-build -A hello.src’ in that it doesn't verify the hash. You can also specify a path to the Nix expression: $ nix-prefetch-url ~/Dev/nixpkgs -A hello.src List elements (typically used in ‘patches’ attributes) also work: $ nix-prefetch-url -A portmidi.patches.0 --- doc/manual/command-ref/nix-prefetch-url.xml | 1 + src/nix-prefetch-url/nix-prefetch-url.cc | 40 ++++++++++++++++++--- 2 files changed, 37 insertions(+), 4 deletions(-) diff --git a/doc/manual/command-ref/nix-prefetch-url.xml b/doc/manual/command-ref/nix-prefetch-url.xml index 0f24bef39..9cbaa42a1 100644 --- a/doc/manual/command-ref/nix-prefetch-url.xml +++ b/doc/manual/command-ref/nix-prefetch-url.xml @@ -20,6 +20,7 @@ nix-prefetch-url hashAlgo + url hash diff --git a/src/nix-prefetch-url/nix-prefetch-url.cc b/src/nix-prefetch-url/nix-prefetch-url.cc index cb6078fca..112d303e0 100644 --- a/src/nix-prefetch-url/nix-prefetch-url.cc +++ b/src/nix-prefetch-url/nix-prefetch-url.cc @@ -5,6 +5,7 @@ #include "eval.hh" #include "eval-inline.hh" #include "common-opts.hh" +#include "attr-path.hh" #include @@ -49,6 +50,9 @@ int main(int argc, char * * argv) std::vector args; Strings searchPath; bool printPath = getEnv("PRINT_PATH") != ""; + bool fromExpr = false; + string attrPath; + std::map autoArgs_; parseCmdLine(argc, argv, [&](Strings::iterator & arg, const Strings::iterator & end) { if (*arg == "--help") @@ -63,6 +67,12 @@ int main(int argc, char * * argv) } 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) == '-') @@ -72,15 +82,37 @@ int main(int argc, char * * argv) return true; }); - if (args.size() < 1 || args.size() > 2) - throw UsageError("nix-prefetch-url expects one argument"); + 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 uri = args[0]; auto name = baseNameOf(uri); if (name.empty()) throw Error(format("cannot figure out file name for ‘%1%’") % uri);