#!/usr/bin/env sh set -eu if [ "$#" -ne 4 ]; then printf '%s\n' 'Usage: replace-plugin-directory.sh ARCHIVE TARGET INSTALL_DIR BACKUP_DIR' >&2 exit 2 fi ARCHIVE=$1 TARGET_DIR=$2 INSTALL_DIR=$3 BACKUP_DIR=$4 for directory in "$TARGET_DIR" "$INSTALL_DIR" "$BACKUP_DIR"; do case "$directory" in /*) ;; *) printf '%s\n' 'Plugin replacement directories must be absolute paths' >&2 exit 2 ;; esac if [ "$directory" = / ]; then printf '%s\n' 'Plugin replacement directories cannot be the filesystem root' >&2 exit 2 fi done TARGET_PARENT=$(dirname -- "$TARGET_DIR") if [ "$(dirname -- "$INSTALL_DIR")" != "$TARGET_PARENT" ] || [ "$(dirname -- "$BACKUP_DIR")" != "$TARGET_PARENT" ]; then printf '%s\n' 'Plugin staging and backup directories must share the target parent' >&2 exit 2 fi if [ "$TARGET_DIR" = "$INSTALL_DIR" ] || [ "$TARGET_DIR" = "$BACKUP_DIR" ] || [ "$INSTALL_DIR" = "$BACKUP_DIR" ]; then printf '%s\n' 'Plugin replacement directories must be distinct' >&2 exit 2 fi if [ ! -f "$ARCHIVE" ]; then printf '%s\n' "Plugin archive does not exist: $ARCHIVE" >&2 exit 2 fi had_target=0 cleanup() { status=$? trap - EXIT HUP INT TERM if [ "$status" -ne 0 ] && [ "$had_target" -eq 1 ] && [ ! -e "$TARGET_DIR" ] && [ -e "$BACKUP_DIR" ]; then mv "$BACKUP_DIR" "$TARGET_DIR" || true fi rm -rf "$INSTALL_DIR" if [ "$status" -eq 0 ]; then rm -rf "$BACKUP_DIR" fi exit "$status" } trap cleanup EXIT trap 'exit 1' HUP INT TERM rm -rf "$INSTALL_DIR" if [ -e "$BACKUP_DIR" ]; then printf '%s\n' "Plugin backup directory already exists: $BACKUP_DIR" >&2 exit 1 fi mkdir -p "$INSTALL_DIR" unzip -q "$ARCHIVE" -d "$INSTALL_DIR" if [ -e "$TARGET_DIR" ]; then mv "$TARGET_DIR" "$BACKUP_DIR" had_target=1 fi mv "$INSTALL_DIR" "$TARGET_DIR" rm -rf "$BACKUP_DIR" had_target=0