aws-sdk-code-generator 0.1.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.
Files changed (78) hide show
  1. checksums.yaml +7 -0
  2. data/lib/aws-sdk-code-generator.rb +91 -0
  3. data/lib/aws-sdk-code-generator/apply_docs.rb +37 -0
  4. data/lib/aws-sdk-code-generator/code_builder.rb +201 -0
  5. data/lib/aws-sdk-code-generator/dsl/access_control_statement.rb +23 -0
  6. data/lib/aws-sdk-code-generator/dsl/attribute_accessor.rb +43 -0
  7. data/lib/aws-sdk-code-generator/dsl/attribute_reader.rb +11 -0
  8. data/lib/aws-sdk-code-generator/dsl/attribute_writer.rb +11 -0
  9. data/lib/aws-sdk-code-generator/dsl/autoload_statement.rb +15 -0
  10. data/lib/aws-sdk-code-generator/dsl/block_param.rb +11 -0
  11. data/lib/aws-sdk-code-generator/dsl/class.rb +27 -0
  12. data/lib/aws-sdk-code-generator/dsl/code_literal.rb +66 -0
  13. data/lib/aws-sdk-code-generator/dsl/code_object.rb +33 -0
  14. data/lib/aws-sdk-code-generator/dsl/docstring.rb +36 -0
  15. data/lib/aws-sdk-code-generator/dsl/eigenclass.rb +15 -0
  16. data/lib/aws-sdk-code-generator/dsl/extend_statement.rb +12 -0
  17. data/lib/aws-sdk-code-generator/dsl/formatter.rb +25 -0
  18. data/lib/aws-sdk-code-generator/dsl/include_statement.rb +17 -0
  19. data/lib/aws-sdk-code-generator/dsl/main.rb +105 -0
  20. data/lib/aws-sdk-code-generator/dsl/method.rb +108 -0
  21. data/lib/aws-sdk-code-generator/dsl/module.rb +167 -0
  22. data/lib/aws-sdk-code-generator/dsl/option_tag.rb +36 -0
  23. data/lib/aws-sdk-code-generator/dsl/param.rb +43 -0
  24. data/lib/aws-sdk-code-generator/dsl/param_list.rb +38 -0
  25. data/lib/aws-sdk-code-generator/dsl/return_tag.rb +19 -0
  26. data/lib/aws-sdk-code-generator/dsl/tag_default.rb +20 -0
  27. data/lib/aws-sdk-code-generator/dsl/tag_docstring.rb +27 -0
  28. data/lib/aws-sdk-code-generator/dsl/tag_type.rb +18 -0
  29. data/lib/aws-sdk-code-generator/errors.rb +30 -0
  30. data/lib/aws-sdk-code-generator/gem_builder.rb +71 -0
  31. data/lib/aws-sdk-code-generator/generators/client_api_module.rb +334 -0
  32. data/lib/aws-sdk-code-generator/generators/client_class.rb +389 -0
  33. data/lib/aws-sdk-code-generator/generators/client_operation_documentation.rb +166 -0
  34. data/lib/aws-sdk-code-generator/generators/errors_module.rb +25 -0
  35. data/lib/aws-sdk-code-generator/generators/resource/action.rb +88 -0
  36. data/lib/aws-sdk-code-generator/generators/resource/batch_builder.rb +211 -0
  37. data/lib/aws-sdk-code-generator/generators/resource/builder.rb +50 -0
  38. data/lib/aws-sdk-code-generator/generators/resource/client_getter.rb +15 -0
  39. data/lib/aws-sdk-code-generator/generators/resource/client_request.rb +49 -0
  40. data/lib/aws-sdk-code-generator/generators/resource/client_request_docs.rb +97 -0
  41. data/lib/aws-sdk-code-generator/generators/resource/client_request_params.rb +88 -0
  42. data/lib/aws-sdk-code-generator/generators/resource/collection_class.rb +180 -0
  43. data/lib/aws-sdk-code-generator/generators/resource/data_attribute_getter.rb +24 -0
  44. data/lib/aws-sdk-code-generator/generators/resource/data_loaded_method.rb +18 -0
  45. data/lib/aws-sdk-code-generator/generators/resource/data_method.rb +49 -0
  46. data/lib/aws-sdk-code-generator/generators/resource/exists_method.rb +29 -0
  47. data/lib/aws-sdk-code-generator/generators/resource/extract_identifier_method.rb +32 -0
  48. data/lib/aws-sdk-code-generator/generators/resource/has_association.rb +101 -0
  49. data/lib/aws-sdk-code-generator/generators/resource/has_many_association.rb +108 -0
  50. data/lib/aws-sdk-code-generator/generators/resource/identifier_getter.rb +26 -0
  51. data/lib/aws-sdk-code-generator/generators/resource/identifiers_method.rb +28 -0
  52. data/lib/aws-sdk-code-generator/generators/resource/initialize_method.rb +67 -0
  53. data/lib/aws-sdk-code-generator/generators/resource/load_method.rb +65 -0
  54. data/lib/aws-sdk-code-generator/generators/resource/value_source.rb +68 -0
  55. data/lib/aws-sdk-code-generator/generators/resource/waiter_method.rb +61 -0
  56. data/lib/aws-sdk-code-generator/generators/resource_class.rb +325 -0
  57. data/lib/aws-sdk-code-generator/generators/response_structure_example.rb +83 -0
  58. data/lib/aws-sdk-code-generator/generators/root_resource_class.rb +42 -0
  59. data/lib/aws-sdk-code-generator/generators/service_documentation.rb +64 -0
  60. data/lib/aws-sdk-code-generator/generators/shared_example.rb +132 -0
  61. data/lib/aws-sdk-code-generator/generators/structure_type_class.rb +95 -0
  62. data/lib/aws-sdk-code-generator/generators/syntax_example.rb +169 -0
  63. data/lib/aws-sdk-code-generator/generators/types_module.rb +52 -0
  64. data/lib/aws-sdk-code-generator/generators/waiter_class.rb +62 -0
  65. data/lib/aws-sdk-code-generator/generators/waiters_module.rb +20 -0
  66. data/lib/aws-sdk-code-generator/hash_formatter.rb +122 -0
  67. data/lib/aws-sdk-code-generator/helper.rb +215 -0
  68. data/lib/aws-sdk-code-generator/service.rb +126 -0
  69. data/lib/aws-sdk-code-generator/underscore.rb +45 -0
  70. data/lib/aws-sdk-code-generator/view.rb +23 -0
  71. data/lib/aws-sdk-code-generator/views.rb +3 -0
  72. data/lib/aws-sdk-code-generator/views/features/env.rb +24 -0
  73. data/lib/aws-sdk-code-generator/views/features/step_definitions.rb +20 -0
  74. data/lib/aws-sdk-code-generator/views/gemspec.rb +41 -0
  75. data/lib/aws-sdk-code-generator/views/service_module.rb +85 -0
  76. data/lib/aws-sdk-code-generator/views/spec/spec_helper.rb +24 -0
  77. data/lib/aws-sdk-code-generator/views/version.rb +16 -0
  78. metadata +120 -0
@@ -0,0 +1,50 @@
1
+ module AwsSdkCodeGenerator
2
+ module Generators
3
+ module Resource
4
+ class Builder < Dsl::CodeLiteral
5
+
6
+ include Helper
7
+
8
+ # @option options [required, Hash] :resource
9
+ # @option options [required, Boolean] :request_made
10
+ def initialize(options = {})
11
+ super()
12
+ @resource = options.fetch(:resource)
13
+ @request_made = options.fetch(:request_made)
14
+ append("#{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, inline:true).format(options)
29
+ end
30
+
31
+ def identifiers
32
+ (@resource['identifiers'] || []).inject({}) do |hash, identifier|
33
+ value = ValueSource.new(identifier).to_s
34
+ hash[underscore(identifier['target']).to_sym] = value
35
+ hash
36
+ end
37
+ end
38
+
39
+ def data_path
40
+ if @request_made
41
+ ValueSource.new('source' => 'response', 'path' => @resource['path'])
42
+ else
43
+ ValueSource.new('source' => 'data', 'path' => @resource['path'])
44
+ end
45
+ end
46
+
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,15 @@
1
+ module AwsSdkCodeGenerator
2
+ module Generators
3
+ module Resource
4
+ class ClientGetter < Dsl::Method
5
+
6
+ def initialize
7
+ super('client')
8
+ returns('Client')
9
+ code('@client')
10
+ end
11
+
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,49 @@
1
+ module AwsSdkCodeGenerator
2
+ module Generators
3
+ module Resource
4
+ class ClientRequest < Dsl::CodeLiteral
5
+
6
+ include Helper
7
+
8
+ # @option options [required, Hash] :request
9
+ # @option options [Boolean] :resp (false)
10
+ # @option options [Boolean] :merge (true)
11
+ def initialize(options = {})
12
+ @request = options.fetch(:request)
13
+ @params = ClientRequestParams.new(params: @request['params'])
14
+ @resp = options.fetch(:resp, false)
15
+ if options.fetch(:merge, true)
16
+ super("#{request_options}#{assignement}@client.#{operation_name}(options)")
17
+ else
18
+ super("#{assignement}@client.#{operation_name}#{params}")
19
+ end
20
+ end
21
+
22
+ private
23
+
24
+ def request_options
25
+ if @params.empty?
26
+ ''
27
+ elsif @params.simple?
28
+ "options = options.merge(#{@params})\n"
29
+ else
30
+ "options = Aws::Util.deep_merge(options, #{@params})\n"
31
+ end
32
+ end
33
+
34
+ def params
35
+ @params.empty? ? @params : "(#{@params})"
36
+ end
37
+
38
+ def assignement
39
+ "resp = " if @resp
40
+ end
41
+
42
+ def operation_name
43
+ underscore(@request['operation'])
44
+ end
45
+
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,97 @@
1
+ require 'set'
2
+
3
+ module AwsSdkCodeGenerator
4
+ module Generators
5
+ module Resource
6
+ class ClientRequestDocs
7
+
8
+ include Helper
9
+
10
+ # @option options [required, Hash] :api
11
+ # @option options [required, Hash] :request
12
+ # @option options [Array<String>] :skip ([])
13
+ # @option options [required, String] :var_name
14
+ # @option options [required, String] :returns
15
+ def initialize(options)
16
+ @api = options.fetch(:api)
17
+ @request = options.fetch(:request)
18
+ @skip = Set.new(options.fetch(:skip, []))
19
+ @var_name = options.fetch(:var_name)
20
+ @returns = options.fetch(:returns)
21
+ end
22
+
23
+ # @param [Dsl::Method] method
24
+ def apply(method)
25
+ apply_request_syntax_example(method)
26
+ apply_option_tags(method)
27
+ end
28
+
29
+ private
30
+
31
+ def apply_option_tags(method)
32
+ input_members.each do |member_name, member_ref, required|
33
+ method.option(
34
+ name: underscore(member_name),
35
+ type: ruby_input_type(member_ref),
36
+ required: required,
37
+ docstring: documentation(member_ref)
38
+ )
39
+ end
40
+ end
41
+
42
+ def apply_request_syntax_example(method)
43
+ if input_shape
44
+ syntax = SyntaxExample.new(
45
+ struct_shape: input_shape,
46
+ api: @api,
47
+ indent: ' '
48
+ ).format.strip
49
+ method.docstring.append("@example Request syntax with placeholder values")
50
+ if @returns
51
+ method.docstring.append("\n #{@returns} = #{@var_name}.#{method.name}(#{syntax})")
52
+ else
53
+ method.docstring.append("\n #{@var_name}.#{method.name}(#{syntax})")
54
+ end
55
+ end
56
+ end
57
+
58
+ def input_members
59
+ if input_shape
60
+ Enumerator.new do |y|
61
+ input_shape['members'].each_pair do |member_name, member_ref|
62
+ required = (input_shape['required'] || []).include?(member_name)
63
+ y.yield(member_name, member_ref, required)
64
+ end
65
+ end
66
+ else
67
+ []
68
+ end
69
+ end
70
+
71
+ def operation
72
+ @api['operations'][@request['operation']]
73
+ end
74
+
75
+ def input_shape
76
+ struct = shape(operation['input'])
77
+ if struct
78
+ struct = deep_copy(struct)
79
+ struct['members'].keys.each do |member_name|
80
+ struct['members'].delete(member_name) if request_param?(member_name)
81
+ struct['members'].delete(member_name) if @skip.include?(member_name)
82
+ end
83
+ end
84
+ struct
85
+ end
86
+
87
+ def request_param?(member_name)
88
+ params = @request['params'] || []
89
+ params.any? do |param|
90
+ param['target'].match(/^#{member_name}\b/) && !(param['target'].include?('[') && param['target'].include?('.'))
91
+ end
92
+ end
93
+
94
+ end
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,88 @@
1
+ module AwsSdkCodeGenerator
2
+ module Generators
3
+ module Resource
4
+ class ClientRequestParams < String
5
+
6
+ include Helper
7
+
8
+ # @option options [Array] :params ([])
9
+ def initialize(options = {})
10
+ @params = options.fetch(:params, nil) || []
11
+ super(format_params)
12
+ end
13
+
14
+ def simple?
15
+ @params.all? { |p| p['target'].match(/^\w+$/) }
16
+ end
17
+
18
+ def empty?
19
+ @params.empty?
20
+ end
21
+
22
+ def size
23
+ @params.size
24
+ end
25
+
26
+ private
27
+
28
+ def format_params
29
+ hash = {}
30
+ @params.each do |param|
31
+ ParamTarget.new(param).apply(hash, ValueSource.new(param))
32
+ end
33
+ formatter = HashFormatter.new(wrap:false, inline: @params.count == 1)
34
+ params = formatter.format(hash)
35
+ @params.size == 1 ? params.strip : params
36
+ end
37
+
38
+ class ParamTarget
39
+
40
+ def initialize(param)
41
+ @target = param['target']
42
+ @steps = []
43
+ @target.scan(/\w+|\[\]|\[\*\]|\[[0-9]+\]/) do |step|
44
+ case step
45
+ when /\[\d+\]/ then @steps += [:array, step[1..-2].to_i]
46
+ when /\[\*\]/ then @steps += [:array, :n]
47
+ when '[]' then @steps += [:array, -1]
48
+ else @steps += [:hash, Underscore.underscore(step).to_sym]
49
+ end
50
+ end
51
+ @steps.shift
52
+ @final = @steps.pop
53
+ end
54
+
55
+ # @return [String] target
56
+ attr_reader :target
57
+
58
+ def apply(hash, value, options = {})
59
+ resource_index = options.fetch(:resource_index, 0)
60
+ if @final == -1
61
+ build_context(hash, resource_index) << value
62
+ else
63
+ build_context(hash, resource_index)[@final] = value
64
+ end
65
+ hash
66
+ end
67
+
68
+ private
69
+
70
+ def build_context(params, n)
71
+ @steps.each_slice(2).inject(params) do |context, (key, type)|
72
+ entry = type == :array ? [] : {}
73
+ if key == -1
74
+ context << entry
75
+ entry
76
+ elsif key == :n
77
+ context[n] ||= entry
78
+ else
79
+ context[key] ||= entry
80
+ end
81
+ end
82
+ end
83
+
84
+ end
85
+ end
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,180 @@
1
+ module AwsSdkCodeGenerator
2
+ module Generators
3
+ module Resource
4
+ class CollectionClass < Dsl::Class
5
+
6
+ include Helper
7
+
8
+ # @option options [required, String] :resource_name
9
+ # @option options [required, Hash] :resource
10
+ # @option options [required, Hash] :api
11
+ def initialize(options)
12
+ @resource_name = options.fetch(:resource_name)
13
+ @resource = options.fetch(:resource)
14
+ @variable_name = underscore(@resource_name)
15
+ @api = options.fetch(:api)
16
+ super('Collection', extends: 'Aws::Resources::Collection')
17
+ add(*batch_actions)
18
+ end
19
+
20
+ def apply(mod)
21
+ mod.class(@resource_name) do |m|
22
+ m.add(self)
23
+ end
24
+ end
25
+
26
+ private
27
+
28
+ def batch_actions
29
+ if @resource['batchActions']
30
+ actions = []
31
+ actions << '# @!group Batch Actions'
32
+ @resource['batchActions'].each do |name, action|
33
+ actions << Dsl::Method.new(batch_action_name(name, action)) do |m|
34
+ m.returns('void')
35
+ m.param('options', default: {})
36
+ param_hash(action)
37
+ apply_batch_action_doc(action, m)
38
+ m.code('batch_enum.each do |batch|')
39
+ m.code(initialize_params)
40
+ m.code(apply_params_per_batch)
41
+ m.code(batch_request(action))
42
+ m.code('end')
43
+ m.code(batch_response)
44
+ end
45
+ end
46
+ actions << '# @!endgroup'
47
+ actions
48
+ else
49
+ []
50
+ end
51
+ end
52
+
53
+ def param_hash(action)
54
+ @batch_obj = {}
55
+ @per_batch = {}
56
+ @action_prefix = false
57
+ action['request']['params'].each do |param|
58
+ if param['target'].include?('[')
59
+ parts = param['target'].split('[')
60
+ pair = parts[0].split('.')
61
+ if pair.length > 1
62
+ @action_prefix = pair.first
63
+ end
64
+ batch_name = pair.last
65
+ batch_param = underscore(parts[1].sub(/.*?\./, ''))
66
+ batch_param = batch_param == "" ? underscore(param['name']) : batch_param
67
+ (@batch_obj[batch_name] ||= []) << {
68
+ batch_param.to_sym => underscore(param['name'] || param['path'])
69
+ }
70
+ else
71
+ @per_batch[param['target']] = underscore(param['name'])
72
+ end
73
+ end
74
+ end
75
+
76
+ def apply_batch_action_doc(action, method)
77
+ skip = []
78
+ if @action_prefix
79
+ skip << @action_prefix
80
+ else
81
+ skip += @per_batch.keys
82
+ skip += @batch_obj.keys
83
+ end
84
+ ClientRequestDocs.new(
85
+ request: action['request'],
86
+ api: @api,
87
+ skip: skip,
88
+ var_name: @variable_name,
89
+ returns: nil
90
+ ).apply(method)
91
+ end
92
+
93
+ def initialize_params
94
+ param_block = []
95
+ param_block << " params = Aws::Util.copy_hash(options)"
96
+ param_block << apply_param_hash
97
+ param_block.join("\n")
98
+ end
99
+
100
+ def apply_param_hash
101
+ block = []
102
+ @per_batch.each do |key, value|
103
+ block << " params[:#{underscore(key)}] = batch[0].#{value}"
104
+ end
105
+ if @action_prefix
106
+ action = underscore(@action_prefix)
107
+ block << " params[:#{action}] ||= {}"
108
+ @batch_obj.keys.each do |key|
109
+ block << " params[:#{action}][:#{underscore(key)}] ||= []"
110
+ end
111
+ else
112
+ @batch_obj.keys.each {|key| block << " params[:#{underscore(key)}] ||= []"}
113
+ end
114
+ block.join("\n")
115
+ end
116
+
117
+ def apply_params_per_batch
118
+ each_batch = []
119
+ each_batch << " batch.each do |item|"
120
+ @batch_obj.each do |key, value|
121
+ hash = {}
122
+ value.each do |v|
123
+ param, identifier = v.first
124
+ hash[param.to_sym] = "item.#{identifier}"
125
+ end
126
+ # Construct hash block
127
+ if @action_prefix
128
+ each_batch << " params[:#{underscore(@action_prefix)}][:#{underscore(key)}] << {"
129
+ else
130
+ each_batch << " params[:#{underscore(key)}] << {"
131
+ end
132
+ # hashformatter treats this as inline, need extra indent
133
+ indent_count = hash.size == 1 ? 3 : 2
134
+ each_batch << indent_helper(HashFormatter.new(wrap: false).format(hash), indent_count)
135
+ each_batch << " }"
136
+ end
137
+ each_batch << " end"
138
+ each_batch.join("\n")
139
+ end
140
+
141
+ def batch_request(action)
142
+ " batch[0].client.#{underscore(action['request']['operation'])}(params)"
143
+ end
144
+
145
+ def batch_response
146
+ "nil"
147
+ end
148
+
149
+ def indent_helper(lines, count)
150
+ block = []
151
+ lines.split("\n").each do |line|
152
+ next if line.strip == ""
153
+ block << " " * count + line
154
+ end
155
+ block.join("\n")
156
+ end
157
+
158
+ def batch_action_name(name, action)
159
+ method_name = "batch_" + underscore(name)
160
+ method_name += '!' if dangerous?(name, action)
161
+ method_name
162
+ end
163
+
164
+ def dangerous?(name, action)
165
+ if
166
+ name.match(/delete/i) ||
167
+ name.match(/terminate/i) ||
168
+ action['request']['operation'].match(/delete/i) ||
169
+ action['request']['operation'].match(/terminate/i)
170
+ then
171
+ true
172
+ else
173
+ false
174
+ end
175
+ end
176
+
177
+ end
178
+ end
179
+ end
180
+ end