umläute
umläute

Reputation: 31254

upgrade or install a homebrew formula

In my CI-setup, i would like to make sure that the newest version of a given formula is installed, regardless of whether it is already installed or not.

i'm currently using something like:

brew update
brew install FORMULA || (brew upgrade FORMULA && brew cleanup FORMULA)

What are the pitfalls with that approach? Is there a nicer approach to the problem (e.g. by first querying whether FORMULA is already installed, rather than relying on brew install to fail only if FORMULA is installed)?

Upvotes: 7

Views: 5482

Answers (2)

mprivat
mprivat

Reputation: 21902

I've been using the following. Depending on the use case, I'll use a shell function as follows:

function smart_brew() {
  HOMEBREW_NO_AUTO_UPDATE=1 brew `brew ls --versions "$1" | wc -l | xargs expr | sed 's/0/install/' | sed 's/1/upgrade/'` "$1"
}

and sometimes as a definition in a Makefile:

define smart_brew
    HOMEBREW_NO_AUTO_UPDATE=1 brew `brew ls --versions "$(1)" | wc -l | xargs expr | sed 's/0/install/' | sed 's/1/upgrade/'` "$(1)"
endef

dev:
    $(call smart_brew,formula)

Same basic idea

Upvotes: 0

joeyhoer
joeyhoer

Reputation: 3767

I you want to install a Homebrew package if it does not already exist, and upgrade it otherwise, the best solution is to use Homebrew Bundle which is officially part of the Homebrew family. If that doesn't work for you, and you want to roll your own solution, you should reference at the suggestions below.

There are other situation where a brew install might fail, other than a package already being installed. I'm not sure, but it doesn't look like the brew install command emits an exit status other than 1 on failure, so you have two options:

  1. Search stderr for "not installed" and check against that
  2. Use a different approach

The most common approach I've seen used for this purpose is to check if the package is installed with the command brew ls --versions:

function install_or_upgrade {
    if brew ls --versions "$1" >/dev/null; then
        HOMEBREW_NO_AUTO_UPDATE=1 brew upgrade "$1"
    else
        HOMEBREW_NO_AUTO_UPDATE=1 brew install "$1"
    fi
}

You'll want to use HOMEBREW_NO_AUTO_UPDATE=1 if you're installing multiple packages so that Homebrew does not try to update in between each install/upgrade.

Upvotes: 13

Related Questions