Skip to content

Instantly share code, notes, and snippets.

@clarkdave
Last active September 3, 2023 14:31
Show Gist options
  • Save clarkdave/85aca4e16f33fd52aceb6a0a29936e52 to your computer and use it in GitHub Desktop.
Save clarkdave/85aca4e16f33fd52aceb6a0a29936e52 to your computer and use it in GitHub Desktop.
RuboCop / Sorbet sigil rule
# typed: true
# @prettier
require 'sorbet-runtime'
# Put this somewhere like lib/rubocop/cop/lint/sorbet_sigil.rb and then
# require it in .rubocop.yml:
#
# require:
# - ./lib/rubocop/cop/lint/sorbet_sigil.rb
#
# If you use Rails etc, make sure to place it somewhere that isn't loaded in
# production (as most likely RuboCop won't be available so it'll error)
module RuboCop
module Cop
module Lint
# This cop ensures the first line of the file contains a valid Sorbet sigil
#
# @example
#
# # bad
# # (start of file)
# # class Foo; end
#
# # bad
# # (start of file)
# # # typed: no
#
# # good
# # (start of file)
# # # typed: true
class SorbetSigil < Cop
extend T::Sig
MSG = 'File must have a Sorbet sigil'.freeze
sig { params(processed_source: RuboCop::ProcessedSource).void }
def investigate(processed_source)
token = processed_source.tokens.first
return if token.nil? || valid_sorbet_sigil(token)
add_offense(token, location: token.pos)
end
sig { params(token: RuboCop::Token).returns(T::Boolean) }
def valid_sorbet_sigil(token)
token.type == :tCOMMENT &&
!token.text.to_s.strip.match(
/^#\s*typed:\s*(ignore|false|true|strict|strong)$/,
)
.nil?
end
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment