nixos-rebuild-ng: do not resolve Flake (#422971)

This commit is contained in:
Thiago Kenji Okada
2025-07-07 19:32:27 +01:00
committed by GitHub
3 changed files with 18 additions and 96 deletions
@@ -61,46 +61,7 @@ class BuildAttr:
return cls(Path(file or "default.nix"), attr)
def discover_git(location: Path) -> Path | None:
"""
Discover the current git repository in the given location.
"""
current = location.resolve()
previous = None
while current.is_dir() and current != previous:
dotgit = current / ".git"
if dotgit.is_dir():
return current
elif dotgit.is_file(): # this is a worktree
with dotgit.open() as f:
dotgit_content = f.read().strip()
if dotgit_content.startswith("gitdir: "):
return Path(dotgit_content.split("gitdir: ")[1])
previous = current
current = current.parent
return None
def discover_closest_flake(location: Path) -> Path | None:
"""
Discover the closest flake.nix file starting from the given location upwards.
"""
current = location.resolve()
previous = None
while current.is_dir() and current != previous:
flake_file = current / "flake.nix"
if flake_file.is_file():
return current
previous = current
current = current.parent
return None
def get_hostname(target_host: Remote | None) -> str | None:
def _get_hostname(target_host: Remote | None) -> str | None:
if target_host:
try:
return run_wrapper(
@@ -133,25 +94,13 @@ class Flake:
assert m is not None, f"got no matches for {flake_str}"
attr = m.group("attr")
nixos_attr = (
f'nixosConfigurations."{attr or get_hostname(target_host) or "default"}"'
f'nixosConfigurations."{attr or _get_hostname(target_host) or "default"}"'
)
path_str = m.group("path")
if ":" in path_str:
return cls(path_str, nixos_attr)
else:
path = Path(path_str)
git_repo = discover_git(path)
if git_repo is not None:
url = f"git+file://{git_repo}"
flake_path = discover_closest_flake(path)
if (
flake_path is not None
and flake_path != git_repo
and flake_path.is_relative_to(git_repo)
):
url += f"?dir={flake_path.relative_to(git_repo)}"
return cls(url, nixos_attr)
path = m.group("path")
if ":" in path:
return cls(path, nixos_attr)
else:
return cls(Path(path), nixos_attr)
@classmethod
def from_arg(cls, flake_arg: Any, target_host: Remote | None) -> Self | None: # noqa: ANN401
@@ -30,13 +30,13 @@ def test_build_attr_to_attr() -> None:
)
@patch("platform.node", autospec=True, return_value="hostname")
@patch("platform.node", autospec=True, return_value=None)
def test_flake_parse(mock_node: Mock, tmpdir: Path, monkeypatch: MonkeyPatch) -> None:
assert m.Flake.parse("/path/to/flake#attr") == m.Flake(
Path("/path/to/flake"), 'nixosConfigurations."attr"'
)
assert m.Flake.parse("/path/ to /flake") == m.Flake(
Path("/path/ to /flake"), 'nixosConfigurations."hostname"'
Path("/path/ to /flake"), 'nixosConfigurations."default"'
)
with patch(
get_qualified_name(m.run_wrapper, m),
@@ -47,40 +47,18 @@ def test_flake_parse(mock_node: Mock, tmpdir: Path, monkeypatch: MonkeyPatch) ->
assert m.Flake.parse("/path/to/flake", target_host) == m.Flake(
Path("/path/to/flake"), 'nixosConfigurations."remote"'
)
# change directory to tmpdir
with monkeypatch.context() as patch_context:
patch_context.chdir(tmpdir)
assert m.Flake.parse(".#attr") == m.Flake(
Path("."), 'nixosConfigurations."attr"'
)
assert m.Flake.parse("#attr") == m.Flake(
Path("."), 'nixosConfigurations."attr"'
)
assert m.Flake.parse(".") == m.Flake(
Path("."), 'nixosConfigurations."hostname"'
)
assert m.Flake.parse(".#attr") == m.Flake(Path("."), 'nixosConfigurations."attr"')
assert m.Flake.parse("#attr") == m.Flake(Path("."), 'nixosConfigurations."attr"')
assert m.Flake.parse(".") == m.Flake(Path("."), 'nixosConfigurations."default"')
assert m.Flake.parse("path:/to/flake#attr") == m.Flake(
"path:/to/flake", 'nixosConfigurations."attr"'
)
# from here on we should return "default"
mock_node.return_value = None
# from here on we should return "hostname"
mock_node.return_value = "hostname"
assert m.Flake.parse("github:user/repo/branch") == m.Flake(
"github:user/repo/branch", 'nixosConfigurations."default"'
)
git_root = tmpdir / "git_root"
git_root.mkdir()
(git_root / ".git").mkdir()
assert m.Flake.parse(str(git_root)) == m.Flake(
f"git+file://{git_root}", 'nixosConfigurations."default"'
)
work_tree = tmpdir / "work_tree"
work_tree.mkdir()
(work_tree / ".git").write_text("gitdir: /path/to/git", "utf-8")
assert m.Flake.parse(str(work_tree)) == m.Flake(
"git+file:///path/to/git", 'nixosConfigurations."default"'
"github:user/repo/branch", 'nixosConfigurations."hostname"'
)
@@ -134,14 +112,9 @@ def test_flake_from_arg(
autospec=True,
return_value=False,
),
patch(
get_qualified_name(m.discover_git),
autospec=True,
return_value="/etc/nixos",
),
):
assert m.Flake.from_arg(None, None) == m.Flake(
"git+file:///etc/nixos", 'nixosConfigurations."hostname"'
Path("/etc/nixos"), 'nixosConfigurations."hostname"'
)
with (
@@ -307,8 +307,8 @@ def test_edit(mock_run: Mock, monkeypatch: MonkeyPatch, tmpdir: Path) -> None:
@patch(get_qualified_name(n.run_wrapper, n), autospec=True)
def test_editd_flake(mock_run: Mock, monkeypatch: MonkeyPatch, tmpdir: Path) -> None:
flake = m.Flake.parse(f"{tmpdir}#attr")
def test_edit_flake(mock_run: Mock) -> None:
flake = m.Flake.parse(".#attr")
n.edit_flake(flake, {"commit_lock_file": True})
mock_run.assert_called_with(
[
@@ -318,7 +318,7 @@ def test_editd_flake(mock_run: Mock, monkeypatch: MonkeyPatch, tmpdir: Path) ->
"edit",
"--commit-lock-file",
"--",
f'{tmpdir}#nixosConfigurations."attr"',
'.#nixosConfigurations."attr"',
],
check=False,
)