diff --git a/pkgs/by-name/ni/nixos-rebuild-ng/src/nixos_rebuild/models.py b/pkgs/by-name/ni/nixos-rebuild-ng/src/nixos_rebuild/models.py index 3fe47acc1bb6..2c7150875b5a 100644 --- a/pkgs/by-name/ni/nixos-rebuild-ng/src/nixos_rebuild/models.py +++ b/pkgs/by-name/ni/nixos-rebuild-ng/src/nixos_rebuild/models.py @@ -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