lib/values: fix submodule definition merging
This commit is contained in:
@@ -23,11 +23,9 @@ let
|
|||||||
prio = {
|
prio = {
|
||||||
__prio = opt.highestPrio;
|
__prio = opt.highestPrio;
|
||||||
};
|
};
|
||||||
subOptions = opt.type.getSubOptions opt.loc;
|
filteredSubOptions = filterOptions (opt.type.getSubOptions opt.loc);
|
||||||
|
|
||||||
attrDefinitions = (lib.modules.mergeAttrDefinitionsWithPrio opt);
|
zipDefs = builtins.zipAttrsWith (_: vs: vs);
|
||||||
zipDefs = builtins.zipAttrsWith (_ns: vs: vs);
|
|
||||||
defs = zipDefs opt.definitions;
|
|
||||||
|
|
||||||
prioPerValue =
|
prioPerValue =
|
||||||
{ type, defs }:
|
{ type, defs }:
|
||||||
@@ -35,7 +33,7 @@ let
|
|||||||
attrName: prioSet:
|
attrName: prioSet:
|
||||||
let
|
let
|
||||||
# Evaluate the submodule
|
# Evaluate the submodule
|
||||||
options = filterOptions subOptions;
|
options = filteredSubOptions;
|
||||||
modules = (
|
modules = (
|
||||||
[
|
[
|
||||||
{ inherit options; }
|
{ inherit options; }
|
||||||
@@ -48,7 +46,6 @@ let
|
|||||||
in
|
in
|
||||||
(lib.optionalAttrs (prioSet ? highestPrio) {
|
(lib.optionalAttrs (prioSet ? highestPrio) {
|
||||||
__prio = prioSet.highestPrio;
|
__prio = prioSet.highestPrio;
|
||||||
# inherit defs options;
|
|
||||||
})
|
})
|
||||||
// (
|
// (
|
||||||
if type.nestedTypes.elemType.name == "submodule" then
|
if type.nestedTypes.elemType.name == "submodule" then
|
||||||
@@ -64,21 +61,30 @@ let
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
attributePrios = prioPerValue {
|
submodulePrios =
|
||||||
type = opt.type;
|
let
|
||||||
inherit defs;
|
options = filteredSubOptions;
|
||||||
} attrDefinitions;
|
modules = (
|
||||||
|
[
|
||||||
|
{ inherit options; }
|
||||||
|
]
|
||||||
|
++ opt.definitions
|
||||||
|
);
|
||||||
|
submoduleEval = lib.evalModules {
|
||||||
|
inherit modules;
|
||||||
|
};
|
||||||
|
in
|
||||||
|
getPrios { options = filterOptions submoduleEval.options; };
|
||||||
|
|
||||||
in
|
in
|
||||||
if opt ? type && opt.type.name == "submodule" then
|
if opt ? type && opt.type.name == "submodule" then
|
||||||
prio // (getPrios { options = subOptions; })
|
(prio) // submodulePrios
|
||||||
else if opt ? type && opt.type.name == "attrsOf" then
|
else if opt ? type && opt.type.name == "attrsOf" then
|
||||||
# prio // attributePrios
|
prio // (
|
||||||
# else if
|
prioPerValue {
|
||||||
# opt ? type && opt.type.name == "attrsOf" && opt.type.nestedTypes.elemType.name == "attrsOf"
|
type = opt.type;
|
||||||
# then
|
defs = zipDefs opt.definitions;
|
||||||
# prio // attributePrios
|
} (lib.modules.mergeAttrDefinitionsWithPrio opt))
|
||||||
# else if opt ? type && opt.type.name == "attrsOf" then
|
|
||||||
prio // attributePrios
|
|
||||||
else if opt ? type && opt._type == "option" then
|
else if opt ? type && opt._type == "option" then
|
||||||
prio
|
prio
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -80,6 +80,56 @@ in
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
test_submodule_with_merging =
|
||||||
|
let
|
||||||
|
evaluated = (
|
||||||
|
eval [
|
||||||
|
{
|
||||||
|
options.foo = lib.mkOption {
|
||||||
|
type = lib.types.submodule {
|
||||||
|
options = {
|
||||||
|
normal = lib.mkOption {
|
||||||
|
type = lib.types.bool;
|
||||||
|
};
|
||||||
|
default = lib.mkOption {
|
||||||
|
type = lib.types.bool;
|
||||||
|
};
|
||||||
|
optionDefault = lib.mkOption {
|
||||||
|
type = lib.types.bool;
|
||||||
|
default = true;
|
||||||
|
};
|
||||||
|
unset = lib.mkOption {
|
||||||
|
type = lib.types.bool;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
{
|
||||||
|
foo.default = lib.mkDefault true;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
foo.normal = false;
|
||||||
|
}
|
||||||
|
]
|
||||||
|
);
|
||||||
|
in
|
||||||
|
{
|
||||||
|
inherit evaluated;
|
||||||
|
expr = slib.getPrios {
|
||||||
|
options = evaluated.options;
|
||||||
|
};
|
||||||
|
expected = {
|
||||||
|
foo = {
|
||||||
|
__prio = 100;
|
||||||
|
normal.__prio = 100; # Set via other module
|
||||||
|
default.__prio = 1000;
|
||||||
|
optionDefault.__prio = 1500;
|
||||||
|
unset.__prio = 9999;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
# TODO(@hsjobeki): Cover this edge case
|
# TODO(@hsjobeki): Cover this edge case
|
||||||
# test_freeform =
|
# test_freeform =
|
||||||
# let
|
# let
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ export const MachineListItem = (props: MachineListItemProps) => {
|
|||||||
}
|
}
|
||||||
if (!info?.deploy?.targetHost) {
|
if (!info?.deploy?.targetHost) {
|
||||||
toast.error(
|
toast.error(
|
||||||
"Machine does not have a target host. Specify where the machine should be deployed."
|
"Machine does not have a target host. Specify where the machine should be deployed.",
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -63,7 +63,7 @@ export const MachineListItem = (props: MachineListItemProps) => {
|
|||||||
loading: "Installing...",
|
loading: "Installing...",
|
||||||
success: "Installed",
|
success: "Installed",
|
||||||
error: "Failed to install",
|
error: "Failed to install",
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
setInstalling(false);
|
setInstalling(false);
|
||||||
};
|
};
|
||||||
@@ -80,7 +80,7 @@ export const MachineListItem = (props: MachineListItemProps) => {
|
|||||||
}
|
}
|
||||||
if (!info?.deploy.targetHost) {
|
if (!info?.deploy.targetHost) {
|
||||||
toast.error(
|
toast.error(
|
||||||
"Machine does not have a target host. Specify where the machine should be deployed."
|
"Machine does not have a target host. Specify where the machine should be deployed.",
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -101,7 +101,7 @@ export const MachineListItem = (props: MachineListItemProps) => {
|
|||||||
loading: "Updating...",
|
loading: "Updating...",
|
||||||
success: "Updated",
|
success: "Updated",
|
||||||
error: "Failed to update",
|
error: "Failed to update",
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
setUpdating(false);
|
setUpdating(false);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ const InstallMachine = (props: InstallMachineProps) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const loading_toast = toast.loading(
|
const loading_toast = toast.loading(
|
||||||
"Installing machine. Grab coffee (15min)..."
|
"Installing machine. Grab coffee (15min)...",
|
||||||
);
|
);
|
||||||
const r = await callApi("install_machine", {
|
const r = await callApi("install_machine", {
|
||||||
opts: {
|
opts: {
|
||||||
@@ -248,13 +248,13 @@ const MachineForm = (props: MachineDetailsProps) => {
|
|||||||
...values.machine,
|
...values.machine,
|
||||||
// TODO: Remove this workaround
|
// TODO: Remove this workaround
|
||||||
tags: Array.from(
|
tags: Array.from(
|
||||||
values.machine.tags || props.initialData.machine.tags || []
|
values.machine.tags || props.initialData.machine.tags || [],
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
if (machine_response.status === "error") {
|
if (machine_response.status === "error") {
|
||||||
toast.error(
|
toast.error(
|
||||||
`Failed to set machine: ${machine_response.errors[0].message}`
|
`Failed to set machine: ${machine_response.errors[0].message}`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (machine_response.status === "success") {
|
if (machine_response.status === "success") {
|
||||||
@@ -455,7 +455,7 @@ const MachineForm = (props: MachineDetailsProps) => {
|
|||||||
// disabled={!online()}
|
// disabled={!online()}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
const modal = document.getElementById(
|
const modal = document.getElementById(
|
||||||
"install_modal"
|
"install_modal",
|
||||||
) as HTMLDialogElement | null;
|
) as HTMLDialogElement | null;
|
||||||
modal?.showModal();
|
modal?.showModal();
|
||||||
}}
|
}}
|
||||||
@@ -561,7 +561,7 @@ function WifiModule(props: MachineWifiProps) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const [nets, setNets] = createSignal<1[]>(
|
const [nets, setNets] = createSignal<1[]>(
|
||||||
new Array(props.initialData.length || 1).fill(1)
|
new Array(props.initialData.length || 1).fill(1),
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleSubmit = async (values: WifiForm) => {
|
const handleSubmit = async (values: WifiForm) => {
|
||||||
@@ -572,7 +572,7 @@ function WifiModule(props: MachineWifiProps) {
|
|||||||
...acc,
|
...acc,
|
||||||
[curr.ssid || ""]: { ssid: curr.ssid, password: curr.password },
|
[curr.ssid || ""]: { ssid: curr.ssid, password: curr.password },
|
||||||
}),
|
}),
|
||||||
{}
|
{},
|
||||||
);
|
);
|
||||||
|
|
||||||
console.log("submitting", values, networks);
|
console.log("submitting", values, networks);
|
||||||
|
|||||||
Reference in New Issue
Block a user