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

version: add major, minor, patch methods #8183

Merged
merged 11 commits into from Aug 12, 2020

Conversation

SeekingMeaning
Copy link
Contributor

@SeekingMeaning SeekingMeaning commented Aug 1, 2020

  • 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 tests with your changes locally?

This adds five new methods to the Version class: major, minor, patch, major_minor, major_minor_patch. In particular, Version#major will be useful for determining the version suffix of gcc: Homebrew/homebrew-core#59485

(Based on cask/dsl/version)

Example usage

version_suffix = Formula["gcc"].linked_version.version.major

Examples in brew irb:

irb(main):001:0> Version.new("10.2")
=> #<Version:0x00007fa606210e90 @version="10.2">
irb(main):002:0> Version.new("10.2").major
=> #<Version::NumericToken 10>
irb(main):003:0> Version.new("10.2").minor
=> #<Version::NumericToken 2>
irb(main):004:0> Version.new("10.2").patch
=> nil
irb(main):005:0> Version.new("10.2").major_minor
=> #<Version:0x00007fb489879e30 @version="10.2">
irb(main):006:0> Version.new("10.2").major_minor_patch
=> #<Version:0x00007fb489885c08 @version="10.2">

@SeekingMeaning
Copy link
Contributor Author

SeekingMeaning commented Aug 2, 2020

One thing I noticed is that Version::NumericTokens can't be compared with strings or integers:

irb(main):001:0> Version::NumericToken.new("1") == "1"
=> false
irb(main):002:0> Version::NumericToken.new("1") == 1
=> false

Whereas this works fine with Version:

irb(main):003:0> Version.new("1") == 1
=> true
irb(main):004:0> Version.new("1") == "1"
=> true

I might open another PR to address this

@SeekingMeaning SeekingMeaning marked this pull request as ready for review August 2, 2020 00:30
@SeekingMeaning SeekingMeaning removed the in progress Maintainers are working on this label Aug 2, 2020
@reitermarkus
Copy link
Member

Might be good to make this a module so it can be shared between both Cask::Version and Version.

@MikeMcQuaid
Copy link
Member

In particular, Version#major will be useful for determining the version suffix of gcc, such as in Homebrew/homebrew-core#58973

Can you provide an example of how it should be used?

Might be good to make this a module so it can be shared between both Cask::Version and Version.

Agreed with this, I'd really love to see this deduplicate some Cask code.

@dtrodrigues
Copy link
Member

Can a formula_suffix method be added to be used in audit.rb? The existing changes seem like they would allow the minor version parsing to be removed from audit.rb:

stable_version_string = stable.version.to_s
stable_url_version = Version.parse(stable.url)
_, stable_url_minor_version, = stable_url_version.to_s
.split(".", 3)
.map(&:to_i)
formula_suffix = stable_version_string.split(".").last.to_i

@gromgit
Copy link
Member

gromgit commented Aug 10, 2020

Can you provide an example of how it should be used?

It would turn the following incantation in the augustus formula:

with_env("HOMEBREW_CC" => Formula["gcc"].opt_bin/"gcc-#{Formula["gcc"].linked_version.to_s.slice(/\d+/)}") do

into:

with_env("HOMEBREW_CC" => Formula["gcc"].opt_bin/"gcc-#{Formula["gcc"].linked_version.version.major}") do

Not that much shorter, but somewhat more comprehensible to the Ruby-challenged like me.

There are at least 5 other formulae I'm tracking that could use the same improvement.

@MikeMcQuaid
Copy link
Member

Not that much shorter, but somewhat more comprehensible to the Ruby-challenged like me.

Yup, makes sense. Can this be stripped down to the minimum number of methods we definitely have a use for in formulae and/or Homebrew/brew (including cask)?

@SeekingMeaning
Copy link
Contributor Author

Can a formula_suffix method be added to be used in audit.rb? The existing changes seem like they would allow the minor version parsing to be removed from audit.rb:

stable_version_string = stable.version.to_s
stable_url_version = Version.parse(stable.url)
_, stable_url_minor_version, = stable_url_version.to_s
.split(".", 3)
.map(&:to_i)
formula_suffix = stable_version_string.split(".").last.to_i

Assuming stable_version_string.split(".").last.to_i always refers to the patch version (i.e. major.minor.patch), we could do something like this:

      stable_version_string = stable.version.to_s
      stable_url_version = Version.parse(stable.url)
      stable_url_minor_version = stable_url_version.minor.to_i

      formula_suffix = stable.version.patch.to_i

Also a few lines down we could replace stable_version_string.split(".")[0..1].join(".") with stable.version.major_minor.to_s

@SeekingMeaning
Copy link
Contributor Author

SeekingMeaning commented Aug 10, 2020

Can this be stripped down to the minimum number of methods we definitely have a use for in formulae and/or Homebrew/brew (including cask)?

I think all of these methods except maybe minor_patch will have a use

  • major, minor, patch - used by the other methods
  • major specifically - can be useful for determining GCC prefix as Adrian mentioned above
  • major_minor - could be useful for includes such as -I#{include}/gupnp-1.2 where 1.2 can be replaced with Formula["gupnp"].version.major_minor

Might be good to make this a module so it can be shared between both Cask::Version and Version.

Agreed with this, I'd really love to see this deduplicate some Cask code.

I tried doing this but I don't think there's really any shared logic in how cask/dsl/version.rb and version.rb handle version tokens other than having the same method names (major_minor, etc.) Casks only use strings for versions and in general parse versions differently, while formulae use full-fledged object instances of the Version class. While we might be able to merge the two, we would have to do a lot of wrangling and be very careful to not introduce any regressions or unexpected behavior

@MikeMcQuaid
Copy link
Member

I think all of these methods except maybe minor_patch will have a use

Let's skip this for now and otherwise can include them.

While we might be able to merge the two, we would have to do a lot of wrangling and be very careful to not introduce any regressions or unexpected behavior

This would be a great project to attempt! A general good start should be seeing if you can use our version logic without changing the tests.

@dtrodrigues
Copy link
Member

Assuming stable_version_string.split(".").last.to_i always refers to the patch version (i.e. major.minor.patch), we could do something like this:

For some reason, I thought that it was almost always the patch version but not always. Looking through the existing throttled formulae though it does seem like it's always the patch, so just using patch would work and there isn't a need for an additional suffix method.

@SeekingMeaning
Copy link
Contributor Author

Made a number of quality-of-life additions/changes, hopefully nothing will break

Copy link
Member

@MikeMcQuaid MikeMcQuaid left a comment

Choose a reason for hiding this comment

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

A few readability tweaks then 👍🏻 to 🚢 . Nice work @SeekingMeaning!

@@ -469,6 +486,26 @@ def <=>(other)
end
alias eql? ==

def major
tokens[0]
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
tokens[0]
tokens.first

end

def minor
tokens[1]
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
tokens[1]
tokens.second

end

def patch
tokens[2]
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
tokens[2]
tokens.third

end

def major_minor
Version.new([major, minor].reject(&:nil?).join("."))
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
Version.new([major, minor].reject(&:nil?).join("."))
Version.new([major, minor].compact.join("."))

end

def major_minor_patch
Version.new([major, minor, patch].reject(&:nil?).join("."))
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
Version.new([major, minor, patch].reject(&:nil?).join("."))
Version.new([major, minor, patch].compact.join("."))

@SeekingMeaning SeekingMeaning merged commit 6d9bf72 into Homebrew:master Aug 12, 2020
@SeekingMeaning SeekingMeaning deleted the version/tokens branch August 12, 2020 17:43
@BrewTestBot BrewTestBot added the outdated PR was locked due to age label Dec 18, 2020
@Homebrew Homebrew locked as resolved and limited conversation to collaborators Dec 18, 2020
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.

None yet

6 participants