diff options
Diffstat (limited to 'src/sailfish_devel_mcp/config.py')
| -rw-r--r-- | src/sailfish_devel_mcp/config.py | 97 |
1 files changed, 97 insertions, 0 deletions
diff --git a/src/sailfish_devel_mcp/config.py b/src/sailfish_devel_mcp/config.py index 73740d1..198b09d 100644 --- a/src/sailfish_devel_mcp/config.py +++ b/src/sailfish_devel_mcp/config.py @@ -12,6 +12,10 @@ DEFAULT_BUS_ADDRESS = "unix:path=/run/user/100000/dbus/user_bus_socket" BUNDLED_BUILD_HELPER = ( Path(__file__).resolve().parent / "vendor" / "build_sailfishos.py" ) +DEFAULT_ANDROID_BUILD_HOST = "android-builder" +DEFAULT_ANDROID_BUILD_SSH_TARGET = "builder@example.invalid" +DEFAULT_ANDROID_BUILD_PROJECT_DIR = "" +DEFAULT_ANDROID_BUILD_STATE_DIR = "/tmp/sailfish-devel-mcp/android-builds" @dataclass(frozen=True) @@ -37,6 +41,33 @@ class DeviceConfig: @dataclass(frozen=True) +class AndroidBuildHostConfig: + name: str + ssh_target: str + project_dir: str + state_dir: str = DEFAULT_ANDROID_BUILD_STATE_DIR + + def public_dict(self) -> dict[str, object]: + return { + "name": self.name, + "ssh_target": self.ssh_target, + "project_dir": self.project_dir, + "state_dir": self.state_dir, + } + + +def default_android_build_hosts() -> dict[str, AndroidBuildHostConfig]: + return { + DEFAULT_ANDROID_BUILD_HOST: AndroidBuildHostConfig( + name=DEFAULT_ANDROID_BUILD_HOST, + ssh_target=DEFAULT_ANDROID_BUILD_SSH_TARGET, + project_dir=DEFAULT_ANDROID_BUILD_PROJECT_DIR, + state_dir=DEFAULT_ANDROID_BUILD_STATE_DIR, + ) + } + + +@dataclass(frozen=True) class PathConfig: git_root: Path = Path.home() / "git" obs_root: Path = Path.home() / "OBS" @@ -62,6 +93,10 @@ class Config: default_device: str devices: Mapping[str, DeviceConfig] = field(default_factory=dict) paths: PathConfig = field(default_factory=PathConfig) + default_android_build_host: str = DEFAULT_ANDROID_BUILD_HOST + android_build_hosts: Mapping[str, AndroidBuildHostConfig] = field( + default_factory=default_android_build_hosts + ) def device(self, name: str | None = None) -> DeviceConfig: key = name or self.default_device @@ -71,6 +106,18 @@ class Config: return DeviceConfig(name=name, ssh_target=name) raise KeyError(f"unknown Sailfish device: {key}") + def android_build_host(self, name: str | None = None) -> AndroidBuildHostConfig: + key = name or self.default_android_build_host + if key in self.android_build_hosts: + return self.android_build_hosts[key] + if name and "@" in name: + return AndroidBuildHostConfig( + name=name, + ssh_target=name, + project_dir=DEFAULT_ANDROID_BUILD_PROJECT_DIR, + ) + raise KeyError(f"unknown Android build host: {key}") + def public_dict(self) -> dict[str, Any]: return { "path": str(self.path) if self.path else None, @@ -79,6 +126,11 @@ class Config: name: device.public_dict() for name, device in self.devices.items() }, "paths": self.paths.public_dict(), + "default_android_build_host": self.default_android_build_host, + "android_build_hosts": { + name: host.public_dict() + for name, host in self.android_build_hosts.items() + }, } @@ -111,11 +163,17 @@ def load_config(path: str | os.PathLike[str] | None = None) -> Config: default_device = str(raw.get("default_device") or next(iter(devices))) paths = _load_paths(raw.get("paths", {})) + android_build_hosts = _load_android_build_hosts(raw.get("android_build_hosts", {})) + default_android_build_host = str( + raw.get("default_android_build_host") or next(iter(android_build_hosts)) + ) return Config( path=config_path if config_path.exists() else None, default_device=default_device, devices=devices, paths=paths, + default_android_build_host=default_android_build_host, + android_build_hosts=android_build_hosts, ) @@ -144,6 +202,45 @@ def _load_devices(raw_devices: Any) -> dict[str, DeviceConfig]: return devices +def _load_android_build_hosts(raw_hosts: Any) -> dict[str, AndroidBuildHostConfig]: + if not isinstance(raw_hosts, dict): + raise ValueError("android_build_hosts must be a JSON object") + + hosts: dict[str, AndroidBuildHostConfig] = {} + for name, value in raw_hosts.items(): + if isinstance(value, str): + value = {"ssh_target": value} + if not isinstance(value, dict): + raise ValueError(f"android build host {name!r} must be a string or object") + hosts[str(name)] = AndroidBuildHostConfig( + name=str(name), + ssh_target=str(value.get("ssh_target") or name), + project_dir=str( + value.get("project_dir") or DEFAULT_ANDROID_BUILD_PROJECT_DIR + ), + state_dir=str(value.get("state_dir") or DEFAULT_ANDROID_BUILD_STATE_DIR), + ) + + if not hosts: + name = os.environ.get("SAILFISH_MCP_ANDROID_BUILD_HOST", DEFAULT_ANDROID_BUILD_HOST) + hosts[name] = AndroidBuildHostConfig( + name=name, + ssh_target=os.environ.get( + "SAILFISH_MCP_ANDROID_BUILD_SSH_TARGET", + DEFAULT_ANDROID_BUILD_SSH_TARGET, + ), + project_dir=os.environ.get( + "SAILFISH_MCP_ANDROID_BUILD_PROJECT_DIR", + DEFAULT_ANDROID_BUILD_PROJECT_DIR, + ), + state_dir=os.environ.get( + "SAILFISH_MCP_ANDROID_BUILD_STATE_DIR", + DEFAULT_ANDROID_BUILD_STATE_DIR, + ), + ) + return hosts + + def _load_paths(raw_paths: Any) -> PathConfig: if not isinstance(raw_paths, dict): raise ValueError("paths must be a JSON object") |
