Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 12 additions & 6 deletions src/libfetchers/fetchers.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Comment on lines +137 to 138
Copy link
Contributor

@xokdvium xokdvium Oct 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generally I don't think that we should mix in business logic with debug prints. toURL is very load bearing and I think we could move this into a separate method that individual input types input schemes could override.

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
Expand All @@ -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
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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));
}
Expand Down
14 changes: 8 additions & 6 deletions src/libfetchers/git.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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);
}

Expand Down Expand Up @@ -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. */
Expand Down
13 changes: 6 additions & 7 deletions src/libfetchers/github.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand All @@ -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,
Expand Down Expand Up @@ -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};
}
Expand Down Expand Up @@ -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};
}
Expand Down Expand Up @@ -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};
Expand Down Expand Up @@ -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};
Expand Down
6 changes: 3 additions & 3 deletions src/libfetchers/include/nix/fetchers/fetchers.hh
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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;

Expand Down
2 changes: 1 addition & 1 deletion src/libfetchers/indirect.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
8 changes: 3 additions & 5 deletions src/libfetchers/mercurial.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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()}}};
};
Expand Down Expand Up @@ -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};
}
Expand Down
2 changes: 1 addition & 1 deletion src/libfetchers/path.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down
6 changes: 3 additions & 3 deletions src/libfetchers/tarball.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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};
}
Expand All @@ -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);
Expand Down
4 changes: 2 additions & 2 deletions tests/functional/flakes/source-paths.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
Loading