From e2cf3c1601249628e568f221b78f6bb41fb240cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Thalheim?= Date: Fri, 22 Sep 2023 15:39:03 +0200 Subject: [PATCH 1/3] fix test not beeing exposed --- pkgs/clan-cli/default.nix | 2 +- pkgs/clan-cli/flake-module.nix | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pkgs/clan-cli/default.nix b/pkgs/clan-cli/default.nix index 7aed0c22f..c643448c9 100644 --- a/pkgs/clan-cli/default.nix +++ b/pkgs/clan-cli/default.nix @@ -113,7 +113,7 @@ python3.pkgs.buildPythonPackage { propagatedBuildInputs = dependencies; # also re-expose dependencies so we test them in CI - passthru.tests = (lib.mapAttrs' (n: lib.nameValuePair "package-${n}") runtimeDependenciesAsSet) // { + passthru.tests = (lib.mapAttrs' (n: lib.nameValuePair "clan-dep-${n}") runtimeDependenciesAsSet) // { clan-pytest = runCommand "clan-pytest" { nativeBuildInputs = [ checkPython ] ++ pytestDependencies; } '' cp -r ${source} ./src chmod +w -R ./src diff --git a/pkgs/clan-cli/flake-module.nix b/pkgs/clan-cli/flake-module.nix index ff7aaee78..422010211 100644 --- a/pkgs/clan-cli/flake-module.nix +++ b/pkgs/clan-cli/flake-module.nix @@ -1,4 +1,4 @@ -{ lib, inputs, ... }: +{ inputs, ... }: { perSystem = { self', pkgs, ... }: { devShells.clan-cli = pkgs.callPackage ./shell.nix { @@ -18,7 +18,7 @@ ## End optional dependencies }; - checks = lib.mkDefault self'.packages.clan-cli.tests; + checks = self'.packages.clan-cli.tests; }; } From e3b2424d9d892bbaee43279268862d94445dab36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Thalheim?= Date: Fri, 22 Sep 2023 16:03:14 +0200 Subject: [PATCH 2/3] make git optional again --- pkgs/clan-cli/clan_cli/config/machine.py | 7 +++++-- pkgs/clan-cli/clan_cli/dirs.py | 8 ++++++-- pkgs/clan-cli/clan_cli/git.py | 3 ++- pkgs/clan-cli/tests/test_dirs.py | 2 +- 4 files changed, 14 insertions(+), 6 deletions(-) diff --git a/pkgs/clan-cli/clan_cli/config/machine.py b/pkgs/clan-cli/clan_cli/config/machine.py index 4e6be49f4..90563194a 100644 --- a/pkgs/clan-cli/clan_cli/config/machine.py +++ b/pkgs/clan-cli/clan_cli/config/machine.py @@ -7,7 +7,7 @@ from typing import Optional from fastapi import HTTPException from clan_cli.dirs import get_clan_flake_toplevel, nixpkgs_source -from clan_cli.git import commit_file +from clan_cli.git import commit_file, find_git_repo_root from clan_cli.machines.folders import machine_folder, machine_settings_file from clan_cli.nix import nix_eval @@ -37,7 +37,10 @@ def set_config_for_machine(machine_name: str, config: dict) -> None: settings_path.parent.mkdir(parents=True, exist_ok=True) with open(settings_path, "w") as f: json.dump(config, f) - commit_file(settings_path) + repo_dir = find_git_repo_root() + + if repo_dir is not None: + commit_file(settings_path, repo_dir) def schema_for_machine(machine_name: str, flake: Optional[Path] = None) -> dict: diff --git a/pkgs/clan-cli/clan_cli/dirs.py b/pkgs/clan-cli/clan_cli/dirs.py index b3d5a2eb2..a3b054016 100644 --- a/pkgs/clan-cli/clan_cli/dirs.py +++ b/pkgs/clan-cli/clan_cli/dirs.py @@ -1,6 +1,7 @@ import os import sys from pathlib import Path +from typing import Optional from .errors import ClanError @@ -9,8 +10,11 @@ def get_clan_flake_toplevel() -> Path: return find_toplevel([".clan-flake", ".git", ".hg", ".svn", "flake.nix"]) -def find_git_repo_root() -> Path: - return find_toplevel([".git"]) +def find_git_repo_root() -> Optional[Path]: + try: + return find_toplevel([".git"]) + except ClanError: + return None def find_toplevel(top_level_files: list[str]) -> Path: diff --git a/pkgs/clan-cli/clan_cli/git.py b/pkgs/clan-cli/clan_cli/git.py index 700d0aa8a..013e07144 100644 --- a/pkgs/clan-cli/clan_cli/git.py +++ b/pkgs/clan-cli/clan_cli/git.py @@ -13,9 +13,10 @@ def commit_file( repo_dir: Optional[Path] = None, commit_message: Optional[str] = None, ) -> None: - # set default for repo_dir if repo_dir is None: repo_dir = find_git_repo_root() + if repo_dir is None: + return # check that the file is in the git repository and exists if not Path(file_path).resolve().is_relative_to(repo_dir.resolve()): raise ClanError(f"File {file_path} is not in the git repository {repo_dir}") diff --git a/pkgs/clan-cli/tests/test_dirs.py b/pkgs/clan-cli/tests/test_dirs.py index 2dec0e174..c621ff19c 100644 --- a/pkgs/clan-cli/tests/test_dirs.py +++ b/pkgs/clan-cli/tests/test_dirs.py @@ -11,7 +11,7 @@ def test_get_clan_flake_toplevel( ) -> None: monkeypatch.chdir(temporary_dir) with pytest.raises(ClanError): - get_clan_flake_toplevel() + print(get_clan_flake_toplevel()) (temporary_dir / ".git").touch() assert get_clan_flake_toplevel() == temporary_dir From fa9e8d757dc9ec8d8e3e4d4d6321d0e74f45cc88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Thalheim?= Date: Fri, 22 Sep 2023 16:03:45 +0200 Subject: [PATCH 3/3] add show-trace option that is disabled by default --- pkgs/clan-cli/clan_cli/config/__init__.py | 43 +++++++++++++---------- 1 file changed, 25 insertions(+), 18 deletions(-) diff --git a/pkgs/clan-cli/clan_cli/config/__init__.py b/pkgs/clan-cli/clan_cli/config/__init__.py index 6be310c34..d74d2db4e 100644 --- a/pkgs/clan-cli/clan_cli/config/__init__.py +++ b/pkgs/clan-cli/clan_cli/config/__init__.py @@ -96,15 +96,15 @@ def cast(value: Any, type: Type, opt_description: str) -> Any: ) -def options_for_machine(machine_name: str) -> dict: +def options_for_machine(machine_name: str, show_trace: bool = False) -> dict: clan_dir = get_clan_flake_toplevel() - # use nix eval to lib.evalModules .#clanModules.machine-{machine_name} - cmd = nix_eval( - flags=[ - "--show-trace", - f"{clan_dir}#nixosConfigurations.{machine_name}.config.clanCore.optionsNix", - ], + flags = [] + if show_trace: + flags.append("--show-trace") + flags.append( + f"{clan_dir}#nixosConfigurations.{machine_name}.config.clanCore.optionsNix" ) + cmd = nix_eval(flags=flags) proc = subprocess.run( cmd, capture_output=True, @@ -117,7 +117,9 @@ def options_for_machine(machine_name: str) -> dict: return json.loads(proc.stdout) -def read_machine_option_value(machine_name: str, option: str) -> str: +def read_machine_option_value( + machine_name: str, option: str, show_trace: bool = False +) -> str: clan_dir = get_clan_flake_toplevel() # use nix eval to read from .#nixosConfigurations.default.config.{option} # this will give us the evaluated config with the options attribute @@ -148,11 +150,13 @@ def read_machine_option_value(machine_name: str, option: str) -> str: def get_or_set_option(args: argparse.Namespace) -> None: if args.value == []: - print(read_machine_option_value(args.machine, args.option)) + print(read_machine_option_value(args.machine, args.option, args.show_trace)) else: # load options if args.options_file is None: - options = options_for_machine(machine_name=args.machine) + options = options_for_machine( + machine_name=args.machine, show_trace=args.show_trace + ) else: with open(args.options_file) as f: options = json.load(f) @@ -169,6 +173,7 @@ def get_or_set_option(args: argparse.Namespace) -> None: options=options, settings_file=settings_file, option_description=args.option, + show_trace=args.show_trace, ) if not args.quiet: new_value = read_machine_option_value(args.machine, args.option) @@ -182,6 +187,7 @@ def set_option( options: dict, settings_file: Path, option_description: str = "", + show_trace: bool = False, ) -> None: option_path = option.split(".") @@ -198,6 +204,7 @@ def set_option( options=options, settings_file=settings_file, option_description=option, + show_trace=show_trace, ) target_type = map_type(options[option]["type"]) @@ -242,7 +249,6 @@ def register_parser( # inject callback function to process the input later parser.set_defaults(func=get_or_set_option) - # add --machine argument parser.add_argument( "--machine", "-m", @@ -251,39 +257,40 @@ def register_parser( default="default", ) - # add --options-file argument + parser.add_argument( + "--show-trace", + help="Show nix trace on evaluation error", + action="store_true", + ) + parser.add_argument( "--options-file", help="JSON file with options", type=Path, ) - # add --settings-file argument parser.add_argument( "--settings-file", help="JSON file with settings", type=Path, ) - # add --quiet argument parser.add_argument( "--quiet", help="Do not print the value", action="store_true", ) - # add single positional argument for the option (e.g. "foo.bar") parser.add_argument( "option", - help="Option to read or set", + help="Option to read or set (e.g. foo.bar)", type=str, ) - # add a single optional argument for the value parser.add_argument( "value", # force this arg to be set nargs="*", - help="Value to set", + help="option value to set (if omitted, the current value is printed)", )