#pragma once ///@file #include "types.hh" #include "hash.hh" #include "canon-path.hh" #include "attrs.hh" #include "url.hh" #include #include namespace nix { class Store; class StorePath; struct InputAccessor; } namespace nix::fetchers { struct InputScheme; /** * The `Input` object is generated by a specific fetcher, based on * user-supplied information, and contains * the information that the specific fetcher needs to perform the * actual fetch. The Input object is most commonly created via the * `fromURL()` or `fromAttrs()` static functions. */ struct Input { friend struct InputScheme; std::shared_ptr scheme; // note: can be null Attrs attrs; bool locked = false; /** * path of the parent of this input, used for relative path resolution */ std::optional parent; public: /** * Create an `Input` from a URL. * * The URL indicate which sort of fetcher, and provides information to that fetcher. */ static Input fromURL(const std::string & url, bool requireTree = true); static Input fromURL(const ParsedURL & url, bool requireTree = true); /** * Create an `Input` from a an `Attrs`. * * The URL indicate which sort of fetcher, and provides information to that fetcher. */ static Input fromAttrs(Attrs && attrs); ParsedURL toURL() const; std::string toURLString(const std::map & extraQuery = {}) const; std::string to_string() const; Attrs toAttrs() const; /** * Check whether this is a "direct" input, that is, not * one that goes through a registry. */ bool isDirect() const; /** * Check whether this is a "locked" input, that is, * one that contains a commit hash or content hash. */ bool isLocked() const { return locked; } bool operator ==(const Input & other) const; bool contains(const Input & other) const; /** * Fetch the entire input into the Nix store, returning the * location in the Nix store and the locked input. */ std::pair fetch(ref store) const; std::pair, Input> getAccessor(ref store) const; Input applyOverrides( std::optional ref, std::optional rev) const; void clone(const Path & destDir) const; std::optional getSourcePath() const; /** * Write a file to this input, for input types that support * writing. Optionally commit the change (for e.g. Git inputs). */ void putFile( const CanonPath & path, std::string_view contents, std::optional commitMsg) const; std::string getName() const; StorePath computeStorePath(Store & store) const; // Convenience functions for common attributes. std::string getType() const; std::optional getNarHash() const; std::optional getRef() const; std::optional getRev() const; std::optional getRevCount() const; std::optional getLastModified() const; /** * For locked inputs, return a string that uniquely specifies the * content of the input (typically a commit hash or content hash). */ std::optional getFingerprint(ref store) const; }; /** * The `InputScheme` represents a type of fetcher. Each fetcher * registers with nix at startup time. When processing an `Input`, * each scheme is given an opportunity to "recognize" that * input from the user-provided url or attributes * and return an `Input` object to represent the input if it is * recognized. The `Input` object contains the information the fetcher * needs to actually perform the `fetch()` when called. */ struct InputScheme { virtual ~InputScheme() { } virtual std::optional inputFromURL(const ParsedURL & url, bool requireTree) const = 0; virtual std::optional inputFromAttrs(const Attrs & attrs) const = 0; /** * What is the name of the scheme? * * The `type` attribute is used to select which input scheme is * used, and then the other fields are forwarded to that input * scheme. */ virtual std::string_view schemeName() const = 0; /** * Allowed attributes in an attribute set that is converted to an * input. * * `type` is not included from this set, because the `type` field is parsed first to choose which scheme; `type` is always required. */ virtual StringSet allowedAttrs() const = 0; virtual ParsedURL toURL(const Input & input) const; virtual Input applyOverrides( const Input & input, std::optional ref, std::optional rev) const; virtual void clone(const Input & input, const Path & destDir) const; virtual std::optional getSourcePath(const Input & input) const; virtual void putFile( const Input & input, const CanonPath & path, std::string_view contents, std::optional commitMsg) const; virtual std::pair fetch(ref store, const Input & input); virtual std::pair, Input> getAccessor(ref store, const Input & input) const; /** * Is this `InputScheme` part of an experimental feature? */ virtual std::optional experimentalFeature() const; virtual bool isDirect(const Input & input) const { return true; } /** * A sufficiently unique string that can be used as a cache key to identify the `input`. * * Only known-equivalent inputs should return the same fingerprint. * * This is not a stable identifier between Nix versions, but not guaranteed to change either. */ virtual std::optional getFingerprint(ref store, const Input & input) const { return std::nullopt; } }; void registerInputScheme(std::shared_ptr && fetcher); nlohmann::json dumpRegisterInputSchemeInfo(); struct PublicKey { std::string type = "ssh-ed25519"; std::string key; }; NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(PublicKey, type, key) std::string publicKeys_to_string(const std::vector&); }