Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 6 additions & 7 deletions trobz_deploy/command/configure.py
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down Expand Up @@ -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

Expand Down
74 changes: 43 additions & 31 deletions trobz_deploy/command/status.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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:
Expand Down
3 changes: 3 additions & 0 deletions trobz_deploy/command/update.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down