|
Nix 2.93.3
Lix: A modern, delicious implementation of the Nix package manager; unstable internal interfaces
|
R""(
nix flake provides subcommands for creating, modifying and querying Nix flakes. Flakes are the unit for packaging Nix code in a reproducible and discoverable way. They can have dependencies on other flakes, making it possible to have multi-repository Nix projects.
A flake is a filesystem tree (typically fetched from a Git repository or a tarball) that contains a file named flake.nix in the root directory. flake.nix specifies some metadata about the flake such as dependencies (called inputs), as well as its outputs (the Nix values such as packages or NixOS modules provided by the flake).
Flake references (flakerefs) are a way to specify the location of a flake. These have two different forms:
Example:
The only required attribute is type. The supported types are listed below.
Example:
These are used on the command line as a more convenient alternative to the attribute set representation. For instance, in the command
github:NixOS/nixpkgs is a flake reference (while hello is an output attribute). They are also allowed in the inputs attribute of a flake, e.g.
is equivalent to
Here are some examples of flake references in their URL-like representation:
Flakes corresponding to a local path can also be referred to by a direct path reference, either /absolute/path/to/the/flake or ./relative/path/to/the/flake (note that the leading ./ is mandatory for relative paths to avoid any ambiguity).
The semantic of such a path is as follows:
The following generic flake reference attributes are supported:
In addition, the following attributes are common to several flake reference types:
ref: A Git or Mercurial branch or tag name.
On Git, this is the branch on which the rev commit appears.
Finally, some attribute are typically not specified by the user, but can occur in locked flake references and are available to Nix code:
Currently the type attribute can be one of the following:
path: arbitrary local directories, or local Git trees. The required attribute path specifies the path of the flake. The URL form is
where path is an absolute path.
path must be a directory in the file system containing a file named flake.nix.
path generally must be an absolute path. However, on the command line, it can be a relative path (e.g. . or ./foo) which is interpreted as relative to the current directory. In this case, it must start with . to avoid ambiguity with registry lookups (e.g. nixpkgs is a registry lookup; ./nixpkgs is a relative path).
git: Git repositories. The location of the repository is specified by the attribute url.
They have the URL form
The ref attribute defaults to resolving the HEAD reference.
The rev attribute must denote a commit that exists in the branch or tag specified by the ref attribute, since Lix doesn't do a full clone of the remote repository by default (and the Git protocol doesn't allow fetching a rev without a known ref). The default is the commit currently pointed to by ref.
When git+file is used without specifying ref or rev, files are fetched directly from the local path as long as they have been added to the Git repository. If there are uncommitted changes, the reference is treated as dirty and a warning is printed.
For example, the following are valid Git flake references:
tarball: Tarballs. The location of the tarball is specified by the attribute url.
In URL form, the schema must be tarball+http://, tarball+https:// or tarball+file://. If the extension corresponds to a known archive format (.zip, .tar, .tgz, .tar.gz, .tar.xz, .tar.bz2 or .tar.zst), then the tarball+ can be dropped.
These URLs can indicate an immutable version's URL via the HTTP Link header in a response or any redirect leading up to it; see the Lockable HTTP Tarball Protocol in the manual for details. This protocol is used by several services on the Internet to rewrite an unlocked URL to a locked one. For example, it is supported by the archive URLs on Forgejo: https://git.lix.systems/lix-project/lix/archive/main.tar.gz works as a stable flake input.
file: Plain files or directory tarballs, either over http(s) or from the local disk.
In URL form, the schema must be file+http://, file+https:// or file+file://. If the extension doesn’t correspond to a known archive format (as defined by the tarball fetcher), then the file+ prefix can be dropped.
github: A more efficient way to fetch repositories from GitHub. The following attributes are required:
These are downloaded as tarball archives, rather than through Git. This is often much faster and uses less disk space since it doesn't require fetching the entire history of the repository. On the other hand, it doesn't allow incremental fetching (but full downloads are often faster than incremental fetches!).
The URL syntax for github flakes is:
<rev-or-ref> specifies the name of a branch or tag (ref), or a commit hash (rev). Note that unlike Git, GitHub allows fetching by commit hash without specifying a branch or tag.
You can also specify host as a parameter, to point to a custom GitHub Enterprise server.
Some examples:
gitlab: Similar to github, is a more efficient way to fetch GitLab repositories. The following attributes are required:
Like github, these are downloaded as tarball archives.
The URL syntax for gitlab flakes is:
gitlab:<owner>/<repo>(/<rev-or-ref>)?(\?<params>)?
<rev-or-ref> works the same as github. Either a branch or tag name (ref), or a commit hash (rev) can be specified.
Since GitLab allows for self-hosting, you can specify host as a parameter, to point to any instances other than gitlab.com.
Some examples:
When accessing a project in a (nested) subgroup, make sure to URL-encode any slashes, i.e. replace / with %2F:
sourcehut: Similar to github, is a more efficient way to fetch SourceHut repositories. The following attributes are required:
Like github, these are downloaded as tarball archives.
The URL syntax for sourcehut flakes is:
sourcehut:<owner>/<repo>(/<rev-or-ref>)?(\?<params>)?
<rev-or-ref> works the same as github. Either a branch or tag name (ref), or a commit hash (rev) can be specified.
Since SourceHut allows for self-hosting, you can specify host as a parameter, to point to any instances other than git.sr.ht.
Currently, ref name resolution only works for Git repositories. You can refer to Mercurial repositories by simply changing host to hg.sr.ht (or any other Mercurial instance). With the caveat that you must explicitly specify a commit hash (rev).
Some examples:
indirect: Indirections through the flake registry. These have the form
These perform a lookup of <flake-id> in the flake registry. For example, nixpkgs and nixpkgs/release-20.09 are indirect flake references. The specified rev and/or ref are merged with the entry in the registry; see nix registry for details.
As an example, here is a simple flake.nix that depends on the Nixpkgs flake and provides a single package (i.e. an installable derivation):
The following attributes are supported in flake.nix:
outputs: A function that, given an attribute set containing the outputs of each of the input flakes keyed by their identifier, yields the Nix values provided by this flake. Thus, in the example above, inputs.nixpkgs contains the result of the call to the outputs function of the nixpkgs flake.
In addition to the outputs of each input, each input in inputs also contains some metadata about the inputs. These are:
The value returned by the outputs function must be an attribute set. The attributes can have arbitrary values; however, various nix subcommands require specific attributes to have a specific value (e.g. packages.x86_64-linux must be an attribute set of derivations built for the x86_64-linux platform).
nixConfig: a set of nix.conf options to be set when evaluating any part of a flake. This attribute is only considered if the flake is at top-level (i.e. if it is passed directly to nix build, nix run, etc, rather than as an input of another flake). In the interests of security, only a small set of set of options is allowed to be set without confirmation so long as accept-flake-config is not enabled in the global configuration:
For the avoidance of doubt, setting accept-flake-config in nix.conf or passing --accept-flake-config allows root access to your machine if you are running as a trusted user and don't read nixConfig in every flake you build.
The attribute inputs specifies the dependencies of a flake, as an attrset mapping input names to flake references. For example, the following specifies a dependency on the nixpkgs and import-cargo repositories:
Alternatively, you can use the URL-like syntax:
Each input is fetched, evaluated and passed to the outputs function as a set of attributes with the same name as the corresponding input. The special input named self refers to the outputs and source tree of this flake. Thus, a typical outputs function looks like this:
It is also possible to omit an input entirely and only list it as expected function argument to outputs. Thus,
without an inputs.nixpkgs attribute is equivalent to
Repositories that don't contain a flake.nix can also be used as inputs, by setting the input's flake attribute to false:
Transitive inputs can be overridden from a flake.nix file. For example, the following overrides the nixpkgs input of the nixops input:
It is also possible to "inherit" an input from another input. This is useful to minimize flake dependencies. For example, the following sets the nixpkgs input of the top-level flake to be equal to the nixpkgs input of the dwarffs input of the top-level flake:
The value of the follows attribute is a /-separated sequence of input names denoting the path of inputs to be followed from the root flake.
Overrides and follows can be combined, e.g.
sets the nixpkgs input of nixops to be the same as the nixpkgs input of dwarffs. It is worth noting, however, that it is generally not useful to eliminate transitive nixpkgs flake inputs in this way. Most flakes provide their functionality through Nixpkgs overlays or NixOS modules, which are composed into the top-level flake's nixpkgs input; so their own nixpkgs input is usually irrelevant.
Inputs specified in flake.nix are typically "unlocked" in the sense that they don't specify an exact revision. To ensure reproducibility, Nix will automatically generate and use a lock file called flake.lock in the flake's directory. The lock file contains a graph structure isomorphic to the graph of dependencies of the root flake. Each node in the graph (except the root node) maps the (usually) unlocked input specifications in flake.nix to locked input specifications. Each node also contains some metadata, such as the dependencies (outgoing edges) of the node.
For example, if flake.nix has the inputs in the example above, then the resulting lock file might be:
This graph has 4 nodes: the root flake, and its 3 dependencies. The nodes have arbitrary labels (e.g. n1). The label of the root node of the graph is specified by the root attribute. Nodes contain the following fields:
locked: The locked input specification, as a set of builtins.fetchTree arguments. Thus, in the example above, when we build this flake, the input nixpkgs is mapped to revision 7f8d4b088e2df7fdb6b513bc2d6941f1d422a013 of the edolstra/nixpkgs repository on GitHub.
It also includes the attribute narHash, specifying the expected contents of the tree in the Nix store (as computed by nix hash-path), and may include input-type-specific attributes such as the lastModified or revCount. The main reason for these attributes is to allow flake inputs to be substituted from a binary cache: narHash allows the store path to be computed, while the other attributes are necessary because they provide information not stored in the store path.
The original and locked attributes are omitted for the root node. This is because we cannot record the commit hash or content hash of the root flake, since modifying flake.lock will invalidate these.
The graph representation of lock files allows circular dependencies between flakes. For example, here are two flakes that reference each other:
and
Lock files transitively lock direct as well as indirect dependencies. That is, if a lock file exists and is up to date, Nix will not look at the lock files of dependencies. However, lock file generation itself does use the lock files of dependencies by default.
)""