mirror of
git://git.code.sf.net/p/zsh/code
synced 2025-06-16 20:58:05 +02:00
51897: update _softwareupdate
based on 51895 (Shohei YOSHIDA)
This commit is contained in:
parent
5ead24c881
commit
c4ec7442f1
2 changed files with 98 additions and 58 deletions
|
@ -1,3 +1,8 @@
|
|||
2023-07-10 Jun-ichi Takimoto <takimoto-j@kba.biglobe.ne.jp>
|
||||
|
||||
* 51897 (+ minor tweaks): Completion/Darwin/Command/_softwareupdate:
|
||||
update _softwareupdate (based on 51895 by Shohei YOSHIDA)
|
||||
|
||||
2023-07-09 Bart Schaefer <schaefer@zsh.org>
|
||||
|
||||
* 51890: Src/builtin.c: fix "whence -wa" for multiple arguments
|
||||
|
|
|
@ -1,75 +1,110 @@
|
|||
#compdef softwareupdate
|
||||
|
||||
_softwareupdate_ignored_update_name() {
|
||||
if [[ -z "$_softwareupdate_ignored_updates" ]]; then
|
||||
local res="$(_call_program pkgs softwareupdate --ignored)"
|
||||
_softwareupdate_ignored_updates=("${(Qs/, /)${${res#Current ignored updates: \(}%\)}}")
|
||||
fi
|
||||
if (( ${#_softwareupdate_ignored_updates} > 0 )); then
|
||||
_wanted pkgs expl "ignored package" compadd -a _softwareupdate_ignored_updates && return 0
|
||||
fi
|
||||
return 1
|
||||
# rebuild cache for available updates everyday (ad hoc)
|
||||
_softwareupdate_caching_policy() {
|
||||
local -a newer=( "$1"(Nmd-1) )
|
||||
return $#newer
|
||||
}
|
||||
|
||||
_softwareupdate_update_name() {
|
||||
local name line
|
||||
if [[ -z "$_softwareupdate_updates" ]]; then
|
||||
# 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 pkgs softwareupdate --list)"}; do
|
||||
if [[ $line == ' '* ]]; then
|
||||
name="${line# ? }"
|
||||
elif [[ -n "$name" ]]; then
|
||||
_softwareupdate_updates+=("$name:${line# }")
|
||||
name=""
|
||||
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
|
||||
if (( ${#_softwareupdate_updates} > 0 )); then
|
||||
_describe -t pkgs "update name" _softwareupdate_updates && return 0
|
||||
fi
|
||||
return 1
|
||||
# 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 context state line expl
|
||||
typeset -A opt_args
|
||||
local -a specs
|
||||
|
||||
_arguments -R \
|
||||
'(-h --help -l --list)-q[quiet mode]' \
|
||||
{-l,--list}'[list all available updates]:*:' \
|
||||
{-d,--download}'[download to directory set in InternetConfig]:*:' \
|
||||
{-i,--install}'[install (requires root)]:*: :->install' \
|
||||
'--ignored[show or manage ignored updates list (per-user)]:*:: :->ignored' \
|
||||
'--schedule[scheduler preferences (per-user)]:automatic checking:(on off)' \
|
||||
{-h,--help}'[print command usage]:*:' && return 0
|
||||
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]:*:'
|
||||
|
||||
case "$state" in
|
||||
install)
|
||||
_arguments \
|
||||
'(* -a --all)'{-a,--all}'[all available active updates]' \
|
||||
'(* -r --req)'{-r,--req}'[all required active updates]' \
|
||||
'*:update name:_softwareupdate_update_name' && return 0
|
||||
;;
|
||||
ignored)
|
||||
local -a ignored_subcmd
|
||||
ignored_subcmd=(add remove)
|
||||
+ '(operation)'
|
||||
|
||||
if (( CURRENT == 1 )); then
|
||||
_describe -t commands "subcommand" ignored_subcmd && return 0
|
||||
fi
|
||||
case $words[1] in
|
||||
add)
|
||||
_softwareupdate_update_name && return 0
|
||||
;;
|
||||
remove)
|
||||
_arguments \
|
||||
'(* -a --all)'{-a,--all}'[all available active updates]' \
|
||||
'*:update name:_softwareupdate_ignored_update_name' && return 0
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
return 1
|
||||
{-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 "$@"
|
||||
|
|
Loading…
Reference in a new issue