Skip to content

Instantly share code, notes, and snippets.

@Magentron
Created December 29, 2016 15:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Magentron/689995f0f94899fab2156c945d340dbd to your computer and use it in GitHub Desktop.
Save Magentron/689995f0f94899fab2156c945d340dbd to your computer and use it in GitHub Desktop.
Upgrade PHPMailer files automatically to latest version
#!/bin/sh
#
# phpmailer-upgrade.sh - Upgrade PHPMailer files automatically to latest version
#
# Copyright (c) 2016 Derks.IT / Jeroen Derks / Magentron
#
# Licensed under the Apache License, Version 2.0 (the “License”);
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an “AS IS” BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
VERSION='1.0.0'
COPYRIGHT_YEARS='2016'
PROGNAME='phpmailer-upgrade.sh'
PROG="`basename \"$0\"`"
BACKUPDIR_DEFAULT="$CWD/phpmailer.backup"
BACKUPEXT_DEFAULT=".BACKUP"
BRANCH_DEFAULT="master"
CWD="`pwd`"
CHECK_FILES="class.phpmailer.php class.pop3.php class.smtp.php"
DATE=`date +%Y%m%d`
DATETIME=`date +%Y%m%d%H%M%S`
DIRNAME=PHPMailer
PATTERN='PHPMailer [Vv]ersion'
JOOMLA_FILES="class.phpmailer.php:phpmailer.php class.smtp.php:smtp.php"
WP_FILES="class.phpmailer.php:class-phpmailer.php class.pop3.php: class.smtp.php:class-smtp.php"
BACKUPDIR="$BACKUPDIR_DEFAULT"
BACKUPEXT="$BACKUPEXT_DEFAULT"
BRANCH="$BRANCH_DEFAULT"
CHECKOUT_DIRECTORY=
DEBUG=:
DRY_RUN=false
COMPARE_ONLY=false
KEEP_TEMPDIR=false
NO_BACKUP=false
RENAME_FILES=false
REPOSITORY='https://github.com/PHPMailer/PHPMailer.git'
VERBOSE=:
###############################################################################
# Functions
#
usage()
{
echo "$PROGNAME v$VERSION - Copyright (c) $COPYRIGHT_YEARS Derks.IT / Jeroen Derks" 1>&2
echo "Upgrades PHPMailer files automatically to last version" 1>&2
echo 1>&2
echo "usage: $PROG [-d] [-n] [-v] [-x] [-B branch] [-C checkout] [-D backup ] [-K] [-M extension] [-N] [-O] directory [ directory [...] ]" 1>&2
echo " -d Enable debug output" 1>&2
echo " -n Dry-run mode" 1>&2
echo " -v Enable verbose output" 1>&2
echo " -x Enable shell debug output" 1>&2
echo " -B PHPMailer GitHub branch name to use (default: $BRANCH_DEFAULT)" 1>&2
echo " -C Directory containing cloned repository with branch to use" 1>&2
echo " -D Backup directory to use (default: $BACKUPDIR_DEFAULT)" 1>&2
echo " -K Keep temporary directory" 1>&2
echo " -M Rename original files using supplied extension (default: $BACKUPEXT_DEFAULT)" 1>&2
echo " -N Do not create backup directory" 1>&2
echo " -O Compare only, do not actually upgrade" 1>&2
if [ $# != 0 ]; then
echo 1>&2
echo "error: $@" 1>&2
fi
exit 1
}
error()
{
errno=$1
shift
echo `date` "[ERROR] $@" 1>&2
exit $errno
}
verbose()
{
echo `date` "[INFO] $@"
}
debug()
{
echo `date` "[DEBUG] $@"
}
dry_run()
{
if [ $# != 0 ]; then
echo "$@ [DRY-RUN]"
fi
}
sanitize_path()
{
echo "$@" | sed -e 's@/\(\./\)\(\./\)*@/@g;s@^\(\.\./\)\(\.\./\)*\|^\./@@g'
}
get_source()
{
filename="$1"
basename="`basename \"$filename\"`"
source=
for check_filename in $CHECK_FILES; do
if [ "$check_filename" = "$basename" ]; then
source="$CHECKOUT_DIRECTORY/$check_filename"
break
else
# check WordPress renames
for wp_file in $WP_FILES $JOOMLA_FILES; do
case "$check_filename:$basename" in
$wp_file)
source="$CHECKOUT_DIRECTORY/$check_filename"
break 2
;;
esac
done
fi
done
echo "$source"
}
mktmp()
{
if mktemp --help 2>&1 | grep -Ee '-t\s+prefix' > /dev/null 2>&1; then
TEMPDIR="`mktemp -d -t $PROGNAME.tmp.$$`"
else
TEMPDIR="`mktemp -d -t $PROGNAME.tmp.$$.XXXXXX`"
fi || error $? "unable to create temporary directory"
if $KEEP_TEMPDIR; then
trap "$VERBOSE keeping temporary directory '$TEMPDIR'" 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
else
trap "$VERBOSE \"removing temporary directory\"; $DEBUG \"rm -rf $TEMPDIR\"; rm -rf \"$TEMPDIR\"" 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
fi
$VERBOSE "created temporary directory '$TEMPDIR'"
}
find_files()
{
FILES_FILENAME="$TEMPDIR/files"
$VERBOSE "searching files using pattern '$PATTERN' => '$filename'"
find $@ -type f -iname '*.php' -o -iname '*.php[3456]' -o -iname '*.inc' -o -iname '*.phtml' -o -iname '*.phtm' | xargs grep -le "$PATTERN" > "$FILES_FILENAME"
if [ ! -s "$FILES_FILENAME" ]; then
error 3 "no files found"
fi
}
backup()
{
if $NO_BACKUP; then
$VERBOSE "not creating backup"
else
basedir="$BACKUPDIR"
#basedir="$TEMPDIR/backup"
$VERBOSE "backing up found files to '$basedir'"
# create directory structure
DIRECTORIES_FILENAME="$TEMPDIR/directories"
rev < "$FILES_FILENAME" | cut -d/ -f 2- | rev | sort -u | uniq > "$DIRECTORIES_FILENAME"
while read directory; do
target="$basedir/`sanitize_path \"$directory\"`"
$DEBUG "mkdir -p '$target'"
$DRY_RUN "mkdir -p '$target'" || \
mkdir -p "$target" || error $? "unable to create backup sub-directory '$target'"
done < "$DIRECTORIES_FILENAME"
# copy files
while read filename; do
target="$basedir/`sanitize_path \"$filename\"`"
$DEBUG "cp -a '$filename' '$target'"
$DRY_RUN "cp -a '$filename' '$target'" || \
cp -a "$filename" "$target" || error $? "unable to backup file '$filename' to '$target'"
done < "$FILES_FILENAME"
fi
}
checkout()
{
if [ ! -z "$CHECKOUT_DIRECTORY" ]; then
# check existing repository
[ ! -e "$CHECKOUT_DIRECTORY" ] && error 2 "checkout directory '$CHECKOUT_DIRECTORY' does not exist"
[ ! -d "$CHECKOUT_DIRECTORY" ] && error 20 "checkout directory '$CHECKOUT_DIRECTORY' is not a directory"
$VERBOSE "using checkout '$CHECKOUT_DIRECTORY'"
# check branch if given
if [ "$BRANCH_DEFAULT" != "$BRANCH" ]; then
branch=`git --git-dir="$CHECKOUT_DIRECTORY/.git" --work-tree="$CHECKOUT_DIRECTORY" branch | grep -e '^\*' | cut -c3-`
if [ "$branch" != "$BRANCH" ]; then
same=false
$DEBUG "branch='$branch'"
if echo "$branch" | grep -e '^(' > /dev/null 2>&1; then
xbranch="`echo \"$branch\" | cut -d\ -f 3 | cut -d\) -f 1`"
$DEBUG "xbranch='$xbranch'"
case "$BRANCH" in
$xbranch*) same=true;;
esac
fi
$same || error 4 "checkout is at branch '$branch', not '$BRANCH'"
fi
fi
else
# checkout repository
$VERBOSE "checking out $REPOSITORY to $DIRNAME ..."
directory="$TEMPDIR/$DIRNAME"
$DEBUG "git clone '$REPOSITORY' '$directory'"
git clone "$REPOSITORY" "$directory" || exit $? "unable to clone git repository '$REPOSITORY' to directory '$directory'"
$DEBUG "git --git-dir='$directory/.git' --work-tree='$directory' checkout '$BRANCH'"
git --git-dir="$directory/.git" --work-tree="$directory" checkout "$BRANCH" || error $? "unable to checkout branch '$BRANCH'"
CHECKOUT_DIRECTORY="$directory"
fi
# get upgrade version
UPGRADE_VERSION="v`grep -A3 -e 'PHPMailer [Vv]ersion' $CHECKOUT_DIRECTORY/*.php | grep -Eoe '[0-9]+\.[0-9]+\.[0-9]+[0-9a-zA-Z_./-]*'`"
if [ ! -z "$UPGRADE_VERSION" ]; then
UPGRADE_VERSION="$BRANCH branch"
fi
$VERBOSE "using $UPGRADE_VERSION from '$CHECKOUT_DIRECTORY'"
}
compare()
{
output="$TEMPDIR/files.differences"
$VERBOSE "comparing files to $UPGRADE_VERSION => $output"
errors=false
while read filename; do
if [ -f "$filename$BACKUPEXT" ]; then
(error 6 "backup file '$filename$BACKUPEXT' already exists")
errors=true
fi
source=`get_source "$filename"`
if [ ! -z "$source" ]; then
diff -bBwU3 "$source" "$filename"
else
(error 5 "unknown file '`basename $filename`' for '$filename'")
errors=true
fi
done < $FILES_FILENAME > "$output"
if $errors; then
exit 7
elif [ ! -s "$output" ]; then
error 12 "no differences found"
fi
}
upgrade()
{
if $COMPARE_ONLY; then
$VERBOSE "only comparing, done"
else
$VERBOSE "upgrading to $UPGRADE_VERSION ..."
errors=false
while read filename; do
source=`get_source "$filename"`
if [ ! -z "$source" ]; then
if $RENAME_FILES; then
basename="`basename \"$filename\"`"
dirname="`dirname \"$filename\"`"
backupfile="$dirname/$basename$BACKUPEXT"
tmpfile="$dirname/.tmp.$$.$basename"
(
trap "rm -f \"$tmpfile\"" 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
$DEBUG "cp -a '$filename' '$tmpfile'"
$DRY_RUN "cp -a '$filename' '$tmpfile'" ||
cp -a "$filename" "$tmpfile" || error $? "unable to copy file to '$tmpfile'"
$DEBUG "mv '$filename' '$backupfile' && mv '$tmpfile' '$filename'"
$DRY_RUN "mv '$filename' '$backupfile' && mv '$tmpfile' '$filename'" ||
(mv "$filename" "$backupfile" && mv "$tmpfile" "$filename") || error $? "unable to copy file to '$tmpfile'"
)
fi
$DEBUG "cp '$source' '$filename'"
$DRY_RUN "cp '$source' '$filename'" || \
cp "$source" "$filename" || error $? "unable to copy file to '$filename'"
$DEBUG "touch -r '$source' '$filename'"
$DRY_RUN "touch -r '$source' '$filename'" || \
touch -r "$source" "$filename" || error $? "unable to touch file '$filename'"
else
(error 5 "unknown file '$basename' for '$filename'")
errors=true
fi
done < $FILES_FILENAME
fi
}
#
# Main
#
# process flags
while [ $# -gt 0 ]; do
case "x$1" in
x-d) DEBUG=debug;;
x-n) DRY_RUN=dry_run;;
x-v) VERBOSE=verbose;;
x-x) set -x;;
x-B|x--branch) BRANCH="$2"; shift;;
x-C|x--checkout-dir) CHECKOUT_DIRECTORY="$2"; shift;;
x-D|x--backup-dir) BACKUPDIR="$2"; shift;;
x-K|x--keep-dir) KEEP_TEMPDIR=true;;
x-M|x--move-files) RENAME_FILES=true;;
x-N|x--no-backup-dir) NO_BACKUP=true;;
x-O|x--compare-only) COMPARE_ONLY=true;;
x-*) usage;;
*) break;;
esac
shift
done
# check supplied directories
if [ $# = 0 ]; then
usage "No directories supplied."
fi
# main
mktmp
find_files $@
checkout
compare
backup
upgrade
# vim: set et sts=4 sw=4 ts=4:
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment