├── LICENSE ├── README.md └── xcode-plugin-updater.sh /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 DynamicDust s.r.o. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Xcode Plugin Updater 2 | 3 | This script serves as an updater for all your Xcode plugins, when a new version of Xcode (or Xcode-Beta) is released. 4 | 5 | ## Reason 6 | 7 | In each new version of Xcode there is a new value generated for the special key in the `Info.plist` file called `DVTPlugInCompatibilityUUID` and when a plugin does not contain this special 128-bit number Xcode will not load the plugin. This makes some people angry (especially me) as most of the time, there aren't such big changes in Xcode that would cause the plugins to stop working. 8 | 9 | So, what it means is that it can be fixed just by adding the new UUID to the `Info.plist` file of the plugin. It is possible to do manually, however when you got a lot of (20+) plugins, this becomes annoying instantly. That's why I sacrificed a few hours and created this plugin. :) 10 | 11 | ## Usage 12 | 13 | #### Updating 14 | 1. Open Terminal.app (or similar) on your Mac 15 | 2. Run the following command (sorry for this mess, didn't have time to do it properly) and all your plugins will be updated. 16 | 17 | ```sh 18 | curl -fsSL http://git.io/vvZMn > $TMPDIR/xcode-plugin-updater.sh && cd $TMPDIR && chmod 755 xcode-plugin-updater.sh && ./xcode-plugin-updater.sh && rm -rf xcode-plugin-updater.sh && cd 19 | ``` 20 | 21 | #### Printing Xcode's UUID 22 | 1. Open Terminal.app (or similar) on your Mac 23 | 2. Run the following command and the UUID will be copied to your clipboard and also printed to the command line! 24 | 25 | ```sh 26 | curl -fsSL http://git.io/vvZMn > $TMPDIR/xcode-plugin-updater.sh && cd $TMPDIR && chmod 755 xcode-plugin-updater.sh && ./xcode-plugin-updater.sh print && rm -rf xcode-plugin-updater.sh && cd 27 | ``` 28 | 29 | ## Roadmap 30 | 31 | - [x] First version 32 | - [ ] Add compatibility for `sh` and `zsh` (currently only works with `bash`) 33 | - [x] Print Xcode UUID (useful for developers) 34 | - [ ] Suggestions? 35 | 36 | ## Contribution 37 | All improvements are welcome. Please, fork the project and then open a pull request to the develop branch. 38 | 39 | ## Credits 40 | Dominik Hádl / [@dominikhadl](https://twitter.com/dominikhadl) / [DynamicDust s.r.o](http://www.dynamicdust.com) 41 | 42 | Created with ♥ in Prague, Czech Republic. 43 | -------------------------------------------------------------------------------- /xcode-plugin-updater.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # -------------------------------- 4 | # xcode-plugin-updater.sh 5 | # The MIT License (MIT) 6 | # 7 | # Copyright (c) 2015 DynamicDust s.r.o. 8 | # 9 | # Permission is hereby granted, free of charge, to any person obtaining a copy 10 | # of this software and associated documentation files (the "Software"), to deal 11 | # in the Software without restriction, including without limitation the rights 12 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | # copies of the Software, and to permit persons to whom the Software is 14 | # furnished to do so, subject to the following conditions: 15 | # 16 | # The above copyright notice and this permission notice shall be included in 17 | # all copies or substantial portions of the Software. 18 | # 19 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | # THE SOFTWARE. 26 | # -------------------------------- 27 | # CONSTANTS 28 | # -------------------------------- 29 | 30 | PLIST="/usr/libexec/PlistBuddy" 31 | 32 | # Xcode constants 33 | X_APP_DIR_GLOBAL="/Applications" 34 | X_APP_DIR_USER="${HOME}/Applications" 35 | X_APP_FILE_BASE_NAME="Xcode*.app" 36 | X_UUID_REGEX="[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}" 37 | X_UUID_PLIST_KEY="DVTPlugInCompatibilityUUID" 38 | 39 | # Plugin constants 40 | P_PLUGIN_DIR="${HOME}/Library/Application Support/Developer/Shared/Xcode/Plug-ins" 41 | P_UUID_PLIST_KEY="DVTPlugInCompatibilityUUIDs" 42 | 43 | # Colors 44 | COLOREND=$(tput sgr0) 45 | GREEN=$(tput setaf 2) 46 | RED=$(tput setaf 1) 47 | UNDER=$(tput smul) 48 | BOLD=$(tput bold) 49 | 50 | # -------------------------------- 51 | # VARIABLES 52 | # -------------------------------- 53 | 54 | XCODE_UUID="" 55 | 56 | # -------------------------------- 57 | # FUNCTIONS 58 | # -------------------------------- 59 | 60 | function start 61 | { 62 | echo "" 63 | echo "${BOLD}${UNDER}${GREEN}xcode-plugin-updater.sh${COLOREND}" 64 | } 65 | 66 | function end 67 | { 68 | echo "" 69 | echo "${BOLD}Done, all plugins updated.${COLOREND}" 70 | } 71 | 72 | # -------------------------------- 73 | 74 | function usage 75 | { 76 | echo "usage: xcode-plugin-updater.sh [-u UUID] [help] [print]" 77 | } 78 | 79 | # -------------------------------- 80 | 81 | function dependencyIsMissing 82 | { 83 | if [[ $# == 1 ]]; then 84 | echo "Dependency (${1}) is missing. Please install it - preferably into /usr/bin." 85 | fi 86 | exit 1 87 | } 88 | 89 | # -------------------------------- 90 | 91 | function validateUUID 92 | { 93 | # Ignore case 94 | shopt -s nocasematch; 95 | 96 | if ! [[ "$XCODE_UUID" =~ ^${X_UUID_REGEX}$ ]]; then 97 | echo "Incorrect format of UUID. Please provide 128bit hex number in 8-4-4-4-12 format." 98 | exit 1 99 | fi 100 | } 101 | 102 | # -------------------------------- 103 | 104 | function updatePlugins 105 | { 106 | validateUUID 107 | 108 | echo "${BOLD}Updating plugins...${COLOREND}" 109 | echo "" 110 | 111 | # Iterate through the plugins in the plugin folder 112 | while read -rd $'\0' plugin; do 113 | 114 | P_PLIST="${plugin}/Contents/Info.plist" 115 | if [[ ! -e ${P_PLIST} ]]; then 116 | echo "${RED}✗ [$(basename "${plugin}")]${COLOREND} Plugin update failed, corrupted or missing Info.plist file." 117 | continue 118 | fi 119 | 120 | P_UUID_ARRAY=$(${PLIST} -c "Print :${P_UUID_PLIST_KEY}:" "${P_PLIST}") 121 | 122 | if [[ $P_UUID_ARRAY == *"${XCODE_UUID}"* ]]; then 123 | echo "${GREEN}✓ [$(basename "${plugin}")]${COLOREND} Plugin already contains this UUID, no need to update." 124 | continue; 125 | fi 126 | 127 | # Add the new UDID to the array 128 | ${PLIST} -c "Add :${P_UUID_PLIST_KEY}: string ${XCODE_UUID}" "${P_PLIST}" 129 | 130 | # Done 131 | echo "${GREEN}✓ [$(basename "${plugin}")]${COLOREND} Plugin updated successfully." 132 | 133 | done < <(find "${P_PLUGIN_DIR}/" -maxdepth 1 -name "*.xcplugin" -print0) 134 | } 135 | 136 | # -------------------------------- 137 | 138 | function getUUID 139 | { 140 | # Check user and global application directory for Xcode (and Xcode-beta) 141 | X_VER_1=$(find ${X_APP_DIR_GLOBAL} -maxdepth 1 -name ${X_APP_FILE_BASE_NAME}) 142 | X_VER_2=$(find ${X_APP_DIR_USER} -maxdepth 1 -name ${X_APP_FILE_BASE_NAME}) 143 | 144 | if [[ $X_VER_1 == "" ]]; then 145 | X_VER_1_COUNT=0 146 | else 147 | X_VER_1_COUNT=$(wc -l <<< "${X_VER_1}") 148 | fi 149 | 150 | if [[ $X_VER_2 == "" ]]; then 151 | X_VER_2_COUNT=0 152 | else 153 | X_VER_2_COUNT=$(wc -l <<< "${X_VER_2}") 154 | fi 155 | 156 | # Number of versions in total 157 | X_VERSION_COUNT=$(($X_VER_1_COUNT+$X_VER_2_COUNT)) 158 | 159 | if (( $X_VER_1_COUNT >= 1 && $X_VER_2_COUNT >= 1 )); then 160 | # IMPORTANT! 161 | # New line is added in between both find results here 162 | X_VERSIONS="$X_VER_1 163 | $X_VER_2" 164 | elif (( $X_VER_1_COUNT >= 1 && $X_VER_2_COUNT == 0 )); then 165 | X_VERSIONS="${X_VER_1}" 166 | else 167 | X_VERSIONS="${X_VER_2}" 168 | fi 169 | 170 | # Final version which we will get the UUID from 171 | X_VERSION="" 172 | 173 | # If more than one version, prompt the user to choose 174 | # else get the UUID of the current version 175 | if (( $X_VERSION_COUNT > 1 )); then 176 | 177 | # Notify 178 | echo "Multiple versions of Xcode found. Which one do you want to use?" 179 | 180 | echo "" 181 | i=0 182 | 183 | # List all the options 184 | while read -rd $'\0' file; do 185 | echo "${BOLD}[$i]${COLOREND} $file" 186 | i=$((i+1)) 187 | done < <(find ${X_APP_DIR_GLOBAL} ${X_APP_DIR_USER} -maxdepth 1 -name ${X_APP_FILE_BASE_NAME} -print0) 188 | 189 | i=$((i-1)) 190 | echo "" 191 | 192 | # Ask the user which version he wants to use 193 | while true; do 194 | read -p "Your choice: " choice 195 | case $choice in 196 | [0-$i]* ) break;; 197 | * ) echo "Please answer in range 0 - $i."; echo;; 198 | esac 199 | done 200 | 201 | # Resets 202 | i=0 203 | echo "" 204 | 205 | # Enumerate again and get the Xcode version chosen by user 206 | for ver in ${X_VERSIONS}; do 207 | if [[ $i == $choice ]]; then 208 | X_VERSION=$ver; 209 | break; 210 | fi 211 | i=$((i+1)) 212 | done 213 | else 214 | 215 | # Get the first (and only) version 216 | for ver in ${X_VERSIONS}; do 217 | X_VERSION=$ver; 218 | break; 219 | done 220 | 221 | fi 222 | 223 | # Check if the Info.plist file exists 224 | X_PLIST="${X_VERSION}/Contents/Info.plist" 225 | if [[ ! -e ${X_PLIST} ]]; then 226 | echo "This Xcode version is corrupted and is missing the Info.plist file." 227 | exit 1 228 | fi 229 | 230 | # Now get the UUID from the version chosen 231 | XCODE_UUID=$(${PLIST} -c "Print ${X_UUID_PLIST_KEY}" "${X_PLIST}") 232 | } 233 | 234 | # -------------------------------- 235 | 236 | function printUUID 237 | { 238 | start 239 | 240 | # Check if PlistBuddy is available 241 | command -v "$PLIST" > /dev/null || dependencyIsMissing "PlistBuddy" 242 | 243 | # Get the UUID 244 | getUUID 245 | 246 | # Copy to the clipboard 247 | echo "${XCODE_UUID}" | pbcopy 248 | 249 | # Print it 250 | echo "${BOLD}Xcode UUID:${COLOREND} ${XCODE_UUID}" 251 | echo "(copied to your clipboard)" 252 | echo "" 253 | } 254 | 255 | # -------------------------------- 256 | # MAIN 257 | # -------------------------------- 258 | 259 | if [[ $# == 1 ]]; then 260 | 261 | # Handle just one argument 262 | if [[ "$1" == "help" ]]; then 263 | usage 264 | exit 0 265 | elif [[ "$1" == "print" ]]; then 266 | printUUID 267 | exit 0 268 | else 269 | echo "Unkown argument $1." 270 | usage 271 | exit 1; 272 | fi 273 | 274 | elif [[ $# == 2 ]]; then 275 | start 276 | echo "" 277 | 278 | # Handle two arguments 279 | if [[ "$1" == "-u" ]]; then 280 | XCODE_UUID="${2}" 281 | updatePlugins 282 | end 283 | exit 0 284 | else 285 | echo "Unkown argument $1." 286 | usage 287 | exit 1; 288 | fi 289 | 290 | else 291 | start 292 | echo "" 293 | 294 | # Check if PlistBuddy is available 295 | command -v "$PLIST" > /dev/null || dependencyIsMissing "PlistBuddy" 296 | 297 | # If no argument passed, then find all Xcode versions and get the UUID 298 | getUUID 299 | 300 | # If the UUID is ready, update the plugins 301 | updatePlugins 302 | 303 | end 304 | 305 | exit 0 306 | fi 307 | 308 | # -------------------------------- --------------------------------------------------------------------------------