aws-sdk-code-generator 0.1.0.pre → 0.2.4.pre
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/lib/aws-sdk-code-generator/api.rb +150 -0
- data/lib/aws-sdk-code-generator/apply_docs.rb +15 -2
- data/lib/aws-sdk-code-generator/client_constructor.rb +39 -0
- data/lib/aws-sdk-code-generator/client_operation_documentation.rb +282 -0
- data/lib/aws-sdk-code-generator/client_operation_list.rb +148 -0
- data/lib/aws-sdk-code-generator/client_response_structure_example.rb +115 -0
- data/lib/aws-sdk-code-generator/code_builder.rb +146 -133
- data/lib/aws-sdk-code-generator/crosslink.rb +42 -0
- data/lib/aws-sdk-code-generator/docstring.rb +199 -0
- data/lib/aws-sdk-code-generator/error_list.rb +77 -0
- data/lib/aws-sdk-code-generator/errors.rb +2 -0
- data/lib/aws-sdk-code-generator/eventstream_example.rb +220 -0
- data/lib/aws-sdk-code-generator/gem_builder.rb +42 -25
- data/lib/aws-sdk-code-generator/hash_formatter.rb +5 -2
- data/lib/aws-sdk-code-generator/helper.rb +86 -119
- data/lib/aws-sdk-code-generator/plugin_list.rb +147 -0
- data/lib/aws-sdk-code-generator/resource_action.rb +69 -0
- data/lib/aws-sdk-code-generator/resource_action_code.rb +57 -0
- data/lib/aws-sdk-code-generator/resource_association.rb +37 -0
- data/lib/aws-sdk-code-generator/resource_attribute.rb +76 -0
- data/lib/aws-sdk-code-generator/resource_batch_action.rb +56 -0
- data/lib/aws-sdk-code-generator/resource_batch_action_code.rb +136 -0
- data/lib/aws-sdk-code-generator/resource_batch_action_documentation.rb +108 -0
- data/lib/aws-sdk-code-generator/resource_batch_builder.rb +212 -0
- data/lib/aws-sdk-code-generator/resource_builder.rb +48 -0
- data/lib/aws-sdk-code-generator/resource_client_request.rb +62 -0
- data/lib/aws-sdk-code-generator/resource_client_request_documentation.rb +81 -0
- data/lib/aws-sdk-code-generator/resource_client_request_params.rb +86 -0
- data/lib/aws-sdk-code-generator/resource_data_method.rb +60 -0
- data/lib/aws-sdk-code-generator/resource_has_association.rb +117 -0
- data/lib/aws-sdk-code-generator/resource_has_many_association.rb +52 -0
- data/lib/aws-sdk-code-generator/resource_has_many_association_code.rb +76 -0
- data/lib/aws-sdk-code-generator/resource_identifier.rb +44 -0
- data/lib/aws-sdk-code-generator/resource_identifiers_method.rb +29 -0
- data/lib/aws-sdk-code-generator/resource_load_method.rb +68 -0
- data/lib/aws-sdk-code-generator/resource_method.rb +22 -0
- data/lib/aws-sdk-code-generator/resource_skip_params.rb +36 -0
- data/lib/aws-sdk-code-generator/resource_value_source.rb +68 -0
- data/lib/aws-sdk-code-generator/resource_waiter.rb +80 -0
- data/lib/aws-sdk-code-generator/service.rb +30 -7
- data/lib/aws-sdk-code-generator/shared_example.rb +131 -0
- data/lib/aws-sdk-code-generator/syntax_example.rb +60 -0
- data/lib/aws-sdk-code-generator/syntax_example_hash.rb +174 -0
- data/lib/aws-sdk-code-generator/underscore.rb +10 -5
- data/lib/aws-sdk-code-generator/view.rb +33 -0
- data/lib/aws-sdk-code-generator/views/apig_endpoint_class.rb +25 -0
- data/lib/aws-sdk-code-generator/views/apig_readme.rb +32 -0
- data/lib/aws-sdk-code-generator/views/async_client_class.rb +68 -0
- data/lib/aws-sdk-code-generator/views/authorizer_class.rb +17 -0
- data/lib/aws-sdk-code-generator/views/client_api_module.rb +602 -0
- data/lib/aws-sdk-code-generator/views/client_class.rb +93 -0
- data/lib/aws-sdk-code-generator/views/docstring.rb +27 -0
- data/lib/aws-sdk-code-generator/views/errors_module.rb +32 -0
- data/lib/aws-sdk-code-generator/views/event_streams_module.rb +149 -0
- data/lib/aws-sdk-code-generator/views/features/env.rb +9 -0
- data/lib/aws-sdk-code-generator/views/features/smoke.rb +52 -0
- data/lib/aws-sdk-code-generator/views/features/smoke_step_definitions.rb +26 -0
- data/lib/aws-sdk-code-generator/views/features/step_definitions.rb +6 -2
- data/lib/aws-sdk-code-generator/views/gemspec.rb +39 -5
- data/lib/aws-sdk-code-generator/views/resource_class.rb +122 -0
- data/lib/aws-sdk-code-generator/views/root_resource_class.rb +58 -0
- data/lib/aws-sdk-code-generator/views/service_module.rb +38 -14
- data/lib/aws-sdk-code-generator/views/spec/spec_helper.rb +9 -0
- data/lib/aws-sdk-code-generator/views/types_module.rb +329 -0
- data/lib/aws-sdk-code-generator/views/version.rb +2 -0
- data/lib/aws-sdk-code-generator/views/waiters_module.rb +37 -0
- data/lib/aws-sdk-code-generator/views.rb +2 -0
- data/lib/aws-sdk-code-generator/waiter.rb +95 -0
- data/lib/aws-sdk-code-generator/yard_option_tag.rb +43 -0
- data/lib/aws-sdk-code-generator.rb +68 -75
- data/templates/apig_endpoint_class.mustache +16 -0
- data/templates/apig_readme.mustache +62 -0
- data/templates/async_client_class.mustache +125 -0
- data/templates/authorizer_class.mustache +37 -0
- data/templates/client_api_module.mustache +106 -0
- data/templates/client_class.mustache +295 -0
- data/templates/code.mustache +4 -0
- data/templates/documentation.mustache +4 -0
- data/templates/errors_module.mustache +70 -0
- data/templates/event_streams_module.mustache +76 -0
- data/templates/features/env.mustache +15 -0
- data/templates/features/smoke.mustache +22 -0
- data/templates/features/smoke_step_definitions.mustache +31 -0
- data/templates/features/step_definitions.mustache +13 -0
- data/templates/gemspec.mustache +31 -0
- data/templates/license.txt +202 -0
- data/templates/method.mustache +7 -0
- data/templates/resource_class.mustache +304 -0
- data/templates/root_resource_class.mustache +51 -0
- data/templates/service_module.mustache +58 -0
- data/templates/spec/spec_helper.mustache +15 -0
- data/templates/types_module.mustache +53 -0
- data/templates/version.mustache +1 -0
- data/templates/waiters_module.mustache +112 -0
- metadata +115 -70
- data/lib/aws-sdk-code-generator/dsl/access_control_statement.rb +0 -23
- data/lib/aws-sdk-code-generator/dsl/attribute_accessor.rb +0 -43
- data/lib/aws-sdk-code-generator/dsl/attribute_reader.rb +0 -11
- data/lib/aws-sdk-code-generator/dsl/attribute_writer.rb +0 -11
- data/lib/aws-sdk-code-generator/dsl/autoload_statement.rb +0 -15
- data/lib/aws-sdk-code-generator/dsl/block_param.rb +0 -11
- data/lib/aws-sdk-code-generator/dsl/class.rb +0 -27
- data/lib/aws-sdk-code-generator/dsl/code_literal.rb +0 -66
- data/lib/aws-sdk-code-generator/dsl/code_object.rb +0 -33
- data/lib/aws-sdk-code-generator/dsl/docstring.rb +0 -36
- data/lib/aws-sdk-code-generator/dsl/eigenclass.rb +0 -15
- data/lib/aws-sdk-code-generator/dsl/extend_statement.rb +0 -12
- data/lib/aws-sdk-code-generator/dsl/formatter.rb +0 -25
- data/lib/aws-sdk-code-generator/dsl/include_statement.rb +0 -17
- data/lib/aws-sdk-code-generator/dsl/main.rb +0 -105
- data/lib/aws-sdk-code-generator/dsl/method.rb +0 -108
- data/lib/aws-sdk-code-generator/dsl/module.rb +0 -167
- data/lib/aws-sdk-code-generator/dsl/option_tag.rb +0 -36
- data/lib/aws-sdk-code-generator/dsl/param.rb +0 -43
- data/lib/aws-sdk-code-generator/dsl/param_list.rb +0 -38
- data/lib/aws-sdk-code-generator/dsl/return_tag.rb +0 -19
- data/lib/aws-sdk-code-generator/dsl/tag_default.rb +0 -20
- data/lib/aws-sdk-code-generator/dsl/tag_docstring.rb +0 -27
- data/lib/aws-sdk-code-generator/dsl/tag_type.rb +0 -18
- data/lib/aws-sdk-code-generator/generators/client_api_module.rb +0 -334
- data/lib/aws-sdk-code-generator/generators/client_class.rb +0 -389
- data/lib/aws-sdk-code-generator/generators/client_operation_documentation.rb +0 -166
- data/lib/aws-sdk-code-generator/generators/errors_module.rb +0 -25
- data/lib/aws-sdk-code-generator/generators/resource/action.rb +0 -88
- data/lib/aws-sdk-code-generator/generators/resource/batch_builder.rb +0 -211
- data/lib/aws-sdk-code-generator/generators/resource/builder.rb +0 -50
- data/lib/aws-sdk-code-generator/generators/resource/client_getter.rb +0 -15
- data/lib/aws-sdk-code-generator/generators/resource/client_request.rb +0 -49
- data/lib/aws-sdk-code-generator/generators/resource/client_request_docs.rb +0 -97
- data/lib/aws-sdk-code-generator/generators/resource/client_request_params.rb +0 -88
- data/lib/aws-sdk-code-generator/generators/resource/collection_class.rb +0 -180
- data/lib/aws-sdk-code-generator/generators/resource/data_attribute_getter.rb +0 -24
- data/lib/aws-sdk-code-generator/generators/resource/data_loaded_method.rb +0 -18
- data/lib/aws-sdk-code-generator/generators/resource/data_method.rb +0 -49
- data/lib/aws-sdk-code-generator/generators/resource/exists_method.rb +0 -29
- data/lib/aws-sdk-code-generator/generators/resource/extract_identifier_method.rb +0 -32
- data/lib/aws-sdk-code-generator/generators/resource/has_association.rb +0 -101
- data/lib/aws-sdk-code-generator/generators/resource/has_many_association.rb +0 -108
- data/lib/aws-sdk-code-generator/generators/resource/identifier_getter.rb +0 -26
- data/lib/aws-sdk-code-generator/generators/resource/identifiers_method.rb +0 -28
- data/lib/aws-sdk-code-generator/generators/resource/initialize_method.rb +0 -67
- data/lib/aws-sdk-code-generator/generators/resource/load_method.rb +0 -65
- data/lib/aws-sdk-code-generator/generators/resource/value_source.rb +0 -68
- data/lib/aws-sdk-code-generator/generators/resource/waiter_method.rb +0 -61
- data/lib/aws-sdk-code-generator/generators/resource_class.rb +0 -325
- data/lib/aws-sdk-code-generator/generators/response_structure_example.rb +0 -83
- data/lib/aws-sdk-code-generator/generators/root_resource_class.rb +0 -42
- data/lib/aws-sdk-code-generator/generators/service_documentation.rb +0 -64
- data/lib/aws-sdk-code-generator/generators/shared_example.rb +0 -132
- data/lib/aws-sdk-code-generator/generators/structure_type_class.rb +0 -95
- data/lib/aws-sdk-code-generator/generators/syntax_example.rb +0 -169
- data/lib/aws-sdk-code-generator/generators/types_module.rb +0 -52
- data/lib/aws-sdk-code-generator/generators/waiter_class.rb +0 -62
- data/lib/aws-sdk-code-generator/generators/waiters_module.rb +0 -20
@@ -0,0 +1,56 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module AwsSdkCodeGenerator
|
4
|
+
class ResourceBatchAction
|
5
|
+
class << self
|
6
|
+
|
7
|
+
# @return [Array<ResourceMethod>]
|
8
|
+
def build_list(resource_name, resource, api)
|
9
|
+
resource.fetch('batchActions', {}).map do |name, action|
|
10
|
+
method_name = build_method_name(name, action)
|
11
|
+
ResourceMethod.new.tap do |m|
|
12
|
+
m.method_name = method_name
|
13
|
+
m.arguments = 'options = {}'
|
14
|
+
m.code = code(action, api)
|
15
|
+
m.documentation = docs(method_name, resource_name, action, api)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def code(action, api)
|
23
|
+
ResourceBatchActionCode.new(action: action, api: api).build
|
24
|
+
end
|
25
|
+
|
26
|
+
def docs(method_name, resource_name, action, api)
|
27
|
+
ResourceBatchActionDocumentation.new(
|
28
|
+
method_name: method_name,
|
29
|
+
var_name: Underscore.underscore(resource_name),
|
30
|
+
action: action,
|
31
|
+
api: api
|
32
|
+
).build
|
33
|
+
end
|
34
|
+
|
35
|
+
def build_method_name(name, action)
|
36
|
+
method_name = "batch_" + Underscore.underscore(name)
|
37
|
+
method_name += '!' if dangerous?(name, action)
|
38
|
+
method_name
|
39
|
+
end
|
40
|
+
|
41
|
+
def dangerous?(name, action)
|
42
|
+
if
|
43
|
+
name.match(/delete/i) ||
|
44
|
+
name.match(/terminate/i) ||
|
45
|
+
action['request']['operation'].match(/delete/i) ||
|
46
|
+
action['request']['operation'].match(/terminate/i)
|
47
|
+
then
|
48
|
+
true
|
49
|
+
else
|
50
|
+
false
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,136 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module AwsSdkCodeGenerator
|
4
|
+
class ResourceBatchActionCode
|
5
|
+
|
6
|
+
def initialize(options)
|
7
|
+
@action = options.fetch(:action)
|
8
|
+
@api = options.fetch(:api)
|
9
|
+
compute_params
|
10
|
+
end
|
11
|
+
|
12
|
+
# @return [String]
|
13
|
+
def build
|
14
|
+
parts = []
|
15
|
+
parts << 'batch_enum.each do |batch|'
|
16
|
+
parts << initialize_params
|
17
|
+
parts << apply_params_per_batch
|
18
|
+
parts << " batch[0].client.#{client_method}(params)"
|
19
|
+
parts << 'end'
|
20
|
+
parts << 'nil'
|
21
|
+
parts.join("\n").rstrip
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def compute_params
|
27
|
+
@batch_obj = {}
|
28
|
+
@per_batch = {}
|
29
|
+
@action_prefix = false
|
30
|
+
@action['request']['params'].each do |param|
|
31
|
+
if param['target'].include?('[')
|
32
|
+
parts = param['target'].split('[')
|
33
|
+
pair = parts[0].split('.')
|
34
|
+
if pair.length > 1
|
35
|
+
@action_prefix = pair.first
|
36
|
+
end
|
37
|
+
batch_name = pair.last
|
38
|
+
batch_param = underscore(parts[1].sub(/.*?\./, ''))
|
39
|
+
batch_param = batch_param == "" ? underscore(param['name']) : batch_param
|
40
|
+
(@batch_obj[batch_name] ||= []) << {
|
41
|
+
batch_param.to_sym => underscore(param['name'] || param['path'])
|
42
|
+
}
|
43
|
+
else
|
44
|
+
@per_batch[param['target']] = underscore(param['name'])
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def client_method
|
50
|
+
Underscore.underscore(@action['request']['operation'])
|
51
|
+
end
|
52
|
+
|
53
|
+
def initialize_params
|
54
|
+
param_block = []
|
55
|
+
param_block << " params = Aws::Util.copy_hash(options)"
|
56
|
+
param_block << apply_param_hash
|
57
|
+
param_block.join("\n")
|
58
|
+
end
|
59
|
+
|
60
|
+
def apply_param_hash
|
61
|
+
block = []
|
62
|
+
@per_batch.each do |key, value|
|
63
|
+
block << " params[:#{underscore(key)}] = batch[0].#{value}"
|
64
|
+
end
|
65
|
+
if @action_prefix
|
66
|
+
action = underscore(@action_prefix)
|
67
|
+
block << " params[:#{action}] ||= {}"
|
68
|
+
@batch_obj.keys.each do |key|
|
69
|
+
block << " params[:#{action}][:#{underscore(key)}] ||= []"
|
70
|
+
end
|
71
|
+
else
|
72
|
+
@batch_obj.keys.each {|key| block << " params[:#{underscore(key)}] ||= []"}
|
73
|
+
end
|
74
|
+
block.join("\n")
|
75
|
+
end
|
76
|
+
|
77
|
+
def apply_params_per_batch
|
78
|
+
each_batch = []
|
79
|
+
each_batch << " batch.each do |item|"
|
80
|
+
@batch_obj.each do |key, value|
|
81
|
+
hash = {}
|
82
|
+
value.each do |v|
|
83
|
+
param, identifier = v.first
|
84
|
+
hash[param.to_sym] = "item.#{identifier}"
|
85
|
+
end
|
86
|
+
first_line = @action_prefix ? " params[:#{underscore(@action_prefix)}][:#{underscore(key)}] << "
|
87
|
+
: " params[:#{underscore(key)}] << "
|
88
|
+
if list_of_string?(key, @action['request']['operation'])
|
89
|
+
_, v = hash.first
|
90
|
+
each_batch << first_line + v
|
91
|
+
else
|
92
|
+
each_batch << first_line + "{"
|
93
|
+
# hashformatter treats this as inline, need extra indent
|
94
|
+
indent_count = hash.size == 1 ? 3 : 2
|
95
|
+
each_batch << indent_helper(HashFormatter.new(wrap: false).format(hash), indent_count)
|
96
|
+
each_batch << " }"
|
97
|
+
end
|
98
|
+
end
|
99
|
+
each_batch << " end"
|
100
|
+
each_batch.join("\n")
|
101
|
+
end
|
102
|
+
|
103
|
+
def indent_helper(lines, count)
|
104
|
+
block = []
|
105
|
+
lines.split("\n").each do |line|
|
106
|
+
next if line.strip == ""
|
107
|
+
block << " " * count + line
|
108
|
+
end
|
109
|
+
block.join("\n")
|
110
|
+
end
|
111
|
+
|
112
|
+
def underscore(str)
|
113
|
+
Underscore.underscore(str)
|
114
|
+
end
|
115
|
+
|
116
|
+
def list_of_string?(member, operation_name)
|
117
|
+
operation_shape = @api['operations'][operation_name]
|
118
|
+
input_shape = @api['shapes'][operation_shape['input']['shape']]
|
119
|
+
|
120
|
+
members = input_shape['type'] == 'structure' ? 'members' : 'member'
|
121
|
+
if @action_prefix
|
122
|
+
prefix_shape_ref = input_shape[members][@action_prefix]
|
123
|
+
_, prefix_shape = Api.resolve(prefix_shape_ref, @api)
|
124
|
+
prefix_members = prefix_shape['type'] == 'structure' ? 'members' : 'member'
|
125
|
+
member_shape_ref = prefix_shape[prefix_members][member]
|
126
|
+
else
|
127
|
+
member_shape_ref = input_shape[members][member]
|
128
|
+
end
|
129
|
+
_, shape = Api.resolve(member_shape_ref, @api)
|
130
|
+
return false unless shape['type'] == 'list'
|
131
|
+
_, item_shape = Api.resolve(shape['member'], @api)
|
132
|
+
item_shape['type'] == 'string'
|
133
|
+
end
|
134
|
+
|
135
|
+
end
|
136
|
+
end
|
@@ -0,0 +1,108 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module AwsSdkCodeGenerator
|
4
|
+
class ResourceBatchActionDocumentation
|
5
|
+
|
6
|
+
def initialize(options)
|
7
|
+
@var_name = options.fetch(:var_name)
|
8
|
+
@method_name = options.fetch(:method_name)
|
9
|
+
@action = options.fetch(:action)
|
10
|
+
@api = options.fetch(:api)
|
11
|
+
compute_params
|
12
|
+
end
|
13
|
+
|
14
|
+
# @return [String]
|
15
|
+
def build
|
16
|
+
Docstring.join_docstrings([
|
17
|
+
request_syntax_example,
|
18
|
+
'# @param options ({})',
|
19
|
+
option_tags,
|
20
|
+
"# @return [void]",
|
21
|
+
], block_comment: false, separator: false)
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def request_syntax_example
|
27
|
+
if input_ref
|
28
|
+
SyntaxExample.new(
|
29
|
+
api: @api,
|
30
|
+
shape: input_shape,
|
31
|
+
method_name: @method_name,
|
32
|
+
receiver: @var_name,
|
33
|
+
resp_var: nil,
|
34
|
+
skip: skip_params
|
35
|
+
).format
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def skip_params
|
40
|
+
skip = []
|
41
|
+
if @action_prefix
|
42
|
+
skip << @action_prefix
|
43
|
+
else
|
44
|
+
skip += @per_batch.keys
|
45
|
+
skip += @batch_obj.keys
|
46
|
+
end
|
47
|
+
skip + ResourceSkipParams.compute(input_shape, @action['request'])
|
48
|
+
end
|
49
|
+
|
50
|
+
def option_tags
|
51
|
+
skip = skip_params
|
52
|
+
if input_shape = Api.shape(input_ref, @api)
|
53
|
+
input_shape['members'].map do |member_name, member_ref|
|
54
|
+
if skip.include?(member_name)
|
55
|
+
nil # skipped
|
56
|
+
else
|
57
|
+
YardOptionTag.new(
|
58
|
+
name: Underscore.underscore(member_name),
|
59
|
+
required: input_shape.fetch('required', []).include?(member_name),
|
60
|
+
ruby_type: Api.ruby_input_type(member_ref, @api),
|
61
|
+
docstring: Docstring.html_to_markdown(Api.docstring(member_ref, @api)),
|
62
|
+
).to_str
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def input_ref
|
69
|
+
@api['operations'][@action['request']['operation']]['input']
|
70
|
+
end
|
71
|
+
|
72
|
+
def input_shape
|
73
|
+
Api.shape(input_ref, @api)
|
74
|
+
end
|
75
|
+
|
76
|
+
def compute_params
|
77
|
+
@batch_obj = {}
|
78
|
+
@per_batch = {}
|
79
|
+
@action_prefix = false
|
80
|
+
@action['request']['params'].each do |param|
|
81
|
+
if param['target'].include?('[')
|
82
|
+
parts = param['target'].split('[')
|
83
|
+
pair = parts[0].split('.')
|
84
|
+
if pair.length > 1
|
85
|
+
@action_prefix = pair.first
|
86
|
+
end
|
87
|
+
batch_name = pair.last
|
88
|
+
batch_param = underscore(parts[1].sub(/.*?\./, ''))
|
89
|
+
batch_param = batch_param == "" ? underscore(param['name']) : batch_param
|
90
|
+
(@batch_obj[batch_name] ||= []) << {
|
91
|
+
batch_param.to_sym => underscore(param['name'] || param['path'])
|
92
|
+
}
|
93
|
+
else
|
94
|
+
@per_batch[param['target']] = underscore(param['name'])
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def client_method
|
100
|
+
underscore(@action['request']['operation'])
|
101
|
+
end
|
102
|
+
|
103
|
+
def underscore(str)
|
104
|
+
Underscore.underscore(str)
|
105
|
+
end
|
106
|
+
|
107
|
+
end
|
108
|
+
end
|
@@ -0,0 +1,212 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'set'
|
4
|
+
|
5
|
+
module AwsSdkCodeGenerator
|
6
|
+
class ResourceBatchBuilder
|
7
|
+
|
8
|
+
# @option options [required, Hash] :resource
|
9
|
+
# @option options [String] :resp_var_name ('resp')
|
10
|
+
def initialize(options)
|
11
|
+
@resource = options.fetch(:resource)
|
12
|
+
@resp_var_name = options.fetch(:resp_var_name, 'resp')
|
13
|
+
verify_resource!
|
14
|
+
@context = loop_context
|
15
|
+
@indent = options.fetch(:indent, '')
|
16
|
+
end
|
17
|
+
|
18
|
+
def build
|
19
|
+
code = ''
|
20
|
+
loops = self.send(:loops)
|
21
|
+
count = loops.size
|
22
|
+
loops.each.with_index do |loop_expression, n|
|
23
|
+
i = ' ' * n
|
24
|
+
code += "#{i}#{loop_expression}\n"
|
25
|
+
if n == count - 1
|
26
|
+
code += i + ' ' + Docstring.indent("batch << #{resource_class}.new(#{constructor_args})\n", i + ' ')
|
27
|
+
end
|
28
|
+
end
|
29
|
+
(count).times do |n|
|
30
|
+
i = ' ' * (count - n - 1)
|
31
|
+
code += "#{i}end\n"
|
32
|
+
end
|
33
|
+
code.rstrip
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def resource_class
|
39
|
+
@resource['type']
|
40
|
+
end
|
41
|
+
|
42
|
+
def constructor_args
|
43
|
+
hash = {}
|
44
|
+
hash.update(identifiers)
|
45
|
+
hash[:data] = data_path if @resource['path']
|
46
|
+
hash[:client] = "@client"
|
47
|
+
HashFormatter.new(wrap:false, inline:true).format(hash)
|
48
|
+
end
|
49
|
+
|
50
|
+
def identifiers
|
51
|
+
(@resource['identifiers'] || []).inject({}) do |hash, identifier|
|
52
|
+
value = relative_identifier_path(identifier)
|
53
|
+
hash[underscore(identifier['target']).to_sym] = value
|
54
|
+
hash
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def data_path
|
59
|
+
relative_identifier_path({
|
60
|
+
'source' => 'data',
|
61
|
+
'path' => @resource['path'],
|
62
|
+
})
|
63
|
+
end
|
64
|
+
|
65
|
+
def relative_identifier_path(identifier)
|
66
|
+
path = identifier['path']
|
67
|
+
if path && path.include?('[]')
|
68
|
+
prefix = loops.last.match(/\|(.+)\|/)[1]
|
69
|
+
suffix = underscore(path[common_prefix.length..-1])
|
70
|
+
unless @context == :response
|
71
|
+
suffix = suffix.gsub(/\.\w+/) { |word| "[:#{word[1..-1]}]" }
|
72
|
+
end
|
73
|
+
suffix.length == 0 ? prefix : prefix + suffix
|
74
|
+
else
|
75
|
+
ResourceValueSource.new(identifier).to_s
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def common_prefix
|
80
|
+
paths = plural_paths
|
81
|
+
if paths.empty?
|
82
|
+
''
|
83
|
+
elsif paths.size == 1
|
84
|
+
# grab everything upto and including the final []
|
85
|
+
paths.first.match(/(.+\[\]).*?$/)[1]
|
86
|
+
else
|
87
|
+
prefix = find_prefix(paths)
|
88
|
+
prefix = prefix.sub(/\[\].+?$/, '[]')
|
89
|
+
if prefix[-2..-1] != '[]'
|
90
|
+
msg = 'response paths must have a common prefix ending in [], got :'
|
91
|
+
msg << paths.inspect
|
92
|
+
raise ArgumentError, msg
|
93
|
+
else
|
94
|
+
prefix
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def find_prefix(paths)
|
100
|
+
prefix = ''
|
101
|
+
loop.with_index do |_, n|
|
102
|
+
return prefix if paths.empty?
|
103
|
+
letter = paths[0][n]
|
104
|
+
paths.each do |path|
|
105
|
+
return prefix if path[n].nil?
|
106
|
+
return prefix if path[n] != letter
|
107
|
+
end
|
108
|
+
prefix += letter
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def loops
|
113
|
+
loop_var =
|
114
|
+
case @context
|
115
|
+
when :data then 'data'
|
116
|
+
when :options then 'options'
|
117
|
+
when :response then "#{@resp_var_name}.data."
|
118
|
+
end
|
119
|
+
|
120
|
+
used_vars = Set.new
|
121
|
+
used_vars << loop_var
|
122
|
+
|
123
|
+
parts = common_prefix.split('[]')
|
124
|
+
parts = parts.map.with_index do |part,n|
|
125
|
+
part = underscore(part)
|
126
|
+
unless @context == :response
|
127
|
+
part = part.gsub(/\w+/) { |word| "[:#{word}]" }
|
128
|
+
part = part.gsub(/\./, '')
|
129
|
+
end
|
130
|
+
part = "#{loop_var}#{part}"
|
131
|
+
loop_var = loop_letter(part, used_vars)
|
132
|
+
part = part + ".each do |#{loop_var}|"
|
133
|
+
part
|
134
|
+
end
|
135
|
+
parts
|
136
|
+
end
|
137
|
+
|
138
|
+
def loop_letter(str, used_vars)
|
139
|
+
letter = if @context == :options
|
140
|
+
str.scan(/:\w/).last[1]
|
141
|
+
else
|
142
|
+
str.split('.').last[0]
|
143
|
+
end
|
144
|
+
n = 1
|
145
|
+
var = letter
|
146
|
+
while used_vars.include?(var)
|
147
|
+
n += 1
|
148
|
+
var = "#{letter}#{n}"
|
149
|
+
end
|
150
|
+
used_vars << var
|
151
|
+
var
|
152
|
+
end
|
153
|
+
|
154
|
+
def all_plural_paths
|
155
|
+
paths = {}
|
156
|
+
@resource['identifiers'].each do |i|
|
157
|
+
if i['path'] && i['path'].include?('[]')
|
158
|
+
paths[i['source']] ||= []
|
159
|
+
paths[i['source']] << i['path']
|
160
|
+
end
|
161
|
+
end
|
162
|
+
paths
|
163
|
+
end
|
164
|
+
|
165
|
+
def plural_paths
|
166
|
+
all_plural_paths.values.first
|
167
|
+
end
|
168
|
+
|
169
|
+
def verify_resource!
|
170
|
+
verify_plural_paths!
|
171
|
+
end
|
172
|
+
|
173
|
+
def verify_plural_paths!
|
174
|
+
paths = all_plural_paths
|
175
|
+
case paths.size
|
176
|
+
when 0
|
177
|
+
msg = 'expected at least one plural identifier path, got none'
|
178
|
+
raise ArgumentError, msg
|
179
|
+
when 1
|
180
|
+
case paths.keys.first
|
181
|
+
when 'requestParameter'
|
182
|
+
when 'response'
|
183
|
+
when 'data'
|
184
|
+
else
|
185
|
+
msg = "unsupported identifier source #{paths.keys.first.inspect}"
|
186
|
+
raise ArgumentError, msg
|
187
|
+
end
|
188
|
+
else
|
189
|
+
msg = 'mixing plural source types is not supported'
|
190
|
+
raise ArgumentError, msg
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
def loop_context
|
195
|
+
case all_plural_paths.keys
|
196
|
+
when ['response'] then :response
|
197
|
+
when ['data'] then :data
|
198
|
+
when ['requestParameter'] then :options
|
199
|
+
else
|
200
|
+
msg = "unable to determine loop context: #{@resource.inspect}"
|
201
|
+
raise msg
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
def underscore(str)
|
206
|
+
str.split('.').map do |part|
|
207
|
+
Underscore.underscore(part)
|
208
|
+
end.join('.')
|
209
|
+
end
|
210
|
+
|
211
|
+
end
|
212
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module AwsSdkCodeGenerator
|
4
|
+
class ResourceBuilder
|
5
|
+
|
6
|
+
# @option options [required, Hash] :resource
|
7
|
+
# @option options [required, Boolean] :request_made
|
8
|
+
def initialize(options = {})
|
9
|
+
@resource = options.fetch(:resource)
|
10
|
+
@request_made = options.fetch(:request_made)
|
11
|
+
end
|
12
|
+
|
13
|
+
def build
|
14
|
+
"#{resource_class}.new(#{constructor_options})"
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def resource_class
|
20
|
+
@resource['type']
|
21
|
+
end
|
22
|
+
|
23
|
+
def constructor_options
|
24
|
+
options = {}
|
25
|
+
options.update(identifiers)
|
26
|
+
options[:data] = data_path if @resource['path']
|
27
|
+
options[:client] = "@client"
|
28
|
+
HashFormatter.new(wrap:false).format(options)
|
29
|
+
end
|
30
|
+
|
31
|
+
def identifiers
|
32
|
+
(@resource['identifiers'] || []).inject({}) do |hash, identifier|
|
33
|
+
value = ResourceValueSource.new(identifier).to_s
|
34
|
+
hash[Underscore.underscore(identifier['target']).to_sym] = value
|
35
|
+
hash
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def data_path
|
40
|
+
if @request_made
|
41
|
+
ResourceValueSource.new('source' => 'response', 'path' => @resource['path'])
|
42
|
+
else
|
43
|
+
ResourceValueSource.new('source' => 'data', 'path' => @resource['path'])
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module AwsSdkCodeGenerator
|
4
|
+
class ResourceClientRequest
|
5
|
+
class << self
|
6
|
+
|
7
|
+
# @option options [required, Hash] :request
|
8
|
+
# @option options [Boolean] :resp (false)
|
9
|
+
# @option options [Boolean] :merge (true)
|
10
|
+
def build(options)
|
11
|
+
request = options.fetch(:request)
|
12
|
+
merge = options.fetch(:merge, true)
|
13
|
+
streaming = options.fetch(:streaming, false)
|
14
|
+
params = ResourceClientRequestParams.new(params: request['params'])
|
15
|
+
parts = []
|
16
|
+
parts << request_options(params) if merge
|
17
|
+
parts << assignment(options)
|
18
|
+
parts << "@client."
|
19
|
+
parts << operation_name(request)
|
20
|
+
parts << arguments(merge, params, streaming)
|
21
|
+
parts.join
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def request_options(params)
|
27
|
+
if params.empty?
|
28
|
+
''
|
29
|
+
elsif params.simple?
|
30
|
+
"options = options.merge(#{params})\n"
|
31
|
+
else
|
32
|
+
hash = params
|
33
|
+
hash = ' ' + hash unless hash[0] == "\n"
|
34
|
+
"options = Aws::Util.deep_merge(options,#{hash})\n"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def assignment(options)
|
39
|
+
if options.fetch(:resp, false)
|
40
|
+
'resp = '
|
41
|
+
else
|
42
|
+
''
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def operation_name(request)
|
47
|
+
Underscore.underscore(request['operation'])
|
48
|
+
end
|
49
|
+
|
50
|
+
def arguments(merge, params, streaming)
|
51
|
+
if merge
|
52
|
+
streaming ? '(options, &block)' : '(options)'
|
53
|
+
elsif params.empty?
|
54
|
+
''
|
55
|
+
else
|
56
|
+
streaming ? "(#{params}, &block)" : "(#{params})"
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'set'
|
4
|
+
|
5
|
+
module AwsSdkCodeGenerator
|
6
|
+
class ResourceClientReqeustDocumentation
|
7
|
+
|
8
|
+
def initialize(options)
|
9
|
+
@api = options.fetch(:api)
|
10
|
+
@method_name = options.fetch(:method_name)
|
11
|
+
@receiver = options.fetch(:receiver)
|
12
|
+
@resp_var = options.fetch(:resp_var, nil)
|
13
|
+
@request = options.fetch(:request)
|
14
|
+
@shape_ref = @api['operations'][@request['operation']]['input']
|
15
|
+
@returns = options.fetch(:returns, nil)
|
16
|
+
@skip = Set.new(options.fetch(:skip, []) + ResourceSkipParams.compute(input_shape, @request))
|
17
|
+
end
|
18
|
+
|
19
|
+
def build
|
20
|
+
Docstring.join_docstrings([
|
21
|
+
request_syntax_example,
|
22
|
+
param_tag,
|
23
|
+
option_tags,
|
24
|
+
return_tag,
|
25
|
+
], block_comment: false, separator: false)
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def request_syntax_example
|
31
|
+
if @shape_ref && Api.shape(@shape_ref, @api)['members'].count - @skip.count > 0
|
32
|
+
SyntaxExample.new(
|
33
|
+
api: @api,
|
34
|
+
shape: input_shape,
|
35
|
+
method_name: @method_name,
|
36
|
+
receiver: @receiver,
|
37
|
+
resp_var: @resp_var,
|
38
|
+
skip: @skip,
|
39
|
+
).format
|
40
|
+
else
|
41
|
+
# TODO : remove these empty examples, not really needed
|
42
|
+
<<-DOCS.rstrip
|
43
|
+
# @example Request syntax with placeholder values
|
44
|
+
#
|
45
|
+
# #{@receiver}.#{@method_name}()
|
46
|
+
DOCS
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def param_tag
|
51
|
+
'# @param [Hash] options ({})'
|
52
|
+
end
|
53
|
+
|
54
|
+
def option_tags
|
55
|
+
if input_shape
|
56
|
+
input_shape['members'].map do |member_name, member_ref|
|
57
|
+
next if @skip.include?(member_name)
|
58
|
+
YardOptionTag.new(
|
59
|
+
name: Underscore.underscore(member_name),
|
60
|
+
required: input_shape.fetch('required', []).include?(member_name),
|
61
|
+
ruby_type: Api.ruby_input_type(member_ref, @api),
|
62
|
+
docstring: Docstring.html_to_markdown(Api.docstring(member_ref, @api)),
|
63
|
+
).to_str
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def input_shape
|
69
|
+
Api.shape(@shape_ref, @api)
|
70
|
+
end
|
71
|
+
|
72
|
+
def return_tag
|
73
|
+
if @returns
|
74
|
+
"# @return [#{@returns}]"
|
75
|
+
else
|
76
|
+
nil
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
81
|
+
end
|