pkg_version: make typed: strict

This required:
- adding signatures/types where missing
- ensuring that we respect the signature of `Version.new`
- remove some non-Sorbet type checks
- fixing the exception in tests
- removing some tests now caught by Sorbet
- fixing `Formula#prefix` so it works as intended with correct type
  usage
This commit is contained in:
Mike McQuaid 2024-12-05 14:01:37 +00:00
parent b93c179b69
commit 84225d0120
No known key found for this signature in database
3 changed files with 18 additions and 14 deletions

View File

@ -722,8 +722,10 @@ class Formula
# This directory points to {#opt_prefix} if it exists and if {#prefix} is not # 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. # called from within the same formula's {#install} or {#post_install} methods.
# Otherwise, return the full path to the formula's versioned cellar. # 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) def prefix(version = pkg_version)
versioned_prefix = versioned_prefix(version) versioned_prefix = versioned_prefix(version)
version = PkgVersion.parse(version) if version.is_a?(String)
if !@prefix_returns_versioned_prefix && version == pkg_version && if !@prefix_returns_versioned_prefix && version == pkg_version &&
versioned_prefix.directory? && Keg.new(versioned_prefix).optlinked? versioned_prefix.directory? && Keg.new(versioned_prefix).optlinked?
opt_prefix opt_prefix

View File

@ -1,4 +1,4 @@
# typed: true # rubocop:todo Sorbet/StrictSigil # typed: strict
# frozen_string_literal: true # frozen_string_literal: true
require "version" require "version"
@ -11,21 +11,28 @@ class PkgVersion
REGEX = /\A(.+?)(?:_(\d+))?\z/ REGEX = /\A(.+?)(?:_(\d+))?\z/
private_constant :REGEX 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 delegate [:major, :minor, :patch, :major_minor, :major_minor_patch] => :version
sig { params(path: String).returns(PkgVersion) }
def self.parse(path) def self.parse(path)
_, version, revision = *path.match(REGEX) _, version, revision = *path.match(REGEX)
version = Version.new(version) version = Version.new(version.to_s)
new(version, revision.to_i) new(version, revision.to_i)
end end
sig { params(version: Version, revision: Integer).void }
def initialize(version, revision) def initialize(version, revision)
@version = version @version = T.let(version, Version)
@revision = revision @revision = T.let(revision, Integer)
end end
sig { returns(T::Boolean) }
def head? def head?
version.head? version.head?
end end
@ -42,9 +49,8 @@ class PkgVersion
sig { returns(String) } sig { returns(String) }
def to_s = to_str def to_s = to_str
sig { params(other: PkgVersion).returns(T.nilable(Integer)) }
def <=>(other) def <=>(other)
return unless other.is_a?(PkgVersion)
version_comparison = (version <=> other.version) version_comparison = (version <=> other.version)
return if version_comparison.nil? return if version_comparison.nil?
@ -52,6 +58,7 @@ class PkgVersion
end end
alias eql? == alias eql? ==
sig { returns(Integer) }
def hash def hash
[version, revision].hash [version, revision].hash
end end

View File

@ -33,13 +33,13 @@ RSpec.describe PkgVersion do
it "raises an error if the other side isn't of the same class" do it "raises an error if the other side isn't of the same class" do
expect do expect do
described_class.new(Version.new("1.0"), 0) > Object.new described_class.new(Version.new("1.0"), 0) > Object.new
end.to raise_error(ArgumentError) end.to raise_error(TypeError)
end end
it "is not compatible with Version" do it "is not compatible with Version" do
expect do expect do
described_class.new(Version.new("1.0"), 0) > Version.new("1.0") described_class.new(Version.new("1.0"), 0) > Version.new("1.0")
end.to raise_error(ArgumentError) end.to raise_error(TypeError)
end end
end end
@ -55,12 +55,7 @@ RSpec.describe PkgVersion do
describe "#<=>" do describe "#<=>" do
it "returns nil if the comparison fails" 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(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
end end