-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
Flake schemas #8892
base: master
Are you sure you want to change the base?
Flake schemas #8892
Conversation
Flake schemas allow us to get rid of output-specific code in commands like `nix flake [show|check|search]`. This is done by allowing flakes to have a `schemas` attribute` that defines how to enumerate the contents of the output (including documentation), and how to check it. In the future, this can be extended to support configurability of flakes in a discoverable way.
This pull request has been mentioned on NixOS Discourse. There might be relevant details there: https://discourse.nixos.org/t/flake-schemas-making-flake-outputs-extensible/32421/1 |
flake.nix
Outdated
@@ -5,8 +5,9 @@ | |||
inputs.nixpkgs-regression.url = "github:NixOS/nixpkgs/215d4d0fd80ca5163643b03a33fde804a29cc1e2"; | |||
inputs.lowdown-src = { url = "github:kristapsdz/lowdown"; flake = false; }; | |||
inputs.flake-compat = { url = "github:edolstra/flake-compat"; flake = false; }; | |||
inputs.flake-schemas.url = github:DeterminateSystems/flake-schemas; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't this be owned by the NixOS organization?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Definitely, if this PR gets accepted.
This comment was marked as duplicate.
This comment was marked as duplicate.
Sorry, something went wrong.
# FIXME: a pre-cached copy of the flake-schemas needs to be built in to the nix binary | ||
defaultSchemas = (builtins.getFlake "github:DeterminateSystems/flake-schemas/3b4d5fef938f698c8737515532a1be53bf6355f2").schemas; | ||
|
||
schemaOverrides = {}; # FIXME |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What does FIXME
mean here for schemaOverrides
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was intended to support adding/overriding (some) schemas from the command line, but I didn't implement that yet.
Considering that the schema returns the children, this defines a new "derivation" centric, tree shaped view of the flake that is determined by the flake itself, as the flake defines the schema. Shouldn't other commands go through the schema then? Otherwise, we are still making assumptions about the schema contents. Should the evaluated schema be exposed to flakes that consume the flake as an input? Do we need the interface between the CLI and the flake need to be schema-like? Why don't we expose the desired functionality directly by defining one or two new outputs that don't rely on the concept of a schema? For example:
Outputs like this seem conceptually simpler to me, and they seem easier to use from within the language. They will be similarly easy to use when the outputs are defined through a library. If we do decide that we need a concept of schema, is the metaschema as simple as it can be, or can it leverage more of the language? |
I didn't think this is intended to be a new view of the flake at all. And it is absolutely not intended to be derivation centric. The real concept being embodied is conceptual outputs that user care about. That is to say: packages, modules, checks, configurations, ci jobs, overlays, deployment definitions, etc. These big picture concept that people would generally hope would show up in The problem, of course, is that there is no simple way to enumerate these artifacts. It is not like these are all top level output attributes. Indeed, they pretty deliberately are mostly not top level attributes, since having some structure makes it possible for tooling to distinguish outputs in useful ways. Most standard output attributes are either attribute sets of these, or attribute sets of attribute sets of these. In practice these artifacts are almost always just nix values that can be reached as an attribute path from output attribute set. Given that in practice in order to use any of these artifacts you need to know how to reference them from an imported flake, it would really make no sense to have the schema define a different tree structure then the output's attributes already have, albeit truncated.
This is a possibility. From a flake authoring perspective, importing evalchecks sounds like a fairly low level thing to be working with, while importing a schema from a flake and assigning that sounds more high level. Similarly from an authoring perspective to add a new schema would be |
I agree about the intent, but it's the details of the design that matter. It is worth repeating that Nix is highly constrained when it comes to making changes, because we've successfully provided compatibility with old expressions, and would like to keep that unique property. While this doesn't apply during the experimental phase of a feature, we will eventually have to judge it by the usual standard before we can call it stable. Another important observation is that the less we do in C++ and the more we do in Nix expressions, we get better opportunities to iterate on our solutions, because users can pin or lock such expressions and adapt to any changes at their own pace, or not at all if we're talking about support for old expressions. Hence I'd take a PR that reifies CLI behavior as an expression-based interface over a PR that introduces new concepts any day - as long as it's clear what the CLI should do, and in case of enumerating and checking that seems rather clear. Extensions to that behavior can be represented by following the dict vs record pattern we've described in the JSON guideline (applied to attrsets instead). |
|
||
Leaf nodes can have the following attributes: | ||
|
||
* `derivation`: The main derivation of this node, if any. It must evaluate for `nix flake check` and `nix flake show` to succeed. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some outputs are not technically a derivation
, but rather a path
, yet they are paths referring to the output of a derivation. apps.*.program
for example. How can they be represented in this schema?
Co-authored-by: Greg Pfeil <[email protected]>
That was causing issues, and now we have a better solution: NixOS/nix#8892
any update on this? i don't think i saw any mention of this on any of the team meetings i glanced through recently |
For what it’s worth we’re using them a lot at determinate systems to good effect.
…On Sat, Feb 24, 2024, at 10:07 AM, Aaron Andersen wrote:
any update on this? i don't think i saw any mention of this on any of the team meetings i glanced through recently
—
Reply to this email directly, view it on GitHub <#8892 (comment)>, or unsubscribe <https://github.com/notifications/unsubscribe-auth/AAASXLEZJUVWTZZFGZSEOX3YVH63XAVCNFSM6AAAAAA4GIL65OVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTSNRSGM4TMNJXGM>.
You are receiving this because you commented.Message ID: ***@***.***>
|
I’ve also had success with them. Here’s a fairly rich schema I use in most of my projects: https://github.com/sellout/project-manager/blob/495cb847eb2cbf6b7981576c3b1610cc077c4768/nix/schemas.nix#L6-L80 |
sounds lovely i wonder what it would take to move forward with this |
That's great to hear. What is the status of y'all moving this forward? |
Forgive my ignorance, but how are people using schemas without the Or are people running a build of this PR branch instead of upstream? |
Flake lock file updates: • Updated input 'flake-schemas': 'github:DeterminateSystems/flake-schemas/764932025c817d4e500a8d2a4d8c565563923d29' (2023-10-16) → 'github:DeterminateSystems/flake-schemas/427266c62c9ed33ad15691a4c5edd3eec46bc129?narHash=sha256-mmVvW7WF39MXuqHdPQwqT6eVmKyapaMAydkw5EBwsGE%3D' (2024-06-25)
Flake lock file updates: • Updated input 'flake-schemas': 'github:DeterminateSystems/flake-schemas/427266c62c9ed33ad15691a4c5edd3eec46bc129?narHash=sha256-mmVvW7WF39MXuqHdPQwqT6eVmKyapaMAydkw5EBwsGE%3D' (2024-06-25) → 'github:DeterminateSystems/flake-schemas/e2723a64e9b2e4e68eed857a470fc6786ff31507?narHash=sha256-twVbB0VtoL21skVW7dv9IjyfAe3RwNJLtRykGKe0SDw%3D' (2024-06-28)
This should be done in the schema.
Flake lock file updates: • Updated input 'flake-schemas': 'github:DeterminateSystems/flake-schemas/e2723a64e9b2e4e68eed857a470fc6786ff31507?narHash=sha256-twVbB0VtoL21skVW7dv9IjyfAe3RwNJLtRykGKe0SDw%3D' (2024-06-28) → 'github:DeterminateSystems/flake-schemas/e647c825db1d60e20d79047d090cbda0e1f25c3d?narHash=sha256-n6UwIart9yr2UhTTNWaQYVlvyXLg/uEJCDj72npf%2BRI%3D' (2024-07-01)
Flake lock file updates: • Updated input 'flake-schemas': 'github:DeterminateSystems/flake-schemas/e647c825db1d60e20d79047d090cbda0e1f25c3d?narHash=sha256-n6UwIart9yr2UhTTNWaQYVlvyXLg/uEJCDj72npf%2BRI%3D' (2024-07-01) → 'github:DeterminateSystems/flake-schemas/61a02d7183d4241962025e6c6307a22a0bb72a21?narHash=sha256-wM%2B8JtoKBkahHiKn%2BEM1ikurMnitwRQrZ91hipJIJK8%3D' (2024-07-01)
No, the schemas reflect what those commands do (e.g. the In the future, some commands could use schemas, e.g.
Assigning a meaning to
Schemas already have some static info (like a |
Discussed in the meeting today. We didn't have a lot of time because we were towards the end of it, so I'll just summarize the thoughts I shared. Naming
Is it possible to export a flake schema into a serializable form? (Or documentation)
|
This uses the still WIP flake schemas feature implemented in NixOS/nix#8892 with our own fix for Intel Mac.
if (auto what = flake_schemas::what(leaf)) | ||
obj.emplace("what", what); | ||
|
||
if (auto shortDescription = flake_schemas::shortDescription(leaf)) | ||
obj.emplace("shortDescription", shortDescription); | ||
|
||
if (auto drv = flake_schemas::derivation(leaf)) | ||
obj.emplace("derivationName", drv->getAttr(state->sName)->getString()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Apart from recognising what
, shortDescription
and derivation
as the leaf
types, it would be nice to also recognise arbitrary values in the configuration.
Perhaps like:
From 1d23c1e871981f5666a12c4409bd0574fc1e1e02 Mon Sep 17 00:00:00 2001
From: shivaraj-bh <[email protected]>
Date: Wed, 21 Aug 2024 15:14:03 +0530
Subject: [PATCH] support value as leaf node
---
src/nix/flake.cc | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/src/nix/flake.cc b/src/nix/flake.cc
index f470d847bf8..6960a3e9e89 100644
--- a/src/nix/flake.cc
+++ b/src/nix/flake.cc
@@ -18,6 +18,7 @@
#include "markdown.hh"
#include "users.hh"
#include "flake-schemas.hh"
+#include "value-to-json.hh"
#include <nlohmann/json.hpp>
#include <queue>
@@ -782,6 +783,13 @@ struct CmdFlakeShow : FlakeCommand, MixJSON, flake_schemas::MixFlakeSchemas
if (auto drv = flake_schemas::derivation(leaf))
obj.emplace("derivationName", drv->getAttr(state->sName)->getString());
+ // TODO: Add a function in flake-schemas.hh to handle this
+ if (auto value = leaf->maybeGetAttr("value")) {
+ auto v = value->forceValue();
+ NixStringContext context;
+ obj.emplace("value", printValueAsJSON(*state, true, v, noPos, context, false));
+ }
+
// FIXME: add more stuff
},
If this is out of scope of this PR, I could raise a separate PR after this is merged, describing the use-case in more detail.
refactor(flake): remove schema code - readd once NixOS/nix#8892 is closed
Is there any rebased version of this branch? |
Motivation
A big problem with current flakes is that commands like
nix flake check
andnix flake show
have built-in support for a limited set of flake output types. For instance, they know aboutnixosConfigurations
but nothomeConfigurations
.This PR moves support for flake output types out of C++ and into Nix functions supplied by a new
schemas
flake output. This allows users to define their own flake output types, and have them show up innix flake show
and checked bynix flake check
. As a result, there are no more flake output types that are more "blessed" than others.There is no central registry of schemas. Instead a flake should add an appropriate
schemas
flake output for the outputs it wants to have checked. Typically this will include schemas from other flakes. In particular, I've made a flake-schemas flake with schemas for the flake output types that were previously built into Nix.The format of schemas is documented in
doc/manual/src/protocols/flake-schemas.md
.To do:
evalChecks
schema attribute need to be refined to allow checkers to return warnings/errors in a more sensible way than an assertion failure.Context
Fixes #3487, #6453, #6454.
Checklist for maintainers
Maintainers: tick if completed or explain if not relevant
tests/**.sh
src/*/tests
tests/nixos/*
Priorities
Add 👍 to pull requests you find important.