-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
What language is flake.nix written in? #4945
Comments
It's a subset of Nix that doesn't allow computation in the flake metadata attributes. So e.g. This should be documented in the flake manpage. |
I marked this as stale due to inactivity. → More info |
Will care about this when the feature gets remotely usable for my use case so please leave this open |
I ran into this and was quite surprised and confused for about half an hour. I used I didn't believe the error message was worded accurately and precisely because I am used to Nix error messages that tell me one type was expected in place of another with little or no further location information and I thought this was one of those cases. An error message something like "file '...' must be written using the limited flake expression language" might have helped me discover my mistake more quickly. Also, none of the docs I read on my way to learning about flakes said anything about this limited expression language so apart from tripping over this error I'm not sure how I would have learned about this. |
This helps NixOS#4945, but I haven't checked all cases are covered by this single error message.
This issue has been mentioned on NixOS Discourse. There might be relevant details there: |
This issue has been mentioned on NixOS Discourse. There might be relevant details there: |
could be awesome if there would be turing decidable(always halt) security attack protected(like infinite reference circular import parsing) nix which allows to be flake input |
This issue has been mentioned on NixOS Discourse. There might be relevant details there: https://discourse.nixos.org/t/flakes-and-pollution-of-downstream-projects/35411/8 |
This issue has a better title and description, but it's a effectively a duplicate of #3966, which has a bunch more discussion. |
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
Let me attempt at a summary here. The problem to solve here is providing access to flake metadata as a plain inert data, which only needs parsing, but not evaluation. If this is not done, than any operation with a flake requires evaluating nix code, which is slow and requires full A negative example for this problem would be the Python ecosystem, where running setup.py is (used to?) required to learn about package dependencies, which could make dependency resolution very slow (as the resolver must sequentially evaluate the graph of transitive dependencies) A positive example would be Rust, where the metadata is available in inert .toml and additionally mirrored in the registry, and, as a result, the tooling is pretty snappy. While inert metadata greatly speeds up and increases the reach of common use-cases, there are also uncommon use-cases which could make use of more computation power for metadata: example Assuming we want to have inert metadata, there are two "dimension" for getting there:
Status quo: a single file is used, with restricted subset of nix for metadata. TOML support was attempted at here: #3966 (comment) |
Notes from myself: Zig is designing a similar system at the moment. The current thinking is to have Disregarding practical implications and thinking from the first principles, using data-only subset of JavaScript (JSON) feels inferior to using data-only subset of nix. |
It seems to me that the opposing sides of this problem are not easily unify-able. on one hand dynamic behavior is really nice in some cases but on the other hand not everyone should always pay this cost. One solution could be template programming:
this way we could:
what we lose:
|
Tried to be clever and hit this with: inputs = let
dep = url: { inherit url; inputs.nixpkgs.follows = "nixpkgs"; };
in {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
nix-darwin = (dep "github:LnL7/nix-darwin");
home-manager = (dep "github:nix-community/home-manager");
zig = (dep "github:Cloudef/nix-zig-stdenv");
zls = (dep "github:zigtools/zls");
hyprland = (dep "github:hyprwm/Hyprland");
eww = (dep "github:elkowar/eww");
}; |
This is already possible by running the more complicated # flake.template.nix
with builtins;
let
toPretty = import (fetchurl
"https://gist.githubusercontent.com/jorsn/012be3e868736359024007fc87b631cf/raw/40bd0d0183215cb6b2cf5ac801559faabee78a0a/prettyUnsafe.nix"
);
#or inherit (toPretty) (getFlake inputs.nixlib.url).lib.generators;
#for less pretty output
genFlake = thisFile: attrs:
attrs // {
flake =
replaceStrings [ "\"<outputs>\"" ] [ "inputs: (import ${thisFile}).outputs inputs" ]
(toPretty "" (attrs // { outputs = "<outputs>"; }))
;
};
in genFlake ./flake.template.nix
{
description = "description";
inputs = let
dep = url: { inherit url; inputs.nixpkgs.follows = "nixpkgs"; };
in {
nixlib.url = "github:nix-community/nixpkgs.lib";
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
nix-darwin = (dep "github:LnL7/nix-darwin");
home-manager = (dep "github:nix-community/home-manager");
zig = (dep "github:Cloudef/nix-zig-stdenv");
zls = (dep "github:zigtools/zls");
hyprland = (dep "github:hyprwm/Hyprland");
eww = (dep "github:elkowar/eww");
};
outputs = inputs: {
};
} For convenience, here is a link to the gist: https://gist.github.com/jorsn/012be3e868736359024007fc87b631cf |
You could avoid some templating by treating None of that should be needed though. We should consider actual solutions within flakes itself. Plain data inputs?Regardless of where and how we represent it, the major use case for this seems to be
So my conclusion thus far is that we could allow Alternatively, in the lock fileAnother, broader solution is to write non-data expressions' outcomes to the lock file. That satisfies the requirement of no evaluation, but it might go out of sync, so it'd be up to you to commit the lock file if you care about others consuming your metadata. Tooling such as CI can help, without being as intrusive as custom templating. Externally consumable flakes should have CI anyway. |
I wrapped my proposal in a flake, to improve ease of use:
Even if we might have a better solution in the future, this is usable now, if anyone is desperate to program flake inputs. |
This issue has been mentioned on NixOS Discourse. There might be relevant details there: |
Rather than saying that a flake is “a subset of nix”, I think it’s generally helpful to describe a .nix file as containing either “a Nix expression” or “Nix data”1. In practice it’s the distinction between whether the contents are evaluated before being acted on. A flake is not evaluated, but the handler for a flake will evaluate portions of it at different times. I think the richness of “Nix data” can be improved without compromising much, though. E.g., let
name = "my-project";
system = "x86_64-linux";
nixpkgsRelease = "24.05";
in {
description = name;
outputs = inputs: {
packages.${system}.${name} = …;
};
inputs.home-manager.url = "github:nix-community/home-manager/release-${nixpkgsRelease}";
inputs.nixpkgs.url = "github:NixOS/nixpkgs/release-${nixpkgsRelease}";
} should only require “normalization”, not evaluation. Since Now, defining (and implementing) what is part of normalization is another question (e.g., should normalization execute But I think regardless of normalization, the data/expression distinction is important and serves a general purpose (and should be documented somewhere so that questions like this can be directed there). Then, instead of talking about “what language” a flake (or some other .nix file) is in, we talk about the “type” of the data. Footnotes
|
This issue may sound silly but it's actually not clear to me what language they are written in.
The syntax and file ending both look like Nix but the manual doesn't apply most of the time.
The manual makes it seem like this should work:
but running that results in
So what language are flake.nix files written in (is there any specification or documentation) and why is that language not Nix?
The text was updated successfully, but these errors were encountered: