Skip to content

Commit

Permalink
nix-prefetch-url: Support prefetching from a Nix expression
Browse files Browse the repository at this point in the history
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
  • Loading branch information
edolstra committed Oct 1, 2015
1 parent a3c4eb0 commit 06f29fa
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 4 deletions.
1 change: 1 addition & 0 deletions doc/manual/command-ref/nix-prefetch-url.xml
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down
40 changes: 36 additions & 4 deletions src/nix-prefetch-url/nix-prefetch-url.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "eval.hh"
#include "eval-inline.hh"
#include "common-opts.hh"
#include "attr-path.hh"

#include <iostream>

Expand Down Expand Up @@ -49,6 +50,9 @@ int main(int argc, char * * argv)
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")
Expand All @@ -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) == '-')
Expand All @@ -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);
Expand Down

0 comments on commit 06f29fa

Please sign in to comment.