diff --git a/lib/jsonschema/default.nix b/lib/jsonschema/default.nix index 66f9b8fe..8c29cf02 100644 --- a/lib/jsonschema/default.nix +++ b/lib/jsonschema/default.nix @@ -17,7 +17,7 @@ let location: ${lib.concatStringsSep "." option.loc} ''; - # Exclude the option if it's type is in the excludedTypes list + # Exclude the option if its type is in the excludedTypes list # or if the option has a defaultText attribute isExcludedOption = option: ((lib.elem (option.type.name or null) excludedTypes) || (option ? defaultText)); @@ -26,6 +26,9 @@ let filterExcludedAttrs = lib.filterAttrs (_name: opt: !isExcludedOption opt); + # Filter out options where the visible attribute is set to false + filterInvisibleOpts = lib.filterAttrs (_name: opt: opt.visible or true); + allBasicTypes = [ "boolean" "integer" @@ -50,7 +53,7 @@ rec { parseOptions = options': let - options = filterExcludedAttrs (clean options'); + options = filterInvisibleOpts (filterExcludedAttrs (clean options')); # parse options to jsonschema properties properties = lib.mapAttrs (_name: option: parseOption option) options; # TODO: figure out how to handle if prop.anyOf is used diff --git a/lib/jsonschema/example-data.json b/lib/jsonschema/example-data.json index 240016f7..9fb8e0cd 100644 --- a/lib/jsonschema/example-data.json +++ b/lib/jsonschema/example-data.json @@ -10,5 +10,11 @@ }, "services": { "opt": "this option doesn't make sense" + }, + "destinations": { + "test-backup": { + "name": "John Doe", + "repo": "test-backup" + } } } diff --git a/lib/jsonschema/example-interface.nix b/lib/jsonschema/example-interface.nix index 97fe4145..0ba65018 100644 --- a/lib/jsonschema/example-interface.nix +++ b/lib/jsonschema/example-interface.nix @@ -50,5 +50,26 @@ ]; description = "A list of enabled kernel modules"; }; + destinations = lib.mkOption { + type = lib.types.attrsOf ( + lib.types.submodule ( + { name, ... }: + { + options = { + name = lib.mkOption { + type = lib.types.strMatching "^[a-zA-Z0-9._-]+$"; + default = name; + description = "the name of the backup job"; + }; + repo = lib.mkOption { + type = lib.types.str; + description = "the borgbackup repository to backup to"; + }; + }; + } + ) + ); + default = { }; + }; }; } diff --git a/lib/jsonschema/example-schema.json b/lib/jsonschema/example-schema.json index 62d68fb1..0073369e 100644 --- a/lib/jsonschema/example-schema.json +++ b/lib/jsonschema/example-schema.json @@ -45,6 +45,27 @@ "description": "A submodule option" } } + }, + "destinations": { + "additionalProperties": { + "properties": { + "name": { + "default": "‹name›", + "description": "the name of the backup job", + "type": "string" + }, + "repo": { + "description": "the borgbackup repository to backup to", + "type": "string" + } + }, + "required": [ + "repo" + ], + "type": "object" + }, + "default": {}, + "type": "object" } } } diff --git a/pkgs/schemas/flake-module.nix b/pkgs/schemas/flake-module.nix index e3f17a0e..a9a81426 100644 --- a/pkgs/schemas/flake-module.nix +++ b/pkgs/schemas/flake-module.nix @@ -7,7 +7,7 @@ # Uncomment if you only want one module to be available # clanModules = { - # syncthing = self.clanModules.syncthing; + # borgbackup = self.clanModules.borgbackup; # }; baseModule = { @@ -30,6 +30,7 @@ ]; }; in + # Filter out "injected" options that are not part of the module if (evaled.options.clan ? "${modulename}") then evaled.options.clan.${modulename} else { }; clanModuleSchemas = lib.mapAttrs ( @@ -46,7 +47,7 @@ checks = { module-schema = pkgs.runCommand "schema-checks" { } '' ${pkgs.check-jsonschema}/bin/check-jsonschema \ - --check-metaschema --fill-defaults ${packages.module-schema} + --check-metaschema ${packages.module-schema} touch $out ''; };