I use Homebrew Cask to install applications on OS X. How do I upgrade all the installed casks?
22 Answers
There is now finally an official upgrade mechanism for Homebrew Cask (see Issue 3396 for the implementation)! To use it, simply run this command:
brew upgrade --cask
However this will not update casks that do not have versioning information (version :latest
) or applications that have a built-in upgrade mechanism (auto_updates true
). To reinstall these casks (and consequently upgrade them if upgrades are available), run the upgrade command with the --greedy
flag like this:
brew upgrade --cask --greedy
homebrew-cask-upgrade
I think this is by far the best solution to upgrade the casks.
source: https://github.com/buo/homebrew-cask-upgrade
Installation & usage
brew tap buo/cask-upgrade
brew update
brew cu
(Optional) Force upgrade outdated apps including the ones marked as latest:
brew cu --all
Bash script to upgrade packages
inspired by Pascal answer
#!/usr/bin/env bash
(set -x; brew update;)
(set -x; brew cleanup;)
(set -x; brew cask cleanup;)
red=`tput setaf 1`
green=`tput setaf 2`
reset=`tput sgr0`
casks=( $(brew cask list) )
for cask in ${casks[@]}
do
version=$(brew cask info $cask | sed -n "s/$cask:\ \(.*\)/\1/p")
installed=$(find "/usr/local/Caskroom/$cask" -type d -maxdepth 1 -maxdepth 1 -name "$version")
if [[ -z $installed ]]; then
echo "${red}${cask}${reset} requires ${red}update${reset}."
(set -x; brew cask uninstall $cask --force;)
(set -x; brew cask install $cask --force;)
else
echo "${red}${cask}${reset} is ${green}up-to-date${reset}."
fi
done
What it does
- update brew/brew cask, cleanup
- read the casks list
- check the
brew cask info
for the newest version - install new version if available (and removes all old versions!)
source: https://gist.github.com/atais/9c72e469b1cbec35c7c430ce03de2a6b
one liner for impatient:
curl -s https://gist.githubusercontent.com/atais/9c72e469b1cbec35c7c430ce03de2a6b/raw/36808a0544628398f26b48f7a3c7b309872ca2c6/cask_upgrade.sh | bash /dev/stdin
save as /usr/local/bin/cask-upgrade
, so you can run it locally as cask-upgrade
later
Here is the function I've written for handling this. Note that I personally didn't want it to just blindly re-install everything since some of the casks I use take a while to install or require additional prompting.
brew_cask_upgrade() {
if [ "$1" != '--continue' ]; then
echo "Removing brew cache"
rm -rf "$(brew --cache)"
echo "Running brew update"
brew update
fi
for c in $(brew cask list); do
echo -e "\n\nInstalled versions of $c: "
ls /opt/homebrew-cask/Caskroom/$c
echo "Cask info for $c"
brew cask info $c
select ynx in "Yes" "No" "Exit"; do
case $ynx in
"Yes") echo "Uninstalling $c"; brew cask uninstall --force "$c"; echo "Re-installing $c"; brew cask install "$c"; break;;
"No") echo "Skipping $c"; break;;
"Exit") echo "Exiting brew_cask_upgrade"; return;;
esac
done
done
}
Based on @Atais' answer, I have enhanced his logic into something nicer. I wanted a way to inspect the packages to upgraded first, before actually forcing the upgrade.
$ brew-cask.sh
just lists an output similar to Homebrew'sbrew update
.- the list above shows all packages installed, with a green
✔
indicating any pending updates. $ brew-cask.sh upgrade
will force the upgrade of those packages.
Code:
# Usage:
#
# $ brew update
# You should execute this first to update everything locally.
#
# $ brew-cask.sh [update]
# This will list all of your cask packages and rather there is an upgrade
# pending with a ✔ checkmark, just like Homebrew does with "brew update".
# The update command is optional, as it doesn't actually do any tracking, there's
# not really anything to "update" with cask. But it keeps with the pattern of
# of Homebrew's "brew update" pattern for those with memory muscle fingers (like me).
#
# $ brew-cask.sh upgrade
# This performs a "brew cask install <cask> --force" of all cask packages that have
# an update pending.
#
# This code was inspired by http://stackoverflow.com/a/36000907/56693
# get the list of installed casks
casks=( $(brew cask list) )
if [[ "$1" == "upgrade" ]]; then
for cask in ${casks[@]}; do
current="$(brew cask info $cask | sed -n '1p' | sed -n 's/^.*: \(.*\)$/\1/p')"
installed=( $(ls /opt/homebrew-cask/Caskroom/$cask))
if (! [[ " ${installed[@]} " == *" $current "* ]]); then
echo "Upgrading $cask to v$current."
(set -x; brew cask install $cask --force;)
else
echo "$cask v$current is up-to-date, skipping."
fi
done
else
echo "Inspecting ${#casks[@]} casks. Use 'brew-cask.sh upgrade' to perform any updates."
for (( i = i ; i < ${#casks[@]} ; i++ )); do
current="$(brew cask info ${casks[$i]} | sed -n '1p' | sed -n 's/^.*: \(.*\)$/\1/p')"
installed=( $(ls /opt/homebrew-cask/Caskroom/${casks[$i]}))
if (! [[ " ${installed[@]} " == *" $current "* ]]); then
casks[$i]="${casks[$i]}$(tput sgr0)$(tput setaf 2) ✔$(tput sgr0)"
fi
done
echo " ${casks[@]/%/$'\n'}" | column
fi
just install it (aka "I need it now!")
It's checked into my .dotfiles
repo; so, you can install it quickly into your ~/bin
with:
$ curl -L https://raw.githubusercontent.com/eduncan911/dotfiles/master/bin/brew-cask.sh --create-dirs -o ~/bin/brew-cask.sh
$ chmod 755 ~/bin/brew-cask.sh
Then use it like so:
$ brew-cask.sh
$ brew-cask.sh upgrade
If you dont have ~/bin
in your path, prefix ~/bin/
to the above statements.
improving on the provided code from deinspanjer, I tried to imitate a noop command, much like the one from chocolatey (choco update --noop / choco outdated).
#!/bin/sh
fetch(){
echo "Removing brew cache"
rm -rf "$(brew --cache)"
echo "Running brew update"
brew update
}
lookup() {
for c in $(brew cask list); do
brew cask info $c
done
}
update(){
var=$( lookup | grep -B 3 'Not installed' | sed -e '/^http/d;/^Not/d;/:/!d' | cut -d ":" -f1)
if [ -n "$var" ]; then
echo "The following installed casks have updates avilable:"
echo "$var"
echo "Install updates now?"
select yn in "Yes" "No"; do
case $yn in
"Yes") echo "updating outdated casks"; break;;
"No") echo "brew cask upgrade cancelled" ;return;;
*) echo "Please choose 1 or 2";;
esac
done
for i in $var; do
echo "Uninstalling $c"; brew cask uninstall --force "$i"; echo "Re-installing $i"; brew cask install "$i"
done
else
echo "all casks are up to date"
fi
}
fetch
update
As one can see, I am using a modular approach since my use case differs a little. I do not want to sit in front of my computer and type yes/no for every app I have installed. While there is no real way of upgrading casks (just the reinstall the newest version), I first do brew update to have the information that there are actually updates available.
Next, I cycle through all the casks to display their information. Because I did brew update before, one is now provided with the information that some cask's latest version is not installed.
Inside my update method, I actually parse the info command for that specific line:
lookup | grep -B 3 'Not installed' | sed -e '/^http/d;/^Not/d;/:/!d' | cut -d ":" -f1
Which translates to: "Give the 3 lines above of info provided whenever you read the line "not installed". Then delete any line that has a link in it, also delete a line that has a ':' in it."
Given the structure of the brew cask info command, we end up with one line (no version info, no app URL), which reflects the cask's actual name that it also was installed with.
In my version, this info is now printed out so one can easily see what casks are out of date and could be updated.
At this point I do a switch case, because maybe right now is not enough time to update things. It depends on your use-case. For me, I sometimes just want to see what's new (waiting for a new version, a bugfix) but don't actually have time to update things because right now I do not want to close my browser etc.
So if one opts for "yes", the list of cleaned names of casks is given to the update function where for each cask that was determined to be out of date the reinstall is issued.
Thanks again to deinspanjer, while trying to solve this issue for myself, I always forgot to issue brew update beforehand so there was no "not installed" line there to actually parse (the foundation of my whole approach).
I hope this was helpful.
I made such script by myself. Please look at the github https://github.com/pesh1983/brew_cask_upgrade. It has pretty good description, but if you have any additional question, feel free to ask me. It does fair upgrade: uninstall and install, so any necessary cleanup will be performed by 'brew' itself.
get outdated casks:
brew cask outdated
upgrade cask:
brew cask reinstall outdated-cask
demo script:
$ cat ~/bin/brew_cask_upgrade.sh
#!/bin/bash
red=$(tput setaf 1)
# green=$(tput setaf 2)
reset=$(tput sgr0)
(set -x; brew update;)
for cask in $(brew cask outdated | awk '{print $1}')
do
echo "${red}update ${cask} ...${reset}."
(set -x; brew cask install --force "$cask";)
done
echo "${red}brew clean up ...${reset}"
(set -x; brew cask cleanup;)
echo "${red}brew clean up done.${reset}"
This has really irked me so I created this script to update all Brew apps and allow the user to choose which Cask apps to update. You can exclude apps from consideration too.
https://github.com/derrekyoung/ScriptsAndUtils/blob/master/brew-cask-upgrade.sh
~/Library/Application Support/Brackets/extensions/user
, and these should persist across upgrades. System plugins are indeed stored within the app bundle inBrackets.app/extensions/default
, and these are lost when you replace the app bundle, but the easiest way would just be to copy the plugins from the old bundle to the new one. – Caleb Xubrew cask upgrade
merged 15 commits into Homebrew:master – l --marc lbrew cask uninstall my-cool-cask
thenbrew cask install my-cool-cask
. – Aaron Gray