diff --git a/Library/Homebrew/PATH.rb b/Library/Homebrew/PATH.rb index f9c347d6e8..20b83d0d36 100644 --- a/Library/Homebrew/PATH.rb +++ b/Library/Homebrew/PATH.rb @@ -1,52 +1,71 @@ -# typed: false +# typed: true # frozen_string_literal: true # Represention of a `*PATH` environment variable. # # @api private class PATH + extend T::Sig + include Enumerable extend Forwardable def_delegator :@paths, :each + # FIXME: Enable cop again when https://github.com/sorbet/sorbet/issues/3532 is fixed. + # rubocop:disable Style/MutableConstant + Element = T.type_alias { T.nilable(T.any(Pathname, String, PATH)) } + private_constant :Element + Elements = T.type_alias { T.any(Element, T::Array[Element]) } + private_constant :Elements + # rubocop:enable Style/MutableConstant + + sig { params(paths: Elements).void } def initialize(*paths) - @paths = parse(*paths) + @paths = parse(paths) end + sig { params(paths: Elements).returns(T.self_type) } def prepend(*paths) - @paths = parse(*paths, *@paths) + @paths = parse(paths + @paths) self end + sig { params(paths: Elements).returns(T.self_type) } def append(*paths) - @paths = parse(*@paths, *paths) + @paths = parse(@paths + paths) self end + sig { params(index: Integer, paths: Elements).returns(T.self_type) } def insert(index, *paths) - @paths = parse(*@paths.insert(index, *paths)) + @paths = parse(@paths.insert(index, *paths)) self end + sig { params(block: T.proc.params(arg0: String).returns(T::Boolean)).returns(T.self_type) } def select(&block) self.class.new(@paths.select(&block)) end + sig { params(block: T.proc.params(arg0: String).returns(T::Boolean)).returns(T.self_type) } def reject(&block) self.class.new(@paths.reject(&block)) end + sig { returns(T::Array[String]) } def to_ary @paths.dup.to_ary end alias to_a to_ary + sig { returns(String) } def to_str @paths.join(File::PATH_SEPARATOR) end alias to_s to_str + sig { params(other: T.untyped).returns(T::Boolean) } def ==(other) if other.respond_to?(:to_ary) && to_ary == other.to_ary true @@ -57,10 +76,12 @@ class PATH end end + sig { returns(T::Boolean) } def empty? @paths.empty? end + sig { returns(T.nilable(T.self_type)) } def existing existing_path = select(&File.method(:directory?)) # return nil instead of empty PATH, to unset environment variables @@ -69,10 +90,11 @@ class PATH private - def parse(*paths) + sig { params(paths: T::Array[Elements]).returns(T::Array[String]) } + def parse(paths) paths.flatten .compact - .flat_map { |p| Pathname.new(p).to_path.split(File::PATH_SEPARATOR) } + .flat_map { |p| Pathname(p).to_path.split(File::PATH_SEPARATOR) } .uniq end end