Commit d59d9774 authored by Stan Hu's avatar Stan Hu

Merge branch 'ajk-graphql-docs-see-doc-ref' into 'master'

Explicit handling of external documentation references

See merge request gitlab-org/gitlab!56704
parents 160d96a5 169e3c33
...@@ -23,10 +23,13 @@ module Mutations ...@@ -23,10 +23,13 @@ module Mutations
argument :color, GraphQL::STRING_TYPE, argument :color, GraphQL::STRING_TYPE,
required: false, required: false,
default_value: Label::DEFAULT_COLOR, default_value: Label::DEFAULT_COLOR,
see: {
'List of color keywords at mozilla.org' =>
'https://developer.mozilla.org/en-US/docs/Web/CSS/color_value#Color_keywords'
},
description: <<~DESC description: <<~DESC
The color of the label given in 6-digit hex notation with leading '#' sign The color of the label given in 6-digit hex notation with leading '#' sign
(for example, `#FFAABB`) or one of the CSS color names (for example, `#FFAABB`) or one of the CSS color names.
<https://developer.mozilla.org/en-US/docs/Web/CSS/color_value#Color_keywords>.
DESC DESC
authorize :admin_label authorize :admin_label
......
...@@ -4,10 +4,11 @@ module Types ...@@ -4,10 +4,11 @@ module Types
class BaseArgument < GraphQL::Schema::Argument class BaseArgument < GraphQL::Schema::Argument
include GitlabStyleDeprecations include GitlabStyleDeprecations
attr_reader :deprecation attr_reader :deprecation, :doc_reference
def initialize(*args, **kwargs, &block) def initialize(*args, **kwargs, &block)
@deprecation = gitlab_deprecation(kwargs) @deprecation = gitlab_deprecation(kwargs)
@doc_reference = kwargs.delete(:see)
super(*args, **kwargs, &block) super(*args, **kwargs, &block)
end end
......
...@@ -8,10 +8,11 @@ module Types ...@@ -8,10 +8,11 @@ module Types
DEFAULT_COMPLEXITY = 1 DEFAULT_COMPLEXITY = 1
attr_reader :deprecation attr_reader :deprecation, :doc_reference
def initialize(**kwargs, &block) def initialize(**kwargs, &block)
@calls_gitaly = !!kwargs.delete(:calls_gitaly) @calls_gitaly = !!kwargs.delete(:calls_gitaly)
@doc_reference = kwargs.delete(:see)
@constant_complexity = kwargs[:complexity].is_a?(Integer) && kwargs[:complexity] > 0 @constant_complexity = kwargs[:complexity].is_a?(Integer) && kwargs[:complexity] > 0
@requires_argument = !!kwargs.delete(:requires_argument) @requires_argument = !!kwargs.delete(:requires_argument)
@authorize = Array.wrap(kwargs.delete(:authorize)) @authorize = Array.wrap(kwargs.delete(:authorize))
......
---
title: Add external documentation references in GraphQL
merge_request: 56704
author:
type: changed
This diff is collapsed.
...@@ -267,7 +267,7 @@ module Gitlab ...@@ -267,7 +267,7 @@ module Gitlab
if deprecated?(object, owner) if deprecated?(object, owner)
render_deprecation(object, owner, context) render_deprecation(object, owner, context)
else else
render_description_of(object) render_description_of(object, owner, context)
end end
end end
...@@ -278,7 +278,7 @@ module Gitlab ...@@ -278,7 +278,7 @@ module Gitlab
deprecations.key?(key) deprecations.key?(key)
end end
def render_description_of(object) def render_description_of(object, owner, context = nil)
desc = if object[:is_edge] desc = if object[:is_edge]
base = object[:name].chomp('Edge') base = object[:name].chomp('Edge')
"The edge type for [`#{base}`](##{base.downcase})." "The edge type for [`#{base}`](##{base.downcase})."
...@@ -292,14 +292,31 @@ module Gitlab ...@@ -292,14 +292,31 @@ module Gitlab
return if desc.blank? return if desc.blank?
desc += '.' unless desc.ends_with?('.') desc += '.' unless desc.ends_with?('.')
see = doc_reference(object, owner)
desc += " #{see}" if see
desc += " (see [Connections](#connections))" if connection?(object) && context != :block
desc desc
end end
def doc_reference(object, owner)
field = schema_field(owner, object[:name]) if owner
return unless field
ref = field.try(:doc_reference)
return if ref.blank?
parts = ref.to_a.map do |(title, url)|
"[#{title.strip}](#{url.strip})"
end
"See #{parts.join(', ')}."
end
def render_deprecation(object, owner, context) def render_deprecation(object, owner, context)
buff = [] buff = []
deprecation = schema_deprecation(owner, object[:name]) deprecation = schema_deprecation(owner, object[:name])
buff << (deprecation&.original_description || render_description_of(object)) if context == :block buff << (deprecation&.original_description || render_description_of(object, owner)) if context == :block
buff << if deprecation buff << if deprecation
deprecation.markdown(context: context) deprecation.markdown(context: context)
else else
...@@ -382,6 +399,13 @@ module Gitlab ...@@ -382,6 +399,13 @@ module Gitlab
"Input type: `#{input_field[:type][:name]}`" "Input type: `#{input_field[:type][:name]}`"
end end
def schema_field(type_name, field_name)
type = schema.types[type_name]
return unless type && type.kind.fields?
type.fields[field_name]
end
def deprecations def deprecations
strong_memoize(:deprecations) do strong_memoize(:deprecations) do
mapping = {} mapping = {}
......
...@@ -150,6 +150,69 @@ RSpec.describe Gitlab::Graphql::Docs::Renderer do ...@@ -150,6 +150,69 @@ RSpec.describe Gitlab::Graphql::Docs::Renderer do
end end
end end
context 'when a field has a documentation reference' do
let(:type) do
wibble = Class.new(::Types::BaseObject) do
graphql_name 'Wibble'
field :x, ::GraphQL::INT_TYPE, null: false
end
Class.new(Types::BaseObject) do
graphql_name 'DocRefSpec'
description 'Testing doc refs'
field :foo,
type: GraphQL::STRING_TYPE,
null: false,
description: 'The foo.',
see: { 'A list of foos' => 'https://example.com/foos' }
field :bar,
type: GraphQL::STRING_TYPE,
null: false,
description: 'The bar.',
see: { 'A list of bars' => 'https://example.com/bars' } do
argument :barity, ::GraphQL::INT_TYPE, required: false, description: '?'
end
field :wibbles,
type: wibble.connection_type,
null: true,
description: 'The wibbles',
see: { 'wibblance' => 'https://example.com/wibbles' }
end
end
let(:section) do
<<~DOC
### `DocRefSpec`
Testing doc refs.
#### Fields
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="docrefspecfoo"></a>`foo` | [`String!`](#string) | The foo. See [A list of foos](https://example.com/foos). |
| <a id="docrefspecwibbles"></a>`wibbles` | [`WibbleConnection`](#wibbleconnection) | The wibbles. See [wibblance](https://example.com/wibbles). (see [Connections](#connections)) |
#### Fields with arguments
##### `DocRefSpec.bar`
The bar. See [A list of bars](https://example.com/bars).
Returns [`String!`](#string).
###### Arguments
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="docrefspecbarbarity"></a>`barity` | [`Int`](#int) | ?. |
DOC
end
it_behaves_like 'renders correctly as GraphQL documentation'
end
context 'when an argument is deprecated' do context 'when an argument is deprecated' do
let(:type) do let(:type) do
Class.new(Types::BaseObject) do Class.new(Types::BaseObject) do
......
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