PLC0415: fix
This commit is contained in:
@@ -8,6 +8,7 @@ from clan_cli.tests import fixtures_flakes
|
||||
from clan_cli.tests.age_keys import SopsSetup, assert_secrets_file_recipients
|
||||
from clan_cli.tests.helpers import cli
|
||||
from clan_cli.tests.stdout import CaptureOutput
|
||||
from clan_lib.errors import ClanError
|
||||
from clan_lib.flake import Flake
|
||||
from clan_lib.persist.inventory_store import InventoryStore
|
||||
|
||||
@@ -93,8 +94,6 @@ def test_machines_update_nonexistent_machine(
|
||||
test_flake_with_core: fixtures_flakes.FlakeForTest,
|
||||
) -> None:
|
||||
"""Test that update command gives helpful error messages for non-existent machines."""
|
||||
from clan_lib.errors import ClanError
|
||||
|
||||
with pytest.raises(ClanError) as exc_info:
|
||||
cli.run(
|
||||
[
|
||||
@@ -118,8 +117,6 @@ def test_machines_update_typo_in_machine_name(
|
||||
test_flake_with_core: fixtures_flakes.FlakeForTest,
|
||||
) -> None:
|
||||
"""Test that update command suggests similar machine names for typos."""
|
||||
from clan_lib.errors import ClanError
|
||||
|
||||
with pytest.raises(ClanError) as exc_info:
|
||||
cli.run(
|
||||
[
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import json
|
||||
import logging
|
||||
import shutil
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
@@ -11,6 +12,7 @@ from clan_cli.vars.check import check_vars
|
||||
from clan_cli.vars.generator import (
|
||||
Generator,
|
||||
GeneratorKey,
|
||||
dependencies_as_dir,
|
||||
)
|
||||
from clan_cli.vars.get import get_machine_var
|
||||
from clan_cli.vars.graph import all_missing_closure, requested_closure
|
||||
@@ -21,7 +23,7 @@ from clan_cli.vars.set import set_var
|
||||
from clan_lib.errors import ClanError
|
||||
from clan_lib.flake import Flake
|
||||
from clan_lib.machines.machines import Machine
|
||||
from clan_lib.nix import nix_eval, run
|
||||
from clan_lib.nix import nix_config, nix_eval, run
|
||||
from clan_lib.vars.generate import (
|
||||
get_generators,
|
||||
run_generators,
|
||||
@@ -29,8 +31,6 @@ from clan_lib.vars.generate import (
|
||||
|
||||
|
||||
def test_dependencies_as_files(temp_dir: Path) -> None:
|
||||
from clan_cli.vars.generator import dependencies_as_dir
|
||||
|
||||
decrypted_dependencies = {
|
||||
"gen_1": {
|
||||
"var_1a": b"var_1a",
|
||||
@@ -506,7 +506,6 @@ def test_generate_secret_var_password_store(
|
||||
monkeypatch.setenv("PASSWORD_STORE_DIR", str(password_store_dir))
|
||||
|
||||
# Initialize password store as a git repository
|
||||
import subprocess
|
||||
|
||||
subprocess.run(["git", "init"], cwd=password_store_dir, check=True)
|
||||
subprocess.run(
|
||||
@@ -613,8 +612,6 @@ def test_generate_secret_for_multiple_machines(
|
||||
) -> None:
|
||||
flake = flake_with_sops
|
||||
|
||||
from clan_lib.nix import nix_config
|
||||
|
||||
local_system = nix_config()["system"]
|
||||
|
||||
machine1_config = flake.machines["machine1"]
|
||||
@@ -1101,8 +1098,6 @@ def test_create_sops_age_secrets(
|
||||
# check private key exists
|
||||
assert (flake.temporary_home / ".config" / "sops" / "age" / "keys.txt").is_file()
|
||||
# it should still work, even if the keys already exist
|
||||
import shutil
|
||||
|
||||
shutil.rmtree(flake.path / "sops" / "users" / "user")
|
||||
cli.run(["vars", "keygen", "--flake", str(flake.path), "--user", "user"])
|
||||
# check public key exists
|
||||
|
||||
@@ -142,8 +142,6 @@ class StoreBase(ABC):
|
||||
value: bytes,
|
||||
is_migration: bool = False,
|
||||
) -> list[Path]:
|
||||
from clan_lib.machines.machines import Machine
|
||||
|
||||
changed_files: list[Path] = []
|
||||
|
||||
# if generator was switched from shared to per-machine or vice versa,
|
||||
@@ -169,6 +167,8 @@ class StoreBase(ABC):
|
||||
if generator.machine is None:
|
||||
log_info = log.info
|
||||
else:
|
||||
from clan_lib.machines.machines import Machine # noqa: PLC0415
|
||||
|
||||
machine = Machine(name=generator.machine, flake=self.flake)
|
||||
log_info = machine.info
|
||||
if self.is_secret_store:
|
||||
|
||||
@@ -32,13 +32,14 @@ def vars_status(
|
||||
flake: Flake,
|
||||
generator_name: None | str = None,
|
||||
) -> VarStatus:
|
||||
from clan_cli.vars.generator import Generator # noqa: PLC0415
|
||||
|
||||
machine = Machine(name=machine_name, flake=flake)
|
||||
missing_secret_vars = []
|
||||
missing_public_vars = []
|
||||
# signals if a var needs to be updated (eg. needs re-encryption due to new users added)
|
||||
unfixed_secret_vars = []
|
||||
invalid_generators = []
|
||||
from clan_cli.vars.generator import Generator
|
||||
|
||||
generators = Generator.get_machine_generators([machine.name], machine.flake)
|
||||
if generator_name:
|
||||
|
||||
@@ -2,6 +2,7 @@ import argparse
|
||||
import logging
|
||||
|
||||
from clan_cli.completions import add_dynamic_completer, complete_machines
|
||||
from clan_cli.vars.generator import Generator
|
||||
from clan_lib.errors import ClanError
|
||||
from clan_lib.flake import require_flake
|
||||
from clan_lib.machines.machines import Machine
|
||||
@@ -10,8 +11,6 @@ log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def fix_vars(machine: Machine, generator_name: None | str = None) -> None:
|
||||
from clan_cli.vars.generator import Generator
|
||||
|
||||
generators = Generator.get_machine_generators([machine.name], machine.flake)
|
||||
if generator_name:
|
||||
for generator in generators:
|
||||
|
||||
@@ -1,23 +1,31 @@
|
||||
import logging
|
||||
import os
|
||||
import shutil
|
||||
import sys
|
||||
from contextlib import ExitStack
|
||||
from dataclasses import dataclass, field
|
||||
from functools import cached_property
|
||||
from pathlib import Path
|
||||
from tempfile import TemporaryDirectory
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from clan_lib import bwrap
|
||||
from clan_lib.cmd import RunOpts, run
|
||||
from clan_lib.errors import ClanError
|
||||
from clan_lib.nix import nix_test_store
|
||||
from clan_lib.git import commit_files
|
||||
from clan_lib.nix import nix_config, nix_shell, nix_test_store
|
||||
|
||||
from .check import check_vars
|
||||
from .prompt import Prompt
|
||||
from .prompt import Prompt, ask
|
||||
from .var import Var
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from clan_lib.flake import Flake
|
||||
from clan_lib.machines.machines import Machine
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from ._types import StoreBase
|
||||
|
||||
from clan_lib.machines.machines import Machine
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@@ -91,8 +99,6 @@ class Generator:
|
||||
list[Generator]: A list of (unsorted) generators for the machine.
|
||||
|
||||
"""
|
||||
from clan_lib.nix import nix_config
|
||||
|
||||
config = nix_config()
|
||||
system = config["system"]
|
||||
|
||||
@@ -125,8 +131,6 @@ class Generator:
|
||||
files_selector,
|
||||
)
|
||||
|
||||
from clan_lib.machines.machines import Machine
|
||||
|
||||
machine = Machine(name=machine_name, flake=flake)
|
||||
pub_store = machine.public_vars_store
|
||||
sec_store = machine.secret_vars_store
|
||||
@@ -207,8 +211,6 @@ class Generator:
|
||||
if self._flake is None:
|
||||
msg = "Flake cannot be None"
|
||||
raise ClanError(msg)
|
||||
from clan_lib.machines.machines import Machine
|
||||
|
||||
machine = Machine(name=self.machine, flake=self._flake)
|
||||
output = Path(
|
||||
machine.select(
|
||||
@@ -226,8 +228,6 @@ class Generator:
|
||||
if self._flake is None:
|
||||
msg = "Flake cannot be None"
|
||||
raise ClanError(msg)
|
||||
from clan_lib.machines.machines import Machine
|
||||
|
||||
machine = Machine(name=self.machine, flake=self._flake)
|
||||
return machine.select(
|
||||
f'config.clan.core.vars.generators."{self.name}".validationHash',
|
||||
@@ -250,8 +250,6 @@ class Generator:
|
||||
Dictionary mapping generator names to their variable values
|
||||
|
||||
"""
|
||||
from clan_lib.errors import ClanError
|
||||
|
||||
generators = self.get_machine_generators([machine.name], machine.flake)
|
||||
result: dict[str, dict[str, bytes]] = {}
|
||||
|
||||
@@ -297,8 +295,6 @@ class Generator:
|
||||
Dictionary mapping prompt names to their values
|
||||
|
||||
"""
|
||||
from .prompt import ask
|
||||
|
||||
prompt_values: dict[str, str] = {}
|
||||
for prompt in self.prompts:
|
||||
var_id = f"{self.name}/{prompt.name}"
|
||||
@@ -323,17 +319,6 @@ class Generator:
|
||||
no_sandbox: Whether to disable sandboxing when executing the generator
|
||||
|
||||
"""
|
||||
import os
|
||||
import sys
|
||||
from contextlib import ExitStack
|
||||
from pathlib import Path
|
||||
from tempfile import TemporaryDirectory
|
||||
|
||||
from clan_lib import bwrap
|
||||
from clan_lib.cmd import RunOpts, run
|
||||
from clan_lib.errors import ClanError
|
||||
from clan_lib.git import commit_files
|
||||
|
||||
if prompt_values is None:
|
||||
prompt_values = self.ask_prompts()
|
||||
|
||||
@@ -353,10 +338,6 @@ class Generator:
|
||||
|
||||
def bubblewrap_cmd(generator: str, tmpdir: Path) -> list[str]:
|
||||
"""Helper function to create bubblewrap command."""
|
||||
import shutil
|
||||
|
||||
from clan_lib.nix import nix_shell, nix_test_store
|
||||
|
||||
test_store = nix_test_store()
|
||||
real_bash_path = Path("bash")
|
||||
if os.environ.get("IN_NIX_SANDBOX"):
|
||||
@@ -414,7 +395,7 @@ class Generator:
|
||||
if sys.platform == "linux" and bwrap.bubblewrap_works():
|
||||
cmd = bubblewrap_cmd(str(final_script), tmpdir)
|
||||
elif sys.platform == "darwin":
|
||||
from clan_lib.sandbox_exec import sandbox_exec_cmd
|
||||
from clan_lib.sandbox_exec import sandbox_exec_cmd # noqa: PLC0415
|
||||
|
||||
cmd = stack.enter_context(sandbox_exec_cmd(str(final_script), tmpdir))
|
||||
else:
|
||||
|
||||
@@ -8,6 +8,7 @@ from tempfile import TemporaryDirectory
|
||||
|
||||
from clan_cli.vars._types import StoreBase
|
||||
from clan_cli.vars.generator import Generator, Var
|
||||
from clan_lib.cmd import Log, RunOpts
|
||||
from clan_lib.flake import Flake
|
||||
from clan_lib.ssh.host import Host
|
||||
from clan_lib.ssh.upload import upload
|
||||
@@ -162,8 +163,6 @@ class SecretStore(StoreBase):
|
||||
if not git_hash:
|
||||
return b""
|
||||
|
||||
from clan_cli.vars.generator import Generator
|
||||
|
||||
generators = Generator.get_machine_generators([machine], self.flake)
|
||||
manifest = [
|
||||
f"{generator.name}/{file.name}".encode()
|
||||
@@ -179,8 +178,6 @@ class SecretStore(StoreBase):
|
||||
if not local_hash:
|
||||
return True
|
||||
|
||||
from clan_lib.cmd import Log, RunOpts
|
||||
|
||||
remote_hash = host.run(
|
||||
[
|
||||
"cat",
|
||||
@@ -195,8 +192,6 @@ class SecretStore(StoreBase):
|
||||
return local_hash != remote_hash.encode()
|
||||
|
||||
def populate_dir(self, machine: str, output_dir: Path, phases: list[str]) -> None:
|
||||
from clan_cli.vars.generator import Generator
|
||||
|
||||
vars_generators = Generator.get_machine_generators([machine], self.flake)
|
||||
if "users" in phases:
|
||||
with tarfile.open(
|
||||
|
||||
@@ -54,7 +54,7 @@ class SecretStore(StoreBase):
|
||||
def ensure_machine_key(self, machine: str) -> None:
|
||||
"""Ensure machine has sops keys initialized."""
|
||||
# no need to generate keys if we don't manage secrets
|
||||
from clan_cli.vars.generator import Generator
|
||||
from clan_cli.vars.generator import Generator # noqa: PLC0415
|
||||
|
||||
vars_generators = Generator.get_machine_generators([machine], self.flake)
|
||||
if not vars_generators:
|
||||
@@ -141,7 +141,7 @@ class SecretStore(StoreBase):
|
||||
|
||||
"""
|
||||
if generators is None:
|
||||
from clan_cli.vars.generator import Generator
|
||||
from clan_cli.vars.generator import Generator # noqa: PLC0415
|
||||
|
||||
generators = Generator.get_machine_generators([machine], self.flake)
|
||||
file_found = False
|
||||
@@ -219,7 +219,7 @@ class SecretStore(StoreBase):
|
||||
return [store_folder]
|
||||
|
||||
def populate_dir(self, machine: str, output_dir: Path, phases: list[str]) -> None:
|
||||
from clan_cli.vars.generator import Generator
|
||||
from clan_cli.vars.generator import Generator # noqa: PLC0415
|
||||
|
||||
vars_generators = Generator.get_machine_generators([machine], self.flake)
|
||||
if "users" in phases or "services" in phases:
|
||||
@@ -291,7 +291,7 @@ class SecretStore(StoreBase):
|
||||
)
|
||||
|
||||
def collect_keys_for_secret(self, machine: str, path: Path) -> set[sops.SopsKey]:
|
||||
from clan_cli.secrets.secrets import (
|
||||
from clan_cli.secrets.secrets import ( # noqa: PLC0415
|
||||
collect_keys_for_path,
|
||||
collect_keys_for_type,
|
||||
)
|
||||
@@ -352,10 +352,10 @@ class SecretStore(StoreBase):
|
||||
ClanError: If the specified file_name is not found
|
||||
|
||||
"""
|
||||
from clan_cli.secrets.secrets import update_keys
|
||||
from clan_cli.secrets.secrets import update_keys # noqa: PLC0415
|
||||
|
||||
if generators is None:
|
||||
from clan_cli.vars.generator import Generator
|
||||
from clan_cli.vars.generator import Generator # noqa: PLC0415
|
||||
|
||||
generators = Generator.get_machine_generators([machine], self.flake)
|
||||
file_found = False
|
||||
|
||||
@@ -20,6 +20,7 @@ from clan_lib.async_run import get_current_thread_opkey
|
||||
from clan_lib.errors import ClanError
|
||||
|
||||
from .serde import dataclass_to_dict, from_dict, sanitize_string
|
||||
from .type_to_jsonschema import JSchemaTypeError, type_to_dict
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
@@ -201,10 +202,6 @@ API.register(get_system_file)
|
||||
return fn
|
||||
|
||||
def to_json_schema(self) -> dict[str, Any]:
|
||||
from typing import get_type_hints
|
||||
|
||||
from .type_to_jsonschema import JSchemaTypeError, type_to_dict
|
||||
|
||||
api_schema: dict[str, Any] = {
|
||||
"$comment": "An object containing API methods. ",
|
||||
"type": "object",
|
||||
@@ -268,8 +265,6 @@ API.register(get_system_file)
|
||||
return api_schema
|
||||
|
||||
def get_method_argtype(self, method_name: str, arg_name: str) -> Any:
|
||||
from inspect import signature
|
||||
|
||||
func = self._registry.get(method_name, None)
|
||||
if not func:
|
||||
msg = f"API Method {method_name} not found in registry. Available methods: {list(self._registry.keys())}"
|
||||
@@ -313,9 +308,9 @@ def load_in_all_api_functions() -> None:
|
||||
We have to make sure python loads every wrapped function at least once.
|
||||
This is done by importing all modules from the clan_lib and clan_cli packages.
|
||||
"""
|
||||
import clan_cli
|
||||
import clan_cli # noqa: PLC0415 # Avoid circular imports - many modules import from clan_lib.api
|
||||
|
||||
import clan_lib
|
||||
import clan_lib # noqa: PLC0415 # Avoid circular imports - many modules import from clan_lib.api
|
||||
|
||||
import_all_modules_from_package(clan_lib)
|
||||
import_all_modules_from_package(clan_cli)
|
||||
|
||||
@@ -4,8 +4,7 @@ from pathlib import Path
|
||||
from typing import Any, Literal
|
||||
|
||||
from clan_lib.cmd import RunOpts, run
|
||||
from clan_lib.flake import Flake
|
||||
from clan_lib.nix import nix_shell
|
||||
from clan_lib.flake.flake import Flake
|
||||
|
||||
from . import API
|
||||
|
||||
@@ -89,6 +88,8 @@ def list_system_storage_devices() -> Blockdevices:
|
||||
A list of detected block devices with metadata like size, path, type, etc.
|
||||
|
||||
"""
|
||||
from clan_lib.nix import nix_shell # noqa: PLC0415
|
||||
|
||||
cmd = nix_shell(
|
||||
["util-linux"],
|
||||
[
|
||||
@@ -123,7 +124,7 @@ def get_clan_directory_relative(flake: Flake) -> str:
|
||||
ClanError: If the flake evaluation fails or directories cannot be found
|
||||
|
||||
"""
|
||||
from clan_lib.dirs import get_clan_directories
|
||||
from clan_lib.dirs import get_clan_directories # noqa: PLC0415
|
||||
|
||||
_, relative_dir = get_clan_directories(flake)
|
||||
return relative_dir
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
from dataclasses import dataclass, field
|
||||
from enum import Enum
|
||||
from pathlib import Path
|
||||
from typing import Any, Literal, TypedDict
|
||||
|
||||
@@ -334,8 +335,6 @@ def test_literal_field() -> None:
|
||||
|
||||
|
||||
def test_enum_roundtrip() -> None:
|
||||
from enum import Enum
|
||||
|
||||
class MyEnum(Enum):
|
||||
FOO = "abc"
|
||||
BAR = 2
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
from dataclasses import dataclass, field
|
||||
from enum import Enum
|
||||
|
||||
# Functions to test
|
||||
from clan_lib.api import (
|
||||
@@ -124,8 +125,6 @@ def test_filters_null_fields() -> None:
|
||||
|
||||
|
||||
def test_custom_enum() -> None:
|
||||
from enum import Enum
|
||||
|
||||
class CustomEnum(Enum):
|
||||
FOO = "foo"
|
||||
BAR = "bar"
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
from dataclasses import dataclass, field
|
||||
from typing import Any, NotRequired, Required
|
||||
from enum import Enum
|
||||
from typing import Any, Generic, NotRequired, Required, TypedDict, TypeVar
|
||||
|
||||
import pytest
|
||||
|
||||
@@ -27,8 +28,6 @@ def test_simple_primitives() -> None:
|
||||
|
||||
|
||||
def test_enum_type() -> None:
|
||||
from enum import Enum
|
||||
|
||||
class Color(Enum):
|
||||
RED = "red"
|
||||
GREEN = "green"
|
||||
@@ -224,8 +223,6 @@ def test_nested_open_dicts() -> None:
|
||||
|
||||
|
||||
def test_type_variables() -> None:
|
||||
from typing import Generic, TypeVar
|
||||
|
||||
T = TypeVar("T")
|
||||
|
||||
@dataclass
|
||||
@@ -254,8 +251,6 @@ def test_type_variables() -> None:
|
||||
def test_type_variable_nested_scopes() -> None:
|
||||
# Define two type variables with the same name "T" but in different scopes
|
||||
|
||||
from typing import Generic, TypeVar
|
||||
|
||||
T = TypeVar("T")
|
||||
|
||||
@dataclass
|
||||
@@ -284,8 +279,6 @@ def test_type_variable_nested_scopes() -> None:
|
||||
|
||||
|
||||
def test_total_typed_dict() -> None:
|
||||
from typing import TypedDict
|
||||
|
||||
class ExampleTypedDict(TypedDict):
|
||||
name: str
|
||||
value: NotRequired[int]
|
||||
@@ -314,8 +307,6 @@ def test_total_typed_dict() -> None:
|
||||
|
||||
|
||||
def test_open_typed_dict() -> None:
|
||||
from typing import TypedDict
|
||||
|
||||
class ExampleTypedDict(TypedDict, total=False):
|
||||
name: Required[str]
|
||||
value: int
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
import sys
|
||||
@@ -6,7 +7,9 @@ from enum import Enum
|
||||
from pathlib import Path
|
||||
from typing import TYPE_CHECKING, Protocol
|
||||
|
||||
from clan_lib.cmd import run
|
||||
from clan_lib.errors import ClanError
|
||||
from clan_lib.nix import nix_eval
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from clan_lib.flake import Flake
|
||||
@@ -198,12 +201,6 @@ def get_clan_directories(flake: "Flake") -> tuple[str, str]:
|
||||
ClanError: If the flake evaluation fails or directories cannot be found
|
||||
|
||||
"""
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
from clan_lib.cmd import run
|
||||
from clan_lib.nix import nix_eval
|
||||
|
||||
# Get the source directory from nix store
|
||||
root_directory = flake.select("sourceInfo")
|
||||
|
||||
|
||||
@@ -11,7 +11,16 @@ from pathlib import Path
|
||||
from tempfile import NamedTemporaryFile
|
||||
from typing import Any
|
||||
|
||||
from clan_lib.cmd import Log, RunOpts, run
|
||||
from clan_lib.dirs import select_source, user_cache_dir
|
||||
from clan_lib.errors import ClanCmdError, ClanError
|
||||
from clan_lib.nix import (
|
||||
nix_build,
|
||||
nix_command,
|
||||
nix_config,
|
||||
nix_metadata,
|
||||
nix_test_store,
|
||||
)
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
@@ -851,11 +860,6 @@ class Flake:
|
||||
|
||||
def prefetch(self) -> None:
|
||||
"""Loads the flake into the store and populates self.store_path and self.hash such that the flake can evaluate locally and offline"""
|
||||
from clan_lib.cmd import RunOpts, run
|
||||
from clan_lib.nix import (
|
||||
nix_command,
|
||||
)
|
||||
|
||||
if self.nix_options is None:
|
||||
self.nix_options = []
|
||||
|
||||
@@ -895,11 +899,6 @@ class Flake:
|
||||
|
||||
This method is used to refresh the cache by reloading it from the flake.
|
||||
"""
|
||||
from clan_lib.dirs import user_cache_dir
|
||||
from clan_lib.nix import (
|
||||
nix_metadata,
|
||||
)
|
||||
|
||||
self.prefetch()
|
||||
|
||||
self._cache = FlakeCache()
|
||||
@@ -951,14 +950,6 @@ class Flake:
|
||||
AssertionError: If the cache or flake cache path is not properly initialized.
|
||||
|
||||
"""
|
||||
from clan_lib.cmd import Log, RunOpts, run
|
||||
from clan_lib.dirs import select_source
|
||||
from clan_lib.nix import (
|
||||
nix_build,
|
||||
nix_config,
|
||||
nix_test_store,
|
||||
)
|
||||
|
||||
if self._cache is None:
|
||||
self.invalidate_cache()
|
||||
if self._cache is None:
|
||||
@@ -1125,8 +1116,6 @@ class Flake:
|
||||
apply: Optional function to apply to the result
|
||||
|
||||
"""
|
||||
from clan_lib.nix import nix_config
|
||||
|
||||
config = nix_config()
|
||||
system = config["system"]
|
||||
|
||||
|
||||
@@ -360,11 +360,6 @@ def test_store_path_with_line_numbers_not_wrapped() -> None:
|
||||
|
||||
def test_store_reference_helpers() -> None:
|
||||
"""Test the store reference helper functions."""
|
||||
from clan_lib.flake.flake import (
|
||||
find_store_references,
|
||||
is_pure_store_path,
|
||||
)
|
||||
|
||||
# Test find_store_references
|
||||
assert find_store_references("/nix/store/abc123-pkg") == ["/nix/store/abc123-pkg"]
|
||||
assert find_store_references("/nix/store/abc123-file.nix:42") == [
|
||||
|
||||
@@ -7,6 +7,7 @@ from tempfile import TemporaryDirectory
|
||||
from typing import Any, Literal
|
||||
|
||||
from clan_cli.facts.generate import generate_facts
|
||||
from clan_cli.vars.generator import Generator
|
||||
from clan_cli.vars.upload import populate_secret_vars
|
||||
|
||||
from clan_lib.api import API
|
||||
@@ -116,8 +117,6 @@ def run_machine_flash(
|
||||
"users": {"root": {"openssh": {"authorizedKeys": {"keys": root_keys}}}},
|
||||
}
|
||||
|
||||
from clan_cli.vars.generator import Generator
|
||||
|
||||
for generator in Generator.get_machine_generators(
|
||||
[machine.name], machine.flake
|
||||
):
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import importlib.util
|
||||
import sys
|
||||
import tempfile
|
||||
from pathlib import Path
|
||||
from textwrap import dedent
|
||||
@@ -52,8 +54,6 @@ def test_import_with_source(tmp_path: Path) -> None:
|
||||
)
|
||||
|
||||
# Add the temp directory to sys.path
|
||||
import sys
|
||||
|
||||
sys.path.insert(0, str(tmp_path))
|
||||
|
||||
try:
|
||||
@@ -130,9 +130,6 @@ def test_import_with_source_with_args() -> None:
|
||||
temp_file = Path(f.name)
|
||||
|
||||
# Import module dynamically
|
||||
import importlib.util
|
||||
import sys
|
||||
|
||||
spec = importlib.util.spec_from_file_location("temp_module", temp_file)
|
||||
assert spec is not None
|
||||
assert spec.loader is not None
|
||||
|
||||
@@ -5,7 +5,6 @@ from contextlib import contextmanager
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
from clan_lib.dirs import user_history_file
|
||||
from clan_lib.jsonrpc import ClanJSONEncoder
|
||||
|
||||
|
||||
@@ -19,11 +18,15 @@ def locked_open(filename: Path, mode: str = "r") -> Generator:
|
||||
|
||||
|
||||
def write_history_file(data: Any) -> None:
|
||||
from clan_lib.dirs import user_history_file # noqa: PLC0415
|
||||
|
||||
with locked_open(user_history_file(), "w+") as f:
|
||||
f.write(json.dumps(data, cls=ClanJSONEncoder, indent=4))
|
||||
|
||||
|
||||
def read_history_file() -> list[dict]:
|
||||
from clan_lib.dirs import user_history_file # noqa: PLC0415
|
||||
|
||||
with locked_open(user_history_file(), "r") as f:
|
||||
content: str = f.read()
|
||||
parsed: list[dict] = json.loads(content)
|
||||
|
||||
@@ -4,11 +4,13 @@ Tests are based on actual usage patterns from example_usage.py and api.py.
|
||||
"""
|
||||
|
||||
import datetime
|
||||
import tempfile
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
from clan_lib.log_manager import (
|
||||
LogFile,
|
||||
LogGroupConfig,
|
||||
LogManager,
|
||||
is_correct_day_format,
|
||||
@@ -472,8 +474,6 @@ class TestLogFileSorting:
|
||||
configured_log_manager: LogManager,
|
||||
) -> None:
|
||||
"""Test that LogFiles are sorted by datetime (newest first)."""
|
||||
from clan_lib.log_manager import LogFile
|
||||
|
||||
# Create LogFiles with different times (same date)
|
||||
newer_file = LogFile(
|
||||
op_key="test_op",
|
||||
@@ -508,8 +508,6 @@ class TestLogFileSorting:
|
||||
configured_log_manager: LogManager,
|
||||
) -> None:
|
||||
"""Test that LogFiles are sorted by date (newer dates first)."""
|
||||
from clan_lib.log_manager import LogFile
|
||||
|
||||
# Create LogFiles with different dates
|
||||
newer_date_file = LogFile(
|
||||
op_key="test_op",
|
||||
@@ -543,8 +541,6 @@ class TestLogFileSorting:
|
||||
configured_log_manager: LogManager,
|
||||
) -> None:
|
||||
"""Test that LogFiles with same datetime are sorted by group name (alphabetical)."""
|
||||
from clan_lib.log_manager import LogFile
|
||||
|
||||
# Create LogFiles with same datetime but different groups
|
||||
group_a_file = LogFile(
|
||||
op_key="test_op",
|
||||
@@ -579,8 +575,6 @@ class TestLogFileSorting:
|
||||
configured_log_manager: LogManager,
|
||||
) -> None:
|
||||
"""Test that LogFiles with same datetime and group are sorted by func_name (alphabetical)."""
|
||||
from clan_lib.log_manager import LogFile
|
||||
|
||||
# Create LogFiles with same datetime and group but different func_names
|
||||
func_a_file = LogFile(
|
||||
op_key="test_op",
|
||||
@@ -614,8 +608,6 @@ class TestLogFileSorting:
|
||||
configured_log_manager: LogManager,
|
||||
) -> None:
|
||||
"""Test that LogFiles with same datetime, group, and func_name are sorted by op_key (alphabetical)."""
|
||||
from clan_lib.log_manager import LogFile
|
||||
|
||||
# Create LogFiles identical except for op_key
|
||||
op_a_file = LogFile(
|
||||
op_key="op_a", # Should sort first alphabetically
|
||||
@@ -649,8 +641,6 @@ class TestLogFileSorting:
|
||||
configured_log_manager: LogManager,
|
||||
) -> None:
|
||||
"""Test complex sorting with multiple LogFiles demonstrating full sort order."""
|
||||
from clan_lib.log_manager import LogFile
|
||||
|
||||
# Create multiple files with different characteristics
|
||||
files = [
|
||||
# Oldest datetime, should be last
|
||||
@@ -813,8 +803,6 @@ class TestLogFileSorting:
|
||||
"""Test that list_log_days returns days sorted newest first."""
|
||||
del configured_log_manager # Unused but kept for API compatibility
|
||||
# Create log files on different days by manipulating the date
|
||||
import tempfile
|
||||
|
||||
# Create files with different dates manually to test sorting
|
||||
with tempfile.TemporaryDirectory() as tmp_dir:
|
||||
base_dir = Path(tmp_dir)
|
||||
|
||||
@@ -33,7 +33,7 @@ class Machine:
|
||||
|
||||
def get_inv_machine(self) -> "InventoryMachine":
|
||||
# Import on demand to avoid circular imports
|
||||
from clan_lib.machines.actions import get_machine
|
||||
from clan_lib.machines.actions import get_machine # noqa: PLC0415
|
||||
|
||||
return get_machine(self.flake, self.name)
|
||||
|
||||
@@ -121,7 +121,7 @@ class Machine:
|
||||
return self.flake.path
|
||||
|
||||
def target_host(self) -> Remote:
|
||||
from clan_lib.network.network import get_best_remote
|
||||
from clan_lib.network.network import get_best_remote # noqa: PLC0415
|
||||
|
||||
with get_best_remote(self) as remote:
|
||||
return remote
|
||||
|
||||
@@ -42,7 +42,7 @@ def _suggest_similar_names(
|
||||
|
||||
|
||||
def get_available_machines(flake: Flake) -> list[str]:
|
||||
from clan_lib.machines.list import list_machines
|
||||
from clan_lib.machines.list import list_machines # noqa: PLC0415
|
||||
|
||||
machines = list_machines(flake)
|
||||
return list(machines.keys())
|
||||
|
||||
@@ -34,7 +34,7 @@ class Peer:
|
||||
_var: dict[str, str] = self._host["var"]
|
||||
machine_name = _var["machine"]
|
||||
generator = _var["generator"]
|
||||
from clan_lib.machines.machines import Machine
|
||||
from clan_lib.machines.machines import Machine # noqa: PLC0415
|
||||
|
||||
machine = Machine(name=machine_name, flake=self.flake)
|
||||
var = get_machine_var(
|
||||
|
||||
@@ -47,8 +47,6 @@ class NetworkTechnology(NetworkTechnologyBase):
|
||||
yield network
|
||||
|
||||
def remote(self, peer: Peer) -> "Remote":
|
||||
from clan_lib.ssh.remote import Remote
|
||||
|
||||
return Remote(
|
||||
address=peer.host,
|
||||
command_prefix=peer.name,
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import logging
|
||||
import socket
|
||||
import time
|
||||
from collections.abc import Iterator
|
||||
from contextlib import contextmanager
|
||||
@@ -70,8 +71,6 @@ class TorCheck:
|
||||
|
||||
def tor_online_test(proxy_port: int) -> None:
|
||||
"""Tests if Tor is online by checking if we can establish a SOCKS5 connection."""
|
||||
import socket
|
||||
|
||||
# Try to establish a SOCKS5 handshake with the Tor proxy
|
||||
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
sock.settimeout(2.0) # Short timeout for local connection
|
||||
|
||||
@@ -8,7 +8,6 @@ from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
from clan_lib.cmd import run
|
||||
from clan_lib.dirs import nixpkgs_flake, nixpkgs_source
|
||||
from clan_lib.errors import ClanError
|
||||
from clan_lib.locked_open import locked_open
|
||||
|
||||
@@ -89,6 +88,8 @@ def nix_eval(flags: list[str]) -> list[str]:
|
||||
],
|
||||
)
|
||||
if os.environ.get("IN_NIX_SANDBOX"):
|
||||
from clan_lib.dirs import nixpkgs_source # noqa: PLC0415
|
||||
|
||||
return [
|
||||
*default_flags,
|
||||
"--override-input",
|
||||
@@ -168,6 +169,9 @@ def nix_shell(packages: list[str], cmd: list[str]) -> list[str]:
|
||||
] + [package for package in packages if "#" in package]
|
||||
if not missing_packages:
|
||||
return cmd
|
||||
|
||||
from clan_lib.dirs import nixpkgs_flake # noqa: PLC0415
|
||||
|
||||
return [
|
||||
*nix_command(["shell", "--inputs-from", f"{nixpkgs_flake()!s}"]),
|
||||
*missing_packages,
|
||||
|
||||
@@ -459,12 +459,12 @@ class Remote:
|
||||
self,
|
||||
opts: "ConnectionOptions | None" = None,
|
||||
) -> None:
|
||||
from clan_lib.network.check import check_machine_ssh_reachable
|
||||
from clan_lib.network.check import check_machine_ssh_reachable # noqa: PLC0415
|
||||
|
||||
return check_machine_ssh_reachable(self, opts)
|
||||
|
||||
def check_machine_ssh_login(self) -> None:
|
||||
from clan_lib.network.check import check_machine_ssh_login
|
||||
from clan_lib.network.check import check_machine_ssh_login # noqa: PLC0415
|
||||
|
||||
return check_machine_ssh_login(self)
|
||||
|
||||
@@ -521,7 +521,6 @@ def _parse_ssh_uri(
|
||||
raise ClanError(msg)
|
||||
hostname = result.hostname
|
||||
port = result.port
|
||||
from clan_lib.ssh.remote import Remote
|
||||
|
||||
return Remote(
|
||||
address=hostname,
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import logging
|
||||
from collections.abc import Callable
|
||||
|
||||
from clan_cli.vars import graph
|
||||
from clan_cli.vars.generator import Generator, GeneratorKey
|
||||
from clan_cli.vars.graph import minimal_closure, requested_closure
|
||||
from clan_cli.vars.migration import check_can_migrate, migrate_files
|
||||
@@ -31,8 +32,6 @@ def get_generators(
|
||||
List of generators based on the specified selection and closure mode.
|
||||
|
||||
"""
|
||||
from clan_cli.vars import graph
|
||||
|
||||
machine_names = [machine.name for machine in machines]
|
||||
vars_generators = Generator.get_machine_generators(
|
||||
machine_names,
|
||||
|
||||
Reference in New Issue
Block a user