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 +4 -4
- data/bin/openapi-addheaders +11 -11
- data/bin/openapi-addparameters +52 -12
- data/bin/openapi-addresponses +11 -12
- data/bin/openapi-addschemas +41 -17
- data/bin/openapi-checkschemas +21 -21
- data/bin/openapi-frequencies +24 -26
- data/bin/openapi-generate +15 -12
- data/bin/openapi-merge +21 -15
- data/bin/openapi-modifypaths +17 -16
- data/bin/openapi-processpaths +16 -27
- data/lib/openapi/sourcetools/apiobjects.rb +191 -0
- data/lib/openapi/sourcetools/common.rb +82 -0
- data/lib/openapi/sourcetools/config.rb +158 -0
- data/lib/openapi/sourcetools/docs.rb +41 -0
- data/lib/{gen.rb → openapi/sourcetools/gen.rb} +38 -13
- data/lib/openapi/sourcetools/generate.rb +96 -0
- data/lib/openapi/sourcetools/helper.rb +93 -0
- data/lib/openapi/sourcetools/loaders.rb +164 -0
- data/lib/openapi/sourcetools/output.rb +83 -0
- data/lib/openapi/sourcetools/securityschemes.rb +268 -0
- data/lib/openapi/sourcetools/task.rb +137 -0
- data/lib/openapi/sourcetools/version.rb +13 -0
- data/lib/openapi/sourcetools.rb +15 -0
- metadata +42 -18
- data/lib/apiobjects.rb +0 -333
- data/lib/common.rb +0 -110
- data/lib/docs.rb +0 -33
- data/lib/generate.rb +0 -90
- data/lib/helper.rb +0 -94
- data/lib/loaders.rb +0 -96
- data/lib/output.rb +0 -58
- data/lib/task.rb +0 -101
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 783a57d4ca224bb9710cb523d3ee2fd2dee0e821cb7382ffc32fa9b8cb36b4f1
|
4
|
+
data.tar.gz: b7c02ac6cd2e30fc4f9f5d9fb87bfcd84b8f60b76007e82d82a1a1bfb7f37e42
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: eec2859f712324b85f9db32f5c92d4e3947a80021f9bf920f287f9b01a2a56ab7d20e3f2b5d30e039a2e606e57b4ca0f0b5872961e91f1898c44c402eade14ef
|
7
|
+
data.tar.gz: 72bbafa47688fd1eb3dd78d1ff0782d8e1a3510e541e4ad4f4e49ceec056cedaf9c6ebbbbe4dd9c7c6b446f3c0dd4c22d54a23afb0bacfa8f5dea33fe751e55a
|
data/bin/openapi-addheaders
CHANGED
@@ -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
|
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.
|
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
|
73
|
+
exit(main) if defined?($unit_test).nil?
|
data/bin/openapi-addparameters
CHANGED
@@ -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
|
-
|
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
|
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.
|
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)
|
112
|
+
exit(main) unless defined?($unit_test)
|
data/bin/openapi-addresponses
CHANGED
@@ -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
|
-
|
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
|
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.
|
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
|
71
|
+
exit(main) if defined?($unit_test).nil?
|
data/bin/openapi-addschemas
CHANGED
@@ -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
|
-
|
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,
|
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
|
-
|
29
|
-
|
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
|
-
|
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
|
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.
|
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
|
-
|
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
|
-
|
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
|
128
|
+
exit(main) if defined?($unit_test).nil?
|
data/bin/openapi-checkschemas
CHANGED
@@ -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.
|
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
|
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
|
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.
|
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
|
217
|
+
exit(main) if defined?($unit_test).nil?
|
data/bin/openapi-frequencies
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
-
# Copyright © 2021-
|
4
|
+
# Copyright © 2021-2025 Ismo Kärkkäinen
|
5
5
|
# Licensed under Universal Permissive License. See LICENSE.txt.
|
6
6
|
|
7
|
-
require_relative '../lib/
|
7
|
+
require_relative '../lib/openapi/sourcetools/apiobjects'
|
8
|
+
require_relative '../lib/openapi/sourcetools/common'
|
8
9
|
require 'optparse'
|
9
|
-
|
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.
|
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 |
|
53
|
-
|
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,
|
73
|
+
Common.dump_result(output_name, doc, 3)
|
76
74
|
end
|
77
75
|
|
78
|
-
exit(main)
|
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-
|
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)
|
61
|
+
exit(main) unless defined?($unit_test)
|