from dataclasses import dataclass from pathlib import Path from typing import Self import argparse import sys import json @dataclass class Config: source_lock: Path = Path.home() / ".hive/flake.lock" source_nixpkgs: str = "nixpkgs-unstable" target_lock: Path = Path.cwd() / "flake.lock" dry: bool = False @classmethod def load(cls, paths: list[Path]) -> Self: c = cls() args = cls.argparse() c.dry = args.dry # Target lock can only be set via args if args.target_lock: c.target_lock = Path(args.target_lock) # We do not need to read config files. if args.source_lock: c.source_lock = Path(args.source_lock) return c # Check if source_lock is set somewhere for p in paths: if not p.exists(): continue with p.open(mode="r") as f: cfg = json.load(f) c.source_lock = Path(cfg["source_lock"]) c.source_nixpkgs = cfg["source_nixpkgs"] break return c @staticmethod def argparse() -> argparse.Namespace: args = argparse.ArgumentParser() args.add_argument( "--source_lock", type=Path, default=None, required=False, help="The flake.lock file to read nixpkgs from.", ) args.add_argument( "--source_nixpkgs", type=Path, default=None, required=False, help="The nixpkgs in flake.lock to use.", ) args.add_argument( "--target_lock", type=Path, default=None, required=False, help="The flake.lock file to write nixpkgs to. Use CWD/flake.lock if unset", ) args.add_argument( "--dry", action="store_true", help="Only show what would be done.", ) return args.parse_args(sys.argv[1:])