aboutsummaryrefslogtreecommitdiff
path: root/src/libfetchers
diff options
context:
space:
mode:
Diffstat (limited to 'src/libfetchers')
-rw-r--r--src/libfetchers/cache.cc8
-rw-r--r--src/libfetchers/cache.hh2
-rw-r--r--src/libfetchers/fetchers.cc20
-rw-r--r--src/libfetchers/fetchers.hh15
-rw-r--r--src/libfetchers/git.cc38
-rw-r--r--src/libfetchers/github.cc108
-rw-r--r--src/libfetchers/indirect.cc2
-rw-r--r--src/libfetchers/mercurial.cc32
-rw-r--r--src/libfetchers/path.cc9
-rw-r--r--src/libfetchers/tarball.cc33
10 files changed, 169 insertions, 98 deletions
diff --git a/src/libfetchers/cache.cc b/src/libfetchers/cache.cc
index 34ff6f85b..0c8ecac9d 100644
--- a/src/libfetchers/cache.cc
+++ b/src/libfetchers/cache.cc
@@ -52,13 +52,13 @@ struct CacheImpl : Cache
const Attrs & inAttrs,
const Attrs & infoAttrs,
const StorePath & storePath,
- bool immutable) override
+ bool locked) override
{
_state.lock()->add.use()
(attrsToJSON(inAttrs).dump())
(attrsToJSON(infoAttrs).dump())
(store->printStorePath(storePath))
- (immutable)
+ (locked)
(time(0)).exec();
}
@@ -91,7 +91,7 @@ struct CacheImpl : Cache
auto infoJSON = stmt.getStr(0);
auto storePath = store->parseStorePath(stmt.getStr(1));
- auto immutable = stmt.getInt(2) != 0;
+ auto locked = stmt.getInt(2) != 0;
auto timestamp = stmt.getInt(3);
store->addTempRoot(storePath);
@@ -105,7 +105,7 @@ struct CacheImpl : Cache
inAttrsJSON, infoJSON, store->printStorePath(storePath));
return Result {
- .expired = !immutable && (settings.tarballTtl.get() == 0 || timestamp + settings.tarballTtl < time(0)),
+ .expired = !locked && (settings.tarballTtl.get() == 0 || timestamp + settings.tarballTtl < time(0)),
.infoAttrs = jsonToAttrs(nlohmann::json::parse(infoJSON)),
.storePath = std::move(storePath)
};
diff --git a/src/libfetchers/cache.hh b/src/libfetchers/cache.hh
index 3db4f081c..3763ee2a6 100644
--- a/src/libfetchers/cache.hh
+++ b/src/libfetchers/cache.hh
@@ -13,7 +13,7 @@ struct Cache
const Attrs & inAttrs,
const Attrs & infoAttrs,
const StorePath & storePath,
- bool immutable) = 0;
+ bool locked) = 0;
virtual std::optional<std::pair<Attrs, StorePath>> lookup(
ref<Store> store,
diff --git a/src/libfetchers/fetchers.cc b/src/libfetchers/fetchers.cc
index e158d914b..976f40d3b 100644
--- a/src/libfetchers/fetchers.cc
+++ b/src/libfetchers/fetchers.cc
@@ -24,11 +24,11 @@ static void fixupInput(Input & input)
input.getType();
input.getRef();
if (input.getRev())
- input.immutable = true;
+ input.locked = true;
input.getRevCount();
input.getLastModified();
if (input.getNarHash())
- input.immutable = true;
+ input.locked = true;
}
Input Input::fromURL(const ParsedURL & url)
@@ -124,15 +124,13 @@ std::pair<Tree, Input> Input::fetch(ref<Store> store) const
debug("using substituted/cached input '%s' in '%s'",
to_string(), store->printStorePath(storePath));
- auto actualPath = store->toRealPath(storePath);
-
- return {fetchers::Tree(std::move(actualPath), std::move(storePath)), *this};
+ return {Tree { .actualPath = store->toRealPath(storePath), .storePath = std::move(storePath) }, *this};
} catch (Error & e) {
debug("substitution of input '%s' failed: %s", to_string(), e.what());
}
}
- auto [tree, input] = [&]() -> std::pair<Tree, Input> {
+ auto [storePath, input] = [&]() -> std::pair<StorePath, Input> {
try {
return scheme->fetch(store, *this);
} catch (Error & e) {
@@ -141,8 +139,10 @@ std::pair<Tree, Input> Input::fetch(ref<Store> store) const
}
}();
- if (tree.actualPath == "")
- tree.actualPath = store->toRealPath(tree.storePath);
+ Tree tree {
+ .actualPath = store->toRealPath(storePath),
+ .storePath = storePath,
+ };
auto narHash = store->queryPathInfo(tree.storePath)->narHash;
input.attrs.insert_or_assign("narHash", narHash.to_string(SRI, true));
@@ -165,7 +165,7 @@ std::pair<Tree, Input> Input::fetch(ref<Store> store) const
input.to_string(), *prevRevCount);
}
- input.immutable = true;
+ input.locked = true;
assert(input.hasAllInfo());
@@ -209,7 +209,7 @@ StorePath Input::computeStorePath(Store & store) const
{
auto narHash = getNarHash();
if (!narHash)
- throw Error("cannot compute store path for mutable input '%s'", to_string());
+ throw Error("cannot compute store path for unlocked input '%s'", to_string());
return store.makeFixedOutputPath(FileIngestionMethod::Recursive, *narHash, getName());
}
diff --git a/src/libfetchers/fetchers.hh b/src/libfetchers/fetchers.hh
index c43b047a7..bc9a76b0b 100644
--- a/src/libfetchers/fetchers.hh
+++ b/src/libfetchers/fetchers.hh
@@ -16,7 +16,6 @@ struct Tree
{
Path actualPath;
StorePath storePath;
- Tree(Path && actualPath, StorePath && storePath) : actualPath(actualPath), storePath(std::move(storePath)) {}
};
struct InputScheme;
@@ -35,7 +34,7 @@ struct Input
std::shared_ptr<InputScheme> scheme; // note: can be null
Attrs attrs;
- bool immutable = false;
+ bool locked = false;
bool direct = true;
/* path of the parent of this input, used for relative path resolution */
@@ -60,9 +59,9 @@ public:
one that goes through a registry. */
bool isDirect() const { return direct; }
- /* Check whether this is an "immutable" input, that is,
+ /* Check whether this is a "locked" input, that is,
one that contains a commit hash or content hash. */
- bool isImmutable() const { return immutable; }
+ bool isLocked() const { return locked; }
bool hasAllInfo() const;
@@ -70,6 +69,8 @@ public:
bool contains(const Input & other) const;
+ /* Fetch the input into the Nix store, returning the location in
+ the Nix store and the locked input. */
std::pair<Tree, Input> fetch(ref<Store> store) const;
Input applyOverrides(
@@ -131,7 +132,7 @@ struct InputScheme
virtual void markChangedFile(const Input & input, std::string_view file, std::optional<std::string> commitMsg);
- virtual std::pair<Tree, Input> fetch(ref<Store> store, const Input & input) = 0;
+ virtual std::pair<StorePath, Input> fetch(ref<Store> store, const Input & input) = 0;
};
void registerInputScheme(std::shared_ptr<InputScheme> && fetcher);
@@ -147,14 +148,14 @@ DownloadFileResult downloadFile(
ref<Store> store,
const std::string & url,
const std::string & name,
- bool immutable,
+ bool locked,
const Headers & headers = {});
std::pair<Tree, time_t> downloadTarball(
ref<Store> store,
const std::string & url,
const std::string & name,
- bool immutable,
+ bool locked,
const Headers & headers = {});
}
diff --git a/src/libfetchers/git.cc b/src/libfetchers/git.cc
index 8468d2afc..7f65c1533 100644
--- a/src/libfetchers/git.cc
+++ b/src/libfetchers/git.cc
@@ -51,7 +51,7 @@ struct GitInputScheme : InputScheme
for (auto &[name, value] : url.query) {
if (name == "rev" || name == "ref")
attrs.emplace(name, value);
- else if (name == "shallow")
+ else if (name == "shallow" || name == "submodules")
attrs.emplace(name, Explicit<bool> { value == "1" });
else
url2.query.emplace(name, value);
@@ -172,7 +172,7 @@ struct GitInputScheme : InputScheme
return {isLocal, isLocal ? url.path : url.base};
}
- std::pair<Tree, Input> fetch(ref<Store> store, const Input & _input) override
+ std::pair<StorePath, Input> fetch(ref<Store> store, const Input & _input) override
{
Input input(_input);
@@ -187,7 +187,7 @@ struct GitInputScheme : InputScheme
if (submodules) cacheType += "-submodules";
if (allRefs) cacheType += "-all-refs";
- auto getImmutableAttrs = [&]()
+ auto getLockedAttrs = [&]()
{
return Attrs({
{"type", cacheType},
@@ -197,21 +197,18 @@ struct GitInputScheme : InputScheme
};
auto makeResult = [&](const Attrs & infoAttrs, StorePath && storePath)
- -> std::pair<Tree, Input>
+ -> std::pair<StorePath, Input>
{
assert(input.getRev());
assert(!_input.getRev() || _input.getRev() == input.getRev());
if (!shallow)
input.attrs.insert_or_assign("revCount", getIntAttr(infoAttrs, "revCount"));
input.attrs.insert_or_assign("lastModified", getIntAttr(infoAttrs, "lastModified"));
- return {
- Tree(store->toRealPath(storePath), std::move(storePath)),
- input
- };
+ return {std::move(storePath), input};
};
if (input.getRev()) {
- if (auto res = getCache()->lookup(store, getImmutableAttrs()))
+ if (auto res = getCache()->lookup(store, getLockedAttrs()))
return makeResult(res->first, std::move(res->second));
}
@@ -285,16 +282,13 @@ struct GitInputScheme : InputScheme
"lastModified",
haveCommits ? std::stoull(runProgram("git", true, { "-C", actualUrl, "log", "-1", "--format=%ct", "--no-show-signature", "HEAD" })) : 0);
- return {
- Tree(store->toRealPath(storePath), std::move(storePath)),
- input
- };
+ return {std::move(storePath), input};
}
}
if (!input.getRef()) input.attrs.insert_or_assign("ref", isLocal ? readHead(actualUrl) : "master");
- Attrs mutableAttrs({
+ Attrs unlockedAttrs({
{"type", cacheType},
{"name", name},
{"url", actualUrl},
@@ -313,7 +307,7 @@ struct GitInputScheme : InputScheme
} else {
- if (auto res = getCache()->lookup(store, mutableAttrs)) {
+ if (auto res = getCache()->lookup(store, unlockedAttrs)) {
auto rev2 = Hash::parseAny(getStrAttr(res->first, "rev"), htSHA1);
if (!input.getRev() || input.getRev() == rev2) {
input.attrs.insert_or_assign("rev", rev2.gitRev());
@@ -324,17 +318,13 @@ struct GitInputScheme : InputScheme
Path cacheDir = getCacheDir() + "/nix/gitv3/" + hashString(htSHA256, actualUrl).to_string(Base32, false);
repoDir = cacheDir;
- Path cacheDirLock = cacheDir + ".lock";
createDirs(dirOf(cacheDir));
- AutoCloseFD lock = openLockFile(cacheDirLock, true);
- lockFile(lock.get(), ltWrite, true);
+ PathLocks cacheDirLock({cacheDir + ".lock"});
if (!pathExists(cacheDir)) {
runProgram("git", true, { "-c", "init.defaultBranch=" + gitInitialBranch, "init", "--bare", repoDir });
}
- deleteLockFile(cacheDirLock, lock.get());
-
Path localRefFile =
input.getRef()->compare(0, 5, "refs/") == 0
? cacheDir + "/" + *input.getRef()
@@ -399,6 +389,8 @@ struct GitInputScheme : InputScheme
if (!input.getRev())
input.attrs.insert_or_assign("rev", Hash::parseAny(chomp(readFile(localRefFile)), htSHA1).gitRev());
+
+ // cache dir lock is removed at scope end; we will only use read-only operations on specific revisions in the remainder
}
bool isShallow = chomp(runProgram("git", true, { "-C", repoDir, "rev-parse", "--is-shallow-repository" })) == "true";
@@ -412,7 +404,7 @@ struct GitInputScheme : InputScheme
/* Now that we know the ref, check again whether we have it in
the store. */
- if (auto res = getCache()->lookup(store, getImmutableAttrs()))
+ if (auto res = getCache()->lookup(store, getLockedAttrs()))
return makeResult(res->first, std::move(res->second));
Path tmpDir = createTempDir();
@@ -484,14 +476,14 @@ struct GitInputScheme : InputScheme
if (!_input.getRev())
getCache()->add(
store,
- mutableAttrs,
+ unlockedAttrs,
infoAttrs,
storePath,
false);
getCache()->add(
store,
- getImmutableAttrs(),
+ getLockedAttrs(),
infoAttrs,
storePath,
true);
diff --git a/src/libfetchers/github.cc b/src/libfetchers/github.cc
index ffc44e9e2..70622bf79 100644
--- a/src/libfetchers/github.cc
+++ b/src/libfetchers/github.cc
@@ -8,6 +8,7 @@
#include <optional>
#include <nlohmann/json.hpp>
+#include <fstream>
namespace nix::fetchers {
@@ -17,7 +18,7 @@ struct DownloadUrl
Headers headers;
};
-// A github or gitlab host
+// A github, gitlab, or sourcehut host
const static std::string hostRegexS = "[a-zA-Z0-9.]*"; // FIXME: check
std::regex hostRegex(hostRegexS, std::regex::ECMAScript);
@@ -180,7 +181,7 @@ struct GitArchiveInputScheme : InputScheme
virtual DownloadUrl getDownloadUrl(const Input & input) const = 0;
- std::pair<Tree, Input> fetch(ref<Store> store, const Input & _input) override
+ std::pair<StorePath, Input> fetch(ref<Store> store, const Input & _input) override
{
Input input(_input);
@@ -192,17 +193,14 @@ struct GitArchiveInputScheme : InputScheme
input.attrs.erase("ref");
input.attrs.insert_or_assign("rev", rev->gitRev());
- Attrs immutableAttrs({
+ Attrs lockedAttrs({
{"type", "git-tarball"},
{"rev", rev->gitRev()},
});
- if (auto res = getCache()->lookup(store, immutableAttrs)) {
+ if (auto res = getCache()->lookup(store, lockedAttrs)) {
input.attrs.insert_or_assign("lastModified", getIntAttr(res->first, "lastModified"));
- return {
- Tree(store->toRealPath(res->second), std::move(res->second)),
- input
- };
+ return {std::move(res->second), input};
}
auto url = getDownloadUrl(input);
@@ -213,7 +211,7 @@ struct GitArchiveInputScheme : InputScheme
getCache()->add(
store,
- immutableAttrs,
+ lockedAttrs,
{
{"rev", rev->gitRev()},
{"lastModified", uint64_t(lastModified)}
@@ -221,7 +219,7 @@ struct GitArchiveInputScheme : InputScheme
tree.storePath,
true);
- return {std::move(tree), input};
+ return {std::move(tree.storePath), input};
}
};
@@ -300,7 +298,7 @@ struct GitLabInputScheme : GitArchiveInputScheme
if ("PAT" == token.substr(0, fldsplit))
return std::make_pair("Private-token", token.substr(fldsplit+1));
warn("Unrecognized GitLab token type %s", token.substr(0, fldsplit));
- return std::nullopt;
+ return std::make_pair(token.substr(0,fldsplit), token.substr(fldsplit+1));
}
Hash getRevFromRef(nix::ref<Store> store, const Input & input) const override
@@ -348,7 +346,95 @@ struct GitLabInputScheme : GitArchiveInputScheme
}
};
+struct SourceHutInputScheme : GitArchiveInputScheme
+{
+ std::string type() override { return "sourcehut"; }
+
+ std::optional<std::pair<std::string, std::string>> accessHeaderFromToken(const std::string & token) const override
+ {
+ // SourceHut supports both PAT and OAuth2. See
+ // https://man.sr.ht/meta.sr.ht/oauth.md
+ return std::pair<std::string, std::string>("Authorization", fmt("Bearer %s", token));
+ // Note: This currently serves no purpose, as this kind of authorization
+ // does not allow for downloading tarballs on sourcehut private repos.
+ // Once it is implemented, however, should work as expected.
+ }
+
+ Hash getRevFromRef(nix::ref<Store> store, const Input & input) const override
+ {
+ // TODO: In the future, when the sourcehut graphql API is implemented for mercurial
+ // and with anonymous access, this method should use it instead.
+
+ auto ref = *input.getRef();
+
+ auto host = maybeGetStrAttr(input.attrs, "host").value_or("git.sr.ht");
+ auto base_url = fmt("https://%s/%s/%s",
+ host, getStrAttr(input.attrs, "owner"), getStrAttr(input.attrs, "repo"));
+
+ Headers headers = makeHeadersWithAuthTokens(host);
+
+ std::string ref_uri;
+ if (ref == "HEAD") {
+ auto file = store->toRealPath(
+ downloadFile(store, fmt("%s/HEAD", base_url), "source", false, headers).storePath);
+ std::ifstream is(file);
+ std::string line;
+ getline(is, line);
+
+ auto ref_index = line.find("ref: ");
+ if (ref_index == std::string::npos) {
+ throw BadURL("in '%d', couldn't resolve HEAD ref '%d'", input.to_string(), ref);
+ }
+
+ ref_uri = line.substr(ref_index+5, line.length()-1);
+ } else
+ ref_uri = fmt("refs/heads/%s", ref);
+
+ auto file = store->toRealPath(
+ downloadFile(store, fmt("%s/info/refs", base_url), "source", false, headers).storePath);
+ std::ifstream is(file);
+
+ std::string line;
+ std::string id;
+ while(getline(is, line)) {
+ auto index = line.find(ref_uri);
+ if (index != std::string::npos) {
+ id = line.substr(0, index-1);
+ break;
+ }
+ }
+
+ if(id.empty())
+ throw BadURL("in '%d', couldn't find ref '%d'", input.to_string(), ref);
+
+ auto rev = Hash::parseAny(id, htSHA1);
+ debug("HEAD revision for '%s' is %s", fmt("%s/%s", base_url, ref), rev.gitRev());
+ return rev;
+ }
+
+ DownloadUrl getDownloadUrl(const Input & input) const override
+ {
+ auto host = maybeGetStrAttr(input.attrs, "host").value_or("git.sr.ht");
+ auto url = fmt("https://%s/%s/%s/archive/%s.tar.gz",
+ host, getStrAttr(input.attrs, "owner"), getStrAttr(input.attrs, "repo"),
+ input.getRev()->to_string(Base16, false));
+
+ Headers headers = makeHeadersWithAuthTokens(host);
+ return DownloadUrl { url, headers };
+ }
+
+ void clone(const Input & input, const Path & destDir) override
+ {
+ auto host = maybeGetStrAttr(input.attrs, "host").value_or("git.sr.ht");
+ Input::fromURL(fmt("git+https://%s/%s/%s",
+ host, getStrAttr(input.attrs, "owner"), getStrAttr(input.attrs, "repo")))
+ .applyOverrides(input.getRef(), input.getRev())
+ .clone(destDir);
+ }
+};
+
static auto rGitHubInputScheme = OnStartup([] { registerInputScheme(std::make_unique<GitHubInputScheme>()); });
static auto rGitLabInputScheme = OnStartup([] { registerInputScheme(std::make_unique<GitLabInputScheme>()); });
+static auto rSourceHutInputScheme = OnStartup([] { registerInputScheme(std::make_unique<SourceHutInputScheme>()); });
}
diff --git a/src/libfetchers/indirect.cc b/src/libfetchers/indirect.cc
index 10e59919a..9288fc6cf 100644
--- a/src/libfetchers/indirect.cc
+++ b/src/libfetchers/indirect.cc
@@ -94,7 +94,7 @@ struct IndirectInputScheme : InputScheme
return input;
}
- std::pair<Tree, Input> fetch(ref<Store> store, const Input & input) override
+ std::pair<StorePath, Input> fetch(ref<Store> store, const Input & input) override
{
throw Error("indirect input '%s' cannot be fetched directly", input.to_string());
}
diff --git a/src/libfetchers/mercurial.cc b/src/libfetchers/mercurial.cc
index d52d4641b..12cdecbc1 100644
--- a/src/libfetchers/mercurial.cc
+++ b/src/libfetchers/mercurial.cc
@@ -26,7 +26,7 @@ static RunOptions hgOptions(const Strings & args)
}
// runProgram wrapper that uses hgOptions instead of stock RunOptions.
-static string runHg(const Strings & args, const std::optional<std::string> & input = {})
+static std::string runHg(const Strings & args, const std::optional<std::string> & input = {})
{
RunOptions opts = hgOptions(args);
opts.input = input;
@@ -143,7 +143,7 @@ struct MercurialInputScheme : InputScheme
return {isLocal, isLocal ? url.path : url.base};
}
- std::pair<Tree, Input> fetch(ref<Store> store, const Input & _input) override
+ std::pair<StorePath, Input> fetch(ref<Store> store, const Input & _input) override
{
Input input(_input);
@@ -193,16 +193,13 @@ struct MercurialInputScheme : InputScheme
auto storePath = store->addToStore(input.getName(), actualUrl, FileIngestionMethod::Recursive, htSHA256, filter);
- return {
- Tree(store->toRealPath(storePath), std::move(storePath)),
- input
- };
+ return {std::move(storePath), input};
}
}
if (!input.getRef()) input.attrs.insert_or_assign("ref", "default");
- auto getImmutableAttrs = [&]()
+ auto getLockedAttrs = [&]()
{
return Attrs({
{"type", "hg"},
@@ -212,32 +209,29 @@ struct MercurialInputScheme : InputScheme
};
auto makeResult = [&](const Attrs & infoAttrs, StorePath && storePath)
- -> std::pair<Tree, Input>
+ -> std::pair<StorePath, Input>
{
assert(input.getRev());
assert(!_input.getRev() || _input.getRev() == input.getRev());
input.attrs.insert_or_assign("revCount", getIntAttr(infoAttrs, "revCount"));
- return {
- Tree(store->toRealPath(storePath), std::move(storePath)),
- input
- };
+ return {std::move(storePath), input};
};
if (input.getRev()) {
- if (auto res = getCache()->lookup(store, getImmutableAttrs()))
+ if (auto res = getCache()->lookup(store, getLockedAttrs()))
return makeResult(res->first, std::move(res->second));
}
auto revOrRef = input.getRev() ? input.getRev()->gitRev() : *input.getRef();
- Attrs mutableAttrs({
+ Attrs unlockedAttrs({
{"type", "hg"},
{"name", name},
{"url", actualUrl},
{"ref", *input.getRef()},
});
- if (auto res = getCache()->lookup(store, mutableAttrs)) {
+ if (auto res = getCache()->lookup(store, unlockedAttrs)) {
auto rev2 = Hash::parseAny(getStrAttr(res->first, "rev"), htSHA1);
if (!input.getRev() || input.getRev() == rev2) {
input.attrs.insert_or_assign("rev", rev2.gitRev());
@@ -260,7 +254,7 @@ struct MercurialInputScheme : InputScheme
runHg({ "pull", "-R", cacheDir, "--", actualUrl });
}
catch (ExecError & e) {
- string transJournal = cacheDir + "/.hg/store/journal";
+ auto transJournal = cacheDir + "/.hg/store/journal";
/* hg throws "abandoned transaction" error only if this file exists */
if (pathExists(transJournal)) {
runHg({ "recover", "-R", cacheDir });
@@ -283,7 +277,7 @@ struct MercurialInputScheme : InputScheme
auto revCount = std::stoull(tokens[1]);
input.attrs.insert_or_assign("ref", tokens[2]);
- if (auto res = getCache()->lookup(store, getImmutableAttrs()))
+ if (auto res = getCache()->lookup(store, getLockedAttrs()))
return makeResult(res->first, std::move(res->second));
Path tmpDir = createTempDir();
@@ -303,14 +297,14 @@ struct MercurialInputScheme : InputScheme
if (!_input.getRev())
getCache()->add(
store,
- mutableAttrs,
+ unlockedAttrs,
infoAttrs,
storePath,
false);
getCache()->add(
store,
- getImmutableAttrs(),
+ getLockedAttrs(),
infoAttrs,
storePath,
true);
diff --git a/src/libfetchers/path.cc b/src/libfetchers/path.cc
index fb5702c4c..59e228e97 100644
--- a/src/libfetchers/path.cc
+++ b/src/libfetchers/path.cc
@@ -80,7 +80,7 @@ struct PathInputScheme : InputScheme
// nothing to do
}
- std::pair<Tree, Input> fetch(ref<Store> store, const Input & input) override
+ std::pair<StorePath, Input> fetch(ref<Store> store, const Input & input) override
{
std::string absPath;
auto path = getStrAttr(input.attrs, "path");
@@ -97,7 +97,7 @@ struct PathInputScheme : InputScheme
// for security, ensure that if the parent is a store path, it's inside it
if (store->isInStore(parent)) {
auto storePath = store->printStorePath(store->toStorePath(parent).first);
- if (!isInDir(absPath, storePath))
+ if (!isDirOrInDir(absPath, storePath))
throw BadStorePath("relative path '%s' points outside of its parent's store path '%s'", path, storePath);
}
} else
@@ -115,10 +115,7 @@ struct PathInputScheme : InputScheme
// FIXME: try to substitute storePath.
storePath = store->addToStore("source", absPath);
- return {
- Tree(store->toRealPath(*storePath), std::move(*storePath)),
- input
- };
+ return {std::move(*storePath), input};
}
};
diff --git a/src/libfetchers/tarball.cc b/src/libfetchers/tarball.cc
index 031ccc5f7..dde0ad761 100644
--- a/src/libfetchers/tarball.cc
+++ b/src/libfetchers/tarball.cc
@@ -13,7 +13,7 @@ DownloadFileResult downloadFile(
ref<Store> store,
const std::string & url,
const std::string & name,
- bool immutable,
+ bool locked,
const Headers & headers)
{
// FIXME: check store
@@ -67,18 +67,18 @@ DownloadFileResult downloadFile(
storePath = std::move(cached->storePath);
} else {
StringSink sink;
- dumpString(*res.data, sink);
- auto hash = hashString(htSHA256, *res.data);
+ dumpString(res.data, sink);
+ auto hash = hashString(htSHA256, res.data);
ValidPathInfo info {
store->makeFixedOutputPath(FileIngestionMethod::Flat, hash, name),
- hashString(htSHA256, *sink.s),
+ hashString(htSHA256, sink.s),
};
- info.narSize = sink.s->size();
+ info.narSize = sink.s.size();
info.ca = FixedOutputHash {
.method = FileIngestionMethod::Flat,
.hash = hash,
};
- auto source = StringSource { *sink.s };
+ auto source = StringSource(sink.s);
store->addToStore(info, source, NoRepair, NoCheckSigs);
storePath = std::move(info.path);
}
@@ -88,7 +88,7 @@ DownloadFileResult downloadFile(
inAttrs,
infoAttrs,
*storePath,
- immutable);
+ locked);
if (url != res.effectiveUri)
getCache()->add(
@@ -100,7 +100,7 @@ DownloadFileResult downloadFile(
},
infoAttrs,
*storePath,
- immutable);
+ locked);
return {
.storePath = std::move(*storePath),
@@ -113,7 +113,7 @@ std::pair<Tree, time_t> downloadTarball(
ref<Store> store,
const std::string & url,
const std::string & name,
- bool immutable,
+ bool locked,
const Headers & headers)
{
Attrs inAttrs({
@@ -126,11 +126,11 @@ std::pair<Tree, time_t> downloadTarball(
if (cached && !cached->expired)
return {
- Tree(store->toRealPath(cached->storePath), std::move(cached->storePath)),
+ Tree { .actualPath = store->toRealPath(cached->storePath), .storePath = std::move(cached->storePath) },
getIntAttr(cached->infoAttrs, "lastModified")
};
- auto res = downloadFile(store, url, name, immutable, headers);
+ auto res = downloadFile(store, url, name, locked, headers);
std::optional<StorePath> unpackedStorePath;
time_t lastModified;
@@ -160,10 +160,10 @@ std::pair<Tree, time_t> downloadTarball(
inAttrs,
infoAttrs,
*unpackedStorePath,
- immutable);
+ locked);
return {
- Tree(store->toRealPath(*unpackedStorePath), std::move(*unpackedStorePath)),
+ Tree { .actualPath = store->toRealPath(*unpackedStorePath), .storePath = std::move(*unpackedStorePath) },
lastModified,
};
}
@@ -176,6 +176,7 @@ struct TarballInputScheme : InputScheme
if (!hasSuffix(url.path, ".zip")
&& !hasSuffix(url.path, ".tar")
+ && !hasSuffix(url.path, ".tgz")
&& !hasSuffix(url.path, ".tar.gz")
&& !hasSuffix(url.path, ".tar.xz")
&& !hasSuffix(url.path, ".tar.bz2")
@@ -201,7 +202,7 @@ struct TarballInputScheme : InputScheme
Input input;
input.attrs = attrs;
- //input.immutable = (bool) maybeGetStrAttr(input.attrs, "hash");
+ //input.locked = (bool) maybeGetStrAttr(input.attrs, "hash");
return input;
}
@@ -224,10 +225,10 @@ struct TarballInputScheme : InputScheme
return true;
}
- std::pair<Tree, Input> fetch(ref<Store> store, const Input & input) override
+ std::pair<StorePath, Input> fetch(ref<Store> store, const Input & input) override
{
auto tree = downloadTarball(store, getStrAttr(input.attrs, "url"), input.getName(), false).first;
- return {std::move(tree), input};
+ return {std::move(tree.storePath), input};
}
};