aws-sdk-code-generator 0.1.0.pre → 0.2.4.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 (155) hide show
  1. checksums.yaml +5 -5
  2. data/lib/aws-sdk-code-generator/api.rb +150 -0
  3. data/lib/aws-sdk-code-generator/apply_docs.rb +15 -2
  4. data/lib/aws-sdk-code-generator/client_constructor.rb +39 -0
  5. data/lib/aws-sdk-code-generator/client_operation_documentation.rb +282 -0
  6. data/lib/aws-sdk-code-generator/client_operation_list.rb +148 -0
  7. data/lib/aws-sdk-code-generator/client_response_structure_example.rb +115 -0
  8. data/lib/aws-sdk-code-generator/code_builder.rb +146 -133
  9. data/lib/aws-sdk-code-generator/crosslink.rb +42 -0
  10. data/lib/aws-sdk-code-generator/docstring.rb +199 -0
  11. data/lib/aws-sdk-code-generator/error_list.rb +77 -0
  12. data/lib/aws-sdk-code-generator/errors.rb +2 -0
  13. data/lib/aws-sdk-code-generator/eventstream_example.rb +220 -0
  14. data/lib/aws-sdk-code-generator/gem_builder.rb +42 -25
  15. data/lib/aws-sdk-code-generator/hash_formatter.rb +5 -2
  16. data/lib/aws-sdk-code-generator/helper.rb +86 -119
  17. data/lib/aws-sdk-code-generator/plugin_list.rb +147 -0
  18. data/lib/aws-sdk-code-generator/resource_action.rb +69 -0
  19. data/lib/aws-sdk-code-generator/resource_action_code.rb +57 -0
  20. data/lib/aws-sdk-code-generator/resource_association.rb +37 -0
  21. data/lib/aws-sdk-code-generator/resource_attribute.rb +76 -0
  22. data/lib/aws-sdk-code-generator/resource_batch_action.rb +56 -0
  23. data/lib/aws-sdk-code-generator/resource_batch_action_code.rb +136 -0
  24. data/lib/aws-sdk-code-generator/resource_batch_action_documentation.rb +108 -0
  25. data/lib/aws-sdk-code-generator/resource_batch_builder.rb +212 -0
  26. data/lib/aws-sdk-code-generator/resource_builder.rb +48 -0
  27. data/lib/aws-sdk-code-generator/resource_client_request.rb +62 -0
  28. data/lib/aws-sdk-code-generator/resource_client_request_documentation.rb +81 -0
  29. data/lib/aws-sdk-code-generator/resource_client_request_params.rb +86 -0
  30. data/lib/aws-sdk-code-generator/resource_data_method.rb +60 -0
  31. data/lib/aws-sdk-code-generator/resource_has_association.rb +117 -0
  32. data/lib/aws-sdk-code-generator/resource_has_many_association.rb +52 -0
  33. data/lib/aws-sdk-code-generator/resource_has_many_association_code.rb +76 -0
  34. data/lib/aws-sdk-code-generator/resource_identifier.rb +44 -0
  35. data/lib/aws-sdk-code-generator/resource_identifiers_method.rb +29 -0
  36. data/lib/aws-sdk-code-generator/resource_load_method.rb +68 -0
  37. data/lib/aws-sdk-code-generator/resource_method.rb +22 -0
  38. data/lib/aws-sdk-code-generator/resource_skip_params.rb +36 -0
  39. data/lib/aws-sdk-code-generator/resource_value_source.rb +68 -0
  40. data/lib/aws-sdk-code-generator/resource_waiter.rb +80 -0
  41. data/lib/aws-sdk-code-generator/service.rb +30 -7
  42. data/lib/aws-sdk-code-generator/shared_example.rb +131 -0
  43. data/lib/aws-sdk-code-generator/syntax_example.rb +60 -0
  44. data/lib/aws-sdk-code-generator/syntax_example_hash.rb +174 -0
  45. data/lib/aws-sdk-code-generator/underscore.rb +10 -5
  46. data/lib/aws-sdk-code-generator/view.rb +33 -0
  47. data/lib/aws-sdk-code-generator/views/apig_endpoint_class.rb +25 -0
  48. data/lib/aws-sdk-code-generator/views/apig_readme.rb +32 -0
  49. data/lib/aws-sdk-code-generator/views/async_client_class.rb +68 -0
  50. data/lib/aws-sdk-code-generator/views/authorizer_class.rb +17 -0
  51. data/lib/aws-sdk-code-generator/views/client_api_module.rb +602 -0
  52. data/lib/aws-sdk-code-generator/views/client_class.rb +93 -0
  53. data/lib/aws-sdk-code-generator/views/docstring.rb +27 -0
  54. data/lib/aws-sdk-code-generator/views/errors_module.rb +32 -0
  55. data/lib/aws-sdk-code-generator/views/event_streams_module.rb +149 -0
  56. data/lib/aws-sdk-code-generator/views/features/env.rb +9 -0
  57. data/lib/aws-sdk-code-generator/views/features/smoke.rb +52 -0
  58. data/lib/aws-sdk-code-generator/views/features/smoke_step_definitions.rb +26 -0
  59. data/lib/aws-sdk-code-generator/views/features/step_definitions.rb +6 -2
  60. data/lib/aws-sdk-code-generator/views/gemspec.rb +39 -5
  61. data/lib/aws-sdk-code-generator/views/resource_class.rb +122 -0
  62. data/lib/aws-sdk-code-generator/views/root_resource_class.rb +58 -0
  63. data/lib/aws-sdk-code-generator/views/service_module.rb +38 -14
  64. data/lib/aws-sdk-code-generator/views/spec/spec_helper.rb +9 -0
  65. data/lib/aws-sdk-code-generator/views/types_module.rb +329 -0
  66. data/lib/aws-sdk-code-generator/views/version.rb +2 -0
  67. data/lib/aws-sdk-code-generator/views/waiters_module.rb +37 -0
  68. data/lib/aws-sdk-code-generator/views.rb +2 -0
  69. data/lib/aws-sdk-code-generator/waiter.rb +95 -0
  70. data/lib/aws-sdk-code-generator/yard_option_tag.rb +43 -0
  71. data/lib/aws-sdk-code-generator.rb +68 -75
  72. data/templates/apig_endpoint_class.mustache +16 -0
  73. data/templates/apig_readme.mustache +62 -0
  74. data/templates/async_client_class.mustache +125 -0
  75. data/templates/authorizer_class.mustache +37 -0
  76. data/templates/client_api_module.mustache +106 -0
  77. data/templates/client_class.mustache +295 -0
  78. data/templates/code.mustache +4 -0
  79. data/templates/documentation.mustache +4 -0
  80. data/templates/errors_module.mustache +70 -0
  81. data/templates/event_streams_module.mustache +76 -0
  82. data/templates/features/env.mustache +15 -0
  83. data/templates/features/smoke.mustache +22 -0
  84. data/templates/features/smoke_step_definitions.mustache +31 -0
  85. data/templates/features/step_definitions.mustache +13 -0
  86. data/templates/gemspec.mustache +31 -0
  87. data/templates/license.txt +202 -0
  88. data/templates/method.mustache +7 -0
  89. data/templates/resource_class.mustache +304 -0
  90. data/templates/root_resource_class.mustache +51 -0
  91. data/templates/service_module.mustache +58 -0
  92. data/templates/spec/spec_helper.mustache +15 -0
  93. data/templates/types_module.mustache +53 -0
  94. data/templates/version.mustache +1 -0
  95. data/templates/waiters_module.mustache +112 -0
  96. metadata +115 -70
  97. data/lib/aws-sdk-code-generator/dsl/access_control_statement.rb +0 -23
  98. data/lib/aws-sdk-code-generator/dsl/attribute_accessor.rb +0 -43
  99. data/lib/aws-sdk-code-generator/dsl/attribute_reader.rb +0 -11
  100. data/lib/aws-sdk-code-generator/dsl/attribute_writer.rb +0 -11
  101. data/lib/aws-sdk-code-generator/dsl/autoload_statement.rb +0 -15
  102. data/lib/aws-sdk-code-generator/dsl/block_param.rb +0 -11
  103. data/lib/aws-sdk-code-generator/dsl/class.rb +0 -27
  104. data/lib/aws-sdk-code-generator/dsl/code_literal.rb +0 -66
  105. data/lib/aws-sdk-code-generator/dsl/code_object.rb +0 -33
  106. data/lib/aws-sdk-code-generator/dsl/docstring.rb +0 -36
  107. data/lib/aws-sdk-code-generator/dsl/eigenclass.rb +0 -15
  108. data/lib/aws-sdk-code-generator/dsl/extend_statement.rb +0 -12
  109. data/lib/aws-sdk-code-generator/dsl/formatter.rb +0 -25
  110. data/lib/aws-sdk-code-generator/dsl/include_statement.rb +0 -17
  111. data/lib/aws-sdk-code-generator/dsl/main.rb +0 -105
  112. data/lib/aws-sdk-code-generator/dsl/method.rb +0 -108
  113. data/lib/aws-sdk-code-generator/dsl/module.rb +0 -167
  114. data/lib/aws-sdk-code-generator/dsl/option_tag.rb +0 -36
  115. data/lib/aws-sdk-code-generator/dsl/param.rb +0 -43
  116. data/lib/aws-sdk-code-generator/dsl/param_list.rb +0 -38
  117. data/lib/aws-sdk-code-generator/dsl/return_tag.rb +0 -19
  118. data/lib/aws-sdk-code-generator/dsl/tag_default.rb +0 -20
  119. data/lib/aws-sdk-code-generator/dsl/tag_docstring.rb +0 -27
  120. data/lib/aws-sdk-code-generator/dsl/tag_type.rb +0 -18
  121. data/lib/aws-sdk-code-generator/generators/client_api_module.rb +0 -334
  122. data/lib/aws-sdk-code-generator/generators/client_class.rb +0 -389
  123. data/lib/aws-sdk-code-generator/generators/client_operation_documentation.rb +0 -166
  124. data/lib/aws-sdk-code-generator/generators/errors_module.rb +0 -25
  125. data/lib/aws-sdk-code-generator/generators/resource/action.rb +0 -88
  126. data/lib/aws-sdk-code-generator/generators/resource/batch_builder.rb +0 -211
  127. data/lib/aws-sdk-code-generator/generators/resource/builder.rb +0 -50
  128. data/lib/aws-sdk-code-generator/generators/resource/client_getter.rb +0 -15
  129. data/lib/aws-sdk-code-generator/generators/resource/client_request.rb +0 -49
  130. data/lib/aws-sdk-code-generator/generators/resource/client_request_docs.rb +0 -97
  131. data/lib/aws-sdk-code-generator/generators/resource/client_request_params.rb +0 -88
  132. data/lib/aws-sdk-code-generator/generators/resource/collection_class.rb +0 -180
  133. data/lib/aws-sdk-code-generator/generators/resource/data_attribute_getter.rb +0 -24
  134. data/lib/aws-sdk-code-generator/generators/resource/data_loaded_method.rb +0 -18
  135. data/lib/aws-sdk-code-generator/generators/resource/data_method.rb +0 -49
  136. data/lib/aws-sdk-code-generator/generators/resource/exists_method.rb +0 -29
  137. data/lib/aws-sdk-code-generator/generators/resource/extract_identifier_method.rb +0 -32
  138. data/lib/aws-sdk-code-generator/generators/resource/has_association.rb +0 -101
  139. data/lib/aws-sdk-code-generator/generators/resource/has_many_association.rb +0 -108
  140. data/lib/aws-sdk-code-generator/generators/resource/identifier_getter.rb +0 -26
  141. data/lib/aws-sdk-code-generator/generators/resource/identifiers_method.rb +0 -28
  142. data/lib/aws-sdk-code-generator/generators/resource/initialize_method.rb +0 -67
  143. data/lib/aws-sdk-code-generator/generators/resource/load_method.rb +0 -65
  144. data/lib/aws-sdk-code-generator/generators/resource/value_source.rb +0 -68
  145. data/lib/aws-sdk-code-generator/generators/resource/waiter_method.rb +0 -61
  146. data/lib/aws-sdk-code-generator/generators/resource_class.rb +0 -325
  147. data/lib/aws-sdk-code-generator/generators/response_structure_example.rb +0 -83
  148. data/lib/aws-sdk-code-generator/generators/root_resource_class.rb +0 -42
  149. data/lib/aws-sdk-code-generator/generators/service_documentation.rb +0 -64
  150. data/lib/aws-sdk-code-generator/generators/shared_example.rb +0 -132
  151. data/lib/aws-sdk-code-generator/generators/structure_type_class.rb +0 -95
  152. data/lib/aws-sdk-code-generator/generators/syntax_example.rb +0 -169
  153. data/lib/aws-sdk-code-generator/generators/types_module.rb +0 -52
  154. data/lib/aws-sdk-code-generator/generators/waiter_class.rb +0 -62
  155. data/lib/aws-sdk-code-generator/generators/waiters_module.rb +0 -20
@@ -0,0 +1,199 @@
1
+ # frozen_string_literal: true
2
+
3
+ # kramdown
4
+ require 'kramdown'
5
+ # end kramdown
6
+
7
+ module AwsSdkCodeGenerator
8
+ module Docstring
9
+ class << self
10
+
11
+ # Prefixes each line of `text` with a pound sign. Given the string
12
+ #
13
+ # Hello
14
+ # World
15
+ #
16
+ # The following string would be returned:
17
+ #
18
+ # # Hello
19
+ # # World
20
+ #
21
+ # @param [String, nil] text
22
+ # @option options [String] :gap (' ')
23
+ # @return [String, nil]
24
+ def block_comment(text, options = {})
25
+ if text
26
+ gap = options.fetch(:gap, ' ')
27
+ text.lines.map do |line|
28
+ line = line.rstrip
29
+ if line == ''
30
+ "#"
31
+ else
32
+ "##{gap}#{line}"
33
+ end
34
+ end.join("\n")
35
+ end
36
+ end
37
+
38
+ # Joins multiple doc strings into a single doc block. Each entry
39
+ # in the given `docstrings` array can be a string, nil, or an another array.
40
+ # Arrays are flattened, and nils are compacted out.
41
+ #
42
+ # Given the following `docstrings`:
43
+ #
44
+ # [
45
+ # "First doc block",
46
+ # nil,
47
+ # "Second doc block\nthat contains\nmultiple lines\n",
48
+ # [
49
+ # "Third doc block\n",
50
+ # "Last doc block\n",
51
+ # ],
52
+ # ]
53
+ #
54
+ # The following joined doc block would be returned:
55
+ #
56
+ # # First doc block
57
+ # #
58
+ # # Second doc block
59
+ # # that contains
60
+ # # multiple lines
61
+ # #
62
+ # # Third doc block
63
+ # #
64
+ # # Last doc block
65
+ #
66
+ # @param [Array<String>] docstrings
67
+ #
68
+ # @option options [Boolean] :block_comment (true)
69
+ # By default, each docstring is commented by passing
70
+ # it to {Docstring.block_comment}. Setting `:block_comment` to
71
+ # false disables this behavior.
72
+ #
73
+ # @option options [String] :gap (' ')
74
+ # This option is given to {Docstring.block_comment} when
75
+ # `:block_comment` is `true`.
76
+ #
77
+ # @option options [String] :separator (true)
78
+ # When `true`, a blank line is inserted between
79
+ # each documentation section.
80
+ #
81
+ # @return [String, nil] If the given `docstrings` is empty,
82
+ # then a `nil` is returned.
83
+ #
84
+ def join_docstrings(docstrings, options = {})
85
+ docs = docstrings.flatten.inject([]) do |sections, section|
86
+ if section.nil? || section.size == 0
87
+ sections
88
+ else
89
+ sections << (options.fetch(:block_comment, true) ?
90
+ block_comment(section, options) :
91
+ section)
92
+ sections << (options.fetch(:separator, true) ? "\n#\n" : "\n")
93
+ sections
94
+ end
95
+ end
96
+ if docs.empty?
97
+ nil
98
+ else
99
+ docs[-1] = docs[-1].rstrip
100
+ docs.join
101
+ end
102
+ end
103
+
104
+ # @param [String]
105
+ # @return [String]
106
+ def escape_html(string)
107
+ string.to_s.encode(:xml => :text)
108
+ end
109
+
110
+ # kramdown html
111
+ # @param [String<HTML>, nil] html
112
+ # @option options [Integer] :line_width (70)
113
+ # @return [String<Markdown>, nil]
114
+ def html_to_markdown(html, options = {})
115
+ line_width = options.fetch(:line_width, 70)
116
+ # TODO : this section of code is **very slow** and runs many times
117
+ # while building a service.
118
+ if html
119
+ html = "<p>#{html}</p>" unless html.match(/<\w+>/)
120
+
121
+ # unescaped curly braces cause YARD errors, they are interpreted
122
+ # as code links.
123
+ html = html.gsub('{', "\\{").gsub('}', "\\}")
124
+
125
+ # Kramdown generates invalid markup when there are attributes
126
+ # on the code tag, have to reduce these down to get the proper markdown.
127
+ html = html.gsub(/<code.*?>(.+?)<\/code>/) { "<code>#{$1}</code>" }
128
+
129
+ # Kramdown creates invalid markup with target="_blank" attributes.
130
+ html = html.gsub(' target="_blank"', '')
131
+
132
+ # There are quite a few empty <a> tags. These appear to be code names,
133
+ # such as structure member names, or structure type names. We should
134
+ # investigate if it is possible to inflect these properly and then
135
+ # turn them into YARD links.
136
+ html = html.gsub(/<a>(.+?)<\/a>/) { $1 }
137
+
138
+ # For span tags, it can contain customized attributes, e.g. data-target
139
+ # keeping text context only for now
140
+ html = html.gsub(/<span.*?>(.+?)<\/span>/) { $1 }
141
+
142
+ # <important> tag doesn't render well
143
+ html = html.gsub(/<important>(.+?)<\/important>/){ "<p>#{$1}</p>" }
144
+
145
+ # <replaceable> doesn't render anything, so sub it out for italic
146
+ html = html.gsub(/<replaceable>(.+?)<\/replaceable>/) { "<i>#{$1}</i>" }
147
+
148
+ markdown = Kramdown::Document.new(
149
+ html,
150
+ input: 'html',
151
+ line_width: line_width,
152
+ auto_ids: false
153
+ ).to_kramdown.strip
154
+
155
+ # remove extra escape
156
+ markdown.gsub(/\\(\*|`|'|")/, '\1')
157
+ end
158
+ end
159
+ # end kramdown html
160
+
161
+ # @param [Array<Array<String>>]
162
+ def markdown_table(table)
163
+ # compute the width of each column by scanning for longest values
164
+ column_width = lambda do |col|
165
+ table.map { |row| row[col].size }.max
166
+ end
167
+ widths = [
168
+ column_width.call(0),
169
+ column_width.call(1),
170
+ column_width.call(2),
171
+ column_width.call(3),
172
+ ]
173
+
174
+ # insert a dashed line after the header row
175
+ table = [
176
+ table[0],
177
+ ['-' * widths[0], '-' * widths[1], '-' * widths[2], '-' * widths[3]]
178
+ ] + table[1..-1]
179
+
180
+ # build the final table
181
+ line = "| #{widths.map{|n| "%-#{n}s" }.join(' | ')} |"
182
+ table.map { |row| line % row }.join("\n")
183
+ end
184
+
185
+ def ucfirst(string)
186
+ if string
187
+ string[0].upcase + string[1..-1]
188
+ end
189
+ end
190
+
191
+ def indent(string, space = ' ')
192
+ string.lines.map do |line|
193
+ "#{space}#{line}"
194
+ end.join.lstrip
195
+ end
196
+
197
+ end
198
+ end
199
+ end
@@ -0,0 +1,77 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AwsSdkCodeGenerator
4
+ class ErrorList
5
+
6
+ include Enumerable
7
+
8
+ def initialize(options)
9
+ @api = options[:api]
10
+ @module_name = options[:module_name]
11
+ @errors = @api['shapes'].inject([]) do |es, (name, shape)|
12
+ # only generate error shape with non empty members
13
+ # excluding event shapes marked as error
14
+ if error_struct?(shape)
15
+ members = shape['members'].inject([]) do |arr, (k, v)|
16
+ arr << {
17
+ name: Underscore.underscore(k),
18
+ type: Docstring.ucfirst(v['type'] ||'String'),
19
+ shared: k.downcase == 'message' || k.downcase == 'code'
20
+ }
21
+ arr
22
+ end
23
+ es << Error.new(
24
+ name: name,
25
+ members: members,
26
+ data_type: "#{@module_name}::Types::#{name}",
27
+ retryable: !!shape['retryable'],
28
+ throttling: throttling?(shape)
29
+ )
30
+ end
31
+ es
32
+ end
33
+ end
34
+
35
+ def error_struct?(shape)
36
+ shape['type'] == 'structure' && !!!shape['event'] &&
37
+ (shape['error'] || shape['exception'])
38
+ end
39
+
40
+ def each(&block)
41
+ @errors.each(&block)
42
+ end
43
+
44
+ def throttling?(shape)
45
+ shape['retryable'] && shape['retryable'].kind_of?(Hash) && shape['retryable']['throttling']
46
+ end
47
+
48
+
49
+ class Error
50
+
51
+ def initialize(options)
52
+ @name = options.fetch(:name)
53
+ @data_type = options[:data_type]
54
+ @members = options[:members]
55
+ @retryable = options[:retryable]
56
+ @throttling = options[:throttling]
57
+ end
58
+
59
+ # @return [String]
60
+ attr_reader :name
61
+
62
+ # @return [String]
63
+ attr_reader :data_type
64
+
65
+ # @return [Array<Hash>]
66
+ attr_reader :members
67
+
68
+ # @return [Boolean]
69
+ attr_reader :retryable
70
+
71
+ # @return [Boolean]
72
+ attr_reader :throttling
73
+
74
+ end
75
+
76
+ end
77
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module AwsSdkCodeGenerator
2
4
  module Errors
3
5
 
@@ -0,0 +1,220 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AwsSdkCodeGenerator
4
+ class EventStreamExample
5
+
6
+ def initialize(options = {})
7
+ @api = options.fetch(:api)
8
+ @method_name = options.fetch(:method_name)
9
+ @module_name = options.fetch(:module_name)
10
+ @receiver = options.fetch(:receiver)
11
+ @resp_var = options.fetch(:resp_var)
12
+ @operation = options.fetch(:operation)
13
+ @input_eventstream_member, @input_eventstream_shape = input_eventstream_shape
14
+ @output_eventstream_member, @output_eventstream_shape = output_eventstream_shape
15
+ if @input_eventstream_shape && @output_eventstream_shape &&
16
+ @input_eventstream_shape == @output_eventstream_shape
17
+ # input and output sharing same eventstream
18
+ # renaming, see EventStreamModules
19
+ @input_eventstream = "#{@module_name}::EventStreams::Input#{@input_eventstream_shape}"
20
+ @output_eventstream = "#{@module_name}::EventStreams::Output#{@output_eventstream_shape}"
21
+ else
22
+ @input_eventstream = "#{@module_name}::EventStreams::#{@input_eventstream_shape}" if @input_eventstream_shape
23
+ @output_eventstream = "#{@module_name}::EventStreams::#{@output_eventstream_shape}" if @output_eventstream_shape
24
+ end
25
+ end
26
+
27
+ def format
28
+ if @input_eventstream_member && @output_eventstream_member
29
+ bi_directional_format
30
+ elsif @output_eventstream_member
31
+ output_format
32
+ # elsif @input_eventstream_member
33
+ # input stream only is supported naturally, but
34
+ # unclear usage when just input streaming, so pending for now
35
+ end
36
+ end
37
+
38
+ def bi_directional_format
39
+ <<-EXAMPLE.strip
40
+ # @example Bi-directional EventStream Operation Example
41
+ #
42
+ # You can signal input events after initial request is
43
+ # established, events will be sent to stream
44
+ # immediately (once stream connection is established successfully).
45
+ #
46
+ # To signal events, you can call #signal methods from an #{@input_eventstream} object.
47
+ # Make sure signal events before calling #wait or #join! at async response.
48
+ #
49
+ # input_stream = #{@input_eventstream}.new
50
+ #
51
+ # async_resp = #{@receiver}.#{@method_name}( # params input,
52
+ # input_event_stream_handler: input_stream) do |out_stream|
53
+ #
54
+ # # register callbacks for events arrival
55
+ #{event_entry(:output, 'out_stream', 2)}
56
+ #
57
+ # end
58
+ # # => returns Aws::Seahorse::Client::AsyncResponse
59
+ #
60
+ # # signal events
61
+ #{event_entry(:input, 'input_stream')}
62
+ #
63
+ # # make sure signaling :end_stream in the end
64
+ # input_stream.signal_end_stream
65
+ #
66
+ # # wait until stream is closed before finalizing sync response
67
+ # resp = async_resp.wait
68
+ # # Or close stream and finalizing sync response immediately
69
+ # # resp = async_resp.join!
70
+ #
71
+ # Inorder to streamingly processing events received, you can also provide an #{@output_eventstream}
72
+ # object to register callbacks before initializing request instead of processing from request block
73
+ #
74
+ # output_stream = #{@output_eventstream}.new
75
+ # # register callbacks for events arrival
76
+ #{event_entry(:output, 'output_stream')}
77
+ #{error_event_entry('output_stream')}
78
+ #
79
+ # async_resp = #{@receiver}.#{@method_name} ( #params input,
80
+ # input_event_stream_handler: input_stream
81
+ # output_event_stream_handler: output_stream
82
+ # )
83
+ #
84
+ # resp = async_resp.wait!
85
+ #
86
+ # Besides above usage patterns for process events when they arrive immediately, you can also
87
+ # iterate through events after response complete.
88
+ #
89
+ # Events are available at #{@resp_var}.#{@output_eventstream_member} # => Enumerator
90
+ EXAMPLE
91
+ end
92
+
93
+ def output_format
94
+ <<-EXAMPLE.strip
95
+ # @example EventStream Operation Example
96
+ #
97
+ # You can process event once it arrives immediately, or wait until
98
+ # full response complete and iterate through eventstream enumerator.
99
+ #
100
+ # To interact with event immediately, you need to register ##{@method_name}
101
+ # with callbacks, callbacks can be register for specifc events or for all events,
102
+ # callback for errors in the event stream is also available for register.
103
+ #
104
+ # Callbacks can be passed in by `:event_stream_handler` option or within block
105
+ # statement attached to ##{@method_name} call directly. Hybrid pattern of both
106
+ # is also supported.
107
+ #
108
+ # `:event_stream_handler` option takes in either Proc object or
109
+ # #{@output_eventstream} object.
110
+ #
111
+ # Usage pattern a): callbacks with a block attached to ##{@method_name}
112
+ # Example for registering callbacks for all event types and error event
113
+ #
114
+ # #{@receiver}.#{@method_name}( # params input# ) do |stream|
115
+ #{error_event_entry('stream', 2)}
116
+ #
117
+ # stream.on_event do |event|
118
+ # # process all events arrive
119
+ # puts event.event_type
120
+ # ...
121
+ # end
122
+ #
123
+ # end
124
+ #
125
+ # Usage pattern b): pass in `:event_stream_handler` for ##{@method_name}
126
+ #
127
+ # 1) create a #{@output_eventstream} object
128
+ # Example for registering callbacks with specific events
129
+ #
130
+ # handler = #{@output_eventstream}.new
131
+ #{event_entry(:output, 'handler', 2)}
132
+ #
133
+ # #{@receiver}.#{@method_name}( # params input #, event_stream_handler: handler)
134
+ #
135
+ # 2) use a Ruby Proc object
136
+ # Example for registering callbacks with specific events
137
+ #
138
+ # handler = Proc.new do |stream|
139
+ #{event_entry(:output, 'stream', 2)}
140
+ # end
141
+ #
142
+ # #{@receiver}.#{@method_name}( # params input #, event_stream_handler: handler)
143
+ #
144
+ # Usage pattern c): hybird pattern of a) and b)
145
+ #
146
+ # handler = #{@output_eventstream}.new
147
+ #{event_entry(:output, 'handler', 2)}
148
+ #
149
+ # #{@receiver}.#{@method_name}( # params input #, event_stream_handler: handler) do |stream|
150
+ #{error_event_entry('stream', 2)}
151
+ # end
152
+ #
153
+ # Besides above usage patterns for process events when they arrive immediately, you can also
154
+ # iterate through events after response complete.
155
+ #
156
+ # Events are available at #{@resp_var}.#{@output_eventstream_member} # => Enumerator
157
+ # For parameter input example, please refer to following request syntax
158
+ EXAMPLE
159
+ end
160
+
161
+ def event_entry(type, ctx, indent = 0)
162
+ case type
163
+ when :input then input_event_entries(ctx, indent)
164
+ when :output then output_event_entries(ctx, indent)
165
+ end
166
+ end
167
+
168
+ def error_event_entry(ctx, indent = 0)
169
+ entries = []
170
+ entries << "# #{' ' * indent}#{ctx}.on_error_event do |event|"
171
+ entries << "# #{' ' * indent} # catch unmodeled error event in the stream"
172
+ entries << "# #{' ' * indent} raise event"
173
+ entries << "# #{' ' * indent} # => Aws::Errors::EventError"
174
+ entries << "# #{' ' * indent} # event.event_type => :error"
175
+ entries << "# #{' ' * indent} # event.error_code => String"
176
+ entries << "# #{' ' * indent} # event.error_message => String"
177
+ entries << "# #{' ' * indent}end"
178
+ entries.join("\n")
179
+ end
180
+
181
+ def input_event_entries(ctx, indent = 0)
182
+ @api['shapes'][@input_eventstream_shape]['members'].each.inject([]) do |entries, (name, _)|
183
+ event_type = Underscore.underscore(name)
184
+ # TODO, place holder values
185
+ entries << "# #{' ' * indent}#{ctx}.signal_#{event_type}_event( ... )"
186
+ entries
187
+ end.join("\n")
188
+ end
189
+
190
+ def output_event_entries(ctx, indent = 0)
191
+ @api['shapes'][@output_eventstream_shape]['members'].keys.each.inject([]) do |entry, name|
192
+ event_type = Underscore.underscore(name)
193
+ entry << "# #{' ' * indent}#{ctx}.on_#{event_type}_event do |event|"
194
+ entry << "# #{' ' * indent}event # => #{@module_name}::Types::#{name}"
195
+ entry << "# #{' ' * indent}end"
196
+ end.join("\n")
197
+ end
198
+
199
+ def input_eventstream_shape
200
+ input_shape = @api['shapes'][@operation['input']['shape']] if @operation['input']
201
+ if input_shape
202
+ input_shape['members'].each do |name, ref|
203
+ return [Underscore.underscore(name), ref['shape']] if Api.eventstream?(ref, @api)
204
+ end
205
+ end
206
+ nil
207
+ end
208
+
209
+ def output_eventstream_shape
210
+ output_shape = @api['shapes'][@operation['output']['shape']] if @operation['output']
211
+ if output_shape
212
+ output_shape['members'].each do |name, ref|
213
+ return [Underscore.underscore(name), ref['shape']] if Api.eventstream?(ref, @api)
214
+ end
215
+ end
216
+ nil
217
+ end
218
+ end
219
+
220
+ end
@@ -1,25 +1,37 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module AwsSdkCodeGenerator
2
4
  class GemBuilder
3
5
 
4
6
  # @param [Hash] options
5
- # @option options [required, Service] :service
7
+ # @option (see CodeBuilder#initialize)
6
8
  def initialize(options)
7
9
  @options = options
8
10
  @service = options.fetch(:service)
11
+ validate_model!
9
12
  end
10
13
 
11
14
  # @return [Hash]
12
15
  attr_reader :options
13
16
 
17
+ def validate_model!
18
+ validate_document_support!
19
+ end
20
+
14
21
  def each(&block)
15
22
  Enumerator.new do |y|
16
- y.yield(gemspec_path, gemspec_file)
17
- y.yield(features_env_path, features_env_file)
18
- y.yield(features_step_definitions_path, features_step_definitions_file)
19
- y.yield(spec_helper_path, spec_helper_file)
20
- y.yield(version_path, version_file)
23
+ y.yield("#{@service.gem_name}.gemspec", gemspec_file)
24
+ y.yield('features/env.rb', features_env_file)
25
+ y.yield('features/step_definitions.rb', features_step_definitions_file)
26
+ y.yield('spec/spec_helper.rb', spec_helper_file)
27
+ if @service.smoke_tests
28
+ y.yield('features/smoke.feature', smoke_file)
29
+ y.yield('features/smoke_step_definitions.rb', smoke_step_definitions_file)
30
+ end
31
+ y.yield('VERSION', version_file)
32
+ y.yield('LICENSE.txt', license_file)
21
33
  code = CodeBuilder.new(@options)
22
- code.source_files(prefix: @service.gem_name).each do |path, code|
34
+ code.source_files.each do |path, code|
23
35
  y.yield("lib/#{path}", code)
24
36
  end
25
37
  end.each(&block)
@@ -27,45 +39,50 @@ module AwsSdkCodeGenerator
27
39
 
28
40
  private
29
41
 
30
- def gemspec_path
31
- "#{@service.gem_name}.gemspec"
32
- end
33
-
34
42
  def gemspec_file
35
43
  Views::Gemspec.new(options).render
36
44
  end
37
45
 
38
- def features_env_path
39
- 'features/env.rb'
40
- end
41
-
42
46
  def features_env_file
43
47
  Views::Features::Env.new(options).render
44
48
  end
45
49
 
46
- def features_step_definitions_path
47
- 'features/step_definitions.rb'
50
+ def smoke_file
51
+ Views::Features::Smoke.new(options).render
48
52
  end
49
53
 
50
- def features_step_definitions_file
51
- Views::Features::StepDefinitions.new(options).render
54
+ def smoke_step_definitions_file
55
+ Views::Features::SmokeStepDefinitions.new(options).render
52
56
  end
53
57
 
54
- def spec_helper_path
55
- 'spec/spec_helper.rb'
58
+ def features_step_definitions_file
59
+ Views::Features::StepDefinitions.new(options).render
56
60
  end
57
61
 
58
62
  def spec_helper_file
59
63
  Views::Spec::SpecHelper.new(options).render
60
64
  end
61
65
 
62
- def version_path
63
- 'VERSION'
64
- end
65
-
66
66
  def version_file
67
67
  Views::Version.new(options).render
68
68
  end
69
69
 
70
+ def license_file
71
+ File.read(File.expand_path('../../../templates/license.txt',__FILE__ ))
72
+ end
73
+
74
+ private
75
+
76
+ # document types are only supported for rest-json and json
77
+ def validate_document_support!
78
+ return if ['rest-json', 'json'].include?(@service.protocol)
79
+
80
+ # Check all shapes and raise if any are Document types
81
+ @service.api.fetch('shapes', {}).each do |name, shape|
82
+ if shape['type'] == 'structure' && shape['document']
83
+ raise "Shape #{name} is a document type. Document types are only supported in json protocols."
84
+ end
85
+ end
86
+ end
70
87
  end
71
88
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module AwsSdkCodeGenerator
2
4
  class HashFormatter
3
5
 
@@ -15,10 +17,11 @@ module AwsSdkCodeGenerator
15
17
  @wrap = options.fetch(:wrap, true)
16
18
  @inline = options.fetch(:inline, false)
17
19
  @quote_strings = options.fetch(:quote_strings, false)
20
+ @indent = options.fetch(:indent, '')
18
21
  end
19
22
 
20
23
  def format(obj)
21
- result = hash(obj, i:'', inline:@inline)
24
+ result = hash(obj, i: @indent, inline:@inline)
22
25
  result = unwrap(result, obj.size) if !@wrap
23
26
  result = result.strip if @inline && result.lines.to_a.length == 1
24
27
  result
@@ -34,7 +37,7 @@ module AwsSdkCodeGenerator
34
37
  when Array then array(obj, i:i)
35
38
  when String then @quote_strings ? obj.inspect : obj
36
39
  when Symbol then obj.inspect
37
- when Fixnum, true, false then obj.inspect
40
+ when Integer, true, false then obj.inspect
38
41
  else raise ArgumentError, "unsupported value `#{obj.class}'"
39
42
  end
40
43
  end