Commit d1397e5b authored by Alex Kalderimis's avatar Alex Kalderimis

Render deprecations for arguments correctly

This uses the schema to pre-compute a lookup table for deprecation
information.

Fixes https://gitlab.com/gitlab-org/gitlab/-/issues/326302
parent c997c886
......@@ -242,7 +242,7 @@ module Gitlab
def render_name(object, owner = nil)
rendered_name = "`#{object[:name]}`"
rendered_name += ' **{warning-solid}**' if object[:is_deprecated]
rendered_name += ' **{warning-solid}**' if deprecated?(object, owner)
return rendered_name unless owner
......@@ -255,13 +255,20 @@ module Gitlab
# 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)
if object[:is_deprecated]
if deprecated?(object, owner)
render_deprecation(object, owner, context)
else
render_description_of(object)
end
end
def deprecated?(object, owner)
return true if object[:is_deprecated] # only populated for fields, not arguments!
key = [*Array.wrap(owner), object[:name]].join('.')
deprecations.key?(key)
end
def render_description_of(object)
desc = if object[:is_edge]
base = object[:name].chomp('Edge')
......@@ -280,7 +287,6 @@ module Gitlab
end
def render_deprecation(object, owner, context)
owner = Array.wrap(owner)
buff = []
deprecation = schema_deprecation(owner, object[:name])
......@@ -356,38 +362,8 @@ module Gitlab
# 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]
key = [*Array.wrap(type_name), field_name].join('.')
deprecations[key]
end
def render_input_type(query)
......@@ -396,6 +372,25 @@ module Gitlab
"Input type: `#{input_field[:type][:name]}`."
end
def deprecations
strong_memoize(:deprecations) do
mapping = {}
schema.types.each do |type_name, type|
next unless type.kind.fields?
type.fields.each do |field_name, field|
mapping["#{type_name}.#{field_name}"] = field.try(:deprecation)
field.arguments.each do |arg_name, arg|
mapping["#{type_name}.#{field_name}.#{arg_name}"] = arg.try(:deprecation)
end
end
end
mapping.compact
end
end
end
end
end
......
......@@ -150,6 +150,43 @@ RSpec.describe Gitlab::Graphql::Docs::Renderer do
end
end
context 'when an argument is deprecated' do
let(:type) do
Class.new(Types::BaseObject) do
graphql_name 'DeprecatedTest'
description 'A thing we used to use, but no longer support'
field :foo,
type: GraphQL::STRING_TYPE,
null: false,
description: 'A description.' do
argument :foo_arg, GraphQL::STRING_TYPE,
required: false,
description: 'The argument.',
deprecated: { reason: 'Bad argument', milestone: '101.2' }
end
end
end
let(:section) do
<<~DOC
##### `DeprecatedTest.foo`
A description.
Returns [`String!`](#string).
###### Arguments
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="deprecatedtestfoofooarg"></a>`fooArg` **{warning-solid}** | [`String`](#string) | **Deprecated** in 101.2. Bad argument. |
DOC
end
it_behaves_like 'renders correctly as GraphQL documentation'
end
context 'when a field is deprecated' do
let(:type) do
Class.new(Types::BaseObject) do
......@@ -338,11 +375,31 @@ RSpec.describe Gitlab::Graphql::Docs::Renderer do
required: true,
description: 'How much prettier?'
mutation.argument :pulchritude,
type: GraphQL::FLOAT_TYPE,
required: false,
description: 'How much prettier?',
deprecated: {
reason: :renamed,
replacement: 'prettinessFactor',
milestone: '72.34'
}
mutation.field :everything,
type: GraphQL::STRING_TYPE,
null: true,
description: 'What we made prettier.'
mutation.field :omnis,
type: GraphQL::STRING_TYPE,
null: true,
description: 'What we made prettier.',
deprecated: {
reason: :renamed,
replacement: 'everything',
milestone: '72.34'
}
mutation
end
......@@ -365,6 +422,7 @@ RSpec.describe Gitlab::Graphql::Docs::Renderer do
| ---- | ---- | ----------- |
| <a id="mutationmakeitprettyclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
| <a id="mutationmakeitprettyprettinessfactor"></a>`prettinessFactor` | [`Float!`](#float) | How much prettier?. |
| <a id="mutationmakeitprettypulchritude"></a>`pulchritude` **{warning-solid}** | [`Float`](#float) | **Deprecated:** This was renamed. Please use `prettinessFactor`. Deprecated in 72.34. |
#### Fields
......@@ -373,6 +431,7 @@ RSpec.describe Gitlab::Graphql::Docs::Renderer do
| <a id="mutationmakeitprettyclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
| <a id="mutationmakeitprettyerrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
| <a id="mutationmakeitprettyeverything"></a>`everything` | [`String`](#string) | What we made prettier. |
| <a id="mutationmakeitprettyomnis"></a>`omnis` **{warning-solid}** | [`String`](#string) | **Deprecated:** This was renamed. Please use `everything`. Deprecated in 72.34. |
DOC
end
end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment