forked from ryangball/nice-updater
-
Notifications
You must be signed in to change notification settings - Fork 7
/
build.sh
executable file
·193 lines (159 loc) · 10.5 KB
/
build.sh
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
#!/bin/bash
# The main identifier which everything hinges on
identifier="com.grahamrpugh.nice_updater"
# Default version of the build, you can leave this alone and specify as an argument like so: ./build.sh 1.7
version="2.5.0"
# The title of the message that is displayed when software updates are in progress and a user is logged in
updateRequiredTitle="macOS Software Updates Required"
# The message that is displayed when software updates are in progress and a user is logged in
updateRequiredMessage="Your administrator requires that these updates are installed as soon as possible.\n\nPlease save your work and press **Continue**. This will open the Software Update panel. From here, press **Install Now** to begin the installation."
# The title of the message that is displayed when software updates are in progress and a user is logged in
updateInProgressTitle="Software Update In Progress"
# The location of your log, keep in mind that if you nest the log into a folder that does not exist you'll need to mkdir -p the directory as well
log="/Library/Logs/Nice_Updater.log"
# The location of the status file, keep in mind that if the folder does not exist you'll need to mkdir -p the directory as well
EAFile="/Library/Scripts/nice_updater_status.txt"
# The number of days to check for updates after a full update has been performed
afterFullUpdateDelayDayCount="7"
# The number of days to check for updates after a updates were checked, but no updates were available
afterEmptyUpdateDelayDayCount="3"
# The number of times to alert a single user prior to forcibly installing updates
maxNotificationCount="8"
# Calendar based start interval - hours and minutes.
startIntervalHour="13" # valid is 0-23. If left blank, daemon will launch every hour instead of once per day.
startIntervalMinute="0" # valid is 0-59. Do not leave blank - set as 0
# The timeout length of the popup window. Should be less than the start interval so that two popups don't start at once.
alertTimeout="3540"
###### Variables below this point are not intended to be modified #####
swiftdialog_tag_required="v2.4.2"
mainDaemonPlist="/Library/LaunchDaemons/${identifier}.plist"
mainDaemonFileName="${mainDaemonPlist##*/}"
mainOnDemandDaemonPlist="/Library/LaunchDaemons/${identifier}_on_demand.plist"
onDemandDaemonFileName="${mainOnDemandDaemonPlist##*/}"
onDemandDaemonIdentifier="${identifier}_on_demand"
watchPathsPlist="/Library/Preferences/${identifier}.trigger.plist"
preferenceFileFullPath="/Library/Preferences/${identifier}.prefs.plist"
preferenceFileName="${preferenceFileFullPath##*/}"
getSwiftDialogDownloadURL() {
url="https://api.github.com/repos/swiftDialog/swiftDialog/releases"
header="Accept: application/json"
tag=${1:-"$(curl -sL -H "${header}" ${url}/latest | awk -F '"' '/tag_name/ { print $4; exit }')"}
curl -sL -H "${header}" "${url}/tags/${tag}" | awk -F '"' '/browser_download_url/ { print $4; exit }'
}
if [[ -n "$1" ]]; then
version="$1"
echo "Version set to $version"
else
echo "No version passed, using version $version"
fi
# Update the variables in the various files of the project
# If you know of a more elegant/efficient way to do this please create a PR
sed -i '' "s|mainDaemonPlist=.*|mainDaemonPlist=\"$mainDaemonPlist\"|" "$PWD/postinstall.sh"
sed -i '' "s|mainDaemonPlist=.*|mainDaemonPlist=\"$mainDaemonPlist\"|" "$PWD/preinstall.sh"
sed -i '' "s|mainOnDemandDaemonPlist=.*|mainOnDemandDaemonPlist=\"$mainOnDemandDaemonPlist\"|" "$PWD/postinstall.sh"
sed -i '' "s|mainOnDemandDaemonPlist=.*|mainOnDemandDaemonPlist=\"$mainOnDemandDaemonPlist\"|" "$PWD/preinstall.sh"
sed -i '' "s|mainOnDemandDaemonPlist=.*|mainOnDemandDaemonPlist=\"$mainOnDemandDaemonPlist\"|" "$PWD/nice_updater.sh"
sed -i '' "s|watchPathsPlist=.*|watchPathsPlist=\"$watchPathsPlist\"|" "$PWD/preinstall.sh"
sed -i '' "s|watchPathsPlist=.*|watchPathsPlist=\"$watchPathsPlist\"|" "$PWD/nice_updater.sh"
sed -i '' "s|preferenceFileFullPath=.*|preferenceFileFullPath=\"$preferenceFileFullPath\"|" "$PWD/postinstall.sh"
sed -i '' "s|preferenceFileFullPath=.*|preferenceFileFullPath=\"$preferenceFileFullPath\"|" "$PWD/nice_updater.sh"
# Create clean temp build directories
find /private/tmp/nice_updater -mindepth 1 -delete &> /dev/null
mkdir -p /private/tmp/nice_updater/files/Library/LaunchDaemons
mkdir -p /private/tmp/nice_updater/files/Library/Preferences
mkdir -p /private/tmp/nice_updater/files/Library/Scripts/
mkdir -p /private/tmp/nice_updater/scripts
mkdir -p "$PWD/build"
# Create/modify the main Daemon plist
[[ -e "$PWD/$mainDaemonFileName" ]] && /usr/libexec/PlistBuddy -c Clear "$PWD/$mainDaemonFileName" &> /dev/null
defaults write "$PWD/$mainDaemonFileName" Label -string "$identifier"
/usr/libexec/PlistBuddy -c "Add :ProgramArguments array" "$PWD/$mainDaemonFileName"
/usr/bin/plutil -insert ProgramArguments.0 -string "/bin/bash" "$PWD/$mainDaemonFileName"
/usr/bin/plutil -insert ProgramArguments.1 -string "/Library/Scripts/nice_updater.sh" "$PWD/$mainDaemonFileName"
/usr/bin/plutil -insert ProgramArguments.2 -string "main" "$PWD/$mainDaemonFileName"
if [[ "$startInterval" ]]; then
defaults write "$PWD/$mainDaemonFileName" StartInterval -int "$startInterval"
else
if [[ $startIntervalHour || $startIntervalMinute ]]; then
/usr/libexec/PlistBuddy -c "Add :StartCalendarInterval dict" "$PWD/$mainDaemonFileName"
[[ $startIntervalHour ]] && /usr/libexec/PlistBuddy -c "Add :StartCalendarInterval:Hour integer '$startIntervalHour'" "$PWD/$mainDaemonFileName"
[[ $startIntervalMinute ]] && /usr/libexec/PlistBuddy -c "Add :StartCalendarInterval:Minute integer '$startIntervalMinute'" "$PWD/$mainDaemonFileName"
fi
fi
# Create/modify the on_demand Daemon plist
[[ -e "$PWD/$onDemandDaemonFileName" ]] && /usr/libexec/PlistBuddy -c Clear "$PWD/$onDemandDaemonFileName" &> /dev/null
defaults write "$PWD/$onDemandDaemonFileName" Label -string "$onDemandDaemonIdentifier"
/usr/libexec/PlistBuddy -c "Add :ProgramArguments array" "$PWD/$onDemandDaemonFileName"
/usr/bin/plutil -insert ProgramArguments.0 -string "/bin/bash" "$PWD/$onDemandDaemonFileName"
/usr/bin/plutil -insert ProgramArguments.1 -string "/Library/Scripts/nice_updater.sh" "$PWD/$onDemandDaemonFileName"
/usr/bin/plutil -insert ProgramArguments.2 -string "on_demand" "$PWD/$onDemandDaemonFileName"
/usr/libexec/PlistBuddy -c "Add :WatchPaths array" "$PWD/$onDemandDaemonFileName"
/usr/bin/plutil -insert WatchPaths.0 -string "$watchPathsPlist" "$PWD/$onDemandDaemonFileName"
# Create/modify the main preference file
[[ -e "$PWD/$preferenceFileName" ]] && /usr/libexec/PlistBuddy -c Clear "$PWD/$preferenceFileName" &> /dev/null
defaults write "$PWD/$preferenceFileName" UpdateRequiredTitle -string "$updateRequiredTitle"
defaults write "$PWD/$preferenceFileName" UpdateRequiredMessage -string "$updateRequiredMessage"
defaults write "$PWD/$preferenceFileName" UpdateInProgressTitle -string "$updateInProgressTitle"
defaults write "$PWD/$preferenceFileName" Log -string "$log"
defaults write "$PWD/$preferenceFileName" EAFile -string "$EAFile"
defaults write "$PWD/$preferenceFileName" AfterFullUpdateDelayDayCount -int "$afterFullUpdateDelayDayCount"
defaults write "$PWD/$preferenceFileName" AfterEmptyUpdateDelayDayCount -int "$afterEmptyUpdateDelayDayCount"
defaults write "$PWD/$preferenceFileName" MaxNotificationCount -int "$maxNotificationCount"
defaults write "$PWD/$preferenceFileName" AlertTimeout -int "$alertTimeout"
defaults write "$PWD/$preferenceFileName" IconCustomPath -string "$iconCustomPath"
# Migrate preinstall and postinstall scripts to temp build directory
cp "$PWD/preinstall.sh" /private/tmp/nice_updater/scripts/preinstall
chmod +x /private/tmp/nice_updater/scripts/preinstall
cp "$PWD/postinstall.sh" /private/tmp/nice_updater/scripts/postinstall
chmod +x /private/tmp/nice_updater/scripts/postinstall
# Put the scripts in place
cp "$PWD/nice_updater.sh" /private/tmp/nice_updater/files/Library/Scripts/nice_updater.sh
cp "$PWD/nice_updater_uninstall.sh" /private/tmp/nice_updater/files/Library/Scripts/nice_updater_uninstall.sh
# put a custom icon in place if present
if find "$PWD/custom_icon" -name "*.png" ; then
icon_path=/Library/Scripts/nice_updater_custom_icon.png
echo "Adding the icon to /private/tmp/nice_updater/files$icon_path"
cp -f "$PWD/custom_icon/"*.png /private/tmp/nice_updater/files$icon_path
defaults write "$PWD/$preferenceFileName" IconCustomPath -string "$icon_path"
else
echo "Nothing found at $PWD/custom_icon/*.png"
defaults write "$PWD/$preferenceFileName" IconCustomPath -string ""
fi
# Copy the LaunchDaemon plists to the temp build directory
cp "$PWD/$mainDaemonFileName" "/private/tmp/nice_updater/files/Library/LaunchDaemons/"
cp "$PWD/$onDemandDaemonFileName" "/private/tmp/nice_updater/files/Library/LaunchDaemons/"
cp "$PWD/$preferenceFileName" "/private/tmp/nice_updater/files/Library/Preferences/"
# Download and copy swiftDialog into the temp build directory
dialog_download_url=$(getSwiftDialogDownloadURL "${swiftdialog_tag_required}")
echo "download url for tag version : ${dialog_download_url}"
echo "Downloading swiftDialog from $dialog_download_url"
curl -L "$dialog_download_url" -o "/private/tmp/nice_updater/scripts/dialog.pkg"
# Remove any unwanted .DS_Store files from the temp build directory
find "/private/tmp/nice_updater/" -name '*.DS_Store' -type f -delete
# Remove the default plists if the identifier has changed
if [[ ! "$identifier" = "com.github.ryangball.nice_updater" ]]; then
rm "$PWD/com.github.ryangball.nice_updater.plist" &> /dev/null
rm "$PWD/com.github.ryangball.nice_updater_on_demand.plist" &> /dev/null
rm "$PWD/com.github.ryangball.nice_updater.prefs.plist" &> /dev/null
fi
# Remove any extended attributes (ACEs) from the temp build directory
/usr/bin/xattr -rc "/private/tmp/nice_updater"
echo "Building the .pkg in $PWD/build/"
/usr/bin/pkgbuild --quiet --root "/private/tmp/nice_updater/files/" \
--install-location "/" \
--scripts "/private/tmp/nice_updater/scripts/" \
--identifier "$identifier" \
--version "$version" \
--ownership recommended \
"$PWD/build/Nice_Updater_${version}.pkg"
# shellcheck disable=SC2181
if [[ "$?" == "0" ]]; then
echo "Revealing Nice_Updater_${version}.pkg in Finder"
open -R "$PWD/build/Nice_Updater_${version}.pkg"
else
echo "Build failed."
fi
# using plutil is fine but it converts the plists to binary which is not good for readability. Let's convert them back.
/usr/bin/plutil -convert xml1 "$PWD/$preferenceFileName"
/usr/bin/plutil -convert xml1 "$PWD/$mainDaemonFileName"
/usr/bin/plutil -convert xml1 "$PWD/$onDemandDaemonFileName"