summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/feature.rb8
-rw-r--r--lib/gitlab/ci/reports/codequality_reports.rb7
-rw-r--r--lib/gitlab/ci/reports/codequality_reports_comparer.rb5
-rw-r--r--lib/gitlab/graphql/docs/helper.rb134
-rw-r--r--lib/gitlab/graphql/docs/renderer.rb7
-rw-r--r--lib/gitlab/graphql/docs/templates/default.md.haml18
-rw-r--r--lib/gitlab/quick_actions/command_definition.rb11
-rw-r--r--lib/tasks/gitlab/graphql.rake4
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'))