Skip to content

Instantly share code, notes, and snippets.

@stanislaw
Created August 28, 2016 13:51
Show Gist options
  • Select an option

  • Save stanislaw/f1f56d59fc82e0d32b607dbc31be5b0f to your computer and use it in GitHub Desktop.

Select an option

Save stanislaw/f1f56d59fc82e0d32b607dbc31be5b0f to your computer and use it in GitHub Desktop.
Proof of concept: Carthage with rsync
#!/bin/bash
# This script is an optimization over Carthage's copy-frameworks script.
# This script copies frameworks provided as "Input Files" in
# Xcode Run Script phase. On the first run it copies the frameworks and
# codesigns them, on subsequent runs it does nothing.
#
# Warning! This optimization has a cost: to upgrade a particular framework
# one has to either delete the whole build cache or
# manually delete that framework from cache.
# All variables that are initialized within this script are prefixed
# "HERE_" so that one can distinguish between them and exported from outside.
# Example: $HERE_PATH
# The variables below are given us from outside by Xcode:
# SCRIPT_INPUT_FILE_COUNT
# SCRIPT_INPUT_FILE_0, SCRIPT_INPUT_FILE_1, SCRIPT_INPUT_FILE_2, ...
# To understand them better read the article on
# how to customize Run Script phases in Xcode:
# http://indiestack.com/2014/12/speeding-up-custom-script-phases/
# Make this script to panic early if:
# 1) at least one subcommand fails
# 2) there is an underfined variable
# https://sipb.mit.edu/doc/safe-shell/
set -euf -o pipefail
echo "copy_frameworks_debug.sh: starting"
# Path to this script (we give it to Xcode to produce
# correct warnings in case of errors)
HERE_PATH="$0";
if [ "${CONFIGURATION}" != "Debug" ]; then
echo "$HERE_PATH:$LINENO: error: This script has to be run only in Debug configuration"
exit 1
fi
# We try to obtain code signing identity from Xcode's environment variables.
# It can be either EXPANDED_CODE_SIGN_IDENTITY like
# "iPhone Developer: Stanislaw Pankevich (LHK84SQ733)”
# or CODE_SIGN_IDENTITY like "iPhone Developer”
# If there is no identity found we fail.
CODE_SIGN_IDENTITY=${CODE_SIGN_IDENTITY:-""} # fallback if Xcode doesn't provide us with this variable.
HERE_SIGNING_IDENTITY=${EXPANDED_CODE_SIGN_IDENTITY:-$CODE_SIGN_IDENTITY}
if [ -z "${HERE_SIGNING_IDENTITY}" ]; then
echo "$HERE_PATH:$LINENO: error: Could not find valid signing identity in either EXPANDED_CODE_SIGN_IDENTITY or CODE_SIGN_IDENTITY"
exit 1
fi
echo "copy_frameworks_debug.sh: found code signing identity: \"$HERE_SIGNING_IDENTITY\""
HERE_LAST_INPUT_FRAMEWORK_INDEX=`expr $SCRIPT_INPUT_FILE_COUNT - 1`
HERE_DESTINATION=$TARGET_BUILD_DIR/$FRAMEWORKS_FOLDER_PATH
# rm -rf ${BUILT_PRODUCTS_DIR}/Frameworks
mkdir -pv ${HERE_DESTINATION}
for i in $(seq 0 $HERE_LAST_INPUT_FRAMEWORK_INDEX)
do
HERE_FILE="SCRIPT_INPUT_FILE_$i"
HERE_FILENAME=${!HERE_FILE}
# rsync with output format '%n' produces a folder or file name to copy if
# a sync has to happen and produces nothing if the framework is
# already there at destination - in this case we skip codesigning it by
# jumping out from the current loop iteration.
# http://stackoverflow.com/questions/12137431/test-if-a-command-outputs-an-empty-string
# The process consists of two steps:
# 1) On the first, fresh run, rsync copies the files from source to destination. Then 'codesign' signs the frameworks.
# 2) rsync ignores existing files (we detect that by seeing nothing
# in the output) so that the codesign code is not reached (via 'continue')
if [[ $(rsync --archive --ignore-existing --no-times --out-format='%n' $HERE_FILENAME $HERE_DESTINATION | wc -c) -eq 0 ]]; then
continue
fi
HERE_CURRENT_FRAMEWORK_NAME=${HERE_FILENAME##*/}
HERE_DESTINATION_FRAMEWORK=${HERE_DESTINATION}/${HERE_CURRENT_FRAMEWORK_NAME}
/usr/bin/xcrun codesign --verbose --sign "$HERE_SIGNING_IDENTITY" ${HERE_DESTINATION_FRAMEWORK} || true
done
echo "copy_frameworks_debug.sh: done."
# open ${HERE_DESTINATION}
# exit 1;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment