aws-sdk-resources 2.0.0.pre
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/lib/aws-sdk-resources.rb +36 -0
- data/lib/aws-sdk-resources/batch.rb +100 -0
- data/lib/aws-sdk-resources/builder.rb +86 -0
- data/lib/aws-sdk-resources/builder_sources.rb +136 -0
- data/lib/aws-sdk-resources/collection.rb +137 -0
- data/lib/aws-sdk-resources/definition.rb +363 -0
- data/lib/aws-sdk-resources/documenter.rb +18 -0
- data/lib/aws-sdk-resources/documenter/base_operation_documenter.rb +269 -0
- data/lib/aws-sdk-resources/documenter/data_operation_documenter.rb +47 -0
- data/lib/aws-sdk-resources/documenter/enumerate_data_operation_documenter.rb +50 -0
- data/lib/aws-sdk-resources/documenter/enumerate_resource_operation_documenter.rb +69 -0
- data/lib/aws-sdk-resources/documenter/operation_documenter.rb +43 -0
- data/lib/aws-sdk-resources/documenter/reference_operation_documenter.rb +102 -0
- data/lib/aws-sdk-resources/documenter/resource_operation_documenter.rb +65 -0
- data/lib/aws-sdk-resources/documenter/waiter_operation_documenter.rb +81 -0
- data/lib/aws-sdk-resources/errors.rb +15 -0
- data/lib/aws-sdk-resources/operation_methods.rb +53 -0
- data/lib/aws-sdk-resources/operations.rb +294 -0
- data/lib/aws-sdk-resources/options.rb +23 -0
- data/lib/aws-sdk-resources/request.rb +39 -0
- data/lib/aws-sdk-resources/request_params.rb +225 -0
- data/lib/aws-sdk-resources/resource.rb +137 -0
- data/lib/aws-sdk-resources/source.rb +39 -0
- data/lib/aws-sdk-resources/validator.rb +152 -0
- data/lib/aws-sdk-resources/validator/context.rb +60 -0
- data/lib/aws-sdk-resources/validator/identifier_validator.rb +107 -0
- data/lib/aws-sdk-resources/validator/operation_validator.rb +352 -0
- data/lib/aws-sdk-resources/validator/rule.rb +45 -0
- data/lib/aws-sdk-resources/validator/shape_validator.rb +47 -0
- metadata +87 -0
@@ -0,0 +1,363 @@
|
|
1
|
+
require 'set'
|
2
|
+
|
3
|
+
module Aws
|
4
|
+
module Resources
|
5
|
+
|
6
|
+
# Given a resource definition document, a {Definition} can build a set
|
7
|
+
# of related resource classes.
|
8
|
+
class Definition
|
9
|
+
|
10
|
+
# @param [Hash] definition
|
11
|
+
# @option options [String] :source_path
|
12
|
+
def initialize(definition = {}, options = {})
|
13
|
+
@source = definition
|
14
|
+
@source_path = options[:source_path]
|
15
|
+
end
|
16
|
+
|
17
|
+
# @param [Module<Service>] namespace
|
18
|
+
# @return [void]
|
19
|
+
def apply(namespace)
|
20
|
+
build_resource_classes(namespace)
|
21
|
+
each_resource_class(namespace) do |resource, definition|
|
22
|
+
define_load(namespace, resource, definition['load'])
|
23
|
+
define_actions(namespace, resource, definition['actions'] || {})
|
24
|
+
define_batch_actions(namespace, resource, definition['batchActions'] || {})
|
25
|
+
define_waiters(namespace, resource, definition['waiters'] || {})
|
26
|
+
define_has_many(namespace, resource, definition['hasMany'] || {})
|
27
|
+
define_has_some(namespace, resource, definition['hasSome'] || {})
|
28
|
+
define_has_one(namespace, resource, definition['hasOne'] || {})
|
29
|
+
define_data_attributes(namespace, resource, definition['shape'])
|
30
|
+
define_subresources(namespace, resource, definition['subResources'] || {})
|
31
|
+
end
|
32
|
+
define_top_level_references(namespace)
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def build_resource_classes(namespace)
|
38
|
+
each_definition do |name, definition|
|
39
|
+
resource_class = Class.new(Resource)
|
40
|
+
resource_class.client_class = namespace::Client
|
41
|
+
resource_class.resource_name = name
|
42
|
+
(definition['identifiers'] || []).each do |identifier|
|
43
|
+
resource_class.add_identifier(underscore(identifier['name']))
|
44
|
+
end
|
45
|
+
namespace.const_set(name, resource_class)
|
46
|
+
unless name == 'Resource'
|
47
|
+
resource_class.const_set(:Batch, Class.new(Batch))
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def each_resource_class(namespace, &block)
|
53
|
+
each_definition do |name, definition|
|
54
|
+
yield(namespace.const_get(name), definition)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def define_subresources(namespace, parent, definition)
|
59
|
+
parent_name = parent.resource_name
|
60
|
+
identifiers = definition['identifiers'] || {}
|
61
|
+
(definition['resources'] || []).each do |child_name|
|
62
|
+
|
63
|
+
method_name = underscore(child_name.sub(/^#{parent_name}/, ''))
|
64
|
+
operation = subresource(namespace, child_name, identifiers)
|
65
|
+
parent.add_operation(method_name, operation)
|
66
|
+
|
67
|
+
method_name = underscore(parent_name)
|
68
|
+
operation = subresource(namespace, parent_name, identifiers.invert)
|
69
|
+
namespace.const_get(child_name).add_operation(method_name, operation)
|
70
|
+
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def subresource(namespace, type, identifiers)
|
75
|
+
Operations::ReferenceOperation.new(builder: define_builder(namespace, {
|
76
|
+
'type' => type,
|
77
|
+
'identifiers' => identifiers.map { |source, target|
|
78
|
+
{
|
79
|
+
'target' => target,
|
80
|
+
'sourceType' => 'identifier',
|
81
|
+
'source' => source,
|
82
|
+
}
|
83
|
+
}
|
84
|
+
}))
|
85
|
+
end
|
86
|
+
|
87
|
+
def define_top_level_references(namespace)
|
88
|
+
top_level = Set.new(resource_definitions.keys)
|
89
|
+
each_resource_class(namespace) do |resource, definition|
|
90
|
+
unless resource.identifiers.count == 1
|
91
|
+
top_level.delete(resource.resource_name)
|
92
|
+
end
|
93
|
+
((definition['subResources'] || {})['resources'] || {}).each do |child|
|
94
|
+
top_level.delete(child)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
top_level.each do |resource_name|
|
98
|
+
method_name = underscore(resource_name)
|
99
|
+
operation = subresource(namespace, resource_name, {})
|
100
|
+
namespace::Resource.add_operation(method_name, operation)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def define_batch_actions(namespace, resource, batch_actions)
|
105
|
+
batch_actions.each do |name, definition|
|
106
|
+
method_name = underscore(name)
|
107
|
+
operation = build_operation(namespace, resource, definition)
|
108
|
+
resource::Batch.add_operation(method_name, operation)
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def define_data_attributes(namespace, resource, shape_name)
|
113
|
+
return unless shape_name
|
114
|
+
shape = resource.client_class.api.shape_map.shape('shape' => shape_name)
|
115
|
+
shape.member_names.each do |member_name|
|
116
|
+
if
|
117
|
+
resource.identifiers.include?(member_name) ||
|
118
|
+
resource.instance_methods.include?(member_name)
|
119
|
+
then
|
120
|
+
next # some data attributes are duplicates to identifiers
|
121
|
+
else
|
122
|
+
resource.add_data_attribute(member_name)
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
def define_load(namespace, resource, definition)
|
128
|
+
return unless definition
|
129
|
+
resource.load_operation = Operations::DataOperation.new(
|
130
|
+
request: define_request(definition['request']),
|
131
|
+
path: underscore(definition['path']),
|
132
|
+
source: source(definition),
|
133
|
+
)
|
134
|
+
end
|
135
|
+
|
136
|
+
def define_actions(namespace, resource, actions)
|
137
|
+
actions.each do |name, action|
|
138
|
+
operation = build_operation(namespace, resource, action)
|
139
|
+
resource.add_operation(underscore(name), operation)
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
def define_waiters(namespace, resource, waiters)
|
144
|
+
waiters.each do |name, definition|
|
145
|
+
operation = build_waiter_operation(namespace, resource, definition)
|
146
|
+
resource.add_operation("wait_until_#{underscore(name)}", operation)
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
def build_operation(namespace, resource, definition)
|
151
|
+
type = operation_type(definition)
|
152
|
+
send("build_#{type}_operation", namespace, resource, definition)
|
153
|
+
end
|
154
|
+
|
155
|
+
def build_basic_operation(namespace, resource, definition)
|
156
|
+
Operations::Operation.new(
|
157
|
+
request: define_request(definition['request']),
|
158
|
+
source: source(definition)
|
159
|
+
)
|
160
|
+
end
|
161
|
+
|
162
|
+
def build_data_operation(namespace, resource, definition)
|
163
|
+
plural = definition['path'].include?('[')
|
164
|
+
source = source(definition)
|
165
|
+
if plural
|
166
|
+
Operations::EnumerateDataOperation.new(
|
167
|
+
request: define_request(definition['request']),
|
168
|
+
path: underscore(definition['path']),
|
169
|
+
source: source,
|
170
|
+
limit_key: limit_key(resource, definition)
|
171
|
+
)
|
172
|
+
else
|
173
|
+
Operations::DataOperation.new(
|
174
|
+
request: define_request(definition['request']),
|
175
|
+
path: underscore(definition['path']),
|
176
|
+
source: source
|
177
|
+
)
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
def build_resource_operation(namespace, resource, definition)
|
182
|
+
builder = define_builder(namespace, definition['resource'])
|
183
|
+
if path = definition['path']
|
184
|
+
source = underscore(path)
|
185
|
+
builder.sources << BuilderSources::ResponsePath.new(source, :data)
|
186
|
+
end
|
187
|
+
Operations::ResourceOperation.new(
|
188
|
+
request: define_request(definition['request']),
|
189
|
+
builder: builder,
|
190
|
+
source: source(definition)
|
191
|
+
)
|
192
|
+
end
|
193
|
+
|
194
|
+
def build_enumerate_resource_operation(namespace, resource, definition)
|
195
|
+
builder = define_builder(namespace, definition['resource'])
|
196
|
+
if path = definition['path']
|
197
|
+
source = underscore(path)
|
198
|
+
builder.sources << BuilderSources::ResponsePath.new(source, :data)
|
199
|
+
end
|
200
|
+
Operations::EnumerateResourceOperation.new(
|
201
|
+
request: define_request(definition['request']),
|
202
|
+
builder: builder,
|
203
|
+
source: source(definition),
|
204
|
+
limit_key: limit_key(resource, definition))
|
205
|
+
end
|
206
|
+
|
207
|
+
def build_waiter_operation(namespace, resource, definition)
|
208
|
+
Operations::WaiterOperation.new(
|
209
|
+
waiter_name: underscore(definition['waiterName']).to_sym,
|
210
|
+
waiter_params: request_params(definition['params']),
|
211
|
+
path: underscore(definition['path'])
|
212
|
+
)
|
213
|
+
end
|
214
|
+
|
215
|
+
def limit_key(resource, definition)
|
216
|
+
operation_name = definition['request']['operation']
|
217
|
+
paginators = resource.client_class.paginators
|
218
|
+
paginators.pager(operation_name).limit_key
|
219
|
+
end
|
220
|
+
|
221
|
+
def define_request(definition)
|
222
|
+
Request.new(
|
223
|
+
method_name: underscore(definition['operation']),
|
224
|
+
params: request_params(definition['params'] || [])
|
225
|
+
)
|
226
|
+
end
|
227
|
+
|
228
|
+
def request_params(params)
|
229
|
+
params.map do |definition|
|
230
|
+
param_class =
|
231
|
+
case definition['sourceType']
|
232
|
+
when 'identifier' then RequestParams::Identifier
|
233
|
+
when 'dataMember' then RequestParams::DataMember
|
234
|
+
when 'string' then RequestParams::String
|
235
|
+
when 'integer' then RequestParams::Integer
|
236
|
+
when 'boolean' then RequestParams::Boolean
|
237
|
+
else
|
238
|
+
msg = "unhandled param source type `#{definition['sourceType']}'"
|
239
|
+
raise ArgumentError, msg
|
240
|
+
end
|
241
|
+
source = definition['source']
|
242
|
+
param_class.new(
|
243
|
+
param_class.literal? ? source : underscore(source),
|
244
|
+
underscore(definition['target'])
|
245
|
+
)
|
246
|
+
end
|
247
|
+
end
|
248
|
+
|
249
|
+
def define_has_many(namespace, resource, has_many)
|
250
|
+
has_many.each do |name, definition|
|
251
|
+
operation = build_enumerate_resource_operation(namespace, resource, definition)
|
252
|
+
resource.add_operation(underscore(name), operation)
|
253
|
+
end
|
254
|
+
end
|
255
|
+
|
256
|
+
def define_has_some(namespace, resource, has_some)
|
257
|
+
has_some.each do |name, definition|
|
258
|
+
define_reference(namespace, resource, name, definition)
|
259
|
+
end
|
260
|
+
end
|
261
|
+
|
262
|
+
def define_has_one(namespace, resource, has_one)
|
263
|
+
has_one.each do |name, definition|
|
264
|
+
define_reference(namespace, resource, name, definition)
|
265
|
+
end
|
266
|
+
end
|
267
|
+
|
268
|
+
def define_reference(namespace, resource, name, definition)
|
269
|
+
builder = define_builder(namespace, definition['resource'])
|
270
|
+
if path = definition['path']
|
271
|
+
source = underscore(path)
|
272
|
+
builder.sources << BuilderSources::DataMember.new(source, :data)
|
273
|
+
end
|
274
|
+
operation = Operations::ReferenceOperation.new(
|
275
|
+
builder: builder,
|
276
|
+
source: source(definition))
|
277
|
+
resource.add_operation(underscore(name), operation)
|
278
|
+
end
|
279
|
+
|
280
|
+
def define_builder(namespace, definition)
|
281
|
+
builder = Builder.new(
|
282
|
+
resource_class: namespace.const_get(definition['type']),
|
283
|
+
sources: builder_sources(definition['identifiers'] || [])
|
284
|
+
)
|
285
|
+
delta = builder.resource_class.identifiers - builder.sources.map(&:target)
|
286
|
+
if delta.size == 0
|
287
|
+
# all identifiers provided
|
288
|
+
elsif delta.size == 1
|
289
|
+
# all but one provided, adding an Argument source
|
290
|
+
target = delta.first
|
291
|
+
builder.sources << BuilderSources::Argument.new(target)
|
292
|
+
else
|
293
|
+
msg = "too many unsourced identifiers: #{definition.inspect}"
|
294
|
+
raise Errors::DefinitionError, msg
|
295
|
+
end
|
296
|
+
builder
|
297
|
+
end
|
298
|
+
|
299
|
+
def builder_sources(sources)
|
300
|
+
sources.map do |definition|
|
301
|
+
source_class =
|
302
|
+
case definition['sourceType']
|
303
|
+
when 'identifier' then BuilderSources::Identifier
|
304
|
+
when 'dataMember' then BuilderSources::DataMember
|
305
|
+
when 'requestParameter' then BuilderSources::RequestParameter
|
306
|
+
when 'responsePath' then BuilderSources::ResponsePath
|
307
|
+
else
|
308
|
+
msg = "unhandled identifier source type `#{definition['sourceType']}'"
|
309
|
+
raise ArgumentError, msg
|
310
|
+
end
|
311
|
+
source_class.new(
|
312
|
+
underscore(definition['source']),
|
313
|
+
underscore(definition['target'])
|
314
|
+
)
|
315
|
+
end
|
316
|
+
end
|
317
|
+
|
318
|
+
def operation_type(action)
|
319
|
+
case action.keys.sort
|
320
|
+
when %w(request) then :basic
|
321
|
+
when %w(path request) then :data
|
322
|
+
when %w(request resource) then :resource
|
323
|
+
when %w(path request resource) then :resource
|
324
|
+
else
|
325
|
+
msg = "unhandled action: #{action.keys.inspect}"
|
326
|
+
raise Errors::DefinitionError, msg
|
327
|
+
end
|
328
|
+
end
|
329
|
+
|
330
|
+
def svc_definition
|
331
|
+
@source['service'] || {}
|
332
|
+
end
|
333
|
+
|
334
|
+
def resource_definitions
|
335
|
+
@source['resources'] || {}
|
336
|
+
end
|
337
|
+
|
338
|
+
def each_definition(&block)
|
339
|
+
yield('Resource', svc_definition)
|
340
|
+
resource_definitions.each(&block)
|
341
|
+
end
|
342
|
+
|
343
|
+
def underscore(str)
|
344
|
+
if str
|
345
|
+
str.gsub(/\w+/) { |part| Seahorse::Util.underscore(part) }
|
346
|
+
end
|
347
|
+
end
|
348
|
+
|
349
|
+
def pluralize(str)
|
350
|
+
underscore(str) + 's'
|
351
|
+
end
|
352
|
+
|
353
|
+
def source(definition)
|
354
|
+
if ENV['SOURCE']
|
355
|
+
Source.new(definition, @source_path)
|
356
|
+
else
|
357
|
+
nil
|
358
|
+
end
|
359
|
+
end
|
360
|
+
|
361
|
+
end
|
362
|
+
end
|
363
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
module Aws
|
4
|
+
module Resources
|
5
|
+
class Documenter
|
6
|
+
|
7
|
+
autoload :BaseOperationDocumenter, 'aws-sdk-resources/documenter/base_operation_documenter'
|
8
|
+
autoload :DataOperationDocumenter, 'aws-sdk-resources/documenter/data_operation_documenter'
|
9
|
+
autoload :EnumerateDataOperationDocumenter, 'aws-sdk-resources/documenter/enumerate_data_operation_documenter'
|
10
|
+
autoload :EnumerateResourceOperationDocumenter, 'aws-sdk-resources/documenter/enumerate_resource_operation_documenter'
|
11
|
+
autoload :OperationDocumenter, 'aws-sdk-resources/documenter/operation_documenter'
|
12
|
+
autoload :ReferenceOperationDocumenter, 'aws-sdk-resources/documenter/reference_operation_documenter'
|
13
|
+
autoload :ResourceOperationDocumenter, 'aws-sdk-resources/documenter/resource_operation_documenter'
|
14
|
+
autoload :WaiterOperationDocumenter, 'aws-sdk-resources/documenter/waiter_operation_documenter'
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,269 @@
|
|
1
|
+
module Aws
|
2
|
+
module Resources
|
3
|
+
class Documenter
|
4
|
+
class BaseOperationDocumenter
|
5
|
+
|
6
|
+
def initialize(yard_class, resource_class, operation_name, operation)
|
7
|
+
@yard_class = yard_class
|
8
|
+
@resource_class = resource_class
|
9
|
+
@resource_class_name = @resource_class.name.split('::').last
|
10
|
+
@operation_name = operation_name.to_s
|
11
|
+
@operation = operation
|
12
|
+
@source = @operation.source
|
13
|
+
if @operation.respond_to?(:request)
|
14
|
+
@api_request_name = @operation.request.method_name
|
15
|
+
@api_request = @resource_class.client_class.api.operation(@api_request_name)
|
16
|
+
@api_request_params = @operation.request.params
|
17
|
+
@request_operation_name = @operation.request.method_name.to_s
|
18
|
+
@called_operation = "Client##{@api_request_name}"
|
19
|
+
end
|
20
|
+
if @operation.respond_to?(:builder)
|
21
|
+
@builder = @operation.builder
|
22
|
+
@target_resource_class = @builder.resource_class
|
23
|
+
@target_resource_class_name = @target_resource_class.name.split('::').last
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# @return [YARD::CodeObject::ClassObject]
|
28
|
+
attr_reader :yard_class
|
29
|
+
|
30
|
+
# @return [Class<Resource>] Returns the resource class this
|
31
|
+
# operation belongs to.
|
32
|
+
attr_reader :resource_class
|
33
|
+
|
34
|
+
# @return [String] The name of this resource operation.
|
35
|
+
attr_reader :operation_name
|
36
|
+
|
37
|
+
# @return [String] Returns the name of the resource class being
|
38
|
+
# documented without the namespace prefix. Example:
|
39
|
+
#
|
40
|
+
# * Aws::S3::Resource => 'Resource'
|
41
|
+
# * Aws::S3::Bucket => 'Bucket'
|
42
|
+
#
|
43
|
+
attr_reader :resource_class_name
|
44
|
+
|
45
|
+
# @return [Class<Resource>,nil] Returns the class of the resource
|
46
|
+
# returned by invoking this operation. Returns `nil` if this operation
|
47
|
+
# does not return any resource objects.
|
48
|
+
attr_reader :target_resource_class
|
49
|
+
|
50
|
+
# @return [String,nil] Returns the name of the resource class
|
51
|
+
# returned by this operation. This is the base name of
|
52
|
+
# the class without a namespace prefix. Returns `nil` if this
|
53
|
+
# operation does not return any resource objects.
|
54
|
+
attr_reader :target_resource_class_name
|
55
|
+
|
56
|
+
# @return [String,nil] Returns the name of the API operation called
|
57
|
+
# on the client. Returns `nil` if this operation does not make
|
58
|
+
# any API requests.
|
59
|
+
attr_reader :api_request_name
|
60
|
+
|
61
|
+
# @return [Seahorse::Model::Operation,nil] Returns the model of the
|
62
|
+
# API operation called. Returns `nil` if this operation does not make
|
63
|
+
# any API requests.
|
64
|
+
attr_reader :api_request
|
65
|
+
|
66
|
+
# @return [Array<Resources::RequestParams::Base>, nil] Returns the
|
67
|
+
# parameters this operation binds to the made request. Returns `nil`
|
68
|
+
# if this operation does not make a request.
|
69
|
+
attr_reader :api_request_params
|
70
|
+
|
71
|
+
# @return [String,nil] Returns the `Client#operation_name` reference.
|
72
|
+
# This is useful for generating `@see` tags and `{links}`.
|
73
|
+
attr_reader :called_operation
|
74
|
+
|
75
|
+
# @return [Builder,nil] Returns the resource builder for
|
76
|
+
# this operation. Returns `nil` if this operation does not build
|
77
|
+
# and return resource objects.
|
78
|
+
attr_reader :builder
|
79
|
+
|
80
|
+
# @return [Source]
|
81
|
+
attr_reader :source
|
82
|
+
|
83
|
+
# Constructs and returns a new YARD method object for this operation.
|
84
|
+
# @return [YARD::CodeObject::MethodObject]
|
85
|
+
def method_object
|
86
|
+
m = YARD::CodeObjects::MethodObject.new(yard_class, operation_name)
|
87
|
+
m.scope = :instance
|
88
|
+
m.parameters = parameters
|
89
|
+
m.docstring = docstring
|
90
|
+
if source
|
91
|
+
m.source_type = :json
|
92
|
+
m.source = source.format
|
93
|
+
filename = source.file
|
94
|
+
filename = filename.match('(aws-sdk-core/apis/.+\.resources\.json)')[1]
|
95
|
+
m.add_file(filename, nil, true)
|
96
|
+
end
|
97
|
+
tags.each do |tag|
|
98
|
+
m.add_tag(tag)
|
99
|
+
end
|
100
|
+
m
|
101
|
+
end
|
102
|
+
|
103
|
+
private
|
104
|
+
|
105
|
+
def parameters
|
106
|
+
if option_tags.empty?
|
107
|
+
[]
|
108
|
+
else
|
109
|
+
[['params', '{}']]
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def docstring
|
114
|
+
''
|
115
|
+
end
|
116
|
+
|
117
|
+
def tags
|
118
|
+
(option_tags + example_tags + [return_tag] + see_also_tags).compact
|
119
|
+
end
|
120
|
+
|
121
|
+
# This method should be overridden in sub-classes to add YARD tags
|
122
|
+
# to the method code object.
|
123
|
+
# @return [Array<YARD::Tag>]
|
124
|
+
def example_tags
|
125
|
+
[]
|
126
|
+
end
|
127
|
+
|
128
|
+
def option_tags
|
129
|
+
if api_request && api_request.input
|
130
|
+
tags = []
|
131
|
+
required = api_request.input.required
|
132
|
+
members = api_request.input.members
|
133
|
+
members = members.sort_by { |name,_| required.include?(name) ? 0 : 1 }
|
134
|
+
members.each do |member_name, member_shape|
|
135
|
+
if api_request_params.any? { |p| p.target.match(/^#{member_name}\b/) }
|
136
|
+
next
|
137
|
+
end
|
138
|
+
docstring = member_shape.documentation
|
139
|
+
req = ' **`required`** — ' if required.include?(member_name)
|
140
|
+
tags << "@option params [#{param_type(member_shape)}] :#{member_name} #{req}#{docstring}"
|
141
|
+
end
|
142
|
+
tags = tags.join("\n")
|
143
|
+
YARD::DocstringParser.new.parse(tags).to_docstring.tags
|
144
|
+
else
|
145
|
+
[]
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
# If this operation makes an API request, then a `@see` tag is
|
150
|
+
# returned that references the client API operation.
|
151
|
+
# @return [Array<YARD::Tag>]
|
152
|
+
def see_also_tags
|
153
|
+
tags = []
|
154
|
+
tags += related_resource_operation_tags if target_resource_class
|
155
|
+
tags += called_operation_tag if called_operation
|
156
|
+
tags
|
157
|
+
end
|
158
|
+
|
159
|
+
def called_operation_tag
|
160
|
+
tag = "@see #{called_operation}"
|
161
|
+
YARD::DocstringParser.new.parse(tag).to_docstring.tags
|
162
|
+
end
|
163
|
+
|
164
|
+
def related_resource_operation_tags
|
165
|
+
tags = []
|
166
|
+
resource_class.operations.each do |name,op|
|
167
|
+
if
|
168
|
+
name.to_s != self.operation_name &&
|
169
|
+
op.respond_to?(:builder) &&
|
170
|
+
op.builder.resource_class == target_resource_class
|
171
|
+
then
|
172
|
+
tags << "@see ##{name}"
|
173
|
+
end
|
174
|
+
end
|
175
|
+
YARD::DocstringParser.new.parse(tags.sort.join("\n")).to_docstring.tags
|
176
|
+
end
|
177
|
+
|
178
|
+
def return_tag
|
179
|
+
if return_type == ['void'] && return_message.strip.empty?
|
180
|
+
nil
|
181
|
+
else
|
182
|
+
YARD::Tags::Tag.new(:return, return_message, return_type)
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
# The response object type for the @return tag. This must be overridden
|
187
|
+
# in sub-classes.
|
188
|
+
def return_type
|
189
|
+
raise NotImplementedError
|
190
|
+
end
|
191
|
+
|
192
|
+
# The message portion of the @return tag for this operation. This must
|
193
|
+
# be overidden in sub-classes.
|
194
|
+
def return_message
|
195
|
+
raise NotImplementedError
|
196
|
+
end
|
197
|
+
|
198
|
+
# Returns a suitable variable name for the resource class being
|
199
|
+
# documented:
|
200
|
+
#
|
201
|
+
# Aws::S3::Resource => 's3'
|
202
|
+
# Aws::S3::Bucket => 'bucket'
|
203
|
+
#
|
204
|
+
def variable_name
|
205
|
+
parts = resource_class.name.split('::')
|
206
|
+
(parts.last == 'Resource' ? parts[-2] : parts[-1]).downcase
|
207
|
+
end
|
208
|
+
|
209
|
+
def path_type
|
210
|
+
case path_shape
|
211
|
+
when Seahorse::Model::Shapes::Structure then 'Structure'
|
212
|
+
when Seahorse::Model::Shapes::List then 'Array'
|
213
|
+
when Seahorse::Model::Shapes::Map then 'Hash'
|
214
|
+
when Seahorse::Model::Shapes::String then 'String'
|
215
|
+
when Seahorse::Model::Shapes::Integer then 'Integer'
|
216
|
+
when Seahorse::Model::Shapes::Float then 'Float'
|
217
|
+
when Seahorse::Model::Shapes::Boolean then 'Boolean'
|
218
|
+
when Seahorse::Model::Shapes::Timestamp then 'Time'
|
219
|
+
when Seahorse::Model::Shapes::Blob then 'IO'
|
220
|
+
else
|
221
|
+
raise "unhandled shape class `#{path_shape.class.name}'"
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
def path_shape
|
226
|
+
resolve_shape(response_shape, @operation.path)
|
227
|
+
end
|
228
|
+
|
229
|
+
# Returns the output shape for the called operation.
|
230
|
+
def response_shape
|
231
|
+
api = resource_class.client_class.api
|
232
|
+
api.operation(@operation.request.method_name).output
|
233
|
+
end
|
234
|
+
|
235
|
+
def resolve_shape(shape, path)
|
236
|
+
if path != '$'
|
237
|
+
shape = path.scan(/\w+|\[.*?\]/).inject(shape) do |shape, part|
|
238
|
+
if part[0] == '['
|
239
|
+
shape.member
|
240
|
+
else
|
241
|
+
shape.member(part)
|
242
|
+
end
|
243
|
+
end
|
244
|
+
end
|
245
|
+
end
|
246
|
+
|
247
|
+
def param_type(shape)
|
248
|
+
case shape
|
249
|
+
when Seahorse::Model::Shapes::Blob then 'IO'
|
250
|
+
when Seahorse::Model::Shapes::Byte then 'String'
|
251
|
+
when Seahorse::Model::Shapes::Boolean then 'Boolean'
|
252
|
+
when Seahorse::Model::Shapes::Character then 'String'
|
253
|
+
when Seahorse::Model::Shapes::Double then 'Float'
|
254
|
+
when Seahorse::Model::Shapes::Float then 'Float'
|
255
|
+
when Seahorse::Model::Shapes::Integer then 'Integer'
|
256
|
+
when Seahorse::Model::Shapes::List then 'Array'
|
257
|
+
when Seahorse::Model::Shapes::Long then 'Integer'
|
258
|
+
when Seahorse::Model::Shapes::Map then 'Hash'
|
259
|
+
when Seahorse::Model::Shapes::String then 'String'
|
260
|
+
when Seahorse::Model::Shapes::Structure then 'Hash'
|
261
|
+
when Seahorse::Model::Shapes::Timestamp then 'Time'
|
262
|
+
else raise 'unhandled type'
|
263
|
+
end
|
264
|
+
end
|
265
|
+
|
266
|
+
end
|
267
|
+
end
|
268
|
+
end
|
269
|
+
end
|