Last active
April 21, 2019 02:02
-
-
Save skabber/63a10739efaead97e59f to your computer and use it in GitHub Desktop.
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
#!/bin/bash | |
function usage { | |
echo "Usage: $0 -c [CodeSign Directory] -p [Xcode Project File.xcodeproj]" | |
echo "If any arguments are not specified, defaults will be attempted. If defaults don't exist, script will exit." | |
echo "OPTIONS:" | |
echo " -c [CodeSign Directory]: Location of directory containing project's provisioning profiles." | |
echo " -p [Xcode Project File]: Path of Xcode project directory (the .xcodeproj, not .pbxproj)" | |
echo " -b: Use PlistBuddy command for UUID replacement instead of sed. (Better handling of a couple of edge cases, but makes diffs impossible to read.)" | |
echo " -v: Verbose logging." | |
echo " -x: Extremely verbose logging. Same as running script with 'bash -x'." | |
echo " -h: Display usage information." | |
} | |
plistBuddy="/usr/libexec/PlistBuddy" | |
profilesDir="${HOME}/Library/MobileDevice/Provisioning Profiles/" | |
setProfilesWithPlistBuddy=false | |
verbose=false | |
while getopts c:p:bvxh option; do | |
case "${option}" in | |
c) codeSignDirectory=${OPTARG};; | |
p) xcodeProject=${OPTARG};; | |
b) setProfilesWithPlistBuddy=true;; | |
v) verbose=true;; | |
x) set -x;; | |
h | help) usage; exit;; | |
esac | |
done | |
function logit() { | |
if [ $verbose == true ]; then | |
echo "$@" | |
fi | |
} | |
function checkForCodeSignDirectory { | |
if [ -z "${codeSignDirectory}" ]; then | |
codeSignDirectory="$PWD/CodeSign" | |
if [ ! -d "${codeSignDirectory}" ]; then | |
echo "No CodeSign directory found or specified with -c option. Exiting." | |
exit 1 | |
fi | |
fi | |
} | |
function checkForXcodeProject { | |
if [ -z "${xcodeProject}" ]; then | |
echo "No Xcode project specified. Please specify Xcode project using -p option. Exiting." | |
exit 1 | |
fi | |
projectName=`basename "$xcodeProject" | cut -d'.' -f1` | |
} | |
function checkForProjectFile { | |
# Check that we have an Xcode project and that the project file exists. | |
projectExtension=`basename "$xcodeProject" | cut -d'.' -f2` | |
if [ "$projectExtension" != "xcodeproj" ]; then | |
echo "Xcode project should have a .xcodeproj file extension. Instead got a .$projectExtension extension. Exiting." | |
exit 1 | |
else | |
projectFile="$xcodeProject/project.pbxproj" | |
if [ ! -f "$projectFile" ]; then | |
echo "Project file $projectFile does not exist. Exiting." | |
exit 1 | |
fi | |
fi | |
} | |
function copyProfiles { | |
# Move all of our profile's to the system's provisioning profile directory | |
mkdir -p "$profilesDir" | |
find "$codeSignDirectory" -name *.mobileprovision | egrep '.*' > /dev/null 2>&1 | |
if [ $? -eq 0 ]; then | |
cp "$codeSignDirectory/"*.mobileprovision "$profilesDir" | |
if [ $? -ne 0 ]; then | |
echo "Copying profiles from CodeSign directory failed. Please run script again with -x option for debugging." | |
exit 1 | |
fi | |
else | |
echo "No provisioning profiles found in CodeSign directory: $codeSignDirectory. Will attempt to proceed with profiles already in system profile directory." | |
fi | |
} | |
function getTargets { | |
# Build an array of all the targets IDs from our project file | |
rootObject=`$plistBuddy -c "Print :rootObject" "$projectFile"` | |
targetList=`$plistBuddy -c "Print :objects:$rootObject:targets" "$projectFile" | sed -e '/Array {/d' -e '/}/d' -e 's/^[ \t]*//'` | |
targets=(`echo $targetList`) | |
} | |
function setNewProfileUuid { | |
# Set our provisioning profiles in the build settings to the UUIDs of our latest profiles from the CodeSign directory | |
if [ "$currentProfileUuid" != "$newProfileUuid" ]; then | |
echo "Changing $configurationName from $currentProfileUuid to $newProfileUuid" | |
if [ $setProfilesWithPlistBuddy == false ]; then | |
sed -i '' "s/$currentProfileUuid/$newProfileUuid/g" "$projectFile" | |
if [ $? -ne 0 ]; then | |
printf "sed command failed on $cleanTargetName:$configurationName attempting to replace \"$currentProfileUuid\" with \"$newProfileUuid\".\nAborting.\nConsider running script with -b flag to use PlistBuddy instead of sed." | |
exit 1 | |
fi | |
elif [ $setProfilesWithPlistBuddy == true ]; then | |
echo "Detected -b flag. Using PlistBuddy instead of sed to set new UUID values..." | |
if [ $currentProfileUuidIsSet == false ]; then | |
logit "No PROVISIONING_PROFILE key is defined for $targetName:$configurationName. Adding one..." | |
$plistBuddy -c "Add :objects:$configurationId:buildSettings:PROVISIONING_PROFILE string $newProfileUuid" "$projectFile" | |
elif [ $currentProfileUuidIsSet == true ]; then | |
$plistBuddy -c "Set :objects:$configurationId:buildSettings:PROVISIONING_PROFILE $newProfileUuid" "$projectFile" | |
fi | |
fi | |
else logit "Provisioning Profile UUID is already set to latest. No change made." | |
fi | |
} | |
function getCurrentProfileUuid { | |
# Get the provisioning profile UUID currently set in the project file | |
currentProfileUuid=`$plistBuddy -c "Print :objects:$configurationId:buildSettings:PROVISIONING_PROFILE" $projectFile 2> /dev/null` | |
if [ $? -eq 0 ]; then | |
currentProfileUuidIsSet=true | |
if [ $currentProfileUuid == '' ]; then | |
echo "Current provisioning profile is blank. Unable to replace using sed, proceeding with PlistBuddy instead." | |
setProfilesWithPlistBuddy=true | |
fi | |
else | |
currentProfileUuidIsSet=false | |
setProfilesWithPlistBuddy=true | |
fi | |
} | |
function configureProvisioningProfiles { | |
for targetId in ${targets[@]}; do | |
targetName=`$plistBuddy -c "Print :objects:$targetId:name" "$projectFile"` | |
logit "Checking Target: $targetName" | |
cleanTargetName=${targetName// /_} | |
buildConfigurationListId=`$plistBuddy -c "Print :objects:$targetId:buildConfigurationList" "$projectFile"` | |
buildConfigurationList=`$plistBuddy -c "Print :objects:$buildConfigurationListId:buildConfigurations" "$projectFile" | sed -e '/Array {/d' -e '/}/d' -e 's/^[ \t]*//'` | |
buildConfigurations=(`echo $buildConfigurationList`) | |
for configurationId in ${buildConfigurations[@]}; do | |
configurationName=`$plistBuddy -c "Print :objects:$configurationId:name" "$projectFile"` | |
logit "Checking Configuration: $configurationName" | |
conventionProfileName=$projectName-$cleanTargetName-$configurationName.mobileprovision | |
logit "Convention Profile Name: $conventionProfileName" | |
if [ -f "$profilesDir/$conventionProfileName" ]; then | |
getCurrentProfileUuid | |
newProfileUuid=`security cms -D -i "$profilesDir/$conventionProfileName" > /tmp/newprofile.plist && /usr/libexec/PlistBuddy -c Print:UUID /tmp/newprofile.plist && rm -f /tmp/newprofile.plist` | |
setNewProfileUuid | |
else logit "No provisioning profile set for target $targetName with configuration $configurationName. No change made." | |
fi | |
done | |
done | |
} | |
checkForCodeSignDirectory | |
checkForXcodeProject | |
checkForProjectFile | |
copyProfiles | |
getTargets | |
configureProvisioningProfiles |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment