forked from lix-project/lix
1ad3328c5e
Previously, for tarball flakes, we recorded the original URL of the tarball flake, rather than the URL to which it ultimately redirects. Thus, a flake URL like http://example.org/patchelf-latest.tar that redirects to http://example.org/patchelf-<revision>.tar was not really usable. We couldn't record the redirected URL, because sites like GitHub redirect to CDN URLs that we can't rely on to be stable. So now we use the redirected URL only if the server returns the `x-nix-is-immutable` or `x-amz-meta-nix-is-immutable` headers in its response.
185 lines
4.9 KiB
C++
185 lines
4.9 KiB
C++
#pragma once
|
|
///@file
|
|
|
|
#include "types.hh"
|
|
#include "hash.hh"
|
|
#include "path.hh"
|
|
#include "attrs.hh"
|
|
#include "url.hh"
|
|
|
|
#include <memory>
|
|
|
|
namespace nix { class Store; }
|
|
|
|
namespace nix::fetchers {
|
|
|
|
struct Tree
|
|
{
|
|
Path actualPath;
|
|
StorePath storePath;
|
|
};
|
|
|
|
struct InputScheme;
|
|
|
|
/**
|
|
* The Input object is generated by a specific fetcher, based on the
|
|
* user-supplied input attribute in the flake.nix file, 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 which are provided
|
|
* the url or attrset specified in the flake file.
|
|
*/
|
|
struct Input
|
|
{
|
|
friend struct InputScheme;
|
|
|
|
std::shared_ptr<InputScheme> scheme; // note: can be null
|
|
Attrs attrs;
|
|
bool locked = false;
|
|
bool direct = true;
|
|
|
|
/**
|
|
* path of the parent of this input, used for relative path resolution
|
|
*/
|
|
std::optional<Path> parent;
|
|
|
|
public:
|
|
static Input fromURL(const std::string & url);
|
|
|
|
static Input fromURL(const ParsedURL & url);
|
|
|
|
static Input fromAttrs(Attrs && attrs);
|
|
|
|
ParsedURL toURL() const;
|
|
|
|
std::string toURLString(const std::map<std::string, std::string> & 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 { return direct; }
|
|
|
|
/**
|
|
* Check whether this is a "locked" input, that is,
|
|
* one that contains a commit hash or content hash.
|
|
*/
|
|
bool isLocked() const { return locked; }
|
|
|
|
/**
|
|
* Check whether the input carries all necessary info required
|
|
* for cache insertion and substitution.
|
|
* These fields are used to uniquely identify cached trees
|
|
* within the "tarball TTL" window without necessarily
|
|
* indicating that the input's origin is unchanged.
|
|
*/
|
|
bool hasAllInfo() const;
|
|
|
|
bool operator ==(const Input & other) const;
|
|
|
|
bool contains(const Input & other) const;
|
|
|
|
/**
|
|
* Fetch the input into the Nix store, returning the location in
|
|
* the Nix store and the locked input.
|
|
*/
|
|
std::pair<Tree, Input> fetch(ref<Store> store) const;
|
|
|
|
Input applyOverrides(
|
|
std::optional<std::string> ref,
|
|
std::optional<Hash> rev) const;
|
|
|
|
void clone(const Path & destDir) const;
|
|
|
|
std::optional<Path> getSourcePath() const;
|
|
|
|
void markChangedFile(
|
|
std::string_view file,
|
|
std::optional<std::string> commitMsg) const;
|
|
|
|
std::string getName() const;
|
|
|
|
StorePath computeStorePath(Store & store) const;
|
|
|
|
// Convenience functions for common attributes.
|
|
std::string getType() const;
|
|
std::optional<Hash> getNarHash() const;
|
|
std::optional<std::string> getRef() const;
|
|
std::optional<Hash> getRev() const;
|
|
std::optional<uint64_t> getRevCount() const;
|
|
std::optional<time_t> getLastModified() const;
|
|
};
|
|
|
|
|
|
/**
|
|
* The InputScheme represents a type of fetcher. Each fetcher
|
|
* registers with nix at startup time. When processing an input for a
|
|
* flake, each scheme is given an opportunity to "recognize" that
|
|
* input from the url or attributes in the flake file's specification
|
|
* 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<Input> inputFromURL(const ParsedURL & url) const = 0;
|
|
|
|
virtual std::optional<Input> inputFromAttrs(const Attrs & attrs) const = 0;
|
|
|
|
virtual ParsedURL toURL(const Input & input) const;
|
|
|
|
virtual bool hasAllInfo(const Input & input) const = 0;
|
|
|
|
virtual Input applyOverrides(
|
|
const Input & input,
|
|
std::optional<std::string> ref,
|
|
std::optional<Hash> rev) const;
|
|
|
|
virtual void clone(const Input & input, const Path & destDir) const;
|
|
|
|
virtual std::optional<Path> getSourcePath(const Input & input);
|
|
|
|
virtual void markChangedFile(const Input & input, std::string_view file, std::optional<std::string> commitMsg);
|
|
|
|
virtual std::pair<StorePath, Input> fetch(ref<Store> store, const Input & input) = 0;
|
|
};
|
|
|
|
void registerInputScheme(std::shared_ptr<InputScheme> && fetcher);
|
|
|
|
struct DownloadFileResult
|
|
{
|
|
StorePath storePath;
|
|
std::string etag;
|
|
std::string effectiveUrl;
|
|
std::optional<std::string> immutableUrl;
|
|
};
|
|
|
|
DownloadFileResult downloadFile(
|
|
ref<Store> store,
|
|
const std::string & url,
|
|
const std::string & name,
|
|
bool locked,
|
|
const Headers & headers = {});
|
|
|
|
struct DownloadTarballResult
|
|
{
|
|
Tree tree;
|
|
time_t lastModified;
|
|
std::optional<std::string> immutableUrl;
|
|
};
|
|
|
|
DownloadTarballResult downloadTarball(
|
|
ref<Store> store,
|
|
const std::string & url,
|
|
const std::string & name,
|
|
bool locked,
|
|
const Headers & headers = {});
|
|
|
|
}
|