feat: export draft documents
This commit is contained in:
@@ -24,7 +24,13 @@ from wf_cli.commands.draft_options import (
|
||||
)
|
||||
from wf_cli.context import load_cli_context_from_typer as load_cli_context
|
||||
from wf_cli.formats import ListOutputFormat, emit_list_payload
|
||||
from wf_cli.io import CliInputError, emit_json, parse_bindings, parse_json_value
|
||||
from wf_cli.io import (
|
||||
CliInputError,
|
||||
emit_json,
|
||||
parse_bindings,
|
||||
parse_json_value,
|
||||
write_json_file,
|
||||
)
|
||||
from wf_cli.remote_errors import run_cli_operation
|
||||
|
||||
app = typer.Typer(
|
||||
@@ -88,6 +94,35 @@ def inspect_draft(
|
||||
)
|
||||
|
||||
|
||||
@app.command("export")
|
||||
def export_draft(
|
||||
ctx: typer.Context,
|
||||
workspace_id: Annotated[str, typer.Argument(help="Draft workspace id.")],
|
||||
output: Annotated[Path, typer.Option("--output", help="Destination JSON file.")],
|
||||
force: Annotated[
|
||||
bool, typer.Option("--force", help="Replace an existing destination file.")
|
||||
] = False,
|
||||
) -> None:
|
||||
"""Export only the exact draft document from an existing workspace."""
|
||||
context = load_cli_context(ctx)
|
||||
payload = run_cli_operation(
|
||||
context,
|
||||
context.handlers.get_draft_workspace(
|
||||
workspace_id=workspace_id,
|
||||
include_draft=True,
|
||||
),
|
||||
)
|
||||
draft = payload.get("draft")
|
||||
if not isinstance(draft, dict):
|
||||
raise typer.BadParameter(
|
||||
"draft workspace response does not contain a draft object"
|
||||
)
|
||||
try:
|
||||
write_json_file(output, draft, force=force)
|
||||
except CliInputError as exc:
|
||||
raise typer.BadParameter(str(exc)) from exc
|
||||
|
||||
|
||||
@app.command("create")
|
||||
def create_draft(
|
||||
ctx: typer.Context,
|
||||
|
||||
@@ -47,6 +47,21 @@ def emit_json(payload: Any) -> None:
|
||||
print(json.dumps(payload, indent=2, sort_keys=True))
|
||||
|
||||
|
||||
def write_json_file(path: Path, payload: Any, *, force: bool) -> None:
|
||||
"""Write stable formatted JSON while refusing accidental replacement."""
|
||||
mode = "w" if force else "x"
|
||||
try:
|
||||
with path.open(mode, encoding="utf-8", newline="\n") as output:
|
||||
output.write(json.dumps(payload, indent=2, sort_keys=True))
|
||||
output.write("\n")
|
||||
except FileExistsError as exc:
|
||||
raise CliInputError(
|
||||
f"file {path!s} already exists; use --force to replace it"
|
||||
) from exc
|
||||
except OSError as exc:
|
||||
raise CliInputError(f"could not write file {path!s}: {exc}") from exc
|
||||
|
||||
|
||||
def parse_bindings(bindings: list[str]) -> dict[str, str]:
|
||||
"""Parse repeatable logical=concrete source binding flags."""
|
||||
parsed: dict[str, str] = {}
|
||||
|
||||
Reference in New Issue
Block a user