fix(ariadne): preserve season paths during extraction
This commit was merged in pull request #13.
This commit is contained in:
@@ -96,3 +96,5 @@
|
|||||||
- In this monorepo, "dotfiles" refers to the dotfiles/NixOS configuration under `src/dotfiles/` and `configs/nixos/`.
|
- 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`.
|
- The flake does not currently define `formatter.x86_64-linux`.
|
||||||
Do not use `nix fmt` as a validation command until a formatter is added.
|
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.
|
||||||
|
|||||||
@@ -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`.
|
This path stays stable when you run the command from inside `src/ariadne`.
|
||||||
Use the game installation directory as the game root.
|
Use the game installation directory as the game root.
|
||||||
One run processes all installed season directories.
|
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.
|
If `rpycdec` is not available, the script uses `extract-tools.nix` to enter a Nix shell.
|
||||||
|
|
||||||
Keep the script as a thin orchestration layer.
|
Keep the script as a thin orchestration layer.
|
||||||
|
|||||||
@@ -68,7 +68,12 @@ say() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
game_root=
|
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
|
output_root=$default_output_root
|
||||||
force=false
|
force=false
|
||||||
original_args=("$@")
|
original_args=("$@")
|
||||||
@@ -149,20 +154,42 @@ is_renpy_runtime_path() {
|
|||||||
[[ "$relative" == renpy/* || "$relative" == */renpy/* ]]
|
[[ "$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() {
|
copy_source_file() {
|
||||||
local input=$1
|
local input=$1
|
||||||
local input_root=$2
|
local input_root=$2
|
||||||
local label=$3
|
local label=$3
|
||||||
local relative output
|
local destination_prefix=${4:-}
|
||||||
|
local relative output log_relative
|
||||||
relative=$(realpath --relative-to="$input_root" "$input")
|
relative=$(realpath --relative-to="$input_root" "$input")
|
||||||
|
log_relative=$(source_log_relative "$relative" "$destination_prefix")
|
||||||
if is_renpy_runtime_path "$relative"; then
|
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
|
return
|
||||||
fi
|
fi
|
||||||
output=$source_dir/$relative
|
output=$(source_output_path "$relative" "$destination_prefix")
|
||||||
mkdir -p -- "$(dirname -- "$output")"
|
mkdir -p -- "$(dirname -- "$output")"
|
||||||
cp -- "$input" "$output"
|
cp -- "$input" "$output"
|
||||||
record "copied $label source: $relative"
|
record "copied $label source: $log_relative"
|
||||||
}
|
}
|
||||||
|
|
||||||
copy_loose_source() {
|
copy_loose_source() {
|
||||||
@@ -172,37 +199,43 @@ copy_loose_source() {
|
|||||||
decompile_compiled_script() {
|
decompile_compiled_script() {
|
||||||
local input=$1
|
local input=$1
|
||||||
local input_root=$2
|
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")
|
relative=$(realpath --relative-to="$input_root" "$input")
|
||||||
|
log_relative=$(source_log_relative "$relative" "$destination_prefix")
|
||||||
if is_renpy_runtime_path "$relative"; then
|
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
|
return
|
||||||
fi
|
fi
|
||||||
output_dir=$source_dir/$(dirname -- "$relative")
|
output_dir=$(source_output_path "$(dirname -- "$relative")" "$destination_prefix")
|
||||||
log_file=$logs_dir/decompile-${relative//\//__}.log
|
log_file=$logs_dir/decompile-${log_relative//\//__}.log
|
||||||
mkdir -p -- "$output_dir"
|
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
|
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() {
|
extract_archive() {
|
||||||
local archive=$1
|
local archive=$1
|
||||||
local relative archive_output log_file
|
local relative archive_output log_file destination_prefix
|
||||||
relative=$(relative_to_game_root "$archive")
|
relative=$(relative_to_game_root "$archive")
|
||||||
archive_output=$work_dir/archives/${relative%.rpa}
|
archive_output=$work_dir/archives/${relative%.rpa}
|
||||||
log_file=$logs_dir/unrpa-${relative//\//__}.log
|
log_file=$logs_dir/unrpa-${relative//\//__}.log
|
||||||
|
destination_prefix=$(dirname -- "$relative")
|
||||||
|
if [[ "$destination_prefix" == "." ]]; then
|
||||||
|
destination_prefix=
|
||||||
|
fi
|
||||||
mkdir -p -- "$archive_output"
|
mkdir -p -- "$archive_output"
|
||||||
say "extracting archive: $relative"
|
say "extracting archive: $relative"
|
||||||
RPYCDEC_NO_WARNING=1 rpycdec unrpa --output "$archive_output" "$archive" > "$log_file" 2>&1
|
RPYCDEC_NO_WARNING=1 rpycdec unrpa --output "$archive_output" "$archive" > "$log_file" 2>&1
|
||||||
log "extracted archive: $relative"
|
log "extracted archive: $relative"
|
||||||
|
|
||||||
while IFS= read -r -d '' archived_source; do
|
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)
|
done < <(find "$archive_output" -type f -name '*.rpy' -print0 | sort -z)
|
||||||
|
|
||||||
while IFS= read -r -d '' compiled; do
|
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)
|
done < <(find "$archive_output" -type f \( -name '*.rpyc' -o -name '*.rpymc' \) -print0 | sort -z)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ pkgs.buildEnv {
|
|||||||
pkgs.bash
|
pkgs.bash
|
||||||
pkgs.coreutils
|
pkgs.coreutils
|
||||||
pkgs.findutils
|
pkgs.findutils
|
||||||
|
pkgs.python3
|
||||||
rpycdec
|
rpycdec
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user