From d4cb206e3ee4289f84a0c08c55170f7fc1f70c19 Mon Sep 17 00:00:00 2001 From: a-kenji Date: Tue, 15 Jul 2025 12:01:20 +0200 Subject: [PATCH] pkgs/cli: Add require_flake clan validation logic Add a `require_flake` function that checks, if no argument is passed, if we are in a clan directory. If not will throw a helpful error. Before `clan show`: ``` Traceback (most recent call last): File "/nix/store/8kb3l3yvz6svygnxdlrw5lmd3h3chc8a-clan-cli/bin/.clan-wrapped", line 9, in sys.exit(main()) ~~~~^^ File "/nix/store/8kb3l3yvz6svygnxdlrw5lmd3h3chc8a-clan-cli/lib/python3.13/site-packages/clan_cli/cli.py", line 493, in main args.func(args) ~~~~~~~~~^^^^^^ File "/nix/store/8kb3l3yvz6svygnxdlrw5lmd3h3chc8a-clan-cli/lib/python3.13/site-packages/clan_cli/clan/show.py", line 12, in show_command meta = get_clan_details(flake) File "/nix/store/8kb3l3yvz6svygnxdlrw5lmd3h3chc8a-clan-cli/lib/python3.13/site-packages/clan_lib/clan/get.py", line 22, in get_clan_details if flake.is_local and not flake.path.exists(): ^^^^^^^^^^^^^^ AttributeError: 'NoneType' object has no attribute 'is_local' ``` with `require_flake`: ``` No clan flake found in the current directory or its parents - Use the --flake flag to specify a clan flake path or URL ``` --- pkgs/clan-cli/clan_lib/flake/__init__.py | 2 +- pkgs/clan-cli/clan_lib/flake/flake.py | 25 ++++++++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/pkgs/clan-cli/clan_lib/flake/__init__.py b/pkgs/clan-cli/clan_lib/flake/__init__.py index 68e040f67..25c428fa2 100644 --- a/pkgs/clan-cli/clan_lib/flake/__init__.py +++ b/pkgs/clan-cli/clan_lib/flake/__init__.py @@ -1 +1 @@ -from .flake import Flake # noqa +from .flake import Flake, require_flake # noqa diff --git a/pkgs/clan-cli/clan_lib/flake/flake.py b/pkgs/clan-cli/clan_lib/flake/flake.py index 2ddd92260..b7d28877d 100644 --- a/pkgs/clan-cli/clan_lib/flake/flake.py +++ b/pkgs/clan-cli/clan_lib/flake/flake.py @@ -931,3 +931,28 @@ class Flake: full_selector = f'clanInternals.machines."{system}"."{machine_name}".{selector}' return self.select(full_selector) + + +def require_flake(flake: Flake | None) -> Flake: + """ + Require that a flake argument is provided, if not in a clan flake. + + This should be called by commands that require a flake but don't have + a sensible default when no clan flake is found locally. + + Args: + flake: The flake object to check, may be None + + Returns: + The validated flake object + + Raises: + ClanError: If the flake is None + """ + if flake is None: + msg = "No clan flake found in the current directory or its parents" + raise ClanError( + msg, + description="Use the --flake flag to specify a clan flake path or URL", + ) + return flake