Adding autorender
This commit is contained in:
+10
-7
@@ -65,10 +65,13 @@ fi
|
|||||||
|
|
||||||
log "autorender start (HEAD $(git -C "$GNOMMO_DIR" rev-parse --short HEAD 2>/dev/null), user $(whoami))"
|
log "autorender start (HEAD $(git -C "$GNOMMO_DIR" rev-parse --short HEAD 2>/dev/null), user $(whoami))"
|
||||||
|
|
||||||
# ── Step 2: render loop — pending `gnommo auto` ────────────────────────────────
|
# ── Step 2: render loop — per-project down → gated render → handoff ────────────
|
||||||
# When gnommo auto lands, replace the placeholder with:
|
# `gnommo auto` scans video* under the cwd, so cd into the repo first. It returns
|
||||||
# cd "$GNOMMO_DIR" && ./venv/bin/python -m gnommo auto 2>&1 | tee -a "$LOG" \
|
# non-zero if any project failed; we ping on that.
|
||||||
# || notify "autorender: gnommo auto reported failures"
|
cd "$GNOMMO_DIR"
|
||||||
log "render step not wired yet (gnommo auto pending) — code-deploy path is live"
|
if ./venv/bin/python -m gnommo auto 2>&1 | tee -a "$LOG"; then
|
||||||
|
log "autorender done (all projects ok)"
|
||||||
log "autorender done"
|
else
|
||||||
|
log "autorender done WITH FAILURES (see log above)"
|
||||||
|
notify "autorender: one or more projects failed on the rig — check autorender.log"
|
||||||
|
fi
|
||||||
|
|||||||
@@ -131,6 +131,7 @@ Examples:
|
|||||||
"grade",
|
"grade",
|
||||||
"all",
|
"all",
|
||||||
"align",
|
"align",
|
||||||
|
"auto",
|
||||||
"import",
|
"import",
|
||||||
"description",
|
"description",
|
||||||
"archive",
|
"archive",
|
||||||
@@ -341,6 +342,8 @@ Examples:
|
|||||||
if args.project is None:
|
if args.project is None:
|
||||||
if action == "pexels" and args.search:
|
if action == "pexels" and args.search:
|
||||||
project_path = Path.cwd() # placeholder; cmd_pexels won't use it in search mode
|
project_path = Path.cwd() # placeholder; cmd_pexels won't use it in search mode
|
||||||
|
elif action == "auto":
|
||||||
|
project_path = Path.cwd() # auto scans this root for video* projects
|
||||||
else:
|
else:
|
||||||
parser.error("argument -p/--project is required")
|
parser.error("argument -p/--project is required")
|
||||||
return 1
|
return 1
|
||||||
@@ -425,6 +428,8 @@ Examples:
|
|||||||
return cmd_all(
|
return cmd_all(
|
||||||
project_path, args.verbose, args.dry_run, args.res, args.force
|
project_path, args.verbose, args.dry_run, args.res, args.force
|
||||||
)
|
)
|
||||||
|
elif action == "auto":
|
||||||
|
return cmd_auto(project_path, args.verbose, args.dry_run, args.res)
|
||||||
elif action == "description":
|
elif action == "description":
|
||||||
return cmd_description(project_path, args.verbose)
|
return cmd_description(project_path, args.verbose)
|
||||||
elif action == "archive":
|
elif action == "archive":
|
||||||
@@ -6171,6 +6176,100 @@ def cmd_all(
|
|||||||
return cmd_up(project_path, verbose, dry_run)
|
return cmd_up(project_path, verbose, dry_run)
|
||||||
|
|
||||||
|
|
||||||
|
# =============================================================================
|
||||||
|
# Auto Command — unattended render driver for the rig (called by autorender.sh)
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
|
||||||
|
def cmd_auto(
|
||||||
|
root: Path,
|
||||||
|
verbose: bool,
|
||||||
|
dry_run: bool,
|
||||||
|
res: str = "full",
|
||||||
|
prod: bool = True,
|
||||||
|
) -> int:
|
||||||
|
"""Unattended per-project driver: down → (commit-gated) render → handoff.
|
||||||
|
|
||||||
|
For every ``video*`` project under ``root`` (default: the current directory,
|
||||||
|
which autorender.sh cd's into), pull the latest tree from the relay, then —
|
||||||
|
only when the project's commits.log has an entry newer than the one this rig
|
||||||
|
last handled — run the gated pipeline (preprocess → trim → render, each of
|
||||||
|
which self-skips when its own inputs are unchanged) and hand the result off.
|
||||||
|
The commit timestamp is the explicit "this is ready" trigger, so incidental
|
||||||
|
file touches don't cause spurious re-renders or version bumps.
|
||||||
|
|
||||||
|
Returns non-zero if any project failed, so autorender.sh can ping on failure.
|
||||||
|
"""
|
||||||
|
from .transfer import cmd_down, _read_log_lines, _last_timestamp, _COMMITS_LOG
|
||||||
|
from .handoff import cmd_handoff
|
||||||
|
from . import state as _state
|
||||||
|
|
||||||
|
projects = sorted(
|
||||||
|
d for d in Path(root).glob("video*")
|
||||||
|
if d.is_dir() and (d / "project.json").exists()
|
||||||
|
)
|
||||||
|
if not projects:
|
||||||
|
print(f" No video* projects with project.json under {root}")
|
||||||
|
return 0
|
||||||
|
|
||||||
|
print(f"=== auto: {len(projects)} project(s) under {root} ===")
|
||||||
|
rendered: list[str] = []
|
||||||
|
skipped: list[str] = []
|
||||||
|
failed: list[tuple[str, str]] = []
|
||||||
|
|
||||||
|
for proj in projects:
|
||||||
|
name = proj.name
|
||||||
|
print(f"\n--- {name} ---")
|
||||||
|
|
||||||
|
# 1. Sync from the relay (brings the newest commits.log + inputs). Skipped
|
||||||
|
# in dry-run so it stays side-effect-free — we just report intent.
|
||||||
|
if not dry_run and cmd_down(proj, verbose, dry_run=False) != 0:
|
||||||
|
print(f" {name}: down failed")
|
||||||
|
failed.append((name, "down"))
|
||||||
|
continue
|
||||||
|
|
||||||
|
# 2. Commit trigger: is commits.log newer than what we last handled here?
|
||||||
|
latest = _last_timestamp(_read_log_lines(proj / _COMMITS_LOG))
|
||||||
|
handled = _state.get_items(proj, "auto").get("handled")
|
||||||
|
if latest is None:
|
||||||
|
print(f" {name}: no commits.log — skipping")
|
||||||
|
skipped.append(name)
|
||||||
|
continue
|
||||||
|
if latest == handled:
|
||||||
|
print(f" {name}: unchanged since {handled} — skipping")
|
||||||
|
skipped.append(name)
|
||||||
|
continue
|
||||||
|
|
||||||
|
print(f" {name}: new commit {latest} (last handled: {handled or 'never'})")
|
||||||
|
if dry_run:
|
||||||
|
print(" [dry-run] would preprocess → trim → render → handoff")
|
||||||
|
rendered.append(name)
|
||||||
|
continue
|
||||||
|
|
||||||
|
# 3. Gated pipeline — each stage self-skips when its inputs are unchanged;
|
||||||
|
# `or` short-circuits at the first non-zero (failing) stage.
|
||||||
|
rc = (
|
||||||
|
cmd_preprocess(proj, verbose, False, force=False, workers=1, res=res)
|
||||||
|
or cmd_trim(proj, verbose, force=False)
|
||||||
|
or cmd_render(proj, verbose, False, res=res, force=False)
|
||||||
|
or cmd_handoff(proj, verbose, None, prod, res)
|
||||||
|
)
|
||||||
|
if rc != 0:
|
||||||
|
print(f" {name}: pipeline failed (rc={rc})")
|
||||||
|
failed.append((name, f"rc={rc}"))
|
||||||
|
continue
|
||||||
|
|
||||||
|
# 4. Record this commit as handled so we don't re-render it next run.
|
||||||
|
_state.record_items(proj, "auto", {"handled": latest})
|
||||||
|
rendered.append(name)
|
||||||
|
|
||||||
|
print("\n=== auto summary ===")
|
||||||
|
print(f" rendered: {', '.join(rendered) or '—'}")
|
||||||
|
print(f" skipped: {', '.join(skipped) or '—'}")
|
||||||
|
print(f" failed: {', '.join(f'{n}({r})' for n, r in failed) or '—'}")
|
||||||
|
return 1 if failed else 0
|
||||||
|
|
||||||
|
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
# Description Command
|
# Description Command
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
|
|||||||
Reference in New Issue
Block a user