rojo/tools/atlas-daemon/atlas_daemon/atlas_cli.py
Joe 9934094dbc Enhance Roblox API integration and refactor CLI commands
- Updated the `clap` dependency in `Cargo.toml` to include the "env" feature for improved command-line argument handling.
- Introduced a new `roblox_api` module to encapsulate Roblox API interactions, including authentication and asset downloading.
- Refactored the `CloneCommand` and `StudioCommand` to utilize the new `roblox_api` functions for fetching experience names and universe IDs, enhancing code clarity and reducing duplication.
- Removed obsolete functions related to Roblox API calls from the CLI commands, streamlining the codebase.
- Added error handling for authentication failures, ensuring better user feedback when required credentials are missing.

These changes aim to improve the overall structure and functionality of the CLI while enhancing the integration with the Roblox API.
2026-03-01 20:03:40 -06:00

101 lines
2.4 KiB
Python

from __future__ import annotations
import asyncio
import logging
from pathlib import Path
log = logging.getLogger(__name__)
async def _run(
*cmd: str, cwd: Path | None = None, timeout: float = 300
) -> tuple[str, str]:
proc = await asyncio.create_subprocess_exec(
*cmd,
stdout=asyncio.subprocess.PIPE,
stderr=asyncio.subprocess.PIPE,
cwd=str(cwd) if cwd else None,
)
stdout_bytes, stderr_bytes = await asyncio.wait_for(
proc.communicate(), timeout=timeout
)
stdout = stdout_bytes.decode(errors="replace") if stdout_bytes else ""
stderr = stderr_bytes.decode(errors="replace") if stderr_bytes else ""
if proc.returncode != 0:
raise RuntimeError(
f"Command failed (exit {proc.returncode}): {' '.join(cmd)}\n{stderr}"
)
return stdout, stderr
async def atlas_clone(
atlas_binary: str,
place_id: int,
path: Path,
opencloud_key: str,
) -> None:
log.info("Cloning place %d into %s", place_id, path)
await _run(
atlas_binary,
"--opencloud",
opencloud_key,
"clone",
str(place_id),
"--path",
str(path),
"--skip-git",
"--skip-rules",
timeout=600,
)
async def atlas_syncback(
atlas_binary: str,
working_dir: Path,
place_id: int,
opencloud_key: str,
) -> str:
log.info("Syncing place %d in %s", place_id, working_dir)
stdout, _ = await _run(
atlas_binary,
"--opencloud",
opencloud_key,
"syncback",
"--download",
str(place_id),
"--working-dir",
str(working_dir),
"--incremental",
"--list",
timeout=600,
)
return stdout
async def git_init(cwd: Path) -> None:
await _run("git", "init", cwd=cwd)
async def git_add_all(cwd: Path) -> None:
await _run("git", "add", ".", cwd=cwd)
async def git_commit(cwd: Path, message: str) -> None:
await _run("git", "commit", "-m", message, "--allow-empty", cwd=cwd)
async def git_diff(cwd: Path) -> str:
try:
stdout, _ = await _run("git", "diff", "HEAD", cwd=cwd)
return stdout
except RuntimeError:
return ""
async def git_diff_name_only(cwd: Path) -> list[str]:
try:
stdout, _ = await _run("git", "diff", "HEAD", "--name-only", cwd=cwd)
return [line.strip() for line in stdout.splitlines() if line.strip()]
except RuntimeError:
return []