From b0f22d7662aa7c443f8d3ea4f4eeb8f7658e973f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Thu, 9 Feb 2023 14:40:18 +0000 Subject: [PATCH] Validate devenv.yaml schema and move overlays to inputs --- docs/reference/yaml-options.md | 3 ++- examples/overlays/devenv.yaml | 7 +++--- src/devenv-yaml.nix | 43 ++++++++++++++++++++++++++++++++++ src/devenv.nix | 4 ++-- src/flake.nix | 13 +++++----- 5 files changed, 57 insertions(+), 13 deletions(-) create mode 100644 src/devenv-yaml.nix diff --git a/docs/reference/yaml-options.md b/docs/reference/yaml-options.md index 2b4e18a4e..d796a64a4 100644 --- a/docs/reference/yaml-options.md +++ b/docs/reference/yaml-options.md @@ -6,8 +6,9 @@ | inputs.<name> | Identifier name used when passing the input in your ``devenv.nix`` function. | | inputs.<name>.url | URI specification of the input, see below for possible values. | | inputs.<name>.flake | Does the input contain ``flake.nix`` or ``devenv.nix``. Defaults to ``true``. | +| inputs.<name>.overlays | A list of overlays to include from the input. | | imports | A list of relative paths or references to inputs to import ``devenv.nix``. | -| overlays | Names of inputs with a list of overlays to include. | + ## inputs.<name>.url diff --git a/examples/overlays/devenv.yaml b/examples/overlays/devenv.yaml index 81e68cd8c..205510e49 100644 --- a/examples/overlays/devenv.yaml +++ b/examples/overlays/devenv.yaml @@ -1,9 +1,8 @@ +allowUnfree: true inputs: nixpkgs: url: github:NixOS/nixpkgs/nixpkgs-unstable rust-overlay: url: github:oxalica/rust-overlay -allowUnfree: true -overlays: - rust-overlay: - - default \ No newline at end of file + overlays: + - default \ No newline at end of file diff --git a/src/devenv-yaml.nix b/src/devenv-yaml.nix new file mode 100644 index 000000000..ff675c480 --- /dev/null +++ b/src/devenv-yaml.nix @@ -0,0 +1,43 @@ +{ pkgs }: + +pkgs.writers.writePython3Bin "devenv-yaml" { libraries = with pkgs.python3Packages; [ strictyaml path ]; } '' + from strictyaml import Map, MapPattern, Str, Seq + from strictyaml import load, Bool, Any, Optional, YAMLError + import json + import sys + import os + from path import Path + + inputsSchema = MapPattern(Str(), Map({ + "url": Str(), + Optional("flake", default=None): Bool(), + Optional("inputs", default=None): Any(), + Optional("overlays", default=None): Seq(Str()) + })) + + schema = Map({ + Optional("inputs", default=None): inputsSchema, + Optional("allowUnfree", default=False): Bool(), + Optional("imports", default=None): Seq(Str()) + }) + + filename = Path("devenv.yaml").bytes().decode('utf8') + try: + devenv = load(filename, schema, label="devenv.yaml").data + except YAMLError as error: + print("Error in `devenv.yaml`", error) + sys.exit(1) + + inputs = {} + for input, attrs in devenv['inputs'].items(): + inputs[input] = {k: attrs[k] for k in ('url', 'inputs', 'flake') + if k in attrs} + + devenv_state = sys.argv[1] + + with open(os.path.join(devenv_state, "flake.json"), 'w') as f: + f.write(json.dumps(inputs)) + + with open(os.path.join(devenv_state, "devenv.json"), 'w') as f: + f.write(json.dumps(devenv)) +'' diff --git a/src/devenv.nix b/src/devenv.nix index c1a20590d..ecdbcf8de 100644 --- a/src/devenv.nix +++ b/src/devenv.nix @@ -29,11 +29,11 @@ pkgs.writeScriptBin "devenv" '' export DEVENV_DIR="$(pwd)/.devenv" export DEVENV_GC="$DEVENV_DIR/gc" mkdir -p "$DEVENV_GC" - # TODO: validate devenv.yaml using jsonschema if [[ -f devenv.yaml ]]; then - cat devenv.yaml | ${pkgs.yaml2json}/bin/yaml2json > "$DEVENV_DIR/devenv.json" + ${import ./devenv-yaml.nix { inherit pkgs; }}/bin/devenv-yaml "$DEVENV_DIR" else [[ -f "$DEVENV_DIR/devenv.json" ]] && rm "$DEVENV_DIR/devenv.json" + [[ -f "$DEVENV_DIR/flake.json" ]] && rm "$DEVENV_DIR/flake.json" fi cp -f ${import ./flake.nix { inherit pkgs version; }} "$FLAKE_FILE" chmod +w "$FLAKE_FILE" diff --git a/src/flake.nix b/src/flake.nix index 08f07e13b..468b32197 100644 --- a/src/flake.nix +++ b/src/flake.nix @@ -5,8 +5,8 @@ pre-commit-hooks.inputs.nixpkgs.follows = "nixpkgs"; nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; devenv.url = "github:cachix/devenv?dir=src/modules"; - } // (if builtins.pathExists ./.devenv/devenv.json - then (builtins.fromJSON (builtins.readFile ./.devenv/devenv.json)).inputs + } // (if builtins.pathExists ./.devenv/flake.json + then builtins.fromJSON (builtins.readFile ./.devenv/flake.json) else {}); outputs = { nixpkgs, ... }@inputs: @@ -14,11 +14,12 @@ devenv = if builtins.pathExists ./.devenv/devenv.json then builtins.fromJSON (builtins.readFile ./.devenv/devenv.json) else {}; - getOverlays = inputName: overlays: - map (overlay: let + getOverlays = inputName: inputAttrs: + map (overlay: let input = inputs.''${inputName} or (throw "No such input `''${inputName}` while trying to configure overlays."); - in input.overlays.''${overlay} or (throw "Input `''${inputName}` has no overlay called `''${overlay}`. Supported overlays: ''${nixpkgs.lib.concatStringsSep ", " (builtins.attrNames input.overlays)}")) overlays; - overlays = nixpkgs.lib.flatten (nixpkgs.lib.mapAttrsToList getOverlays (devenv.overlays or {})); + in input.overlays.''${overlay} or (throw "Input `''${inputName}` has no overlay called `''${overlay}`. Supported overlays: ''${nixpkgs.lib.concatStringsSep ", " (builtins.attrNames input.overlays)}")) + inputAttrs.overlays or []; + overlays = nixpkgs.lib.flatten (nixpkgs.lib.mapAttrsToList getOverlays (devenv.inputs or {})); pkgs = import nixpkgs { system = "${pkgs.system}"; allowUnfree = devenv.allowUnfree or false;