Skip to content

Instantly share code, notes, and snippets.

@noordawod
Last active July 1, 2017 12:44
Show Gist options
  • Save noordawod/ea1a5fc1fb5654fcba509f6e5862a4eb to your computer and use it in GitHub Desktop.
Save noordawod/ea1a5fc1fb5654fcba509f6e5862a4eb to your computer and use it in GitHub Desktop.
Shell script to fix issue with synx and git-enabled Xcode projects
#!/bin/sh
#
# README
# ------
# This script fixes an issue with synx (https://github.com/venmo/synx) that causes the script to
# occasionally script sabbotage a git-driven Xcode project. The issue has been reported by many
# on the Issues page, but no solution was offered by the maintainers.
#
# This simple script will fix that problem by allowing the user to choose certain directories
# to move aside and thus stopping synx from operating on them. Once synx is finished, this
# script will move back those directories to their original location.
#
# Author: Noor Dawod <[email protected]>
#
# MIT LICENSE
# -----------
# Copyright 2017 Noor Dawod. All rights reserved.
#
# Permission is hereby granted, free of charge, to any person obtaining a copy of this software
# and associated documentation files (the "Software"), to deal in the Software without
# restriction, including without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all copies or
# substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
# BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
# DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
if [ "x" = "x$2" ]; then
echo "Syntax: $0 <xcode-project-dir> <temporary-folder> [keep-directories]"
echo "Where:"
echo " <xcode-project-dir>: Xcode project directory to sync"
echo " <temporary-folder>: Temporary location to use for syncing"
echo " [keep-directories]: List of directories to ignore while syncing"
exit 1
fi
# Xcode directory to use.
XCODE_DIR="$1"
shift
# Make sure this project is correct.
if [ ! -d "$XCODE_DIR" ]; then
echo "Fatal: Xcode project directory invalid: '$XCODE_DIR'"
exit 2
fi
# Home directory of Xcode project.
PROJ_DIR="$XCODE_DIR/.."
# Check that temporary directory exists.
TEMP_DIR="$1"
shift
if [ ! -d "$TEMP_DIR" ]; then
echo "Fatal: Temporary directory invalid: '$TEMP_DIR'"
exit 3
fi
# Create a temporary folder inside temporary directory.
TEMP_PATH="$TEMP_DIR/`date '+%Y%m%d.%H%M%S.%s'`"
mkdir -p "$TEMP_PATH"
if [ ! -d "$TEMP_PATH" ]; then
echo "Fatal: Unable to create a temporary directory: '$TEMP_PATH'"
exit 4
fi
# We'll use a new separator character so that spaces are supported.
OLD_IFS=$IFS
NEW_IFS=$'\n'
# List of directories to ignore.
FILES_LIST="bin${NEW_IFS}.git${NEW_IFS}.gitignore${NEW_IFS}README.md${NEW_IFS}Pods${NEW_IFS}Podfile${NEW_IFS}${NEW_IFS}en.lproj"
# User-provided directories to ignore.
USER_FILES_LIST=$*
# Add user-supplied directories, if provided.
if [ "x$USER_FILES_LIST" != "x" ]; then
for FILE_NAME in $USER_FILES_LIST
do
FILES_LIST="${FILES_LIST}${NEW_IFS}${FILE_NAME}"
done
fi
# Start using new IFS.
IFS=$NEW_IFS
# Move aside certain folders before running synx.
echo "Moving files and directories aside:"
MOVED_FILES_LIST=""
for FILE_NAME in $FILES_LIST
do
FILE_PATH="$PROJ_DIR/$FILE_NAME"
# Make sure this directory exists before moving.
if [ -e "$FILE_PATH" ]; then
echo "\t$FILE_PATH"
/bin/mv -f "$FILE_PATH" "$TEMP_PATH/" > /dev/null 2>&1
if [ "0" = "$?" ]; then
MOVED_FILES_LIST="${MOVED_FILES_LIST}${FILE_NAME}${NEW_IFS}"
fi
fi
done
echo " "
# Ready to run synx.
synx --no-sort-by-name "$XCODE_DIR"
echo " "
echo "Moving files and directories back:"
# Bring back directories always.
for FILE_NAME in $MOVED_FILES_LIST
do
TEMP_FILE_PATH="$TEMP_PATH/$FILE_NAME"
FILE_PATH="$PROJ_DIR/$FILE_NAME"
if [ "$NEW_IFS" != "$FILE_NAME" ]; then
# If original file is a directory, remove any empty directory that might have been
# created after running synx.
if [ -d "$TEMP_FILE_PATH" ]; then
# Try to remove the directory using rmdir. If it fails, it's non-empty...
/bin/rmdir "$FILE_PATH" > /dev/null 2>&1
# If directory is non-empty, move it aside so we're able to restore
# the original one.
if [ "0" != "$?" ]; then
/bin/mv -f "$FILE_PATH" "${FILE_PATH}.BAK" > /dev/null 2>&1
fi
fi
/bin/mv -f "$TEMP_FILE_PATH" "$FILE_PATH" > /dev/null 2>&1
if [ "0" = "$?" ]; then
echo "\t$FILE_PATH"
else
echo "\tERROR RESTORING '$FILE_NAME'"
fi
fi
done
# Remove temporary directory.
/usr/bin/rm -fr "$TEMP_PATH" > /dev/null 2>&1
# Bring back old IFS.
IFS=$OLD_IFS
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment