Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add brew link --HEAD #11397

Merged
merged 31 commits into from May 26, 2021
Merged

Add brew link --HEAD #11397

merged 31 commits into from May 26, 2021

Conversation

cnnrmnn
Copy link
Contributor

@cnnrmnn cnnrmnn commented May 17, 2021

  • Have you followed the guidelines in our Contributing document?
  • Have you checked to ensure there aren't other open Pull Requests for the same change?
  • Have you added an explanation of what your changes do and why you'd like us to include them?
  • Have you written new tests for your changes? Here's an example.
  • Have you successfully run brew style with your changes locally?
  • Have you successfully run brew typecheck with your changes locally?
  • Have you successfully run brew tests with your changes locally?

Closes #11224.

Currently, if the head and stable versions of a formula are both installed, it isn't possible to link the head version of the formula. This PR adds the --HEAD flag to link the head version of a formula.

I had to revise the link command to use to_formulae_and_casks(only: :formula, method: :kegs) rather than to_kegs (which calls to_formulae_and_casks(only: :formula, method: :keg) to get both the head and stable kegs. I may have inadvertently created an issue if multiple non-head kegs can be installed. My modifications make the link command attempt to link any non-head kegs unless --HEAD is given.

I would appreciate it if a maintainer weighed in on this.

@cnnrmnn
Copy link
Contributor Author

cnnrmnn commented May 17, 2021

typecheck is currently failing because to_formulae_and_casks doesn't return an array of kegs like to_kegs does. Going to wait to fix this until someone weighs in on issue I outlined in previous message.

@MikeMcQuaid
Copy link
Member

Nice work again so far @cnnrmnn!

I may have inadvertently created an issue if multiple non-head kegs can be installed

Yes, you can have multiple non-head kegs installed 😭. Let me know if you need a hand with how to progress.

@cnnrmnn
Copy link
Contributor Author

cnnrmnn commented May 18, 2021

I may have inadvertently created an issue if multiple non-head kegs can be installed

Yes, you can have multiple non-head kegs installed 😭. Let me know if you need a hand with how to progress.

Do you know why to_kegs is named to_kegs despite using method: :keg when calling to_formulae_and_casks? I'm considering defining a similar method that uses method: :kegs to correct the current type issue.

@MikeMcQuaid
Copy link
Member

Do you know why to_kegs is named to_kegs despite using method: :keg when calling to_formulae_and_casks? I'm considering defining a similar method that uses method: :kegs to correct the current type issue.

My guess is just it's pluralised like to_formulae_and_casks is. I agree the naming is a little confusing in this case and would be fine with it being changed.

cnnrmnn and others added 3 commits May 18, 2021 09:35
@cnnrmnn
Copy link
Contributor Author

cnnrmnn commented May 18, 2021

My guess is just it's pluralised like to_formulae_and_casks is. I agree the naming is a little confusing in this case and would be fine with it being changed.

It was called to_kegs because it converted each of the named arguments to kegs (same reason as to_formulae_and_casks, as you suggested).

@cnnrmnn
Copy link
Contributor Author

cnnrmnn commented May 18, 2021

The code doesn't work in its current state. Main issue is that brew link <formula> (without --HEAD) will link the head version of the formula if

  1. It's the only installed version of the formula. This may or may not be behavior we want.
  2. If it is the most recently installed version of the formula and is thus linked in HOMEBREW_PREFIX/opt and HOMEBREW_LINKED_KEGS. This is obviously undesirable since it leaves no way to link a non-head version of the formula if the head version of the formula is the most recently installed version of the formula.

Why do both HOMEBREW_PREFIX/opt and HOMEBREW_LINKED_KEGS both exist? They seem to mirror each other.

@MikeMcQuaid
Copy link
Member

  • It's the only installed version of the formula. This may or may not be behavior we want.

I think this is desirable 👍🏻

2. If it is the most recently installed version of the formula and is thus linked in HOMEBREW_PREFIX/opt and HOMEBREW_LINKED_KEGS. This is obviously undesirable since it leaves no way to link a non-head version of the formula if the head version of the formula is the most recently installed version of the formula.

I think this would be OK, actually, we could output a message staging that brew unlink is required first.

Why do both HOMEBREW_PREFIX/opt and HOMEBREW_LINKED_KEGS both exist? They seem to mirror each other.

opt links should always be present for any installed formula. HOMEBREW_LINKED_KEGS indicates a formula has been brew linked (either by default on installation or through brew link --force afterwards).

@cnnrmnn
Copy link
Contributor Author

cnnrmnn commented May 18, 2021

Another strange behavior I noticed is that installing the head version of a formula uninstalls any non-head versions of that formula that are installed. However, installing a non-head version of a formula does not uninstall the head version of the formula if it's installed.

Also, if there are multiple non-head versions of a formula installed, there's no way to control which one gets linked by brew link.

@cnnrmnn
Copy link
Contributor Author

cnnrmnn commented May 18, 2021

I think this would be OK, actually, we could output a message staging that brew unlink is required first.

brew unlink wouldn't solve the problem. If the head version of a formula is the most recently installed version, it is linked in HOMEBREW_PREFIX/opt and HOMEBREW_LINKED_KEGS. Calling brew unlink unlinks it in HOMEBREW_LINKED_KEGS, but not in HOMEBREW_PREFIX/opt. to_keg (called when using brew link without --HEAD), uses the link in HOMEBREW_PREFIX/opt to get the keg, so calling brew link and brew unlink repeatedly links and unlinks the head version of the formula.

Example (formula is initially unlinked):
Screen Shot 2021-05-18 at 11 44 50 AM

@cnnrmnn
Copy link
Contributor Author

cnnrmnn commented May 18, 2021

I think the main question here is if the link in HOMEBREW_PREFIX can't be used to determine which version of the formula should be linked by brew link, what should we use?

Also, if there are multiple non-head versions of a formula installed, there's no way to control which one gets linked by brew link.

I think the answer should ideally address this.

Perhaps a version flag should be added to brew link so that user can optionally choose the version to be linked. Default could be linking highest installed non-head version of the formula or the head version of the formula if no non-head versions are installed.

Library/Homebrew/test/cli/named_args_spec.rb Outdated Show resolved Hide resolved
Library/Homebrew/dev-cmd/linkage.rb Outdated Show resolved Hide resolved
Library/Homebrew/cmd/list.rb Outdated Show resolved Hide resolved
@@ -98,8 +98,8 @@ def load_formula_or_cask(name, only: nil, method: nil)
Formulary.factory(name, *spec, force_bottle: @force_bottle, flags: @flags)
when :resolve
resolve_formula(name)
when :keg
resolve_keg(name)
when :default_kegs
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@MikeMcQuaid is this going to be a backward-incompatible change? It looks like Homebrew::CLI::NamedArgs is in the private API but Homebrew::CLI::Args#named is a public method that returns a NamedArgs array. I wonder, then, if the @api private label here is incorrect.

In fact, I realized that I'm using args.named.to_formulae in a few taps, not realizing it wasn't a public method.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is. Ideally we'd allow but deprecate (on the next minor version e.g. add a commented out # odeprecated) the existing naming.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@MikeMcQuaid should the @api level be changed?

@Rylan12
Copy link
Member

Rylan12 commented May 19, 2021

Another strange behavior I noticed is that installing the head version of a formula uninstalls any non-head versions of that formula that are installed. However, installing a non-head version of a formula does not uninstall the head version of the formula if it's installed.

I don't know if there's a reason for this but I can't think of one off the top of my head. It seems to me that what a user would expect when installing is that whatever version they've most recently installed is the one that's linked. I don't see why installing a stable version shouldn't wipe the HEAD version but installing HEAD does wipe the stable. If anything, I would think it should be the opposite because a new stable version might now match the HEAD version.

Perhaps a version flag should be added to brew link so that user can optionally choose the version to be linked. Default could be linking highest installed non-head version of the formula or the head version of the formula if no non-head versions are installed.

In what situation are there two versions installed, other than a HEAD and a stable version? I don't know of a way to cause this to happen when it isn't a mistake, but I guess I could be missing something.

@cnnrmnn
Copy link
Contributor Author

cnnrmnn commented May 19, 2021

In what situation are there two versions installed, other than a HEAD and a stable version? I don't know of a way to cause this to happen when it isn't a mistake, but I guess I could be missing something.

I can't think of any off of the top of my head, but @MikeMcQuaid mentioned earlier in this PR that it is possible to have multiple non-head kegs installed:

Yes, you can have multiple non-head kegs installed 😭. Let me know if you need a hand with how to progress.

@Rylan12
Copy link
Member

Rylan12 commented May 19, 2021

I guess my thinking is that even if it's possible for there to be multiple we don't need to support doing anything with the non-(head-or-latest-version) keg.

So I think just autodetecting the latest version is the way to go; no need to add any new flags. Same goes for brew list in my opinion

Let's hear from Mike and see if he has a different opinion.

Library/Homebrew/cli/named_args.rb Outdated Show resolved Hide resolved
Library/Homebrew/test/cli/named_args_spec.rb Outdated Show resolved Hide resolved
Library/Homebrew/test/cli/named_args_spec.rb Show resolved Hide resolved
Library/Homebrew/test/cli/named_args_spec.rb Outdated Show resolved Hide resolved
@cnnrmnn
Copy link
Contributor Author

cnnrmnn commented May 20, 2021

My recent changes make brew link <formula> (no --HEAD) link the non-head keg with the most recent version or the head keg if there are no installed non-head kegs.

Connor Mann and others added 3 commits May 21, 2021 11:52
Co-authored-by: Mike McQuaid <mike@mikemcquaid.com>
Co-authored-by: Mike McQuaid <mike@mikemcquaid.com>
@cnnrmnn
Copy link
Contributor Author

cnnrmnn commented May 21, 2021

syntax is currently failing because style doesn't like duplicate branch bodies with :default_kegs and to-be-deprecated :keg.

Library/Homebrew/cmd/unlink.rb Show resolved Hide resolved
Library/Homebrew/cli/named_args.rb Outdated Show resolved Hide resolved
Library/Homebrew/test/cli/named_args_spec.rb Show resolved Hide resolved
Library/Homebrew/cmd/link.rb Outdated Show resolved Hide resolved
Copy link
Member

@Rylan12 Rylan12 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just one suggestion and then I think this will be good

Library/Homebrew/cmd/link.rb Outdated Show resolved Hide resolved
Library/Homebrew/cmd/link.rb Outdated Show resolved Hide resolved
Copy link
Member

@Rylan12 Rylan12 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me!

Thanks again for the great work, @cnnrmnn!

@Rylan12 Rylan12 merged commit d0f5a08 into Homebrew:master May 26, 2021
@cnnrmnn cnnrmnn deleted the add-link-head branch May 26, 2021 15:48
@github-actions github-actions bot added the outdated PR was locked due to age label Jun 26, 2021
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Jun 26, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
outdated PR was locked due to age
Projects
None yet
Development

Successfully merging this pull request may close these issues.

brew install --HEAD for already installed formula gives incorrect instructions about link
3 participants