Flake schemas: Making flake outputs extensible
Flakes are a generic solution to bundle Nix artifacts.
Flake output attributes are arbitrary Nix values, to allow them to be packages, NixOS modules, CI jobs, and so forth.
Whereas there are a selection of “well-known” flake output varieties which can be acknowledged by instruments just like the nix
CLI—nix develop
, for instance, operates on the devShells
output—nothing prevents you from defining your personal flake output varieties.
Sadly, such “non-standard” flake output varieties have a giant drawback: instruments like nix flake show
and nix flake check
do not know something about them, to allow them to’t show or test something about these outputs.
The nixpkgs
flake, for example, has a lib
output that Nix is aware of nothing about:
github:NixOS/nixpkgs/4ecab3273592f27479a583fb6d975d4aba3486fe
├───...
└───lib: unknown
This was an issue once we have been creating FlakeHub: the FlakeHub net interface ought to be capable of show the contents of a flake, together with documentation, however we wish to achieve this in an extensible approach.
Right now we’re proposing an answer to this drawback: flake schemas.
Flake schemas allow flakes to declare features that enumerate and test the contents of their outputs.
Schemas themselves are outlined as a flake output named schemas
.
Instruments like nix flake test
and FlakeHub can then use these schemas to show or test the contents of flakes in a generic approach.
On this method, flakes carry their very own schema definitions, so you aren’t depending on some central registry of schema definitions—you outline what your flake outputs are purported to appear like.
Right here is an instance of what the outputs of a flake, extracted utilizing that flake’s schemas, appear like in FlakeHub:
Whilst you can outline your personal schema definition (see beneath), normally you’d use schema definitions supplied by others.
We offer a repository named flake-schemas
with schemas for probably the most broadly used flake outputs (those for which Nix has built-in help).
Declaring what schemas to make use of is straightforward: you simply outline a schemas
output.
{
inputs.flake-schemas.url = github:DeterminateSystems/flake-schemas;
inputs.different-schemas.url = ...;
outputs = { self, flake-schemas, different-schemas }: {
schemas = flake-schemas.schemas // different-schemas.schemas;
packages = ...;
devShells = ...;
};
}
With schemas, we are able to now train Nix concerning the lib
output talked about beforehand. Under is a flake that has a lib
output.
Just like lib
in Nixpkgs, it has a nested construction (e.g. it gives a perform lists.singleton
).
The flake additionally has a schemas.lib
attribute that tells Nix two issues:
- Find out how to checklist the contents of the
lib
output. - To test that each perform identify follows the camelCase naming conference.
{
outputs = { self }: {
schemas.lib = {
model = 1;
doc = ''
The `lib` flake output defines Nix features.
'';
stock = output:
let
recurse = attrs: {
youngsters = builtins.mapAttrs (attrName: attr:
if builtins.isFunction attr
then
{
what = "library perform";
evalChecks.camelCase = builtins.match "^[a-z][a-zA-Z]*$" attrName == [];
}
else if builtins.isAttrs attr
then
recurse attr
else
throw "unsupported 'lib' sort")
attrs;
};
in recurse output;
};
lib.id = x: x;
lib.const = x: y: x;
lib.lists.singleton = x: [x];
};
}
With this schema, nix flake present
can now present details about lib
:
git+file:///house/eelco/Determinate/flake-schemas/lib-test
└───lib
├───const: library perform
├───id: library perform
└───lists
└───singleton: library perform
Whereas nix flake test
will now complain if we add a perform that violates the naming conference we outlined:
warning: Analysis test 'camelCase' of flake output attribute 'lib.ConcatStrings' failed.
For extra data on the way to write schema definitions, see the Nix documentation.
Flake schemas should not a kind system for Nix, since that will be an enormous mission.
They merely present an interface that allows customers to inform Nix the way to enumerate and test flake outputs.
As an illustration, for a NixOS configuration, this implies utilizing the module system to test that the configuration evaluates accurately; for a Nix bundle, it simply implies that the output attribute evaluates to a derivation.
Flake schemas are new, they usually’re a useful growth of the consumer expertise of FlakeHub and Nix flakes generally.
We consider that incorporating schemas into Nix itself will make flakes extra broadly useful and canopy use circumstances that we have not but imagined.
We’re on the lookout for enter from the neighborhood to see whether or not the present schema design covers all use circumstances.
We have submitted a pull request to the Nix project that provides schema help to nix flake show
and nix flake check
.
Please have a look!
As future work, schemas will allow us to lastly make flakes configurable in a discoverable approach: flake schemas can return the configuration choices supported by a flake output—for the nixosConfigurations
output, for instance, these could be all of the NixOS choices—after which the Nix CLI can allow customers to override choices from the command line.
Flake schemas resolve a long-standing drawback with flakes: the truth that Nix at present has built-in help for a solely small set of output varieties, which made these outputs extra equal than others.
With schemas, all flake output varieties are on an equal footing.