Homebrew-cask: `brew cask upgrade` outline

Created on 23 Jan 2017  Â·  79Comments  Â·  Source: Homebrew/homebrew-cask

This issue is meant to outline the desired behaviour of upgrade (and outdated). Marking as ready to implement but discussion is encouraged. Will keep this top post updated with the final decisions of the discussion.

outdated should be implemented first, to make sure we have a solid foundation. upgrade should be built on top of it

Behaviour of brew cask outdated:

  1. If given arguments, act on those casks. If not, act on all installed casks.
  2. If called with --greedy, jump directly to step 5.
  3. Ignore the ones that have auto_updates true.
  4. Ignore the ones that have version :latest.
  5. For the rest, compare the installed version to the latest one.
  6. Output outdated casks with the same format as Homebrew:
aria2 (1.30.0) < 1.31.0
cmake (3.7.1) < 3.7.2

Behaviour for brew cask upgrade:

Same steps 1–5.

  1. For the ones that differ, run the uninstall and install steps. Uninstalling is necessary to avoid leaving old traces of it when uninstallation procedures change.
  2. If install fails (after uninstall), revert to previous version.

For those interested in giving a go at this, take a look at https://github.com/Homebrew/brew/pull/1523. It should give you a starting point (but don’t feel obligated to use it). That specific PR has things that would need to be removed (pin/unpin) and added (take auto_updates into account). If working on it, ideally you could commit to provide some further support for the feature for a little while (just enough to make sure the code itself is stable, not be tied to it _ad eternum_).

There was an important consideration when thinking about this feature:

You have a commercial app at version 3.2. The developer releases a paid upgrade: 4.0, the cask is updated, and you upgrade. However, you did not want to pay for version 4.0. Now you’re stuck with a version you do not want. Not only is that a bad experience for you as a user, now you’ll likely introduce that last version into caskroom/versions, further filling the repo.

Some solutions were discussed, but ultimately it was argued they might not be needed or be detrimental at this stage, before we have a better understanding on how best to proceed:

(
) we have auto_updates (not yet taken into account in this PR) and I’m thinking: “are there any commercial apps that do not auto-update”? I’m betting those might very well be the minority if they exist (after all, if you ask for more money for upgrades, you want to auto-update so your users get notified).


Pinging @caskroom/maintainers. Any user is welcome to chime in.

Most helpful comment

outdated is now merged (but not yet live).

Also, a few examples of why for detecting updates, we need to check for a different version, not try to detect a higher one: https://github.com/caskroom/homebrew-versions/pull/3463#issuecomment-287074204 and https://github.com/caskroom/homebrew-cask/pull/30930. In both those cases, the version number is lower than what it was, but the build is newer.

All 79 comments

This looks promising - may I suggest, though, that as a first step in this and to provide some testing, that brew cask outdated gets done and pushed _before_ brew cask upgrade.

The reason I suggest this is that it seems to me the proposal for brew cask outdated doesn't actually _do_ anything but list outdated Casks. Implementing this first will not interfere with user's existing Cask installs, and may then highlight any potential problems that we can tackle before implementing brew cask upgrade.

@miccal No objections. Ideally they’ll be built at the same time anyway, and upgrade should lean on outdated.

This looks promising - may I suggest, though, that as a first step in this and to provide some testing, that brew cask outdated gets done and pushed before brew cask upgrade.

I second that, as we first need to figure out what outdated means exactly.

Edited top post to give precedence to outdated. Also added another step: “ignore the ones that have version :latest”.

I think this is still needed. I've had several issues with the Slack app where the auto-update showed no updates, but there was an updated cask. I'm pretty busy, but I might be able to look into this next weekend.

You should still be able to force updates for :latest casks, at least.

I think this is still needed. I've had several issues with the Slack app where the auto-update showed no updates, but there was an updated cask. I'm pretty busy, but I might be able to look into this next weekend.

I have a similar issue with Dropbox, so I run cd /usr/local/Caskroom/; rm -r dropbox; cd so that Dropbox does not appear on brew cask list and therefore will not be updated whenever the Cask is updated.

I have always had issues whenever I force Dropbox to update.

so I run cd /usr/local/Caskroom/; rm -r dropbox; cd

Small note: cd - changes to the previous working directory. So cd /usr/local/Caskroom/; rm -r dropbox; cd - will get you back to wherever you were before. But why not just rm -r /usr/local/Caskroom/dropbox directly?

Even in those cases cases of Dropbox and Slack, presumably they’d still be auto-updated at some point and it might be that the apps are themselves delaying it on purpose (to prevent everyone contacting the server at once?). With that in mind, I don’t think we need to by default force those to update when the cask does. We might still ignore it. If a user knows an update was released and wants it right now, reinstall suffices.

Small note: cd - changes to the previous working directory. So cd /usr/local/Caskroom/; rm -r dropbox; cd - will get you back to wherever you were before. But why not just rm -r /usr/local/Caskroom/dropbox directly?

I like to be in the directory I am working in - don't ask me why, because I don't have an answer!

I am using buo/homebrew-cask-upgrade successfully for over 6 months.

For me it seems like brew cu --dry-run behaves like the wanted brew cask outdated, with the exceptions

  1. you just can check all casks
  2. auto_updates casks are not filtered out
  3. the output format is different from brew

brew cu behaves like the wanted brew cask upgrade, except it does not do rollback or the uninstall routines.

I just wanted to link to this project, as it is already written in ruby and maybe some of the code/ideas can be reused.

/cc https://github.com/buo/homebrew-cask-upgrade/issues/23

@leipert As has been repeated ad nauseam and is even stated in that repo, those scripts are fragile and rely on unreliable features. By your own admission, that one is missing pretty major stuff.

Lets please focus on building this right and natively, not retrofitting incomplete scripts that use user-facing features. Those are slow and can’t be trusted entirely.

While I fully agree with what @vitorgalvao said, thank you @leipert for the heads up 👍

Would love to see a flag for both outdated and upgrade to show auto_updates casks anyway. Just in case there was an error in the cask, or you have the auto update feature in the app disabled for some reason.

or you have the auto update feature in the app disabled for some reason

How?

I agree. It would be nice to be able to force the update and outdated checks
 For example, most apps that do auto update, have the option to opt in to automatic updates. Someone may turn that off in the app, and rely instead on hbc to do the updates.

I don't know why I would want to do that
 But it might be a use case to consider.

With multiple maintainers and users asking for it, --force has now been added to the top post.

Changed --force to --extensive (seems more accurate/clearer).

What does --extensive mean? --force makes more sense to me

I think within the context of "outdated" "--extensive" makes more sense (i.e. brew cask outdated --extensive) - but within the context of "upgrade", "--force" makes more sense (i.e. brew cask upgrade --force).

However, it gets confusing when there are two different options with basically do the same thing.

Personally, I prefer "--force" (even brew cask outdated --force makes a little bit of sense)...but I really don't care what the option is called.

And a minor nitpick - for "Behavior for brew cask upgrade", it states "Same steps 1–5." and then it starts with step "5" again.

What about --all?

And a minor nitpick - for "Behavior for brew cask upgrade", it states "Same steps 1–5." and then it starts with step "5" again.

Thank you. Fixed.

but within the context of "upgrade", "--force" makes more sense (i.e. brew cask upgrade --force).

I feel --force is inadequate because it looks like we’re doing a force reinstall, and that is not the case at all. I’d rather we save the keyword for if we actually need it later.

What about --all?

I fear that sends the wrong message. Just as people ran brew update && brew cask update (which we deprecated it exactly because it was being used wrongly), --all is “what do you mean “all”? Of course I want all to be updated, that should be the default”. I’m betting we’d see that option used in a majority of the time when it doesn’t make sense.

--extensive to me means “do more than the recommended”. Whatever the exact word is, that’s the message I think it should convey: “you should not be using this flag most of the time, and it does more than the recommended”. It also indicates the operation will take longer (which it will).

I think it’s more beneficial to have a word users aren’t absolutely clear about and as such will need to read the docs, than one they think they are clear about when it actually means something else.

Regarding those two statements:

or you have the auto update feature in the app disabled for some reason

How?

I don't know why I would want to do that
 But it might be a use case to consider.

I actually disable all autoupdates by blocking http(s) calls with Little Snitch for most apps and/or disabling the auto checks in the options, because I do not want them to send more information "home" than necessary and do not want to handle constant nagging/auto-downloads. I'd rather have manual updates with the help of brew cask, so I have control over when an updates happen and which apps will get updates.

This brings me to my question:

Would it make sense to have two different flags for auto_updates true and version :latest?
Because on a normal day I just want nicely versioned upgrades for e.g. firefox and not for version: latest casks.

Sorry for hijacking the discussion again and a big 👍 for all your work, you lovely maintainers :)

@leipert That setup makes you an outlier.

Just like changing the install directory to /Applications HBC is a slight inconvenience to users who run on non-admin accounts, or how HB does not support installing anywhere other than /usr/local, even though that is technically possible, #13201 is clear: workarounds in the code make a mess, and our procedure should seek to emulate normal manual usage.

Blocking all auto-upgrades and upgrading manually is not common enough to be supported as a specific use-case and complicating the options.

We might eventually reach the conclusion it is indeed worth it, but at this point I don’t see it.

@vitorgalvao
I know it makes me an outlier and I demand no support for my setup. Just shared it, so you maintainers have a better understanding how HBC is used "in the wild".

Good suggestions so far! While --force seems obvious at a glance, I don’t see how we can make it work well in practice, given the commitment we already have made in too many places that whenever we say --force, we mean “do whatever it takes to make this work” and that is a whole different thing.

With upgrade --all, we would give users too many ways to read either less or more into it than it actually is (cf. @vitorgalvao’s example).

Regarding --extensive: of the suggestions on the table so far, I can see it work best; yet, it feels just a tad too smart, overly far removed from our everyday language. (Let’s say your spouse just returned from work. Would you, in real life, greet him/her with the words, “Howdy love! Would you mind taking off your shoes because I just gave the house an _extensive_ vacuuming?”)

Let’s consider simple words, like --greedy. I’d personally prefer --greedy; it feels more in touch with the language we actually use in our lives. It’s quite vivid so users might have an easier time to memorize it; that gives it a practical value. It’s already being used in the wild as a configuration option (although this is true for the other suggestions, too). Programmers will probably recall _greedy_ from yet another, not too unfamiliar domain; and while we’re there, one of its antonyms happens to be surprisingly consistent with what we already have in mind for the default, non--greedy behavior: “try to do as little work as possible.”

@claui I’m completely down with --greedy! Clear, easy to memorise, write, and understand. Also gives the right mood for the action. I’m convinced.

Yes, --greedy seems like a better idea than --brute-force. 😜

I don’t suppose we could add a command or flag that directly checks appcasts for Casks with version :latest and outputs the results? That would be extremely helpful for manual usage. I understand there is already a similar script in Homebrew-Cask, but that is not intended for non-maintainers to use.

I don’t suppose we could add a command or flag that directly checks appcasts for Casks with version :latest and outputs the results?

There are no casks with version :latest and an appcast. If you found one, it needs to be fixed. All casks with appcasts get a specific version, even if the url is unversioned.

There were 5 still with :latest and an appcast @vitorgalvao. Fixed in #29756

What exactly are you after @Saklad5 ?
brew cask list --versions will show you the installed casks with version latest. You're not going to be able to get any available update information though.

I was hoping for a way to narrow down which programs may be outdated manually.

Google still ranks https://github.com/caskroom/homebrew-cask/issues/4678 pretty high up when searching for brew cask upgrade. Perhaps explicitly mention this issue in there? (Though I guess due to the way GitHub works, that may be done automatically after I submit this comment)

One of the issues that is mentioned in this and #1523 is the problem of how to handle several major versions. Homebrew core recently changed their versioning strategy from a repo approach to a file approach. Documented at http://docs.brew.sh/Versions.html and https://github.com/Homebrew/brew/issues/620. I think it would be a good solution to the problem to do something similar in HBC.

I'll use a real example. Recently Bitwig released Bitwig Studio (BWS) 2.0, a paid upgrade. I anticipate continuing to use BWS 1 for a while. I'd like to see the following casks in this repo: [email protected], bitwig-studio@2.

@joshka
Homebrew core recently changed their versioning strategy from a repo approach to a file approach.

This actually already works with casks too - I have created a cask for kindle that pins the version at 1.17 (https://github.com/toonetown/homebrew-extras/blob/master/Casks/kindle%401.17.rb)

I don't know how "supported" it is...but at least all the under-the-scenes plumbing is in place to where that is an option.

There’s nothing about that approach that would make implementing upgrade easier. If you’ll continue to use an old version of an app, use the one in caskroom/versions. “What about if we ever remove that version?”. Then we would’ve removed the cask with the version in the name as well.

I like the idea of tackling this a small piece at a time per https://github.com/caskroom/homebrew-cask/issues/29301#issuecomment-274372842. I think there could be a few small steps between brew cask outdated and brew cask upgrade that would be helpful.

@vitorgalvao you mentioned that uninstall was necessary in case the uninstallation procedures change. I think you miss that if the uninstallation procedures changed between versions, the valid uninstallation procedure for the later version of an app should very likely be those of the later version not the earlier. If I update in-app, it would be also be nice to be able to mark the app as updated in the caskroom rather than reinstalling. I'm assuming this is a place where that's a general rule, but one that has some complexity and exceptions? This is just my guess though.

So I think we could use a few more commands prior to implementing brew cask update.

  1. brew cask check-version --appcast: takes a cask and checks the installed version / latest version against the app's appcast. The output of this command would be useful for determining whether the cask is out of date (and the app if it's not yet been updated).

I imagine this being used to automatically ping a particular maintainer to update an app's cask to the latest version whenever the appcast gets an update.

  1. brew cask check-version --plist: takes a cask and checks the CFBundleShortVersionString from `Abc.App/Contents/Info.plist'. This would be useful in determining whether the app is newer than the installed version / cask.

I'm guessing that these would very likely cover a large amount of cases, and allow us to know when to update the app / cask / both. However we might need custom version sensing for some auto_updates / latest casks that don't install an app, or those that break this assumption.

  1. A brew cask mark-updated command might be useful to mark the installed app's version as the installed version. E.g. brew thinks v1.0 is installed, but I've updated to v1.1, brew cask mark-updated picks up the plist or appcast version (or other custom mechanism).

for 2)

you get with mdls -name kMDItemVersion <path to file> also the version. what is better?

(example mdls -name kMDItemVersion /Applications/iPhoto.app)

you mentioned that uninstall was necessary in case the uninstallation procedures change. I think you miss that if the uninstallation procedures changed between versions, the valid uninstallation procedure for the later version of an app should very likely be those of the later version not the earlier.

Not at all. That is precisely why we have a .metadata directory that saves a copy of the cask at the moment you installed. When uninstalling, that is the used procedure. By your logic, casks would already be breaking, upgrade or not.

If I update in-app, it would be also be nice to be able to mark the app as updated in the caskroom rather than reinstalling.

There is no way to do that accurately. auto_updates exists for that very reason. If that’s important to you, you’ll need to reinstall.

  1. brew cask check-version --appcast: takes a cask and checks the installed version / latest version against the app's appcast. The output of this command would be useful for determining whether the cask is out of date (and the app if it's not yet been updated).

No. Appcasts are mostly different, even amongst themselves (github, sparkle), and there’s no reliable way to get versions from them without working mostly case-by-case.

I imagine this being used to automatically ping a particular maintainer to update an app's cask to the latest version whenever the appcast gets an update.

There were already scripts done for that, and more are in the works. That’s the whole goal of appcast, they were always built with that in mind.

  1. brew cask check-version --plist: takes a cask and checks the CFBundleShortVersionString from `Abc.App/Contents/Info.plist'. This would be useful in determining whether the app is newer than the installed version / cask.

Also no. There are a ton of casks that aren’t apps, so this wouldn’t work.

However we might need custom version sensing for some auto_updates / latest casks that don't install an app, or those that break this assumption.

Which means more ugly workarounds and a new mess to handle. The very thing #13201 aims to fix.

  1. A brew cask mark-updated command might be useful to mark the installed app's version as the installed version. E.g. brew thinks v1.0 is installed, but I've updated to v1.1, brew cask mark-updated picks up the plist or appcast version (or other custom mechanism).

Again, you can’t rely on the plist. At the most all this command could do is say “replace the old .metadata with the latest version of the cask”. That’s an ugly manual process, though. It’d make more sense to add a new flag to uninstall to say “ignore the .metadata version and use the current one”, or just make all auto_updates cask do that by default.

Since it seems like a lot of the obstacles consist of dealing with vastly different types of Casks, I am starting to think it would be wise to split some types into entirely new Homebrew projects. I don’t see how simplicity and functionality can be preserved otherwise.

Since it seems like a lot of the obstacles are dealing with vastly different types of Casks

Not at all. Even similar types of casks (apps, fonts, pkgs) are different amongst themselves. Splitting them into new homebrew projects would be nonsensical. A bunch of the logic would be repeated, and problems would multiply instead or being reduced.

The reason #13201 came to be was precisely because it was thought that all apps could be dealt in the same way, and all pkgs in the same different way, and so on. But they can’t. Just because apps share a type, it does not mean they can be dealt with using the exact same methods. Exceptions always occur.

The code could easily be shared, in the same fashion that Homebrew-Cask shares functionality with Homebrew proper already. And individual projects could still include workarounds and exceptions, though they would need fewer for obvious reasons.

I’m not saying it is a good idea. However, ugly workarounds seem like the only other option, no?

However, ugly workarounds seem like the only other option, no?

No. We’re reducing those, not adding them, and it’s working well. Again, read #13201.

Following on from https://github.com/Homebrew/brew/pull/2250#discussion_r104303535, how should Casks that aren't in a tap show in outdated?
E.g.:

$ brew cask outdated --greedy
alfred: (3.1_718) < 3.3.1_806
arturia-analog-lab: (1.2.4.126) <
arturia-mini-v: (2.7.0.76) <
arturia-software-center: (1.1.3.145) <
atom: (1.8.0) < 1.14.4
...

I wrote the arturia Casks some time ago, submitted as a PR, but neglected to fix up the uninstall appropriately to make them acceptable.

I would say they show the same way that formulas that aren't in a tap show for brew outdated

@toonetown did you perhaps mean brew cask list?

Edit: ah - just realized you said brew not brew cask ;)

how should Casks that aren't in a tap show in outdated?

What does that even mean? If they aren't in a Tap, they shouldn't be outdated in the first place, since there is no way to tell, right?

Oh - I see what you mean now...there actually is no update for those casks...so they shouldn't be showing up, I would say.

I thought you were talking about how the output of brew cask outdated Should be formatted, and I was just stating that it probably should mirror how brew outdated is formatted.

If they aren't in a Tap, they shouldn't be outdated in the first place, since there is no way to tell

Agreed.

how should Casks that aren't in a tap show in outdated?

They should never appear in outdated.

Agreed - I left the nil check in to ensure these types of Casks don't show up.
https://github.com/Homebrew/brew/pull/2250/commits/bc3bc1a4d6776b3675a1a365e20b5931d5bfdf50#diff-f85d4948a976b9727959680dbfe1118aR94

I think brew cask outdated should duplicate the --verbose and --quiet behavior of brew outdated. Default is to show version info in interactive shells, names otherwise. The flags override this behavior. This is separate and in addition to the --greedy flag.

@joshka No objections.

Due to a small thread of comments (deleted by their authors, so my replies didn’t make sense anymore) I remind every commenter this issue is about implementing brew cask upgrade correctly.

That means you should refrain from submitting one of the myriad of hackish solutions that exist in the form of external scripts. We are aware those exist, and to the benefit of everyone they will be made obsolete when brew cask upgrade is complete.

In the meantime, if you need one to get by, check homebrew-cask-upgrade.

Not at all. That is precisely why we have a .metadata directory that saves a copy of the cask at the moment you installed. When uninstalling, that is the used procedure. By your logic, casks would already be breaking, upgrade or not.

Yep I see that. but by your logic above, the reason why we need to uninstall is to "avoid leaving old traces of it when uninstallation procedures change". I don't have any evidence that this is a problem currently, but do you have any evidence that updated uninstallation procedures don't break things?

If I update in-app, it would be also be nice to be able to mark the app as updated in the caskroom rather than reinstalling.

There is no way to do that accurately. auto_updates exists for that very reason. If that’s important to you, you’ll need to reinstall.

What about the greedy case? Does it matter if this is accurate? Can we store the original .metadata file as a record of how the file was installed while keeping the new metadata file in the usual place.
I think I'm coming to see item 3 in the outdated list (ignore :auto_updates) as not a good practice. If I brew cask install Firefox to install Firefox 50, update in app to Firefox 51, but later run brew cask outdated, I would expect Firefox 52 to show up in. In brew cask upgrade (even if I don't specify --greedy). I think it should at least show a warning that it has not upgraded because it's marked as auto_update. I guess I see auto_update as an indicator that an app may be different to the version initially installed, not that it cannot be updated by HBC. Is this how you see it?

brew cask check-version --appcast: takes a cask and checks the installed version / latest version against the app's appcast. The output of this command would be useful for determining whether the cask is out of date (and the app if it's not yet been updated).

No. Appcasts are mostly different, even amongst themselves (github, sparkle), and there’s no reliable way to get versions from them without working mostly case-by-case.

I imagine this being used to automatically ping a particular maintainer to update an app's cask to the latest version whenever the appcast gets an update.

There were already scripts done for that, and more are in the works. That’s the whole goal of appcast, they were always built with that in mind.

Fair enough, definitely out of scope for anything required for brew cask update. Do those scripts you're talking about fall in the "hackish solutions" category? This proposal was mostly about getting from there to correctly implemented.

A brew cask mark-updated command might be useful to mark the installed app's version as the installed version. E.g. brew thinks v1.0 is installed, but I've updated to v1.1, brew cask mark-updated picks up the plist or appcast version (or other custom mechanism).

Again, you can’t rely on the plist. At the most all this command could do is say “replace the old .metadata with the latest version of the cask”. That’s an ugly manual process, though. It’d make more sense to add a new flag to uninstall to say “ignore the .metadata version and use the current one”, or just make all auto_updates cask do that by default.

One of the things you might be missing is that we're dealing with the installation of apps, which can be very large downloads. If I've already updated using the application's auto update mechanism, there's no need to re-download and reinstall. This doesn't matter much to those with fast unlimited internet connections, but it does if you have either slow (common in regional areas away from big cities) or capped allowances (common in Australia and on cell phones). This is another argument for only doing stuff locally when the app is already up to date, and a reason to look at ways to detect and reason about this even if there are a number of these that differ. I'm guessing that this number is not going to be huge. A logical fallback if you can't use a plist / custom version finding method is to take a hash of notable installed files. If a file differs, you know a different version is installed than what is expected.

In summary while I think these are important concepts down the track, they're not crucial to the initial implementation of brew cask upgrade

Side note: don't you find it odd that the stanza that indicates whether an app upgrades automatically is called auto_update rather than auto_upgrade? I understand this is historical reasons, but perhaps this would be good to rename for consistency and to remove any potential confusion over terminology in brew / HBC

Unrelated to the above, brew outdated shows multiple installed versions rather than just one. Should brew cask outdated do the same?

$ brew outdated
vitorgalvao/tiny-scripts/cask-repair (0.31.0, 0.32.0) < 0.34.0

Should brew cask outdated do the same?

I'd say yes, brew cask list --versions also shows all versions. We really only support one version at a time, but I think it's still helpful to show all of them.

I don't have any evidence that this is a problem currently, but do you have any evidence that updated uninstallation procedures don't break things?

The reason it isn’t a problem is we’ve been using the .metadata method for a long time. That is precisely why updated uninstallation procedures don’t break old installs: they are not applied to them.

while keeping the new metadata file in the usual place

There is no new metadata file. The new metadata is the current cask, as it exists in the repo.

If I brew cask install Firefox to install Firefox 50, update in app to Firefox 51, but later run brew cask outdated, I would expect Firefox 52 to show up in.

If you update in-app, HBC cannot know which version you are on. That doesn’t work. Building code to detect the actual version you have installed will be hard and a waste of time. That’s trying to be overly smart, and that’s what got us in a mess in the first place (#13201 again).

auto_update

Small note, it’s auto_upates. Mentioning not to nitpick, but because you’re writing code for it, and the typo might trip you up.

I guess I see auto_update as an indicator that an app may be different to the version initially installed, not that it cannot be updated by HBC. Is this how you see it?

Not exactly, but for the purposes of the discussion I think that yes, your thought process is correct.

Do those scripts you're talking about fall in the "hackish solutions" category?

No. appcast is not meant to be used by HBC itself. That doesn’t work due to the vast differences in appcasts in the wild. appcast is designed to cater to the external scripts.

One of the things [cut for size] installed than what is expected.

.metadata is just a directory that contains the cask file at the moment of install. Updating it to the current one means just copying the latest cask file, no downloads are involved.

Also, again, HBC works its installation by leaving the app alone to do what it needs to. We’re not going to start adding extra code to casks just to find out on each one how to detect its version, plus adding workarounds on top of that to cater for apps that have wrong versions inside themselves, plus a myriad of other problems we’re not even seeing now.

Apologies, but this particular facet is not up for discussion. I’ve been here from the start and have seen what trying to be smart on these details does. It leads to workaround on top of workaround, and an untenable mess.

In summary while I think these are important concepts down the track, they're not crucial to the initial implementation of brew cask upgrade.

I agree. As I mentioned in the top post, some details we still have to see how they’ll work in practice, before adding anything else.

Side note: don't you find it odd that the stanza that indicates whether an app upgrades automatically is called auto_update rather than auto_upgrade? I understand this is historical reasons, but perhaps this would be good to rename for consistency and to remove any potential confusion over terminology in brew / HBC

(Quick reminder to not forget the s). I don’t think auto_upgrades is less confusing, because to me it looks like HBC will auto upgrade that Cask without user intervention, for some reason, which isn’t the case. Especially now that we’re talking about auto-updating .metadata and everything (which is a cask, the think brew update does), it makes sense to me. That said, if most people find one clearer than the other, I won’t oppose changing it. But I don’t remember seeing confusion ever before.

As for showing multiple versions: https://github.com/Homebrew/brew/pull/2250#issuecomment-285683005.

outdated is now merged (but not yet live).

Also, a few examples of why for detecting updates, we need to check for a different version, not try to detect a higher one: https://github.com/caskroom/homebrew-versions/pull/3463#issuecomment-287074204 and https://github.com/caskroom/homebrew-cask/pull/30930. In both those cases, the version number is lower than what it was, but the build is newer.

outdated is now merged (but not yet live)

what is preventing it from being "live"?

to me at least it seems like the actual upgrade step is certainly very possible to implement so really looking forward to seeing this in action 👍

thanks to all involved!

Also, a few examples of why for detecting updates, we need to check for a different version

if 'upgrade greedy' is called, would it be reasonable to exclude those casks that have a checksum + have the same checksum as the newest-version-available?
thanks

@monouser7dig:

[W]hat is preventing it from being "live"?

Answer by lurker: Changes (like Homebrew/brew#2309, which implements the one that resolves this issue) in how Homebrew/brew — that is, the brew command itself, into which brew cask's functionality has been merged as of #14384 — are only pushed from master to stable when a new release is tagged.

so by 'new release' you mean new 'brew' release or new 'brew-cask' release? (the cask-releases seem to be quite conservative)
is there an easy way to roll between the latest version and the stable one? (probably not recommended but anyway, wanted to ask)
thanks

To clarify and reiterate, by 'new release,' I mean a new release of brew — _but_, like I said above, that _also_ means a new release of brew cask due to #14384. As for switching stable (the default branch) to master, you can do so by one of the following methods:

  1. Either:

    1. Set the HOMEBREW_DEVELOPER environment variable to '1,' or 'true' in binary.

    2. Run one of the brew sub-commands listed in the 'DEVELOPER COMMANDS' section of brew's man page (the result of running man brew in Terminal.)

  2. Run brew update.

You _might_ also be able to replace step 1 with a simple git -C "$(brew --repository)" checkout master (and maybe even skip step 2 after that,) but I haven't tested that (git's -C option changes directories for you so you don't have to mess around with cd.) To get back to the stable branch, do this:

  1. cd "$(brew --repository)"
  2. Depending on what you did earlier, either:

    1. Unset the HOMEBREW_DEVELOPER environment variable (you can actually do this _before_ changing directories, but I put this step here for symmetry with my earlier set of instructions.)

    2. Run git config --local --bool homebrew.devcmdrun false. (If you've somehow managed to set the homebrew.devcmdrun git config variable to multiple values like I have in the past, just add --replace-all to that command invocation between --local and --bool to fix this.)

  3. Run git checkout -B stable $LATEST_HOMEBREW_RELEASE_TAG (where $LATEST_HOMEBREW_RELEASE_TAG is the latest brew release tag as listed here.)

After that, you can cd back to wherever you were before (or you could just pass the relevant path to git with its -C flag while invoking it again, but I digress.) You can also run brew update again, too, if you feel like it. (I'll admit, though, that this last process is
rather more involved than either you or I might like. Maybe I'll put in a feature request for an extension to brew update-reset that simplifies this
)

wow that was quite an extensive answer!
thanks, I will try as soon as I have an environment where I can also mess sth. up.

You're very welcome, @monouser7dig. It's always a pleasure to help others find what they're looking for. Now, back to my regularly scheduled lurking


I've got a question about brew cask outdated and --greedy...I'd like to list all the non-latest versions...but it seems to be unable to pipe the results out. For example, if I run:

> brew cask outdated --greedy
app1 (latest) != latest
app2 (latest) != latest
app3 (1.2.3) != 1.2.4
app4 (latest) != latest
````

All is good so far, but I get this:

```bash
> brew cask outdated --greedy | grep -v '(latest)'
app1
app2
app3
app4

And even:

> brew cask outdated --greedy 2>&1 | grep -v '(latest)'
app1
app2
app3
app4

Is there a way to specify that I want that version information to be piped to my grep command instead of dropped?

--verbose will do it.

Just wanted to add this one here too in case it's relevant. virtualbox was updated today with a minor version change which happens to be a dependent of virtualbox-extension-pack. Reinstall works fine, but then the extension pack is missing because everything had been deleted even though cask shows the package as installed.

Should there be a method of removing dependents and then adding them back again as part of updating casks?

EDIT: Hmm, the pack might have been there after all. Still an interesting question.

@claui I like your explanations regarding the --greedy flag, but I'm in favor of the --extensive flag that @vitorgalvao used. Is it okay to settle with both flags?

@daylightbrightledlight That train as already left. --greedy has been decided and is already implemented in outdated.

Having two wildly different flags that mean the same thing is a recipe for confusion, so we won’t add --extensive.

@vitorgalvao Okay. I understand. Thanks for the support.

Is there a reason, why outdated is not documented yet? Especially the --greedy and --verbose flags 


Is there a reason, why outdated is not documented yet? Especially the --greedy and --verbose flags 


man brew-cask | less +'/outdated '

How is the progress?

@daylightbrightledlight No comments generally mean no progress. outdated is done; upgrade is not. As usual, PRs welcome.

FYI: Just pointing out _homebrew-cask-upgrade_ in case it might be relevant here.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

pendolf picture pendolf  Â·  4Comments

pablopunk picture pablopunk  Â·  3Comments

GeekOnGadgets picture GeekOnGadgets  Â·  3Comments

vasigorc picture vasigorc  Â·  3Comments

arnogues picture arnogues  Â·  4Comments