From 8b573c94895dc0ac0e1d9d59cf3e8745e8b539ca Mon Sep 17 00:00:00 2001 From: GitLab Bot Date: Thu, 17 Dec 2020 11:59:07 +0000 Subject: Add latest changes from gitlab-org/gitlab@13-7-stable-ee --- rubocop/cop/graphql/descriptions.rb | 60 ++++++++++++++++++++++++++++--------- rubocop/cop/graphql/id_type.rb | 2 +- 2 files changed, 47 insertions(+), 15 deletions(-) (limited to 'rubocop/cop/graphql') diff --git a/rubocop/cop/graphql/descriptions.rb b/rubocop/cop/graphql/descriptions.rb index b4e00dfe336..1585e5c9788 100644 --- a/rubocop/cop/graphql/descriptions.rb +++ b/rubocop/cop/graphql/descriptions.rb @@ -13,42 +13,74 @@ # argument :some_argument, GraphQL::STRING_TYPE # end # +# class UngoodClass +# field :some_argument, +# GraphQL::STRING_TYPE, +# description: "A description that does not end in a period" +# end +# # # good # class GreatClass # argument :some_field, # GraphQL::STRING_TYPE, -# description: "Well described - a superb description" +# description: "Well described - a superb description." # # field :some_field, # GraphQL::STRING_TYPE, -# description: "A thorough and compelling description" +# description: "A thorough and compelling description." # end module RuboCop module Cop module Graphql class Descriptions < RuboCop::Cop::Cop - MSG = 'Please add a `description` property.' + MSG_NO_DESCRIPTION = 'Please add a `description` property.' + MSG_NO_PERIOD = '`description` strings must end with a `.`.' # ability_field and permission_field set a default description. - def_node_matcher :fields, <<~PATTERN - (send nil? :field $...) - PATTERN - - def_node_matcher :arguments, <<~PATTERN - (send nil? :argument $...) + def_node_matcher :field_or_argument?, <<~PATTERN + (send nil? {:field :argument} ...) PATTERN - def_node_matcher :has_description?, <<~PATTERN - (hash <(pair (sym :description) _) ...>) + def_node_matcher :description, <<~PATTERN + (... (hash <(pair (sym :description) $_) ...>)) PATTERN def on_send(node) - matches = fields(node) || arguments(node) + return unless field_or_argument?(node) + + description = description(node) + + return add_offense(node, location: :expression, message: MSG_NO_DESCRIPTION) unless description + + add_offense(node, location: :expression, message: MSG_NO_PERIOD) if no_period?(description) + end + + # Autocorrect missing periods at end of description. + def autocorrect(node) + lambda do |corrector| + description = description(node) + next unless description + + corrector.insert_after(before_end_quote(description), '.') + end + end + + private + + def no_period?(description) + # Test that the description node is a `:str` (as opposed to + # a `#copy_field_description` call) before checking. + description.type == :str && !description.value.strip.end_with?('.') + end - return if matches.nil? + # Returns a Parser::Source::Range that ends just before the final String delimiter. + def before_end_quote(string) + return string.source_range.adjust(end_pos: -1) unless string.heredoc? - add_offense(node, location: :expression) unless has_description?(matches.last) + heredoc_source = string.location.heredoc_body.source + adjust = heredoc_source.index(/\s+\Z/) - heredoc_source.length + string.location.heredoc_body.adjust(end_pos: adjust) end end end diff --git a/rubocop/cop/graphql/id_type.rb b/rubocop/cop/graphql/id_type.rb index 96f90ac136a..0d2fb6ad852 100644 --- a/rubocop/cop/graphql/id_type.rb +++ b/rubocop/cop/graphql/id_type.rb @@ -6,7 +6,7 @@ module RuboCop class IDType < RuboCop::Cop::Cop MSG = 'Do not use GraphQL::ID_TYPE, use a specific GlobalIDType instead' - WHITELISTED_ARGUMENTS = %i[iid full_path project_path group_path target_project_path].freeze + WHITELISTED_ARGUMENTS = %i[iid full_path project_path group_path target_project_path namespace_path].freeze def_node_search :graphql_id_type?, <<~PATTERN (send nil? :argument (_ #does_not_match?) (const (const nil? :GraphQL) :ID_TYPE) ...) -- cgit v1.2.3