aws-sdk-code-generator 0.1.0.pre

Sign up to get free protection for your applications and to get access to all the features.
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