diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/feature.rb | 8 | ||||
-rw-r--r-- | lib/gitlab/ci/reports/codequality_reports.rb | 7 | ||||
-rw-r--r-- | lib/gitlab/ci/reports/codequality_reports_comparer.rb | 5 | ||||
-rw-r--r-- | lib/gitlab/graphql/docs/helper.rb | 134 | ||||
-rw-r--r-- | lib/gitlab/graphql/docs/renderer.rb | 7 | ||||
-rw-r--r-- | lib/gitlab/graphql/docs/templates/default.md.haml | 18 | ||||
-rw-r--r-- | lib/gitlab/quick_actions/command_definition.rb | 11 | ||||
-rw-r--r-- | lib/tasks/gitlab/graphql.rake | 4 |
8 files changed, 143 insertions, 51 deletions
diff --git a/lib/feature.rb b/lib/feature.rb index ad243719096..7c926b25587 100644 --- a/lib/feature.rb +++ b/lib/feature.rb @@ -57,7 +57,7 @@ class Feature # use `default_enabled: true` to default the flag to being `enabled` # unless set explicitly. The default is `disabled` # TODO: remove the `default_enabled:` and read it from the `defintion_yaml` - # check: https://gitlab.com/gitlab-org/gitlab/-/issues/271275 + # check: https://gitlab.com/gitlab-org/gitlab/-/issues/30228 def enabled?(key, thing = nil, type: :development, default_enabled: false) if check_feature_flags_definition? if thing && !thing.respond_to?(:flipper_id) @@ -65,11 +65,11 @@ class Feature "The thing '#{thing.class.name}' for feature flag '#{key}' needs to include `FeatureGate` or implement `flipper_id`" end - Feature::Definition.valid_usage!(key, type: type, default_enabled: :yaml) + Feature::Definition.valid_usage!(key, type: type, default_enabled: default_enabled) end - # TODO: Remove rubocop disable comment once `default_enabled` argument is removed https://gitlab.com/gitlab-org/gitlab/-/issues/271275 - default_enabled = Feature::Definition.default_enabled?(key) # rubocop:disable Lint/ShadowedArgument + # If `default_enabled: :yaml` we fetch the value from the YAML definition instead. + default_enabled = Feature::Definition.default_enabled?(key) if default_enabled == :yaml # During setup the database does not exist yet. So we haven't stored a value # for the feature yet and return the default. diff --git a/lib/gitlab/ci/reports/codequality_reports.rb b/lib/gitlab/ci/reports/codequality_reports.rb index ed7373a7d4b..27c41c384b8 100644 --- a/lib/gitlab/ci/reports/codequality_reports.rb +++ b/lib/gitlab/ci/reports/codequality_reports.rb @@ -6,6 +6,7 @@ module Gitlab class CodequalityReports attr_reader :degradations, :error_message + SEVERITY_PRIORITIES = %w(blocker critical major minor info).map.with_index.to_h.freeze # { "blocker" => 0, "critical" => 1 ... } CODECLIMATE_SCHEMA_PATH = Rails.root.join('app', 'validators', 'json_schemas', 'codeclimate.json').to_s def initialize @@ -29,6 +30,12 @@ module Gitlab @degradations.values end + def sort_degradations! + @degradations = @degradations.sort_by do |_fingerprint, degradation| + SEVERITY_PRIORITIES[degradation.dig(:severity)] + end.to_h + end + private def valid_degradation?(degradation) diff --git a/lib/gitlab/ci/reports/codequality_reports_comparer.rb b/lib/gitlab/ci/reports/codequality_reports_comparer.rb index 10748b8ca02..e34d9675c10 100644 --- a/lib/gitlab/ci/reports/codequality_reports_comparer.rb +++ b/lib/gitlab/ci/reports/codequality_reports_comparer.rb @@ -7,6 +7,11 @@ module Gitlab def initialize(base_report, head_report) @base_report = base_report @head_report = head_report + + unless not_found? + @base_report.sort_degradations! + @head_report.sort_degradations! + end end def success? diff --git a/lib/gitlab/graphql/docs/helper.rb b/lib/gitlab/graphql/docs/helper.rb index e9ff85d9ca9..f4173e26224 100644 --- a/lib/gitlab/graphql/docs/helper.rb +++ b/lib/gitlab/graphql/docs/helper.rb @@ -27,7 +27,10 @@ module Gitlab MD end - def render_name_and_description(object, level = 3) + # Template methods: + # Methods that return chunks of Markdown for insertion into the document + + def render_name_and_description(object, owner: nil, level: 3) content = [] content << "#{'#' * level} `#{object[:name]}`" @@ -35,10 +38,22 @@ module Gitlab if object[:description].present? desc = object[:description].strip desc += '.' unless desc.ends_with?('.') + end + + if object[:is_deprecated] + owner = Array.wrap(owner) + deprecation = schema_deprecation(owner, object[:name]) + content << (deprecation&.original_description || desc) + content << render_deprecation(object, owner, :block) + else content << desc end - content.join("\n\n") + content.compact.join("\n\n") + end + + def render_return_type(query) + "Returns #{render_field_type(query[:type])}.\n" end def sorted_by_name(objects) @@ -47,39 +62,25 @@ module Gitlab objects.sort_by { |o| o[:name] } end - def render_field(field) - row(render_name(field), render_field_type(field[:type]), render_description(field)) + def render_field(field, owner) + render_row( + render_name(field, owner), + render_field_type(field[:type]), + render_description(field, owner, :inline) + ) end - def render_enum_value(value) - row(render_name(value), render_description(value)) + def render_enum_value(enum, value) + render_row(render_name(value, enum[:name]), render_description(value, enum[:name], :inline)) end - def row(*values) - "| #{values.join(' | ')} |" + def render_union_member(member) + "- [`#{member}`](##{member.downcase})" end - def render_name(object) - rendered_name = "`#{object[:name]}`" - rendered_name += ' **{warning-solid}**' if object[:is_deprecated] - rendered_name - end + # QUERIES: - # Returns the object description. If the object has been deprecated, - # the deprecation reason will be returned in place of the description. - def render_description(object) - return object[:description] unless object[:is_deprecated] - - "**Deprecated:** #{object[:deprecation_reason]}" - end - - def render_field_type(type) - "[`#{type[:info]}`](##{type[:name].downcase})" - end - - def render_return_type(query) - "Returns #{render_field_type(query[:type])}.\n" - end + # Methods that return parts of the schema, or related information: # We are ignoring connections and built in types for now, # they should be added when queries are generated. @@ -103,6 +104,83 @@ module Gitlab !enum_type[:name].in?(%w[__DirectiveLocation __TypeKind]) end end + + private # DO NOT CALL THESE METHODS IN TEMPLATES + + # Template methods + + def render_row(*values) + "| #{values.map { |val| val.to_s.squish }.join(' | ')} |" + end + + def render_name(object, owner = nil) + rendered_name = "`#{object[:name]}`" + rendered_name += ' **{warning-solid}**' if object[:is_deprecated] + rendered_name + end + + # Returns the object description. If the object has been deprecated, + # the deprecation reason will be returned in place of the description. + def render_description(object, owner = nil, context = :block) + owner = Array.wrap(owner) + return render_deprecation(object, owner, context) if object[:is_deprecated] + return if object[:description].blank? + + desc = object[:description].strip + desc += '.' unless desc.ends_with?('.') + desc + end + + def render_deprecation(object, owner, context) + deprecation = schema_deprecation(owner, object[:name]) + return deprecation.markdown(context: context) if deprecation + + reason = object[:deprecation_reason] || 'Use of this is deprecated.' + "**Deprecated:** #{reason}" + end + + def render_field_type(type) + "[`#{type[:info]}`](##{type[:name].downcase})" + end + + # Queries + + # returns the deprecation information for a field or argument + # See: Gitlab::Graphql::Deprecation + def schema_deprecation(type_name, field_name) + schema_member(type_name, field_name)&.deprecation + end + + # Return a part of the schema. + # + # This queries the Schema by owner and name to find: + # + # - fields (e.g. `schema_member('Query', 'currentUser')`) + # - arguments (e.g. `schema_member(['Query', 'project], 'fullPath')`) + def schema_member(type_name, field_name) + type_name = Array.wrap(type_name) + if type_name.size == 2 + arg_name = field_name + type_name, field_name = type_name + else + type_name = type_name.first + arg_name = nil + end + + return if type_name.nil? || field_name.nil? + + type = schema.types[type_name] + return unless type && type.kind.fields? + + field = type.fields[field_name] + return field if arg_name.nil? + + args = field.arguments + is_mutation = field.mutation && field.mutation <= ::Mutations::BaseMutation + args = args['input'].type.unwrap.arguments if is_mutation + + args[arg_name] + end end end end diff --git a/lib/gitlab/graphql/docs/renderer.rb b/lib/gitlab/graphql/docs/renderer.rb index 6abd56c89c6..497567f9389 100644 --- a/lib/gitlab/graphql/docs/renderer.rb +++ b/lib/gitlab/graphql/docs/renderer.rb @@ -10,17 +10,20 @@ module Gitlab # It uses graphql-docs helpers and schema parser, more information in https://github.com/gjtorikian/graphql-docs. # # Arguments: - # schema - the GraphQL schema definition. For GitLab should be: GitlabSchema.graphql_definition + # schema - the GraphQL schema definition. For GitLab should be: GitlabSchema # output_dir: The folder where the markdown files will be saved # template: The path of the haml template to be parsed class Renderer include Gitlab::Graphql::Docs::Helper + attr_reader :schema + def initialize(schema, output_dir:, template:) @output_dir = output_dir @template = template @layout = Haml::Engine.new(File.read(template)) - @parsed_schema = GraphQLDocs::Parser.new(schema, {}).parse + @parsed_schema = GraphQLDocs::Parser.new(schema.graphql_definition, {}).parse + @schema = schema end def contents diff --git a/lib/gitlab/graphql/docs/templates/default.md.haml b/lib/gitlab/graphql/docs/templates/default.md.haml index 847f1777b08..fe73297d0d9 100644 --- a/lib/gitlab/graphql/docs/templates/default.md.haml +++ b/lib/gitlab/graphql/docs/templates/default.md.haml @@ -27,7 +27,7 @@ \ - sorted_by_name(queries).each do |query| - = render_name_and_description(query) + = render_name_and_description(query, owner: 'Query') \ = render_return_type(query) - unless query[:arguments].empty? @@ -35,7 +35,7 @@ ~ "| Name | Type | Description |" ~ "| ---- | ---- | ----------- |" - sorted_by_name(query[:arguments]).each do |argument| - = render_field(argument) + = render_field(argument, query[:type][:name]) \ :plain @@ -58,7 +58,7 @@ ~ "| Field | Type | Description |" ~ "| ----- | ---- | ----------- |" - sorted_by_name(type[:fields]).each do |field| - = render_field(field) + = render_field(field, type[:name]) \ :plain @@ -79,7 +79,7 @@ ~ "| Value | Description |" ~ "| ----- | ----------- |" - sorted_by_name(enum[:values]).each do |value| - = render_enum_value(value) + = render_enum_value(enum, value) \ :plain @@ -121,12 +121,12 @@ \ - graphql_union_types.each do |type| - = render_name_and_description(type, 4) + = render_name_and_description(type, level: 4) \ One of: \ - - type[:possible_types].each do |type_name| - ~ "- [`#{type_name}`](##{type_name.downcase})" + - type[:possible_types].each do |member| + = render_union_member(member) \ :plain @@ -134,7 +134,7 @@ \ - graphql_interface_types.each do |type| - = render_name_and_description(type, 4) + = render_name_and_description(type, level: 4) \ Implementations: \ @@ -144,5 +144,5 @@ ~ "| Field | Type | Description |" ~ "| ----- | ---- | ----------- |" - sorted_by_name(type[:fields] + type[:connections]).each do |field| - = render_field(field) + = render_field(field, type[:name]) \ diff --git a/lib/gitlab/quick_actions/command_definition.rb b/lib/gitlab/quick_actions/command_definition.rb index b17a0208f95..8ce13db4c03 100644 --- a/lib/gitlab/quick_actions/command_definition.rb +++ b/lib/gitlab/quick_actions/command_definition.rb @@ -56,15 +56,18 @@ module Gitlab end def execute(context, arg) - return unless executable?(context) + return if noop? count_commands_executed_in(context) + return unless available?(context) + execute_block(action_block, context, arg) end def execute_message(context, arg) - return unless executable?(context) + return if noop? + return _('Could not apply %{name} command.') % { name: name } unless available?(context) if execution_message.respond_to?(:call) execute_block(execution_message, context, arg) @@ -101,10 +104,6 @@ module Gitlab private - def executable?(context) - !noop? && available?(context) - end - def count_commands_executed_in(context) return unless context.respond_to?(:commands_executed_count=) diff --git a/lib/tasks/gitlab/graphql.rake b/lib/tasks/gitlab/graphql.rake index 77377a7e0fd..27bba6aa307 100644 --- a/lib/tasks/gitlab/graphql.rake +++ b/lib/tasks/gitlab/graphql.rake @@ -110,7 +110,7 @@ namespace :gitlab do desc 'GitLab | GraphQL | Generate GraphQL docs' task compile_docs: [:environment, :enable_feature_flags] do - renderer = Gitlab::Graphql::Docs::Renderer.new(GitlabSchema.graphql_definition, render_options) + renderer = Gitlab::Graphql::Docs::Renderer.new(GitlabSchema, render_options) renderer.write @@ -119,7 +119,7 @@ namespace :gitlab do desc 'GitLab | GraphQL | Check if GraphQL docs are up to date' task check_docs: [:environment, :enable_feature_flags] do - renderer = Gitlab::Graphql::Docs::Renderer.new(GitlabSchema.graphql_definition, render_options) + renderer = Gitlab::Graphql::Docs::Renderer.new(GitlabSchema, render_options) doc = File.read(Rails.root.join(OUTPUT_DIR, 'index.md')) |