2020-03-30 14:04:18 +00:00
|
|
|
#include "fetchers.hh"
|
|
|
|
#include "cache.hh"
|
2020-04-08 12:12:22 +00:00
|
|
|
#include "filetransfer.hh"
|
2020-03-30 14:04:18 +00:00
|
|
|
#include "globals.hh"
|
|
|
|
#include "store-api.hh"
|
|
|
|
#include "archive.hh"
|
|
|
|
#include "tarfile.hh"
|
|
|
|
|
|
|
|
namespace nix::fetchers {
|
|
|
|
|
|
|
|
DownloadFileResult downloadFile(
|
|
|
|
ref<Store> store,
|
|
|
|
const std::string & url,
|
|
|
|
const std::string & name,
|
|
|
|
bool immutable)
|
|
|
|
{
|
|
|
|
// FIXME: check store
|
|
|
|
|
|
|
|
Attrs inAttrs({
|
|
|
|
{"type", "file"},
|
|
|
|
{"url", url},
|
|
|
|
{"name", name},
|
|
|
|
});
|
|
|
|
|
|
|
|
auto cached = getCache()->lookupExpired(store, inAttrs);
|
|
|
|
|
|
|
|
auto useCached = [&]() -> DownloadFileResult
|
|
|
|
{
|
|
|
|
return {
|
|
|
|
.storePath = std::move(cached->storePath),
|
|
|
|
.etag = getStrAttr(cached->infoAttrs, "etag"),
|
|
|
|
.effectiveUrl = getStrAttr(cached->infoAttrs, "url")
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
if (cached && !cached->expired)
|
|
|
|
return useCached();
|
|
|
|
|
2020-04-08 12:12:22 +00:00
|
|
|
FileTransferRequest request(url);
|
2020-03-30 14:04:18 +00:00
|
|
|
if (cached)
|
|
|
|
request.expectedETag = getStrAttr(cached->infoAttrs, "etag");
|
2020-04-08 12:12:22 +00:00
|
|
|
FileTransferResult res;
|
2020-03-30 14:04:18 +00:00
|
|
|
try {
|
2020-04-08 12:12:22 +00:00
|
|
|
res = getFileTransfer()->download(request);
|
|
|
|
} catch (FileTransferError & e) {
|
2020-03-30 14:04:18 +00:00
|
|
|
if (cached) {
|
|
|
|
warn("%s; using cached version", e.msg());
|
|
|
|
return useCached();
|
|
|
|
} else
|
|
|
|
throw;
|
|
|
|
}
|
|
|
|
|
|
|
|
// FIXME: write to temporary file.
|
|
|
|
|
|
|
|
Attrs infoAttrs({
|
|
|
|
{"etag", res.etag},
|
|
|
|
{"url", res.effectiveUri},
|
|
|
|
});
|
|
|
|
|
|
|
|
std::optional<StorePath> storePath;
|
|
|
|
|
|
|
|
if (res.cached) {
|
|
|
|
assert(cached);
|
|
|
|
assert(request.expectedETag == res.etag);
|
|
|
|
storePath = std::move(cached->storePath);
|
|
|
|
} else {
|
|
|
|
StringSink sink;
|
|
|
|
dumpString(*res.data, sink);
|
|
|
|
auto hash = hashString(htSHA256, *res.data);
|
|
|
|
ValidPathInfo info(store->makeFixedOutputPath(false, hash, name));
|
|
|
|
info.narHash = hashString(htSHA256, *sink.s);
|
|
|
|
info.narSize = sink.s->size();
|
|
|
|
info.ca = makeFixedOutputCA(false, hash);
|
|
|
|
store->addToStore(info, sink.s, NoRepair, NoCheckSigs);
|
|
|
|
storePath = std::move(info.path);
|
|
|
|
}
|
|
|
|
|
|
|
|
getCache()->add(
|
|
|
|
store,
|
|
|
|
inAttrs,
|
|
|
|
infoAttrs,
|
|
|
|
*storePath,
|
|
|
|
immutable);
|
|
|
|
|
|
|
|
if (url != res.effectiveUri)
|
|
|
|
getCache()->add(
|
|
|
|
store,
|
|
|
|
{
|
|
|
|
{"type", "file"},
|
|
|
|
{"url", res.effectiveUri},
|
|
|
|
{"name", name},
|
|
|
|
},
|
|
|
|
infoAttrs,
|
|
|
|
*storePath,
|
|
|
|
immutable);
|
|
|
|
|
|
|
|
return {
|
|
|
|
.storePath = std::move(*storePath),
|
|
|
|
.etag = res.etag,
|
|
|
|
.effectiveUrl = res.effectiveUri,
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
Remove TreeInfo
The attributes previously stored in TreeInfo (narHash, revCount,
lastModified) are now stored in Input. This makes it less arbitrary
what attributes are stored where.
As a result, the lock file format has changed. An entry like
"info": {
"lastModified": 1585405475,
"narHash": "sha256-bESW0n4KgPmZ0luxvwJ+UyATrC6iIltVCsGdLiphVeE="
},
"locked": {
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "b88ff468e9850410070d4e0ccd68c7011f15b2be",
"type": "github"
},
is now stored as
"locked": {
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "b88ff468e9850410070d4e0ccd68c7011f15b2be",
"type": "github",
"lastModified": 1585405475,
"narHash": "sha256-bESW0n4KgPmZ0luxvwJ+UyATrC6iIltVCsGdLiphVeE="
},
The 'Input' class is now a dumb set of attributes. All the fetcher
implementations subclass InputScheme, not Input. This simplifies the
API.
Also, fix substitution of flake inputs. This was broken since lazy
flake fetching started using fetchTree internally.
2020-05-29 22:44:11 +00:00
|
|
|
std::pair<Tree, time_t> downloadTarball(
|
2020-03-30 14:04:18 +00:00
|
|
|
ref<Store> store,
|
|
|
|
const std::string & url,
|
|
|
|
const std::string & name,
|
|
|
|
bool immutable)
|
|
|
|
{
|
|
|
|
Attrs inAttrs({
|
|
|
|
{"type", "tarball"},
|
|
|
|
{"url", url},
|
|
|
|
{"name", name},
|
|
|
|
});
|
|
|
|
|
|
|
|
auto cached = getCache()->lookupExpired(store, inAttrs);
|
|
|
|
|
|
|
|
if (cached && !cached->expired)
|
Remove TreeInfo
The attributes previously stored in TreeInfo (narHash, revCount,
lastModified) are now stored in Input. This makes it less arbitrary
what attributes are stored where.
As a result, the lock file format has changed. An entry like
"info": {
"lastModified": 1585405475,
"narHash": "sha256-bESW0n4KgPmZ0luxvwJ+UyATrC6iIltVCsGdLiphVeE="
},
"locked": {
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "b88ff468e9850410070d4e0ccd68c7011f15b2be",
"type": "github"
},
is now stored as
"locked": {
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "b88ff468e9850410070d4e0ccd68c7011f15b2be",
"type": "github",
"lastModified": 1585405475,
"narHash": "sha256-bESW0n4KgPmZ0luxvwJ+UyATrC6iIltVCsGdLiphVeE="
},
The 'Input' class is now a dumb set of attributes. All the fetcher
implementations subclass InputScheme, not Input. This simplifies the
API.
Also, fix substitution of flake inputs. This was broken since lazy
flake fetching started using fetchTree internally.
2020-05-29 22:44:11 +00:00
|
|
|
return {
|
|
|
|
Tree {
|
|
|
|
.actualPath = store->toRealPath(cached->storePath),
|
|
|
|
.storePath = std::move(cached->storePath),
|
2020-03-30 14:04:18 +00:00
|
|
|
},
|
Remove TreeInfo
The attributes previously stored in TreeInfo (narHash, revCount,
lastModified) are now stored in Input. This makes it less arbitrary
what attributes are stored where.
As a result, the lock file format has changed. An entry like
"info": {
"lastModified": 1585405475,
"narHash": "sha256-bESW0n4KgPmZ0luxvwJ+UyATrC6iIltVCsGdLiphVeE="
},
"locked": {
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "b88ff468e9850410070d4e0ccd68c7011f15b2be",
"type": "github"
},
is now stored as
"locked": {
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "b88ff468e9850410070d4e0ccd68c7011f15b2be",
"type": "github",
"lastModified": 1585405475,
"narHash": "sha256-bESW0n4KgPmZ0luxvwJ+UyATrC6iIltVCsGdLiphVeE="
},
The 'Input' class is now a dumb set of attributes. All the fetcher
implementations subclass InputScheme, not Input. This simplifies the
API.
Also, fix substitution of flake inputs. This was broken since lazy
flake fetching started using fetchTree internally.
2020-05-29 22:44:11 +00:00
|
|
|
getIntAttr(cached->infoAttrs, "lastModified")
|
2020-03-30 14:04:18 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
auto res = downloadFile(store, url, name, immutable);
|
|
|
|
|
|
|
|
std::optional<StorePath> unpackedStorePath;
|
|
|
|
time_t lastModified;
|
|
|
|
|
|
|
|
if (cached && res.etag != "" && getStrAttr(cached->infoAttrs, "etag") == res.etag) {
|
|
|
|
unpackedStorePath = std::move(cached->storePath);
|
|
|
|
lastModified = getIntAttr(cached->infoAttrs, "lastModified");
|
|
|
|
} else {
|
|
|
|
Path tmpDir = createTempDir();
|
|
|
|
AutoDelete autoDelete(tmpDir, true);
|
|
|
|
unpackTarfile(store->toRealPath(res.storePath), tmpDir);
|
|
|
|
auto members = readDirectory(tmpDir);
|
|
|
|
if (members.size() != 1)
|
|
|
|
throw nix::Error("tarball '%s' contains an unexpected number of top-level files", url);
|
|
|
|
auto topDir = tmpDir + "/" + members.begin()->name;
|
|
|
|
lastModified = lstat(topDir).st_mtime;
|
|
|
|
unpackedStorePath = store->addToStore(name, topDir, true, htSHA256, defaultPathFilter, NoRepair);
|
|
|
|
}
|
|
|
|
|
|
|
|
Attrs infoAttrs({
|
|
|
|
{"lastModified", lastModified},
|
|
|
|
{"etag", res.etag},
|
|
|
|
});
|
|
|
|
|
|
|
|
getCache()->add(
|
|
|
|
store,
|
|
|
|
inAttrs,
|
|
|
|
infoAttrs,
|
|
|
|
*unpackedStorePath,
|
|
|
|
immutable);
|
|
|
|
|
Remove TreeInfo
The attributes previously stored in TreeInfo (narHash, revCount,
lastModified) are now stored in Input. This makes it less arbitrary
what attributes are stored where.
As a result, the lock file format has changed. An entry like
"info": {
"lastModified": 1585405475,
"narHash": "sha256-bESW0n4KgPmZ0luxvwJ+UyATrC6iIltVCsGdLiphVeE="
},
"locked": {
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "b88ff468e9850410070d4e0ccd68c7011f15b2be",
"type": "github"
},
is now stored as
"locked": {
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "b88ff468e9850410070d4e0ccd68c7011f15b2be",
"type": "github",
"lastModified": 1585405475,
"narHash": "sha256-bESW0n4KgPmZ0luxvwJ+UyATrC6iIltVCsGdLiphVeE="
},
The 'Input' class is now a dumb set of attributes. All the fetcher
implementations subclass InputScheme, not Input. This simplifies the
API.
Also, fix substitution of flake inputs. This was broken since lazy
flake fetching started using fetchTree internally.
2020-05-29 22:44:11 +00:00
|
|
|
return {
|
|
|
|
Tree {
|
|
|
|
.actualPath = store->toRealPath(*unpackedStorePath),
|
|
|
|
.storePath = std::move(*unpackedStorePath),
|
2020-03-30 14:04:18 +00:00
|
|
|
},
|
Remove TreeInfo
The attributes previously stored in TreeInfo (narHash, revCount,
lastModified) are now stored in Input. This makes it less arbitrary
what attributes are stored where.
As a result, the lock file format has changed. An entry like
"info": {
"lastModified": 1585405475,
"narHash": "sha256-bESW0n4KgPmZ0luxvwJ+UyATrC6iIltVCsGdLiphVeE="
},
"locked": {
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "b88ff468e9850410070d4e0ccd68c7011f15b2be",
"type": "github"
},
is now stored as
"locked": {
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "b88ff468e9850410070d4e0ccd68c7011f15b2be",
"type": "github",
"lastModified": 1585405475,
"narHash": "sha256-bESW0n4KgPmZ0luxvwJ+UyATrC6iIltVCsGdLiphVeE="
},
The 'Input' class is now a dumb set of attributes. All the fetcher
implementations subclass InputScheme, not Input. This simplifies the
API.
Also, fix substitution of flake inputs. This was broken since lazy
flake fetching started using fetchTree internally.
2020-05-29 22:44:11 +00:00
|
|
|
lastModified,
|
2020-03-30 14:04:18 +00:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
struct TarballInputScheme : InputScheme
|
|
|
|
{
|
Remove TreeInfo
The attributes previously stored in TreeInfo (narHash, revCount,
lastModified) are now stored in Input. This makes it less arbitrary
what attributes are stored where.
As a result, the lock file format has changed. An entry like
"info": {
"lastModified": 1585405475,
"narHash": "sha256-bESW0n4KgPmZ0luxvwJ+UyATrC6iIltVCsGdLiphVeE="
},
"locked": {
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "b88ff468e9850410070d4e0ccd68c7011f15b2be",
"type": "github"
},
is now stored as
"locked": {
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "b88ff468e9850410070d4e0ccd68c7011f15b2be",
"type": "github",
"lastModified": 1585405475,
"narHash": "sha256-bESW0n4KgPmZ0luxvwJ+UyATrC6iIltVCsGdLiphVeE="
},
The 'Input' class is now a dumb set of attributes. All the fetcher
implementations subclass InputScheme, not Input. This simplifies the
API.
Also, fix substitution of flake inputs. This was broken since lazy
flake fetching started using fetchTree internally.
2020-05-29 22:44:11 +00:00
|
|
|
std::optional<Input> inputFromURL(const ParsedURL & url) override
|
2020-03-30 14:04:18 +00:00
|
|
|
{
|
Remove TreeInfo
The attributes previously stored in TreeInfo (narHash, revCount,
lastModified) are now stored in Input. This makes it less arbitrary
what attributes are stored where.
As a result, the lock file format has changed. An entry like
"info": {
"lastModified": 1585405475,
"narHash": "sha256-bESW0n4KgPmZ0luxvwJ+UyATrC6iIltVCsGdLiphVeE="
},
"locked": {
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "b88ff468e9850410070d4e0ccd68c7011f15b2be",
"type": "github"
},
is now stored as
"locked": {
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "b88ff468e9850410070d4e0ccd68c7011f15b2be",
"type": "github",
"lastModified": 1585405475,
"narHash": "sha256-bESW0n4KgPmZ0luxvwJ+UyATrC6iIltVCsGdLiphVeE="
},
The 'Input' class is now a dumb set of attributes. All the fetcher
implementations subclass InputScheme, not Input. This simplifies the
API.
Also, fix substitution of flake inputs. This was broken since lazy
flake fetching started using fetchTree internally.
2020-05-29 22:44:11 +00:00
|
|
|
if (url.scheme != "file" && url.scheme != "http" && url.scheme != "https") return {};
|
2020-03-30 14:04:18 +00:00
|
|
|
|
|
|
|
if (!hasSuffix(url.path, ".zip")
|
|
|
|
&& !hasSuffix(url.path, ".tar")
|
|
|
|
&& !hasSuffix(url.path, ".tar.gz")
|
|
|
|
&& !hasSuffix(url.path, ".tar.xz")
|
|
|
|
&& !hasSuffix(url.path, ".tar.bz2"))
|
Remove TreeInfo
The attributes previously stored in TreeInfo (narHash, revCount,
lastModified) are now stored in Input. This makes it less arbitrary
what attributes are stored where.
As a result, the lock file format has changed. An entry like
"info": {
"lastModified": 1585405475,
"narHash": "sha256-bESW0n4KgPmZ0luxvwJ+UyATrC6iIltVCsGdLiphVeE="
},
"locked": {
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "b88ff468e9850410070d4e0ccd68c7011f15b2be",
"type": "github"
},
is now stored as
"locked": {
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "b88ff468e9850410070d4e0ccd68c7011f15b2be",
"type": "github",
"lastModified": 1585405475,
"narHash": "sha256-bESW0n4KgPmZ0luxvwJ+UyATrC6iIltVCsGdLiphVeE="
},
The 'Input' class is now a dumb set of attributes. All the fetcher
implementations subclass InputScheme, not Input. This simplifies the
API.
Also, fix substitution of flake inputs. This was broken since lazy
flake fetching started using fetchTree internally.
2020-05-29 22:44:11 +00:00
|
|
|
return {};
|
|
|
|
|
|
|
|
Input input;
|
|
|
|
input.attrs.insert_or_assign("type", "tarball");
|
|
|
|
input.attrs.insert_or_assign("url", url.to_string());
|
|
|
|
auto narHash = url.query.find("narHash");
|
|
|
|
if (narHash != url.query.end())
|
|
|
|
input.attrs.insert_or_assign("narHash", narHash->second);
|
2020-03-30 14:04:18 +00:00
|
|
|
return input;
|
|
|
|
}
|
|
|
|
|
Remove TreeInfo
The attributes previously stored in TreeInfo (narHash, revCount,
lastModified) are now stored in Input. This makes it less arbitrary
what attributes are stored where.
As a result, the lock file format has changed. An entry like
"info": {
"lastModified": 1585405475,
"narHash": "sha256-bESW0n4KgPmZ0luxvwJ+UyATrC6iIltVCsGdLiphVeE="
},
"locked": {
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "b88ff468e9850410070d4e0ccd68c7011f15b2be",
"type": "github"
},
is now stored as
"locked": {
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "b88ff468e9850410070d4e0ccd68c7011f15b2be",
"type": "github",
"lastModified": 1585405475,
"narHash": "sha256-bESW0n4KgPmZ0luxvwJ+UyATrC6iIltVCsGdLiphVeE="
},
The 'Input' class is now a dumb set of attributes. All the fetcher
implementations subclass InputScheme, not Input. This simplifies the
API.
Also, fix substitution of flake inputs. This was broken since lazy
flake fetching started using fetchTree internally.
2020-05-29 22:44:11 +00:00
|
|
|
std::optional<Input> inputFromAttrs(const Attrs & attrs) override
|
2020-03-30 14:04:18 +00:00
|
|
|
{
|
|
|
|
if (maybeGetStrAttr(attrs, "type") != "tarball") return {};
|
|
|
|
|
|
|
|
for (auto & [name, value] : attrs)
|
Remove TreeInfo
The attributes previously stored in TreeInfo (narHash, revCount,
lastModified) are now stored in Input. This makes it less arbitrary
what attributes are stored where.
As a result, the lock file format has changed. An entry like
"info": {
"lastModified": 1585405475,
"narHash": "sha256-bESW0n4KgPmZ0luxvwJ+UyATrC6iIltVCsGdLiphVeE="
},
"locked": {
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "b88ff468e9850410070d4e0ccd68c7011f15b2be",
"type": "github"
},
is now stored as
"locked": {
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "b88ff468e9850410070d4e0ccd68c7011f15b2be",
"type": "github",
"lastModified": 1585405475,
"narHash": "sha256-bESW0n4KgPmZ0luxvwJ+UyATrC6iIltVCsGdLiphVeE="
},
The 'Input' class is now a dumb set of attributes. All the fetcher
implementations subclass InputScheme, not Input. This simplifies the
API.
Also, fix substitution of flake inputs. This was broken since lazy
flake fetching started using fetchTree internally.
2020-05-29 22:44:11 +00:00
|
|
|
if (name != "type" && name != "url" && /* name != "hash" && */ name != "narHash")
|
2020-03-30 14:04:18 +00:00
|
|
|
throw Error("unsupported tarball input attribute '%s'", name);
|
|
|
|
|
Remove TreeInfo
The attributes previously stored in TreeInfo (narHash, revCount,
lastModified) are now stored in Input. This makes it less arbitrary
what attributes are stored where.
As a result, the lock file format has changed. An entry like
"info": {
"lastModified": 1585405475,
"narHash": "sha256-bESW0n4KgPmZ0luxvwJ+UyATrC6iIltVCsGdLiphVeE="
},
"locked": {
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "b88ff468e9850410070d4e0ccd68c7011f15b2be",
"type": "github"
},
is now stored as
"locked": {
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "b88ff468e9850410070d4e0ccd68c7011f15b2be",
"type": "github",
"lastModified": 1585405475,
"narHash": "sha256-bESW0n4KgPmZ0luxvwJ+UyATrC6iIltVCsGdLiphVeE="
},
The 'Input' class is now a dumb set of attributes. All the fetcher
implementations subclass InputScheme, not Input. This simplifies the
API.
Also, fix substitution of flake inputs. This was broken since lazy
flake fetching started using fetchTree internally.
2020-05-29 22:44:11 +00:00
|
|
|
Input input;
|
|
|
|
input.attrs = attrs;
|
|
|
|
//input.immutable = (bool) maybeGetStrAttr(input.attrs, "hash");
|
2020-03-30 14:04:18 +00:00
|
|
|
return input;
|
|
|
|
}
|
Remove TreeInfo
The attributes previously stored in TreeInfo (narHash, revCount,
lastModified) are now stored in Input. This makes it less arbitrary
what attributes are stored where.
As a result, the lock file format has changed. An entry like
"info": {
"lastModified": 1585405475,
"narHash": "sha256-bESW0n4KgPmZ0luxvwJ+UyATrC6iIltVCsGdLiphVeE="
},
"locked": {
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "b88ff468e9850410070d4e0ccd68c7011f15b2be",
"type": "github"
},
is now stored as
"locked": {
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "b88ff468e9850410070d4e0ccd68c7011f15b2be",
"type": "github",
"lastModified": 1585405475,
"narHash": "sha256-bESW0n4KgPmZ0luxvwJ+UyATrC6iIltVCsGdLiphVeE="
},
The 'Input' class is now a dumb set of attributes. All the fetcher
implementations subclass InputScheme, not Input. This simplifies the
API.
Also, fix substitution of flake inputs. This was broken since lazy
flake fetching started using fetchTree internally.
2020-05-29 22:44:11 +00:00
|
|
|
|
|
|
|
ParsedURL toURL(const Input & input) override
|
|
|
|
{
|
|
|
|
auto url = parseURL(getStrAttr(input.attrs, "url"));
|
|
|
|
// NAR hashes are preferred over file hashes since tar/zip files
|
|
|
|
// don't have a canonical representation.
|
|
|
|
if (auto narHash = input.getNarHash())
|
|
|
|
url.query.insert_or_assign("narHash", narHash->to_string(SRI));
|
|
|
|
/*
|
|
|
|
else if (auto hash = maybeGetStrAttr(input.attrs, "hash"))
|
|
|
|
url.query.insert_or_assign("hash", Hash(*hash).to_string(SRI));
|
|
|
|
*/
|
|
|
|
return url;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool hasAllInfo(const Input & input) override
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::pair<Tree, Input> fetch(ref<Store> store, const Input & input) override
|
|
|
|
{
|
|
|
|
auto tree = downloadTarball(store, getStrAttr(input.attrs, "url"), "source", false).first;
|
|
|
|
return {std::move(tree), input};
|
|
|
|
}
|
2020-03-30 14:04:18 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static auto r1 = OnStartup([] { registerInputScheme(std::make_unique<TarballInputScheme>()); });
|
|
|
|
|
|
|
|
}
|