Skip to content

Instantly share code, notes, and snippets.

@mcaskill
Last active July 28, 2021 13:59
Show Gist options
  • Save mcaskill/c3063cc6c8dcd7d40e1ca4d6e388b493 to your computer and use it in GitHub Desktop.
Save mcaskill/c3063cc6c8dcd7d40e1ca4d6e388b493 to your computer and use it in GitHub Desktop.
Better safe than sorry. A shell function wrapper for Composer to check for local changes and create back-ups before executing operations that may overwrite data.
#
# Alias of `composer` command that, if Composer's installed.json is present, checks
# for local changes in dependencies and backs-up the composer.json, composer.lock,
# and vendor directory before executing install, reinstall, or update commands.
#
# Useful if you often need to modify the code of your dependencies and they are
# installed from source.
#
# Version: 1.1.0
# License: MIT
# Author: Chauncey McAskill
#
# Note:
# - This code has only been tested on Unix systems.
# - Change the `bin` variable to where the `composer` binary is located.
# - Change the `bck` variable to where you want to store backups,
# defaults to Composer's `cache-dir`.
# - Backups are named with a timestamp, seconds since the Unix epoch.
# - If the status check detects changes, the requested operation
# will be aborted.
# - If the back-up process fails in any way, the requested operation
# will be aborted.
# - The status check and back-up can considerably slow down any attempt
# to install or update.
#
# Example of a command to delete 15-day-or-older backups, which can be used as
# a cronjob:
#
# ```
# find $(composer config cache-dir)/backups -mindepth 1 -maxdepth 1 -type d -mtime +15 -delete
# ```
#
# Link:
# - https://getcomposer.org/
# - https://github.com/composer/composer/issues/9972#issuecomment-861806548
#
# Arguments:
# - https://getcomposer.org/doc/03-cli.md
#
function composer() {
local bin=/usr/local/bin/composer
if [ -f "vendor/composer/installed.json" ]; then
case $1 in
install | reinstall | update)
echo "The current operation may overwrite data."
echo "Verifying if you have local changes…"
$bin status
if [ $? -ne 0 ] ; then
return
fi
local bck=$($bin config cache-dir)/backups/$(date +%s)
echo "Preparing backup of manifest, lock file, and vendor directory…"
mkdir -p $bck
if [ $? -ne 0 ] ; then
echo "Failed to create backup directory"
return
fi
cp -R ./vendor $bck
local ex=$?
if [ $? -ne 0 ] ; then
echo "Failed to backup vendor directory"
return
fi
cp ./composer.lock $bck
local ex=$?
if [ $? -ne 0 ] ; then
echo "Failed to backup lock file"
return
fi
cp ./composer.json $bck
local ex=$?
if [ $? -ne 0 ] ; then
echo "Failed to backup manifest file and vendor directory"
return
fi
echo "Backup of vendor directory is located at: ${bck}"
;;
esac
fi
$bin $*
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment