diff --git a/src/libexpr/flake/flakeref.cc b/src/libexpr/flake/flakeref.cc index f97679dd9..5c38f7ea5 100644 --- a/src/libexpr/flake/flakeref.cc +++ b/src/libexpr/flake/flakeref.cc @@ -16,7 +16,10 @@ const static std::string subDirRegex = subDirElemRegex + "(?:/" + subDirElemRege std::string FlakeRef::to_string() const { - return input->to_string(); + auto url = input->toURL(); + if (subdir != "") + url.query.insert_or_assign("dir", subdir); + return url.to_string(); } fetchers::Attrs FlakeRef::toAttrs() const diff --git a/src/libstore/fetchers/fetchers.hh b/src/libstore/fetchers/fetchers.hh index deb1c9c59..5e33ec4ca 100644 --- a/src/libstore/fetchers/fetchers.hh +++ b/src/libstore/fetchers/fetchers.hh @@ -5,6 +5,7 @@ #include "path.hh" #include "tree-info.hh" #include "attrs.hh" +#include "parse.hh" #include @@ -45,7 +46,12 @@ struct Input : std::enable_shared_from_this virtual std::optional getRev() const { return {}; } - virtual std::string to_string() const = 0; + virtual ParsedURL toURL() const = 0; + + std::string to_string() const + { + return toURL().to_string(); + } Attrs toAttrs() const; @@ -74,8 +80,6 @@ private: virtual Attrs toAttrsInternal() const = 0; }; -struct ParsedURL; - struct InputScheme { virtual ~InputScheme() { } diff --git a/src/libstore/fetchers/git.cc b/src/libstore/fetchers/git.cc index ede758544..f6b7820b8 100644 --- a/src/libstore/fetchers/git.cc +++ b/src/libstore/fetchers/git.cc @@ -48,14 +48,14 @@ struct GitInput : Input std::optional getRev() const override { return rev; } - std::string to_string() const override + ParsedURL toURL() const override { ParsedURL url2(url); 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(); + return url2; } Attrs toAttrsInternal() const override diff --git a/src/libstore/fetchers/github.cc b/src/libstore/fetchers/github.cc index 0fef456df..5e34ee051 100644 --- a/src/libstore/fetchers/github.cc +++ b/src/libstore/fetchers/github.cc @@ -42,13 +42,16 @@ struct GitHubInput : Input std::optional getRev() const override { return rev; } - std::string to_string() const override + ParsedURL toURL() const override { - auto s = fmt("github:%s/%s", owner, repo); + auto path = owner + "/" + repo; assert(!(ref && rev)); - if (ref) s += "/" + *ref; - if (rev) s += "/" + rev->to_string(Base16, false); - return s; + if (ref) path += "/" + *ref; + if (rev) path += "/" + rev->to_string(Base16, false); + return ParsedURL { + .scheme = "github", + .path = path, + }; } Attrs toAttrsInternal() const override diff --git a/src/libstore/fetchers/indirect.cc b/src/libstore/fetchers/indirect.cc index 963abd85f..37e5afbc4 100644 --- a/src/libstore/fetchers/indirect.cc +++ b/src/libstore/fetchers/indirect.cc @@ -43,14 +43,14 @@ struct IndirectInput : Input && (!rev || rev == other2->rev); } - std::string to_string() const override + ParsedURL toURL() const override { ParsedURL url; url.scheme = "flake"; url.path = id; if (ref) { url.path += '/'; url.path += *ref; }; if (rev) { url.path += '/'; url.path += rev->gitRev(); }; - return url.to_string(); + return url; } Attrs toAttrsInternal() const override diff --git a/src/libstore/fetchers/mercurial.cc b/src/libstore/fetchers/mercurial.cc index 5cd43a74e..6fb13391b 100644 --- a/src/libstore/fetchers/mercurial.cc +++ b/src/libstore/fetchers/mercurial.cc @@ -42,13 +42,13 @@ struct MercurialInput : Input std::optional getRev() const override { return rev; } - std::string to_string() const override + ParsedURL toURL() const override { ParsedURL url2(url); url2.scheme = "hg+" + url2.scheme; if (rev) url2.query.insert_or_assign("rev", rev->gitRev()); if (ref) url2.query.insert_or_assign("ref", *ref); - return url2.to_string(); + return url; } Attrs toAttrsInternal() const override diff --git a/src/libstore/fetchers/tarball.cc b/src/libstore/fetchers/tarball.cc index 62d43ca36..2beb7876d 100644 --- a/src/libstore/fetchers/tarball.cc +++ b/src/libstore/fetchers/tarball.cc @@ -190,7 +190,7 @@ struct TarballInput : Input return hash || narHash; } - std::string to_string() const override + ParsedURL toURL() const override { auto url2(url); // NAR hashes are preferred over file hashes since tar/zip files @@ -199,7 +199,7 @@ struct TarballInput : Input url2.query.insert_or_assign("narHash", narHash->to_string(SRI)); else if (hash) url2.query.insert_or_assign("hash", hash->to_string(SRI)); - return url2.to_string(); + return url2; } Attrs toAttrsInternal() const override diff --git a/src/nix/flake.cc b/src/nix/flake.cc index 317d1bc18..b090ea201 100644 --- a/src/nix/flake.cc +++ b/src/nix/flake.cc @@ -79,7 +79,7 @@ struct CmdFlakeList : EvalCommand static void printFlakeInfo(const Store & store, const Flake & flake) { - std::cout << fmt("URL: %s\n", flake.lockedRef.input->to_string()); + std::cout << fmt("URL: %s\n", flake.lockedRef.to_string()); std::cout << fmt("Edition: %s\n", flake.edition); if (flake.description) std::cout << fmt("Description: %s\n", *flake.description); @@ -99,7 +99,7 @@ static nlohmann::json flakeToJson(const Store & store, const Flake & flake) if (flake.description) j["description"] = *flake.description; j["edition"] = flake.edition; - j["url"] = flake.lockedRef.input->to_string(); + j["url"] = flake.lockedRef.to_string(); if (auto rev = flake.lockedRef.input->getRev()) j["revision"] = rev->to_string(Base16, false); if (flake.sourceInfo->info.revCount)