-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathmakeXcodePluginsWork
executable file
·235 lines (205 loc) · 5.3 KB
/
makeXcodePluginsWork
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
#!/bin/bash
xcodePath="/Applications/Xcode.app"
binaryPath="$xcodePath/Contents/MacOS/Xcode"
pluginsDir="$HOME/Library/Application Support/Developer/Shared/Xcode/Plug-ins"
altPluginsDir="$HOME/Library/Developer/Xcode/Plug-ins"
tmpRepoPath="/tmp/unsign-updatePlugins"
bold=$(tput bold)
normal=$(tput sgr0)
if pgrep "Xcode" > /dev/null
then
printf "${bold}Xcode is Running, please quit now...${normal}\n"
while pgrep "Xcode" > /dev/null
do
sleep 1
done
fi
function signedState {
if [ -f "$binaryPath.unsigned" ]; then
return 1 # binary is currently signed
elif [ -f "$binaryPath.signed" ]; then
return 2 # binary is currently unsigned
fi
return 0 # binary is currently signed
}
function restoreUnsigned {
sudo mv "$binaryPath" "$binaryPath.signed"
sudo mv "$binaryPath.unsigned" "$binaryPath"
printf "Restored unsigned binary\n"
}
function restoreSigned {
sudo mv "$binaryPath" "$binaryPath.unsigned"
sudo mv "$binaryPath.signed" "$binaryPath"
printf "Restored signed binary\n"
}
function unsign {
rm -rf "$tmpRepoPath"
mkdir "$tmpRepoPath"
cd $tmpRepoPath
printf "Cloning unsign repository\n"
git clone [email protected]:steakknife/unsign.git
cd unsign
make
printf "Unsigning (admin permissions required)\n"
sudo ./unsign "$binaryPath"
status=$?
if [ $status -eq 0 ]; then
sudo mv "$binaryPath" "$binaryPath.signed"
sudo mv "$binaryPath.unsigned" "$binaryPath"
printf "Done!\n"
else
printf "Failed.\n"
fi
rm -rf "$tmpRepoPath"
}
function resetWarning {
version=$(defaults read /Applications/Xcode.app/Contents/version CFBundleShortVersionString)
defaults delete com.apple.dt.Xcode "DVTPlugInManagerNonApplePlugIns-Xcode-$version" > /dev/null 2>&1
printf "\nReset!\n"
}
UUID=$(defaults read /Applications/Xcode.app/Contents/Info DVTPlugInCompatibilityUUID)
function containsElement {
local e
for e in "${@:2}"; do [[ "$e" == "$1" ]] && return 0; done
return 1
}
function checkIfLatestUUID {
existingUUIDs=($(defaults read "$1/Contents/Info" DVTPlugInCompatibilityUUIDs | sed "s/[,()\"]*//g"))
containsElement "$UUID" "${existingUUIDs[@]}"
return $?
}
function upgradePlugin {
checkIfLatestUUID "$1"
if [ $? -eq 0 ]; then
return 1
fi
defaults write "$1/Contents/Info" DVTPlugInCompatibilityUUIDs -array-add $UUID
return 0
}
function upgradePlugins {
found=0
function findPlugins {
plugins=()
while read -d '' -r; do
((found++))
checkIfLatestUUID "$REPLY"
if [ $? -eq 1 ]; then
plugins+=( "$REPLY" )
fi
done < <(find "$1" -name "*.xcplugin" -maxdepth 1 -print0 2>/dev/null)
}
findPlugins "$pluginsDir"
options=("${plugins[@]}")
findPlugins "$altPluginsDir"
options=( "${options[@]}" "${plugins[@]}" )
printf "\n"
if [ ${#options[@]} -eq 0 ]; then
printf "No plugins need upgrading! $found plugins found already have latest UUID.\n"
break
else
((upgraded=$found-${#options[@]}))
if [ $upgraded -gt 0 ]; then
printf "$upgraded plugins already have latest UUID.\n"
fi
fi
if [ $1 == "update" ]; then
printf "\n${bold}"
PS3="${bold}Please select a plugin to update: ${normal}"
select opt in "${options[@]}" "Back" "Quit" ; do
if (( REPLY == 1 + ${#options[@]} )) ; then
break
elif (( REPLY == 2 + ${#options[@]} )) ; then
exit
elif (( REPLY > 0 && REPLY <= ${#options[@]} )) ; then
upgradePlugin "$opt"
if [ $? -eq 0 ]; then
printf "Upgraded $opt"
else
printf "Already upgraded this plugin"
fi
else
printf "Invalid option. Try another one."
fi
printf "\n"
done
else
for i in "${options[@]}"; do
upgradePlugin "$i"
if [ $? -eq 0 ]; then
printf "Upgraded $i"
fi
done
fi
}
while true
do
declare -a mainOptTests=("all" "unsign" "restoreUnsigned" "restoreSigned" "resetWarning" "update" "updateAll" "quit")
declare -a mainOpts=("Just make it work! (unsign, reset warning, update plugins)" "Unsign Xcode" "Restore unsigned Xcode" "Restore signed Xcode" "Reset 'Load Bundles' Xcode warning" "Update specific plugins" "Update all plugins" "Quit")
signedState
SS=$?
case $SS in
0) # fresh xcode, currently signed, remove both 'restore' options
unset mainOpts[2]
unset mainOptTests[2]
unset mainOpts[3]
unset mainOptTests[3]
;;
1) # unsigned binary present, currently signed remove 'restore signed'
unset mainOptTests[3]
unset mainOpts[3]
;;
2) # signed binary present, currently unsigned, remove 'unsign' and 'restore unsigned'
unset mainOpts[1]
unset mainOptTests[1]
unset mainOpts[2]
unset mainOptTests[2]
;;
esac
mainOptTests=( "${mainOptTests[@]}" )
mainOpts=( "${mainOpts[@]}" )
printf "\n${bold}"
PS3="${bold}Which do you want to do?: ${normal}"
select opt in "${mainOpts[@]}" ; do
printf "${normal}"
testRes=${mainOptTests[REPLY-1]}
case $testRes in
"all" )
signedState
case $SS in
0)
unsign
;;
1)
restoreUnsigned
;;
esac
resetWarning
upgradePlugins "updateAll"
break
;;
"unsign" )
unsign
break
;;
"restoreUnsigned" )
restoreUnsigned
break
;;
"restoreSigned" )
restoreSigned
break
;;
"resetWarning" )
resetWarning
break
;;
"update" | "updateAll" )
upgradePlugins $testRes
break
;;
"quit" )
exit
;;
esac
done
done