diff options
Diffstat (limited to 'third_party/nix/src/nix-prefetch-url/nix-prefetch-url.cc')
-rw-r--r-- | third_party/nix/src/nix-prefetch-url/nix-prefetch-url.cc | 253 |
1 files changed, 0 insertions, 253 deletions
diff --git a/third_party/nix/src/nix-prefetch-url/nix-prefetch-url.cc b/third_party/nix/src/nix-prefetch-url/nix-prefetch-url.cc deleted file mode 100644 index b61a38a7f193..000000000000 --- a/third_party/nix/src/nix-prefetch-url/nix-prefetch-url.cc +++ /dev/null @@ -1,253 +0,0 @@ -#include <iostream> - -#include <absl/strings/match.h> -#include <fcntl.h> -#include <glog/logging.h> -#include <sys/stat.h> -#include <sys/types.h> - -#include "libexpr/attr-path.hh" -#include "libexpr/common-eval-args.hh" -#include "libexpr/eval-inline.hh" -#include "libexpr/eval.hh" -#include "libmain/shared.hh" -#include "libstore/download.hh" -#include "libstore/store-api.hh" -#include "libutil/finally.hh" -#include "libutil/hash.hh" -#include "nix/legacy.hh" - -using namespace nix; - -/* If ‘uri’ starts with ‘mirror://’, then resolve it using the list of - mirrors defined in Nixpkgs. */ -std::string resolveMirrorUri(EvalState& state, std::string uri) { - if (std::string(uri, 0, 9) != "mirror://") { - return uri; - } - - std::string s(uri, 9); - auto p = s.find('/'); - if (p == std::string::npos) { - throw Error("invalid mirror URI"); - } - std::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->second.value); - - if (mirrorList->second.value->listSize() < 1) { - throw Error(format("mirror URI '%1%' did not expand to anything") % uri); - } - - std::string mirror = state.forceString(*(*mirrorList->second.value->list)[0]); - return mirror + (absl::EndsWith(mirror, "/") ? "" : "/") + - std::string(s, p + 1); -} - -static int _main(int argc, char** argv) { - { - HashType ht = htSHA256; - std::vector<std::string> args; - bool printPath = getEnv("PRINT_PATH").has_value(); - bool fromExpr = false; - std::string attrPath; - bool unpack = false; - std::string name; - - struct MyArgs : LegacyArgs, MixEvalArgs { - using LegacyArgs::LegacyArgs; - }; - - MyArgs myArgs(baseNameOf(argv[0]), - [&](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") { - std::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 (*arg == "--unpack") { - unpack = true; - } else if (*arg == "--name") { - name = getArg(*arg, arg, end); - } else if (*arg != "" && arg->at(0) == '-') { - return false; - } else { - args.push_back(*arg); - } - return true; - }); - - myArgs.parseCmdline(argvToStrings(argc, argv)); - - if (args.size() > 2) { - throw UsageError("too many arguments"); - } - - auto store = openStore(); - auto state = std::make_unique<EvalState>(myArgs.searchPath, store); - - std::unique_ptr<Bindings> autoArgs = myArgs.getAutoArgs(*state); - - /* If -A is given, get the URI from the specified Nix - expression. */ - std::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.get(), vRoot)); - state->forceAttrs(v); - - /* Extract the URI. */ - auto attr = v.attrs->find(state->symbols.Create("urls")); - if (attr == v.attrs->end()) { - throw Error("attribute set does not contain a 'urls' attribute"); - } - state->forceList(*attr->second.value); - if (attr->second.value->listSize() < 1) { - throw Error("'urls' list is empty"); - } - uri = state->forceString(*(*attr->second.value->list)[0]); - - /* Extract the hash mode. */ - attr = v.attrs->find(state->symbols.Create("outputHashMode")); - if (attr == v.attrs->end()) { - LOG(WARNING) << "this does not look like a fetchurl call"; - } else { - unpack = state->forceString(*attr->second.value) == "recursive"; - } - - /* Extract the name. */ - if (name.empty()) { - attr = v.attrs->find(state->symbols.Create("name")); - if (attr != v.attrs->end()) { - name = state->forceString(*attr->second.value); - } - } - } - - /* Figure out a name in the Nix store. */ - if (name.empty()) { - 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; - Hash expectedHash(ht); - Path storePath; - if (args.size() == 2) { - auto expectedHash_ = Hash::deserialize(args[1], ht); - expectedHash = Hash::unwrap_throw(expectedHash); - storePath = store->makeFixedOutputPath(unpack, expectedHash, name); - if (store->isValidPath(storePath)) { - hash = expectedHash; - } else { - storePath.clear(); - } - } - - if (storePath.empty()) { - auto actualUri = resolveMirrorUri(*state, uri); - - AutoDelete tmpDir(createTempDir(), true); - Path tmpFile = Path(tmpDir) + "/tmp"; - - /* Download the file. */ - { - AutoCloseFD fd( - open(tmpFile.c_str(), O_WRONLY | O_CREAT | O_EXCL, 0600)); - if (!fd) { - throw SysError("creating temporary file '%s'", tmpFile); - } - - FdSink sink(fd.get()); - - DownloadRequest req(actualUri); - req.decompress = false; - getDownloader()->download(std::move(req), sink); - } - - /* Optionally unpack the file. */ - if (unpack) { - LOG(INFO) << "unpacking..."; - Path unpacked = Path(tmpDir) + "/unpacked"; - createDirs(unpacked); - if (absl::EndsWith(baseNameOf(uri), ".zip")) { - runProgram("unzip", true, {"-qq", tmpFile, "-d", unpacked}); - } else { - // FIXME: this requires GNU tar for decompression. - runProgram("tar", true, {"xf", tmpFile, "-C", unpacked}); - } - - /* If the archive unpacks to a single file/directory, then use - that as the top-level. */ - auto entries = readDirectory(unpacked); - if (entries.size() == 1) { - tmpFile = unpacked + "/" + entries[0].name; - } else { - tmpFile = unpacked; - } - } - - /* FIXME: inefficient; addToStore() will also hash - this. */ - hash = unpack ? hashPath(ht, tmpFile).first : hashFile(ht, tmpFile); - - if (expectedHash != Hash(ht) && expectedHash != hash) { - throw Error(format("hash mismatch for '%1%'") % uri); - } - - /* 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. */ - storePath = store->addToStore(name, tmpFile, unpack, ht); - - assert(storePath == store->makeFixedOutputPath(unpack, hash, name)); - } - - if (!printPath) { - LOG(INFO) << "path is '" << storePath << "'"; - } - - std::cout << printHash16or32(hash) << std::endl; - if (printPath) { - std::cout << storePath << std::endl; - } - - return 0; - } -} - -static RegisterLegacyCommand s1("nix-prefetch-url", _main); |