diff options
Diffstat (limited to 'rubocop')
-rw-r--r-- | rubocop/cop/graphql/authorize_types.rb | 6 | ||||
-rw-r--r-- | rubocop/cop/graphql/descriptions.rb | 56 | ||||
-rw-r--r-- | rubocop/graphql_helpers.rb | 13 | ||||
-rw-r--r-- | rubocop/rubocop.rb | 1 |
4 files changed, 73 insertions, 3 deletions
diff --git a/rubocop/cop/graphql/authorize_types.rb b/rubocop/cop/graphql/authorize_types.rb index cd8bdbaee59..69c23be0252 100644 --- a/rubocop/cop/graphql/authorize_types.rb +++ b/rubocop/cop/graphql/authorize_types.rb @@ -7,12 +7,12 @@ module RuboCop MSG = 'Add an `authorize :ability` call to the type: '\ 'https://docs.gitlab.com/ee/development/api_graphql_styleguide.html#type-authorization' - TYPES_DIR = 'app/graphql/types' - # We want to exclude our own basetypes and scalars WHITELISTED_TYPES = %w[BaseEnum BaseScalar BasePermissionType MutationType QueryType GraphQL::Schema BaseUnion].freeze + TYPES_DIR = 'app/graphql/types' + def_node_search :authorize?, <<~PATTERN (send nil? :authorize ...) PATTERN @@ -44,7 +44,7 @@ module RuboCop end def superclass_constant(class_node) - # First one is the class name itself, second is it's superclass + # First one is the class name itself, second is its superclass _class_constant, *others = class_node.descendants others.find { |node| node.const_type? && node&.const_name != 'Types' } diff --git a/rubocop/cop/graphql/descriptions.rb b/rubocop/cop/graphql/descriptions.rb new file mode 100644 index 00000000000..b4e00dfe336 --- /dev/null +++ b/rubocop/cop/graphql/descriptions.rb @@ -0,0 +1,56 @@ +# frozen_string_literal: true + +# This cop checks for missing GraphQL field descriptions. +# +# @example +# +# # bad +# class AwfulClass +# field :some_field, GraphQL::STRING_TYPE +# end +# +# class TerribleClass +# argument :some_argument, GraphQL::STRING_TYPE +# end +# +# # good +# class GreatClass +# argument :some_field, +# GraphQL::STRING_TYPE, +# description: "Well described - a superb description" +# +# field :some_field, +# GraphQL::STRING_TYPE, +# description: "A thorough and compelling description" +# end + +module RuboCop + module Cop + module Graphql + class Descriptions < RuboCop::Cop::Cop + MSG = 'Please add a `description` property.' + + # 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 $...) + PATTERN + + def_node_matcher :has_description?, <<~PATTERN + (hash <(pair (sym :description) _) ...>) + PATTERN + + def on_send(node) + matches = fields(node) || arguments(node) + + return if matches.nil? + + add_offense(node, location: :expression) unless has_description?(matches.last) + end + end + end + end +end diff --git a/rubocop/graphql_helpers.rb b/rubocop/graphql_helpers.rb new file mode 100644 index 00000000000..eef83df0112 --- /dev/null +++ b/rubocop/graphql_helpers.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +module RuboCop + module GraphqlHelpers + TYPES_DIR = 'app/graphql/types' + + def in_type?(node) + path = node.location.expression.source_buffer.name + + path.include?(TYPES_DIR) + end + end +end diff --git a/rubocop/rubocop.rb b/rubocop/rubocop.rb index 9d97aa86bf6..29864777f59 100644 --- a/rubocop/rubocop.rb +++ b/rubocop/rubocop.rb @@ -49,3 +49,4 @@ require_relative 'cop/code_reuse/active_record' require_relative 'cop/group_public_or_visible_to_user' require_relative 'cop/inject_enterprise_edition_module' require_relative 'cop/graphql/authorize_types' +require_relative 'cop/graphql/descriptions' |