Support flake attr nixosModule
(#401)
* flake_info.nix: remove helper fn `default` Nix has builtin syntax for fetching attrs with a default value. * flake_info.nix: minor refactor - Remove commented out code - Simplify pkg filtering - Break overlong line * flake_info.nix: support flake attr `nixosModule` * Support default modules in rust backend and elm Co-authored-by: Yannik Sander <me@ysndr.de>
This commit is contained in:
parent
32700e3eee
commit
096ea9e49c
|
@ -5,43 +5,32 @@ let
|
|||
nixpkgs = (import <nixpkgs> {});
|
||||
lib = nixpkgs.lib;
|
||||
|
||||
|
||||
default = drv: attr: default: if drv ? ${attr} then drv.${attr} else default;
|
||||
|
||||
# filter = lib.filterAttrs (key: _ : key == "apps" || key == "packages");
|
||||
|
||||
withSystem = fn: lib.mapAttrs (system: drvs: (fn system drvs));
|
||||
isValid = d:
|
||||
let
|
||||
r = builtins.tryEval (lib.isDerivation d && ! (lib.attrByPath [ "meta" "broken" ] false d) && builtins.seq d.name true && d ? outputs);
|
||||
r = builtins.tryEval (lib.isDerivation d && ! (lib.attrByPath [ "meta" "broken" ] false d) &&
|
||||
builtins.seq d.name true && d ? outputs);
|
||||
in
|
||||
r.success && r.value;
|
||||
all = pkgs:
|
||||
let
|
||||
validPkgs = lib.filterAttrs (k: v: isValid v) pkgs;
|
||||
in
|
||||
validPkgs;
|
||||
|
||||
|
||||
validPkgs = lib.filterAttrs (k: v: isValid v);
|
||||
|
||||
readPackages = system: drvs: lib.mapAttrsToList (
|
||||
attribute_name: drv: (
|
||||
# if isValid drv then
|
||||
{
|
||||
attribute_name = attribute_name;
|
||||
system = system;
|
||||
name = drv.name;
|
||||
# TODO consider using `builtins.parseDrvName`
|
||||
version = default drv "version" "";
|
||||
version = drv.version or "";
|
||||
outputs = drv.outputs;
|
||||
# paths = builtins.listToAttrs ( map (output: {name = output; value = drv.${output};}) drv.outputs );
|
||||
}
|
||||
// lib.optionalAttrs (drv ? meta && drv.meta ? description) { inherit (drv.meta) description; }
|
||||
// lib.optionalAttrs (drv ? meta && drv.meta ? license) { inherit (drv.meta) license; }
|
||||
|
||||
# else {}
|
||||
)
|
||||
) (all drvs);
|
||||
) (validPkgs drvs);
|
||||
readApps = system: apps: lib.mapAttrsToList (
|
||||
attribute_name: app: (
|
||||
{
|
||||
|
@ -54,8 +43,7 @@ let
|
|||
)
|
||||
) apps;
|
||||
|
||||
readOptions = modules: isNixOS: let
|
||||
|
||||
readOptions = let
|
||||
declarations = module: (
|
||||
lib.evalModules {
|
||||
modules = (if lib.isList module then module else [ module ]) ++ [
|
||||
|
@ -70,7 +58,7 @@ let
|
|||
}
|
||||
).options;
|
||||
|
||||
cleanUpOption = module: opt:
|
||||
cleanUpOption = extraAttrs: opt:
|
||||
let
|
||||
applyOnAttr = n: f: lib.optionalAttrs (builtins.hasAttr n opt) { ${n} = f opt.${n}; };
|
||||
mkDeclaration = decl:
|
||||
|
@ -96,31 +84,47 @@ let
|
|||
// applyOnAttr "example" substFunction # (_: { __type = "function"; })
|
||||
// applyOnAttr "type" substFunction
|
||||
// applyOnAttr "declarations" (map mkDeclaration)
|
||||
// lib.optionalAttrs (!isNixOS) { flake = [ flake module ]; };
|
||||
|
||||
|
||||
options = lib.mapAttrs (
|
||||
attr: module: let
|
||||
list = lib.optionAttrSetToDocList (declarations module);
|
||||
in
|
||||
map (cleanUpOption attr) (lib.filter (x: !x.internal) list)
|
||||
) modules;
|
||||
// extraAttrs;
|
||||
in
|
||||
lib.flatten (builtins.attrValues options);
|
||||
{ module, modulePath ? null }: let
|
||||
opts = lib.optionAttrSetToDocList (declarations module);
|
||||
extraAttrs = lib.optionalAttrs (modulePath != null) {
|
||||
flake = modulePath;
|
||||
};
|
||||
in
|
||||
map (cleanUpOption extraAttrs) (lib.filter (x: !x.internal) opts);
|
||||
|
||||
readFlakeOptions = let
|
||||
nixosModulesOpts = builtins.concatLists (lib.mapAttrsToList (moduleName: module:
|
||||
readOptions {
|
||||
inherit module;
|
||||
modulePath = [ flake moduleName ];
|
||||
}
|
||||
) (resolved.nixosModules or {}));
|
||||
|
||||
nixosModuleOpts = lib.optionals (resolved ? nixosModule) (
|
||||
readOptions {
|
||||
module = resolved.nixosModule;
|
||||
modulePath = [ flake ];
|
||||
}
|
||||
);
|
||||
in
|
||||
# We assume that `nixosModules` includes `nixosModule` when there
|
||||
# are multiple modules
|
||||
if nixosModulesOpts != [] then nixosModulesOpts else nixosModuleOpts;
|
||||
|
||||
read = reader: set: lib.flatten (lib.attrValues (withSystem reader set));
|
||||
|
||||
legacyPackages' = read readPackages (default resolved "legacyPackages" {});
|
||||
packages' = read readPackages (default resolved "packages" {});
|
||||
legacyPackages' = read readPackages (resolved.legacyPackages or {});
|
||||
packages' = read readPackages (resolved.packages or {});
|
||||
|
||||
apps' = read readApps (default resolved "apps" {});
|
||||
apps' = read readApps (resolved.apps or {});
|
||||
|
||||
|
||||
collectSystems = lib.lists.foldr (
|
||||
drv@{ attribute_name, system, ... }: set:
|
||||
let
|
||||
present = default set "${attribute_name}" ({ platforms = []; } // drv);
|
||||
present = set."${attribute_name}" or ({ platforms = []; } // drv);
|
||||
|
||||
drv' = present // {
|
||||
platforms = present.platforms ++ [ system ];
|
||||
|
@ -138,11 +142,9 @@ rec {
|
|||
legacyPackages = lib.attrValues (collectSystems legacyPackages');
|
||||
packages = lib.attrValues (collectSystems packages');
|
||||
apps = lib.attrValues (collectSystems apps');
|
||||
options = readOptions (default resolved "nixosModules" {}) false;
|
||||
nixos-options = readOptions (
|
||||
{
|
||||
"nixos" = import "${builtins.fetchTarball { url = flake; }}/nixos/modules/module-list.nix";
|
||||
}
|
||||
) true;
|
||||
options = readFlakeOptions;
|
||||
nixos-options = readOptions {
|
||||
module = import "${builtins.fetchTarball { url = flake; }}/nixos/modules/module-list.nix";
|
||||
};
|
||||
all = packages ++ apps ++ options;
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
/// Flakes, or Nixpkgs.
|
||||
use std::{convert::TryInto, path::PathBuf};
|
||||
|
||||
use super::{import::DocValue, pandoc::PandocExt};
|
||||
use super::{import::{DocValue, ModulePath}, pandoc::PandocExt};
|
||||
use crate::data::import::NixOption;
|
||||
use log::error;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
@ -110,7 +110,7 @@ pub enum Derivation {
|
|||
|
||||
option_example: Option<DocValue>,
|
||||
|
||||
option_flake: Option<(String, String)>,
|
||||
option_flake: Option<ModulePath>,
|
||||
},
|
||||
}
|
||||
|
||||
|
|
|
@ -63,8 +63,18 @@ pub struct NixOption {
|
|||
pub default: Option<DocValue>,
|
||||
pub example: Option<DocValue>,
|
||||
|
||||
/// If defined in a flake, contains defining flake and module
|
||||
pub flake: Option<(String, String)>,
|
||||
/// If defined in a flake, contains defining flake and optionally a module
|
||||
pub flake: Option<ModulePath>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
#[serde(untagged)]
|
||||
pub enum ModulePath {
|
||||
/// A module taken from <flake>.nixosModule
|
||||
/// JSON representation is a list, therefore use a 1-Tuple as representation
|
||||
DefaultModule((String,)),
|
||||
/// A module taken from <flake>.nixosModules.<name>
|
||||
NamedModule((String, String)),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Deserialize)]
|
||||
|
@ -345,6 +355,32 @@ mod tests {
|
|||
.collect();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_flake_option() {
|
||||
let json = r#"
|
||||
{
|
||||
"declarations": [],
|
||||
"name": "test-option",
|
||||
"flake": ["flake", "module"]
|
||||
}
|
||||
"#;
|
||||
|
||||
serde_json::from_str::<NixOption>(json).unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_flake_option_default_module() {
|
||||
let json = r#"
|
||||
{
|
||||
"declarations": [],
|
||||
"name": "test-option",
|
||||
"flake": ["flake"]
|
||||
}
|
||||
"#;
|
||||
|
||||
serde_json::from_str::<NixOption>(json).unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_option_parsing() {}
|
||||
}
|
||||
|
|
|
@ -68,7 +68,7 @@ type alias ResultItemSource =
|
|||
, source : Maybe String
|
||||
|
||||
-- flake
|
||||
, flake : Maybe ( String, String )
|
||||
, flake : Maybe (List String)
|
||||
, flakeName : Maybe String
|
||||
, flakeDescription : Maybe String
|
||||
, flakeUrl : Maybe String
|
||||
|
@ -274,17 +274,20 @@ viewResultItem channel _ show item =
|
|||
Maybe.map asGithubLink item.source.source
|
||||
|
||||
flakeOrNixpkgs =
|
||||
case ( item.source.flakeName, item.source.flake, item.source.flakeUrl ) of
|
||||
let
|
||||
mkLink flake url =
|
||||
a [ href url ] [ text flake ]
|
||||
in
|
||||
case ( item.source.flake, item.source.flakeUrl ) of
|
||||
-- its a flake
|
||||
( Just name, Just ( flake, attr ), Just flakeUrl_ ) ->
|
||||
( Just (flake :: []), Just url ) ->
|
||||
Just
|
||||
[ li []
|
||||
[ a [ href flakeUrl_ ] [ text flake ]
|
||||
, text "#"
|
||||
, text attr
|
||||
]
|
||||
[ li [] [ mkLink flake url ]
|
||||
]
|
||||
|
||||
( Just (flake :: moduleName :: []), Just url ) ->
|
||||
Just [ li [] [ mkLink flake url, text "#", text moduleName ] ]
|
||||
|
||||
_ ->
|
||||
Nothing
|
||||
in
|
||||
|
@ -344,12 +347,16 @@ findSource channel source =
|
|||
flakeOrNixpkgs =
|
||||
case ( source.flake, source.flakeUrl ) of
|
||||
-- its a flake
|
||||
( Just ( name, module_ ), Just flakeUrl_ ) ->
|
||||
( Just (name :: attrs), Just flakeUrl_ ) ->
|
||||
let
|
||||
module_ =
|
||||
Maybe.withDefault "(default)" <| Maybe.map (\m -> "(Module: " ++ m ++ ")") <| List.head attrs
|
||||
in
|
||||
Just <|
|
||||
List.append
|
||||
(Maybe.withDefault [] <| Maybe.map (\sourceFile_ -> [ sourceFile_, span [] [ text " in " ] ]) sourceFile)
|
||||
[ span [] [ text "Flake: " ]
|
||||
, a [ href flakeUrl_ ] [ text <| name ++ "(Module: " ++ module_ ++ ")" ]
|
||||
, a [ href flakeUrl_ ] [ text <| name ++ module_ ]
|
||||
]
|
||||
|
||||
( Nothing, _ ) ->
|
||||
|
@ -420,7 +427,7 @@ decodeResultItemSource =
|
|||
|> Json.Decode.Pipeline.optional "option_example" (Json.Decode.map Just Json.Decode.string) Nothing
|
||||
|> Json.Decode.Pipeline.optional "option_source" (Json.Decode.map Just Json.Decode.string) Nothing
|
||||
|> Json.Decode.Pipeline.optional "option_flake"
|
||||
(Json.Decode.map Just <| Json.Decode.map2 Tuple.pair (Json.Decode.index 0 Json.Decode.string) (Json.Decode.index 1 Json.Decode.string))
|
||||
(Json.Decode.map Just <| Json.Decode.list Json.Decode.string)
|
||||
Nothing
|
||||
|> Json.Decode.Pipeline.optional "flake_name" (Json.Decode.map Just Json.Decode.string) Nothing
|
||||
|> Json.Decode.Pipeline.optional "flake_description" (Json.Decode.map Just Json.Decode.string) Nothing
|
||||
|
|
Loading…
Reference in a new issue