diff options
Diffstat (limited to 'src/libstore/fetchers')
-rw-r--r-- | src/libstore/fetchers/attrs.cc | 25 | ||||
-rw-r--r-- | src/libstore/fetchers/attrs.hh | 13 | ||||
-rw-r--r-- | src/libstore/fetchers/git.cc | 16 | ||||
-rw-r--r-- | src/libstore/fetchers/mercurial.cc | 2 |
4 files changed, 49 insertions, 7 deletions
diff --git a/src/libstore/fetchers/attrs.cc b/src/libstore/fetchers/attrs.cc index 83b6d9164..40c02de42 100644 --- a/src/libstore/fetchers/attrs.cc +++ b/src/libstore/fetchers/attrs.cc @@ -14,6 +14,8 @@ Attrs jsonToAttrs(const nlohmann::json & json) attrs.emplace(i.key(), i.value().get<int64_t>()); else if (i.value().is_string()) attrs.emplace(i.key(), i.value().get<std::string>()); + else if (i.value().is_boolean()) + attrs.emplace(i.key(), i.value().get<bool>()); else throw Error("unsupported input attribute type in lock file"); } @@ -29,6 +31,8 @@ nlohmann::json attrsToJson(const Attrs & attrs) json[attr.first] = *v; } else if (auto v = std::get_if<std::string>(&attr.second)) { json[attr.first] = *v; + } else if (auto v = std::get_if<Explicit<bool>>(&attr.second)) { + json[attr.first] = v->t; } else abort(); } return json; @@ -40,7 +44,7 @@ std::optional<std::string> maybeGetStrAttr(const Attrs & attrs, const std::strin if (i == attrs.end()) return {}; if (auto v = std::get_if<std::string>(&i->second)) return *v; - throw Error("input attribute '%s' is not a string", name); + throw Error("input attribute '%s' is not a string %s", name, attrsToJson(attrs).dump()); } std::string getStrAttr(const Attrs & attrs, const std::string & name) @@ -57,7 +61,7 @@ std::optional<int64_t> maybeGetIntAttr(const Attrs & attrs, const std::string & if (i == attrs.end()) return {}; if (auto v = std::get_if<int64_t>(&i->second)) return *v; - throw Error("input attribute '%s' is not a string", name); + throw Error("input attribute '%s' is not an integer", name); } int64_t getIntAttr(const Attrs & attrs, const std::string & name) @@ -68,4 +72,21 @@ int64_t getIntAttr(const Attrs & attrs, const std::string & name) return *s; } +std::optional<bool> maybeGetBoolAttr(const Attrs & attrs, const std::string & name) +{ + auto i = attrs.find(name); + if (i == attrs.end()) return {}; + if (auto v = std::get_if<int64_t>(&i->second)) + return *v; + throw Error("input attribute '%s' is not a Boolean", name); +} + +bool getBoolAttr(const Attrs & attrs, const std::string & name) +{ + auto s = maybeGetBoolAttr(attrs, name); + if (!s) + throw Error("input attribute '%s' is missing", name); + return *s; +} + } diff --git a/src/libstore/fetchers/attrs.hh b/src/libstore/fetchers/attrs.hh index b7f98d71b..2c9e772d2 100644 --- a/src/libstore/fetchers/attrs.hh +++ b/src/libstore/fetchers/attrs.hh @@ -8,7 +8,14 @@ namespace nix::fetchers { -typedef std::variant<std::string, int64_t> Attr; +/* Wrap bools to prevent string literals (i.e. 'char *') from being + cast to a bool in Attr. */ +template<typename T> +struct Explicit { + T t; +}; + +typedef std::variant<std::string, int64_t, Explicit<bool>> Attr; typedef std::map<std::string, Attr> Attrs; Attrs jsonToAttrs(const nlohmann::json & json); @@ -23,4 +30,8 @@ std::optional<int64_t> maybeGetIntAttr(const Attrs & attrs, const std::string & int64_t getIntAttr(const Attrs & attrs, const std::string & name); +std::optional<bool> maybeGetBoolAttr(const Attrs & attrs, const std::string & name); + +bool getBoolAttr(const Attrs & attrs, const std::string & name); + } diff --git a/src/libstore/fetchers/git.cc b/src/libstore/fetchers/git.cc index 179a5fb83..c5d4f019c 100644 --- a/src/libstore/fetchers/git.cc +++ b/src/libstore/fetchers/git.cc @@ -83,6 +83,7 @@ struct GitInput : Input ParsedURL url; std::optional<std::string> ref; std::optional<Hash> rev; + bool shallow = false; GitInput(const ParsedURL & url) : url(url) { } @@ -114,6 +115,7 @@ struct GitInput : Input if (url2.scheme != "git") url2.scheme = "git+" + url2.scheme; if (rev) url2.query.insert_or_assign("rev", rev->gitRev()); if (ref) url2.query.insert_or_assign("ref", *ref); + if (shallow) url2.query.insert_or_assign("shallow", "1"); return url2.to_string(); } @@ -125,6 +127,8 @@ struct GitInput : Input attrs.emplace("ref", *ref); if (rev) attrs.emplace("rev", rev->gitRev()); + if (shallow) + attrs.emplace("shallow", true); return attrs; } @@ -361,9 +365,12 @@ struct GitInput : Input bool isShallow = chomp(runProgram("git", true, { "-C", repoDir, "rev-parse", "--is-shallow-repository" })) == "true"; + if (isShallow && !shallow) + throw Error("'%s' is a shallow Git repository, but a non-shallow repository is needed", actualUrl); + if (auto tree = lookupGitInfo(store, name, *input->rev)) { assert(*input->rev == tree->first); - if (isShallow) tree->second.info.revCount.reset(); + if (shallow) tree->second.info.revCount.reset(); return {std::move(tree->second), input}; } @@ -393,7 +400,7 @@ struct GitInput : Input .storePath = std::move(storePath), .info = TreeInfo { .revCount = - !isShallow + !shallow ? std::optional(std::stoull(runProgram("git", true, { "-C", repoDir, "rev-list", "--count", input->rev->gitRev() }))) : std::nullopt, .lastModified = lastModified @@ -440,7 +447,7 @@ struct GitInputScheme : InputScheme if (maybeGetStrAttr(attrs, "type") != "git") return {}; for (auto & [name, value] : attrs) - if (name != "type" && name != "url" && name != "ref" && name != "rev") + if (name != "type" && name != "url" && name != "ref" && name != "rev" && name != "shallow") throw Error("unsupported Git input attribute '%s'", name); auto input = std::make_unique<GitInput>(parseURL(getStrAttr(attrs, "url"))); @@ -451,6 +458,9 @@ struct GitInputScheme : InputScheme } if (auto rev = maybeGetStrAttr(attrs, "rev")) input->rev = Hash(*rev, htSHA1); + + input->shallow = maybeGetBoolAttr(attrs, "shallow").value_or(false); + return input; } }; diff --git a/src/libstore/fetchers/mercurial.cc b/src/libstore/fetchers/mercurial.cc index a9c86f1b4..3a767ef17 100644 --- a/src/libstore/fetchers/mercurial.cc +++ b/src/libstore/fetchers/mercurial.cc @@ -260,7 +260,7 @@ struct MercurialInput : Input Attrs infoAttrs({ {"rev", input->rev->gitRev()}, - {"revCount", revCount}, + {"revCount", (int64_t) revCount}, }); if (!this->rev) |