mirror of
https://github.com/NixOS/nix
synced 2025-07-04 03:01:47 +02:00
Remove InputScheme::fetchToStore()
InputSchemes now only have a getAccessor(). They could be implemented internally by fetching the input to the store, but in that case they will just return a FSInputAccessor.
This commit is contained in:
parent
360a1284db
commit
55c63c9b89
13 changed files with 168 additions and 162 deletions
|
@ -94,7 +94,7 @@ SourcePath lookupFileArg(EvalState & state, std::string_view s)
|
||||||
if (isUri(s)) {
|
if (isUri(s)) {
|
||||||
auto storePath = fetchers::downloadTarball(
|
auto storePath = fetchers::downloadTarball(
|
||||||
state.store, resolveUri(s), "source", false).first;
|
state.store, resolveUri(s), "source", false).first;
|
||||||
auto accessor = makeFSInputAccessor(CanonPath(state.store->toRealPath(storePath)));
|
auto accessor = makeStorePathAccessor(state.store, storePath);
|
||||||
state.registerAccessor(accessor);
|
state.registerAccessor(accessor);
|
||||||
return {accessor, CanonPath::root};
|
return {accessor, CanonPath::root};
|
||||||
} else if (s.size() > 2 && s.at(0) == '<' && s.at(s.size() - 1) == '>') {
|
} else if (s.size() > 2 && s.at(0) == '<' && s.at(s.size() - 1) == '>') {
|
||||||
|
|
|
@ -791,7 +791,7 @@ SourcePath EvalState::findFile(SearchPath & searchPath, const std::string_view p
|
||||||
try {
|
try {
|
||||||
auto storePath = fetchers::downloadTarball(
|
auto storePath = fetchers::downloadTarball(
|
||||||
store, resolveUri(elem.second), "source", false).first;
|
store, resolveUri(elem.second), "source", false).first;
|
||||||
auto accessor = makeFSInputAccessor(CanonPath(store->toRealPath(storePath)));
|
auto accessor = makeStorePathAccessor(store, storePath);
|
||||||
registerAccessor(accessor);
|
registerAccessor(accessor);
|
||||||
res.emplace(SourcePath {accessor, CanonPath::root});
|
res.emplace(SourcePath {accessor, CanonPath::root});
|
||||||
} catch (FileTransferError & e) {
|
} catch (FileTransferError & e) {
|
||||||
|
|
|
@ -115,32 +115,40 @@ bool Input::contains(const Input & other) const
|
||||||
|
|
||||||
std::pair<StorePath, Input> Input::fetchToStore(ref<Store> store) const
|
std::pair<StorePath, Input> Input::fetchToStore(ref<Store> store) const
|
||||||
{
|
{
|
||||||
if (!scheme)
|
|
||||||
throw Error("cannot fetch unsupported input '%s'", attrsToJSON(toAttrs()));
|
|
||||||
|
|
||||||
auto [storePath, input] = [&]() -> std::pair<StorePath, Input> {
|
auto [storePath, input] = [&]() -> std::pair<StorePath, Input> {
|
||||||
try {
|
try {
|
||||||
return scheme->fetchToStore(store, *this);
|
auto [accessor, input2] = getAccessor(store);
|
||||||
|
|
||||||
|
// FIXME: add an optimisation for the case where the
|
||||||
|
// accessor is an FSInputAccessor pointing to a store
|
||||||
|
// path.
|
||||||
|
auto source = sinkToSource([&, accessor{accessor}](Sink & sink) {
|
||||||
|
accessor->dumpPath(CanonPath::root, sink);
|
||||||
|
});
|
||||||
|
|
||||||
|
auto storePath = store->addToStoreFromDump(*source, input2.getName());
|
||||||
|
|
||||||
|
return {storePath, input2};
|
||||||
} catch (Error & e) {
|
} catch (Error & e) {
|
||||||
e.addTrace({}, "while fetching the input '%s'", to_string());
|
e.addTrace({}, "while fetching the input '%s'", to_string());
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
}();
|
}();
|
||||||
|
|
||||||
checkLocked(*store, storePath, input);
|
|
||||||
|
|
||||||
return {std::move(storePath), input};
|
return {std::move(storePath), input};
|
||||||
}
|
}
|
||||||
|
|
||||||
void Input::checkLocked(Store & store, const StorePath & storePath, Input & input) const
|
void Input::checkLocks(Input & input) const
|
||||||
{
|
{
|
||||||
|
#if 0
|
||||||
auto narHash = store.queryPathInfo(storePath)->narHash;
|
auto narHash = store.queryPathInfo(storePath)->narHash;
|
||||||
input.attrs.insert_or_assign("narHash", narHash.to_string(SRI, true));
|
input.attrs.insert_or_assign("narHash", narHash.to_string(SRI, true));
|
||||||
|
#endif
|
||||||
|
|
||||||
if (auto prevNarHash = getNarHash()) {
|
if (auto prevNarHash = getNarHash()) {
|
||||||
if (narHash != *prevNarHash)
|
if (input.getNarHash() != prevNarHash)
|
||||||
throw Error((unsigned int) 102, "NAR hash mismatch in input '%s' (%s), expected '%s', got '%s'",
|
throw Error((unsigned int) 102, "NAR hash mismatch in input '%s', expected '%s'",
|
||||||
to_string(), store.printStorePath(storePath), prevNarHash->to_string(SRI, true), narHash.to_string(SRI, true));
|
to_string(), prevNarHash->to_string(SRI, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (auto prevLastModified = getLastModified()) {
|
if (auto prevLastModified = getLastModified()) {
|
||||||
|
@ -155,9 +163,12 @@ void Input::checkLocked(Store & store, const StorePath & storePath, Input & inpu
|
||||||
input.to_string(), *prevRevCount);
|
input.to_string(), *prevRevCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME
|
||||||
|
#if 0
|
||||||
input.locked = true;
|
input.locked = true;
|
||||||
|
|
||||||
assert(input.hasAllInfo());
|
assert(input.hasAllInfo());
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<ref<InputAccessor>, Input> Input::getAccessor(ref<Store> store) const
|
std::pair<ref<InputAccessor>, Input> Input::getAccessor(ref<Store> store) const
|
||||||
|
@ -166,7 +177,9 @@ std::pair<ref<InputAccessor>, Input> Input::getAccessor(ref<Store> store) const
|
||||||
throw Error("cannot fetch unsupported input '%s'", attrsToJSON(toAttrs()));
|
throw Error("cannot fetch unsupported input '%s'", attrsToJSON(toAttrs()));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return scheme->getAccessor(store, *this);
|
auto [accessor, final] = scheme->getAccessor(store, *this);
|
||||||
|
checkLocks(final);
|
||||||
|
return {accessor, std::move(final)};
|
||||||
} catch (Error & e) {
|
} catch (Error & e) {
|
||||||
e.addTrace({}, "while fetching the input '%s'", to_string());
|
e.addTrace({}, "while fetching the input '%s'", to_string());
|
||||||
throw;
|
throw;
|
||||||
|
@ -262,7 +275,7 @@ std::optional<std::string> Input::getFingerprint(ref<Store> store) const
|
||||||
return scheme->getFingerprint(store, *this);
|
return scheme->getFingerprint(store, *this);
|
||||||
}
|
}
|
||||||
|
|
||||||
ParsedURL InputScheme::toURL(const Input & input)
|
ParsedURL InputScheme::toURL(const Input & input) const
|
||||||
{
|
{
|
||||||
throw Error("don't know how to convert input '%s' to a URL", attrsToJSON(input.attrs));
|
throw Error("don't know how to convert input '%s' to a URL", attrsToJSON(input.attrs));
|
||||||
}
|
}
|
||||||
|
@ -270,7 +283,7 @@ ParsedURL InputScheme::toURL(const Input & input)
|
||||||
Input InputScheme::applyOverrides(
|
Input InputScheme::applyOverrides(
|
||||||
const Input & input,
|
const Input & input,
|
||||||
std::optional<std::string> ref,
|
std::optional<std::string> ref,
|
||||||
std::optional<Hash> rev)
|
std::optional<Hash> rev) const
|
||||||
{
|
{
|
||||||
if (ref)
|
if (ref)
|
||||||
throw Error("don't know how to set branch/tag name of input '%s' to '%s'", input.to_string(), *ref);
|
throw Error("don't know how to set branch/tag name of input '%s' to '%s'", input.to_string(), *ref);
|
||||||
|
@ -288,31 +301,9 @@ void InputScheme::putFile(
|
||||||
throw Error("input '%s' does not support modifying file '%s'", input.to_string(), path);
|
throw Error("input '%s' does not support modifying file '%s'", input.to_string(), path);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InputScheme::clone(const Input & input, const Path & destDir)
|
void InputScheme::clone(const Input & input, const Path & destDir) const
|
||||||
{
|
{
|
||||||
throw Error("do not know how to clone input '%s'", input.to_string());
|
throw Error("do not know how to clone input '%s'", input.to_string());
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<StorePath, Input> InputScheme::fetchToStore(ref<Store> store, const Input & input)
|
|
||||||
{
|
|
||||||
auto [accessor, input2] = getAccessor(store, input);
|
|
||||||
|
|
||||||
auto source = sinkToSource([&, accessor{accessor}](Sink & sink) {
|
|
||||||
accessor->dumpPath(CanonPath::root, sink);
|
|
||||||
});
|
|
||||||
|
|
||||||
auto storePath = store->addToStoreFromDump(*source, "source");
|
|
||||||
|
|
||||||
return {storePath, input2};
|
|
||||||
}
|
|
||||||
|
|
||||||
std::pair<ref<InputAccessor>, Input> InputScheme::getAccessor(ref<Store> store, const Input & input)
|
|
||||||
{
|
|
||||||
auto [storePath, input2] = fetchToStore(store, input);
|
|
||||||
|
|
||||||
input.checkLocked(*store, storePath, input2);
|
|
||||||
|
|
||||||
return {makeFSInputAccessor(CanonPath(store->toRealPath(storePath))), input2};
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -100,7 +100,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void checkLocked(Store & store, const StorePath & storePath, Input & input) const;
|
void checkLocks(Input & input) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* The InputScheme represents a type of fetcher. Each fetcher
|
/* The InputScheme represents a type of fetcher. Each fetcher
|
||||||
|
@ -116,20 +116,20 @@ struct InputScheme
|
||||||
virtual ~InputScheme()
|
virtual ~InputScheme()
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
virtual std::optional<Input> inputFromURL(const ParsedURL & url) = 0;
|
virtual std::optional<Input> inputFromURL(const ParsedURL & url) const = 0;
|
||||||
|
|
||||||
virtual std::optional<Input> inputFromAttrs(const Attrs & attrs) = 0;
|
virtual std::optional<Input> inputFromAttrs(const Attrs & attrs) const = 0;
|
||||||
|
|
||||||
virtual ParsedURL toURL(const Input & input);
|
virtual ParsedURL toURL(const Input & input) const;
|
||||||
|
|
||||||
virtual bool hasAllInfo(const Input & input) = 0;
|
virtual bool hasAllInfo(const Input & input) const = 0;
|
||||||
|
|
||||||
virtual Input applyOverrides(
|
virtual Input applyOverrides(
|
||||||
const Input & input,
|
const Input & input,
|
||||||
std::optional<std::string> ref,
|
std::optional<std::string> ref,
|
||||||
std::optional<Hash> rev);
|
std::optional<Hash> rev) const;
|
||||||
|
|
||||||
virtual void clone(const Input & input, const Path & destDir);
|
virtual void clone(const Input & input, const Path & destDir) const;
|
||||||
|
|
||||||
virtual void putFile(
|
virtual void putFile(
|
||||||
const Input & input,
|
const Input & input,
|
||||||
|
@ -137,13 +137,7 @@ struct InputScheme
|
||||||
std::string_view contents,
|
std::string_view contents,
|
||||||
std::optional<std::string> commitMsg) const;
|
std::optional<std::string> commitMsg) const;
|
||||||
|
|
||||||
/* Note: the default implementations of fetchToStore() and
|
virtual std::pair<ref<InputAccessor>, Input> getAccessor(ref<Store> store, const Input & input) const = 0;
|
||||||
getAccessor() are defined using the other, so implementations
|
|
||||||
have to override at least one. */
|
|
||||||
|
|
||||||
virtual std::pair<StorePath, Input> fetchToStore(ref<Store> store, const Input & input);
|
|
||||||
|
|
||||||
virtual std::pair<ref<InputAccessor>, Input> getAccessor(ref<Store> store, const Input & input);
|
|
||||||
|
|
||||||
virtual std::optional<CanonPath> isRelative(const Input & input) const
|
virtual std::optional<CanonPath> isRelative(const Input & input) const
|
||||||
{ return std::nullopt; }
|
{ return std::nullopt; }
|
||||||
|
|
|
@ -140,7 +140,7 @@ bool isNotDotGitDirectory(const Path & path)
|
||||||
|
|
||||||
struct GitInputScheme : InputScheme
|
struct GitInputScheme : InputScheme
|
||||||
{
|
{
|
||||||
std::optional<Input> inputFromURL(const ParsedURL & url) override
|
std::optional<Input> inputFromURL(const ParsedURL & url) const override
|
||||||
{
|
{
|
||||||
if (url.scheme != "git" &&
|
if (url.scheme != "git" &&
|
||||||
url.scheme != "git+http" &&
|
url.scheme != "git+http" &&
|
||||||
|
@ -169,7 +169,7 @@ struct GitInputScheme : InputScheme
|
||||||
return inputFromAttrs(attrs);
|
return inputFromAttrs(attrs);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<Input> inputFromAttrs(const Attrs & attrs) override
|
std::optional<Input> inputFromAttrs(const Attrs & attrs) const override
|
||||||
{
|
{
|
||||||
if (maybeGetStrAttr(attrs, "type") != "git") return {};
|
if (maybeGetStrAttr(attrs, "type") != "git") return {};
|
||||||
|
|
||||||
|
@ -192,7 +192,7 @@ struct GitInputScheme : InputScheme
|
||||||
return input;
|
return input;
|
||||||
}
|
}
|
||||||
|
|
||||||
ParsedURL toURL(const Input & input) override
|
ParsedURL toURL(const Input & input) const override
|
||||||
{
|
{
|
||||||
auto url = parseURL(getStrAttr(input.attrs, "url"));
|
auto url = parseURL(getStrAttr(input.attrs, "url"));
|
||||||
if (url.scheme != "git") url.scheme = "git+" + url.scheme;
|
if (url.scheme != "git") url.scheme = "git+" + url.scheme;
|
||||||
|
@ -203,7 +203,7 @@ struct GitInputScheme : InputScheme
|
||||||
return url;
|
return url;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hasAllInfo(const Input & input) override
|
bool hasAllInfo(const Input & input) const override
|
||||||
{
|
{
|
||||||
bool maybeDirty = !input.getRef();
|
bool maybeDirty = !input.getRef();
|
||||||
bool shallow = maybeGetBoolAttr(input.attrs, "shallow").value_or(false);
|
bool shallow = maybeGetBoolAttr(input.attrs, "shallow").value_or(false);
|
||||||
|
@ -215,7 +215,7 @@ struct GitInputScheme : InputScheme
|
||||||
Input applyOverrides(
|
Input applyOverrides(
|
||||||
const Input & input,
|
const Input & input,
|
||||||
std::optional<std::string> ref,
|
std::optional<std::string> ref,
|
||||||
std::optional<Hash> rev) override
|
std::optional<Hash> rev) const override
|
||||||
{
|
{
|
||||||
auto res(input);
|
auto res(input);
|
||||||
if (rev) res.attrs.insert_or_assign("rev", rev->gitRev());
|
if (rev) res.attrs.insert_or_assign("rev", rev->gitRev());
|
||||||
|
@ -225,7 +225,7 @@ struct GitInputScheme : InputScheme
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
void clone(const Input & input, const Path & destDir) override
|
void clone(const Input & input, const Path & destDir) const override
|
||||||
{
|
{
|
||||||
auto repoInfo = getRepoInfo(input);
|
auto repoInfo = getRepoInfo(input);
|
||||||
|
|
||||||
|
@ -394,7 +394,7 @@ struct GitInputScheme : InputScheme
|
||||||
return repoInfo;
|
return repoInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::set<CanonPath> listFiles(const RepoInfo & repoInfo)
|
std::set<CanonPath> listFiles(const RepoInfo & repoInfo) const
|
||||||
{
|
{
|
||||||
auto gitOpts = Strings({ "-C", repoInfo.url, "--git-dir", repoInfo.gitDir, "ls-files", "-z" });
|
auto gitOpts = Strings({ "-C", repoInfo.url, "--git-dir", repoInfo.gitDir, "ls-files", "-z" });
|
||||||
if (repoInfo.submodules)
|
if (repoInfo.submodules)
|
||||||
|
@ -409,14 +409,14 @@ struct GitInputScheme : InputScheme
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateRev(Input & input, const RepoInfo & repoInfo, const std::string & ref)
|
void updateRev(Input & input, const RepoInfo & repoInfo, const std::string & ref) const
|
||||||
{
|
{
|
||||||
if (!input.getRev())
|
if (!input.getRev())
|
||||||
input.attrs.insert_or_assign("rev",
|
input.attrs.insert_or_assign("rev",
|
||||||
Hash::parseAny(chomp(runProgram("git", true, { "-C", repoInfo.url, "--git-dir", repoInfo.gitDir, "rev-parse", ref })), htSHA1).gitRev());
|
Hash::parseAny(chomp(runProgram("git", true, { "-C", repoInfo.url, "--git-dir", repoInfo.gitDir, "rev-parse", ref })), htSHA1).gitRev());
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t getLastModified(const RepoInfo & repoInfo, const std::string & repoDir, const std::string & ref)
|
uint64_t getLastModified(const RepoInfo & repoInfo, const std::string & repoDir, const std::string & ref) const
|
||||||
{
|
{
|
||||||
return
|
return
|
||||||
repoInfo.hasHead
|
repoInfo.hasHead
|
||||||
|
@ -426,7 +426,7 @@ struct GitInputScheme : InputScheme
|
||||||
: 0;
|
: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t getRevCount(const RepoInfo & repoInfo, const std::string & repoDir, const Hash & rev)
|
uint64_t getRevCount(const RepoInfo & repoInfo, const std::string & repoDir, const Hash & rev) const
|
||||||
{
|
{
|
||||||
// FIXME: cache this.
|
// FIXME: cache this.
|
||||||
return
|
return
|
||||||
|
@ -437,7 +437,7 @@ struct GitInputScheme : InputScheme
|
||||||
: 0;
|
: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string getDefaultRef(const RepoInfo & repoInfo)
|
std::string getDefaultRef(const RepoInfo & repoInfo) const
|
||||||
{
|
{
|
||||||
auto head = repoInfo.isLocal
|
auto head = repoInfo.isLocal
|
||||||
? readHead(repoInfo.url)
|
? readHead(repoInfo.url)
|
||||||
|
@ -449,11 +449,14 @@ struct GitInputScheme : InputScheme
|
||||||
return *head;
|
return *head;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<StorePath, Input> fetchToStore(ref<Store> store, const Input & _input) override
|
StorePath fetchToStore(
|
||||||
|
ref<Store> store,
|
||||||
|
RepoInfo & repoInfo,
|
||||||
|
Input & input) const
|
||||||
{
|
{
|
||||||
Input input(_input);
|
assert(!repoInfo.isDirty);
|
||||||
|
|
||||||
auto repoInfo = getRepoInfo(input);
|
auto origRev = input.getRev();
|
||||||
|
|
||||||
std::string name = input.getName();
|
std::string name = input.getName();
|
||||||
|
|
||||||
|
@ -466,15 +469,21 @@ struct GitInputScheme : InputScheme
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
auto makeResult = [&](const Attrs & infoAttrs, StorePath && storePath)
|
auto makeResult = [&](const Attrs & infoAttrs, const StorePath & storePath) -> StorePath
|
||||||
-> std::pair<StorePath, Input>
|
|
||||||
{
|
{
|
||||||
assert(input.getRev());
|
assert(input.getRev());
|
||||||
assert(!_input.getRev() || _input.getRev() == input.getRev());
|
assert(!origRev || origRev == input.getRev());
|
||||||
if (!repoInfo.shallow)
|
if (!repoInfo.shallow)
|
||||||
input.attrs.insert_or_assign("revCount", getIntAttr(infoAttrs, "revCount"));
|
input.attrs.insert_or_assign("revCount", getIntAttr(infoAttrs, "revCount"));
|
||||||
input.attrs.insert_or_assign("lastModified", getIntAttr(infoAttrs, "lastModified"));
|
input.attrs.insert_or_assign("lastModified", getIntAttr(infoAttrs, "lastModified"));
|
||||||
return {std::move(storePath), input};
|
|
||||||
|
// FIXME: remove?
|
||||||
|
//input.attrs.erase("narHash");
|
||||||
|
auto narHash = store->queryPathInfo(storePath)->narHash;
|
||||||
|
input.attrs.insert_or_assign("narHash", narHash.to_string(SRI, true));
|
||||||
|
input.locked = true;
|
||||||
|
|
||||||
|
return storePath;
|
||||||
};
|
};
|
||||||
|
|
||||||
if (input.getRev()) {
|
if (input.getRev()) {
|
||||||
|
@ -482,9 +491,6 @@ struct GitInputScheme : InputScheme
|
||||||
return makeResult(res->first, std::move(res->second));
|
return makeResult(res->first, std::move(res->second));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (repoInfo.isDirty)
|
|
||||||
return fetchFromWorkdir(store, repoInfo, std::move(input));
|
|
||||||
|
|
||||||
auto originalRef = input.getRef();
|
auto originalRef = input.getRef();
|
||||||
auto ref = originalRef ? *originalRef : getDefaultRef(repoInfo);
|
auto ref = originalRef ? *originalRef : getDefaultRef(repoInfo);
|
||||||
input.attrs.insert_or_assign("ref", ref);
|
input.attrs.insert_or_assign("ref", ref);
|
||||||
|
@ -674,7 +680,7 @@ struct GitInputScheme : InputScheme
|
||||||
infoAttrs.insert_or_assign("revCount",
|
infoAttrs.insert_or_assign("revCount",
|
||||||
getRevCount(repoInfo, repoDir, rev));
|
getRevCount(repoInfo, repoDir, rev));
|
||||||
|
|
||||||
if (!_input.getRev())
|
if (!origRev)
|
||||||
getCache()->add(
|
getCache()->add(
|
||||||
store,
|
store,
|
||||||
unlockedAttrs,
|
unlockedAttrs,
|
||||||
|
@ -692,45 +698,27 @@ struct GitInputScheme : InputScheme
|
||||||
return makeResult(infoAttrs, std::move(storePath));
|
return makeResult(infoAttrs, std::move(storePath));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<StorePath, Input> fetchFromWorkdir(
|
std::pair<ref<InputAccessor>, Input> getAccessor(ref<Store> store, const Input & _input) const override
|
||||||
ref<Store> store,
|
|
||||||
const RepoInfo & repoInfo,
|
|
||||||
Input input)
|
|
||||||
{
|
|
||||||
/* This is an unclean working tree. So copy all tracked
|
|
||||||
files. */
|
|
||||||
repoInfo.checkDirty();
|
|
||||||
|
|
||||||
auto files = listFiles(repoInfo);
|
|
||||||
|
|
||||||
CanonPath repoDir(repoInfo.url);
|
|
||||||
|
|
||||||
PathFilter filter = [&](const Path & p) -> bool {
|
|
||||||
return CanonPath(p).removePrefix(repoDir).isAllowed(files);
|
|
||||||
};
|
|
||||||
|
|
||||||
auto storePath = store->addToStore(input.getName(), repoInfo.url, FileIngestionMethod::Recursive, htSHA256, filter);
|
|
||||||
|
|
||||||
// FIXME: maybe we should use the timestamp of the last
|
|
||||||
// modified dirty file?
|
|
||||||
input.attrs.insert_or_assign(
|
|
||||||
"lastModified",
|
|
||||||
getLastModified(repoInfo, repoInfo.url, "HEAD"));
|
|
||||||
|
|
||||||
return {std::move(storePath), input};
|
|
||||||
}
|
|
||||||
|
|
||||||
std::pair<ref<InputAccessor>, Input> getAccessor(ref<Store> store, const Input & _input) override
|
|
||||||
{
|
{
|
||||||
Input input(_input);
|
Input input(_input);
|
||||||
|
|
||||||
auto repoInfo = getRepoInfo(input);
|
auto repoInfo = getRepoInfo(input);
|
||||||
|
|
||||||
|
auto makeNotAllowedError = [url{repoInfo.url}](const CanonPath & path) -> RestrictedPathError
|
||||||
|
{
|
||||||
|
if (nix::pathExists(path.abs()))
|
||||||
|
return RestrictedPathError("access to path '%s' is forbidden because it is not under Git control; maybe you should 'git add' it to the repository '%s'?", path, url);
|
||||||
|
else
|
||||||
|
return RestrictedPathError("path '%s' does not exist in Git repository '%s'", path, url);
|
||||||
|
};
|
||||||
|
|
||||||
/* Unless we're using the working tree, copy the tree into the
|
/* Unless we're using the working tree, copy the tree into the
|
||||||
Nix store. TODO: We could have an accessor for fetching
|
Nix store. TODO: We could have an accessor for fetching
|
||||||
files from the Git repository directly. */
|
files from the Git repository directly. */
|
||||||
if (input.getRef() || input.getRev() || !repoInfo.isLocal)
|
if (input.getRef() || input.getRev() || !repoInfo.isLocal) {
|
||||||
return InputScheme::getAccessor(store, input);
|
auto storePath = fetchToStore(store, repoInfo, input);
|
||||||
|
return {makeStorePathAccessor(store, storePath, std::move(makeNotAllowedError)), input};
|
||||||
|
}
|
||||||
|
|
||||||
repoInfo.checkDirty();
|
repoInfo.checkDirty();
|
||||||
|
|
||||||
|
@ -753,14 +741,6 @@ struct GitInputScheme : InputScheme
|
||||||
"lastModified",
|
"lastModified",
|
||||||
getLastModified(repoInfo, repoInfo.url, ref));
|
getLastModified(repoInfo, repoInfo.url, ref));
|
||||||
|
|
||||||
auto makeNotAllowedError = [url{repoInfo.url}](const CanonPath & path) -> RestrictedPathError
|
|
||||||
{
|
|
||||||
if (nix::pathExists(path.abs()))
|
|
||||||
return RestrictedPathError("access to path '%s' is forbidden because it is not under Git control; maybe you should 'git add' it to the repository '%s'?", path, url);
|
|
||||||
else
|
|
||||||
return RestrictedPathError("path '%s' does not exist in Git repository '%s'", path, url);
|
|
||||||
};
|
|
||||||
|
|
||||||
return {makeFSInputAccessor(CanonPath(repoInfo.url), listFiles(repoInfo), std::move(makeNotAllowedError)), input};
|
return {makeFSInputAccessor(CanonPath(repoInfo.url), listFiles(repoInfo), std::move(makeNotAllowedError)), input};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -26,11 +26,11 @@ std::regex hostRegex(hostRegexS, std::regex::ECMAScript);
|
||||||
|
|
||||||
struct GitArchiveInputScheme : InputScheme
|
struct GitArchiveInputScheme : InputScheme
|
||||||
{
|
{
|
||||||
virtual std::string type() = 0;
|
virtual std::string type() const = 0;
|
||||||
|
|
||||||
virtual std::optional<std::pair<std::string, std::string>> accessHeaderFromToken(const std::string & token) const = 0;
|
virtual std::optional<std::pair<std::string, std::string>> accessHeaderFromToken(const std::string & token) const = 0;
|
||||||
|
|
||||||
std::optional<Input> inputFromURL(const ParsedURL & url) override
|
std::optional<Input> inputFromURL(const ParsedURL & url) const override
|
||||||
{
|
{
|
||||||
if (url.scheme != type()) return {};
|
if (url.scheme != type()) return {};
|
||||||
|
|
||||||
|
@ -100,7 +100,7 @@ struct GitArchiveInputScheme : InputScheme
|
||||||
return input;
|
return input;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<Input> inputFromAttrs(const Attrs & attrs) override
|
std::optional<Input> inputFromAttrs(const Attrs & attrs) const override
|
||||||
{
|
{
|
||||||
if (maybeGetStrAttr(attrs, "type") != type()) return {};
|
if (maybeGetStrAttr(attrs, "type") != type()) return {};
|
||||||
|
|
||||||
|
@ -116,7 +116,7 @@ struct GitArchiveInputScheme : InputScheme
|
||||||
return input;
|
return input;
|
||||||
}
|
}
|
||||||
|
|
||||||
ParsedURL toURL(const Input & input) override
|
ParsedURL toURL(const Input & input) const override
|
||||||
{
|
{
|
||||||
auto owner = getStrAttr(input.attrs, "owner");
|
auto owner = getStrAttr(input.attrs, "owner");
|
||||||
auto repo = getStrAttr(input.attrs, "repo");
|
auto repo = getStrAttr(input.attrs, "repo");
|
||||||
|
@ -132,7 +132,7 @@ struct GitArchiveInputScheme : InputScheme
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hasAllInfo(const Input & input) override
|
bool hasAllInfo(const Input & input) const override
|
||||||
{
|
{
|
||||||
return input.getRev() &&
|
return input.getRev() &&
|
||||||
true; // FIXME
|
true; // FIXME
|
||||||
|
@ -142,7 +142,7 @@ struct GitArchiveInputScheme : InputScheme
|
||||||
Input applyOverrides(
|
Input applyOverrides(
|
||||||
const Input & _input,
|
const Input & _input,
|
||||||
std::optional<std::string> ref,
|
std::optional<std::string> ref,
|
||||||
std::optional<Hash> rev) override
|
std::optional<Hash> rev) const override
|
||||||
{
|
{
|
||||||
auto input(_input);
|
auto input(_input);
|
||||||
if (rev && ref)
|
if (rev && ref)
|
||||||
|
@ -185,7 +185,7 @@ struct GitArchiveInputScheme : InputScheme
|
||||||
|
|
||||||
virtual DownloadUrl getDownloadUrl(const Input & input) const = 0;
|
virtual DownloadUrl getDownloadUrl(const Input & input) const = 0;
|
||||||
|
|
||||||
std::pair<StorePath, Input> downloadArchive(ref<Store> store, Input input)
|
std::pair<StorePath, Input> downloadArchive(ref<Store> store, Input input) const
|
||||||
{
|
{
|
||||||
if (!maybeGetStrAttr(input.attrs, "ref")) input.attrs.insert_or_assign("ref", "HEAD");
|
if (!maybeGetStrAttr(input.attrs, "ref")) input.attrs.insert_or_assign("ref", "HEAD");
|
||||||
|
|
||||||
|
@ -228,7 +228,7 @@ struct GitArchiveInputScheme : InputScheme
|
||||||
return {res.storePath, input};
|
return {res.storePath, input};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<ref<InputAccessor>, Input> getAccessor(ref<Store> store, const Input & input) override
|
std::pair<ref<InputAccessor>, Input> getAccessor(ref<Store> store, const Input & input) const override
|
||||||
{
|
{
|
||||||
auto [storePath, input2] = downloadArchive(store, input);
|
auto [storePath, input2] = downloadArchive(store, input);
|
||||||
|
|
||||||
|
@ -242,7 +242,7 @@ struct GitArchiveInputScheme : InputScheme
|
||||||
|
|
||||||
struct GitHubInputScheme : GitArchiveInputScheme
|
struct GitHubInputScheme : GitArchiveInputScheme
|
||||||
{
|
{
|
||||||
std::string type() override { return "github"; }
|
std::string type() const override { return "github"; }
|
||||||
|
|
||||||
std::optional<std::pair<std::string, std::string>> accessHeaderFromToken(const std::string & token) const override
|
std::optional<std::pair<std::string, std::string>> accessHeaderFromToken(const std::string & token) const override
|
||||||
{
|
{
|
||||||
|
@ -291,7 +291,7 @@ struct GitHubInputScheme : GitArchiveInputScheme
|
||||||
return DownloadUrl { url, headers };
|
return DownloadUrl { url, headers };
|
||||||
}
|
}
|
||||||
|
|
||||||
void clone(const Input & input, const Path & destDir) override
|
void clone(const Input & input, const Path & destDir) const override
|
||||||
{
|
{
|
||||||
auto host = maybeGetStrAttr(input.attrs, "host").value_or("github.com");
|
auto host = maybeGetStrAttr(input.attrs, "host").value_or("github.com");
|
||||||
Input::fromURL(fmt("git+https://%s/%s/%s.git",
|
Input::fromURL(fmt("git+https://%s/%s/%s.git",
|
||||||
|
@ -303,7 +303,7 @@ struct GitHubInputScheme : GitArchiveInputScheme
|
||||||
|
|
||||||
struct GitLabInputScheme : GitArchiveInputScheme
|
struct GitLabInputScheme : GitArchiveInputScheme
|
||||||
{
|
{
|
||||||
std::string type() override { return "gitlab"; }
|
std::string type() const override { return "gitlab"; }
|
||||||
|
|
||||||
std::optional<std::pair<std::string, std::string>> accessHeaderFromToken(const std::string & token) const override
|
std::optional<std::pair<std::string, std::string>> accessHeaderFromToken(const std::string & token) const override
|
||||||
{
|
{
|
||||||
|
@ -358,7 +358,7 @@ struct GitLabInputScheme : GitArchiveInputScheme
|
||||||
return DownloadUrl { url, headers };
|
return DownloadUrl { url, headers };
|
||||||
}
|
}
|
||||||
|
|
||||||
void clone(const Input & input, const Path & destDir) override
|
void clone(const Input & input, const Path & destDir) const override
|
||||||
{
|
{
|
||||||
auto host = maybeGetStrAttr(input.attrs, "host").value_or("gitlab.com");
|
auto host = maybeGetStrAttr(input.attrs, "host").value_or("gitlab.com");
|
||||||
// FIXME: get username somewhere
|
// FIXME: get username somewhere
|
||||||
|
@ -371,7 +371,7 @@ struct GitLabInputScheme : GitArchiveInputScheme
|
||||||
|
|
||||||
struct SourceHutInputScheme : GitArchiveInputScheme
|
struct SourceHutInputScheme : GitArchiveInputScheme
|
||||||
{
|
{
|
||||||
std::string type() override { return "sourcehut"; }
|
std::string type() const override { return "sourcehut"; }
|
||||||
|
|
||||||
std::optional<std::pair<std::string, std::string>> accessHeaderFromToken(const std::string & token) const override
|
std::optional<std::pair<std::string, std::string>> accessHeaderFromToken(const std::string & token) const override
|
||||||
{
|
{
|
||||||
|
@ -445,7 +445,7 @@ struct SourceHutInputScheme : GitArchiveInputScheme
|
||||||
return DownloadUrl { url, headers };
|
return DownloadUrl { url, headers };
|
||||||
}
|
}
|
||||||
|
|
||||||
void clone(const Input & input, const Path & destDir) override
|
void clone(const Input & input, const Path & destDir) const override
|
||||||
{
|
{
|
||||||
auto host = maybeGetStrAttr(input.attrs, "host").value_or("git.sr.ht");
|
auto host = maybeGetStrAttr(input.attrs, "host").value_or("git.sr.ht");
|
||||||
Input::fromURL(fmt("git+https://%s/%s/%s",
|
Input::fromURL(fmt("git+https://%s/%s/%s",
|
||||||
|
|
|
@ -7,7 +7,7 @@ std::regex flakeRegex("[a-zA-Z][a-zA-Z0-9_-]*", std::regex::ECMAScript);
|
||||||
|
|
||||||
struct IndirectInputScheme : InputScheme
|
struct IndirectInputScheme : InputScheme
|
||||||
{
|
{
|
||||||
std::optional<Input> inputFromURL(const ParsedURL & url) override
|
std::optional<Input> inputFromURL(const ParsedURL & url) const override
|
||||||
{
|
{
|
||||||
if (url.scheme != "flake") return {};
|
if (url.scheme != "flake") return {};
|
||||||
|
|
||||||
|
@ -50,7 +50,7 @@ struct IndirectInputScheme : InputScheme
|
||||||
return input;
|
return input;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<Input> inputFromAttrs(const Attrs & attrs) override
|
std::optional<Input> inputFromAttrs(const Attrs & attrs) const override
|
||||||
{
|
{
|
||||||
if (maybeGetStrAttr(attrs, "type") != "indirect") return {};
|
if (maybeGetStrAttr(attrs, "type") != "indirect") return {};
|
||||||
|
|
||||||
|
@ -68,7 +68,7 @@ struct IndirectInputScheme : InputScheme
|
||||||
return input;
|
return input;
|
||||||
}
|
}
|
||||||
|
|
||||||
ParsedURL toURL(const Input & input) override
|
ParsedURL toURL(const Input & input) const override
|
||||||
{
|
{
|
||||||
ParsedURL url;
|
ParsedURL url;
|
||||||
url.scheme = "flake";
|
url.scheme = "flake";
|
||||||
|
@ -78,7 +78,7 @@ struct IndirectInputScheme : InputScheme
|
||||||
return url;
|
return url;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hasAllInfo(const Input & input) override
|
bool hasAllInfo(const Input & input) const override
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -86,7 +86,7 @@ struct IndirectInputScheme : InputScheme
|
||||||
Input applyOverrides(
|
Input applyOverrides(
|
||||||
const Input & _input,
|
const Input & _input,
|
||||||
std::optional<std::string> ref,
|
std::optional<std::string> ref,
|
||||||
std::optional<Hash> rev) override
|
std::optional<Hash> rev) const override
|
||||||
{
|
{
|
||||||
auto input(_input);
|
auto input(_input);
|
||||||
if (rev) input.attrs.insert_or_assign("rev", rev->gitRev());
|
if (rev) input.attrs.insert_or_assign("rev", rev->gitRev());
|
||||||
|
@ -94,7 +94,7 @@ struct IndirectInputScheme : InputScheme
|
||||||
return input;
|
return input;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<StorePath, Input> fetchToStore(ref<Store> store, const Input & input) override
|
std::pair<ref<InputAccessor>, Input> getAccessor(ref<Store> store, const Input & input) const override
|
||||||
{
|
{
|
||||||
throw Error("indirect input '%s' cannot be fetched directly", input.to_string());
|
throw Error("indirect input '%s' cannot be fetched directly", input.to_string());
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include "input-accessor.hh"
|
#include "input-accessor.hh"
|
||||||
#include "util.hh"
|
#include "util.hh"
|
||||||
|
#include "store-api.hh"
|
||||||
|
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
|
|
||||||
|
@ -235,6 +236,14 @@ ref<FSInputAccessor> makeFSInputAccessor(
|
||||||
return make_ref<FSInputAccessorImpl>(root, std::move(allowedPaths), std::move(makeNotAllowedError));
|
return make_ref<FSInputAccessorImpl>(root, std::move(allowedPaths), std::move(makeNotAllowedError));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ref<FSInputAccessor> makeStorePathAccessor(
|
||||||
|
ref<Store> store,
|
||||||
|
const StorePath & storePath,
|
||||||
|
MakeNotAllowedError && makeNotAllowedError)
|
||||||
|
{
|
||||||
|
return makeFSInputAccessor(CanonPath(store->toRealPath(storePath)), {}, std::move(makeNotAllowedError));
|
||||||
|
}
|
||||||
|
|
||||||
std::ostream & operator << (std::ostream & str, const SourcePath & path)
|
std::ostream & operator << (std::ostream & str, const SourcePath & path)
|
||||||
{
|
{
|
||||||
str << path.to_string();
|
str << path.to_string();
|
||||||
|
|
|
@ -10,6 +10,8 @@ namespace nix {
|
||||||
MakeError(RestrictedPathError, Error);
|
MakeError(RestrictedPathError, Error);
|
||||||
|
|
||||||
struct SourcePath;
|
struct SourcePath;
|
||||||
|
class StorePath;
|
||||||
|
class Store;
|
||||||
|
|
||||||
struct InputAccessor : public std::enable_shared_from_this<InputAccessor>
|
struct InputAccessor : public std::enable_shared_from_this<InputAccessor>
|
||||||
{
|
{
|
||||||
|
@ -91,6 +93,11 @@ ref<FSInputAccessor> makeFSInputAccessor(
|
||||||
std::optional<std::set<CanonPath>> && allowedPaths = {},
|
std::optional<std::set<CanonPath>> && allowedPaths = {},
|
||||||
MakeNotAllowedError && makeNotAllowedError = {});
|
MakeNotAllowedError && makeNotAllowedError = {});
|
||||||
|
|
||||||
|
ref<FSInputAccessor> makeStorePathAccessor(
|
||||||
|
ref<Store> store,
|
||||||
|
const StorePath & storePath,
|
||||||
|
MakeNotAllowedError && makeNotAllowedError = {});
|
||||||
|
|
||||||
struct SourcePath;
|
struct SourcePath;
|
||||||
|
|
||||||
struct MemoryInputAccessor : InputAccessor
|
struct MemoryInputAccessor : InputAccessor
|
||||||
|
|
|
@ -43,7 +43,7 @@ static std::string runHg(const Strings & args, const std::optional<std::string>
|
||||||
|
|
||||||
struct MercurialInputScheme : InputScheme
|
struct MercurialInputScheme : InputScheme
|
||||||
{
|
{
|
||||||
std::optional<Input> inputFromURL(const ParsedURL & url) override
|
std::optional<Input> inputFromURL(const ParsedURL & url) const override
|
||||||
{
|
{
|
||||||
if (url.scheme != "hg+http" &&
|
if (url.scheme != "hg+http" &&
|
||||||
url.scheme != "hg+https" &&
|
url.scheme != "hg+https" &&
|
||||||
|
@ -69,7 +69,7 @@ struct MercurialInputScheme : InputScheme
|
||||||
return inputFromAttrs(attrs);
|
return inputFromAttrs(attrs);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<Input> inputFromAttrs(const Attrs & attrs) override
|
std::optional<Input> inputFromAttrs(const Attrs & attrs) const override
|
||||||
{
|
{
|
||||||
if (maybeGetStrAttr(attrs, "type") != "hg") return {};
|
if (maybeGetStrAttr(attrs, "type") != "hg") return {};
|
||||||
|
|
||||||
|
@ -89,7 +89,7 @@ struct MercurialInputScheme : InputScheme
|
||||||
return input;
|
return input;
|
||||||
}
|
}
|
||||||
|
|
||||||
ParsedURL toURL(const Input & input) override
|
ParsedURL toURL(const Input & input) const override
|
||||||
{
|
{
|
||||||
auto url = parseURL(getStrAttr(input.attrs, "url"));
|
auto url = parseURL(getStrAttr(input.attrs, "url"));
|
||||||
url.scheme = "hg+" + url.scheme;
|
url.scheme = "hg+" + url.scheme;
|
||||||
|
@ -98,7 +98,7 @@ struct MercurialInputScheme : InputScheme
|
||||||
return url;
|
return url;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hasAllInfo(const Input & input) override
|
bool hasAllInfo(const Input & input) const override
|
||||||
{
|
{
|
||||||
// FIXME: ugly, need to distinguish between dirty and clean
|
// FIXME: ugly, need to distinguish between dirty and clean
|
||||||
// default trees.
|
// default trees.
|
||||||
|
@ -108,7 +108,7 @@ struct MercurialInputScheme : InputScheme
|
||||||
Input applyOverrides(
|
Input applyOverrides(
|
||||||
const Input & input,
|
const Input & input,
|
||||||
std::optional<std::string> ref,
|
std::optional<std::string> ref,
|
||||||
std::optional<Hash> rev) override
|
std::optional<Hash> rev) const override
|
||||||
{
|
{
|
||||||
auto res(input);
|
auto res(input);
|
||||||
if (rev) res.attrs.insert_or_assign("rev", rev->gitRev());
|
if (rev) res.attrs.insert_or_assign("rev", rev->gitRev());
|
||||||
|
@ -148,9 +148,9 @@ struct MercurialInputScheme : InputScheme
|
||||||
return {isLocal, isLocal ? url.path : url.base};
|
return {isLocal, isLocal ? url.path : url.base};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<StorePath, Input> fetchToStore(ref<Store> store, const Input & _input) override
|
StorePath fetchToStore(ref<Store> store, Input & input) const
|
||||||
{
|
{
|
||||||
Input input(_input);
|
auto origRev = input.getRev();
|
||||||
|
|
||||||
auto name = input.getName();
|
auto name = input.getName();
|
||||||
|
|
||||||
|
@ -200,7 +200,7 @@ struct MercurialInputScheme : InputScheme
|
||||||
|
|
||||||
auto storePath = store->addToStore(input.getName(), actualPath, FileIngestionMethod::Recursive, htSHA256, filter);
|
auto storePath = store->addToStore(input.getName(), actualPath, FileIngestionMethod::Recursive, htSHA256, filter);
|
||||||
|
|
||||||
return {std::move(storePath), input};
|
return storePath;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -224,13 +224,13 @@ struct MercurialInputScheme : InputScheme
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
auto makeResult = [&](const Attrs & infoAttrs, StorePath && storePath)
|
auto makeResult = [&](const Attrs & infoAttrs, const StorePath & storePath) -> StorePath
|
||||||
-> std::pair<StorePath, Input>
|
|
||||||
{
|
{
|
||||||
assert(input.getRev());
|
assert(input.getRev());
|
||||||
assert(!_input.getRev() || _input.getRev() == input.getRev());
|
assert(!origRev || origRev == input.getRev());
|
||||||
input.attrs.insert_or_assign("revCount", getIntAttr(infoAttrs, "revCount"));
|
input.attrs.insert_or_assign("revCount", getIntAttr(infoAttrs, "revCount"));
|
||||||
return {std::move(storePath), input};
|
input.locked = true;
|
||||||
|
return storePath;
|
||||||
};
|
};
|
||||||
|
|
||||||
if (input.getRev()) {
|
if (input.getRev()) {
|
||||||
|
@ -310,7 +310,7 @@ struct MercurialInputScheme : InputScheme
|
||||||
{"revCount", (uint64_t) revCount},
|
{"revCount", (uint64_t) revCount},
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!_input.getRev())
|
if (!origRev)
|
||||||
getCache()->add(
|
getCache()->add(
|
||||||
store,
|
store,
|
||||||
unlockedAttrs,
|
unlockedAttrs,
|
||||||
|
@ -327,6 +327,15 @@ struct MercurialInputScheme : InputScheme
|
||||||
|
|
||||||
return makeResult(infoAttrs, std::move(storePath));
|
return makeResult(infoAttrs, std::move(storePath));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::pair<ref<InputAccessor>, Input> getAccessor(ref<Store> store, const Input & _input) const override
|
||||||
|
{
|
||||||
|
Input input(_input);
|
||||||
|
|
||||||
|
auto storePath = fetchToStore(store, input);
|
||||||
|
|
||||||
|
return {makeStorePathAccessor(store, storePath), input};
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static auto rMercurialInputScheme = OnStartup([] { registerInputScheme(std::make_unique<MercurialInputScheme>()); });
|
static auto rMercurialInputScheme = OnStartup([] { registerInputScheme(std::make_unique<MercurialInputScheme>()); });
|
||||||
|
|
|
@ -6,7 +6,7 @@ namespace nix::fetchers {
|
||||||
|
|
||||||
struct PathInputScheme : InputScheme
|
struct PathInputScheme : InputScheme
|
||||||
{
|
{
|
||||||
std::optional<Input> inputFromURL(const ParsedURL & url) override
|
std::optional<Input> inputFromURL(const ParsedURL & url) const override
|
||||||
{
|
{
|
||||||
if (url.scheme != "path") return {};
|
if (url.scheme != "path") return {};
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ struct PathInputScheme : InputScheme
|
||||||
return input;
|
return input;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<Input> inputFromAttrs(const Attrs & attrs) override
|
std::optional<Input> inputFromAttrs(const Attrs & attrs) const override
|
||||||
{
|
{
|
||||||
if (maybeGetStrAttr(attrs, "type") != "path") return {};
|
if (maybeGetStrAttr(attrs, "type") != "path") return {};
|
||||||
|
|
||||||
|
@ -54,7 +54,7 @@ struct PathInputScheme : InputScheme
|
||||||
return input;
|
return input;
|
||||||
}
|
}
|
||||||
|
|
||||||
ParsedURL toURL(const Input & input) override
|
ParsedURL toURL(const Input & input) const override
|
||||||
{
|
{
|
||||||
auto query = attrsToQuery(input.attrs);
|
auto query = attrsToQuery(input.attrs);
|
||||||
query.erase("path");
|
query.erase("path");
|
||||||
|
@ -75,7 +75,7 @@ struct PathInputScheme : InputScheme
|
||||||
return CanonPath(path);
|
return CanonPath(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hasAllInfo(const Input & input) override
|
bool hasAllInfo(const Input & input) const override
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -103,7 +103,7 @@ struct PathInputScheme : InputScheme
|
||||||
throw Error("cannot fetch input '%s' because it uses a relative path", input.to_string());
|
throw Error("cannot fetch input '%s' because it uses a relative path", input.to_string());
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<ref<InputAccessor>, Input> getAccessor(ref<Store> store, const Input & input) override
|
std::pair<ref<InputAccessor>, Input> getAccessor(ref<Store> store, const Input & input) const override
|
||||||
{
|
{
|
||||||
auto absPath = getAbsPath(input);
|
auto absPath = getAbsPath(input);
|
||||||
auto input2(input);
|
auto input2(input);
|
||||||
|
|
|
@ -185,7 +185,7 @@ struct CurlInputScheme : InputScheme
|
||||||
|
|
||||||
virtual bool isValidURL(const ParsedURL & url) const = 0;
|
virtual bool isValidURL(const ParsedURL & url) const = 0;
|
||||||
|
|
||||||
std::optional<Input> inputFromURL(const ParsedURL & url) override
|
std::optional<Input> inputFromURL(const ParsedURL & url) const override
|
||||||
{
|
{
|
||||||
if (!isValidURL(url))
|
if (!isValidURL(url))
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
|
@ -203,7 +203,7 @@ struct CurlInputScheme : InputScheme
|
||||||
return input;
|
return input;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<Input> inputFromAttrs(const Attrs & attrs) override
|
std::optional<Input> inputFromAttrs(const Attrs & attrs) const override
|
||||||
{
|
{
|
||||||
auto type = maybeGetStrAttr(attrs, "type");
|
auto type = maybeGetStrAttr(attrs, "type");
|
||||||
if (type != inputType()) return {};
|
if (type != inputType()) return {};
|
||||||
|
@ -220,7 +220,7 @@ struct CurlInputScheme : InputScheme
|
||||||
return input;
|
return input;
|
||||||
}
|
}
|
||||||
|
|
||||||
ParsedURL toURL(const Input & input) override
|
ParsedURL toURL(const Input & input) const override
|
||||||
{
|
{
|
||||||
auto url = parseURL(getStrAttr(input.attrs, "url"));
|
auto url = parseURL(getStrAttr(input.attrs, "url"));
|
||||||
// NAR hashes are preferred over file hashes since tar/zip
|
// NAR hashes are preferred over file hashes since tar/zip
|
||||||
|
@ -230,7 +230,7 @@ struct CurlInputScheme : InputScheme
|
||||||
return url;
|
return url;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hasAllInfo(const Input & input) override
|
bool hasAllInfo(const Input & input) const override
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -250,10 +250,18 @@ struct FileInputScheme : CurlInputScheme
|
||||||
: !hasTarballExtension(url.path));
|
: !hasTarballExtension(url.path));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<StorePath, Input> fetchToStore(ref<Store> store, const Input & input) override
|
std::pair<ref<InputAccessor>, Input> getAccessor(ref<Store> store, const Input & _input) const override
|
||||||
{
|
{
|
||||||
|
auto input(_input);
|
||||||
|
|
||||||
auto file = downloadFile(store, getStrAttr(input.attrs, "url"), input.getName(), false);
|
auto file = downloadFile(store, getStrAttr(input.attrs, "url"), input.getName(), false);
|
||||||
return {std::move(file.storePath), input};
|
|
||||||
|
// FIXME: remove?
|
||||||
|
auto narHash = store->queryPathInfo(file.storePath)->narHash;
|
||||||
|
input.attrs.insert_or_assign("narHash", narHash.to_string(SRI, true));
|
||||||
|
input.locked = true;
|
||||||
|
|
||||||
|
return {makeStorePathAccessor(store, file.storePath), input};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -271,12 +279,18 @@ struct TarballInputScheme : CurlInputScheme
|
||||||
: hasTarballExtension(url.path));
|
: hasTarballExtension(url.path));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<StorePath, Input> fetchToStore(ref<Store> store, const Input & input) override
|
std::pair<ref<InputAccessor>, Input> getAccessor(ref<Store> store, const Input & _input) const override
|
||||||
{
|
{
|
||||||
return {
|
auto input(_input);
|
||||||
downloadTarball(store, getStrAttr(input.attrs, "url"), input.getName(), false).first,
|
|
||||||
input
|
auto storePath = downloadTarball(store, getStrAttr(input.attrs, "url"), input.getName(), false).first;
|
||||||
};
|
|
||||||
|
// FIXME: remove?
|
||||||
|
auto narHash = store->queryPathInfo(storePath)->narHash;
|
||||||
|
input.attrs.insert_or_assign("narHash", narHash.to_string(SRI, true));
|
||||||
|
input.locked = true;
|
||||||
|
|
||||||
|
return {makeStorePathAccessor(store, storePath), input};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -120,6 +120,7 @@ git -C $repo commit -m 'Bla3' -a
|
||||||
path4=$(nix eval --impure --refresh --raw --expr "(builtins.fetchGit file://$repo).outPath")
|
path4=$(nix eval --impure --refresh --raw --expr "(builtins.fetchGit file://$repo).outPath")
|
||||||
[[ $path2 = $path4 ]]
|
[[ $path2 = $path4 ]]
|
||||||
|
|
||||||
|
status=0
|
||||||
nix eval --impure --raw --expr "(builtins.fetchGit { url = $repo; rev = \"$rev2\"; narHash = \"sha256-B5yIPHhEm0eysJKEsO7nqxprh9vcblFxpJG11gXJus1=\"; }).outPath" || status=$?
|
nix eval --impure --raw --expr "(builtins.fetchGit { url = $repo; rev = \"$rev2\"; narHash = \"sha256-B5yIPHhEm0eysJKEsO7nqxprh9vcblFxpJG11gXJus1=\"; }).outPath" || status=$?
|
||||||
[[ "$status" = "102" ]]
|
[[ "$status" = "102" ]]
|
||||||
|
|
||||||
|
@ -223,4 +224,5 @@ rm -rf $repo/.git
|
||||||
|
|
||||||
# should succeed for a repo without commits
|
# should succeed for a repo without commits
|
||||||
git init $repo
|
git init $repo
|
||||||
|
git -C $repo add hello # need to add at least one file to cause the root of the repo to be visible
|
||||||
path10=$(nix eval --impure --raw --expr "(builtins.fetchGit \"file://$repo\").outPath")
|
path10=$(nix eval --impure --raw --expr "(builtins.fetchGit \"file://$repo\").outPath")
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue