fix(clew): collect compiled script archives
This commit is contained in:
@@ -11,7 +11,8 @@ bazel run //src/clew -- \
|
|||||||
--force
|
--force
|
||||||
```
|
```
|
||||||
|
|
||||||
The first version copies loose `.rpy` files and extracts `.rpy` files from `.rpa` archives.
|
The first version copies loose `.rpy` files and collects compiled script files.
|
||||||
|
It extracts `.rpy`, `.rpyc`, and `.rpymc` files from `.rpa` archives.
|
||||||
It writes output under `source/`, `work/`, and `logs/`.
|
It writes output under `source/`, `work/`, and `logs/`.
|
||||||
|
|
||||||
Use `--force` to replace those Clew-managed directories.
|
Use `--force` to replace those Clew-managed directories.
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ from rpycdec.rpa import extract_rpa
|
|||||||
|
|
||||||
LOGGER = logging.getLogger("clew")
|
LOGGER = logging.getLogger("clew")
|
||||||
MANAGED_DIRS = ("source", "work", "logs")
|
MANAGED_DIRS = ("source", "work", "logs")
|
||||||
|
SCRIPT_SUFFIXES = (".rpy", ".rpyc", ".rpymc")
|
||||||
|
|
||||||
|
|
||||||
def parse_args(argv: list[str]) -> argparse.Namespace:
|
def parse_args(argv: list[str]) -> argparse.Namespace:
|
||||||
@@ -49,6 +50,17 @@ def fail(message: str) -> None:
|
|||||||
raise SystemExit(f"clew: {message}")
|
raise SystemExit(f"clew: {message}")
|
||||||
|
|
||||||
|
|
||||||
|
def resolve_output_root(output_root: Path) -> Path:
|
||||||
|
if output_root.is_absolute():
|
||||||
|
return output_root.resolve()
|
||||||
|
|
||||||
|
workspace = os.environ.get("BUILD_WORKSPACE_DIRECTORY")
|
||||||
|
if workspace:
|
||||||
|
return (Path(workspace) / output_root).resolve()
|
||||||
|
|
||||||
|
return output_root.resolve()
|
||||||
|
|
||||||
|
|
||||||
def prepare_output(output_root: Path, force: bool) -> tuple[Path, Path, Path]:
|
def prepare_output(output_root: Path, force: bool) -> tuple[Path, Path, Path]:
|
||||||
for name in MANAGED_DIRS:
|
for name in MANAGED_DIRS:
|
||||||
path = output_root / name
|
path = output_root / name
|
||||||
@@ -96,6 +108,18 @@ def copy_source_file(
|
|||||||
LOGGER.info("copied %s source: %s", label, output_relative)
|
LOGGER.info("copied %s source: %s", label, output_relative)
|
||||||
|
|
||||||
|
|
||||||
|
def copy_compiled_file(compiled_file: Path, input_root: Path, work_dir: Path) -> None:
|
||||||
|
relative = relative_to(input_root, compiled_file)
|
||||||
|
if is_renpy_runtime_path(relative):
|
||||||
|
LOGGER.info("skipped Ren'Py runtime compiled script: %s", relative)
|
||||||
|
return
|
||||||
|
|
||||||
|
destination = work_dir / "compiled" / relative
|
||||||
|
destination.parent.mkdir(parents=True, exist_ok=True)
|
||||||
|
shutil.copy2(compiled_file, destination)
|
||||||
|
LOGGER.info("copied compiled script: %s", relative)
|
||||||
|
|
||||||
|
|
||||||
def archive_work_path(work_dir: Path, archive_relative: Path) -> Path:
|
def archive_work_path(work_dir: Path, archive_relative: Path) -> Path:
|
||||||
return work_dir / "archives" / archive_relative.with_suffix("")
|
return work_dir / "archives" / archive_relative.with_suffix("")
|
||||||
|
|
||||||
@@ -114,7 +138,7 @@ def extract_archive(archive: Path, game_root: Path, source_dir: Path, work_dir:
|
|||||||
|
|
||||||
LOGGER.info("extracting archive: %s", archive_relative)
|
LOGGER.info("extracting archive: %s", archive_relative)
|
||||||
with archive.open("rb") as handle:
|
with archive.open("rb") as handle:
|
||||||
extract_rpa(handle, output_dir=str(output_dir), suffixes=[".rpy"])
|
extract_rpa(handle, output_dir=str(output_dir), suffixes=list(SCRIPT_SUFFIXES))
|
||||||
LOGGER.info("extracted archive: %s", archive_relative)
|
LOGGER.info("extracted archive: %s", archive_relative)
|
||||||
|
|
||||||
destination_prefix = archive_destination_prefix(archive_relative)
|
destination_prefix = archive_destination_prefix(archive_relative)
|
||||||
@@ -137,7 +161,7 @@ def configure_logging(logs_dir: Path) -> None:
|
|||||||
|
|
||||||
def run(args: argparse.Namespace) -> None:
|
def run(args: argparse.Namespace) -> None:
|
||||||
game_root = args.game_root.resolve()
|
game_root = args.game_root.resolve()
|
||||||
output_root = args.output_root.resolve()
|
output_root = resolve_output_root(args.output_root)
|
||||||
|
|
||||||
if not game_root.is_dir():
|
if not game_root.is_dir():
|
||||||
fail(f"game root is not a directory: {game_root}")
|
fail(f"game root is not a directory: {game_root}")
|
||||||
@@ -149,6 +173,11 @@ def run(args: argparse.Namespace) -> None:
|
|||||||
for source_file in sorted(game_root.rglob("*.rpy")):
|
for source_file in sorted(game_root.rglob("*.rpy")):
|
||||||
copy_source_file(source_file, game_root, source_dir, "loose")
|
copy_source_file(source_file, game_root, source_dir, "loose")
|
||||||
|
|
||||||
|
LOGGER.info("scanning loose compiled scripts")
|
||||||
|
for suffix in ("*.rpyc", "*.rpymc"):
|
||||||
|
for compiled_file in sorted(game_root.rglob(suffix)):
|
||||||
|
copy_compiled_file(compiled_file, game_root, work_dir)
|
||||||
|
|
||||||
LOGGER.info("scanning archives")
|
LOGGER.info("scanning archives")
|
||||||
for archive in sorted(game_root.rglob("*.rpa")):
|
for archive in sorted(game_root.rglob("*.rpa")):
|
||||||
extract_archive(archive, game_root, source_dir, work_dir)
|
extract_archive(archive, game_root, source_dir, work_dir)
|
||||||
|
|||||||
Reference in New Issue
Block a user