diff options
author | Eelco Dolstra <edolstra@gmail.com> | 2020-01-28 13:11:02 +0100 |
---|---|---|
committer | Eelco Dolstra <edolstra@gmail.com> | 2020-01-28 13:11:02 +0100 |
commit | 1af7b94c1d4655e8d10529c257ce044294c33137 (patch) | |
tree | b5e630fdd070011c0ffe7a27a0f95e06c2164f67 /src/libstore/fetchers/tarball.cc | |
parent | c39c2503f721406e655ee6700cafd7f1ddc65894 (diff) |
Add support for tarball flake inputs
For example,
$ nix flake info https://github.com/edolstra/dwarffs/archive/master.tar.gz
Fixes #2929.
Diffstat (limited to 'src/libstore/fetchers/tarball.cc')
-rw-r--r-- | src/libstore/fetchers/tarball.cc | 91 |
1 files changed, 91 insertions, 0 deletions
diff --git a/src/libstore/fetchers/tarball.cc b/src/libstore/fetchers/tarball.cc new file mode 100644 index 000000000..e82066089 --- /dev/null +++ b/src/libstore/fetchers/tarball.cc @@ -0,0 +1,91 @@ +#include "fetchers.hh" +#include "download.hh" +#include "globals.hh" +#include "parse.hh" +#include "store-api.hh" + +namespace nix::fetchers { + +struct TarballInput : Input +{ + ParsedURL url; + std::optional<Hash> hash; + + bool operator ==(const Input & other) const override + { + auto other2 = dynamic_cast<const TarballInput *>(&other); + return + other2 + && to_string() == other2->to_string() + && hash == other2->hash; + } + + bool isImmutable() const override + { + return (bool) hash; + } + + std::string to_string() const override + { + auto url2(url); + if (narHash) + url2.query.insert_or_assign("narHash", narHash->to_string(SRI)); + return url2.to_string(); + } + + std::pair<Tree, std::shared_ptr<const Input>> fetchTreeInternal(nix::ref<Store> store) const override + { + CachedDownloadRequest request(url.to_string()); + request.unpack = true; + request.getLastModified = true; + request.name = "source"; + + auto res = getDownloader()->downloadCached(store, request); + + auto input = std::make_shared<TarballInput>(*this); + + auto storePath = store->parseStorePath(res.storePath); + + input->narHash = store->queryPathInfo(storePath)->narHash; + + return { + Tree { + .actualPath = res.path, + .storePath = std::move(storePath), + .lastModified = *res.lastModified + }, + input + }; + } +}; + +struct TarballInputScheme : InputScheme +{ + std::unique_ptr<Input> inputFromURL(const ParsedURL & url) override + { + if (url.scheme != "file" && url.scheme != "http" && url.scheme != "https") return nullptr; + + if (!hasSuffix(url.path, ".zip") + && !hasSuffix(url.path, ".tar") + && !hasSuffix(url.path, ".tar.gz") + && !hasSuffix(url.path, ".tar.xz") + && !hasSuffix(url.path, ".tar.bz2")) + return nullptr; + + auto input = std::make_unique<TarballInput>(); + input->type = "tarball"; + input->url = url; + + auto narHash = url.query.find("narHash"); + if (narHash != url.query.end()) { + // FIXME: require SRI hash. + input->narHash = Hash(narHash->second); + } + + return input; + } +}; + +static auto r1 = OnStartup([] { registerInputScheme(std::make_unique<TarballInputScheme>()); }); + +} |