diff --git a/trobz_deploy/command/configure.py b/trobz_deploy/command/configure.py index bbf0f80..7c356c6 100644 --- a/trobz_deploy/command/configure.py +++ b/trobz_deploy/command/configure.py @@ -120,6 +120,10 @@ def configure( # noqa: C901 except ExecutorError: click.secho(f"\nCreating instance directory ~/{instance_name}…", fg="green") executor.run(f"mkdir -p {instance_path}") + elif eff_type == "service" and not eff_repo_url: + # Binary/system service mode: no repo, just ensure a working directory exists + click.secho(f"\nCreating instance directory ~/{instance_name}…", fg="green") + executor.run(f"mkdir -p {instance_path}") else: if not eff_repo_url: msg = click.style( @@ -171,13 +175,8 @@ def configure( # noqa: C901 ) else: # service build_cmd: str | None = opts.get("build") - if not build_cmd: - msg = click.style( - "build command is required for service type. Set it in deploy.yml.", - fg="red", - ) - raise click.ClickException(msg) - executor.run(build_cmd, cwd=service_path) + if build_cmd: + executor.run(build_cmd, cwd=service_path) except ExecutorError as exc: raise click.ClickException(click.style(str(exc), fg="red")) from exc diff --git a/trobz_deploy/command/status.py b/trobz_deploy/command/status.py index 9b90b05..b0c6817 100644 --- a/trobz_deploy/command/status.py +++ b/trobz_deploy/command/status.py @@ -6,6 +6,36 @@ from trobz_deploy.utils.executor import Executor, ExecutorError +def _get_unit_line(executor: Executor, instance_name: str) -> str: + try: + raw = executor.capture( + f"systemctl --user show {instance_name} --property=ActiveState,SubState,ActiveEnterTimestamp" + ) + except ExecutorError: + return "unknown" + props: dict[str, str] = {} + for line in raw.splitlines(): + if "=" in line: + key, _, val = line.partition("=") + props[key.strip()] = val.strip() + active = props.get("ActiveState", "unknown") + sub = props.get("SubState", "unknown") + ts = props.get("ActiveEnterTimestamp", "") + # Timestamp format: "Mon 2026-03-09 08:12:03 UTC" + since = " ".join(ts.split()[1:3]) if ts else "" + unit_line = f"{active} ({sub})" + if since: + unit_line += f" since {since}" + return unit_line + + +def _get_git_info(executor: Executor, instance_path: str) -> tuple[str, str, str]: + remote_url = executor.capture("git remote get-url origin", cwd=instance_path) + branch = executor.capture("git rev-parse --abbrev-ref HEAD", cwd=instance_path) + commit = executor.capture("git rev-parse --short HEAD", cwd=instance_path) + return remote_url, branch, commit + + @click.command() @click.argument("instance_name") @click.argument("ssh_host", required=False) @@ -49,41 +79,23 @@ def status( msg = f"Instance directory not found: ~/{instance_name}" raise click.ClickException(msg) from None - # Step 3: Git info - try: - remote_url = executor.capture("git remote get-url origin", cwd=instance_path) - branch = executor.capture("git rev-parse --abbrev-ref HEAD", cwd=instance_path) - commit = executor.capture("git rev-parse --short HEAD", cwd=instance_path) - except ExecutorError as exc: - msg = f"Failed to get git info: {exc}" - raise click.ClickException(msg) from exc + # Step 3: Git info (skipped for no-repo service instances) + has_repo = bool(cfg.get("repo_url")) + remote_url = branch = commit = None + if has_repo: + try: + remote_url, branch, commit = _get_git_info(executor, instance_path) + except ExecutorError as exc: + msg = f"Failed to get git info: {exc}" + raise click.ClickException(msg) from exc # Step 4: systemd unit status - unit_line = "unknown" - try: - raw = executor.capture( - f"systemctl --user show {instance_name} --property=ActiveState,SubState,ActiveEnterTimestamp" - ) - props: dict[str, str] = {} - for line in raw.splitlines(): - if "=" in line: - key, _, val = line.partition("=") - props[key.strip()] = val.strip() - - active = props.get("ActiveState", "unknown") - sub = props.get("SubState", "unknown") - ts = props.get("ActiveEnterTimestamp", "") - # Timestamp format: "Mon 2026-03-09 08:12:03 UTC" - since = " ".join(ts.split()[1:3]) if ts else "" - unit_line = f"{active} ({sub})" - if since: - unit_line += f" since {since}" - except ExecutorError: - pass + unit_line = _get_unit_line(executor, instance_name) click.echo(f"Instance: {instance_name}") - click.echo(f"Remote: {remote_url}") - click.echo(f"Branch: {branch} ({commit})") + if has_repo: + click.echo(f"Remote: {remote_url}") + click.echo(f"Branch: {branch} ({commit})") click.echo(f"Unit: {unit_line}") if watch: diff --git a/trobz_deploy/command/update.py b/trobz_deploy/command/update.py index ad86c1f..067bcfc 100644 --- a/trobz_deploy/command/update.py +++ b/trobz_deploy/command/update.py @@ -147,6 +147,9 @@ def run_hooks(hook_name: str) -> bool: run_hooks("post-update-fail") msg = click.style(f"Package upgrade failed: {exc}", fg="red") raise click.ClickException(msg) from exc + elif eff_type == "service" and not opts.get("repo_url"): + # Binary/system service mode: no repo to pull, skip straight to restart + click.secho("\nNo repository to update, skipping pull…", fg="yellow") else: # Repo mode: git pull then update deps try: