mirror of
https://github.com/mtan93/Installomator.git
synced 2026-03-08 05:31:53 +00:00
extracted labels
This commit is contained in:
@@ -10,8 +10,8 @@ label="" # if no label is sent to the script, this will be used
|
||||
# with additional ideas and contribution from Isaac Ordonez, Mann consulting
|
||||
# and help from Søren Theilgaard (theilgaard.dk)
|
||||
|
||||
VERSION='0.5.0'
|
||||
VERSIONDATE='2021-04-13'
|
||||
VERSION='0.6.0'
|
||||
VERSIONDATE='2021-04-20'
|
||||
|
||||
export PATH=/usr/bin:/bin:/usr/sbin:/sbin
|
||||
|
||||
|
||||
3211
Installomator_assembled.sh
Normal file
3211
Installomator_assembled.sh
Normal file
File diff suppressed because it is too large
Load Diff
14
assembleScript.sh
Normal file
14
assembleScript.sh
Normal file
@@ -0,0 +1,14 @@
|
||||
#!/bin/zsh
|
||||
|
||||
destination_file="Installomator_assembled.sh"
|
||||
fragments_dir="fragments"
|
||||
labels_dir="$fragments_dir/labels"
|
||||
|
||||
# read the header
|
||||
cat "$fragments_dir/header.txt" > $destination_file
|
||||
|
||||
# all the labels
|
||||
cat "$labels_dir"/*.txt >> $destination_file
|
||||
|
||||
# add the footer
|
||||
cat "$fragments_dir/footer.txt" >> $destination_file
|
||||
27
extractLabels.sh
Normal file
27
extractLabels.sh
Normal file
@@ -0,0 +1,27 @@
|
||||
#!/bin/zsh
|
||||
|
||||
label_re='^([a-z0-9\_-]*)(\)|\|\\)$'
|
||||
endlabel_re='^( |\t);;$'
|
||||
|
||||
label_dir="fragments/labels"
|
||||
|
||||
IFS=$'\n'
|
||||
|
||||
in_label=0
|
||||
current_label=""
|
||||
while read -r line; do
|
||||
if [[ $in_label -eq 0 && "$line" =~ $label_re ]]; then
|
||||
label_name=${match[1]}
|
||||
echo "found label $label_name"
|
||||
in_label=1
|
||||
fi
|
||||
if [[ $in_label -eq 1 ]]; then
|
||||
current_label=$current_label$'\n'$line
|
||||
fi
|
||||
if [[ $in_label -eq 1 && "$line" =~ $endlabel_re ]]; then
|
||||
echo $current_label > "$label_dir/${label_name}.txt"
|
||||
in_label=0
|
||||
current_label=""
|
||||
fi
|
||||
|
||||
done <./Installomator.sh
|
||||
6
fragments/broken/brokenappname.txt
Normal file
6
fragments/broken/brokenappname.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
brokenappname)
|
||||
name="brokenapp"
|
||||
type="dmg"
|
||||
downloadURL="https://dl.google.com/chrome/mac/stable/GGRO/googlechrome.dmg"
|
||||
expectedTeamID="EQHXZ8M8AV"
|
||||
;;
|
||||
6
fragments/broken/brokendownloadurl.txt
Normal file
6
fragments/broken/brokendownloadurl.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
brokendownloadurl)
|
||||
name="Google Chrome"
|
||||
type="dmg"
|
||||
downloadURL="https://broken.com/broken.dmg"
|
||||
expectedTeamID="EQHXZ8M8AV"
|
||||
;;
|
||||
6
fragments/broken/brokenteamid.txt
Normal file
6
fragments/broken/brokenteamid.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
brokenteamid)
|
||||
name="Google Chrome"
|
||||
type="dmg"
|
||||
downloadURL="https://dl.google.com/chrome/mac/stable/GGRO/googlechrome.dmg"
|
||||
expectedTeamID="broken"
|
||||
;;
|
||||
10
fragments/disabled/cdef.txt
Normal file
10
fragments/disabled/cdef.txt
Normal file
@@ -0,0 +1,10 @@
|
||||
|
||||
cdef)
|
||||
# cdef currently not signed
|
||||
# credit: Søren Theilgaard (@theilgaard)
|
||||
name="cdef"
|
||||
type="pkg"
|
||||
downloadURL=$(downloadURLFromGit Shufflepuck cdef)
|
||||
appNewVersion=$(versionFromGit Shufflepuck cdef)
|
||||
#expectedTeamID="EM3ER8T33A"
|
||||
;;
|
||||
10
fragments/disabled/fontforge.txt
Normal file
10
fragments/disabled/fontforge.txt
Normal file
@@ -0,0 +1,10 @@
|
||||
|
||||
fontforge)
|
||||
# FontForge Not signed
|
||||
# credit: Søren Theilgaard (@theilgaard)
|
||||
name="FontForge"
|
||||
type="dmg"
|
||||
downloadURL=$(downloadURLFromGit fontforge fontforge)
|
||||
appNewVersion=$(versionFromGit fontforge fontforge)
|
||||
expectedTeamID=""
|
||||
;;
|
||||
12
fragments/disabled/notifier.txt
Normal file
12
fragments/disabled/notifier.txt
Normal file
@@ -0,0 +1,12 @@
|
||||
|
||||
notifier)
|
||||
# not signed
|
||||
# credit: Søren Theilgaard (@theilgaard)
|
||||
name="dataJAR Notifier"
|
||||
type="pkg"
|
||||
#packageID="uk.co.dataJAR.Notifier" # Version 2.2.3 was actually "uk.co.dataJAR.Notifier-2.2.3" so unusable
|
||||
downloadURL=$(downloadURLFromGit dataJAR Notifier)
|
||||
appNewVersion=$(versionFromGit dataJAR Notifier)
|
||||
expectedTeamID=""
|
||||
blockingProcesses=( "Notifier" )
|
||||
;;
|
||||
9
fragments/disabled/packages.txt
Normal file
9
fragments/disabled/packages.txt
Normal file
@@ -0,0 +1,9 @@
|
||||
|
||||
packages)
|
||||
#NOTE: Packages is signed but _not_ notarized, so spctl will reject it
|
||||
name="Packages"
|
||||
type="pkgInDmg"
|
||||
pkgName="Install Packages.pkg"
|
||||
downloadURL="http://s.sudre.free.fr/Software/files/Packages.dmg"
|
||||
expectedTeamID="NL5M9E394P"
|
||||
;;
|
||||
10
fragments/disabled/powershell-lts.txt
Normal file
10
fragments/disabled/powershell-lts.txt
Normal file
@@ -0,0 +1,10 @@
|
||||
|
||||
powershell-lts)
|
||||
#NOTE: powershell installers are not notarized
|
||||
# credit: Tadayuki Onishi (@kenchan0130)
|
||||
name="PowerShell"
|
||||
type="pkg"
|
||||
downloadURL=$(curl -fs "https://api.github.com/repos/Powershell/Powershell/releases/latest" \
|
||||
| awk -F '"' '/browser_download_url/ && /pkg/ { print $4 }' | grep lts)
|
||||
expectedTeamID="UBF8T346G9"
|
||||
;;
|
||||
10
fragments/disabled/powershell.txt
Normal file
10
fragments/disabled/powershell.txt
Normal file
@@ -0,0 +1,10 @@
|
||||
|
||||
powershell)
|
||||
#NOTE: powershell installers are not notarized
|
||||
# credit: Tadayuki Onishi (@kenchan0130)
|
||||
name="PowerShell"
|
||||
type="pkg"
|
||||
downloadURL=$(curl -fs "https://api.github.com/repos/Powershell/Powershell/releases/latest" \
|
||||
| awk -F '"' '/browser_download_url/ && /pkg/ { print $4 }' | grep -v lts )
|
||||
expectedTeamID="UBF8T346G9"
|
||||
;;
|
||||
10
fragments/disabled/vmwarefusion.txt
Normal file
10
fragments/disabled/vmwarefusion.txt
Normal file
@@ -0,0 +1,10 @@
|
||||
|
||||
vmwarefusion)
|
||||
#TODO: vmwarefusion installation process needs testing
|
||||
# credit: Erik Stam (@erikstam)
|
||||
name="VMware Fusion"
|
||||
type="dmg"
|
||||
downloadURL="https://www.vmware.com/go/getfusion"
|
||||
appNewVersion=$( curl -fsIL "${downloadURL}" | grep -i "^location" | awk '{print $2}' | sed -E 's/.*Fusion-([0-9.]*)-.*/\1/g' )
|
||||
expectedTeamID="EG7KH642X6"
|
||||
;;
|
||||
13
fragments/disabled/wordmat.txt
Normal file
13
fragments/disabled/wordmat.txt
Normal file
@@ -0,0 +1,13 @@
|
||||
|
||||
wordmat)
|
||||
# WordMat currently not signed
|
||||
# credit: Søren Theilgaard (@theilgaard)
|
||||
name="WordMat"
|
||||
type="pkg"
|
||||
packageID="com.eduap.pkg.WordMat"
|
||||
downloadURL=$(downloadURLFromGit Eduap-com WordMat)
|
||||
#downloadURL=$(curl -fs "https://api.github.com/repos/Eduap-com/WordMat/releases/latest" | awk -F '"' "/browser_download_url/ && /pkg/ && ! /sig/ && ! /CLI/ && ! /sha256/ { print \$4 }")
|
||||
appNewVersion=$(versionFromGit Eduap-com WordMat)
|
||||
#curl -fs "https://api.github.com/repos/Eduap-com/WordMat/releases/latest" | grep tag_name | cut -d '"' -f 4 | sed 's/[^0-9\.]//g'
|
||||
expectedTeamID=""
|
||||
;;
|
||||
8
fragments/disabled/wwdcformac.txt
Normal file
8
fragments/disabled/wwdcformac.txt
Normal file
@@ -0,0 +1,8 @@
|
||||
|
||||
wwdcformac)
|
||||
#this label looks like software/site is gone
|
||||
name="WWDC"
|
||||
type="zip"
|
||||
downloadURL="https://cdn.wwdc.io/WWDC_latest.zip"
|
||||
expectedTeamID="8C7439RJLG"
|
||||
;;
|
||||
230
fragments/footer.txt
Normal file
230
fragments/footer.txt
Normal file
@@ -0,0 +1,230 @@
|
||||
*)
|
||||
# unknown label
|
||||
#printlog "unknown label $label"
|
||||
cleanupAndExit 1 "unknown label $label"
|
||||
;;
|
||||
esac
|
||||
|
||||
|
||||
# MARK: application download and installation starts here
|
||||
|
||||
printlog "BLOCKING_PROCESS_ACTION=${BLOCKING_PROCESS_ACTION}"
|
||||
printlog "NOTIFY=${NOTIFY}"
|
||||
|
||||
# Finding LOGO to use in dialogs
|
||||
case $LOGO in
|
||||
appstore)
|
||||
# Apple App Store on Mac
|
||||
if [[ $(sw_vers -buildVersion) > "19" ]]; then
|
||||
LOGO="/System/Applications/App Store.app/Contents/Resources/AppIcon.icns"
|
||||
else
|
||||
LOGO="/Applications/App Store.app/Contents/Resources/AppIcon.icns"
|
||||
fi
|
||||
;;
|
||||
jamf)
|
||||
# Jamf Pro
|
||||
LOGO="/Library/Application Support/JAMF/Jamf.app/Contents/Resources/AppIcon.icns"
|
||||
;;
|
||||
mosyleb)
|
||||
# Mosyle Business
|
||||
LOGO="/Applications/Business.app/Contents/Resources/AppIcon.icns"
|
||||
;;
|
||||
mosylem)
|
||||
# Mosyle Manager (education)
|
||||
LOGO="/Applications/Manager.app/Contents/Resources/AppIcon.icns"
|
||||
;;
|
||||
addigy)
|
||||
# Addigy
|
||||
LOGO="/Library/Addigy/macmanage/MacManage.app/Contents/Resources/atom.icns"
|
||||
;;
|
||||
esac
|
||||
if [[ ! -a "${LOGO}" ]]; then
|
||||
if [[ $(sw_vers -buildVersion) > "19" ]]; then
|
||||
LOGO="/System/Applications/App Store.app/Contents/Resources/AppIcon.icns"
|
||||
else
|
||||
LOGO="/Applications/App Store.app/Contents/Resources/AppIcon.icns"
|
||||
fi
|
||||
fi
|
||||
printlog "LOGO=${LOGO}"
|
||||
|
||||
# MARK: extract info from data
|
||||
if [ -z "$archiveName" ]; then
|
||||
case $type in
|
||||
dmg|pkg|zip|tbz)
|
||||
archiveName="${name}.$type"
|
||||
;;
|
||||
pkgInDmg)
|
||||
archiveName="${name}.dmg"
|
||||
;;
|
||||
*InZip)
|
||||
archiveName="${name}.zip"
|
||||
;;
|
||||
updateronly)
|
||||
;;
|
||||
*)
|
||||
printlog "Cannot handle type $type"
|
||||
cleanupAndExit 99
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
if [ -z "$appName" ]; then
|
||||
# when not given derive from name
|
||||
appName="$name.app"
|
||||
fi
|
||||
|
||||
if [ -z "$targetDir" ]; then
|
||||
case $type in
|
||||
dmg|zip|tbz|app*)
|
||||
targetDir="/Applications"
|
||||
;;
|
||||
pkg*)
|
||||
targetDir="/"
|
||||
;;
|
||||
updateronly)
|
||||
;;
|
||||
*)
|
||||
printlog "Cannot handle type $type"
|
||||
cleanupAndExit 99
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
if [[ -z $blockingProcesses ]]; then
|
||||
printlog "no blocking processes defined, using $name as default"
|
||||
blockingProcesses=( $name )
|
||||
fi
|
||||
|
||||
# MARK: determine tmp dir
|
||||
if [ "$DEBUG" -ne 0 ]; then
|
||||
# for debugging use script dir as working directory
|
||||
tmpDir=$(dirname "$0")
|
||||
else
|
||||
# create temporary working directory
|
||||
tmpDir=$(mktemp -d )
|
||||
fi
|
||||
|
||||
# MARK: change directory to temporary working directory
|
||||
printlog "Changing directory to $tmpDir"
|
||||
if ! cd "$tmpDir"; then
|
||||
printlog "error changing directory $tmpDir"
|
||||
cleanupAndExit 1
|
||||
fi
|
||||
|
||||
# MARK: check if this is an Update and we can use updateTool
|
||||
getAppVersion
|
||||
printlog "appversion: $appversion"
|
||||
if [[ (-n $appversion && -n "$updateTool") || "$type" == "updateronly" ]]; then
|
||||
printlog "appversion & updateTool"
|
||||
if [[ $DEBUG -eq 0 ]]; then
|
||||
if runUpdateTool; then
|
||||
finishing
|
||||
cleanupAndExit 0
|
||||
elif [[ $type == "updateronly" ]];then
|
||||
printlog "type is $type so we end here."
|
||||
cleanupAndExit 0
|
||||
fi # otherwise continue
|
||||
else
|
||||
printlog "DEBUG mode enabled, not running update tool"
|
||||
fi
|
||||
fi
|
||||
|
||||
# MARK: Exit if new version is the same as installed version (appNewVersion specified)
|
||||
# credit: Søren Theilgaard (@theilgaard)
|
||||
if [[ -n $appNewVersion ]]; then
|
||||
printlog "Latest version of $name is $appNewVersion"
|
||||
if [[ $appversion == $appNewVersion ]]; then
|
||||
if [[ $DEBUG -eq 0 ]]; then
|
||||
printlog "There is no newer version available."
|
||||
if [[ $INSTALL != "force" ]]; then
|
||||
message="$name, version $appNewVersion, is the latest version."
|
||||
if [[ $currentUser != "loginwindow" && $NOTIFY == "all" ]]; then
|
||||
printlog "notifying"
|
||||
displaynotification "$message" "No update for $name!"
|
||||
fi
|
||||
cleanupAndExit 0 "No newer version."
|
||||
else
|
||||
printlog "Using force to install anyway."
|
||||
fi
|
||||
else
|
||||
printlog "DEBUG mode enabled, not exiting, but there is no new version of app."
|
||||
fi
|
||||
fi
|
||||
else
|
||||
printlog "Latest version not specified."
|
||||
fi
|
||||
|
||||
# MARK: download the archive
|
||||
if [ -f "$archiveName" ] && [ "$DEBUG" -ne 0 ]; then
|
||||
printlog "$archiveName exists and DEBUG enabled, skipping download"
|
||||
else
|
||||
# download the dmg
|
||||
printlog "Downloading $downloadURL to $archiveName"
|
||||
if [[ $currentUser != "loginwindow" && $NOTIFY == "all" ]]; then
|
||||
printlog "notifying"
|
||||
displaynotification "Downloading $name update" "Download in progress …"
|
||||
fi
|
||||
if ! curl --location --fail --silent "$downloadURL" -o "$archiveName"; then
|
||||
printlog "error downloading $downloadURL"
|
||||
message="$name update/installation failed. This will be logged, so IT can follow up."
|
||||
if [[ $currentUser != "loginwindow" && $NOTIFY == "all" ]]; then
|
||||
printlog "notifying"
|
||||
displaynotification "$message" "Error installing/updating $name"
|
||||
fi
|
||||
cleanupAndExit 2
|
||||
fi
|
||||
fi
|
||||
|
||||
# MARK: when user is logged in, and app is running, prompt user to quit app
|
||||
if [[ $BLOCKING_PROCESS_ACTION == "ignore" ]]; then
|
||||
printlog "ignoring blocking processes"
|
||||
else
|
||||
if [[ $currentUser != "loginwindow" ]]; then
|
||||
if [[ ${#blockingProcesses} -gt 0 ]]; then
|
||||
if [[ ${blockingProcesses[1]} != "NONE" ]]; then
|
||||
checkRunningProcesses
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# MARK: install the download
|
||||
printlog "Installing $name"
|
||||
if [[ $currentUser != "loginwindow" && $NOTIFY == "all" ]]; then
|
||||
printlog "notifying"
|
||||
displaynotification "Installing $name" "Installation in progress …"
|
||||
fi
|
||||
|
||||
case $type in
|
||||
dmg)
|
||||
installFromDMG
|
||||
;;
|
||||
pkg)
|
||||
installFromPKG
|
||||
;;
|
||||
zip)
|
||||
installFromZIP
|
||||
;;
|
||||
tbz)
|
||||
installFromTBZ
|
||||
;;
|
||||
pkgInDmg)
|
||||
installPkgInDmg
|
||||
;;
|
||||
pkgInZip)
|
||||
installPkgInZip
|
||||
;;
|
||||
appInDmgInZip)
|
||||
installAppInDmgInZip
|
||||
;;
|
||||
*)
|
||||
printlog "Cannot handle type $type"
|
||||
cleanupAndExit 99
|
||||
;;
|
||||
esac
|
||||
|
||||
# MARK: Finishing — print installed application location and version
|
||||
finishing
|
||||
|
||||
# all done!
|
||||
cleanupAndExit 0
|
||||
815
fragments/header.txt
Normal file
815
fragments/header.txt
Normal file
@@ -0,0 +1,815 @@
|
||||
#!/bin/zsh
|
||||
label="" # if no label is sent to the script, this will be used
|
||||
|
||||
# Installomator
|
||||
#
|
||||
# Downloads and installs an Applications
|
||||
# 2020 Armin Briegel - Scripting OS X
|
||||
#
|
||||
# inspired by the download scripts from William Smith and Sander Schram
|
||||
# with additional ideas and contribution from Isaac Ordonez, Mann consulting
|
||||
# and help from Søren Theilgaard (theilgaard.dk)
|
||||
|
||||
VERSION='0.6.0'
|
||||
VERSIONDATE='2021-04-20'
|
||||
|
||||
export PATH=/usr/bin:/bin:/usr/sbin:/sbin
|
||||
|
||||
# NOTE: adjust these variables:
|
||||
|
||||
# set to 0 for production, 1 for debugging
|
||||
# while debugging, items will be downloaded to the parent directory of this script
|
||||
# also no actual installation will be performed
|
||||
DEBUG=1
|
||||
|
||||
# notify behavior
|
||||
NOTIFY=success
|
||||
# options:
|
||||
# - success notify the user on success
|
||||
# - silent no notifications
|
||||
# - all all notifications (great for Self Service installation)
|
||||
|
||||
|
||||
# behavior when blocking processes are found
|
||||
BLOCKING_PROCESS_ACTION=prompt_user
|
||||
# options:
|
||||
# - ignore continue even when blocking processes are found
|
||||
# - silent_fail exit script without prompt or installation
|
||||
# - prompt_user show a user dialog for each blocking process found
|
||||
# abort after three attempts to quit
|
||||
# (only if user accepts to quit the apps, otherwise
|
||||
# the update is cancelled).
|
||||
# - prompt_user_then_kill
|
||||
# show a user dialog for each blocking process found,
|
||||
# attempt to quit two times, kill the process finally
|
||||
# - prompt_user_loop
|
||||
# Like prompt-user, but clicking "Not Now", will just wait an hour,
|
||||
# and then it will ask again.
|
||||
# - tell_user User will be showed a notification about the important update,
|
||||
# but user is only allowed to quit and continue, and then we
|
||||
# ask the app to quit.
|
||||
# - tell_user_then_kill
|
||||
# Show dialog 2 times, and if the quitting fails, the
|
||||
# blocking processes will be killed.
|
||||
# - kill kill process without prompting or giving the user a chance to save
|
||||
|
||||
|
||||
# logo-icon used in dialog boxes if app is blocking
|
||||
LOGO=appstore
|
||||
# options:
|
||||
# - appstore Icon is Apple App Store (default)
|
||||
# - jamf JAMF Pro
|
||||
# - mosyleb Mosyle Business
|
||||
# - mosylem Mosyle Manager (Education)
|
||||
# path can also be set in the command call, and if file exists, it will be used, like 'LOGO="/System/Applications/App\ Store.app/Contents/Resources/AppIcon.icns"' (spaces are escaped).
|
||||
|
||||
|
||||
# install behavior
|
||||
INSTALL=""
|
||||
# options:
|
||||
# - When not set, software will only be installed
|
||||
# if it is newer/different in version
|
||||
# - force Install even if it’s the same version
|
||||
|
||||
|
||||
# Re-opening of closed app
|
||||
REOPEN="yes"
|
||||
# options:
|
||||
# - yes App wil be reopened if it was closed
|
||||
# - no App not reopened
|
||||
|
||||
|
||||
# NOTE: How labels work
|
||||
|
||||
# Each workflow label needs to be listed in the case statement below.
|
||||
# for each label these variables can be set:
|
||||
#
|
||||
# - name: (required)
|
||||
# Name of the installed app.
|
||||
# This is used to derive many of the other variables.
|
||||
#
|
||||
# - type: (required)
|
||||
# The type of the installation. Possible values:
|
||||
# - dmg
|
||||
# - pkg
|
||||
# - zip
|
||||
# - tbz
|
||||
# - pkgInDmg
|
||||
# - pkgInZip
|
||||
# - appInDmgInZip
|
||||
# - updateronly This last one is for labels that should only run an updateTool (see below)
|
||||
#
|
||||
# - packageID: (optional)
|
||||
# The package ID of a pkg
|
||||
# If given, will be used to find version of installed software, instead of searching for an app.
|
||||
# Usefull if a pkg does not install an app.
|
||||
# See label installomator_st
|
||||
#
|
||||
# - downloadURL: (required)
|
||||
# URL to download the dmg.
|
||||
# Can be generated with a series of commands (see BBEdit for an example).
|
||||
#
|
||||
# - appNewVersion: (optional)
|
||||
# Version of the downloaded software.
|
||||
# If given, it will be compared to installed version, to see if download is different.
|
||||
# It does not check for newer or not, only different.
|
||||
#
|
||||
# - expectedTeamID: (required)
|
||||
# 10-digit developer team ID.
|
||||
# Obtain the team ID by running:
|
||||
#
|
||||
# - Applications (in dmgs or zips)
|
||||
# spctl -a -vv /Applications/BBEdit.app
|
||||
#
|
||||
# - Pkgs
|
||||
# spctl -a -vv -t install ~/Downloads/desktoppr-0.2.pkg
|
||||
#
|
||||
# The team ID is the ten-digit ID at the end of the line starting with 'origin='
|
||||
#
|
||||
# - archiveName: (optional)
|
||||
# The name of the downloaded file.
|
||||
# When not given the archiveName is derived from the $name.
|
||||
#
|
||||
# - appName: (optional)
|
||||
# File name of the app bundle in the dmg to verify and copy (include .app).
|
||||
# When not given, the appName is derived from the $name.
|
||||
#
|
||||
# - targetDir: (optional)
|
||||
# dmg or zip:
|
||||
# Applications will be copied to this directory.
|
||||
# Default value is '/Applications' for dmg and zip installations.
|
||||
# pkg:
|
||||
# targetDir is used as the install-location. Default is '/'.
|
||||
#
|
||||
# - blockingProcesses: (optional)
|
||||
# Array of process names that will block the installation or update.
|
||||
# If no blockingProcesses array is given the default will be:
|
||||
# blockingProcesses=( $name )
|
||||
# When a package contains multiple applications, _all_ should be listed, e.g:
|
||||
# blockingProcesses=( "Keynote" "Pages" "Numbers" )
|
||||
# When a workflow has no blocking processes, use
|
||||
# blockingProcesses=( NONE )
|
||||
#
|
||||
# - pkgName: (optional, only used for pkgInDmg, dmgInZip, and appInDmgInZip)
|
||||
# File name of the pkg/dmg file _inside_ the dmg or zip
|
||||
# When not given the pkgName is derived from the $name
|
||||
#
|
||||
# - updateTool:
|
||||
# - updateToolArguments:
|
||||
# When Installomator detects an existing installation of the application,
|
||||
# and the updateTool variable is set
|
||||
# $updateTool $updateArguments
|
||||
# Will be run instead of of downloading and installing a complete new version.
|
||||
# Use this when the updateTool does differential and optimized downloads.
|
||||
# e.g. msupdate
|
||||
#
|
||||
# - updateToolRunAsCurrentUser:
|
||||
# When this variable is set (any value), $updateTool will be run as the current user.
|
||||
#
|
||||
|
||||
|
||||
# MARK: Functions
|
||||
|
||||
cleanupAndExit() { # $1 = exit code, $2 message
|
||||
if [[ -n $2 && $1 -ne 0 ]]; then
|
||||
printlog "ERROR: $2"
|
||||
fi
|
||||
if [ "$DEBUG" -eq 0 ]; then
|
||||
# remove the temporary working directory when done
|
||||
printlog "Deleting $tmpDir"
|
||||
rm -Rf "$tmpDir"
|
||||
fi
|
||||
|
||||
if [ -n "$dmgmount" ]; then
|
||||
# unmount disk image
|
||||
printlog "Unmounting $dmgmount"
|
||||
hdiutil detach "$dmgmount"
|
||||
fi
|
||||
# If we closed any processes, reopen the app again
|
||||
reopenClosedProcess
|
||||
printlog "################## End Installomator, exit code $1 \n\n"
|
||||
exit "$1"
|
||||
}
|
||||
|
||||
runAsUser() {
|
||||
if [[ $currentUser != "loginwindow" ]]; then
|
||||
uid=$(id -u "$currentUser")
|
||||
launchctl asuser $uid sudo -u $currentUser "$@"
|
||||
fi
|
||||
}
|
||||
|
||||
reloadAsUser() {
|
||||
if [[ $currentUser != "loginwindow" ]]; then
|
||||
uid=$(id -u "$currentUser")
|
||||
su - $currentUser -c "${@}"
|
||||
fi
|
||||
}
|
||||
|
||||
displaydialog() { # $1: message $2: title
|
||||
message=${1:-"Message"}
|
||||
title=${2:-"Installomator"}
|
||||
runAsUser osascript -e "button returned of (display dialog \"$message\" with title \"$title\" buttons {\"Not Now\", \"Quit and Update\"} default button \"Quit and Update\" with icon POSIX file \"$LOGO\")"
|
||||
}
|
||||
|
||||
displaydialogContinue() { # $1: message $2: title
|
||||
message=${1:-"Message"}
|
||||
title=${2:-"Installomator"}
|
||||
runAsUser osascript -e "button returned of (display dialog \"$message\" with title \"$title\" buttons {\"Quit and Update\"} default button \"Quit and Update\" with icon POSIX file \"$LOGO\")"
|
||||
}
|
||||
|
||||
displaynotification() { # $1: message $2: title
|
||||
message=${1:-"Message"}
|
||||
title=${2:-"Notification"}
|
||||
manageaction="/Library/Application Support/JAMF/bin/Management Action.app/Contents/MacOS/Management Action"
|
||||
|
||||
if [[ -x "$manageaction" ]]; then
|
||||
"$manageaction" -message "$message" -title "$title"
|
||||
else
|
||||
runAsUser osascript -e "display notification \"$message\" with title \"$title\""
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
# MARK: Logging
|
||||
log_location="/private/var/log/Installomator.log"
|
||||
|
||||
printlog(){
|
||||
|
||||
timestamp=$(date +%F\ %T)
|
||||
|
||||
if [[ "$(whoami)" == "root" ]]; then
|
||||
echo "$timestamp" "$label" "$1" | tee -a $log_location
|
||||
else
|
||||
echo "$timestamp" "$label" "$1"
|
||||
fi
|
||||
}
|
||||
|
||||
# will get the latest release download from a github repo
|
||||
downloadURLFromGit() { # $1 git user name, $2 git repo name
|
||||
gitusername=${1?:"no git user name"}
|
||||
gitreponame=${2?:"no git repo name"}
|
||||
|
||||
if [[ $type == "pkgInDmg" ]]; then
|
||||
filetype="dmg"
|
||||
elif [[ $type == "pkgInZip" ]]; then
|
||||
filetype="zip"
|
||||
else
|
||||
filetype=$type
|
||||
fi
|
||||
|
||||
if [ -n "$archiveName" ]; then
|
||||
downloadURL=$(curl --silent --fail "https://api.github.com/repos/$gitusername/$gitreponame/releases/latest" \
|
||||
| awk -F '"' "/browser_download_url/ && /$archiveName\"/ { print \$4; exit }")
|
||||
else
|
||||
downloadURL=$(curl --silent --fail "https://api.github.com/repos/$gitusername/$gitreponame/releases/latest" \
|
||||
| awk -F '"' "/browser_download_url/ && /$filetype\"/ { print \$4; exit }")
|
||||
fi
|
||||
if [ -z "$downloadURL" ]; then
|
||||
cleanupAndExit 9 "could not retrieve download URL for $gitusername/$gitreponame"
|
||||
#exit 9
|
||||
else
|
||||
echo "$downloadURL"
|
||||
return 0
|
||||
fi
|
||||
}
|
||||
|
||||
versionFromGit() {
|
||||
# credit: Søren Theilgaard (@theilgaard)
|
||||
# $1 git user name, $2 git repo name
|
||||
gitusername=${1?:"no git user name"}
|
||||
gitreponame=${2?:"no git repo name"}
|
||||
|
||||
appNewVersion=$(curl --silent --fail "https://api.github.com/repos/$gitusername/$gitreponame/releases/latest" | grep tag_name | cut -d '"' -f 4 | sed 's/[^0-9\.]//g')
|
||||
if [ -z "$appNewVersion" ]; then
|
||||
printlog "could not retrieve version number for $gitusername/$gitreponame"
|
||||
appNewVersion=""
|
||||
else
|
||||
echo "$appNewVersion"
|
||||
return 0
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
# Handling of differences in xpath between Catalina and Big Sur
|
||||
xpath() {
|
||||
# the xpath tool changes in Big Sur and now requires the `-e` option
|
||||
if [[ $(sw_vers -buildVersion) > "20A" ]]; then
|
||||
/usr/bin/xpath -e $@
|
||||
# alternative: switch to xmllint (which is not perl)
|
||||
#xmllint --xpath $@ -
|
||||
else
|
||||
/usr/bin/xpath $@
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
getAppVersion() {
|
||||
# modified by: Søren Theilgaard (@theilgaard)
|
||||
# pkgs contains a version number, then we don't have to search for an app
|
||||
if [[ $packageID != "" ]]; then
|
||||
appversion="$(pkgutil --pkg-info-plist ${packageID} 2>/dev/null | grep -A 1 pkg-version | tail -1 | sed -E 's/.*>([0-9.]*)<.*/\1/g')"
|
||||
if [[ $appversion != "" ]]; then
|
||||
printlog "found packageID $packageID installed, version $appversion"
|
||||
return
|
||||
else
|
||||
printlog "No version found using packageID $packageID"
|
||||
fi
|
||||
fi
|
||||
|
||||
# get all apps matching name
|
||||
applist=$(mdfind "kind:application $appName" -0 )
|
||||
if [[ $applist = "" ]]; then
|
||||
printlog "Spotlight not returning any app, trying manually in /Applications."
|
||||
if [[ -d "/Applications/$appName" ]]; then
|
||||
applist="/Applications/$appName"
|
||||
fi
|
||||
fi
|
||||
|
||||
appPathArray=( ${(0)applist} )
|
||||
|
||||
if [[ ${#appPathArray} -gt 0 ]]; then
|
||||
filteredAppPaths=( ${(M)appPathArray:#${targetDir}*} )
|
||||
if [[ ${#filteredAppPaths} -eq 1 ]]; then
|
||||
installedAppPath=$filteredAppPaths[1]
|
||||
#appversion=$(mdls -name kMDItemVersion -raw $installedAppPath )
|
||||
appversion=$(defaults read $installedAppPath/Contents/Info.plist CFBundleShortVersionString) #Not dependant on Spotlight indexing
|
||||
printlog "found app at $installedAppPath, version $appversion"
|
||||
else
|
||||
printlog "could not determine location of $appName"
|
||||
fi
|
||||
else
|
||||
printlog "could not find $appName"
|
||||
fi
|
||||
}
|
||||
|
||||
checkRunningProcesses() {
|
||||
# don't check in DEBUG mode
|
||||
if [[ $DEBUG -ne 0 ]]; then
|
||||
printlog "DEBUG mode, not checking for blocking processes"
|
||||
return
|
||||
fi
|
||||
|
||||
# try at most 3 times
|
||||
for i in {1..4}; do
|
||||
countedProcesses=0
|
||||
for x in ${blockingProcesses}; do
|
||||
if pgrep -xq "$x"; then
|
||||
printlog "found blocking process $x"
|
||||
appClosed=1
|
||||
|
||||
case $BLOCKING_PROCESS_ACTION in
|
||||
kill)
|
||||
printlog "killing process $x"
|
||||
pkill $x
|
||||
sleep 5
|
||||
;;
|
||||
prompt_user|prompt_user_then_kill)
|
||||
button=$(displaydialog "Quit “$x” to continue updating? (Leave this dialogue if you want to activate this update later)." "The application “$x” needs to be updated.")
|
||||
if [[ $button = "Not Now" ]]; then
|
||||
cleanupAndExit 10 "user aborted update"
|
||||
else
|
||||
if [[ $i > 2 && $BLOCKING_PROCESS_ACTION = "prompt_user_then_kill" ]]; then
|
||||
printlog "Changing BLOCKING_PROCESS_ACTION to kill"
|
||||
BLOCKING_PROCESS_ACTION=kill
|
||||
else
|
||||
printlog "telling app $x to quit"
|
||||
runAsUser osascript -e "tell app \"$x\" to quit"
|
||||
# give the user a bit of time to quit apps
|
||||
printlog "waiting 30 seconds for processes to quit"
|
||||
sleep 30
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
prompt_user_loop)
|
||||
button=$(displaydialog "Quit “$x” to continue updating? (Click “Not Now” to be asked in 1 hour, or leave this open until you are ready)." "The application “$x” needs to be updated.")
|
||||
if [[ $button = "Not Now" ]]; then
|
||||
if [[ $i < 2 ]]; then
|
||||
printlog "user wants to wait an hour"
|
||||
sleep 3600 # 3600 seconds is an hour
|
||||
else
|
||||
printlog "change of BLOCKING_PROCESS_ACTION to tell_user"
|
||||
BLOCKING_PROCESS_ACTION=tell_user
|
||||
fi
|
||||
else
|
||||
printlog "telling app $x to quit"
|
||||
runAsUser osascript -e "tell app \"$x\" to quit"
|
||||
# give the user a bit of time to quit apps
|
||||
printlog "waiting 30 seconds for processes to quit"
|
||||
sleep 30
|
||||
fi
|
||||
;;
|
||||
tell_user|tell_user_then_kill)
|
||||
button=$(displaydialogContinue "Quit “$x” to continue updating? (This is an important update). Wait for notification of update before launching app again." "The application “$x” needs to be updated.")
|
||||
printlog "telling app $x to quit"
|
||||
runAsUser osascript -e "tell app \"$x\" to quit"
|
||||
# give the user a bit of time to quit apps
|
||||
printlog "waiting 30 seconds for processes to quit"
|
||||
sleep 30
|
||||
if [[ $i > 1 && $BLOCKING_PROCESS_ACTION = tell_user_then_kill ]]; then
|
||||
printlog "Changing BLOCKING_PROCESS_ACTION to kill"
|
||||
BLOCKING_PROCESS_ACTION=kill
|
||||
fi
|
||||
;;
|
||||
silent_fail)
|
||||
cleanupAndExit 12 "blocking process '$x' found, aborting"
|
||||
;;
|
||||
esac
|
||||
|
||||
countedProcesses=$((countedProcesses + 1))
|
||||
fi
|
||||
done
|
||||
|
||||
done
|
||||
|
||||
if [[ $countedProcesses -ne 0 ]]; then
|
||||
cleanupAndExit 11 "could not quit all processes, aborting..."
|
||||
fi
|
||||
|
||||
printlog "no more blocking processes, continue with update"
|
||||
}
|
||||
|
||||
reopenClosedProcess() {
|
||||
# If Installomator closed any processes, let's get the app opened again
|
||||
# credit: Søren Theilgaard (@theilgaard)
|
||||
|
||||
# don't reopen if REOPEN is not "yes"
|
||||
if [[ $REOPEN != yes ]]; then
|
||||
printlog "REOPEN=no, not reopening anything"
|
||||
return
|
||||
fi
|
||||
|
||||
# don't reopen in DEBUG mode
|
||||
if [[ $DEBUG -ne 0 ]]; then
|
||||
printlog "DEBUG mode, not reopening anything"
|
||||
return
|
||||
fi
|
||||
|
||||
if [[ $appClosed == 1 ]]; then
|
||||
printlog "Telling app $appName to open"
|
||||
#runAsUser osascript -e "tell app \"$appName\" to open"
|
||||
#runAsUser open -a "${appName}"
|
||||
reloadAsUser "open -a \"${appName}\""
|
||||
#reloadAsUser "open \"${(0)applist}\""
|
||||
processuser=$(ps aux | grep -i "${appName}" | grep -vi "grep" | awk '{print $1}')
|
||||
printlog "Reopened ${appName} as $processuser"
|
||||
else
|
||||
printlog "App not closed, so no reopen."
|
||||
fi
|
||||
}
|
||||
|
||||
installAppWithPath() { # $1: path to app to install in $targetDir
|
||||
# modified by: Søren Theilgaard (@theilgaard)
|
||||
appPath=${1?:"no path to app"}
|
||||
|
||||
# check if app exists
|
||||
if [ ! -e "$appPath" ]; then
|
||||
cleanupAndExit 8 "could not find: $appPath"
|
||||
fi
|
||||
|
||||
# verify with spctl
|
||||
printlog "Verifying: $appPath"
|
||||
if ! teamID=$(spctl -a -vv "$appPath" 2>&1 | awk '/origin=/ {print $NF }' | tr -d '()' ); then
|
||||
cleanupAndExit 4 "Error verifying $appPath"
|
||||
fi
|
||||
|
||||
printlog "Team ID matching: $teamID (expected: $expectedTeamID )"
|
||||
|
||||
if [ "$expectedTeamID" != "$teamID" ]; then
|
||||
cleanupAndExit 5 "Team IDs do not match"
|
||||
fi
|
||||
|
||||
# versioncheck
|
||||
# credit: Søren Theilgaard (@theilgaard)
|
||||
appNewVersion=$(defaults read $appPath/Contents/Info.plist CFBundleShortVersionString)
|
||||
if [[ $appversion == $appNewVersion ]]; then
|
||||
printlog "Downloaded version of $name is $appNewVersion, same as installed."
|
||||
if [[ $INSTALL != "force" ]]; then
|
||||
message="$name, version $appNewVersion, is the latest version."
|
||||
if [[ $currentUser != "loginwindow" && $NOTIFY == "all" ]]; then
|
||||
printlog "notifying"
|
||||
displaynotification "$message" "No update for $name!"
|
||||
fi
|
||||
cleanupAndExit 0 "No new version to install"
|
||||
else
|
||||
printlog "Using force to install anyway."
|
||||
fi
|
||||
else
|
||||
printlog "Downloaded version of $name is $appNewVersion (replacing version $appversion)."
|
||||
fi
|
||||
|
||||
# skip install for DEBUG
|
||||
if [ "$DEBUG" -ne 0 ]; then
|
||||
printlog "DEBUG enabled, skipping remove, copy and chown steps"
|
||||
return 0
|
||||
fi
|
||||
|
||||
# check for root
|
||||
if [ "$(whoami)" != "root" ]; then
|
||||
# not running as root
|
||||
cleanupAndExit 6 "not running as root, exiting"
|
||||
fi
|
||||
|
||||
# remove existing application
|
||||
if [ -e "$targetDir/$appName" ]; then
|
||||
printlog "Removing existing $targetDir/$appName"
|
||||
rm -Rf "$targetDir/$appName"
|
||||
fi
|
||||
|
||||
# copy app to /Applications
|
||||
printlog "Copy $appPath to $targetDir"
|
||||
if ! ditto "$appPath" "$targetDir/$appName"; then
|
||||
cleanupAndExit 7 "Error while copying"
|
||||
fi
|
||||
|
||||
|
||||
# set ownership to current user
|
||||
if [ "$currentUser" != "loginwindow" ]; then
|
||||
printlog "Changing owner to $currentUser"
|
||||
chown -R "$currentUser" "$targetDir/$appName"
|
||||
else
|
||||
printlog "No user logged in, not changing user"
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
mountDMG() {
|
||||
# mount the dmg
|
||||
printlog "Mounting $tmpDir/$archiveName"
|
||||
# always pipe 'Y\n' in case the dmg requires an agreement
|
||||
if ! dmgmount=$(echo 'Y'$'\n' | hdiutil attach "$tmpDir/$archiveName" -nobrowse -readonly | tail -n 1 | cut -c 54- ); then
|
||||
cleanupAndExit 3 "Error mounting $tmpDir/$archiveName"
|
||||
fi
|
||||
|
||||
if [[ ! -e $dmgmount ]]; then
|
||||
printlog "Error mounting $tmpDir/$archiveName"
|
||||
cleanupAndExit 3
|
||||
fi
|
||||
|
||||
printlog "Mounted: $dmgmount"
|
||||
}
|
||||
|
||||
installFromDMG() {
|
||||
mountDMG
|
||||
|
||||
installAppWithPath "$dmgmount/$appName"
|
||||
}
|
||||
|
||||
installFromPKG() {
|
||||
# verify with spctl
|
||||
printlog "Verifying: $archiveName"
|
||||
|
||||
if ! spctlout=$(spctl -a -vv -t install "$archiveName" 2>&1 ); then
|
||||
printlog "Error verifying $archiveName"
|
||||
cleanupAndExit 4
|
||||
fi
|
||||
|
||||
teamID=$(echo $spctlout | awk -F '(' '/origin=/ {print $2 }' | tr -d '()' )
|
||||
|
||||
# Apple signed software has no teamID, grab entire origin instead
|
||||
if [[ -z $teamID ]]; then
|
||||
teamID=$(echo $spctlout | awk -F '=' '/origin=/ {print $NF }')
|
||||
fi
|
||||
|
||||
|
||||
printlog "Team ID: $teamID (expected: $expectedTeamID )"
|
||||
|
||||
if [ "$expectedTeamID" != "$teamID" ]; then
|
||||
printlog "Team IDs do not match!"
|
||||
cleanupAndExit 5
|
||||
fi
|
||||
|
||||
# Check version of pkg to be installed if packageID is set
|
||||
if [[ $packageID != "" && $appversion != "" ]]; then
|
||||
printlog "Checking package version."
|
||||
pkgutil --expand "$archiveName" "$archiveName"_pkg
|
||||
#printlog "$(cat "$archiveName"_pkg/Distribution | xpath '//installer-gui-script/pkg-ref[@id][@version]' 2>/dev/null)"
|
||||
appNewVersion=$(cat "$archiveName"_pkg/Distribution | xpath '//installer-gui-script/pkg-ref[@id][@version]' 2>/dev/null | grep -i "$packageID" | tr ' ' '\n' | grep -i version | cut -d \" -f 2) #sed -E 's/.*\"([0-9.]*)\".*/\1/g'
|
||||
rm -r "$archiveName"_pkg
|
||||
printlog "Downloaded package $packageID version $appNewVersion"
|
||||
if [[ $appversion == $appNewVersion ]]; then
|
||||
printlog "Downloaded version of $name is the same as installed."
|
||||
if [[ $INSTALL != "force" ]]; then
|
||||
message="$name, version $appNewVersion, is the latest version."
|
||||
if [[ $currentUser != "loginwindow" && $NOTIFY == "all" ]]; then
|
||||
printlog "notifying"
|
||||
displaynotification "$message" "No update for $name!"
|
||||
fi
|
||||
cleanupAndExit 0 "No new version to install"
|
||||
else
|
||||
printlog "Using force to install anyway."
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# skip install for DEBUG
|
||||
if [ "$DEBUG" -ne 0 ]; then
|
||||
printlog "DEBUG enabled, skipping installation"
|
||||
return 0
|
||||
fi
|
||||
|
||||
# check for root
|
||||
if [ "$(whoami)" != "root" ]; then
|
||||
# not running as root
|
||||
cleanupAndExit 6 "not running as root, exiting"
|
||||
fi
|
||||
|
||||
# install pkg
|
||||
printlog "Installing $archiveName to $targetDir"
|
||||
if ! installer -pkg "$archiveName" -tgt "$targetDir" ; then
|
||||
printlog "error installing $archiveName"
|
||||
cleanupAndExit 9
|
||||
fi
|
||||
}
|
||||
|
||||
installFromZIP() {
|
||||
# unzip the archive
|
||||
printlog "Unzipping $archiveName"
|
||||
|
||||
# tar -xf "$archiveName"
|
||||
|
||||
# note: when you expand a zip using tar in Mojave the expanded
|
||||
# app will never pass the spctl check
|
||||
|
||||
# unzip -o -qq "$archiveName"
|
||||
|
||||
# note: githubdesktop fails spctl verification when expanded
|
||||
# with unzip
|
||||
|
||||
ditto -x -k "$archiveName" "$tmpDir"
|
||||
installAppWithPath "$tmpDir/$appName"
|
||||
}
|
||||
|
||||
installFromTBZ() {
|
||||
# unzip the archive
|
||||
printlog "Unzipping $archiveName"
|
||||
tar -xf "$archiveName"
|
||||
installAppWithPath "$tmpDir/$appName"
|
||||
}
|
||||
|
||||
installPkgInDmg() {
|
||||
mountDMG
|
||||
# locate pkg in dmg
|
||||
if [[ -z $pkgName ]]; then
|
||||
# find first file ending with 'pkg'
|
||||
findfiles=$(find "$dmgmount" -iname "*.pkg" -maxdepth 1 )
|
||||
filearray=( ${(f)findfiles} )
|
||||
if [[ ${#filearray} -eq 0 ]]; then
|
||||
cleanupAndExit 20 "couldn't find pkg in dmg $archiveName"
|
||||
fi
|
||||
archiveName="${filearray[1]}"
|
||||
printlog "found pkg: $archiveName"
|
||||
else
|
||||
# it is now safe to overwrite archiveName for installFromPKG
|
||||
archiveName="$dmgmount/$pkgName"
|
||||
fi
|
||||
|
||||
# installFromPkgs
|
||||
installFromPKG
|
||||
}
|
||||
|
||||
installPkgInZip() {
|
||||
# unzip the archive
|
||||
printlog "Unzipping $archiveName"
|
||||
tar -xf "$archiveName"
|
||||
|
||||
# locate pkg in zip
|
||||
if [[ -z $pkgName ]]; then
|
||||
# find first file ending with 'pkg'
|
||||
findfiles=$(find "$tmpDir" -iname "*.pkg" -maxdepth 2 )
|
||||
filearray=( ${(f)findfiles} )
|
||||
if [[ ${#filearray} -eq 0 ]]; then
|
||||
cleanupAndExit 20 "couldn't find pkg in zip $archiveName"
|
||||
fi
|
||||
archiveName="${filearray[1]}"
|
||||
# it is now safe to overwrite archiveName for installFromPKG
|
||||
printlog "found pkg: $archiveName"
|
||||
else
|
||||
# it is now safe to overwrite archiveName for installFromPKG
|
||||
archiveName="$tmpDir/$pkgName"
|
||||
fi
|
||||
|
||||
# installFromPkgs
|
||||
installFromPKG
|
||||
}
|
||||
|
||||
installAppInDmgInZip() {
|
||||
# unzip the archive
|
||||
printlog "Unzipping $archiveName"
|
||||
tar -xf "$archiveName"
|
||||
|
||||
# locate dmg in zip
|
||||
if [[ -z $pkgName ]]; then
|
||||
# find first file ending with 'dmg'
|
||||
findfiles=$(find "$tmpDir" -iname "*.dmg" -maxdepth 2 )
|
||||
filearray=( ${(f)findfiles} )
|
||||
if [[ ${#filearray} -eq 0 ]]; then
|
||||
cleanupAndExit 20 "couldn't find dmg in zip $archiveName"
|
||||
fi
|
||||
archiveName="$(basename ${filearray[1]})"
|
||||
# it is now safe to overwrite archiveName for installFromDMG
|
||||
printlog "found dmg: $tmpDir/$archiveName"
|
||||
else
|
||||
# it is now safe to overwrite archiveName for installFromDMG
|
||||
archiveName="$pkgName"
|
||||
fi
|
||||
|
||||
# installFromDMG, DMG expected to include an app (will not work with pkg)
|
||||
installFromDMG
|
||||
}
|
||||
|
||||
runUpdateTool() {
|
||||
printlog "Function called: runUpdateTool"
|
||||
if [[ -x $updateTool ]]; then
|
||||
printlog "running $updateTool $updateToolArguments"
|
||||
if [[ -n $updateToolRunAsCurrentUser ]]; then
|
||||
runAsUser $updateTool ${updateToolArguments}
|
||||
else
|
||||
$updateTool ${updateToolArguments}
|
||||
fi
|
||||
if [[ $? -ne 0 ]]; then
|
||||
cleanupAndExit 15 "Error running $updateTool"
|
||||
fi
|
||||
else
|
||||
printlog "couldn't find $updateTool, continuing normally"
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
finishing() {
|
||||
printlog "Finishing…"
|
||||
sleep 10 # wait a moment to let spotlight catch up
|
||||
getAppVersion
|
||||
|
||||
if [[ -z $appversion ]]; then
|
||||
message="Installed $name"
|
||||
else
|
||||
message="Installed $name, version $appversion"
|
||||
fi
|
||||
|
||||
printlog "$message"
|
||||
|
||||
if [[ $currentUser != "loginwindow" && ( $NOTIFY == "success" || $NOTIFY == "all" ) ]]; then
|
||||
printlog "notifying"
|
||||
displaynotification "$message" "$name update/installation complete!"
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
# MARK: check minimal macOS requirement
|
||||
autoload is-at-least
|
||||
|
||||
if ! is-at-least 10.14 $(sw_vers -productVersion); then
|
||||
printlog "Installomator requires at least macOS 10.14 Mojave."
|
||||
exit 98
|
||||
fi
|
||||
|
||||
# MARK: argument parsing
|
||||
if [[ $# -eq 0 ]]; then
|
||||
if [[ -z $label ]]; then # check if label is set inside script
|
||||
printlog "no label provided, printing labels"
|
||||
grep -E '^[a-z0-9\_-]*(\)|\|\\)$' "$0" | tr -d ')|\' | grep -v -E '^(broken.*|longversion|version|valuesfromarguments)$' | sort
|
||||
#grep -E '^[a-z0-9\_-]*(\)|\|\\)$' "${labelFile}" | tr -d ')|\' | grep -v -E '^(broken.*|longversion|version|valuesfromarguments)$' | sort
|
||||
exit 0
|
||||
fi
|
||||
elif [[ $1 == "/" ]]; then
|
||||
# jamf uses sends '/' as the first argument
|
||||
printlog "shifting arguments for Jamf"
|
||||
shift 3
|
||||
fi
|
||||
|
||||
while [[ -n $1 ]]; do
|
||||
if [[ $1 =~ ".*\=.*" ]]; then
|
||||
# if an argument contains an = character, send it to eval
|
||||
printlog "setting variable from argument $1"
|
||||
eval $1
|
||||
else
|
||||
# assume it's a label
|
||||
label=$1
|
||||
fi
|
||||
# shift to next argument
|
||||
shift 1
|
||||
done
|
||||
|
||||
# lowercase the label
|
||||
label=${label:l}
|
||||
|
||||
printlog "################## Start Installomator v. $VERSION"
|
||||
printlog "################## $label"
|
||||
|
||||
# get current user
|
||||
currentUser=$(scutil <<< "show State:/Users/ConsoleUser" | awk '/Name :/ { print $3 }')
|
||||
|
||||
|
||||
# MARK: labels in case statement
|
||||
case $label in
|
||||
version)
|
||||
# print the script VERSION
|
||||
printlog "$VERSION"
|
||||
exit 0
|
||||
;;
|
||||
longversion)
|
||||
# print the script version
|
||||
printlog "Installomater: version $VERSION ($VERSIONDATE)"
|
||||
exit 0
|
||||
;;
|
||||
10
fragments/labels/1password7.txt
Normal file
10
fragments/labels/1password7.txt
Normal file
@@ -0,0 +1,10 @@
|
||||
1password7)
|
||||
name="1Password 7"
|
||||
type="pkg"
|
||||
downloadURL="https://app-updates.agilebits.com/download/OPM7"
|
||||
appNewVersion=$( curl -fsIL "${downloadURL}" | grep -i "^location" | awk '{print $2}' | sed -E 's/.*\/[0-9a-zA-Z]*-([0-9.]*)\..*/\1/g' )
|
||||
expectedTeamID="2BUA8C4S2C"
|
||||
blockingProcesses=( "1Password Extension Helper" "1Password 7" "1Password (Safari)" "1PasswordNativeMessageHost" "1PasswordSafariAppExtension" )
|
||||
#forcefulQuit=YES
|
||||
#Company="Agilebits"
|
||||
;;
|
||||
10
fragments/labels/8x8.txt
Normal file
10
fragments/labels/8x8.txt
Normal file
@@ -0,0 +1,10 @@
|
||||
8x8)
|
||||
# credit: #D-A-James from MacAdmins Slack and Isaac Ordonez, Mann consulting (@mannconsulting)
|
||||
name="8x8 Work"
|
||||
type="dmg"
|
||||
downloadURL=$(curl -fs -L https://support.8x8.com/cloud-phone-service/voice/work-desktop/download-8x8-work-for-desktop | grep -m 1 -o "https.*dmg" | sed 's/\"//' | awk '{print $1}')
|
||||
# As for appNewVersion, it needs to be checked for newer version than 7.2.4
|
||||
appNewVersion=$(curl -fs -L https://support.8x8.com/cloud-phone-service/voice/work-desktop/download-8x8-work-for-desktop | grep -m 1 -o "https.*dmg" | sed 's/\"//' | awk '{print $1}' | sed -E 's/.*-v([0-9\.]*)[-\.]*.*/\1/' )
|
||||
expectedTeamID="FC967L3QRG"
|
||||
#Company="8x8"
|
||||
;;
|
||||
8
fragments/labels/abstract.txt
Normal file
8
fragments/labels/abstract.txt
Normal file
@@ -0,0 +1,8 @@
|
||||
abstract)
|
||||
name="Abstract"
|
||||
type="zip"
|
||||
downloadURL="https://api.goabstract.com/releases/latest/download"
|
||||
appNewVersion=$( curl -fsIL "${downloadURL}" | grep -i "^location" | awk '{print $2}' | sed -E 's/.*\/[a-zA-Z]*-([0-9.]*)\..*/\1/g' )
|
||||
expectedTeamID="77MZLZE47D"
|
||||
#Company="Elastic Projects, Inc"
|
||||
;;
|
||||
8
fragments/labels/adobebrackets.txt
Normal file
8
fragments/labels/adobebrackets.txt
Normal file
@@ -0,0 +1,8 @@
|
||||
adobebrackets)
|
||||
# credit: Adrian Bühler (@midni9ht)
|
||||
name="Brackets"
|
||||
type="dmg"
|
||||
downloadURL=$(downloadURLFromGit adobe brackets )
|
||||
appNewVersion=$(versionFromGit adobe brackets )
|
||||
expectedTeamID="JQ525L2MZD"
|
||||
;;
|
||||
10
fragments/labels/adobeconnect.txt
Normal file
10
fragments/labels/adobeconnect.txt
Normal file
@@ -0,0 +1,10 @@
|
||||
adobeconnect)
|
||||
# credit: Oh4sh0 https://github.com/Oh4sh0
|
||||
# Comment by Søren: I do not know this software.
|
||||
# Looks like it's an Adobe installer in an app, so it will probably not work
|
||||
name="AdobeConnectInstaller"
|
||||
type="dmg"
|
||||
downloadURL="http://www.adobe.com/go/ConnectSetupMac"
|
||||
appNewVersion=$(curl -fs https://helpx.adobe.com/adobe-connect/connect-downloads-updates.html | grep "Mac" | grep version | head -1 | sed -E 's/.*\(version ([0-9\.]*),.*/\1/g')
|
||||
expectedTeamID="JQ525L2MZD"
|
||||
;;
|
||||
9
fragments/labels/adobereaderdc-update.txt
Normal file
9
fragments/labels/adobereaderdc-update.txt
Normal file
@@ -0,0 +1,9 @@
|
||||
adobereaderdc-update)
|
||||
name="Adobe Acrobat Reader DC"
|
||||
type="pkgInDmg"
|
||||
downloadURL=$(adobecurrent=`curl --fail --silent https://armmf.adobe.com/arm-manifests/mac/AcrobatDC/reader/current_version.txt | tr -d '.'` && echo http://ardownload.adobe.com/pub/adobe/reader/mac/AcrobatDC/"$adobecurrent"/AcroRdrDCUpd"$adobecurrent"_MUI.dmg)
|
||||
appNewVersion=$(curl -s https://armmf.adobe.com/arm-manifests/mac/AcrobatDC/reader/current_version.txt)
|
||||
#appNewVersion=$(curl -s -H "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15)" https://get.adobe.com/reader/ | grep ">Version" | sed -E 's/.*Version 20([0-9.]*)<.*/\1/g') # credit: Søren Theilgaard (@theilgaard)
|
||||
expectedTeamID="JQ525L2MZD"
|
||||
blockingProcesses=( "AdobeReader" )
|
||||
;;
|
||||
14
fragments/labels/adobereaderdc.txt
Normal file
14
fragments/labels/adobereaderdc.txt
Normal file
@@ -0,0 +1,14 @@
|
||||
adobereaderdc|\
|
||||
adobereaderdc-install)
|
||||
name="Adobe Acrobat Reader DC"
|
||||
type="pkgInDmg"
|
||||
packageID="com.adobe.acrobat.DC.reader.app.pkg.MUI"
|
||||
downloadURL=$(curl --silent --fail -H "Sec-Fetch-Site: same-origin" -H "Accept-Encoding: gzip, deflate, br" -H "Accept-Language: en-US;q=0.9,en;q=0.8" -H "DNT: 1" -H "Sec-Fetch-Mode: cors" -H "X-Requested-With: XMLHttpRequest" -H "Referer: https://get.adobe.com/reader/enterprise/" -H "Accept: */*" "https://get.adobe.com/reader/webservices/json/standalone/?platform_type=Macintosh&platform_dist=OSX&platform_arch=x86-32&language=English&eventname=readerotherversions" | grep -Eo '"download_url":.*?[^\]",' | head -n 1 | cut -d \" -f 4)
|
||||
appNewVersion=$(curl -s https://armmf.adobe.com/arm-manifests/mac/AcrobatDC/reader/current_version.txt)
|
||||
#appNewVersion=$(curl -s -H "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15)" https://get.adobe.com/reader/ | grep ">Version" | sed -E 's/.*Version 20([0-9.]*)<.*/\1/g') # credit: Søren Theilgaard (@theilgaard)
|
||||
expectedTeamID="JQ525L2MZD"
|
||||
blockingProcesses=( "AdobeReader" )
|
||||
#Company="Adobe"
|
||||
#PatchName="AcrobatReader"
|
||||
#PatchSkip="YES"
|
||||
;;
|
||||
7
fragments/labels/aircall.txt
Normal file
7
fragments/labels/aircall.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
aircall)
|
||||
# credit: @kris-anderson
|
||||
name="Aircall"
|
||||
type="dmg"
|
||||
downloadURL="https://electron.aircall.io/download/osx"
|
||||
expectedTeamID="3ML357Q795"
|
||||
;;
|
||||
9
fragments/labels/airserver.txt
Normal file
9
fragments/labels/airserver.txt
Normal file
@@ -0,0 +1,9 @@
|
||||
airserver)
|
||||
# credit: AP Orlebeke (@apizz)
|
||||
name="AirServer"
|
||||
type="dmg"
|
||||
downloadURL="https://www.airserver.com/download/mac/latest"
|
||||
#appNewVersion=$() # Cannot find version history or release notes on home page
|
||||
expectedTeamID="6C755KS5W3"
|
||||
#Company="App Dynamic ehf"
|
||||
;;
|
||||
10
fragments/labels/alfred.txt
Normal file
10
fragments/labels/alfred.txt
Normal file
@@ -0,0 +1,10 @@
|
||||
alfred)
|
||||
# credit: AP Orlebeke (@apizz)
|
||||
name="Alfred"
|
||||
type="dmg"
|
||||
downloadURL=$(curl -fs https://www.alfredapp.com | awk -F '"' "/dmg/ {print \$2}" | head -1)
|
||||
appNewVersion=$(echo "${downloadURL}" | sed -E 's/.*Alfred_([0-9.]*)_.*/\1/')
|
||||
appName="Alfred 4.app"
|
||||
expectedTeamID="XZZXE9SED4"
|
||||
#Company="Running with Crayons Ltd"
|
||||
;;
|
||||
9
fragments/labels/amazonchime.txt
Normal file
9
fragments/labels/amazonchime.txt
Normal file
@@ -0,0 +1,9 @@
|
||||
amazonchime)
|
||||
# credit: @dvsjr macadmins slack
|
||||
name="Amazon Chime"
|
||||
type="dmg"
|
||||
downloadURL="https://clients.chime.aws/mac/latest"
|
||||
appNewVersion=$( curl -fsIL "${downloadURL}" | grep -i "^location" | awk '{print $2}' | sed -E 's/.*\/[a-zA-Z.\-]*-([0-9.]*)\..*/\1/g' )
|
||||
expectedTeamID="94KV3E626L"
|
||||
#Company="Amazon"
|
||||
;;
|
||||
8
fragments/labels/amazonworkspaces.txt
Normal file
8
fragments/labels/amazonworkspaces.txt
Normal file
@@ -0,0 +1,8 @@
|
||||
amazonworkspaces)
|
||||
# credit: Isaac Ordonez, Mann consulting (@mannconsulting)
|
||||
name="Workspaces"
|
||||
type="pkg"
|
||||
downloadURL="https://d2td7dqidlhjx7.cloudfront.net/prod/global/osx/WorkSpaces.pkg"
|
||||
appNewVersion=$(curl -fs https://d2td7dqidlhjx7.cloudfront.net/prod/iad/osx/WorkSpacesAppCast_macOS_20171023.xml | grep -o "Version*.*<" | head -1 | cut -d " " -f2 | cut -d "<" -f1)
|
||||
expectedTeamID="94KV3E626L"
|
||||
;;
|
||||
7
fragments/labels/androidfiletransfer.txt
Normal file
7
fragments/labels/androidfiletransfer.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
androidfiletransfer)
|
||||
#credit: Sam Ess (saess-sep)
|
||||
name="Android File Transfer"
|
||||
type="dmg"
|
||||
downloadURL="https://dl.google.com/dl/androidjumper/mtp/current/AndroidFileTransfer.dmg"
|
||||
expectedTeamID="EQHXZ8M8AV"
|
||||
;;
|
||||
7
fragments/labels/apparency.txt
Normal file
7
fragments/labels/apparency.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
apparency)
|
||||
name="Apparency"
|
||||
type="dmg"
|
||||
downloadURL="https://www.mothersruin.com/software/downloads/Apparency.dmg"
|
||||
expectedTeamID="936EB786NH"
|
||||
#Company="Mother's Ruin Graphics"
|
||||
;;
|
||||
9
fragments/labels/appcleaner.txt
Normal file
9
fragments/labels/appcleaner.txt
Normal file
@@ -0,0 +1,9 @@
|
||||
appcleaner)
|
||||
# credit: Tadayuki Onishi (@kenchan0130)
|
||||
name="AppCleaner"
|
||||
type="zip"
|
||||
downloadURL=$(curl -fs https://freemacsoft.net/appcleaner/Updates.xml | xpath '//rss/channel/*/enclosure/@url' 2>/dev/null | tr " " "
|
||||
" | sort | tail -1 | cut -d '"' -f 2)
|
||||
expectedTeamID="X85ZX835W9"
|
||||
#Company=FreeMacSoft
|
||||
;;
|
||||
10
fragments/labels/aquaskk.txt
Normal file
10
fragments/labels/aquaskk.txt
Normal file
@@ -0,0 +1,10 @@
|
||||
aquaskk)
|
||||
# credit: Tadayuki Onishi (@kenchan0130)
|
||||
name="aquaskk"
|
||||
type="pkg"
|
||||
downloadURL=$(downloadURLFromGit codefirst aquaskk)
|
||||
appNewVersion=$(versionFromGit codefirst aquaskk)
|
||||
expectedTeamID="FPZK4WRGW7"
|
||||
#Company="Code First"
|
||||
#PatchSkip="YES"
|
||||
;;
|
||||
9
fragments/labels/atom.txt
Normal file
9
fragments/labels/atom.txt
Normal file
@@ -0,0 +1,9 @@
|
||||
atom)
|
||||
name="Atom"
|
||||
type="zip"
|
||||
archiveName="atom-mac.zip"
|
||||
downloadURL=$(downloadURLFromGit atom atom )
|
||||
appNewVersion=$(versionFromGit atom atom)
|
||||
expectedTeamID="VEKTX9H2N7"
|
||||
#Company=GitHub
|
||||
;;
|
||||
9
fragments/labels/autodmg.txt
Normal file
9
fragments/labels/autodmg.txt
Normal file
@@ -0,0 +1,9 @@
|
||||
autodmg)
|
||||
# credit: Mischa van der Bent (@mischavdbent)
|
||||
name="AutoDMG"
|
||||
type="dmg"
|
||||
downloadURL=$(downloadURLFromGit MagerValp AutoDMG)
|
||||
appNewVersion=$(versionFromGit MagerValp AutoDMG)
|
||||
expectedTeamID="5KQ3D3FG5H"
|
||||
#Company=MagerValp
|
||||
;;
|
||||
10
fragments/labels/autopkgr.txt
Normal file
10
fragments/labels/autopkgr.txt
Normal file
@@ -0,0 +1,10 @@
|
||||
autopkgr)
|
||||
# credit: Søren Theilgaard (@theilgaard)
|
||||
name="AutoPkgr"
|
||||
type="dmg"
|
||||
#downloadURL=$(curl -fs "https://api.github.com/repos/lindegroup/autopkgr/releases/latest" | awk -F '"' "/browser_download_url/ && /dmg/ && ! /sig/ && ! /CLI/ && ! /sha256/ { print \$4 }")
|
||||
downloadURL=$(downloadURLFromGit lindegroup autopkgr)
|
||||
appNewVersion=$(versionFromGit lindegroup autopkgr)
|
||||
expectedTeamID="JVY2ZR6SEF"
|
||||
#Company="Linde Group"
|
||||
;;
|
||||
8
fragments/labels/aviatrix.txt
Normal file
8
fragments/labels/aviatrix.txt
Normal file
@@ -0,0 +1,8 @@
|
||||
aviatrix)
|
||||
# credit: Isaac Ordonez, Mann consulting (@mannconsulting)
|
||||
name="Aviatrix VPN Client"
|
||||
type="pkg"
|
||||
downloadURL="https://s3-us-west-2.amazonaws.com/aviatrix-download/AviatrixVPNClient/AVPNC_mac.pkg"
|
||||
expectedTeamID="32953Z7NBN"
|
||||
#Company=Aviatrix
|
||||
;;
|
||||
9
fragments/labels/awscli2.txt
Normal file
9
fragments/labels/awscli2.txt
Normal file
@@ -0,0 +1,9 @@
|
||||
awscli2)
|
||||
# credit: Bilal Habib (@Pro4TLZZ)
|
||||
name="AWSCLI"
|
||||
type="pkg"
|
||||
packageID="com.amazon.aws.cli2"
|
||||
downloadURL="https://awscli.amazonaws.com/AWSCLIV2.pkg"
|
||||
appNewVersion=$( curl -fs "https://raw.githubusercontent.com/aws/aws-cli/v2/CHANGELOG.rst" | grep -i "CHANGELOG" -a4 | grep "[0-9.]" )
|
||||
expectedTeamID="94KV3E626L"
|
||||
;;
|
||||
9
fragments/labels/awsvpnclient.txt
Normal file
9
fragments/labels/awsvpnclient.txt
Normal file
@@ -0,0 +1,9 @@
|
||||
awsvpnclient)
|
||||
name="AWS VPN Client"
|
||||
type="pkg"
|
||||
downloadURL="https://d20adtppz83p9s.cloudfront.net/OSX/latest/AWS_VPN_Client.pkg"
|
||||
expectedTeamID="94KV3E626L"
|
||||
appNewVersion=$(curl -is "https://beta2.communitypatch.com/jamf/v1/ba1efae22ae74a9eb4e915c31fef5dd2/patch/AWSVPNClient" | grep currentVersion | tr ',' '
|
||||
' | grep currentVersion | cut -d '"' -f 4)
|
||||
#Company=Amazon
|
||||
;;
|
||||
9
fragments/labels/balenaetcher.txt
Normal file
9
fragments/labels/balenaetcher.txt
Normal file
@@ -0,0 +1,9 @@
|
||||
balenaetcher)
|
||||
# credit: Adrian Bühler (@midni9ht)
|
||||
name="balenaEtcher"
|
||||
type="dmg"
|
||||
downloadURL=$(downloadURLFromGit balena-io etcher )
|
||||
appNewVersion=$(versionFromGit balena-io etcher )
|
||||
expectedTeamID="66H43P8FRG"
|
||||
#Company="Balena"
|
||||
;;
|
||||
8
fragments/labels/basecamp3.txt
Normal file
8
fragments/labels/basecamp3.txt
Normal file
@@ -0,0 +1,8 @@
|
||||
basecamp3)
|
||||
#credit: @matins
|
||||
name="Basecamp 3"
|
||||
type="dmg"
|
||||
downloadURL="https://bc3-desktop.s3.amazonaws.com/mac/basecamp3.dmg"
|
||||
expectedTeamID="2WNYUYRS7G"
|
||||
appName="Basecamp 3.app"
|
||||
;;
|
||||
8
fragments/labels/bbedit.txt
Normal file
8
fragments/labels/bbedit.txt
Normal file
@@ -0,0 +1,8 @@
|
||||
bbedit)
|
||||
name="BBEdit"
|
||||
type="dmg"
|
||||
downloadURL=$(curl -s https://versioncheck.barebones.com/BBEdit.xml | grep dmg | sort | tail -n1 | cut -d">" -f2 | cut -d"<" -f1)
|
||||
appNewVersion=$(curl -s https://versioncheck.barebones.com/BBEdit.xml | grep dmg | sort | tail -n1 | sed -E 's/.*BBEdit_([0-9 .]*)\.dmg.*/\1/')
|
||||
expectedTeamID="W52GZAXT98"
|
||||
#Company="Bare Bones Software"
|
||||
;;
|
||||
8
fragments/labels/bettertouchtool.txt
Normal file
8
fragments/labels/bettertouchtool.txt
Normal file
@@ -0,0 +1,8 @@
|
||||
bettertouchtool)
|
||||
# credit: Søren Theilgaard (@theilgaard)
|
||||
name="BetterTouchTool"
|
||||
type="zip"
|
||||
downloadURL="https://folivora.ai/releases/BetterTouchTool.zip"
|
||||
appNewVersion=$(curl -fs https://updates.folivora.ai/bettertouchtool_release_notes.html | grep BetterTouchTool | head -n 2 | tail -n 1 | sed -E 's/.* ([0-9\.]*) .*/\1/g')
|
||||
expectedTeamID="DAFVSXZ82P"
|
||||
;;
|
||||
7
fragments/labels/bitwarden.txt
Normal file
7
fragments/labels/bitwarden.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
bitwarden)
|
||||
name="Bitwarden"
|
||||
type="dmg"
|
||||
downloadURL=$(downloadURLFromGit bitwarden desktop )
|
||||
appNewVersion=$(versionFromGit bitwarden desktop )
|
||||
expectedTeamID="LTZ2PFU5D6"
|
||||
;;
|
||||
7
fragments/labels/blender.txt
Normal file
7
fragments/labels/blender.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
blender)
|
||||
name="blender"
|
||||
type="dmg"
|
||||
downloadURL=$(redirect=$(curl -sfL https://www.blender.org/download/ | sed 's/.*href="//' | sed 's/".*//' | grep .dmg) && curl -sfL "$redirect" | sed 's/.*href="//' | sed 's/".*//' | grep .dmg)
|
||||
appNewVersion=$( echo "${downloadURL}" | sed -E 's/.*\/[a-zA-Z]*-([0-9.]*)-.*/\1/g' )
|
||||
expectedTeamID="68UA947AUU"
|
||||
;;
|
||||
8
fragments/labels/bluejeans.txt
Normal file
8
fragments/labels/bluejeans.txt
Normal file
@@ -0,0 +1,8 @@
|
||||
bluejeans)
|
||||
name="BlueJeans"
|
||||
type="pkg"
|
||||
downloadURL=$(curl -fs "https://www.bluejeans.com/downloads" | xmllint --html --format - 2>/dev/null | grep -o "https://.*BlueJeansInstaller.dmg" | sed 's/dmg/pkg/g')
|
||||
appNewVersion=$(echo $downloadURL | cut -d '/' -f6)
|
||||
expectedTeamID="HE4P42JBGN"
|
||||
#Company="Verizon"
|
||||
;;
|
||||
12
fragments/labels/boxdrive.txt
Normal file
12
fragments/labels/boxdrive.txt
Normal file
@@ -0,0 +1,12 @@
|
||||
boxdrive)
|
||||
# credit: Isaac Ordonez, Mann consulting (@mannconsulting)
|
||||
name="Box"
|
||||
type="pkg"
|
||||
if [[ $(arch) == "arm64" ]]; then
|
||||
#Note: https://support.box.com/hc/en-us/articles/1500004479962-Box-Drive-support-on-devices-with-M1-chips
|
||||
downloadURL="https://e3.boxcdn.net/desktop/pre-releases/mac/BoxDrive.2.20.140-M1-beta.pkg"
|
||||
elif [[ $(arch) == "i386" ]]; then
|
||||
downloadURL="https://e3.boxcdn.net/box-installers/desktop/releases/mac/Box.pkg"
|
||||
fi
|
||||
expectedTeamID="M683GB7CPW"
|
||||
;;
|
||||
17
fragments/labels/brave.txt
Normal file
17
fragments/labels/brave.txt
Normal file
@@ -0,0 +1,17 @@
|
||||
brave)
|
||||
# credit: @securitygeneration
|
||||
name="Brave Browser"
|
||||
type="dmg"
|
||||
if [[ $(arch) != "i386" ]]; then
|
||||
printlog "Architecture: arm64 (not i386)"
|
||||
downloadURL=$(curl -fsIL https://laptop-updates.brave.com/latest/osxarm64/release | grep -i "^location" | awk '{print $2}' | tr -d '
|
||||
')
|
||||
else
|
||||
printlog "Architecture: i386"
|
||||
downloadURL=$(curl -fsIL https://laptop-updates.brave.com/latest/osx/release | grep -i "^location" | awk '{print $2}' | tr -d '
|
||||
')
|
||||
fi
|
||||
# downloadURL=$(curl --location --fail --silent "https://updates.bravesoftware.com/sparkle/Brave-Browser/stable/appcast.xml" | xpath '//rss/channel/item[last()]/enclosure/@url' 2>/dev/null | cut -d '"' -f 2)
|
||||
appNewVersion=$(curl --location --fail --silent "https://updates.bravesoftware.com/sparkle/Brave-Browser/stable/appcast.xml" | xpath '//rss/channel/item[last()]/enclosure/@sparkle:shortVersionString' 2>/dev/null | cut -d '"' -f 2)
|
||||
expectedTeamID="KL8N8XSYF4"
|
||||
;;
|
||||
8
fragments/labels/cakebrew.txt
Normal file
8
fragments/labels/cakebrew.txt
Normal file
@@ -0,0 +1,8 @@
|
||||
cakebrew)
|
||||
# credit: Adrian Bühler (@midni9ht)
|
||||
name="Cakebrew"
|
||||
type="zip"
|
||||
downloadURL=$(curl -fsL "https://www.cakebrew.com/appcast/profileInfo.php" | xpath '//rss/channel/item[1]/enclosure/@url' 2>/dev/null | cut -d '"' -f 2)
|
||||
appNewVersion=$( curl -fsL "https://www.cakebrew.com/appcast/profileInfo.php" | xpath '//rss/channel/item[1]/enclosure/@sparkle:shortVersionString' 2>/dev/null | cut -d '"' -f 2 )
|
||||
expectedTeamID="R85D3K8ATT"
|
||||
;;
|
||||
8
fragments/labels/calibre.txt
Normal file
8
fragments/labels/calibre.txt
Normal file
@@ -0,0 +1,8 @@
|
||||
calibre)
|
||||
# credit: Drew Diver (@grumpydrew on MacAdmins Slack)
|
||||
name="calibre"
|
||||
type="dmg"
|
||||
downloadURL="https://calibre-ebook.com/dist/osx"
|
||||
appNewVersion=$( curl -fsIL "${downloadURL}" | grep -i "^location" | awk '{print $2}' | sed -E 's/.*\/[a-zA-Z]*-([0-9.]*)\..*/\1/g' )
|
||||
expectedTeamID="NTY7FVCEKP"
|
||||
;;
|
||||
8
fragments/labels/camostudio.txt
Normal file
8
fragments/labels/camostudio.txt
Normal file
@@ -0,0 +1,8 @@
|
||||
camostudio)
|
||||
# credit: Søren Theilgaard (@theilgaard)
|
||||
name="Camo Studio"
|
||||
type="zip"
|
||||
downloadURL="https://reincubate.com/res/labs/camo/camo-macos-latest.zip"
|
||||
#appNewVersion=$( ) # Can't find any versioniing on web server
|
||||
expectedTeamID="Q248YREB53"
|
||||
;;
|
||||
6
fragments/labels/camtasia.txt
Normal file
6
fragments/labels/camtasia.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
camtasia)
|
||||
name="Camtasia 2020"
|
||||
type="dmg"
|
||||
downloadURL=https://download.techsmith.com/camtasiamac/releases/Camtasia.dmg
|
||||
expectedTeamID="7TQL462TU8"
|
||||
;;
|
||||
8
fragments/labels/citrixworkspace.txt
Normal file
8
fragments/labels/citrixworkspace.txt
Normal file
@@ -0,0 +1,8 @@
|
||||
citrixworkspace)
|
||||
#credit: Erik Stam (@erikstam) and #Philipp on MacAdmins Slack
|
||||
name="Citrix Workspace"
|
||||
type="pkgInDmg"
|
||||
downloadURL="https:"$(curl -s -L "https://www.citrix.com/downloads/workspace-app/mac/workspace-app-for-mac-latest.html#ctx-dl-eula-external" | grep "dmg?" | sed "s/.*rel=.\(.*\)..id=.*/\1/") # http://downloads.citrix.com/18823/CitrixWorkspaceApp.dmg?__gda__=1605791892_edc6786a90eb5197fb226861a8e27aa8
|
||||
appNewVersion=$(curl -fs https://www.citrix.com/downloads/workspace-app/mac/workspace-app-for-mac-latest.html | grep "<p>Version" | head -1 | cut -d " " -f1 | cut -d ";" -f2 | cut -d "." -f 1-3)
|
||||
expectedTeamID="S272Y5R93J"
|
||||
;;
|
||||
9
fragments/labels/clevershare2.txt
Normal file
9
fragments/labels/clevershare2.txt
Normal file
@@ -0,0 +1,9 @@
|
||||
clevershare2)
|
||||
# credit: Søren Theilgaard (@theilgaard)
|
||||
name="Clevershare"
|
||||
type="dmg"
|
||||
downloadURL=$(curl -fs https://archive.clevertouch.com/clevershare2g | grep -i "_Mac" | tr '"' "
|
||||
" | grep "^http.*dmg")
|
||||
appNewVersion=$( echo "${downloadURL}" | sed -E 's/.*\/[a-zA-Z-]*_Mac\.([0-9.]*)\.[0-9]*\.dmg$/\1/g' )
|
||||
expectedTeamID="P76M9BE8DQ"
|
||||
;;
|
||||
8
fragments/labels/code42.txt
Normal file
8
fragments/labels/code42.txt
Normal file
@@ -0,0 +1,8 @@
|
||||
code42)
|
||||
# credit: Isaac Ordonez, Mann consulting (@mannconsulting)
|
||||
name="Code42"
|
||||
type="pkgInDmg"
|
||||
downloadURL=https://download.code42.com/installs/agent/latest-mac.dmg
|
||||
expectedTeamID="9YV9435DHD"
|
||||
blockingProcesses=( NONE )
|
||||
;;
|
||||
7
fragments/labels/coderunner.txt
Normal file
7
fragments/labels/coderunner.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
coderunner)
|
||||
# credit: Erik Stam (@erikstam)
|
||||
name="CodeRunner"
|
||||
type="zip"
|
||||
downloadURL="https://coderunnerapp.com/download"
|
||||
expectedTeamID="R4GD98AJF9"
|
||||
;;
|
||||
8
fragments/labels/cormorant.txt
Normal file
8
fragments/labels/cormorant.txt
Normal file
@@ -0,0 +1,8 @@
|
||||
cormorant)
|
||||
# credit: Søren Theilgaard (@theilgaard)
|
||||
name="Cormorant"
|
||||
type="zip"
|
||||
downloadURL=$(curl -fs https://eclecticlight.co/downloads/ | grep -i $name | grep zip | sed -E 's/.*href=\"(https.*)\">.*/\1/g')
|
||||
appNewVersion=$(curl -fs https://eclecticlight.co/downloads/ | grep zip | grep -o -E "$name [0-9.]*" | awk '{print $2}')
|
||||
expectedTeamID="QWY4LRW926"
|
||||
;;
|
||||
7
fragments/labels/cryptomator.txt
Normal file
7
fragments/labels/cryptomator.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
cryptomator)
|
||||
name="Cryptomator"
|
||||
type="dmg"
|
||||
downloadURL=$(downloadURLFromGit cryptomator cryptomator)
|
||||
appNewVersion=$(versionFromGit cryptomator cryptomator)
|
||||
expectedTeamID="YZQJQUHA3L"
|
||||
;;
|
||||
7
fragments/labels/cyberduck.txt
Normal file
7
fragments/labels/cyberduck.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
cyberduck)
|
||||
name="Cyberduck"
|
||||
type="zip"
|
||||
downloadURL=$(curl -fs https://version.cyberduck.io/changelog.rss | xpath '//rss/channel/item/enclosure/@url' 2>/dev/null | cut -d '"' -f 2 )
|
||||
appNewVersion=$(curl -fs https://version.cyberduck.io/changelog.rss | xpath '//rss/channel/item/enclosure/@sparkle:shortVersionString' 2>/dev/null | cut -d '"' -f 2 )
|
||||
expectedTeamID="G69SCX94XU"
|
||||
;;
|
||||
7
fragments/labels/dangerzone.txt
Normal file
7
fragments/labels/dangerzone.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
dangerzone)
|
||||
# credit: Micah Lee (@micahflee)
|
||||
name="Dangerzone"
|
||||
type="dmg"
|
||||
downloadURL=$(curl -s https://dangerzone.rocks/ | grep https://github.com/firstlookmedia/dangerzone/releases/download | grep \.dmg | cut -d'"' -f2)
|
||||
expectedTeamID="P24U45L8P5"
|
||||
;;
|
||||
8
fragments/labels/darktable.txt
Normal file
8
fragments/labels/darktable.txt
Normal file
@@ -0,0 +1,8 @@
|
||||
darktable)
|
||||
# credit: Søren Theilgaard (@theilgaard)
|
||||
name="darktable"
|
||||
type="dmg"
|
||||
downloadURL=$(downloadURLFromGit darktable-org darktable)
|
||||
appNewVersion=$(versionFromGit darktable-org darktable)
|
||||
expectedTeamID="85Q3K4KQRY"
|
||||
;;
|
||||
8
fragments/labels/dbeaverce.txt
Normal file
8
fragments/labels/dbeaverce.txt
Normal file
@@ -0,0 +1,8 @@
|
||||
dbeaverce)
|
||||
# credit: Adrian Bühler (@midni9ht)
|
||||
name="DBeaver"
|
||||
type="dmg"
|
||||
downloadURL="https://dbeaver.io/files/dbeaver-ce-latest-macos.dmg"
|
||||
expectedTeamID="42B6MDKMW8"
|
||||
blockingProcesses=( dbeaver )
|
||||
;;
|
||||
7
fragments/labels/debookee.txt
Normal file
7
fragments/labels/debookee.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
debookee)
|
||||
# credit: Adrian Bühler (@midni9ht)
|
||||
name="Debookee"
|
||||
type="zip"
|
||||
downloadURL=$(curl --location --fail --silent "https://www.iwaxx.com/debookee/appcast.xml" | xpath '//rss/channel/item[1]/enclosure/@url' 2>/dev/null | cut -d '"' -f 2)
|
||||
expectedTeamID="AATLWWB4MZ"
|
||||
;;
|
||||
7
fragments/labels/depnotify.txt
Normal file
7
fragments/labels/depnotify.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
depnotify)
|
||||
name="DEPNotify"
|
||||
type="zip"
|
||||
downloadURL="https://files.nomad.menu/DEPNotify.zip"
|
||||
expectedTeamID="VRPY9KHGX6"
|
||||
targetDir="/Applications/Utilities"
|
||||
;;
|
||||
9
fragments/labels/desktoppr.txt
Normal file
9
fragments/labels/desktoppr.txt
Normal file
@@ -0,0 +1,9 @@
|
||||
desktoppr)
|
||||
name="desktoppr"
|
||||
type="pkg"
|
||||
packageID="com.scriptingosx.desktoppr"
|
||||
downloadURL=$(downloadURLFromGit "scriptingosx" "desktoppr")
|
||||
appNewVersion=$(versionFromGit "scriptingosx" "desktoppr")
|
||||
expectedTeamID="JME5BW3F3R"
|
||||
blockingProcesses=( NONE )
|
||||
;;
|
||||
8
fragments/labels/detectxswift.txt
Normal file
8
fragments/labels/detectxswift.txt
Normal file
@@ -0,0 +1,8 @@
|
||||
detectxswift)
|
||||
# credit: AP Orlebeke (@apizz)
|
||||
name="DetectX Swift"
|
||||
type="zip"
|
||||
downloadURL="https://s3.amazonaws.com/sqwarq.com/PublicZips/DetectX_Swift.app.zip"
|
||||
appNewVersion=$(curl -fs https://s3.amazonaws.com/sqwarq.com/AppCasts/dtxswift_release_notes.html | grep Version | head -1 | sed -E 's/.*Version ([0-9.]*)\<.*/\1/')
|
||||
expectedTeamID="MAJ5XBJSG3"
|
||||
;;
|
||||
12
fragments/labels/devonthink.txt
Normal file
12
fragments/labels/devonthink.txt
Normal file
@@ -0,0 +1,12 @@
|
||||
devonthink)
|
||||
# It's a zipped dmg file, needs function installAppInDmgInZip
|
||||
# credit: Søren Theilgaard (@theilgaard)
|
||||
name="DEVONthink 3"
|
||||
type="appInDmgInZip"
|
||||
downloadURL=$( curl -fs https://www.devontechnologies.com/apps/devonthink | grep -i "download.devon" | tr '"' '
|
||||
' | tr "'" '
|
||||
' | grep -e '^https://' )
|
||||
appNewVersion=$( echo ${downloadURL} | tr '/' '
|
||||
' | grep "[0-9]" | grep "[.]" | head -1 )
|
||||
expectedTeamID="679S2QUWR8"
|
||||
;;
|
||||
7
fragments/labels/dialpad.txt
Normal file
7
fragments/labels/dialpad.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
dialpad)
|
||||
# credit: @ehosaka
|
||||
name="Dialpad"
|
||||
type="dmg"
|
||||
downloadURL="https://storage.googleapis.com/dialpad_native/osx/Dialpad.dmg"
|
||||
expectedTeamID="9V29MQSZ9M"
|
||||
;;
|
||||
6
fragments/labels/discord.txt
Normal file
6
fragments/labels/discord.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
discord)
|
||||
name="Discord"
|
||||
type="dmg"
|
||||
downloadURL="https://discordapp.com/api/download?platform=osx"
|
||||
expectedTeamID="53Q6R32WPB"
|
||||
;;
|
||||
13
fragments/labels/docker.txt
Normal file
13
fragments/labels/docker.txt
Normal file
@@ -0,0 +1,13 @@
|
||||
docker)
|
||||
# credit: @securitygeneration
|
||||
name="Docker"
|
||||
type="dmg"
|
||||
#downloadURL="https://download.docker.com/mac/stable/Docker.dmg"
|
||||
if [[ $(arch) == arm64 ]]; then
|
||||
downloadURL="https://desktop.docker.com/mac/stable/arm64/Docker.dmg"
|
||||
elif [[ $(arch) == i386 ]]; then
|
||||
downloadURL="https://desktop.docker.com/mac/stable/amd64/Docker.dmg"
|
||||
fi
|
||||
appNewVersion=$(curl -ifs https://docs.docker.com/docker-for-mac/release-notes/ | grep ">Docker Desktop Community" | head -1 | sed -n -e 's/^.*Community //p' | cut -d '<' -f1)
|
||||
expectedTeamID="9BNSXJN65R"
|
||||
;;
|
||||
6
fragments/labels/dropbox.txt
Normal file
6
fragments/labels/dropbox.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
dropbox)
|
||||
name="Dropbox"
|
||||
type="dmg"
|
||||
downloadURL="https://www.dropbox.com/download?plat=mac&full=1"
|
||||
expectedTeamID="G7HH3F8CAK"
|
||||
;;
|
||||
9
fragments/labels/easeusdatarecoverywizard.txt
Normal file
9
fragments/labels/easeusdatarecoverywizard.txt
Normal file
@@ -0,0 +1,9 @@
|
||||
easeusdatarecoverywizard)
|
||||
# credit: Søren Theilgaard (@theilgaard)
|
||||
name="EaseUS Data Recovery Wizard"
|
||||
type="dmg"
|
||||
downloadURL=$( curl -fsIL https://down.easeus.com/product/mac_drw_free_setup | grep -i "^location" | awk '{print $2}' | tr -d '
|
||||
' )
|
||||
#appNewVersion=""
|
||||
expectedTeamID="DLLVW95FSM"
|
||||
;;
|
||||
8
fragments/labels/egnyte.txt
Normal file
8
fragments/labels/egnyte.txt
Normal file
@@ -0,0 +1,8 @@
|
||||
egnyte)
|
||||
# credit: #MoeMunyoki from MacAdmins Slack
|
||||
name="Egnyte Connect"
|
||||
type="pkg"
|
||||
downloadURL="https://egnyte-cdn.egnyte.com/egnytedrive/mac/en-us/latest/EgnyteConnectMac.pkg"
|
||||
expectedTeamID="FELUD555VC"
|
||||
blockingProcesses=( NONE )
|
||||
;;
|
||||
7
fragments/labels/element.txt
Normal file
7
fragments/labels/element.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
element)
|
||||
# credit: Adrian Bühler (@midni9ht)
|
||||
name="Element"
|
||||
type="dmg"
|
||||
downloadURL="https://packages.riot.im/desktop/install/macos/Element.dmg"
|
||||
expectedTeamID="7J4U792NQT"
|
||||
;;
|
||||
6
fragments/labels/eraseinstall.txt
Normal file
6
fragments/labels/eraseinstall.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
eraseinstall)
|
||||
name="EraseInstall"
|
||||
type="pkg"
|
||||
downloadURL=https://bitbucket.org$(curl -fs https://bitbucket.org/prowarehouse-nl/erase-install/downloads/ | grep pkg | cut -d'"' -f2 | head -n 1)
|
||||
expectedTeamID="R55HK5K86Y"
|
||||
;;
|
||||
7
fragments/labels/etrecheck.txt
Normal file
7
fragments/labels/etrecheck.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
etrecheck)
|
||||
# credit: @dvsjr macadmins slack
|
||||
name="EtreCheckPro"
|
||||
type="zip"
|
||||
downloadURL="https://cdn.etrecheck.com/EtreCheckPro.zip"
|
||||
expectedTeamID="U87NE528LC"
|
||||
;;
|
||||
8
fragments/labels/exelbanstats.txt
Normal file
8
fragments/labels/exelbanstats.txt
Normal file
@@ -0,0 +1,8 @@
|
||||
exelbanstats)
|
||||
# credit: Søren Theilgaard (@theilgaard)
|
||||
name="Stats"
|
||||
type="dmg"
|
||||
downloadURL=$(downloadURLFromGit exelban stats)
|
||||
appNewVersion=$(versionFromGit exelban stats)
|
||||
expectedTeamID="RP2S87B72W"
|
||||
;;
|
||||
8
fragments/labels/fantastical.txt
Normal file
8
fragments/labels/fantastical.txt
Normal file
@@ -0,0 +1,8 @@
|
||||
fantastical)
|
||||
# credit: Drew Diver (@grumpydrew on MacAdmins Slack)
|
||||
name="Fantastical"
|
||||
type="zip"
|
||||
downloadURL="https://flexibits.com/fantastical/download"
|
||||
appNewVersion=$( curl -fsIL "${downloadURL}" | grep -i "^location" | awk '{print $2}' | sed -E 's/.*\/[a-zA-Z]*_([0-9.]*)\..*/\1/g' )
|
||||
expectedTeamID="85C27NK92C"
|
||||
;;
|
||||
8
fragments/labels/ferdi.txt
Normal file
8
fragments/labels/ferdi.txt
Normal file
@@ -0,0 +1,8 @@
|
||||
ferdi)
|
||||
# credit: Adrian Bühler (@midni9ht)
|
||||
name="Ferdi"
|
||||
type="dmg"
|
||||
downloadURL=$(downloadURLFromGit getferdi ferdi )
|
||||
appNewVersion=$(versionFromGit getferdi ferdi )
|
||||
expectedTeamID="B6J9X9DWFL"
|
||||
;;
|
||||
7
fragments/labels/figma.txt
Normal file
7
fragments/labels/figma.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
figma)
|
||||
name="Figma"
|
||||
type="zip"
|
||||
downloadURL="https://www.figma.com/download/desktop/mac/"
|
||||
expectedTeamID="T8RA8NE3B7"
|
||||
#Company="Figma"
|
||||
;;
|
||||
8
fragments/labels/firefox.txt
Normal file
8
fragments/labels/firefox.txt
Normal file
@@ -0,0 +1,8 @@
|
||||
firefox)
|
||||
name="Firefox"
|
||||
type="dmg"
|
||||
downloadURL="https://download.mozilla.org/?product=firefox-latest&os=osx&lang=en-US"
|
||||
appNewVersion=$(/usr/bin/curl https://www.mozilla.org/en-US/firefox/releases/ --silent | /usr/bin/grep '<html' | /usr/bin/awk -F\" '{ print $8 }') # Credit: William Smith (@meck)
|
||||
expectedTeamID="43AQ936H96"
|
||||
blockingProcesses=( firefox )
|
||||
;;
|
||||
8
fragments/labels/firefox_da.txt
Normal file
8
fragments/labels/firefox_da.txt
Normal file
@@ -0,0 +1,8 @@
|
||||
firefox_da)
|
||||
name="Firefox"
|
||||
type="dmg"
|
||||
downloadURL="https://download.mozilla.org/?product=firefox-latest&os=osx&lang=da"
|
||||
appNewVersion=$(/usr/bin/curl https://www.mozilla.org/en-US/firefox/releases/ --silent | /usr/bin/grep '<html' | /usr/bin/awk -F\" '{ print $8 }') # Credit: William Smith (@meck)
|
||||
expectedTeamID="43AQ936H96"
|
||||
blockingProcesses=( firefox )
|
||||
;;
|
||||
8
fragments/labels/firefoxesr.txt
Normal file
8
fragments/labels/firefoxesr.txt
Normal file
@@ -0,0 +1,8 @@
|
||||
firefoxesr|\
|
||||
firefoxesrpkg)
|
||||
name="Firefox"
|
||||
type="pkg"
|
||||
downloadURL="https://download.mozilla.org/?product=firefox-esr-pkg-latest-ssl&os=osx"
|
||||
expectedTeamID="43AQ936H96"
|
||||
blockingProcesses=( firefox )
|
||||
;;
|
||||
7
fragments/labels/firefoxpkg.txt
Normal file
7
fragments/labels/firefoxpkg.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
firefoxpkg)
|
||||
name="Firefox"
|
||||
type="pkg"
|
||||
downloadURL="https://download.mozilla.org/?product=firefox-pkg-latest-ssl&os=osx&lang=en-US"
|
||||
expectedTeamID="43AQ936H96"
|
||||
blockingProcesses=( firefox )
|
||||
;;
|
||||
7
fragments/labels/front.txt
Normal file
7
fragments/labels/front.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
front)
|
||||
name="Front"
|
||||
type="dmg"
|
||||
downloadURL="https://dl.frontapp.com/macos/Front.dmg"
|
||||
expectedTeamID="X549L7572J"
|
||||
Company="FrontApp. Inc."
|
||||
;;
|
||||
7
fragments/labels/fsmonitor.txt
Normal file
7
fragments/labels/fsmonitor.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
fsmonitor)
|
||||
# credit: Adrian Bühler (@midni9ht)
|
||||
name="FSMonitor"
|
||||
type="zip"
|
||||
downloadURL=$(curl --location --fail --silent "https://fsmonitor.com/FSMonitor/Archives/appcast2.xml" | xpath '//rss/channel/item[last()]/enclosure/@url' 2>/dev/null | cut -d '"' -f 2)
|
||||
expectedTeamID="V85GBYB7B9"
|
||||
;;
|
||||
8
fragments/labels/gimp.txt
Normal file
8
fragments/labels/gimp.txt
Normal file
@@ -0,0 +1,8 @@
|
||||
gimp)
|
||||
name="GIMP-2.10"
|
||||
type="dmg"
|
||||
downloadURL=https://$(curl -fs https://www.gimp.org/downloads/ | grep -m 1 -o "download.*gimp-.*.dmg")
|
||||
appNewVersion=$(echo $downloadURL | cut -d "-" -f 2)
|
||||
expectedTeamID="T25BQ8HSJF"
|
||||
#Company="GIMP"
|
||||
;;
|
||||
7
fragments/labels/githubdesktop.txt
Normal file
7
fragments/labels/githubdesktop.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
githubdesktop)
|
||||
name="GitHub Desktop"
|
||||
type="zip"
|
||||
downloadURL="https://central.github.com/deployments/desktop/desktop/latest/darwin"
|
||||
appNewVersion=$(curl -fsL https://central.github.com/deployments/desktop/desktop/changelog.json | awk -F '{' '/"version"/ { print $2 }' | sed -E 's/.*,\"version\":\"([0-9.]*)\".*/\1/g')
|
||||
expectedTeamID="VEKTX9H2N7"
|
||||
;;
|
||||
12
fragments/labels/golang.txt
Normal file
12
fragments/labels/golang.txt
Normal file
@@ -0,0 +1,12 @@
|
||||
golang)
|
||||
# credit: Søren Theilgaard (@theilgaard)
|
||||
name="GoLang"
|
||||
type="pkg"
|
||||
packageID="org.golang.go"
|
||||
downloadURL="$(curl -fsIL "https://golang.org$(curl -fs "https://golang.org/dl/" | grep -i "downloadBox" | grep "pkg" | tr '"' '
|
||||
' | grep "pkg")" | grep -i "^location" | awk '{print $2}' | tr -d '
|
||||
')"
|
||||
appNewVersion="$( echo "${downloadURL}" | sed -E 's/.*\/(go[0-9.]*)\..*/\1/g' )" # Version includes letters "go"
|
||||
expectedTeamID="EQHXZ8M8AV"
|
||||
blockingProcesses=( NONE )
|
||||
;;
|
||||
14
fragments/labels/googlechrome.txt
Normal file
14
fragments/labels/googlechrome.txt
Normal file
@@ -0,0 +1,14 @@
|
||||
googlechrome)
|
||||
name="Google Chrome"
|
||||
type="dmg"
|
||||
if [[ $(arch) != "i386" ]]; then
|
||||
printlog "Architecture: arm64 (not i386)"
|
||||
downloadURL="https://dl.google.com/chrome/mac/universal/stable/GGRO/googlechrome.dmg"
|
||||
appNewVersion=$(curl -s https://omahaproxy.appspot.com/history | awk -F',' '/mac_arm64,stable/{print $3; exit}') # Credit: William Smith (@meck)
|
||||
else
|
||||
printlog "Architecture: i386"
|
||||
downloadURL="https://dl.google.com/chrome/mac/stable/GGRO/googlechrome.dmg"
|
||||
appNewVersion=$(curl -s https://omahaproxy.appspot.com/history | awk -F',' '/mac,stable/{print $3; exit}') # Credit: William Smith (@meck)
|
||||
fi
|
||||
expectedTeamID="EQHXZ8M8AV"
|
||||
;;
|
||||
13
fragments/labels/googlechromepkg.txt
Normal file
13
fragments/labels/googlechromepkg.txt
Normal file
@@ -0,0 +1,13 @@
|
||||
googlechromepkg)
|
||||
name="Google Chrome"
|
||||
type="pkg"
|
||||
#
|
||||
# Note: this url acknowledges that you accept the terms of service
|
||||
# https://support.google.com/chrome/a/answer/9915669
|
||||
#
|
||||
downloadURL="https://dl.google.com/chrome/mac/stable/accept_tos%3Dhttps%253A%252F%252Fwww.google.com%252Fintl%252Fen_ph%252Fchrome%252Fterms%252F%26_and_accept_tos%3Dhttps%253A%252F%252Fpolicies.google.com%252Fterms/googlechrome.pkg"
|
||||
expectedTeamID="EQHXZ8M8AV"
|
||||
updateTool="/Library/Google/GoogleSoftwareUpdate/GoogleSoftwareUpdate.bundle/Contents/Resources/GoogleSoftwareUpdateAgent.app/Contents/MacOS/GoogleSoftwareUpdateAgent"
|
||||
updateToolArguments=( -runMode oneshot -userInitiated YES )
|
||||
updateToolRunAsCurrentUser=1
|
||||
;;
|
||||
10
fragments/labels/googledrive.txt
Normal file
10
fragments/labels/googledrive.txt
Normal file
@@ -0,0 +1,10 @@
|
||||
googledrive|\
|
||||
googledrivefilestream)
|
||||
# credit: Isaac Ordonez, Mann consulting (@mannconsulting)
|
||||
name="Google Drive File Stream"
|
||||
type="pkgInDmg"
|
||||
packageID="com.google.drivefs"
|
||||
downloadURL="https://dl.google.com/drive-file-stream/GoogleDriveFileStream.dmg" # downloadURL="https://dl.google.com/drive-file-stream/GoogleDrive.dmg"
|
||||
blockingProcesses=( "Google Docs" "Google Drive" "Google Sheets" "Google Slides" )
|
||||
expectedTeamID="EQHXZ8M8AV"
|
||||
;;
|
||||
8
fragments/labels/googledrivebackupandsync.txt
Normal file
8
fragments/labels/googledrivebackupandsync.txt
Normal file
@@ -0,0 +1,8 @@
|
||||
googledrivebackupandsync)
|
||||
name="Backup and Sync"
|
||||
type="dmg"
|
||||
downloadURL="https://dl.google.com/drive/InstallBackupAndSync.dmg"
|
||||
expectedTeamID="EQHXZ8M8AV"
|
||||
#Company="Google"
|
||||
#PatchSkip="YES"
|
||||
;;
|
||||
7
fragments/labels/googleearth.txt
Normal file
7
fragments/labels/googleearth.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
googleearth)
|
||||
name="Google Earth Pro"
|
||||
type="pkgInDmg"
|
||||
downloadURL="https://dl.google.com/earth/client/advanced/current/GoogleEarthProMac-Intel.dmg"
|
||||
expectedTeamID="EQHXZ8M8AV"
|
||||
#Company="Google"
|
||||
;;
|
||||
8
fragments/labels/googlejapaneseinput.txt
Normal file
8
fragments/labels/googlejapaneseinput.txt
Normal file
@@ -0,0 +1,8 @@
|
||||
googlejapaneseinput)
|
||||
# credit: Tadayuki Onishi (@kenchan0130)
|
||||
name="GoogleJapaneseInput"
|
||||
type="pkgInDmg"
|
||||
pkgName="GoogleJapaneseInput.pkg"
|
||||
downloadURL="https://dl.google.com/japanese-ime/latest/GoogleJapaneseInput.dmg"
|
||||
expectedTeamID="EQHXZ8M8AV"
|
||||
;;
|
||||
7
fragments/labels/gotomeeting.txt
Normal file
7
fragments/labels/gotomeeting.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
gotomeeting)
|
||||
# credit: @matins
|
||||
name="GoToMeeting"
|
||||
type="dmg"
|
||||
downloadURL="https://link.gotomeeting.com/latest-dmg"
|
||||
expectedTeamID="GFNFVT632V"
|
||||
;;
|
||||
8
fragments/labels/gpgsuite.txt
Normal file
8
fragments/labels/gpgsuite.txt
Normal file
@@ -0,0 +1,8 @@
|
||||
gpgsuite)
|
||||
# credit: Micah Lee (@micahflee)
|
||||
name="GPG Suite"
|
||||
type="pkgInDmg"
|
||||
pkgName="Install.pkg"
|
||||
downloadURL=$(curl -s https://gpgtools.org/ | grep https://releases.gpgtools.org/GPG_Suite- | grep Download | cut -d'"' -f4)
|
||||
expectedTeamID="PKV8ZPD836"
|
||||
;;
|
||||
7
fragments/labels/gpgsync.txt
Normal file
7
fragments/labels/gpgsync.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
gpgsync)
|
||||
# credit: Micah Lee (@micahflee)
|
||||
name="GPG Sync"
|
||||
type="pkg"
|
||||
downloadURL="https://github.com$(curl -s -L https://github.com/firstlookmedia/gpgsync/releases/latest | grep /firstlookmedia/gpgsync/releases/download | grep \.pkg | cut -d'"' -f2)"
|
||||
expectedTeamID="P24U45L8P5"
|
||||
;;
|
||||
6
fragments/labels/grandperspective.txt
Normal file
6
fragments/labels/grandperspective.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
grandperspective)
|
||||
name="GrandPerspective"
|
||||
type="dmg"
|
||||
downloadURL="https://sourceforge.net/projects/grandperspectiv/files/latest/download"
|
||||
expectedTeamID="3Z75QZGN66"
|
||||
;;
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user