open_api_import 0.10.9 → 0.11.0

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