fix(ariadne): preserve season paths during extraction

This commit was merged in pull request #13.
This commit is contained in:
2026-09-05 19:36:38 -04:00
parent 675576bff6
commit 8d91550937
4 changed files with 52 additions and 14 deletions

View File

@@ -96,3 +96,5 @@
- In this monorepo, "dotfiles" refers to the dotfiles/NixOS configuration under `src/dotfiles/` and `configs/nixos/`.
- The flake does not currently define `formatter.x86_64-linux`.
Do not use `nix fmt` as a validation command until a formatter is added.
- Ariadne extraction must preserve the game-root season prefix for archived source.
Different game installs can contain compiled scripts with the same internal path.

View File

@@ -18,6 +18,8 @@ The script defaults to `<workspace>/src/ariadne/output`.
This path stays stable when you run the command from inside `src/ariadne`.
Use the game installation directory as the game root.
One run processes all installed season directories.
Extracted archive source keeps the archive path relative to the game root, so files with the same
internal path from different season installs do not overwrite each other.
If `rpycdec` is not available, the script uses `extract-tools.nix` to enter a Nix shell.
Keep the script as a thin orchestration layer.

View File

@@ -68,7 +68,12 @@ say() {
}
game_root=
default_output_root=${BUILD_WORKSPACE_DIRECTORY:-$(pwd)}/src/ariadne/output
script_dir=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)
if [[ -n "${BUILD_WORKSPACE_DIRECTORY:-}" ]]; then
default_output_root=$BUILD_WORKSPACE_DIRECTORY/src/ariadne/output
else
default_output_root=$script_dir/output
fi
output_root=$default_output_root
force=false
original_args=("$@")
@@ -149,20 +154,42 @@ is_renpy_runtime_path() {
[[ "$relative" == renpy/* || "$relative" == */renpy/* ]]
}
source_output_path() {
local relative=$1
local destination_prefix=${2:-}
if [[ -n "$destination_prefix" ]]; then
printf '%s/%s/%s\n' "$source_dir" "$destination_prefix" "$relative"
else
printf '%s/%s\n' "$source_dir" "$relative"
fi
}
source_log_relative() {
local relative=$1
local destination_prefix=${2:-}
if [[ -n "$destination_prefix" ]]; then
printf '%s/%s\n' "$destination_prefix" "$relative"
else
printf '%s\n' "$relative"
fi
}
copy_source_file() {
local input=$1
local input_root=$2
local label=$3
local relative output
local destination_prefix=${4:-}
local relative output log_relative
relative=$(realpath --relative-to="$input_root" "$input")
log_relative=$(source_log_relative "$relative" "$destination_prefix")
if is_renpy_runtime_path "$relative"; then
log "skipped $label Ren'Py runtime source: $relative"
log "skipped $label Ren'Py runtime source: $log_relative"
return
fi
output=$source_dir/$relative
output=$(source_output_path "$relative" "$destination_prefix")
mkdir -p -- "$(dirname -- "$output")"
cp -- "$input" "$output"
record "copied $label source: $relative"
record "copied $label source: $log_relative"
}
copy_loose_source() {
@@ -172,37 +199,43 @@ copy_loose_source() {
decompile_compiled_script() {
local input=$1
local input_root=$2
local relative output_dir log_file
local destination_prefix=${3:-}
local relative output_dir log_file log_relative
relative=$(realpath --relative-to="$input_root" "$input")
log_relative=$(source_log_relative "$relative" "$destination_prefix")
if is_renpy_runtime_path "$relative"; then
log "skipped Ren'Py runtime compiled script: $relative"
log "skipped Ren'Py runtime compiled script: $log_relative"
return
fi
output_dir=$source_dir/$(dirname -- "$relative")
log_file=$logs_dir/decompile-${relative//\//__}.log
output_dir=$(source_output_path "$(dirname -- "$relative")" "$destination_prefix")
log_file=$logs_dir/decompile-${log_relative//\//__}.log
mkdir -p -- "$output_dir"
say "decompiling script: $relative"
say "decompiling script: $log_relative"
RPYCDEC_NO_WARNING=1 rpycdec decompile --output "$output_dir" "$input" > "$log_file" 2>&1
log "decompiled script: $relative"
log "decompiled script: $log_relative"
}
extract_archive() {
local archive=$1
local relative archive_output log_file
local relative archive_output log_file destination_prefix
relative=$(relative_to_game_root "$archive")
archive_output=$work_dir/archives/${relative%.rpa}
log_file=$logs_dir/unrpa-${relative//\//__}.log
destination_prefix=$(dirname -- "$relative")
if [[ "$destination_prefix" == "." ]]; then
destination_prefix=
fi
mkdir -p -- "$archive_output"
say "extracting archive: $relative"
RPYCDEC_NO_WARNING=1 rpycdec unrpa --output "$archive_output" "$archive" > "$log_file" 2>&1
log "extracted archive: $relative"
while IFS= read -r -d '' archived_source; do
copy_source_file "$archived_source" "$archive_output" archived
copy_source_file "$archived_source" "$archive_output" archived "$destination_prefix"
done < <(find "$archive_output" -type f -name '*.rpy' -print0 | sort -z)
while IFS= read -r -d '' compiled; do
decompile_compiled_script "$compiled" "$archive_output"
decompile_compiled_script "$compiled" "$archive_output" "$destination_prefix"
done < <(find "$archive_output" -type f \( -name '*.rpyc' -o -name '*.rpymc' \) -print0 | sort -z)
}

View File

@@ -23,6 +23,7 @@ pkgs.buildEnv {
pkgs.bash
pkgs.coreutils
pkgs.findutils
pkgs.python3
rpycdec
];
}