diff options
Diffstat (limited to 'src/libexpr/flake/flakeref.hh')
-rw-r--r-- | src/libexpr/flake/flakeref.hh | 182 |
1 files changed, 20 insertions, 162 deletions
diff --git a/src/libexpr/flake/flakeref.hh b/src/libexpr/flake/flakeref.hh index addf5449f..f552c99d8 100644 --- a/src/libexpr/flake/flakeref.hh +++ b/src/libexpr/flake/flakeref.hh @@ -7,194 +7,52 @@ namespace nix { -/* Flake references are a URI-like syntax to specify a flake. +class Store; - Examples: - - * <flake-id>(/rev-or-ref(/rev)?)? - - Look up a flake by ID in the flake lock file or in the flake - registry. These must specify an actual location for the flake - using the formats listed below. Note that in pure evaluation - mode, the flake registry is empty. - - Optionally, the rev or ref from the dereferenced flake can be - overriden. For example, - - nixpkgs/19.09 - - uses the "19.09" branch of the nixpkgs' flake GitHub repository, - while - - nixpkgs/98a2a5b5370c1e2092d09cb38b9dcff6d98a109f - - uses the specified revision. For Git (rather than GitHub) - repositories, both the rev and ref must be given, e.g. - - nixpkgs/19.09/98a2a5b5370c1e2092d09cb38b9dcff6d98a109f - - * github:<owner>/<repo>(/<rev-or-ref>)? - - A repository on GitHub. These differ from Git references in that - they're downloaded in a efficient way (via the tarball mechanism) - and that they support downloading a specific revision without - specifying a branch. <rev-or-ref> is either a commit hash ("rev") - or a branch or tag name ("ref"). The default is: "master" if none - is specified. Note that in pure evaluation mode, a commit hash - must be used. - - Flakes fetched in this manner expose "rev" and "lastModified" - attributes, but not "revCount". - - Examples: - - github:edolstra/dwarffs - github:edolstra/dwarffs/unstable - github:edolstra/dwarffs/41c0c1bf292ea3ac3858ff393b49ca1123dbd553 - - * git+https://<server>/<path>(\?attr(&attr)*)? - git+ssh://<server>/<path>(\?attr(&attr)*)? - git://<server>/<path>(\?attr(&attr)*)? - file:///<path>(\?attr(&attr)*)? - - where 'attr' is one of: - rev=<rev> - ref=<ref> - - A Git repository fetched through https. The default for "ref" is - "master". - - Examples: - - git+https://example.org/my/repo.git - git+https://example.org/my/repo.git?ref=release-1.2.3 - git+https://example.org/my/repo.git?rev=e72daba8250068216d79d2aeef40d4d95aff6666 - git://github.com/edolstra/dwarffs.git?ref=flake&rev=2efca4bc9da70fb001b26c3dc858c6397d3c4817 - - * /path(\?attr(&attr)*)? - - Like file://path, but if no "ref" or "rev" is specified, the - (possibly dirty) working tree will be used. Using a working tree - is not allowed in pure evaluation mode. - - Examples: - - /path/to/my/repo - /path/to/my/repo?ref=develop - /path/to/my/repo?rev=e72daba8250068216d79d2aeef40d4d95aff6666 - - * https://<server>/<path>.tar.xz(?hash=<sri-hash>) - file:///<path>.tar.xz(?hash=<sri-hash>) - - A flake distributed as a tarball. In pure evaluation mode, an SRI - hash is mandatory. It exposes a "lastModified" attribute, being - the newest file inside the tarball. - - Example: - - https://releases.nixos.org/nixos/unstable/nixos-19.03pre167858.f2a1a4e93be/nixexprs.tar.xz - https://releases.nixos.org/nixos/unstable/nixos-19.03pre167858.f2a1a4e93be/nixexprs.tar.xz?hash=sha256-56bbc099995ea8581ead78f22832fee7dbcb0a0b6319293d8c2d0aef5379397c - - Note: currently, there can be only one flake per Git repository, and - it must be at top-level. In the future, we may want to add a field - (e.g. "dir=<dir>") to specify a subdirectory inside the repository. -*/ +namespace fetchers { struct Input; } typedef std::string FlakeId; -typedef std::string FlakeUri; struct FlakeRef { - struct IsId - { - FlakeId id; - bool operator<(const IsId & b) const { return id < b.id; }; - bool operator==(const IsId & b) const { return id == b.id; }; - }; - - struct IsGitHub { - std::string owner, repo; - bool operator<(const IsGitHub & b) const { - return std::make_tuple(owner, repo) < std::make_tuple(b.owner, b.repo); - } - bool operator==(const IsGitHub & b) const { - return owner == b.owner && repo == b.repo; - } - }; - - // Git, Tarball - struct IsGit - { - std::string uri; - bool operator<(const IsGit & b) const { return uri < b.uri; } - bool operator==(const IsGit & b) const { return uri == b.uri; } - }; - - struct IsPath - { - Path path; - bool operator<(const IsPath & b) const { return path < b.path; } - bool operator==(const IsPath & b) const { return path == b.path; } - }; - - // Git, Tarball - - std::variant<IsId, IsGitHub, IsGit, IsPath> data; + std::shared_ptr<const fetchers::Input> input; - std::optional<std::string> ref; - std::optional<Hash> rev; - Path subdir = ""; // This is a relative path pointing at the flake.nix file's directory, relative to the git root. + Path subdir; - bool operator<(const FlakeRef & flakeRef) const - { - return std::make_tuple(data, ref, rev, subdir) < - std::make_tuple(flakeRef.data, flakeRef.ref, flakeRef.rev, subdir); - } + bool operator==(const FlakeRef & other) const; - bool operator==(const FlakeRef & flakeRef) const + FlakeRef(const std::shared_ptr<const fetchers::Input> & input, const Path & subdir) + : input(input), subdir(subdir) { - return std::make_tuple(data, ref, rev, subdir) == - std::make_tuple(flakeRef.data, flakeRef.ref, flakeRef.rev, flakeRef.subdir); + assert(input); } - // Parse a flake URI. - FlakeRef(const std::string & uri, bool allowRelative = false); - // FIXME: change to operator <<. std::string to_string() const; /* Check whether this is a "direct" flake reference, that is, not a flake ID, which requires a lookup in the flake registry. */ - bool isDirect() const - { - return !std::get_if<FlakeRef::IsId>(&data); - } + bool isDirect() const; /* Check whether this is an "immutable" flake reference, that is, one that contains a commit hash or content hash. */ bool isImmutable() const; - FlakeRef baseRef() const; - - bool isDirty() const - { - return std::get_if<FlakeRef::IsPath>(&data) - && rev == Hash(rev->type); - } - - /* Return true if 'other' is not less specific than 'this'. For - example, 'nixpkgs' contains 'nixpkgs/release-19.03', and both - 'nixpkgs' and 'nixpkgs/release-19.03' contain - 'nixpkgs/release-19.03/<hash>'. */ - bool contains(const FlakeRef & other) const; + FlakeRef resolve(ref<Store> store) const; }; std::ostream & operator << (std::ostream & str, const FlakeRef & flakeRef); -MakeError(BadFlakeRef, Error); -MakeError(MissingFlake, BadFlakeRef); +FlakeRef parseFlakeRef( + const std::string & url, const std::optional<Path> & baseDir = {}); + +std::optional<FlakeRef> maybeParseFlake( + const std::string & url, const std::optional<Path> & baseDir = {}); + +std::pair<FlakeRef, std::string> parseFlakeRefWithFragment( + const std::string & url, const std::optional<Path> & baseDir = {}); -std::optional<FlakeRef> parseFlakeRef( - const std::string & uri, bool allowRelative = false); +std::optional<std::pair<FlakeRef, std::string>> maybeParseFlakeRefWithFragment( + const std::string & url, const std::optional<Path> & baseDir = {}); } |