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

pkg_version: make typed: strict #18875

Merged
merged 1 commit into from
Dec 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Library/Homebrew/formula.rb
Original file line number Diff line number Diff line change
Expand Up @@ -722,8 +722,10 @@ def latest_installed_prefix
# This directory points to {#opt_prefix} if it exists and if {#prefix} is not
# called from within the same formula's {#install} or {#post_install} methods.
# Otherwise, return the full path to the formula's versioned cellar.
sig { params(version: T.any(String, PkgVersion)).returns(Pathname) }
def prefix(version = pkg_version)
versioned_prefix = versioned_prefix(version)
version = PkgVersion.parse(version) if version.is_a?(String)
if !@prefix_returns_versioned_prefix && version == pkg_version &&
versioned_prefix.directory? && Keg.new(versioned_prefix).optlinked?
opt_prefix
Expand Down
21 changes: 14 additions & 7 deletions Library/Homebrew/pkg_version.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# typed: true # rubocop:todo Sorbet/StrictSigil
# typed: strict
# frozen_string_literal: true

require "version"
Expand All @@ -11,21 +11,28 @@ class PkgVersion
REGEX = /\A(.+?)(?:_(\d+))?\z/
private_constant :REGEX

attr_reader :version, :revision
sig { returns(Version) }
attr_reader :version

sig { returns(Integer) }
attr_reader :revision

delegate [:major, :minor, :patch, :major_minor, :major_minor_patch] => :version

sig { params(path: String).returns(PkgVersion) }
def self.parse(path)
_, version, revision = *path.match(REGEX)
version = Version.new(version)
version = Version.new(version.to_s)
new(version, revision.to_i)
end

sig { params(version: Version, revision: Integer).void }
def initialize(version, revision)
@version = version
@revision = revision
@version = T.let(version, Version)
@revision = T.let(revision, Integer)
end

sig { returns(T::Boolean) }
def head?
version.head?
end
Expand All @@ -42,16 +49,16 @@ def to_str
sig { returns(String) }
def to_s = to_str

sig { params(other: PkgVersion).returns(T.nilable(Integer)) }
def <=>(other)
return unless other.is_a?(PkgVersion)

version_comparison = (version <=> other.version)
return if version_comparison.nil?

version_comparison.nonzero? || revision <=> other.revision
end
alias eql? ==

sig { returns(Integer) }
def hash
[version, revision].hash
end
Expand Down
9 changes: 2 additions & 7 deletions Library/Homebrew/test/pkg_version_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,13 @@
it "raises an error if the other side isn't of the same class" do
expect do
described_class.new(Version.new("1.0"), 0) > Object.new
end.to raise_error(ArgumentError)
end.to raise_error(TypeError)
end

it "is not compatible with Version" do
expect do
described_class.new(Version.new("1.0"), 0) > Version.new("1.0")
end.to raise_error(ArgumentError)
end.to raise_error(TypeError)
end
end

Expand All @@ -55,12 +55,7 @@

describe "#<=>" do
it "returns nil if the comparison fails" do
expect(described_class.new(Version.new("1.0"), 0) <=> Object.new).to be_nil
expect(Object.new <=> described_class.new(Version.new("1.0"), 0)).to be_nil
expect(Object.new <=> described_class.new(Version.new("1.0"), 0)).to be_nil
expect(described_class.new(Version.new("1.0"), 0) <=> nil).to be_nil
# This one used to fail due to dereferencing a null `self`
expect(described_class.new(nil, 0) <=> described_class.new(Version.new("1.0"), 0)).to be_nil
end
end

Expand Down
Loading