Merge pull request #9199 from reitermarkus/type-signatures
Add more type signatures and `rspec-sorbet`.
This commit is contained in:
commit
ca333a5da0
1
.gitignore
vendored
1
.gitignore
vendored
@ -128,6 +128,7 @@
|
||||
**/vendor/bundle/ruby/*/gems/rspec-mocks-*/
|
||||
**/vendor/bundle/ruby/*/gems/rspec-retry-*/
|
||||
**/vendor/bundle/ruby/*/gems/rspec-support-*/
|
||||
**/vendor/bundle/ruby/*/gems/rspec-sorbet-*/
|
||||
**/vendor/bundle/ruby/*/gems/rspec-wait-*/
|
||||
**/vendor/bundle/ruby/*/gems/rubocop-1*/
|
||||
**/vendor/bundle/ruby/*/gems/rubocop-ast-*/
|
||||
|
||||
@ -18,6 +18,7 @@ AllCops:
|
||||
- 'Homebrew/sorbet/rbi/gems/**/*.rbi'
|
||||
- 'Homebrew/sorbet/rbi/hidden-definitions/**/*.rbi'
|
||||
- 'Homebrew/sorbet/rbi/todo.rbi'
|
||||
- 'Homebrew/sorbet/rbi/upstream.rbi'
|
||||
- 'Homebrew/bin/*'
|
||||
- 'Homebrew/vendor/**/*'
|
||||
|
||||
|
||||
@ -10,6 +10,7 @@ gem "ronn", require: false
|
||||
gem "rspec", require: false
|
||||
gem "rspec-its", require: false
|
||||
gem "rspec-retry", require: false
|
||||
gem "rspec-sorbet", require: false
|
||||
gem "rspec-wait", require: false
|
||||
gem "rubocop", require: false
|
||||
gem "simplecov", require: false
|
||||
|
||||
@ -95,6 +95,9 @@ GEM
|
||||
rspec-support (~> 3.10.0)
|
||||
rspec-retry (0.6.2)
|
||||
rspec-core (> 3.3)
|
||||
rspec-sorbet (1.7.0)
|
||||
sorbet
|
||||
sorbet-runtime
|
||||
rspec-support (3.10.0)
|
||||
rspec-wait (0.0.9)
|
||||
rspec (>= 3, < 4)
|
||||
@ -167,6 +170,7 @@ DEPENDENCIES
|
||||
rspec
|
||||
rspec-its
|
||||
rspec-retry
|
||||
rspec-sorbet
|
||||
rspec-wait
|
||||
rubocop
|
||||
rubocop-performance
|
||||
|
||||
@ -1,34 +1,44 @@
|
||||
# typed: false
|
||||
# typed: true
|
||||
# frozen_string_literal: true
|
||||
|
||||
# Settings for the build environment.
|
||||
#
|
||||
# @api private
|
||||
class BuildEnvironment
|
||||
extend T::Sig
|
||||
|
||||
sig { params(settings: Symbol).void }
|
||||
def initialize(*settings)
|
||||
@settings = Set.new(*settings)
|
||||
@settings = Set.new(settings)
|
||||
end
|
||||
|
||||
sig { params(args: T::Enumerable[Symbol]).returns(T.self_type) }
|
||||
def merge(*args)
|
||||
@settings.merge(*args)
|
||||
self
|
||||
end
|
||||
|
||||
sig { params(o: Symbol).returns(T.self_type) }
|
||||
def <<(o)
|
||||
@settings << o
|
||||
self
|
||||
end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def std?
|
||||
@settings.include? :std
|
||||
end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def userpaths?
|
||||
@settings.include? :userpaths
|
||||
end
|
||||
|
||||
# DSL for specifying build environment settings.
|
||||
module DSL
|
||||
extend T::Sig
|
||||
|
||||
sig { params(settings: Symbol).returns(BuildEnvironment) }
|
||||
def env(*settings)
|
||||
@env ||= BuildEnvironment.new
|
||||
@env.merge(settings)
|
||||
@ -50,16 +60,18 @@ class BuildEnvironment
|
||||
].freeze
|
||||
private_constant :KEYS
|
||||
|
||||
sig { params(env: T.untyped).returns(T::Array[String]) }
|
||||
def self.keys(env)
|
||||
KEYS & env.keys
|
||||
end
|
||||
|
||||
sig { params(env: T.untyped, f: IO).void }
|
||||
def self.dump(env, f = $stdout)
|
||||
keys = self.keys(env)
|
||||
keys -= %w[CC CXX OBJC OBJCXX] if env["CC"] == env["HOMEBREW_CC"]
|
||||
|
||||
keys.each do |key|
|
||||
value = env[key]
|
||||
value = env.fetch(key)
|
||||
s = +"#{key}: #{value}"
|
||||
case key
|
||||
when "CC", "CXX", "LD"
|
||||
|
||||
@ -6,9 +6,10 @@ module Cask
|
||||
#
|
||||
# @api private
|
||||
module Cache
|
||||
module_function
|
||||
extend T::Sig
|
||||
|
||||
def path
|
||||
sig { returns(Pathname) }
|
||||
def self.path
|
||||
@path ||= HOMEBREW_CACHE/"Cask"
|
||||
end
|
||||
end
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
# typed: false
|
||||
# typed: true
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "utils/user"
|
||||
@ -10,13 +10,13 @@ module Cask
|
||||
module Caskroom
|
||||
extend T::Sig
|
||||
|
||||
module_function
|
||||
|
||||
def path
|
||||
sig { returns(Pathname) }
|
||||
def self.path
|
||||
@path ||= HOMEBREW_PREFIX.join("Caskroom")
|
||||
end
|
||||
|
||||
def ensure_caskroom_exists
|
||||
sig { void }
|
||||
def self.ensure_caskroom_exists
|
||||
return if path.exist?
|
||||
|
||||
sudo = !path.parent.writable?
|
||||
@ -32,8 +32,8 @@ module Cask
|
||||
SystemCommand.run("/usr/bin/chgrp", args: ["admin", path], sudo: sudo)
|
||||
end
|
||||
|
||||
sig { params(config: Config).returns(T::Array[Cask]) }
|
||||
def casks(config: nil)
|
||||
sig { params(config: T.nilable(Config)).returns(T::Array[Cask]) }
|
||||
def self.casks(config: nil)
|
||||
return [] unless path.exist?
|
||||
|
||||
Pathname.glob(path.join("*")).sort.select(&:directory?).map do |path|
|
||||
|
||||
@ -8,19 +8,25 @@ module Cask
|
||||
#
|
||||
# @api private
|
||||
class Pkg
|
||||
extend T::Sig
|
||||
|
||||
sig { params(regexp: String, command: T.class_of(SystemCommand)).returns(T::Array[Pkg]) }
|
||||
def self.all_matching(regexp, command)
|
||||
command.run("/usr/sbin/pkgutil", args: ["--pkgs=#{regexp}"]).stdout.split("\n").map do |package_id|
|
||||
new(package_id.chomp, command)
|
||||
end
|
||||
end
|
||||
|
||||
sig { returns(String) }
|
||||
attr_reader :package_id
|
||||
|
||||
sig { params(package_id: String, command: T.class_of(SystemCommand)).void }
|
||||
def initialize(package_id, command = SystemCommand)
|
||||
@package_id = package_id
|
||||
@command = command
|
||||
end
|
||||
|
||||
sig { void }
|
||||
def uninstall
|
||||
unless pkgutil_bom_files.empty?
|
||||
odebug "Deleting pkg files"
|
||||
@ -65,23 +71,28 @@ module Cask
|
||||
forget
|
||||
end
|
||||
|
||||
sig { void }
|
||||
def forget
|
||||
odebug "Unregistering pkg receipt (aka forgetting)"
|
||||
@command.run!("/usr/sbin/pkgutil", args: ["--forget", package_id], sudo: true)
|
||||
end
|
||||
|
||||
sig { returns(T::Array[Pathname]) }
|
||||
def pkgutil_bom_files
|
||||
@pkgutil_bom_files ||= pkgutil_bom_all.select(&:file?) - pkgutil_bom_specials
|
||||
end
|
||||
|
||||
sig { returns(T::Array[Pathname]) }
|
||||
def pkgutil_bom_specials
|
||||
@pkgutil_bom_specials ||= pkgutil_bom_all.select(&method(:special?))
|
||||
end
|
||||
|
||||
sig { returns(T::Array[Pathname]) }
|
||||
def pkgutil_bom_dirs
|
||||
@pkgutil_bom_dirs ||= pkgutil_bom_all.select(&:directory?) - pkgutil_bom_specials
|
||||
end
|
||||
|
||||
sig { returns(T::Array[Pathname]) }
|
||||
def pkgutil_bom_all
|
||||
@pkgutil_bom_all ||= @command.run!("/usr/sbin/pkgutil", args: ["--files", package_id])
|
||||
.stdout
|
||||
@ -90,6 +101,7 @@ module Cask
|
||||
.reject(&MacOS.public_method(:undeletable?))
|
||||
end
|
||||
|
||||
sig { returns(Pathname) }
|
||||
def root
|
||||
@root ||= Pathname.new(info.fetch("volume")).join(info.fetch("install-location"))
|
||||
end
|
||||
@ -101,10 +113,12 @@ module Cask
|
||||
|
||||
private
|
||||
|
||||
sig { params(path: Pathname).returns(T::Boolean) }
|
||||
def special?(path)
|
||||
path.symlink? || path.chardev? || path.blockdev?
|
||||
end
|
||||
|
||||
sig { params(path: Pathname).void }
|
||||
def rmdir(path)
|
||||
return unless path.children.empty?
|
||||
|
||||
@ -115,7 +129,8 @@ module Cask
|
||||
end
|
||||
end
|
||||
|
||||
def with_full_permissions(path)
|
||||
sig { params(path: Pathname, _block: T.proc.void).void }
|
||||
def with_full_permissions(path, &_block)
|
||||
original_mode = (path.stat.mode % 01000).to_s(8)
|
||||
original_flags = @command.run!("/usr/bin/stat", args: ["-f", "%Of", "--", path]).stdout.chomp
|
||||
|
||||
@ -128,10 +143,12 @@ module Cask
|
||||
end
|
||||
end
|
||||
|
||||
sig { params(paths: T::Array[Pathname]).returns(T::Array[Pathname]) }
|
||||
def deepest_path_first(paths)
|
||||
paths.sort_by { |path| -path.to_s.split(File::SEPARATOR).count }
|
||||
end
|
||||
|
||||
sig { params(dir: Pathname).void }
|
||||
def clean_ds_store(dir)
|
||||
return unless (ds_store = dir.join(".DS_Store")).exist?
|
||||
|
||||
@ -140,12 +157,14 @@ module Cask
|
||||
|
||||
# Some packages leave broken symlinks around; we clean them out before
|
||||
# attempting to `rmdir` to prevent extra cruft from accumulating.
|
||||
sig { params(dir: Pathname).void }
|
||||
def clean_broken_symlinks(dir)
|
||||
dir.children.select(&method(:broken_symlink?)).each do |path|
|
||||
@command.run!("/bin/rm", args: ["--", path], sudo: true)
|
||||
end
|
||||
end
|
||||
|
||||
sig { params(path: Pathname).returns(T::Boolean) }
|
||||
def broken_symlink?(path)
|
||||
path.symlink? && !path.exist?
|
||||
end
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
# typed: false
|
||||
# typed: true
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "utils/user"
|
||||
@ -8,25 +8,35 @@ module Cask
|
||||
#
|
||||
# @api private
|
||||
module Staged
|
||||
extend T::Sig
|
||||
|
||||
# FIXME: Enable cop again when https://github.com/sorbet/sorbet/issues/3532 is fixed.
|
||||
# rubocop:disable Style/MutableConstant
|
||||
Paths = T.type_alias { T.any(String, Pathname, T::Array[T.any(String, Pathname)]) }
|
||||
# rubocop:enable Style/MutableConstant
|
||||
|
||||
sig { params(paths: Paths, permissions_str: String).void }
|
||||
def set_permissions(paths, permissions_str)
|
||||
full_paths = remove_nonexistent(paths)
|
||||
return if full_paths.empty?
|
||||
|
||||
@command.run!("/bin/chmod", args: ["-R", "--", permissions_str] + full_paths,
|
||||
@command.run!("/bin/chmod", args: ["-R", "--", permissions_str, *full_paths],
|
||||
sudo: false)
|
||||
end
|
||||
|
||||
def set_ownership(paths, user: User.current, group: "staff")
|
||||
sig { params(paths: Paths, user: T.any(String, User), group: String).void }
|
||||
def set_ownership(paths, user: T.must(User.current), group: "staff")
|
||||
full_paths = remove_nonexistent(paths)
|
||||
return if full_paths.empty?
|
||||
|
||||
ohai "Changing ownership of paths required by #{@cask}; your password may be necessary"
|
||||
@command.run!("/usr/sbin/chown", args: ["-R", "--", "#{user}:#{group}"] + full_paths,
|
||||
@command.run!("/usr/sbin/chown", args: ["-R", "--", "#{user}:#{group}", *full_paths],
|
||||
sudo: true)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
sig { params(paths: Paths).returns(T::Array[Pathname]) }
|
||||
def remove_nonexistent(paths)
|
||||
Array(paths).map { |p| Pathname(p).expand_path }.select(&:exist?)
|
||||
end
|
||||
|
||||
7
Library/Homebrew/cask/staged.rbi
Normal file
7
Library/Homebrew/cask/staged.rbi
Normal file
@ -0,0 +1,7 @@
|
||||
# typed: strict
|
||||
|
||||
module Cask
|
||||
module Staged
|
||||
include Kernel
|
||||
end
|
||||
end
|
||||
@ -1,4 +1,4 @@
|
||||
# typed: false
|
||||
# typed: true
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "tsort"
|
||||
@ -8,7 +8,11 @@ module Cask
|
||||
class TopologicalHash < Hash
|
||||
include TSort
|
||||
|
||||
alias tsort_each_node each_key
|
||||
private
|
||||
|
||||
def tsort_each_node(&block)
|
||||
each_key(&block)
|
||||
end
|
||||
|
||||
def tsort_each_child(node, &block)
|
||||
fetch(node).each(&block)
|
||||
|
||||
@ -47,11 +47,10 @@ module Homebrew
|
||||
Utils::Shell.from_path(args.shell)
|
||||
end
|
||||
|
||||
env_keys = BuildEnvironment.keys(ENV)
|
||||
if shell.nil?
|
||||
BuildEnvironment.dump ENV
|
||||
else
|
||||
env_keys.each do |key|
|
||||
BuildEnvironment.keys(ENV).each do |key|
|
||||
puts Utils::Shell.export_value(key, ENV[key], shell)
|
||||
end
|
||||
end
|
||||
|
||||
@ -0,0 +1,8 @@
|
||||
# DO NOT EDIT MANUALLY
|
||||
# This is an autogenerated file for types exported from the `rspec-sorbet` gem.
|
||||
# Please instead update this file by running `tapioca sync`.
|
||||
|
||||
# typed: true
|
||||
|
||||
# THIS IS AN EMPTY RBI FILE.
|
||||
# see https://github.com/Shopify/tapioca/blob/master/README.md#manual-gem-requires
|
||||
@ -3030,6 +3030,16 @@ class BottleSpecification
|
||||
extend ::T::Private::Methods::SingletonMethodHooks
|
||||
end
|
||||
|
||||
module BuildEnvironment::DSL
|
||||
extend ::T::Private::Methods::MethodHooks
|
||||
extend ::T::Private::Methods::SingletonMethodHooks
|
||||
end
|
||||
|
||||
class BuildEnvironment
|
||||
extend ::T::Private::Methods::MethodHooks
|
||||
extend ::T::Private::Methods::SingletonMethodHooks
|
||||
end
|
||||
|
||||
Bundler::Deprecate = Gem::Deprecate
|
||||
|
||||
class Bundler::Env
|
||||
@ -5479,6 +5489,11 @@ class Cask::Audit
|
||||
extend ::T::Private::Methods::SingletonMethodHooks
|
||||
end
|
||||
|
||||
module Cask::Cache
|
||||
extend ::T::Private::Methods::MethodHooks
|
||||
extend ::T::Private::Methods::SingletonMethodHooks
|
||||
end
|
||||
|
||||
class Cask::Cask
|
||||
def app(&block); end
|
||||
|
||||
@ -5806,11 +5821,21 @@ class Cask::MultipleCaskErrors
|
||||
extend ::T::Private::Methods::SingletonMethodHooks
|
||||
end
|
||||
|
||||
class Cask::Pkg
|
||||
extend ::T::Private::Methods::MethodHooks
|
||||
extend ::T::Private::Methods::SingletonMethodHooks
|
||||
end
|
||||
|
||||
module Cask::Quarantine
|
||||
extend ::T::Private::Methods::MethodHooks
|
||||
extend ::T::Private::Methods::SingletonMethodHooks
|
||||
end
|
||||
|
||||
module Cask::Staged
|
||||
extend ::T::Private::Methods::MethodHooks
|
||||
extend ::T::Private::Methods::SingletonMethodHooks
|
||||
end
|
||||
|
||||
module Cask::Utils
|
||||
extend ::T::Private::Methods::MethodHooks
|
||||
extend ::T::Private::Methods::SingletonMethodHooks
|
||||
@ -8046,6 +8071,11 @@ class GitHub::Actions::Annotation
|
||||
extend ::T::Private::Methods::SingletonMethodHooks
|
||||
end
|
||||
|
||||
module GitHub::Actions
|
||||
extend ::T::Private::Methods::MethodHooks
|
||||
extend ::T::Private::Methods::SingletonMethodHooks
|
||||
end
|
||||
|
||||
module GitHub
|
||||
extend ::T::Private::Methods::MethodHooks
|
||||
extend ::T::Private::Methods::SingletonMethodHooks
|
||||
@ -8132,6 +8162,11 @@ class Homebrew::CLI::Args
|
||||
extend ::T::Private::Methods::SingletonMethodHooks
|
||||
end
|
||||
|
||||
class Homebrew::CLI::NamedArgs
|
||||
extend ::T::Private::Methods::MethodHooks
|
||||
extend ::T::Private::Methods::SingletonMethodHooks
|
||||
end
|
||||
|
||||
class Homebrew::CLI::Parser
|
||||
include ::Homebrew::CLI::Parser::Compat
|
||||
end
|
||||
@ -8287,6 +8322,11 @@ class Homebrew::Style::LineLocation
|
||||
extend ::T::Private::Methods::SingletonMethodHooks
|
||||
end
|
||||
|
||||
class Homebrew::TapAuditor
|
||||
extend ::T::Private::Methods::MethodHooks
|
||||
extend ::T::Private::Methods::SingletonMethodHooks
|
||||
end
|
||||
|
||||
module Homebrew
|
||||
extend ::FileUtils::StreamUtils_
|
||||
extend ::T::Private::Methods::MethodHooks
|
||||
@ -13289,8 +13329,6 @@ end
|
||||
class Net::HTTPAlreadyReported
|
||||
end
|
||||
|
||||
Net::HTTPClientError::EXCEPTION_TYPE = Net::HTTPServerException
|
||||
|
||||
Net::HTTPClientErrorCode = Net::HTTPClientError
|
||||
|
||||
class Net::HTTPEarlyHints
|
||||
@ -13352,8 +13390,6 @@ end
|
||||
class Net::HTTPRangeNotSatisfiable
|
||||
end
|
||||
|
||||
Net::HTTPRedirection::EXCEPTION_TYPE = Net::HTTPRetriableError
|
||||
|
||||
Net::HTTPRedirectionCode = Net::HTTPRedirection
|
||||
|
||||
Net::HTTPRequestURITooLarge = Net::HTTPURITooLong
|
||||
@ -13362,8 +13398,6 @@ Net::HTTPResponceReceiver = Net::HTTPResponse
|
||||
|
||||
Net::HTTPRetriableCode = Net::HTTPRedirection
|
||||
|
||||
Net::HTTPServerError::EXCEPTION_TYPE = Net::HTTPFatalError
|
||||
|
||||
Net::HTTPServerErrorCode = Net::HTTPServerError
|
||||
|
||||
Net::HTTPSession = Net::HTTP
|
||||
@ -25362,6 +25396,25 @@ end
|
||||
|
||||
RSpec::SharedContext = RSpec::Core::SharedContext
|
||||
|
||||
module RSpec::Sorbet
|
||||
end
|
||||
|
||||
module RSpec::Sorbet::Doubles
|
||||
def allow_doubles!(); end
|
||||
|
||||
def allow_instance_doubles!(); end
|
||||
INLINE_DOUBLE_REGEX = ::T.let(nil, ::T.untyped)
|
||||
TYPED_ARRAY_MESSAGE = ::T.let(nil, ::T.untyped)
|
||||
VERIFYING_DOUBLE_OR_DOUBLE = ::T.let(nil, ::T.untyped)
|
||||
end
|
||||
|
||||
module RSpec::Sorbet::Doubles
|
||||
end
|
||||
|
||||
module RSpec::Sorbet
|
||||
extend ::RSpec::Sorbet::Doubles
|
||||
end
|
||||
|
||||
module RSpec::Support
|
||||
DEFAULT_FAILURE_NOTIFIER = ::T.let(nil, ::T.untyped)
|
||||
DEFAULT_WARNING_NOTIFIER = ::T.let(nil, ::T.untyped)
|
||||
@ -30740,6 +30793,16 @@ module Utils::Inreplace
|
||||
extend ::T::Private::Methods::SingletonMethodHooks
|
||||
end
|
||||
|
||||
class Utils::Shebang::RewriteInfo
|
||||
extend ::T::Private::Methods::MethodHooks
|
||||
extend ::T::Private::Methods::SingletonMethodHooks
|
||||
end
|
||||
|
||||
module Utils::Shebang
|
||||
extend ::T::Private::Methods::MethodHooks
|
||||
extend ::T::Private::Methods::SingletonMethodHooks
|
||||
end
|
||||
|
||||
module Utils::Shell
|
||||
extend ::T::Private::Methods::MethodHooks
|
||||
extend ::T::Private::Methods::SingletonMethodHooks
|
||||
|
||||
11
Library/Homebrew/sorbet/rbi/upstream.rbi
Normal file
11
Library/Homebrew/sorbet/rbi/upstream.rbi
Normal file
@ -0,0 +1,11 @@
|
||||
# typed: strict
|
||||
|
||||
class Pathname
|
||||
# https://github.com/sorbet/sorbet/pull/3676
|
||||
sig { params(p1: T.any(String, Pathname), p2: String).returns(T::Array[Pathname]) }
|
||||
def self.glob(p1, p2 = T.unsafe(nil)); end
|
||||
|
||||
# https://github.com/sorbet/sorbet/pull/3678
|
||||
sig { params(with_directory: T::Boolean).returns(T::Array[Pathname]) }
|
||||
def children(with_directory = true); end
|
||||
end
|
||||
@ -26,6 +26,7 @@ end
|
||||
require "rspec/its"
|
||||
require "rspec/wait"
|
||||
require "rspec/retry"
|
||||
require "rspec/sorbet"
|
||||
require "rubocop"
|
||||
require "rubocop/rspec/support"
|
||||
require "find"
|
||||
@ -58,6 +59,10 @@ TEST_DIRECTORIES = [
|
||||
HOMEBREW_TEMP,
|
||||
].freeze
|
||||
|
||||
# Make `instance_double` and `class_double`
|
||||
# work when type-checking is active.
|
||||
RSpec::Sorbet.allow_doubles!
|
||||
|
||||
RSpec.configure do |config|
|
||||
config.order = :random
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
# typed: false
|
||||
# typed: true
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "utils/tty"
|
||||
@ -8,6 +8,9 @@ module GitHub
|
||||
#
|
||||
# @api private
|
||||
module Actions
|
||||
extend T::Sig
|
||||
|
||||
sig { params(string: String).returns(String) }
|
||||
def self.escape(string)
|
||||
# See https://github.community/t/set-output-truncates-multiline-strings/16852/3.
|
||||
string.gsub("%", "%25")
|
||||
@ -19,6 +22,7 @@ module GitHub
|
||||
class Annotation
|
||||
extend T::Sig
|
||||
|
||||
sig { params(path: T.any(String, Pathname)).returns(T.nilable(Pathname)) }
|
||||
def self.path_relative_to_workspace(path)
|
||||
workspace = Pathname(ENV.fetch("GITHUB_WORKSPACE", Dir.pwd)).realpath
|
||||
path = Pathname(path)
|
||||
@ -27,6 +31,12 @@ module GitHub
|
||||
path.realpath.relative_path_from(workspace)
|
||||
end
|
||||
|
||||
sig do
|
||||
params(
|
||||
type: Symbol, message: String,
|
||||
file: T.nilable(T.any(String, Pathname)), line: T.nilable(Integer), column: T.nilable(Integer)
|
||||
).void
|
||||
end
|
||||
def initialize(type, message, file: nil, line: nil, column: nil)
|
||||
raise ArgumentError, "Unsupported type: #{type.inspect}" unless [:warning, :error].include?(type)
|
||||
|
||||
@ -39,17 +49,23 @@ module GitHub
|
||||
|
||||
sig { returns(String) }
|
||||
def to_s
|
||||
file = "file=#{Actions.escape(@file.to_s)}" if @file
|
||||
line = "line=#{@line}" if @line
|
||||
column = "col=#{@column}" if @column
|
||||
metadata = @type.to_s
|
||||
|
||||
metadata = [*file, *line, *column].join(",").presence&.prepend(" ")
|
||||
if @file
|
||||
metadata << " file=#{Actions.escape(@file.to_s)}"
|
||||
|
||||
"::#{@type}#{metadata}::#{Actions.escape(@message)}"
|
||||
if @line
|
||||
metadata << ",line=#{@line}"
|
||||
metadata << ",col=#{@column}" if @column
|
||||
end
|
||||
end
|
||||
|
||||
"::#{metadata}::#{Actions.escape(@message)}"
|
||||
end
|
||||
|
||||
# An annotation is only relevant if the corresponding `file` is relative to
|
||||
# the `GITHUB_WORKSPACE` directory or if no `file` is specified.
|
||||
sig { returns(T::Boolean) }
|
||||
def relevant?
|
||||
return true if @file.nil?
|
||||
|
||||
|
||||
@ -6,14 +6,19 @@ module Utils
|
||||
#
|
||||
# @api private
|
||||
module Shebang
|
||||
extend T::Sig
|
||||
|
||||
module_function
|
||||
|
||||
# Specification on how to rewrite a given shebang.
|
||||
#
|
||||
# @api private
|
||||
class RewriteInfo
|
||||
extend T::Sig
|
||||
|
||||
attr_reader :regex, :max_length, :replacement
|
||||
|
||||
sig { params(regex: Regexp, max_length: Integer, replacement: T.any(String, Pathname)).void }
|
||||
def initialize(regex, max_length, replacement)
|
||||
@regex = regex
|
||||
@max_length = max_length
|
||||
@ -27,6 +32,7 @@ module Utils
|
||||
# rewrite_shebang detected_python_shebang, bin/"script.py"
|
||||
#
|
||||
# @api public
|
||||
sig { params(rewrite_info: RewriteInfo, paths: T::Array[T.any(String, Pathname)]).void }
|
||||
def rewrite_shebang(rewrite_info, *paths)
|
||||
paths.each do |f|
|
||||
f = Pathname(f)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user