open_api_import 0.10.9 → 0.11.0

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.
@@ -0,0 +1,693 @@
1
+ class OpenApiImport
2
+ ##############################################################################################
3
+ # Import a Swagger or Open API file and create a Ruby Request Hash file including all requests and responses.
4
+ # The http methods that will be treated are: 'get','post','put','delete', 'patch'.
5
+ # @param swagger_file [String]. Path and file name. Could be absolute or relative to project root folder.
6
+ # @param include_responses [Boolean]. (default: true) if you want to add the examples of responses in the resultant file.
7
+ # @param mock_response [Boolean]. (default:false) Add the first response on the request as mock_response to be used.
8
+ # In case using nice_http gem: if NiceHttp.use_mocks = true will use it instead of getting the real response from the WS.
9
+ # @param create_method_name [Symbol]. (:path, :operation_id, :operationId) (default: operation_id). How the name of the methods will be generated.
10
+ # path: it will be used the path and http method, for example for a GET on path: /users/list, the method name will be get_users_list
11
+ # operation_id: it will be used the operationId field but using the snake_case version, for example for listUsers: list_users
12
+ # operationId: it will be used the operationId field like it is, for example: listUsers
13
+ # @param name_for_module [Symbol]. (:path, :path_file, :fixed, :tags, :tags_file) (default: :path). How the module names will be created.
14
+ # @param create_constants [Boolean]. (default: false) For required arguments, it will create keyword arguments assigning by default a constant.
15
+ # @param silent [Boolean]. (default: false) It will display only errors.
16
+ # path: It will be used the first folder of the path to create the module name, for example the path /users/list will be in the module Users and all the requests from all modules in the same file.
17
+ # path_file: It will be used the first folder of the path to create the module name, for example the path /users/list will be in the module Users and each module will be in a new requests file.
18
+ # tags: It will be used the tags key to create the module name, for example the tags: [users,list] will create the module UsersList and all the requests from all modules in the same file.
19
+ # tags_file: It will be used the tags key to create the module name, for example the tags: [users,list] will create the module UsersList and and each module will be in a new requests file.
20
+ # fixed: all the requests will be under the module Requests
21
+ ##############################################################################################
22
+ def self.from(swagger_file, create_method_name: :operation_id, include_responses: true, mock_response: false, name_for_module: :path, silent: false, create_constants: false)
23
+ begin
24
+ f = File.new("#{swagger_file}_open_api_import.log", "w")
25
+ f.sync = true
26
+ @logger = Logger.new f
27
+ puts "Logs file: #{swagger_file}_open_api_import.log" unless silent
28
+ rescue StandardError => e
29
+ warn "Not possible to create the Logger file"
30
+ warn e
31
+ @logger = Logger.new nil
32
+ end
33
+
34
+ begin
35
+ @logger.info "swagger_file: #{swagger_file}, include_responses: #{include_responses}, mock_response: #{mock_response}\n"
36
+ @logger.info "create_method_name: #{create_method_name}, name_for_module: #{name_for_module}\n"
37
+
38
+ file_to_convert = if swagger_file["./"].nil?
39
+ swagger_file
40
+ else
41
+ Dir.pwd.to_s + "/" + swagger_file.gsub("./", "")
42
+ end
43
+ unless File.exist?(file_to_convert)
44
+ raise "The file #{file_to_convert} doesn't exist"
45
+ end
46
+
47
+ file_errors = file_to_convert + ".errors.log"
48
+ File.delete(file_errors) if File.exist?(file_errors)
49
+ import_errors = ""
50
+ required_constants = []
51
+
52
+ begin
53
+ definition = OasParser::Definition.resolve(swagger_file)
54
+ rescue Exception => stack
55
+ message = "There was a problem parsing the Open Api document using the oas_parser gem. The execution was aborted.\n"
56
+ message += "Visit the github for oas_parser gem for bugs and more info: https://github.com/Nexmo/oas_parser\n"
57
+ message += "Error: #{stack.message}"
58
+ puts message
59
+ @logger.fatal message
60
+ @logger.fatal stack.backtrace
61
+ exit!
62
+ end
63
+
64
+ raw = definition.raw.deep_symbolize_keys
65
+
66
+ if raw.key?(:openapi) && (raw[:openapi].to_f > 0)
67
+ raw[:swagger] = raw[:openapi]
68
+ end
69
+ if raw[:swagger].to_f < 2.0
70
+ raise "Unsupported Swagger version. Only versions >= 2.0 are valid."
71
+ end
72
+
73
+ base_host = ""
74
+ base_path = ""
75
+
76
+ base_host = raw[:host] if raw.key?(:host)
77
+ base_path = raw[:basePath] if raw.key?(:basePath)
78
+ module_name = raw[:info][:title].camel_case
79
+ module_version = "V#{raw[:info][:version].to_s.snake_case}"
80
+
81
+ output = []
82
+ output_header = []
83
+ output_header << "#" * 50
84
+ output_header << "# #{raw[:info][:title]}"
85
+ output_header << "# version: #{raw[:info][:version]}"
86
+ output_header << "# description: "
87
+ raw[:info][:description].to_s.split("\n").each do |d|
88
+ output_header << "# #{d}" unless d == ""
89
+ end
90
+ output_header << "#" * 50
91
+
92
+ output_header << "module Swagger"
93
+ output_header << "module #{module_name}"
94
+ output_header << "module #{module_version}"
95
+ output_header << "module Requests" if name_for_module == :fixed
96
+
97
+ files = {}
98
+
99
+ module_requests = ""
100
+
101
+ definition.paths.each do |path|
102
+ raw = path.raw.deep_symbolize_keys
103
+
104
+ if raw.key?(:parameters)
105
+ raw.each do |met, cont|
106
+ if met != :parameters
107
+ if raw[met].key?(:parameters)
108
+ #in case parameters for all methods in path is present
109
+ raw[met][:parameters] = raw[met][:parameters] + raw[:parameters]
110
+ else
111
+ raw[met][:parameters] = raw[:parameters]
112
+ end
113
+ end
114
+ end
115
+ raw.delete(:parameters)
116
+ end
117
+
118
+ raw.each do |met, cont|
119
+ if %w[get post put delete patch].include?(met.to_s.downcase)
120
+ params = []
121
+ params_path = []
122
+ params_query = []
123
+ params_required = []
124
+ params_data = []
125
+ description_parameters = []
126
+ data_form = []
127
+ data_required = []
128
+ #todo: add nested one.true.three to data_read_only
129
+ data_read_only = []
130
+ data_default = []
131
+ data_examples = []
132
+ data_pattern = []
133
+ responses = []
134
+
135
+ # for the case operationId is missing
136
+ cont[:operationId] = "undefined" unless cont.key?(:operationId)
137
+
138
+ if create_method_name == :path
139
+ method_name = (met.to_s + "_" + path.path.to_s).snake_case
140
+ method_name.chop! if method_name[-1] == "_"
141
+ elsif create_method_name == :operation_id
142
+ if (name_for_module == :tags or name_for_module == :tags_file) and cont.key?(:tags) and cont[:tags].is_a?(Array) and cont[:tags].size > 0
143
+ metnametmp = cont[:operationId].gsub(/^#{cont[:tags].join}[\s_]*/, "")
144
+ cont[:tags].join.split(" ").each do |tag|
145
+ metnametmp.gsub!(/^#{tag}[\s_]*/i, "")
146
+ end
147
+ metnametmp = met if metnametmp == ""
148
+ else
149
+ metnametmp = cont[:operationId]
150
+ end
151
+ method_name = metnametmp.to_s.snake_case
152
+ else
153
+ if (name_for_module == :tags or name_for_module == :tags_file) and cont.key?(:tags) and cont[:tags].is_a?(Array) and cont[:tags].size > 0
154
+ method_name = cont[:operationId].gsub(/^#{cont[:tags].join}[\s_]*/, "")
155
+ cont[:tags].join.split(" ").each do |tag|
156
+ method_name.gsub!(/^#{tag}[\s_]*/i, "")
157
+ end
158
+ method_name = met if method_name == ""
159
+ else
160
+ method_name = cont[:operationId]
161
+ end
162
+ end
163
+ path_txt = path.path.dup.to_s
164
+ if [:path, :path_file, :tags, :tags_file].include?(name_for_module)
165
+ old_module_requests = module_requests
166
+ if [:path, :path_file].include?(name_for_module)
167
+ # to remove version from path fex: /v1/Customer
168
+ path_requests = path_txt.gsub(/^\/v[\d\.]*\//i, "")
169
+ # to remove version from path fex: /1.0/Customer
170
+ path_requests = path_requests.gsub(/^\/[\d\.]*\//i, "")
171
+ if (path_requests == path_txt) && (path_txt.scan("/").size == 1)
172
+ # no folder in path
173
+ module_requests = "Root"
174
+ else
175
+ res_path = path_requests.scan(/(\w+)/)
176
+ module_requests = res_path[0][0].camel_case
177
+ end
178
+ else
179
+ if cont.key?(:tags) and cont[:tags].is_a?(Array) and cont[:tags].size > 0
180
+ module_requests = cont[:tags].join(" ").camel_case
181
+ else
182
+ module_requests = "Undefined"
183
+ end
184
+ end
185
+
186
+ # to remove from method_name: v1_list_regions and add it to module
187
+ if /^(?<vers>v\d+)/i =~ method_name
188
+ method_name.gsub!(/^#{vers}_?/, "")
189
+ module_requests = (vers.capitalize + module_requests).camel_case unless module_requests.start_with?(vers)
190
+ end
191
+
192
+ if old_module_requests != module_requests
193
+ output << "end" unless old_module_requests == "" or name_for_module == :path_file or name_for_module == :tags_file
194
+ if name_for_module == :path or name_for_module == :tags
195
+ # to add the end for the previous module unless is the first one
196
+ output << "module #{module_requests}"
197
+ else #:path_file, :tags_file
198
+ if old_module_requests != ""
199
+ unless files.key?(old_module_requests)
200
+ files[old_module_requests] = Array.new
201
+ end
202
+ files[old_module_requests].concat(output)
203
+ output = Array.new
204
+ end
205
+ output << "module #{module_requests}" unless files.key?(module_requests) # don't add in case already existed
206
+ end
207
+ end
208
+ end
209
+
210
+ output << ""
211
+ output << "# operationId: #{cont[:operationId]}, method: #{met}"
212
+ output << "# summary: #{cont[:summary]}"
213
+ if !cont[:description].to_s.split("\n").empty?
214
+ output << "# description: "
215
+ cont[:description].to_s.split("\n").each do |d|
216
+ output << "# #{d}" unless d == ""
217
+ end
218
+ else
219
+ output << "# description: #{cont[:description]}"
220
+ end
221
+
222
+ mock_example = []
223
+
224
+ if include_responses && cont.key?(:responses) && cont[:responses].is_a?(Hash)
225
+ cont[:responses].each do |k, v|
226
+ response_example = []
227
+ response_example = get_response_examples(v)
228
+
229
+ data_pattern += get_patterns("", v[:schema]) if v.key?(:schema)
230
+ data_pattern.uniq!
231
+ v[:description] = v[:description].to_s.gsub("'", %q(\\\'))
232
+ if !response_example.empty?
233
+ responses << "'#{k}': { "
234
+ responses << "message: '#{v[:description]}', "
235
+ responses << "data: "
236
+ responses << response_example
237
+ responses << "},"
238
+ if mock_response and mock_example.size == 0
239
+ mock_example << "code: '#{k}',"
240
+ mock_example << "message: '#{v[:description]}',"
241
+ mock_example << "data: "
242
+ mock_example << response_example
243
+ end
244
+ else
245
+ responses << "'#{k}': { message: '#{v[:description]}'}, "
246
+ end
247
+ end
248
+ end
249
+ # todo: for open api 3.0 add the new Link feature: https://swagger.io/docs/specification/links/
250
+ # todo: for open api 3.0 is not getting the required params in all cases
251
+
252
+ # for the case open api 3 with cont.requestBody.content.'applicatin/json'.schema
253
+ # example: petstore-expanded.yaml operationId=addPet
254
+ if cont.key?(:requestBody) and cont[:requestBody].key?(:content) and
255
+ cont[:requestBody][:content].key?(:'application/json') and cont[:requestBody][:content][:'application/json'].key?(:schema)
256
+ cont[:parameters] = [] unless cont.key?(:parameters)
257
+ cont[:parameters] << { in: "body", schema: cont[:requestBody][:content][:'application/json'][:schema] }
258
+ end
259
+
260
+ data_examples_all_of = false
261
+ if cont.key?(:parameters) && cont[:parameters].is_a?(Array)
262
+ cont[:parameters].each do |p|
263
+ if p.keys.include?(:schema) and p[:schema].include?(:type)
264
+ type = p[:schema][:type]
265
+ elsif p.keys.include?(:type)
266
+ type = p[:type]
267
+ else
268
+ type = ""
269
+ end
270
+
271
+ if p[:in] == "path"
272
+ if create_method_name == :operationId
273
+ param_name = p[:name]
274
+ path_txt.gsub!("{#{param_name}}", "\#{#{param_name}}")
275
+ else
276
+ param_name = p[:name].to_s.snake_case
277
+ path_txt.gsub!("{#{p[:name]}}", "\#{#{param_name}}")
278
+ end
279
+ unless params_path.include?(param_name)
280
+ if create_constants
281
+ params_path << "#{param_name}: #{param_name.upcase}"
282
+ required_constants << param_name.upcase
283
+ else
284
+ params_path << param_name
285
+ end
286
+ #params_required << param_name if p[:required].to_s=="true"
287
+ description_parameters << "# #{p[:name]}: (#{type}) #{"(required)" if p[:required].to_s == "true"} #{p[:description].split("\n").join("\n#\t\t\t")}"
288
+ end
289
+ elsif p[:in] == "query"
290
+ params_query << p[:name]
291
+ params_required << p[:name] if p[:required].to_s == "true"
292
+ description_parameters << "# #{p[:name]}: (#{type}) #{"(required)" if p[:required].to_s == "true"} #{p[:description].split("\n").join("\n#\t\t\t")}"
293
+ elsif p[:in] == "formData" or p[:in] == "formdata"
294
+ #todo: take in consideration: default, required
295
+ #todo: see if we should add the required as params to the method and not required as options
296
+ #todo: set on data the required fields with the values from args
297
+
298
+ description_parameters << "# #{p[:name]}: (#{p[:type]}) #{p[:description].split("\n").join("\n#\t\t\t")}"
299
+
300
+ case p[:type]
301
+ when /^string$/i
302
+ data_form << "#{p[:name]}: ''"
303
+ when /^boolean$/i
304
+ data_form << "#{p[:name]}: true"
305
+ when /^number$/i
306
+ data_form << "#{p[:name]}: 0"
307
+ when /^integer$/i
308
+ data_form << "#{p[:name]}: 0"
309
+ else
310
+ puts "! on formData not supported type #{p[:type]}"
311
+ end
312
+ elsif p[:in] == "body"
313
+ if p.keys.include?(:schema)
314
+ if p[:schema].key?(:oneOf)
315
+ bodies = p[:schema][:oneOf]
316
+ elsif p[:schema].key?(:anyOf)
317
+ bodies = p[:schema][:anyOf]
318
+ elsif p[:schema].key?(:allOf)
319
+ data_examples_all_of, bodies = get_data_all_of_bodies(p)
320
+ bodies.unshift(p[:schema]) if p[:schema].key?(:required) or p.key?(:required) #todo: check if this 'if' is necessary
321
+ data_examples_all_of = true # because we are on data and allOf already
322
+ else
323
+ bodies = [p[:schema]]
324
+ end
325
+
326
+ params_data = []
327
+
328
+ bodies.each do |body|
329
+ data_required += get_required_data(body)
330
+ all_properties = []
331
+ all_properties << body[:properties] if body.keys.include?(:properties) and body[:properties].size > 0
332
+ if body.key?(:allOf)
333
+ body[:allOf].each do |item|
334
+ all_properties << item[:properties] if item.key?(:properties)
335
+ end
336
+ end
337
+
338
+ all_properties.each do |props|
339
+ props.each { |dpk, dpv|
340
+ if dpv.keys.include?(:example)
341
+ if dpv[:example].is_a?(Array) and dpv.type != "array"
342
+ valv = dpv[:example][0]
343
+ else
344
+ valv = dpv[:example].to_s
345
+ end
346
+ else
347
+ if dpv.type == "object"
348
+ if dpv.key?(:properties)
349
+ valv = get_examples(dpv[:properties], :key_value, true).join("\n")
350
+ else
351
+ valv = "{}"
352
+ end
353
+ elsif dpv.type == "array"
354
+ if dpv.key?(:items)
355
+ valv = get_examples({ dpk => dpv }, :only_value)
356
+ valv = valv.join("\n")
357
+ else
358
+ valv = "[]"
359
+ end
360
+ else
361
+ valv = ""
362
+ end
363
+ end
364
+
365
+ if dpv.keys.include?(:description)
366
+ description_parameters << "# #{dpk}: (#{dpv[:type]}) #{dpv[:description].split("\n").join("\n#\t\t\t")}"
367
+ end
368
+
369
+ data_pattern += get_patterns(dpk, dpv)
370
+ data_pattern.uniq!
371
+ dpkeys = []
372
+ data_pattern.reject! do |dp|
373
+ dpkey = dp.scan(/^'[\w\.]+'/)
374
+
375
+ if dpkeys.include?(dpkey)
376
+ true
377
+ else
378
+ dpkeys << dpkey
379
+ false
380
+ end
381
+ end
382
+
383
+ if dpv.keys.include?(:readOnly) and dpv[:readOnly] == true
384
+ data_read_only << dpk
385
+ end
386
+ if dpv.keys.include?(:default)
387
+ if dpv[:default].nil?
388
+ data_default << "#{dpk}: nil"
389
+ elsif dpv.type != "string"
390
+ data_default << "#{dpk}: #{dpv[:default]}"
391
+ else
392
+ data_default << "#{dpk}: '#{dpv[:default]}'"
393
+ end
394
+ end
395
+
396
+ #todo: consider check default and insert it
397
+ #todo: remove array from here and add the option to get_examples for the case thisisthekey: ['xxxx']
398
+ if dpv.key?(:type) and dpv[:type] != "array"
399
+ params_data << get_examples({ dpk => dpv }, :only_value, true).join
400
+ params_data[-1].chop!.chop! if params_data[-1].to_s[-2..-1] == ", "
401
+ params_data.pop if params_data[-1].match?(/^\s*$/im)
402
+ else
403
+ if valv.to_s == ""
404
+ valv = '""'
405
+ elsif valv.include?('"')
406
+ valv.gsub!('"', "'")
407
+ end
408
+ params_data << "#{dpk}: #{valv}"
409
+ end
410
+ }
411
+ if params_data.size > 0
412
+ if data_examples_all_of == true and data_examples.size > 0
413
+ data_examples[0] += params_data
414
+ else
415
+ data_examples << params_data
416
+ end
417
+ params_data = []
418
+ end
419
+ end
420
+ end
421
+
422
+ unless data_required.empty?
423
+ data_required.uniq!
424
+ output << "# required data: #{data_required.inspect}"
425
+ end
426
+ end
427
+ elsif p[:in] == "header"
428
+ #todo: see how we can treat those cases
429
+ else
430
+ puts "! not imported data with :in:#{p[:in]} => #{p.inspect}"
431
+ end
432
+ end
433
+
434
+ params = params_path
435
+
436
+ unless params_query.empty?
437
+ path_txt += "?"
438
+ params_required.each do |pr|
439
+ if create_constants
440
+ if params_query.include?(pr)
441
+ if create_method_name == :operationId
442
+ path_txt += "#{pr}=\#{#{pr}}&"
443
+ params << "#{pr}: #{pr.upcase}"
444
+ required_constants << pr.upcase
445
+ else
446
+ path_txt += "#{pr}=\#{#{pr.to_s.snake_case}}&"
447
+ params << "#{pr.to_s.snake_case}: #{pr.to_s.snake_case.upcase}"
448
+ required_constants << pr.to_s.snake_case.upcase
449
+ end
450
+ end
451
+ else
452
+ if params_query.include?(pr)
453
+ if create_method_name == :operationId
454
+ path_txt += "#{pr}=\#{#{pr}}&"
455
+ params << "#{pr}"
456
+ else
457
+ path_txt += "#{pr}=\#{#{pr.to_s.snake_case}}&"
458
+ params << "#{pr.to_s.snake_case}"
459
+ end
460
+ end
461
+ end
462
+ end
463
+ params_query.each do |pq|
464
+ unless params_required.include?(pq)
465
+ if create_method_name == :operationId
466
+ path_txt += "#{pq}=\#{#{pq}}&"
467
+ params << "#{pq}: ''"
468
+ else
469
+ path_txt += "#{pq}=\#{#{pq.to_s.snake_case}}&"
470
+ params << "#{pq.to_s.snake_case}: ''"
471
+ end
472
+ end
473
+ end
474
+ end
475
+ end
476
+
477
+ if description_parameters.size > 0
478
+ output << "# parameters description: "
479
+ output << description_parameters.uniq
480
+ end
481
+
482
+ #for the case we still have some parameters on path that were not in 'parameters'
483
+ if path_txt.scan(/[^#]{\w+}/).size > 0
484
+ paramst = []
485
+ prms = path_txt.scan(/[^#]{(\w+)}/)
486
+ prms.each do |p|
487
+ #if create_constants
488
+ # paramst<<"#{p[0].to_s.snake_case}: #{p[0].to_s.snake_case.upcase}"
489
+ # required_constants << p[0].to_s.snake_case.upcase
490
+ #else
491
+ paramst << p[0].to_s.snake_case
492
+ #end
493
+ path_txt.gsub!("{#{p[0]}}", "\#{#{p[0].to_s.snake_case}}")
494
+ end
495
+ paramst.concat params
496
+ params = paramst
497
+ end
498
+ params.uniq!
499
+ output << "def self.#{method_name} (#{params.join(", ")})"
500
+
501
+ output << "{"
502
+
503
+ output << "name: \"#{module_requests}.#{method_name}\","
504
+
505
+ output << "path: \"#{base_path}#{path_txt}\","
506
+
507
+ output << "method: :#{met}," if met.to_s != ""
508
+
509
+ unless data_required.empty?
510
+ output << "data_required: ["
511
+ output << ":'#{data_required.uniq.join("', :'")}'"
512
+ output << "],"
513
+ end
514
+ unless data_read_only.empty?
515
+ output << "data_read_only: ["
516
+ output << ":'#{data_read_only.uniq.join("', :'")}'"
517
+ output << "],"
518
+ end
519
+ unless data_default.empty?
520
+ output << "data_default: {"
521
+ data_default.uniq!
522
+ output << data_default.join(", \n")
523
+ output << "},"
524
+ end
525
+
526
+ unless data_pattern.empty?
527
+ output << "data_pattern: {"
528
+ output << data_pattern.uniq.join(", \n")
529
+ output << "},"
530
+ end
531
+
532
+ unless data_form.empty?
533
+ data_examples << data_form
534
+ end
535
+
536
+ unless data_examples.empty?
537
+ unless data_required.empty?
538
+ reqdata = []
539
+ begin
540
+ data_examples[0].uniq!
541
+ data_ex = eval("{#{data_examples[0].join(", ")}}")
542
+ rescue
543
+ data_ex = {}
544
+ end
545
+ if (data_required.grep(/\./)).empty?
546
+ reqdata = filter(data_ex, data_required) #not nested
547
+ else
548
+ reqdata = filter(data_ex, data_required, true) #nested
549
+ end
550
+ unless reqdata.empty?
551
+ phsd = pretty_hash_symbolized(reqdata)
552
+ phsd[0] = "data: {"
553
+ output += phsd
554
+ end
555
+ end
556
+ unless data_read_only.empty? or !data_required.empty?
557
+ reqdata = []
558
+ #remove read only fields from :data
559
+ data_examples[0].each do |edata|
560
+ read_only = false
561
+ data_read_only.each do |rdata|
562
+ if edata.scan(/^#{rdata}:/).size > 0
563
+ read_only = true
564
+ break
565
+ elsif edata.scan(/:/).size == 0
566
+ break
567
+ end
568
+ end
569
+ reqdata << edata unless read_only
570
+ end
571
+ unless reqdata.empty?
572
+ output << "data: {"
573
+ output << reqdata.join(", \n")
574
+ output << "},"
575
+ end
576
+ end
577
+
578
+ output << "data_examples: ["
579
+ data_examples.each do |data|
580
+ output << "{"
581
+ data.uniq!
582
+ output << data.join(", \n")
583
+ output << "}, "
584
+ end
585
+ output << "],"
586
+ end
587
+
588
+ unless mock_example.empty?
589
+ output << "mock_response: {"
590
+ output << mock_example
591
+ output << "},"
592
+ end
593
+
594
+ unless responses.empty?
595
+ output << "responses: {"
596
+ output << responses
597
+ output << "},"
598
+ end
599
+
600
+ output << "}"
601
+ output << "end"
602
+ else
603
+ @logger.warn "Not imported method: #{met} for path: #{path.path} since it is not supported by OpenApiImport"
604
+ end
605
+ end
606
+ end
607
+ output_footer = []
608
+
609
+ output_footer << "end" unless (module_requests == "") && ([:path, :path_file, :tags, :tags_file].include?(name_for_module))
610
+ output_footer << "end" << "end" << "end"
611
+
612
+ if files.size == 0
613
+ output = output_header + output + output_footer
614
+ output_txt = output.join("\n")
615
+ requests_file_path = file_to_convert + ".rb"
616
+ File.open(requests_file_path, "w") { |file| file.write(output_txt) }
617
+ res_rufo = `rufo #{requests_file_path}`
618
+ message = "** Requests file: #{swagger_file}.rb that contains the code of the requests after importing the Swagger file"
619
+ puts message unless silent
620
+ @logger.info message
621
+ @logger.error " Error formating with rufo" unless res_rufo.to_s.match?(/\AFormat:.+$\s*\z/)
622
+ @logger.error " Syntax Error: #{`ruby -c #{requests_file_path}`}" unless `ruby -c #{requests_file_path}`.include?("Syntax OK")
623
+ else
624
+ unless files.key?(module_requests)
625
+ files[module_requests] = Array.new
626
+ end
627
+ files[module_requests].concat(output) #for the last one
628
+
629
+ requires_txt = ""
630
+ message = "** Generated files that contain the code of the requests after importing the Swagger file: "
631
+ puts message unless silent
632
+ @logger.info message
633
+ files.each do |mod, out_mod|
634
+ output = output_header + out_mod + output_footer
635
+ output_txt = output.join("\n")
636
+ requests_file_path = file_to_convert + "_" + mod + ".rb"
637
+ requires_txt += "require_relative '#{File.basename(swagger_file)}_#{mod}'\n"
638
+ File.open(requests_file_path, "w") { |file| file.write(output_txt) }
639
+ res_rufo = `rufo #{requests_file_path}`
640
+ message = " - #{requests_file_path}"
641
+ puts message unless silent
642
+ @logger.info message
643
+ @logger.error " Error formating with rufo" unless res_rufo.to_s.match?(/\AFormat:.+$\s*\z/)
644
+ @logger.error " Syntax Error: #{`ruby -c #{requests_file_path}`}" unless `ruby -c #{requests_file_path}`.include?("Syntax OK")
645
+ end
646
+
647
+ requests_file_path = file_to_convert + ".rb"
648
+ if required_constants.size > 0
649
+ rconsts = "# Required constants\n"
650
+ required_constants.uniq!
651
+ required_constants.each do |rq|
652
+ rconsts += "#{rq} ||= ENV['#{rq}'] ||=''\n"
653
+ end
654
+ rconsts += "\n\n"
655
+ else
656
+ rconsts = ""
657
+ end
658
+
659
+ File.open(requests_file_path, "w") { |file| file.write(rconsts + requires_txt) }
660
+ res_rufo = `rufo #{requests_file_path}`
661
+ message = "** File that contains all the requires for all Request files: \n"
662
+ message += " - #{requests_file_path} "
663
+ puts message unless silent
664
+ @logger.info message
665
+ @logger.error " Error formating with rufo" unless res_rufo.to_s.match?(/\AFormat:.+$\s*\z/)
666
+ @logger.error " Syntax Error: #{`ruby -c #{requests_file_path}`}" unless `ruby -c #{requests_file_path}`.include?("Syntax OK")
667
+ end
668
+
669
+ begin
670
+ res = eval(output_txt)
671
+ rescue Exception => stack
672
+ import_errors += "\n\nResult evaluating the ruby file generated: \n" + stack.to_s
673
+ end
674
+
675
+ if import_errors.to_s != ""
676
+ File.open(file_errors, "w") { |file| file.write(import_errors) }
677
+ message = "* It seems there was a problem importing the Swagger file #{file_to_convert}\n"
678
+ message += "* Take a look at the detected errors at #{file_errors}\n"
679
+ warn message
680
+ @logger.fatal message
681
+ return false
682
+ else
683
+ return true
684
+ end
685
+ rescue StandardError => stack
686
+ puts stack.message
687
+ @logger.fatal stack.message
688
+ @logger.fatal stack.backtrace
689
+ puts stack.backtrace
690
+ end
691
+ end
692
+ end
693
+