Arcadelux update script added.

This commit is contained in:
Storm Dragon committed 2026-10-13 15:06:01 -04:00
1 parent 82edcc66b8
commit fd72a85003
5 files changed
+193 -4

No files matched your search

+163
View File
@@ -251,3 +251,166 @@ install_with_progress() {
;;
esac
}
# Return the latest GitHub release tag and one matching asset URL, one per line.
github_latest_release() {
local repo="$1"
local assetFilter="$2"
local response tag
local -a assetUrls=()
if [[ -z "$repo" || "$repo" != */* ]]; then
echo "Expected a GitHub repository in owner/repo format." >&2
return 1
fi
if ! response="$(curl -fsSL --retry 3 "https://api.github.com/repos/${repo}/releases/latest")"; then
echo "Could not fetch the latest release for ${repo}." >&2
return 1
fi
tag="$(sed -n 's/.*"tag_name"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' <<< "$response" | head -n1)"
mapfile -t assetUrls < <(
sed -n 's/.*"browser_download_url"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' <<< "$response"
)
if [[ -n "$assetFilter" ]]; then
mapfile -t assetUrls < <(
printf '%s\n' "${assetUrls[@]}" | grep -iF -- "$assetFilter"
)
fi
if [[ -z "$tag" || ${#assetUrls[@]} -ne 1 ]]; then
echo "Could not identify one matching release asset for ${repo}." >&2
return 1
fi
printf '%s\n%s\n' "$tag" "${assetUrls[0]}"
}
# Install or replace a game from its latest GitHub release.
# Arguments: repository, asset filter, destination, expected executable, and
# zero or more relative paths or files to preserve from the old installation.
update_github_release_game() {
local repo="$1"
local assetFilter="$2"
local destination="$3"
local expectedExecutable="$4"
shift 4
local -a preservePaths=("$@")
local -a releaseInfo=() executablePaths=() pathParts=()
local releaseInfoText installedVersion latestTag latestUrl archiveFile
local stageRoot archiveRoot newRoot executablePath preservePath sourcePath targetPath pathPart
local updateFailed="false"
githubReleaseGameStatus="checking"
destination="${destination%/}"
if [[ -z "$destination" || "$destination" != /* ]]; then
echo "The game destination must be an absolute path." >&2
return 1
fi
for preservePath in "${preservePaths[@]}"; do
if [[ "$preservePath" == /* ]]; then
echo "Preserve paths must be relative to the game directory: ${preservePath}" >&2
return 1
fi
IFS='/' read -r -a pathParts <<< "$preservePath"
for pathPart in "${pathParts[@]}"; do
if [[ -z "$pathPart" || "$pathPart" == "." || "$pathPart" == ".." ]]; then
echo "Invalid preserve path: ${preservePath}" >&2
return 1
fi
done
done
if ! releaseInfoText="$(github_latest_release "$repo" "$assetFilter")"; then
return 1
fi
mapfile -t releaseInfo <<< "$releaseInfoText"
latestTag="${releaseInfo[0]}"
latestUrl="${releaseInfo[1]}"
if [[ -f "${destination}/.agm-version" ]]; then
installedVersion="$(<"${destination}/.agm-version")"
if [[ "$installedVersion" == "$latestTag" && -f "${destination}/${expectedExecutable}" ]]; then
githubReleaseGameStatus="up-to-date"
echo "${game:-The game} is already at ${latestTag}."
return 0
fi
fi
archiveFile="${latestUrl##*/}"
archiveFile="${archiveFile//%20/ }"
archiveFile="${archiveFile#*\?filename=}"
archiveFile="${archiveFile%\?*}"
rm -f "${cache}/${archiveFile}"
download "$latestUrl"
mkdir -p "$(dirname "$destination")"
stageRoot="${destination}.agm-update.$$"
archiveRoot="${stageRoot}/archive"
mkdir -p "$archiveRoot"
if ! unzip -q "${cache}/${archiveFile}" -d "$archiveRoot"; then
echo "Could not extract ${archiveFile}." >&2
rm -rf "$stageRoot"
return 1
fi
mapfile -t executablePaths < <(find "$archiveRoot" -type f -name "$expectedExecutable" -print)
if [[ ${#executablePaths[@]} -ne 1 ]]; then
echo "The release did not contain exactly one ${expectedExecutable}." >&2
rm -rf "$stageRoot"
return 1
fi
executablePath="${executablePaths[0]}"
newRoot="${executablePath%/*}"
for preservePath in "${preservePaths[@]}"; do
sourcePath="${destination}/${preservePath}"
[[ -e "$sourcePath" ]] || continue
targetPath="${newRoot}/${preservePath}"
if [[ -d "$sourcePath" ]]; then
mkdir -p "$targetPath"
if ! cp -a "${sourcePath}/." "$targetPath/"; then
echo "Could not preserve ${preservePath}." >&2
updateFailed="true"
break
fi
else
mkdir -p "${targetPath%/*}"
if ! cp -a "$sourcePath" "$targetPath"; then
echo "Could not preserve ${preservePath}." >&2
updateFailed="true"
break
fi
fi
done
if [[ "$updateFailed" == "true" ]]; then
rm -rf "$stageRoot"
return 1
fi
printf '%s\n' "$latestTag" > "${newRoot}/.agm-version"
if [[ -e "$destination" ]]; then
if ! mv "$destination" "${stageRoot}/old"; then
echo "Could not move the old installation aside." >&2
rm -rf "$stageRoot"
return 1
fi
fi
if ! mv "$newRoot" "$destination"; then
echo "Could not install the new version." >&2
if [[ -e "${stageRoot}/old" ]]; then
mv "${stageRoot}/old" "$destination"
fi
rm -rf "$stageRoot"
return 1
fi
rm -rf "$stageRoot"
githubReleaseGameStatus="updated"
echo "${game:-The game} has been updated to ${latestTag}."
}