Homebrew / homebrew-cask

🍻 A CLI workflow for the administration of macOS applications distributed as binaries
https://brew.sh
BSD 2-Clause "Simplified" License
20.94k stars 10.73k forks source link

brew cask upgrade #309

Closed shrx closed 9 years ago

shrx commented 11 years ago

this issue currently tracks the discussion and work around adding a brew cask upgrade command to homebrew-cask. it started as a bug ticket, whose original contents can be found below.

any action on implementing brew cask upgrade functionality will happen here.


(original title: Calibre is not updated automatically)

I have calibre 0.2.29 installed with cask. brew update; brew upgrade does not update it to the latest version available (0.2.30 as of now). brew cask info Calibre output:

calibre: latest
http://calibre-ebook.com/
Not installed
https://github.com/phinze/homebrew-cask/commits/master/Casks/calibre.rb
vitorgalvao commented 11 years ago

That probably happened since the versioning was changed from an explicit number (0.2.29) to simply “latest”. Does Calibre not auto-update?

Since the old link was broken and it is possible to get a link to the latest version, I think this is a better solution than having it break every time they increment the version by (literally) 0.0.01. This way, when first installing it you always get the most up-to-date version, and then it’ll update itself; unless of course it doesn’t actually check for updates, in which case we’d have to discuss what option seems to be the most acceptable.

Does the app warn you of new versions?

shrx commented 11 years ago

It checks for updates, but I have to manually download the dmg and install. And yeah their update system has always been like this, 0.0.01 increment every few days.

phinze commented 11 years ago

We're not hooked into brew upgrade right now are we? So the "upgrade" path is just to do brew cask uninstall && brew cask install.

Or am I missing something?

shrx commented 11 years ago

I don't know, but even brew cask uninstall && brew cask install should update it fine (which it didn't). I now went through all my apps installed with cask, and noticed that brew cask list does not list the apps that had their .rb file changed (or so it appears). Meaning that I had to manually run the brew cask uninstall && brew cask install command for dropbox and vlc as well.

vitorgalvao commented 11 years ago

That’s something more prevalent earlier in the project, since even the syntax of casks is still under discussion, but it’s something we should probably look into.

That said, if you’re able to update calibre from now on with brew cask uninstall calibre && brew cask install calibre (should probably make that into a shell alias), then it seems to me the way it works now is better. Not only is it easier and faster for you to do (running a command vs having to go to the website and get the new version), it’s also more future-proof, as we won’t have to update the cask every couple of days.

shrx commented 11 years ago

I thought this should be automatically executed with brew upgrade for outdated cask apps.

phinze commented 11 years ago

I think a brew cask upgrade command is probably in order.

There's a larger question about whether we should attempt to hook into homebrew commands (#44), which would give you brew upgrade integration. I'm still sort of skeptical about that notion, though.

If you were able to issue a brew cask upgrade command, would that meet your needs?

vitorgalvao commented 11 years ago

As you know, I employ homebrew-cask a little differently from the way it’s intended, so either way will not affect my workflow.

That said, from a usability perspective won’t brew cask upgrade be a bit confusing, seeing as brew update functions as expected? It’s like I can already feel the multiple open issues at various points in time asking about this (cue TextExpander snippet, to explain how it works). I believe the commands can work either way, either with cask or without, but they should be consistent, i.e. either brew update and brew upgrade or brew cask update and brew cask upgrade. There’s also another kind-of solution, which would be to have brew cask upgrade and alias brew cask update to simply call brew update (although this could be a bit confusing in itself, seeing as the command would also update homebrew, but I think it wouldn’t be as confusing).

shrx commented 11 years ago

Yes, brew cask upgrade is perfectly fine. I'm already using an alias for all system update commands so including this will be no problem. But I have to agree with @vitorgalvao, this could prove to be confusing to some users.

shrx commented 11 years ago

Suggesion for the brew cask upgrade command code:

#! /bin/bash

caskApps=( $(ls /opt/homebrew-cask/Caskroom/) )
caskList=( $(brew cask list) )

diffs=()
for i in "${caskApps[@]}"; do
    skip=
    for j in "${caskList[@]}"; do
        [[ $i == $j ]] && { skip=1; break; }
    done
    [[ -n $skip ]] || diffs+=("$i")
done

if [ $(echo ${#diffs[@]}) -eq 0 ]; then
    exit
elif [ $(echo ${#diffs[@]}) -gt 1 ]; then
    s="s"
fi

difList=$(printf ", %s" "${diffs[@]}")
difList=${difList:1}

echo -e "==> Upgrading ${#diffs[@]} outdated cask$s, with result:\n$difList\n"

for i in "${diffs[@]}"; do
    brew cask uninstall "$i"
    brew cask install "$i"
done

What do you think? Edit: I get warnings:

Error: APP_NAME is not installed

With this script, and older versions are not removed.

passcod commented 11 years ago

I suppose that's pseudo-code, as you'll have undoubtedly noticed we use Ruby? For the less bash-savvy, do you think you could provide a less line-noisy alternative?

shrx commented 11 years ago

This is bash, I don't know ruby. Basically it computes an array "diffs" with cask names that are installed in /opt/homebrew-cask/Caskroom/ but not shown in the output of brew cask list command, and then performs an "update" for each application in array - brew cask uninstall and brew cask install.

vitorgalvao commented 11 years ago

Even in bash, that could be way less verbose. No need for the arrays.

#!/bin/bash

caskApps=$(ls /opt/homebrew-cask/Caskroom/) # Lists the casks in the Caskroom

for app in ${caskApps}; do # For every app there, do this
    appToCheck=$(brew cask list | grep "${app}") # If the app is not present in `brew cask list`, this variable will be empty

    if [[ -z "${appToCheck}" ]]; then # If the variable is empty, then
        brew cask install --force "${app}" # Force an install of the app
    fi
done
phinze commented 11 years ago

haha well let's not refine the bash too much before we convert it to ruby! :smiley_cat:

i do this the general logic that you suggested seems good @shrx - we essentially need to get smarter about detecting if any version is installed. i think we'll probably be modifying the definition of Cask#installed? and then maybe adding Cask#installed_version - then we can drive the upgrade process from those two concepts.

of course for latest casks we'll need to decide if the upgrade command should always attempt upgrade or warn or ignore.

passcod commented 11 years ago

Do we still want this? Also this discussion and #316 are related.

phinze commented 11 years ago

Yup - I think we do. I'm going to edit the original issue so the title is clearer.

lmergner commented 10 years ago

Just a note, running brew cask uninstall calibre && brew cask install calibre will reinstall the last downloaded version from the cache. This works:

rm -r `brew --cache`/calibre-latest && brew cask uninstall calibre && brew cask install calibre'
licx commented 10 years ago

How can I update all the applications installed with cask? Should I manually run brew cask install for each one of them?

vitorgalvao commented 10 years ago

@licx That alone will not work (see @lmergner’s comment). What you would need to do is clear homebrew’s cache and force install all of them. The following (untested) should do it.

rm -rf "$(brew --cache)"
brew update

for app in $(brew cask list); do
    brew cask install --force "${app}"
done
MoOx commented 10 years ago

For my concern, most of the app update themselves, so I don't worry about that. Also, checkout Bodega.app :) But it's an interesting point.

stylerw commented 10 years ago

Another vote in favor of noting the current version of the installed casks, and --force-ing during an upgrade step when $cask_installed_version < $cask_version.

I don't even think we'd need to query the app itself for version, just note the version from the cask file on install, and when the cask is updated and the version number is higher than that, do a --force. Since people are unlikely to create a cask update for a old version when a new release is out through other channels, Worst case scenario, you overwrite an already-updated app by moving to the most recent version.

Perhaps an --no-update flag at install, if you're running betas through the app's channel (which would get overwritten with the current release version the next time the cask gets updated)?

I also vote in favor of running these upgrades, when implemented, as a part of "brew upgrade". Part of the joy of cask is using the same system for everything. If I could automagically upgrade calibre at the same time I upgrade node.js, that'd be a wonderful thing. And if it works for "brew update", it should work for "brew upgrade".

licx commented 10 years ago

+1 for running these upgrades as part of brew upgrade

adyton commented 10 years ago

Agree.. Make the upgrade process part of "brew upgrade"

passcod commented 10 years ago

Addressing a few points:

Also, checkout Bodega.app :)

But isn't the point of Homebrew Cask to avoid using yet another GUI app store / manager? ;)

I also vote in favor of running these upgrades … as a part of "brew upgrade". [If] it works for "brew update", it should work for "brew upgrade".

I counter-vote to make a brew cask update command and recommend its use over brew update for cask metadata updating, just so we avoid these "votes" about having a brew upgrade hook-in. :wink:

Another vote in favor of noting the current version of the installed casks

and

I don't even think we'd need to query the app itself for version, just note the version from the cask file on install

We already do that, as casks are installed in .../app-name/version-number/.

Perhaps an --no-update flag at install, if you're running betas through the app's channel (which would get overwritten with the current release version the next time the cask gets updated)?

That could be interesting, albeit maybe a bit too much complexity.

kstefanini commented 10 years ago

+1 for brew upgrade process.

brendonrapp commented 10 years ago

+1 for hooking brew upgrade, but either way, this functionality needs to be added. It's extremely counterintuitive the way things are now.

AlJohri commented 10 years ago

-1 for brew upgrade

brew cask is extremely different from the rest of brew, installing binaries for GUI apps. it doesn't fit within the rest of the brew paradigm. I appreciate being able to use the same application to perform both tasks but mixing the paradigms is a much larger discussion.

brew cask upgrade should definitely be the first step

I think this sentiment is also reflected here https://github.com/phinze/homebrew-cask/issues/309#issuecomment-17789036 by @phinze

Please see this issue for https://github.com/phinze/homebrew-cask/issues/44 discussion about integration.

bric3 commented 10 years ago

Agreed -1 for brew upgrade. I like when my system is stable. And I take brew-cask as another application not as a real subsystem of brew.

But it would be great to have other commands that you can find in brew like brew cask outdated, brew cask pin formula / brew cask unpin formula. Pinning applications would be useful as we mey have licence for a version but not the new one !

sgtpep commented 10 years ago

Let me share my one-liner doing brew cask upgrade:

brew update
for c in `brew cask list`; do ! brew cask info $c | grep -qF "Not installed" || brew cask install $c; done
elgs commented 10 years ago
MoOx commented 2 months ago
For my concern, most of the app update themselves, so I don't worry about that. 
Also, checkout Bodega.app :)
But it's an interesting point.

@MoOx I have a concern about the brew cask installed app upgrading themselves. Normally the apps install themselves at /Applications, however, brew cask installs apps at /opt/homebrew-cask/Caskroom. My concern is when the apps try to upgrade themselves, are they aware that the new versions should replace the old versions at /opt/homebrew-cask/Caskroom instead of /Applications?

Best regards, Elgs

MoOx commented 10 years ago

@elgs I don't use Bodega. That being said, I still have (like everyone) apps that autoupdate. I think like all apps I got autoupdate. I don't see any issue. It still symlinks in /Applications.

alebcay commented 10 years ago

My concern is when the apps try to upgrade themselves, are they aware that the new versions should replace the old versions at /opt/homebrew-cask/Caskroom instead of /Applications?

They should hopefully not touch the app at /opt/homebrew-cask/Caskroom, since previous versions downloaded should be preserved. However, it would be nice to have some cask command that detects when apps have been updated, and then copy the new app into the Caskroom and put it in the right place accordingly.

elgs commented 10 years ago

@alebcay if this is the case, the new version should be placed in /Applications, right? However, brew cask put everything in /opt/homebrew-cask/Caskroom/, and a link for each app is placed at ~/Applications. Now if the app upgrade process downloads and place the new version at /Applications, is it going to be a mess?

lanterndev commented 10 years ago

Maybe HOMEBREW_CASK_OPTS='--appdir=/Applications' could help you @elgs?

elgs commented 10 years ago

@skivvies thanks. I think this should be the default behavior, or brew cask upgrade should be implemented. I'm very new to brew cask, I'm sorry if I missed anything.

stylerw commented 10 years ago

This is debate reflects a fundamental choice about what homebrew-cask is,

  1. HBC is a Package Management System like Homebrew for Binaries - I as the user install something with HBC, and want it to be on my machine, accessible, and updated, damnit. In this case, HBC needs to handle upgrades, just like homebrew does, and it needs to be transparent to the user. brew cask upgrade, all versions are checked, new versions are Dled and installed, and everything's at the latest casked version, no matter whether sparkle (or some other update manager) has run. Don't need Bodega, don't need sparkle, don't need to go to the website to DL the latest version, don't even need to open the app, it's up-to-date. I have an ongoing relationship with HBC, it has my back. This is what I want, and this is what doesn't exist in CLI form, and what kind of exists, for some apps, in Bodega, but without the CLI grace.
  2. HBC is a one-time package installation script designed to be quicker than doing it manually - I as the user install something with HBC because it's easier than going to the developer's website, downloading a DMG, dragging, etc. After that, I want to be on my own, and update apps through Sparkle, through re-downloading the DMG, etc. Here, your relationship with HBC ends after the command to install what you want finishes, and it's effectively a very nice way of bootstrapping all your apps after a clean install, on a new machine, etc. In this case, the only sane choice is to have HBC copy the application files themselves into /Applications, to abandon version foldering and /opt for anything except for the cask git repo.

If we're doing #2, we need to make that clear. And if we're claiming #1, we need to deliver it.

lanterndev commented 10 years ago

Bravo! Well said, and another +1 for option 1.

On Friday, March 14, 2014, Will Styler notifications@github.com wrote:

This is debate reflects a fundamental choice about what homebrew-cask is,

1.

HBC is a Package Management System like Homebrew for Binaries - I as the user install something with HBC, and want it to be on my machine, accessible, and updated, damnit. In this case, HBC needs to handle upgrades, just like homebrew does, and it needs to be transparent to the user. brew cask upgrade, all versions are checked, new versions are Dled and installed, and everything's at the latest casked version, no matter whether sparkle (or some other update manager) has run. Don't need Bodega, don't need sparkle, don't need to open the app to be up-to-date. Things just are there, and I have an ongoing relationship with HBC. This is what I want, and this is what doesn't exist in CLI form, and what kind of exists, for some apps, in Bodega, but without the CLI grace. 2.

HBC is a one-time package installation script designed to be quicker than doing it manually - I as the user install something with HBC because it's easier than going to the developer's website, downloading a DMG, dragging, etc. After that, I want to be on my own, and update apps through Sparkle, through re-downloading the DMG, etc. Here, your relationship with HBC ends after the command to install what you want finishes, and it's effectively a very nice way of bootstrapping all your apps after a clean install, on a new machine, etc. In this case, the only sane choice is to have HBC copy the application files themselves into /Applications, to abandon version foldering and /opt anything except for the cask git repo.

If we're doing #2 https://github.com/phinze/homebrew-cask/pull/2, we need to make that clear. And if we're claiming #1https://github.com/phinze/homebrew-cask/pull/1, we need to deliver it.

Reply to this email directly or view it on GitHubhttps://github.com/phinze/homebrew-cask/issues/309#issuecomment-37667282 .

lowbatteries commented 10 years ago

@stylerw hits the nail on the head. I too, would prefer #1 - I'm planning on soon doing a lot of traveling where data usage will need to be tightly controlled, and I'd prefer to update all my apps at a time of my choosing, so I would disable auto-update features and prefer to have a simple way to update all my apps. Apps from the App Store, I can do that, and would love a way to do that for all my other apps.

Rorto commented 10 years ago

Good point @stylerw. +1 for 1.

lowbatteries commented 10 years ago

Also, it might be prudent to be able to set an auto-update preference to off when the app is installed (to avoid overwriting the Cask version). Most apps I believe would just have this in a plist somewhere, right? Would be nice if there was a systematic way to do it that worked across most apps using major update frameworks.

Some apps, like Google Chrome, might auto-update in the background without even notifying users. There would need to be a way to handle those apps in a different way.

elgs commented 10 years ago

@stylerw great! Just to the point.

stylerw commented 10 years ago

@lowbatteries I like that idea. Something like brew cask install --no-upgrade appname, this would also handle the "I have a serial for 3.x, but not for 4.x" condition nicely.

vitorgalvao commented 10 years ago

I’m pretty sure auto-updating is not an issue that breaks things. I’ve never had any problem with apps auto-updating, and I believe the ones that do, replace the current app in place, wherever that might be. It makes sense — it’s not that hard to do, and why would you assume everyone installs to /Applications? Worst case you would get the specific version of an app inside a directory with the wrong version number as the name.

@elgs To discuss linking to /Applications as the default, we have this issue.

Regarding @stylerw’s comment, The first option would be the ideal goal, yes (this is still an open issue, after all). However, please take into account that homebrew-cask is not even at version 1, yet. You all certainly understand that not only does this need to be implemented, how it should be implemented also needs considering.

This particular request has been brought up in a variety of issues/comments and even an initial proposal/pull request was submitted at one point. We appreciate all of your inputs, and (at least try to) read through and consider all of them. This project has grown ever more ambitious (it started with apps and now supports more, like fonts and quicklook plugins), and the fact that so many of us rely on it regularly is a testament to how functional it already is, thanks to the contributions of the community. You, the users, have been invaluable in shaping this to be what it is today.

In sum, we may not be there yet, but rest assured this is not forgotten.

lowbatteries commented 10 years ago

@stylerw - I think that describes something different - I was just thinking of a way to disable sparkle updates, it sounds like what you are describing would exempt the app from "brew cask upgrade".

Anahkiasen commented 10 years ago

I'm kind of having trouble getting the global point of the discussion, was this rejected ?

alebcay commented 10 years ago

Not quite - it's just that the individual points mentioned in this discussion are already being discussed elsewhere in other issues (e.g. #2534).

hanxue commented 10 years ago

+1 for brew upgrade to update Casks as well.

m3nu commented 10 years ago

Yeah. brew upgrade should do cask as well, if no important reasons prevent it.

Until then I'm using the solution by @sgtpep.

wizonesolutions commented 10 years ago

Also +1 for brew outdated to show which casks will be upgraded.

itsthejb commented 10 years ago

Mind a tiny bit blown that this isn't a key feature provided out of the box...