Last active
January 2, 2020 09:12
Dotfile Status Script
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env/bash | |
# This is a simple script to check the current local/remote status of your | |
# dotfiles, and prompt to update them if needed. | |
# | |
# Update the contents of the 'sync_dotfiles' function below to change the | |
# method for performing dotfile updates. | |
# | |
# You must set the 'LOCAL_DOTFILES_REPOSITORY' environment variable | |
# to point to the path of your local dotfiles repo prior to executing this script. | |
# | |
# The core portion of this script is taken from a general solution for checking | |
# the status of local/remote git repos posted by Neil Mayhew on StackOverflow: | |
# http://stackoverflow.com/a/3278427/1428743 | |
# Syncs dotfile changes | |
# NOTE TO USER: | |
# Modify this function to use your desired mothod of syncing dotfiles | |
function sync_dotfiles() { | |
# Currently using updot (https://github.com/ntpeters/updot) for dotfile sync | |
# Ensure Python is installed | |
if ! prog_loc="$(type -p "python")" || [ -z "$prog_loc" ] || [ "$prog_loc" == *"not found"* ]; then | |
echo "ERROR: Python does not exist in path! Updot requires Python. Please ensure Python is installed, and try again." | |
return | |
fi | |
# Try executing updot from its default location | |
if [ -f $HOME/.updot/updot.py ]; then | |
python $HOME/.updot/updot.py | |
else | |
echo "ERROR: updot not found! Aborting sync!" | |
fi | |
} | |
# Checks the status of local and remote dotfiles repos to determine if they | |
# need to be synced up. | |
function check_dotfiles_status() { | |
# Make sure the path we were given is a git repo | |
if [ ! -d ./.git ]; then | |
echo "ERROR: Provided dotfile directory is not a git repository!" | |
return | |
fi | |
# Check if git is available | |
if ! prog_loc="$(type -p "git")" || [ -z "$prog_loc" ] || [ "$prog_loc" == *"not found"* ]; then | |
echo "ERROR: Git does not exist in path! Please ensure git is installed, and try again." | |
return | |
fi | |
# Check for active internet connection | |
echo -e "GET http://google.com HTTP/1.0\n\n" | nc google.com 80 > /dev/null 2>&1 | |
if [ $? -eq 1 ]; then | |
echo "ERROR: Failed to get status of remote dotfiles. No active internet connection detected!" | |
return | |
fi | |
# Get remote branch info | |
$(git fetch > /dev/null 2>&1) | |
# Retrieve hashes from git | |
local LOCAL=$(git rev-parse @) | |
local REMOTE=$(git rev-parse @\{u\}) | |
local BASE=$(git merge-base @ @\{u\}) | |
# Check for uncommitted changes | |
$(! git diff-index --quiet HEAD --) | |
local UNCOMMITTED=$? | |
# Flag to determine if an update may need to be done | |
local update=true | |
# Determine status of dotfiles | |
if [ -z $LOCAL ] || [ -z $REMOTE ] || [ -z $BASE ]; then | |
echo "ERROR: Failed to get status of local dotfiles!" | |
update=false | |
elif [ $UNCOMMITTED = 0 ]; then | |
echo "Local dotfiles have uncommitted changes." | |
elif [ $LOCAL = $REMOTE ]; then | |
echo "Dotfiles up-to-date." | |
update=false | |
elif [ $LOCAL = $BASE ]; then | |
echo "Remote dotfiles have changed." | |
elif [ $REMOTE = $BASE ]; then | |
echo "Local dotfiles have changed." | |
else | |
echo "WARNING: Local and remote dotfiles have diverged. You may experience merge conflicts!" | |
fi | |
# See if the user wants to sync dotfiles | |
if $update; then | |
read -p "Sync dotfiles now? [y/n] " -n 1 -r | |
echo | |
if [[ $REPLY =~ ^[Yy]$ ]]; then | |
echo | |
# Execute the defined method of syncing dotfiles | |
sync_dotfiles | |
fi | |
fi | |
} | |
# Check if other shell instances are currently running | |
# Only check dotfile status on initial shell open | |
cur_shell_instances=$(pgrep -f `ps -p $$ -ocomm= | cut -d'/' -f 3` | wc -l | tr -d ' ') | |
default_shell_instances=$(pgrep -f ${SHELL##*/} | wc -l | tr -d ' ') | |
total_shell_instances=$(( $cur_shell_instances + $default_shell_instances )) | |
if (( $total_shell_instances > 1 )); then | |
exit 1 | |
fi | |
# Ensure a path to the local dotfiles repo has been provided | |
if [ -z ${LOCAL_DOTFILES_REPOSITORY+x} ]; then | |
echo "ERROR: Must set the 'LOCAL_DOTFILES_REPOSITORY' variable with path to your dotfiles directory!" | |
else | |
# Ensure path to dotfiles repo has expanded tilde for home dir | |
# Not sure how portable this method is... | |
local_dotfiles_repo=$(eval "echo $LOCAL_DOTFILES_REPOSITORY") | |
# Check if dotfiles need to be updated | |
( cd ${local_dotfiles_repo} && check_dotfiles_status ) | |
fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment