Merge pull request 'clan_cli: add select command' (#2815) from kenji/clan-core:lass/clan-select into main

Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/2815
This commit is contained in:
kenji
2025-02-04 07:32:55 +00:00
4 changed files with 43 additions and 5 deletions

View File

@@ -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

View File

@@ -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",

View File

@@ -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)

View File

@@ -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",
)