Effettuare un brew upgrade completo
(pubblicato il 25 marzo 2021) Photo by olia danilevich on Pexels.com
Sul Mac trovo comodo usare brew . Permette di gestire tante applicazioni con un gestore di pacchetti.
- Nota positiva: in generale, funziona bene, per quello che lo conosco.
- Nota negativa: in contraddizione col punto precedente, l’upgrade dei cask mi pare faccia cilecca [1]
In passato, eseguivo l’update / upgrade delle formule e l’upgrade dei cask.
Col tempo, la gestione dei cask è diventata più omogenea con quella delle formule ma l’update / upgrade mi rimane ancora un po’ misterioso.
Eseguendo un brew update && brew upgrade
, soprattutto dalle ultime versioni (dalla 3.0.7 in poi di sicuro), l’update sembra fare il suo lavoro e trova un po’ di cask aggiornare.
Càpita però che l’upgrade ne aggiorni qualcuno, un brew upgrade --cask
ne aggiorni qualcun altro (senza raggiungere il totale iniziale) e provando a rifare l’update subito dopo (e anche l’upgrade) il sistema rimane intatto come se fosse up-to-date.
Agendo puntualmente sul cask invece, l’aggiornamento parte eccome. Come se fossero rimaste in cache delle informazioni discordanti sullo stato reale dell’applicazione e su quello potenziale.
Ho cercato un po’ in rete, sembra un problema comune.
Al solito, è partito lo script.
#!/usr/bin/bash
echo -e '\E[37;44m'"\033[1m***************\033[0m"
echo -e '\E[37;44m'"\033[1m* brew update *\033[0m"
echo -e '\E[37;44m'"\033[1m***************\033[0m"
brew update
echo -e "\n"
echo -e '\E[37;44m'"\033[1m****************\033[0m"
echo -e '\E[37;44m'"\033[1m* brew upgrade *\033[0m"
echo -e '\E[37;44m'"\033[1m****************\033[0m"
if [[ -z $(brew upgrade) ]]; then
echo -e "Nothing."
fi
echo -e "\n"
echo -e '\E[37;44m'"\033[1m***********************\033[0m"
echo -e '\E[37;44m'"\033[1m* brew upgrade --cask *\033[0m"
echo -e '\E[37;44m'"\033[1m***********************\033[0m"
for c in $(brew list --cask -1); do
printf %-30s "$c"
info=$(brew info --cask "$c")
current_ver=$(head -n1 <<< "$info" | cut -d " " -f 2)
installed_ver=$(head -n3 <<< "$info" | tail -n1 | cut -d"/" -f 6 | cut -d " " -f 1)
if [ "$installed_ver" != "$current_ver" ]; then
answer=""
while [[ -z $answer ]]; do
read -r -p "$c installed version is '$installed_ver', but the current version is '$current_ver'. Do you want to upgrade $c? ["$'\e[;32;1mYES\e[0m/no] ' answer
case ${answer,,} in
yes|"")
brew upgrade --cask --force $c
answer="yes"
;;
no)
echo "Installation of $c $current_ver skipped"
;;
*)
answer=""
;;
esac
done
else
printf ": \033[38;5;70mis up-to-date (ver. $installed_ver)\033[0m\n"
fi
done
echo -e "\n"
echo -e '\E[37;44m'"\033[1m****************\033[0m"
echo -e '\E[37;44m'"\033[1m* brew cleanup *\033[0m"
echo -e '\E[37;44m'"\033[1m****************\033[0m"
if [[ -z $(brew cleanup) ]]; then
echo -e "Nothing."
fi
echo -e "\n"
echo -e '\E[37;44m'"\033[1m***************\033[0m"
echo -e '\E[37;44m'"\033[1m* brew doctor *\033[0m"
echo -e '\E[37;44m'"\033[1m***************\033[0m"
brew doctor
Al di là dello zucchero sintattico, la soluzione è stata brutale e ruvida: un ciclo sulla lista dei cask con il force sull’upgrade (righe 21-50). La cosa ancora più singolare è che in questo modo vengono aggiornati dei cask che non risultavano nemmeno nel primo upgrade.
Sicuramente si potrà fare anche meglio. [2]
- Ho provato a usare
brew livecheck
per recuperare più elegantemente le info nelle righe 25-26 ma mi dà qualche problema, ogni tanto va in crash. Ho optato per la scansione secca della lista. - Non so bene come lavori
brew outdated
, se soffra degli stessi problemi degli altri comandi (sospetto di sì ma devo verificare). - In realtà basterebbe una sola riga:
brew list --cask|xargs brew upgrade --cask
solo che così non riesco a controllare il numero di versione causando un aggiornamento quasi sempre inutile per tutti quei cask che hanno come versione “latest” (come Cisco Webex)
Lo script fa il suo lavoro ma ho trovato anche questa alternativa (decisamente più elegante): https://github.com/buo/homebrew-cask-upgrade
Un comando esterno, brew cu
nella sua forma compatta, che sostituisce ed estende le funzionalità di brew upgrade
. Avendo aggiornato da poco, non l’ho ancora visto all’opera.
Edit (31/03/2021):
In realtà, leggendo anche il man e il log dell’applicazione su stdout, ho capito che il funzionamento di brew è corretto.
upgrade e outadated prendono in esame solo i cask che non dispongono di autoupdate.
==> Casks with ‘auto_updates’ or ‘version :latest’ will not be upgraded; pass --greedy to upgrade them.
Un atteggiamento prudenziale che è facile comprendere. Laddove sia disponibile una funzionalità di autoupdate, si preferisce che sia l’applicazione stessa a gestire questo aspetto, lasciando a brew upgrade --cask
(e ai file .rb di configurazione del cask, di conseguenza) la gestione di tutto il resto.
In questo modo, i cask che possono autoaggiornarsi, possono farlo in autonomia appena possibile, senza dipendere dalla modifica necessaria al file di configurazione che innesca l’aggiornamento.
Volendo bypassare questo comportamento, si può ricorrere all’opzione --greedy che forza l’upgrade sia per le app con autoupdate che per quelle che gestiscono il numero di versione con l’orrendo “latest”
Quindi:
brew outdated --greedy --cask
e
brew upgrade --greedy --cask
permettono rispettivamente:
- di elencare tutti i cask che necessitano di un aggiornamento, compresi quelli con autoupdate e con versione “latest”
- di forzare l’aggiornamento dei cask di cui sopra
Forzando l’aggiornamento in questo modo, si potrà andare incontro ad un disallineamento, tipo:
- sul sistema può essere presente una versione più aggiornata di quanto non dica il file di configurazione
- affidandosi all’autoupdate, l’opzione --greedy continuerà a rilevare comunque un aggiornamento da fare (ecco perché brew preferisce ignorare questo tipo di applicazioni)
N.B. brew cu
funziona benissimo permettendo di gestire separatamente sia l’autoupdate che il latest
Note all’articolo