blob: 9ac9b9cd2fa9eaba038e85b27375231e80d728ae (
plain) (
blame)
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
|
#compdef softwareupdate
# rebuild cache for available updates everyday (ad hoc)
_softwareupdate_caching_policy() {
local -a newer=( "$1"(Nmd-1) )
return $#newer
}
# completes available updates (with description)
_softwareupdate_update_names () {
local name line update_policy ret=1
local cache_id=softwareupdate-updates
zstyle -s ":completion:${curcontext}:" cache-policy update_policy
if [[ -z "$update_policy" ]]; then
zstyle ":completion:${curcontext}:" cache-policy \
_softwareupdate_caching_policy
fi
if { [[ ! -v _softwareupdate_updates ]] || _cache_invalid $cache_id } &&
! _retrieve_cache $cache_id; then
# Output format of 'softwareupdate --list' seems to be not stable,
# but at least on macOS 12 and 13 it contains the following two lines
# for each update:
#* Label: update name (may contain spaces)
# Title: description of the update (single TAB before Title:)
# softwareupdate(1) manpage says the '*' before the Label: is replaced
# by '-' for non-recommended updates (but I've never seen it).
_softwareupdate_updates=()
for line in ${(f)"$(_call_program updates softwareupdate --list)"}; do
if [[ $line = [-\*]\ Label:\ (#b)(*) ]]; then
# add '*' or '-' in front of the name; this will be removed later
name=$line[1]$match[1]
elif [[ -n $name && $line = $'\t'Title:\ (#b)(*) ]]; then
_softwareupdate_updates+=( $name:$match[1] )
name=
fi
done
_store_cache $cache_id _softwareupdate_updates
fi
# recommended and non-recommended updates
local rec=( ${${_softwareupdate_updates:#-*}#\*} )
local non=( ${${(M)_softwareupdate_updates:#-*}#-} )
_describe -t updates "update" rec && ret=0
_describe -t non-recommended-updates "non-recommended update" non && ret=0
return ret
}
# completes versions of available macOS full installer (with description)
_softwareupdate_installer_versions () {
local versions=()
for line in ${(f)"$(_call_program installer-versions
softwareupdate --list-full-installers 2>/dev/null)"}; do
if [[ $line = \*\ Title:\ *\ Version:\ (#b)([0-9.]##)* ]]; then
versions+=( ${match[1]}:${line#*Title: } )
fi
done
_describe -t insteller-versions "version" versions
}
# main completion script
_softwareupdate() {
local -a specs
if (( ${words[(I)(-i|--install)]} == 0 )); then
specs=(
'--no-scan[do not scan when listing or installing updates]'
'--product-types[limit a scan to a particular product type only]:list of product types'
'--products[a comma separated list of product keys to operate on]:list of product keys'
'--force[force an operation to complete]'
'--agree-to-license[agree to the software license agreement without user interaction]'
'--verbose[enable verbose output]'
'(* -)'{-h,--help}'[print command usage]:*:'
+ '(operation)'
{-l,--list}'[list all available updates]'
{-d,--download}'[download but not install specified updates]:*: : _softwareupdate_update_names'
{-i,--install}'[download and install specified updates]'
'(* -)--list-full-installers[list the available macOS installers]'
'(* -)--fetch-full-installer[install the latest recommended macOS installer]: :(--full-installer-version): : _softwareupdate_installer_versions'
'--install-rosetta[install Rosetta 2 (Apple Silicon only)]'
'(* -)--schedule[returns the per-machine automatic check preference]'
'--background[trigger a background scan and update operation]'
'(* -)--dump-state[log the internal state of the SU daemon to /var/log/install.log]'
'--evaluate-products[evaluate a list of product keys specified by the --products option]'
'--history[show the install history]'
)
else # if -i/--install is already on the command line
specs=(
!{-i,--install}
'(-R --restart)'{-R,--restart}'[automatically restart if required to complete installation]'
'--stdinpass[password to authenticate as an owner (Apple Silicon only)]'
'--user[local username to authenticate as an owner (Apple Silicon only)]'
'*: : _softwareupdate_update_names'
+ '(select-updates)'
'(*)'{-a,--all}'[all updates that are applicable to your system]'
'(*)'{-r,--recommended}'[all updates recommended for your system]'
'(*)--os-only[only macOS updates]'
'(*)--safari-only[only Safari updates]'
)
fi
_arguments -s : $specs
}
_softwareupdate "$@"
|