openapi-sourcetools 0.7.0 → 0.8.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 211083083a2a3c53321234416ffff41bd1d00320a5ebbdab3ccdcd49576653b3
4
- data.tar.gz: 34535443138a6308869974d62e79321d9ec9dbb3f46434c19d571075044751e1
3
+ metadata.gz: 783a57d4ca224bb9710cb523d3ee2fd2dee0e821cb7382ffc32fa9b8cb36b4f1
4
+ data.tar.gz: b7c02ac6cd2e30fc4f9f5d9fb87bfcd84b8f60b76007e82d82a1a1bfb7f37e42
5
5
  SHA512:
6
- metadata.gz: 3c4a5361e25a1cf7903b6038a32f4a94cf42579c0c4fefb21f885fae996c219a02eef322fd91d694dfe0ff668314685b990d3128ca7e6a98c3f30660639494d0
7
- data.tar.gz: a563ba480140037e0ef91dbdc89fb62a2175954897726717976760879a74bf8284d673d3a259ce338b7b7493c84fd6c1f5cf4246b90ee42ae1959d3b31c7b21f
6
+ metadata.gz: eec2859f712324b85f9db32f5c92d4e3947a80021f9bf920f287f9b01a2a56ab7d20e3f2b5d30e039a2e606e57b4ca0f0b5872961e91f1898c44c402eade14ef
7
+ data.tar.gz: 72bbafa47688fd1eb3dd78d1ff0782d8e1a3510e541e4ad4f4e49ceec056cedaf9c6ebbbbe4dd9c7c6b446f3c0dd4c22d54a23afb0bacfa8f5dea33fe751e55a
@@ -1,13 +1,14 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
3
 
4
- # Copyright © 2024 Ismo Kärkkäinen
4
+ # Copyright © 2024-2025 Ismo Kärkkäinen
5
5
  # Licensed under Universal Permissive License. See LICENSE.txt.
6
6
 
7
- require_relative '../lib/apiobjects'
8
- require_relative '../lib/common'
7
+ require_relative '../lib/openapi/sourcetools/apiobjects'
8
+ require_relative '../lib/openapi/sourcetools/common'
9
9
  require 'optparse'
10
10
  require 'yaml'
11
+ include OpenAPISourceTools
11
12
 
12
13
 
13
14
  def replace_headers(obj, components)
@@ -30,9 +31,8 @@ def main
30
31
  input_name = nil
31
32
  output_name = nil
32
33
  path = %w[components headers]
33
- components = Components.new(path, 'Header')
34
+ components = ApiObjects::Components.new(path, 'Header')
34
35
 
35
- ENV['POSIXLY_CORRECT'] = '1'
36
36
  parser = OptionParser.new do |opts|
37
37
  opts.summary_indent = ' '
38
38
  opts.summary_width = 26
@@ -42,7 +42,7 @@ def main
42
42
  opts.on('-i', '--input FILE', 'Read API spec from FILE, not stdin.') do |f|
43
43
  input_name = f
44
44
  end
45
- opts.on('-o', '--output FILE', 'Output to FILE, not stdout .') do |f|
45
+ opts.on('-o', '--output FILE', 'Output to FILE, not stdout.') do |f|
46
46
  output_name = f
47
47
  end
48
48
  components.add_options(opts)
@@ -57,17 +57,17 @@ replaces the original with reference.
57
57
  exit 0
58
58
  end
59
59
  end
60
- parser.parse!
60
+ parser.order!
61
61
 
62
- doc = load_source(input_name)
62
+ doc = Common.load_source(input_name)
63
63
  return 2 if doc.nil?
64
64
 
65
65
  components.items = doc.dig(*path) || {}
66
66
  replace_headers(doc.dig('components', 'responses') || {}, components)
67
67
  replace_headers(doc.fetch('paths', {}), components)
68
- bury(doc, path, components.items) unless components.items.empty?
68
+ Common.bury(doc, path, components.items) unless components.items.empty?
69
69
 
70
- dump_result(output_name, doc, 3)
70
+ Common.dump_result(output_name, doc, 3)
71
71
  end
72
72
 
73
- exit(main) if (defined? $unit_test).nil?
73
+ exit(main) if defined?($unit_test).nil?
@@ -1,13 +1,13 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
3
 
4
- # Copyright © 2024 Ismo Kärkkäinen
4
+ # Copyright © 2024-2025 Ismo Kärkkäinen
5
5
  # Licensed under Universal Permissive License. See LICENSE.txt.
6
6
 
7
- require_relative '../lib/apiobjects'
8
- require_relative '../lib/common'
7
+ require_relative '../lib/openapi/sourcetools/apiobjects'
8
+ require_relative '../lib/openapi/sourcetools/common'
9
9
  require 'optparse'
10
- require 'yaml'
10
+ include OpenAPISourceTools
11
11
 
12
12
  def replace_parameter(p, components)
13
13
  return p unless p.is_a?(Hash) # Could complain.
@@ -26,13 +26,43 @@ def replace_parameters(obj, components)
26
26
  end
27
27
  end
28
28
 
29
+ def ref_name(ref)
30
+ idx = ref.rindex('/') || -1
31
+ ref[(idx + 1)..]
32
+ end
33
+
34
+ def nameloc2ref(params, referenced)
35
+ nl2r = {}
36
+ params.each do |ref|
37
+ rn = ref_name(ref['$ref'])
38
+ refd = referenced[rn]
39
+ nl2r["#{refd['name']} #{refd['in']}"] = ref
40
+ end
41
+ nl2r
42
+ end
43
+
44
+ def add_operations_parameters(paths, referenced)
45
+ # Top level is path item objects.
46
+ # Below that are operations objects.
47
+ paths.each_value do |item|
48
+ top_nameloc2ref = nameloc2ref(item['parameters'] || [], referenced)
49
+ oos = ApiObjects.operation_objects(item)
50
+ oos.each_value do |operation|
51
+ nl2r = nameloc2ref(operation['parameters'] || [], referenced)
52
+ params = top_nameloc2ref.merge(nl2r)
53
+ # Map also avoids alias creation at YAML saving.
54
+ operation['parameters'] = params.keys.sort!.map { |k| { '$ref' => params[k]['$ref'] } }
55
+ end
56
+ end
57
+ end
58
+
29
59
  def main
30
60
  input_name = nil
31
61
  output_name = nil
62
+ add2operations = false
32
63
  path = %w[components parameters]
33
- components = Components.new(path, 'Parameter')
64
+ components = ApiObjects::Components.new(path, 'Parameter')
34
65
 
35
- ENV['POSIXLY_CORRECT'] = '1'
36
66
  parser = OptionParser.new do |opts|
37
67
  opts.summary_indent = ' '
38
68
  opts.summary_width = 26
@@ -42,9 +72,12 @@ def main
42
72
  opts.on('-i', '--input FILE', 'Read API spec from FILE, not stdin.') do |f|
43
73
  input_name = f
44
74
  end
45
- opts.on('-o', '--output FILE', 'Output to FILE, not stdout .') do |f|
75
+ opts.on('-o', '--output FILE', 'Output to FILE, not stdout.') do |f|
46
76
  output_name = f
47
77
  end
78
+ opts.on('-a', '--add', 'Add parameters to operations objects.') do
79
+ add2operations = true
80
+ end
48
81
  components.add_options(opts)
49
82
  opts.on('-h', '--help', 'Print this help and exit.') do
50
83
  $stdout.puts %(#{opts}
@@ -52,21 +85,28 @@ def main
52
85
  Loads API document in OpenAPI format and moves parameters under components and
53
86
  replaces the original with reference.
54
87
 
88
+ Optionally adds parameters to all operations objects by copying parameters
89
+ from path item and replacing ones referred to in operations object. The
90
+ path item parameters are left in place. Even empty arrays are added.
91
+
55
92
  #{components.help}
56
93
  )
57
94
  exit 0
58
95
  end
59
96
  end
60
- parser.parse!
97
+ parser.order!
61
98
 
62
- doc = load_source(input_name)
99
+ doc = Common.load_source(input_name)
63
100
  return 2 if doc.nil?
64
101
 
65
102
  components.items = doc.dig(*path) || {}
66
103
  replace_parameters(doc.fetch('paths', {}), components)
67
- bury(doc, path, components.items) unless components.items.empty?
104
+ Common.bury(doc, path, components.items) unless components.items.empty?
105
+ # If nothing has parameters, this adds empty arrays.
106
+ # Consistency might be desired for code generation templates.
107
+ add_operations_parameters(doc.fetch('paths', {}), components.items) if add2operations
68
108
 
69
- dump_result(output_name, doc, 3)
109
+ Common.dump_result(output_name, doc, 3)
70
110
  end
71
111
 
72
- exit(main) if defined?($unit_test).nil?
112
+ exit(main) unless defined?($unit_test)
@@ -1,13 +1,13 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
3
 
4
- # Copyright © 2024 Ismo Kärkkäinen
4
+ # Copyright © 2024-2025 Ismo Kärkkäinen
5
5
  # Licensed under Universal Permissive License. See LICENSE.txt.
6
6
 
7
- require_relative '../lib/apiobjects'
8
- require_relative '../lib/common'
7
+ require_relative '../lib/openapi/sourcetools/apiobjects'
8
+ require_relative '../lib/openapi/sourcetools/common'
9
9
  require 'optparse'
10
- require 'yaml'
10
+ include OpenAPISourceTools
11
11
 
12
12
 
13
13
  def replace_responses(obj, components)
@@ -30,9 +30,8 @@ def main
30
30
  input_name = nil
31
31
  output_name = nil
32
32
  path = %w[components responses]
33
- components = Components.new(path, 'Response')
33
+ components = ApiObjects::Components.new(path, 'Response')
34
34
 
35
- ENV['POSIXLY_CORRECT'] = '1'
36
35
  parser = OptionParser.new do |opts|
37
36
  opts.summary_indent = ' '
38
37
  opts.summary_width = 26
@@ -42,7 +41,7 @@ def main
42
41
  opts.on('-i', '--input FILE', 'Read API spec from FILE, not stdin.') do |f|
43
42
  input_name = f
44
43
  end
45
- opts.on('-o', '--output FILE', 'Output to FILE, not stdout .') do |f|
44
+ opts.on('-o', '--output FILE', 'Output to FILE, not stdout.') do |f|
46
45
  output_name = f
47
46
  end
48
47
  components.add_options(opts)
@@ -57,16 +56,16 @@ replaces the original with reference.
57
56
  exit 0
58
57
  end
59
58
  end
60
- parser.parse!
59
+ parser.order!
61
60
 
62
- doc = load_source(input_name)
61
+ doc = Common.load_source(input_name)
63
62
  return 2 if doc.nil?
64
63
 
65
64
  components.items = doc.dig(*path) || {}
66
65
  replace_responses(doc.fetch('paths', {}), components)
67
- bury(doc, path, components.items) unless components.items.empty?
66
+ Common.bury(doc, path, components.items) unless components.items.empty?
68
67
 
69
- dump_result(output_name, doc, 3)
68
+ Common.dump_result(output_name, doc, 3)
70
69
  end
71
70
 
72
- exit(main) if (defined? $unit_test).nil?
71
+ exit(main) if defined?($unit_test).nil?
@@ -1,13 +1,13 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
3
 
4
- # Copyright © 2024 Ismo Kärkkäinen
4
+ # Copyright © 2024-2025 Ismo Kärkkäinen
5
5
  # Licensed under Universal Permissive License. See LICENSE.txt.
6
6
 
7
- require_relative '../lib/apiobjects'
8
- require_relative '../lib/common'
7
+ require_relative '../lib/openapi/sourcetools/apiobjects'
8
+ require_relative '../lib/openapi/sourcetools/common'
9
9
  require 'optparse'
10
- require 'yaml'
10
+ include OpenAPISourceTools
11
11
 
12
12
 
13
13
  def remove_subitem(obj, path)
@@ -17,7 +17,7 @@ def remove_subitem(obj, path)
17
17
  parent.delete(path.last) || {}
18
18
  end
19
19
 
20
- def replace_inlines(obj, components, top_level = false)
20
+ def replace_inlines(obj, components, top_level_name = nil)
21
21
  if obj.is_a?(Array)
22
22
  obj.each do |o|
23
23
  return false unless replace_inlines(o, components)
@@ -25,8 +25,11 @@ def replace_inlines(obj, components, top_level = false)
25
25
  return true
26
26
  end
27
27
  return true unless obj.is_a?(Hash)
28
- return true if obj.key?('$ref')
29
- # Prior return would be the place to get rid of other keys if so desired.
28
+ if obj.key?('$ref')
29
+ components.store_anchor(obj)
30
+ # Here would be the place to get rid of other keys if so desired.
31
+ return true
32
+ end
30
33
  # Is inlined, process parts recursively.
31
34
  items = obj['allOf']
32
35
  items = obj['anyOf'] if items.nil?
@@ -36,6 +39,7 @@ def replace_inlines(obj, components, top_level = false)
36
39
  t = obj['type']
37
40
  if t.nil? # Some kind of intermediate-level object.
38
41
  (obj.keys.sort! { |a, b| a.to_s <=> b.to_s }).each do |key|
42
+ next if key == 'securitySchemes'
39
43
  return false unless replace_inlines(obj[key], components)
40
44
  end
41
45
  return true
@@ -49,17 +53,34 @@ def replace_inlines(obj, components, top_level = false)
49
53
  return false unless replace_inlines(props[name], components)
50
54
  end
51
55
  end
52
- obj.replace({ '$ref' => components.reference(obj) }) unless top_level
56
+ r = components.ref_string(top_level_name) || components.reference(obj)
57
+ components.store_anchor(obj, r)
58
+ obj.replace({ '$ref' => r }) if top_level_name.nil?
53
59
  true
54
60
  end
55
61
 
62
+ def replace_anchor_refs(obj, components)
63
+ if obj.is_a?(Array)
64
+ obj.each do |o|
65
+ replace_anchor_refs(o, components)
66
+ end
67
+ return
68
+ end
69
+ return unless obj.is_a?(Hash)
70
+ r = obj['$ref']
71
+ obj['$ref'] = components.anchor_ref_replacement(r) unless r.nil?
72
+ obj.each_value do |value|
73
+ # Loops over $ref value but that is a string so nothing done to it.
74
+ replace_anchor_refs(value, components)
75
+ end
76
+ end
77
+
56
78
  def main
57
79
  input_name = nil
58
80
  output_name = nil
59
81
  path = %w[components schemas]
60
- components = Components.new(path, 'Schema')
82
+ components = ApiObjects::Components.new(path, 'Schema')
61
83
 
62
- ENV['POSIXLY_CORRECT'] = '1'
63
84
  parser = OptionParser.new do |opts|
64
85
  opts.summary_indent = ' '
65
86
  opts.summary_width = 26
@@ -69,7 +90,7 @@ def main
69
90
  opts.on('-i', '--input FILE', 'Read API spec from FILE, not stdin.') do |f|
70
91
  input_name = f
71
92
  end
72
- opts.on('-o', '--output FILE', 'Output to FILE, not stdout .') do |f|
93
+ opts.on('-o', '--output FILE', 'Output to FILE, not stdout.') do |f|
73
94
  output_name = f
74
95
  end
75
96
  components.add_options(opts)
@@ -83,9 +104,9 @@ Loads API document in OpenAPI format and adds a schema for each inline type.
83
104
  exit 0
84
105
  end
85
106
  end
86
- parser.parse!
107
+ parser.order!
87
108
 
88
- doc = load_source(input_name)
109
+ doc = Common.load_source(input_name)
89
110
  return 2 if doc.nil?
90
111
 
91
112
  # Find schema object and remove it temporarily to prevent being
@@ -93,12 +114,15 @@ Loads API document in OpenAPI format and adds a schema for each inline type.
93
114
  components.items = remove_subitem(doc, path)
94
115
  # Get rid of inlined types within existing schemas first.
95
116
  components.items.keys.sort!.each do |k|
96
- return 4 unless replace_inlines(components.items[k], components, true)
117
+ components.add_schema_name(k)
118
+ return 4 unless replace_inlines(components.items[k], components, k)
97
119
  end
98
120
  return 4 unless replace_inlines(doc, components)
99
- bury(doc, path, components.items) unless components.items.empty?
121
+ components.alter_anchors
122
+ Common.bury(doc, path, components.items) unless components.items.empty?
123
+ replace_anchor_refs(doc, components)
100
124
 
101
- dump_result(output_name, doc, 3)
125
+ Common.dump_result(output_name, doc, 3)
102
126
  end
103
127
 
104
- exit(main) if (defined? $unit_test).nil?
128
+ exit(main) if defined?($unit_test).nil?
@@ -1,18 +1,19 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
3
 
4
- # Copyright © 2024 Ismo Kärkkäinen
4
+ # Copyright © 2024-2025 Ismo Kärkkäinen
5
5
  # Licensed under Universal Permissive License. See LICENSE.txt.
6
6
 
7
- require_relative '../lib/apiobjects'
8
- require_relative '../lib/common'
7
+ require_relative '../lib/openapi/sourcetools/apiobjects'
8
+ require_relative '../lib/openapi/sourcetools/common'
9
9
  require 'optparse'
10
10
  require 'yaml'
11
+ include OpenAPISourceTools
11
12
 
12
13
 
13
14
  def typesame(a, b, ignored_keys)
14
- return same(a, b, ignored_keys) unless a['type'] == 'object'
15
- return same(a, b, ignored_keys) unless b['type'] == 'object'
15
+ return ApiObjects.same(a, b, ignored_keys) unless a['type'] == 'object'
16
+ return ApiObjects.same(a, b, ignored_keys) unless b['type'] == 'object'
16
17
  # For each property in a, find out unused mathing property in b that is
17
18
  # also either required or not.
18
19
  # Requiring property affects e.g. C++ by allowing direct membership or
@@ -54,7 +55,7 @@ def gather_equivalencies(components)
54
55
  (order.size - 1).times do |k|
55
56
  item = components.items[order[k]]
56
57
  ((k + 1)...order.size).each do |n|
57
- if same(item, components.items[order[n]], components.ignored_keys)
58
+ if ApiObjects.same(item, components.items[order[n]], components.ignored_keys)
58
59
  result[order[k]].push(order[n])
59
60
  result[order[n]].push(order[k])
60
61
  end
@@ -120,7 +121,7 @@ def drop_untouched(refs, report, prefix)
120
121
  %w[equivalent typematch].each do |s|
121
122
  r = report[s]
122
123
  next if r.nil?
123
- r.keys.each { |k| touched.add("#{prefix}#{k}") }
124
+ r.each_key { |k| touched.add("#{prefix}#{k}") }
124
125
  end
125
126
  refs.delete_if { |k, _v| !touched.member?(k) }
126
127
  end
@@ -135,14 +136,13 @@ def main
135
136
  input_name = nil
136
137
  output_name = nil
137
138
  path = %w[components schemas]
138
- components = Components.new(path, '')
139
+ components = ApiObjects::Components.new(path, '')
139
140
  equivalent = true
140
141
  typematch = false
141
142
  references = false
142
143
  count = true
143
144
  keep = false
144
145
 
145
- ENV['POSIXLY_CORRECT'] = '1'
146
146
  parser = OptionParser.new do |opts|
147
147
  opts.summary_indent = ' '
148
148
  opts.summary_width = 26
@@ -152,22 +152,22 @@ def main
152
152
  opts.on('-i', '--input FILE', 'Read API spec from FILE, not stdin.') do |f|
153
153
  input_name = f
154
154
  end
155
- opts.on('-o', '--output FILE', 'Output to FILE, not stdout .') do |f|
155
+ opts.on('-o', '--output FILE', 'Output to FILE, not stdout.') do |f|
156
156
  output_name = f
157
157
  end
158
- opts.on('-e', '--[no-]equivalent', "Report equivalent schemas, default #{equivalent}") do |b|
158
+ opts.on('-e', '--[no-]equivalent', "Report equivalent schemas, default #{Common.yesno(equivalent)}") do |b|
159
159
  equivalent = b
160
160
  end
161
- opts.on('-t', '--[no-]typematch', "Report typematch schemas, default #{typematch}") do |b|
161
+ opts.on('-t', '--[no-]typematch', "Report typematch schemas, default #{Common.yesno(typematch)}") do |b|
162
162
  typematch = b
163
163
  end
164
- opts.on('-r', '--[no-]reference', "Report schema references, default #{references}") do |b|
164
+ opts.on('-r', '--[no-]reference', "Report schema references, default #{Common.yesno(references)}") do |b|
165
165
  references = b
166
166
  end
167
- opts.on('-c', '--[no-]count', "Report schema reference counts, default #{count}") do |b|
167
+ opts.on('-c', '--[no-]count', "Report schema reference counts, default #{Common.yesno(count)}") do |b|
168
168
  count = b
169
169
  end
170
- opts.on('-k', '--[no-]keep', "Keep all schema references/counts, default #{keep}") do |b|
170
+ opts.on('-k', '--[no-]keep', "Keep all schema references/counts, default #{Common.yesno(keep)}") do |b|
171
171
  keep = b
172
172
  end
173
173
  components.add_options(opts)
@@ -182,19 +182,19 @@ names differ but types match.
182
182
 
183
183
  Search is performed only at top schema level. References to equivalent types
184
184
  are not considered equivalent when references themselves are not equivalent.
185
- Any allOf, anyOf, oneOf checks merely check the refernces. Hence two different
185
+ Any allOf, anyOf, oneOf checks merely check the references. Hence two different
186
186
  allOf schemas may in practice result in equivalent types and that is not
187
187
  detected.
188
188
 
189
189
  Implicit expectation is the openapi-addschemas has been used to process the
190
- input, as inlined types in requests for example are ignored.
190
+ input, as inlined types in requests, for example, are ignored.
191
191
  )
192
192
  exit 0
193
193
  end
194
194
  end
195
- parser.parse!
195
+ parser.order!
196
196
 
197
- doc = load_source(input_name)
197
+ doc = Common.load_source(input_name)
198
198
  return 2 if doc.nil?
199
199
 
200
200
  components.items = doc.dig(*path) || {}
@@ -211,7 +211,7 @@ input, as inlined types in requests for example are ignored.
211
211
  end
212
212
  # Filter reference counts that are not for type in equivalent or typematch.
213
213
  # Could check for pretty-printed output format here.
214
- dump_result(output_name, YAML.dump(report, line_width: 80), 3)
214
+ Common.dump_result(output_name, YAML.dump(report, line_width: 80), 3)
215
215
  end
216
216
 
217
- exit(main) if (defined? $unit_test).nil?
217
+ exit(main) if defined?($unit_test).nil?
@@ -1,12 +1,13 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
3
 
4
- # Copyright © 2021-2024 Ismo Kärkkäinen
4
+ # Copyright © 2021-2025 Ismo Kärkkäinen
5
5
  # Licensed under Universal Permissive License. See LICENSE.txt.
6
6
 
7
- require_relative '../lib/common'
7
+ require_relative '../lib/openapi/sourcetools/apiobjects'
8
+ require_relative '../lib/openapi/sourcetools/common'
8
9
  require 'optparse'
9
- require 'yaml'
10
+ include OpenAPISourceTools
10
11
 
11
12
  def main
12
13
  input_name = nil
@@ -32,47 +33,44 @@ def main
32
33
  $stdout.puts %(#{opts}
33
34
 
34
35
  Matches given OpenAPI document file paths with paths from file and adds
35
- into each path object matching count as "freq".
36
+ into each path object matching count as "x-openapi-sourcetools-freq".
36
37
  )
37
38
  exit 0
38
39
  end
39
40
  end
40
- parser.parse!
41
+ parser.order!
41
42
 
42
- return aargh('Path log file name must be given.', 1) if paths_name.nil?
43
+ return Common.aargh('Path log file name must be given.', 1) if paths_name.nil?
43
44
 
44
- doc = load_source(input_name)
45
+ doc = Common.load_source(input_name)
45
46
  return 2 if doc.nil?
46
47
 
48
+ doc['paths'].each do |path, item|
49
+ item[:path] = ApiObjects::ServerPath.new(Common.split_path(path, true))
50
+ item['x-openapi-sourcetools-freq'] = 0
51
+ end
52
+
47
53
  begin
48
54
  # Expect one path per line with nothing else. Query is allowed and ignored.
49
55
  f = File.new(paths_name, 'rt')
50
56
  f.each_line do |line|
51
- p = ServerPath.new(split_path(line))
52
- doc['paths'].each_value do |info|
53
- next unless (p <=> info['parts']).zero?
54
- info['freq'] = info.fetch('freq', 0) + 1
55
- # Lookalikes are the others that can be matched, since path has no
56
- # variables so any change in fixed parts (not a lookalike) will be a
57
- # mismatch with path.
58
- info['lookalike'].each do |path|
59
- cand = doc['paths'][path]
60
- next unless (p <=> cand['parts']).zero?
61
- cand['freq'] = cand.fetch('freq', 0) + 1
62
- end
63
- break
57
+ p = ApiObjects::ServerPath.new(Common.split_path(line))
58
+ doc['paths'].each_value do |item|
59
+ item['x-openapi-sourcetools-freq'] += 1 if p.compare(item[:path]).zero?
64
60
  end
65
61
  end
66
62
  f.close
67
63
  rescue Errno::ENOENT
68
- return aargh("Could not read path log file: #{paths_name}", 4)
69
- rescue NoMethodError
70
- return aargh('Is input file an output of openapi-processpaths?', 5)
64
+ return Common.aargh("Could not read path log file: #{paths_name}", 4)
71
65
  rescue StandardError => e
72
- return aargh(e.to_s, 6)
66
+ return Common.aargh(e.to_s, 6)
67
+ end
68
+
69
+ doc['paths'].each_value do |item|
70
+ item.delete(:path)
73
71
  end
74
72
 
75
- dump_result(output_name, YAML.dump(doc), 3)
73
+ Common.dump_result(output_name, doc, 3)
76
74
  end
77
75
 
78
- exit(main) if (defined? $unit_test).nil?
76
+ exit(main) unless defined?($unit_test)
data/bin/openapi-generate CHANGED
@@ -1,20 +1,20 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
3
 
4
- # Copyright © 2021-2024 Ismo Kärkkäinen
4
+ # Copyright © 2021-2025 Ismo Kärkkäinen
5
5
  # Licensed under Universal Permissive License. See LICENSE.txt.
6
6
 
7
- require_relative '../lib/common'
8
- require_relative '../lib/loaders'
9
- require_relative '../lib/gen'
10
- require_relative '../lib/generate'
7
+ require_relative '../lib/openapi/sourcetools/common'
8
+ require_relative '../lib/openapi/sourcetools/loaders'
9
+ require_relative '../lib/openapi/sourcetools/gen'
10
+ require_relative '../lib/openapi/sourcetools/generate'
11
11
  require 'optparse'
12
- require 'yaml'
13
12
 
14
13
 
15
14
  def main
16
15
  input_name = nil
17
16
  output_dir = nil
17
+ config_prefix = 'openapi-generate'
18
18
 
19
19
  parser = OptionParser.new do |opts|
20
20
  opts.summary_indent = ' '
@@ -28,11 +28,14 @@ def main
28
28
  opts.on('-o', '--outdir DIR', 'Output directory.') do |d|
29
29
  output_dir = d
30
30
  end
31
+ opts.on('-c', '--config', "Internal configuration prefix, default: #{config_prefix}") do |c|
32
+ config_prefix = c
33
+ end
31
34
  opts.on('-h', '--help', 'Print this help and exit.') do
32
35
  $stdout.puts %(#{opts}
33
36
  Loads API document in OpenAPI format and generator names. Built-in generator
34
37
  or additional document loaders accept the following:
35
- #{Loaders.document.strip}
38
+ #{OpenAPISourceTools::Loaders.document.strip}
36
39
 
37
40
  During load each generator can add and modify tasks via Gen module:
38
41
  #{Gen.document.strip}
@@ -44,15 +47,15 @@ After all generators have loaded succesfully, tasks are run.
44
47
  end
45
48
  parser.order!
46
49
 
47
- return aargh('Generator names must be given.', 1) if ARGV.empty?
50
+ return OpenAPISourceTools::Common.aargh('Generator names must be given.', 1) if ARGV.empty?
48
51
 
49
- a = load_source(input_name)
52
+ a = OpenAPISourceTools::Common.load_source(input_name)
50
53
  return 2 if a.nil?
51
- return aargh("Not a directory: #{output_dir}", 3) unless File.directory?(output_dir)
52
- gen = Generator.new(a, input_name, output_dir)
54
+ return OpenAPISourceTools::Common.aargh("Not a directory: #{output_dir}", 3) unless File.directory?(output_dir)
55
+ gen = OpenAPISourceTools::Generator.new(a, input_name, output_dir, config_prefix)
53
56
  ec = gen.load(ARGV)
54
57
  return ec unless ec.zero?
55
58
  gen.run
56
59
  end
57
60
 
58
- exit(main) if defined?($unit_test).nil?
61
+ exit(main) unless defined?($unit_test)