1
1
Fork 0
mirror of https://github.com/NixOS/nix.git synced 2025-11-09 03:56:01 +01:00

Abbreviate flakerefs in error messages

In particular, this gets rid of the `narHash` query parameter and
shortens the Git revision in GitHub flakerefs. So instead of

       … from call site
         at «github:NixOS/nixpkgs/3bea86e918d8b54aa49780505d2d4cd9261413be?narHash=sha256-Ica%2B%2BSXFuLyxX9Q7YxhfZulUif6/gwM8AEQYlUxqSgE%3D»/lib/customisation.nix:69:16:
           68|     let
           69|       result = f origArgs;
             |                ^
           70|

we get

       … from call site
         at «github:NixOS/nixpkgs/3bea86e»/lib/customisation.nix:69:16:
           68|     let
           69|       result = f origArgs;
             |                ^
           70|
This commit is contained in:
Eelco Dolstra 2025-10-30 15:24:44 +01:00
parent 49084a7e9e
commit f30663a94a
9 changed files with 39 additions and 34 deletions

View file

@ -134,11 +134,17 @@ std::optional<std::string> Input::getFingerprint(ref<Store> store) const
return fingerprint;
}
ParsedURL Input::toURL() const
ParsedURL Input::toURL(bool abbreviate) const
{
if (!scheme)
throw Error("cannot show unsupported input '%s'", attrsToJSON(attrs));
return scheme->toURL(*this);
auto url = scheme->toURL(*this, abbreviate);
if (abbreviate)
url.query.erase("narHash");
return url;
}
std::string Input::toURLString(const StringMap & extraQuery) const
@ -149,9 +155,9 @@ std::string Input::toURLString(const StringMap & extraQuery) const
return url.to_string();
}
std::string Input::to_string() const
std::string Input::to_string(bool abbreviate) const
{
return toURL().to_string();
return toURL(abbreviate).to_string();
}
bool Input::isDirect() const
@ -352,7 +358,7 @@ std::pair<ref<SourceAccessor>, Input> Input::getAccessorUnchecked(ref<Store> sto
settings->getCache()->upsert(cacheKey, *store, {}, storePath);
}
accessor->setPathDisplay("«" + to_string() + "»");
accessor->setPathDisplay("«" + to_string(true) + "»");
return {accessor, *this};
} catch (Error & e) {
@ -468,7 +474,7 @@ std::optional<time_t> Input::getLastModified() const
return {};
}
ParsedURL InputScheme::toURL(const Input & input) const
ParsedURL InputScheme::toURL(const Input & input, bool abbreviate) const
{
throw Error("don't know how to convert input '%s' to a URL", attrsToJSON(input.attrs));
}

View file

@ -241,15 +241,17 @@ struct GitInputScheme : InputScheme
return input;
}
ParsedURL toURL(const Input & input) const override
ParsedURL toURL(const Input & input, bool abbreviate) const override
{
auto url = parseURL(getStrAttr(input.attrs, "url"));
if (url.scheme != "git")
url.scheme = "git+" + url.scheme;
if (auto rev = input.getRev())
url.query.insert_or_assign("rev", rev->gitRev());
if (auto ref = input.getRef())
url.query.insert_or_assign("ref", *ref);
if (auto ref = input.getRef()) {
if (!abbreviate || (*ref != "master" && *ref != "main"))
url.query.insert_or_assign("ref", *ref);
}
if (getShallowAttr(input))
url.query.insert_or_assign("shallow", "1");
if (getLfsAttr(input))
@ -750,7 +752,7 @@ struct GitInputScheme : InputScheme
bool exportIgnore = getExportIgnoreAttr(input);
bool smudgeLfs = getLfsAttr(input);
auto accessor = repo->getAccessor(rev, exportIgnore, "«" + input.to_string() + "»", smudgeLfs);
auto accessor = repo->getAccessor(rev, exportIgnore, "«" + input.to_string(true) + "»", smudgeLfs);
/* If the repo has submodules, fetch them and return a mounted
input accessor consisting of the accessor for the top-level
@ -787,7 +789,7 @@ struct GitInputScheme : InputScheme
attrs.insert_or_assign("allRefs", Explicit<bool>{true});
auto submoduleInput = fetchers::Input::fromAttrs(*input.settings, std::move(attrs));
auto [submoduleAccessor, submoduleInput2] = submoduleInput.getAccessor(store);
submoduleAccessor->setPathDisplay("«" + submoduleInput.to_string() + "»");
submoduleAccessor->setPathDisplay("«" + submoduleInput.to_string(true) + "»");
mounts.insert_or_assign(submodule.path, submoduleAccessor);
}
@ -840,7 +842,7 @@ struct GitInputScheme : InputScheme
auto submoduleInput = fetchers::Input::fromAttrs(*input.settings, std::move(attrs));
auto [submoduleAccessor, submoduleInput2] = submoduleInput.getAccessor(store);
submoduleAccessor->setPathDisplay("«" + submoduleInput.to_string() + "»");
submoduleAccessor->setPathDisplay("«" + submoduleInput.to_string(true) + "»");
/* If the submodule is dirty, mark this repo dirty as
well. */

View file

@ -134,7 +134,7 @@ struct GitArchiveInputScheme : InputScheme
return input;
}
ParsedURL toURL(const Input & input) const override
ParsedURL toURL(const Input & input, bool abbreviate) const override
{
auto owner = getStrAttr(input.attrs, "owner");
auto repo = getStrAttr(input.attrs, "repo");
@ -145,7 +145,7 @@ struct GitArchiveInputScheme : InputScheme
if (ref)
path.push_back(*ref);
if (rev)
path.push_back(rev->to_string(HashFormat::Base16, false));
path.push_back(abbreviate ? rev->gitShortRev() : rev->gitRev());
auto url = ParsedURL{
.scheme = std::string{schemeName()},
.path = path,
@ -324,7 +324,7 @@ struct GitArchiveInputScheme : InputScheme
#endif
input.attrs.insert_or_assign("lastModified", uint64_t(tarballInfo.lastModified));
auto accessor = getTarballCache()->getAccessor(tarballInfo.treeHash, false, "«" + input.to_string() + "»");
auto accessor = getTarballCache()->getAccessor(tarballInfo.treeHash, false, "«" + input.to_string(true) + "»");
return {accessor, input};
}
@ -419,8 +419,7 @@ struct GitHubInputScheme : GitArchiveInputScheme
: headers.empty() ? "https://%s/%s/%s/archive/%s.tar.gz"
: "https://api.%s/repos/%s/%s/tarball/%s";
const auto url =
fmt(urlFmt, host, getOwner(input), getRepo(input), input.getRev()->to_string(HashFormat::Base16, false));
const auto url = fmt(urlFmt, host, getOwner(input), getRepo(input), input.getRev()->gitRev());
return DownloadUrl{parseURL(url), headers};
}
@ -500,7 +499,7 @@ struct GitLabInputScheme : GitArchiveInputScheme
host,
getStrAttr(input.attrs, "owner"),
getStrAttr(input.attrs, "repo"),
input.getRev()->to_string(HashFormat::Base16, false));
input.getRev()->gitRev());
Headers headers = makeHeadersWithAuthTokens(*input.settings, host, input);
return DownloadUrl{parseURL(url), headers};
@ -590,7 +589,7 @@ struct SourceHutInputScheme : GitArchiveInputScheme
host,
getStrAttr(input.attrs, "owner"),
getStrAttr(input.attrs, "repo"),
input.getRev()->to_string(HashFormat::Base16, false));
input.getRev()->gitRev());
Headers headers = makeHeadersWithAuthTokens(*input.settings, host, input);
return DownloadUrl{parseURL(url), headers};

View file

@ -68,11 +68,11 @@ public:
*/
static Input fromAttrs(const Settings & settings, Attrs && attrs);
ParsedURL toURL() const;
ParsedURL toURL(bool abbreviate = false) const;
std::string toURLString(const StringMap & extraQuery = {}) const;
std::string to_string() const;
std::string to_string(bool abbreviate = false) const;
Attrs toAttrs() const;
@ -219,7 +219,7 @@ struct InputScheme
*/
virtual StringSet allowedAttrs() const = 0;
virtual ParsedURL toURL(const Input & input) const;
virtual ParsedURL toURL(const Input & input, bool abbreviate = false) const;
virtual Input applyOverrides(const Input & input, std::optional<std::string> ref, std::optional<Hash> rev) const;

View file

@ -81,7 +81,7 @@ struct IndirectInputScheme : InputScheme
return input;
}
ParsedURL toURL(const Input & input) const override
ParsedURL toURL(const Input & input, bool abbreviate) const override
{
ParsedURL url{
.scheme = "flake",

View file

@ -94,7 +94,7 @@ struct MercurialInputScheme : InputScheme
return input;
}
ParsedURL toURL(const Input & input) const override
ParsedURL toURL(const Input & input, bool abbreviate) const override
{
auto url = parseURL(getStrAttr(input.attrs, "url"));
url.scheme = "hg+" + url.scheme;
@ -222,9 +222,7 @@ struct MercurialInputScheme : InputScheme
auto revInfoKey = [&](const Hash & rev) {
if (rev.algo != HashAlgorithm::SHA1)
throw Error(
"Hash '%s' is not supported by Mercurial. Only sha1 is supported.",
rev.to_string(HashFormat::Base16, true));
throw Error("Hash '%s' is not supported by Mercurial. Only sha1 is supported.", rev.gitRev());
return Cache::Key{"hgRev", {{"store", store->storeDir}, {"name", name}, {"rev", input.getRev()->gitRev()}}};
};
@ -331,7 +329,7 @@ struct MercurialInputScheme : InputScheme
auto storePath = fetchToStore(store, input);
auto accessor = store->requireStoreObjectAccessor(storePath);
accessor->setPathDisplay("«" + input.to_string() + "»");
accessor->setPathDisplay("«" + input.to_string(true) + "»");
return {accessor, input};
}

View file

@ -65,7 +65,7 @@ struct PathInputScheme : InputScheme
return input;
}
ParsedURL toURL(const Input & input) const override
ParsedURL toURL(const Input & input, bool abbreviate) const override
{
auto query = attrsToQuery(input.attrs);
query.erase("path");

View file

@ -309,7 +309,7 @@ struct CurlInputScheme : InputScheme
return input;
}
ParsedURL toURL(const Input & input) const override
ParsedURL toURL(const Input & input, bool abbreviate) const override
{
auto url = parseURL(getStrAttr(input.attrs, "url"));
// NAR hashes are preferred over file hashes since tar/zip
@ -355,7 +355,7 @@ struct FileInputScheme : CurlInputScheme
auto accessor = ref{store->getFSAccessor(file.storePath)};
accessor->setPathDisplay("«" + input.to_string() + "»");
accessor->setPathDisplay("«" + input.to_string(true) + "»");
return {accessor, input};
}
@ -382,7 +382,7 @@ struct TarballInputScheme : CurlInputScheme
auto input(_input);
auto result =
downloadTarball_(*input.settings, getStrAttr(input.attrs, "url"), {}, "«" + input.to_string() + "»");
downloadTarball_(*input.settings, getStrAttr(input.attrs, "url"), {}, "«" + input.to_string(true) + "»");
if (result.immutableUrl) {
auto immutableInput = Input::fromURL(*input.settings, *result.immutableUrl);

View file

@ -30,10 +30,10 @@ expectStderr 1 nix eval "$repo#y" | grepQuiet "at $repo/flake.nix:"
git -C "$repo" commit -a -m foo
expectStderr 1 nix eval "git+file://$repo?ref=master#y" | grepQuiet "at «git+file://$repo?ref=master&rev=.*»/flake.nix:"
expectStderr 1 nix eval "git+file://$repo?ref=master#y" | grepQuiet "at «git+file://$repo?rev=.*»/flake.nix:"
expectStderr 1 nix eval "$repo#z" | grepQuiet "error: Path 'foo' does not exist in Git repository \"$repo\"."
expectStderr 1 nix eval "git+file://$repo?ref=master#z" | grepQuiet "error: '«git+file://$repo?ref=master&rev=.*»/foo' does not exist"
expectStderr 1 nix eval "git+file://$repo?ref=master#z" | grepQuiet "error: '«git+file://$repo?rev=.*»/foo' does not exist"
expectStderr 1 nix eval "$repo#a" | grepQuiet "error: Path 'foo' does not exist in Git repository \"$repo\"."
echo 123 > "$repo/foo"