flake: prevent outPath in multiselect to avoid serialization issues
When using multiselect with outPath like {outPath,?meta}, nix evaluation
collapses the attrset to just the outPath string, breaking further selection.
Add validation during selector parsing to catch this and provide a clear error.
This commit is contained in:
@@ -168,6 +168,16 @@ def parse_selector(selector: str) -> list[Selector]:
|
|||||||
else:
|
else:
|
||||||
set_select_type = SetSelectorType.STR
|
set_select_type = SetSelectorType.STR
|
||||||
acc_selectors.append(SetSelector(type=set_select_type, value=acc_str))
|
acc_selectors.append(SetSelector(type=set_select_type, value=acc_str))
|
||||||
|
# Check for invalid multiselect patterns with outPath
|
||||||
|
for subselector in acc_selectors:
|
||||||
|
if subselector.value == "outPath":
|
||||||
|
msg = (
|
||||||
|
"Cannot use 'outPath' in multiselect {...}. "
|
||||||
|
"When nix evaluates attrsets with outPath in a multiselect, "
|
||||||
|
"it collapses the entire attrset to just the outPath string, "
|
||||||
|
"breaking further selection. Use individual selectors instead."
|
||||||
|
)
|
||||||
|
raise ValueError(msg)
|
||||||
selectors.append(Selector(type=SelectorType.SET, value=acc_selectors))
|
selectors.append(Selector(type=SelectorType.SET, value=acc_selectors))
|
||||||
|
|
||||||
submode = ""
|
submode = ""
|
||||||
|
|||||||
@@ -168,6 +168,20 @@ def test_out_path() -> None:
|
|||||||
assert test_cache.select(selectors) == "/nix/store/bla"
|
assert test_cache.select(selectors) == "/nix/store/bla"
|
||||||
|
|
||||||
|
|
||||||
|
def test_out_path_in_multiselect_raises_exception() -> None:
|
||||||
|
with pytest.raises(ValueError, match="Cannot use 'outPath' in multiselect"):
|
||||||
|
parse_selector("{outPath}")
|
||||||
|
|
||||||
|
with pytest.raises(ValueError, match="Cannot use 'outPath' in multiselect"):
|
||||||
|
parse_selector("x.{y,outPath}")
|
||||||
|
|
||||||
|
with pytest.raises(ValueError, match="Cannot use 'outPath' in multiselect"):
|
||||||
|
parse_selector("a.b.{c,d,outPath,e}")
|
||||||
|
|
||||||
|
with pytest.raises(ValueError, match="Cannot use 'outPath' in multiselect"):
|
||||||
|
parse_selector("{?outPath}")
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.with_core
|
@pytest.mark.with_core
|
||||||
def test_conditional_all_selector(flake: ClanFlake) -> None:
|
def test_conditional_all_selector(flake: ClanFlake) -> None:
|
||||||
m1 = flake.machines["machine1"]
|
m1 = flake.machines["machine1"]
|
||||||
|
|||||||
Reference in New Issue
Block a user