nixos-rebuild-ng: handle subflakes correctly

Tested with a simple flake setup:

/tmp/zen-mcnulty-jHbPy1 main*
% /nix/store/9a2w8pb4zxz084hmjbfcmgpswan1kz51-nixos-rebuild-ng-0.0.0/bin/nixos-rebuild-ng repl --flake .#nixos
Nix 2.28.3
nix-repl> config.networking.hostName
"nixos"

/tmp/zen-mcnulty-jHbPy1 main*

% cd subflake
 configuration.nix   flake.nix   hardware-configuration.nix   tmp/

/tmp/zen-mcnulty-jHbPy1/subflake main*
% /nix/store/9a2w8pb4zxz084hmjbfcmgpswan1kz51-nixos-rebuild-ng-0.0.0/bin/nixos-rebuild-ng repl --flake .#nixos
nix-repl> config.networking.hostName
"foo"
This commit is contained in:
Jörg Thalheim
2025-05-24 14:20:00 +02:00
parent 631b610af8
commit c6fe53c58e

View File

@@ -61,19 +61,39 @@ class BuildAttr:
return cls(Path(file or "default.nix"), attr)
def discover_git(location: Path) -> str | None:
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 str(current)
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 dotgit_content.split("gitdir: ")[1]
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
@@ -110,7 +130,15 @@ class Flake:
path = Path(path_str)
git_repo = discover_git(path)
if git_repo is not None:
return cls(f"git+file://{git_repo}", nixos_attr)
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)
return cls(path, nixos_attr)
@classmethod