Brew: Make `brew install $ALIAS` follow alias changes

Created on 21 Jul 2016  ยท  25Comments  ยท  Source: Homebrew/brew

If brew install boost is an alias to brew install boost123 then if the boost alias changes from boost123 to boost124 then brew upgrade should upgrade between these versions.

This will allow us to use the Homebrew versions-style formula naming (or an alternative like @UniqMartin has suggested e.g. boost+1.2.3) combined with these aliases to allow us to have formula pinned to versions if they need to be and have users (and some formulae) follow the latest version of e.g. boost if they don't break on newer versions.

When this issue is done we'll have a larger discussion about a new approach to versioning in Homebrew.

features

All 25 comments

Sounds good to me.

Would this be a reasonable way to do this?

  1. Persist the alias used to install a formula in the INSTALL_RECEIPT
  2. When upgrading, if an alias is in the INSTALL_RECEIPT and the target of the alias has changed, install the new formulae the alias refers to (and store the alias in its INSTALL_RECEIPT too).

@penman Yep, that's the plan! Please feel free to beat me to a PR though ๐Ÿ˜€

If somebody had run brew install boost and got boost+1.2.3, then boost 1.2.4 was released they ran brew upgrade boost, they'd get boost+1.2.4 installed.

But what if they run brew upgrade boost+1.2.3? Seems to me that that should ignore that it was originally installed with just boost and install the latest version of the boost+1.2.3 formula, even if boost has been re-aliased to boost+1.2.4. If that's the case, should that re-write the INSTALL_RECEIPT so that future brew upgrades also stick to boost+1.2.3, or leave it alone?

If somebody had run brew install boost and got boost+1.2.3, then boost 1.2.4 was released they ran brew upgrade boost, they'd get boost+1.2.4 installed.

Yep ๐Ÿ‘

But what if they run brew upgrade boost+1.2.3? Seems to me that that should ignore that it was originally installed with just boost and install the latest version of the boost+1.2.3 formula, even if boost has been re-aliased to boost+1.2.4. If that's the case, should that re-write the INSTALL_RECEIPT so that future brew upgrades also stick to boost+1.2.3, or leave it alone?

I think brew upgrade boost+1.2.3 (although we're actually using [email protected] now) should probably be a no-op unless there's been a revision upgrade and we just treat it like a separate formula. I think this behaviour will occur as-is, though ๐Ÿ‘

although we're actually using [email protected] now

๐Ÿ‘๐ŸŽ‰๐Ÿ‘๐ŸŽ‰๐Ÿ‘๐ŸŽ‰

(This was my preference but I didn't want to get into bikeshedding :P)

So it seems to me them at there are three different ways an aliased formula could be updated:

  • [x] brew upgrade boost โ€” should follow boost alias and install the new version
  • [x] brew upgrade [email protected] โ€” should not follow boost alias (even if it was installed with brew install boost), just check for changes in the [email protected] formula.
  • [ ] brew upgrade โ€” should follow the alias iff the alias was originally used to install the formula

I'll check these off as I test them and get them working correctly.

Something that's come up as I've been trying to implement this is that there's no good way to find formula installed with a previous value for an alias after it's changed.

The only way I've found to check is to loop through Formula.installed and check the alias_path for all of them. I have a lot of formula installed and can't say I've noticed a performance hit when trying it this way, but it seems like a lot more work than necessary.

Any ideas?

Looks good to me, @penman. Using Formula.installed seems fine for now; it doesn't matter too much if brew upgrade is a little sluggish as we scan all the installed formulae for their e.g. versions anyway.

This would affect brew upgrade boost (ie a upgrading a single formula) in addition to brew upgrade (all), but I think it'll be okay.

@penman How's this looking?

@MikeMcQuaid My computer and I haven't been getting on well this week, but I've made some good progress today.

If [email protected] was installed with brew install boost, then boost is changed to point to [email protected], what should another brew install boost do? Install [email protected] or error saying boost is already installed?

I think either option is probably fine but saying boost is already installed and pointing them to brew upgrade feels nicer.

And in that situation, would brew outdated [email protected] report outdatedness or not?

I think brew outdated boost would but not [email protected]. I think basically if you specify something by its full version it should never "jump" to a newer version but if you specify just the alias (e.g. boost) then it should act like it does currently.

Worth nothing is that it won't actually be [email protected] but [email protected] and [email protected] which can both have upgrades e.g. from 1.2.1 to 1.2.2 and 1.3.1 to 1.3.2. Make sense?

Yeah, makes sense. Thanks.

Just about ready to put up a PR. One more question: how should brew outdated's JSON output be changed to handle alias changes? Here's what it's currently showing without me touching it when hello@2 is installed with brew install hello, and hello is then changed to target hello@3:

[
  {
    "name": "hello@2",
    "installed_versions": [
      "2.10"
    ],
    "current_version": "2.10"
  }
]

I guess we'll need a new JSON version, like brew outdated --json=v2, but should there be any changes to the v1 version as well? With this new logic for what's outdated, its current output doesn't really make sense.

I think that makes sense for brew outdated hello@2's output but for brew outdated hello would ideally output:

[
  {
    "name": "hello",
    "installed_versions": [
      "2.10"
    ],
    "current_version": "2.10"
  }
]

or something, I think?

I was just worried that doing that could break a JSON consumer that didn't know how to handle Homebrew aliases. Is that something we need to worry about?

The ideal JSON (that would require a version bump), would look like this, I think:

[
  {
    "name": "hello",
    "installed": [
      {
        "formula": "hello@2",
        "version": "2.10"
      }
    ],
    "current": {
      "formula": "hello@3",
      "version": "3.0"
    }
  }
]

Or alternatively we could just leave the JSON output as-is for now and consider iteration on it if the previous version causes problems. I think my format would be fine if we assume it's being used to decide whether to run e.g. brew upgrade on a given formula. Thoughts?

Okay, I'll just leave it for now and get a PR up, then we can take it from there.

This is done now, right?

Yes ๐ŸŽ‰! Well done @penman!

Was this page helpful?
0 / 5 - 0 ratings