diff --git a/docs/mkdocs.yml b/docs/mkdocs.yml index 679958377..eea466904 100644 --- a/docs/mkdocs.yml +++ b/docs/mkdocs.yml @@ -121,6 +121,7 @@ nav: - reference/cli/flash.md - reference/cli/history.md - reference/cli/machines.md + - reference/cli/select.md - reference/cli/secrets.md - reference/cli/show.md - reference/cli/ssh.md diff --git a/pkgs/clan-cli/clan_cli/__init__.py b/pkgs/clan-cli/clan_cli/__init__.py index ed39584d8..d66a7860f 100644 --- a/pkgs/clan-cli/clan_cli/__init__.py +++ b/pkgs/clan-cli/clan_cli/__init__.py @@ -18,6 +18,7 @@ from . import ( clan, history, secrets, + select, state, vms, ) @@ -373,6 +374,30 @@ For more detailed information, visit: {help_hyperlink("deploy", "https://docs.cl ) history.register_parser(parser_history) + parser_select = subparsers.add_parser( + "select", + help="Select nixos values from the flake", + description="Select nixos values from the flake", + epilog=( + """ +This subcommand provides an interface nix values defined in the flake. + +Examples: + + $ clan select nixosConfigurations.*.config.networking.hostName + List hostnames of all nixos configurations as JSON. + + $ clan select nixosConfigurations.{jon,alice}.config.clan.core.vars.generators.*.name + List all vars generators for jon and alice. + + $ clan select nixosConfigurations.jon.config.envirnonment.systemPackages.1 + List the first system package for jon. + """ + ), + formatter_class=argparse.RawTextHelpFormatter, + ) + select.register_parser(parser_select) + parser_state = subparsers.add_parser( "state", help="Query state information about machines", diff --git a/pkgs/clan-cli/clan_cli/flake.py b/pkgs/clan-cli/clan_cli/flake.py index e9226b2d3..ef1430792 100644 --- a/pkgs/clan-cli/clan_cli/flake.py +++ b/pkgs/clan-cli/clan_cli/flake.py @@ -192,7 +192,6 @@ class FlakeCacheEntry: self.value[sel].is_cached(selectors[1:]) for sel in self.value ) # TODO: check if we already have all the keys anyway? - print("not cached because self.selector is not all") return False if ( isinstance(selector, set) @@ -200,15 +199,12 @@ class FlakeCacheEntry: and isinstance(self.value, dict) ): if not selector.issubset(self.selector): - print("not cached because selector is not subset of self.selector") return False return all(self.value[sel].is_cached(selectors[1:]) for sel in selector) if isinstance(selector, str | int) and isinstance(self.value, dict): if selector in self.value: return self.value[selector].is_cached(selectors[1:]) - print("not cached because selector is not in self.value") return False - print("not cached because of unknown reason") return False def select(self, selectors: list[Selector]) -> Any: @@ -307,6 +303,5 @@ class Flake: def select(self, selector: str) -> Any: if not self.cache.is_cached(selector): log.info(f"Cache miss for {selector}") - print(f"Cache miss for {selector}") self.prepare_cache([selector]) return self.cache.select(selector) diff --git a/pkgs/clan-cli/clan_cli/select.py b/pkgs/clan-cli/clan_cli/select.py new file mode 100644 index 000000000..7dd68985e --- /dev/null +++ b/pkgs/clan-cli/clan_cli/select.py @@ -0,0 +1,17 @@ +import argparse +import json + +from clan_cli.flake import Flake + + +def select_command(args: argparse.Namespace) -> None: + flake = Flake(args.flake.path) + print(json.dumps(flake.select(args.selector), indent=4)) + + +def register_parser(parser: argparse.ArgumentParser) -> None: + parser.set_defaults(func=select_command) + parser.add_argument( + "selector", + help="select from a flake", + )