openapi-sourcetools 0.7.1 → 0.8.1
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 +8 -7
- data/bin/openapi-addparameters +50 -9
- data/bin/openapi-addresponses +8 -8
- data/bin/openapi-addschemas +10 -9
- data/bin/openapi-addsecurityschemes +108 -0
- data/bin/openapi-checkschemas +16 -15
- data/bin/openapi-frequencies +23 -25
- data/bin/openapi-generate +17 -14
- data/bin/openapi-merge +6 -6
- data/bin/openapi-modifypaths +16 -15
- data/bin/openapi-processpaths +15 -26
- 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/openapi/sourcetools/gen.rb +121 -0
- data/lib/openapi/sourcetools/generate.rb +95 -0
- data/lib/openapi/sourcetools/helper.rb +93 -0
- data/lib/openapi/sourcetools/loaders.rb +163 -0
- data/lib/openapi/sourcetools/output.rb +83 -0
- data/lib/openapi/sourcetools/task.rb +137 -0
- data/lib/openapi/sourcetools/version.rb +13 -0
- data/lib/openapi/sourcetools.rb +16 -0
- metadata +43 -18
- data/lib/apiobjects.rb +0 -306
- data/lib/common.rb +0 -114
- data/lib/docs.rb +0 -33
- data/lib/gen.rb +0 -104
- 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: 93117ebfa33920b762da40afe48264ead793574ad336628487d3cfb3b6019987
|
4
|
+
data.tar.gz: 67cb3400cd879b3625e58b72db11cfc860a87179d069ff341a6202391f8d61f5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: af4681c719424375326d4149ede787f0d6a58d33ff28082d7c1f7b00db4b40186f6406bfe99707012aeae0ac03d4504fb14cd49b6e587f55d91c1f2cb353a3b3
|
7
|
+
data.tar.gz: f6c84c0a9e6b20040fefa9611c8abf211abc1fb65c6a3c3041ce1f96f3b3482fa1789eb2eb16460c5a1d892d56fd843164ae4d7dfb9c4cdb6e3a13f26977d323
|
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,7 +31,7 @@ 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
36
|
parser = OptionParser.new do |opts|
|
36
37
|
opts.summary_indent = ' '
|
@@ -58,15 +59,15 @@ replaces the original with reference.
|
|
58
59
|
end
|
59
60
|
parser.order!
|
60
61
|
|
61
|
-
doc = load_source(input_name)
|
62
|
+
doc = Common.load_source(input_name)
|
62
63
|
return 2 if doc.nil?
|
63
64
|
|
64
65
|
components.items = doc.dig(*path) || {}
|
65
66
|
replace_headers(doc.dig('components', 'responses') || {}, components)
|
66
67
|
replace_headers(doc.fetch('paths', {}), components)
|
67
|
-
bury(doc, path, components.items) unless components.items.empty?
|
68
|
+
Common.bury(doc, path, components.items) unless components.items.empty?
|
68
69
|
|
69
|
-
dump_result(output_name, doc, 3)
|
70
|
+
Common.dump_result(output_name, doc, 3)
|
70
71
|
end
|
71
72
|
|
72
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,11 +26,42 @@ 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
66
|
parser = OptionParser.new do |opts|
|
36
67
|
opts.summary_indent = ' '
|
@@ -44,6 +75,9 @@ def main
|
|
44
75
|
opts.on('-o', '--output FILE', 'Output to FILE, not stdout.') do |f|
|
45
76
|
output_name = f
|
46
77
|
end
|
78
|
+
opts.on('-a', '--add', 'Add parameters to operations objects.') do
|
79
|
+
add2operations = true
|
80
|
+
end
|
47
81
|
components.add_options(opts)
|
48
82
|
opts.on('-h', '--help', 'Print this help and exit.') do
|
49
83
|
$stdout.puts %(#{opts}
|
@@ -51,6 +85,10 @@ def main
|
|
51
85
|
Loads API document in OpenAPI format and moves parameters under components and
|
52
86
|
replaces the original with reference.
|
53
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
|
+
|
54
92
|
#{components.help}
|
55
93
|
)
|
56
94
|
exit 0
|
@@ -58,14 +96,17 @@ replaces the original with reference.
|
|
58
96
|
end
|
59
97
|
parser.order!
|
60
98
|
|
61
|
-
doc = load_source(input_name)
|
99
|
+
doc = Common.load_source(input_name)
|
62
100
|
return 2 if doc.nil?
|
63
101
|
|
64
102
|
components.items = doc.dig(*path) || {}
|
65
103
|
replace_parameters(doc.fetch('paths', {}), components)
|
66
|
-
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
|
67
108
|
|
68
|
-
dump_result(output_name, doc, 3)
|
109
|
+
Common.dump_result(output_name, doc, 3)
|
69
110
|
end
|
70
111
|
|
71
|
-
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,7 +30,7 @@ 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
35
|
parser = OptionParser.new do |opts|
|
36
36
|
opts.summary_indent = ' '
|
@@ -58,14 +58,14 @@ replaces the original with reference.
|
|
58
58
|
end
|
59
59
|
parser.order!
|
60
60
|
|
61
|
-
doc = load_source(input_name)
|
61
|
+
doc = Common.load_source(input_name)
|
62
62
|
return 2 if doc.nil?
|
63
63
|
|
64
64
|
components.items = doc.dig(*path) || {}
|
65
65
|
replace_responses(doc.fetch('paths', {}), components)
|
66
|
-
bury(doc, path, components.items) unless components.items.empty?
|
66
|
+
Common.bury(doc, path, components.items) unless components.items.empty?
|
67
67
|
|
68
|
-
dump_result(output_name, doc, 3)
|
68
|
+
Common.dump_result(output_name, doc, 3)
|
69
69
|
end
|
70
70
|
|
71
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)
|
@@ -39,6 +39,7 @@ def replace_inlines(obj, components, top_level_name = nil)
|
|
39
39
|
t = obj['type']
|
40
40
|
if t.nil? # Some kind of intermediate-level object.
|
41
41
|
(obj.keys.sort! { |a, b| a.to_s <=> b.to_s }).each do |key|
|
42
|
+
next if key == 'securitySchemes'
|
42
43
|
return false unless replace_inlines(obj[key], components)
|
43
44
|
end
|
44
45
|
return true
|
@@ -68,7 +69,7 @@ def replace_anchor_refs(obj, components)
|
|
68
69
|
return unless obj.is_a?(Hash)
|
69
70
|
r = obj['$ref']
|
70
71
|
obj['$ref'] = components.anchor_ref_replacement(r) unless r.nil?
|
71
|
-
obj.
|
72
|
+
obj.each_value do |value|
|
72
73
|
# Loops over $ref value but that is a string so nothing done to it.
|
73
74
|
replace_anchor_refs(value, components)
|
74
75
|
end
|
@@ -78,7 +79,7 @@ def main
|
|
78
79
|
input_name = nil
|
79
80
|
output_name = nil
|
80
81
|
path = %w[components schemas]
|
81
|
-
components = Components.new(path, 'Schema')
|
82
|
+
components = ApiObjects::Components.new(path, 'Schema')
|
82
83
|
|
83
84
|
parser = OptionParser.new do |opts|
|
84
85
|
opts.summary_indent = ' '
|
@@ -105,7 +106,7 @@ Loads API document in OpenAPI format and adds a schema for each inline type.
|
|
105
106
|
end
|
106
107
|
parser.order!
|
107
108
|
|
108
|
-
doc = load_source(input_name)
|
109
|
+
doc = Common.load_source(input_name)
|
109
110
|
return 2 if doc.nil?
|
110
111
|
|
111
112
|
# Find schema object and remove it temporarily to prevent being
|
@@ -118,10 +119,10 @@ Loads API document in OpenAPI format and adds a schema for each inline type.
|
|
118
119
|
end
|
119
120
|
return 4 unless replace_inlines(doc, components)
|
120
121
|
components.alter_anchors
|
121
|
-
bury(doc, path, components.items) unless components.items.empty?
|
122
|
+
Common.bury(doc, path, components.items) unless components.items.empty?
|
122
123
|
replace_anchor_refs(doc, components)
|
123
124
|
|
124
|
-
dump_result(output_name, doc, 3)
|
125
|
+
Common.dump_result(output_name, doc, 3)
|
125
126
|
end
|
126
127
|
|
127
128
|
exit(main) if defined?($unit_test).nil?
|
@@ -0,0 +1,108 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
# Copyright © 2025 Ismo Kärkkäinen
|
5
|
+
# Licensed under Universal Permissive License. See LICENSE.txt.
|
6
|
+
|
7
|
+
require_relative '../lib/openapi/sourcetools/apiobjects'
|
8
|
+
require_relative '../lib/openapi/sourcetools/common'
|
9
|
+
require 'optparse'
|
10
|
+
include OpenAPISourceTools
|
11
|
+
|
12
|
+
|
13
|
+
def add_combinations(combinations, security)
|
14
|
+
security.each do |s|
|
15
|
+
subset = s.keys.sort!
|
16
|
+
next if subset.empty?
|
17
|
+
combinations.add(subset)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def gather_security(doc)
|
22
|
+
combinations = Set.new
|
23
|
+
security = doc.fetch('security', [])
|
24
|
+
add_combinations(combinations, security)
|
25
|
+
operation_objects = []
|
26
|
+
doc.fetch('paths', {}).each_value do |item|
|
27
|
+
oos = ApiObjects.operation_objects(item).values
|
28
|
+
oos.each do |oo|
|
29
|
+
add_combinations(combinations, oo['security'] || [])
|
30
|
+
operation_objects.push(oo)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
[security, operation_objects, combinations]
|
34
|
+
end
|
35
|
+
|
36
|
+
def check_security(doc, combinations)
|
37
|
+
singles = Set.new
|
38
|
+
combinations.each do |c|
|
39
|
+
c.each do |s|
|
40
|
+
singles.add(s)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
available = Set.new((doc.dig('components', 'securitySchemes') || {}).keys)
|
44
|
+
missing = false
|
45
|
+
singles.each do |s|
|
46
|
+
unless available.include?(s)
|
47
|
+
$stderr.puts "Security scheme unavailable: #{s}"
|
48
|
+
missing = true
|
49
|
+
end
|
50
|
+
end
|
51
|
+
!missing
|
52
|
+
end
|
53
|
+
|
54
|
+
def namelist2security(item)
|
55
|
+
item.keys.sort!.join(' ')
|
56
|
+
end
|
57
|
+
|
58
|
+
def security2hash(security)
|
59
|
+
out = {}
|
60
|
+
security.each { |s| out[namelist2security(s)] = s }
|
61
|
+
out
|
62
|
+
end
|
63
|
+
|
64
|
+
def add_security_to_operations(operation_objects, top_level_security)
|
65
|
+
operation_objects.each do |oo|
|
66
|
+
sec = security2hash(oo['security'] || top_level_security)
|
67
|
+
oo['security'] = sec.keys.sort!.map { |k| Marshal.load(Marshal.dump(sec[k])) }
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def main
|
72
|
+
input_name = nil
|
73
|
+
output_name = nil
|
74
|
+
|
75
|
+
parser = OptionParser.new do |opts|
|
76
|
+
opts.summary_indent = ' '
|
77
|
+
opts.summary_width = 26
|
78
|
+
opts.banner = 'Usage: openapi-addsecurityschemes [options]'
|
79
|
+
opts.separator ''
|
80
|
+
opts.separator 'Options:'
|
81
|
+
opts.on('-i', '--input FILE', 'Read API spec from FILE, not stdin.') do |f|
|
82
|
+
input_name = f
|
83
|
+
end
|
84
|
+
opts.on('-o', '--output FILE', 'Output to FILE, not stdout.') do |f|
|
85
|
+
output_name = f
|
86
|
+
end
|
87
|
+
opts.on('-h', '--help', 'Print this help and exit.') do
|
88
|
+
$stdout.puts %(#{opts}
|
89
|
+
|
90
|
+
Loads API document in OpenAPI format and moves security schemes under components and
|
91
|
+
replaces the original with reference.
|
92
|
+
)
|
93
|
+
exit 0
|
94
|
+
end
|
95
|
+
end
|
96
|
+
parser.order!
|
97
|
+
|
98
|
+
doc = Common.load_source(input_name)
|
99
|
+
return 2 if doc.nil?
|
100
|
+
|
101
|
+
security, operation_objects, combinations = gather_security(doc)
|
102
|
+
return 4 unless check_security(doc, combinations)
|
103
|
+
add_security_to_operations(operation_objects, security)
|
104
|
+
|
105
|
+
Common.dump_result(output_name, doc, 3)
|
106
|
+
end
|
107
|
+
|
108
|
+
exit(main) unless defined?($unit_test)
|
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,7 +136,7 @@ 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
|
@@ -154,19 +155,19 @@ def main
|
|
154
155
|
opts.on('-o', '--output FILE', 'Output to FILE, not stdout.') do |f|
|
155
156
|
output_name = f
|
156
157
|
end
|
157
|
-
opts.on('-e', '--[no-]equivalent', "Report equivalent schemas, default #{yesno(equivalent)}") do |b|
|
158
|
+
opts.on('-e', '--[no-]equivalent', "Report equivalent schemas, default #{Common.yesno(equivalent)}") do |b|
|
158
159
|
equivalent = b
|
159
160
|
end
|
160
|
-
opts.on('-t', '--[no-]typematch', "Report typematch schemas, default #{yesno(typematch)}") do |b|
|
161
|
+
opts.on('-t', '--[no-]typematch', "Report typematch schemas, default #{Common.yesno(typematch)}") do |b|
|
161
162
|
typematch = b
|
162
163
|
end
|
163
|
-
opts.on('-r', '--[no-]reference', "Report schema references, default #{yesno(references)}") do |b|
|
164
|
+
opts.on('-r', '--[no-]reference', "Report schema references, default #{Common.yesno(references)}") do |b|
|
164
165
|
references = b
|
165
166
|
end
|
166
|
-
opts.on('-c', '--[no-]count', "Report schema reference counts, default #{yesno(count)}") do |b|
|
167
|
+
opts.on('-c', '--[no-]count', "Report schema reference counts, default #{Common.yesno(count)}") do |b|
|
167
168
|
count = b
|
168
169
|
end
|
169
|
-
opts.on('-k', '--[no-]keep', "Keep all schema references/counts, default #{yesno(keep)}") do |b|
|
170
|
+
opts.on('-k', '--[no-]keep', "Keep all schema references/counts, default #{Common.yesno(keep)}") do |b|
|
170
171
|
keep = b
|
171
172
|
end
|
172
173
|
components.add_options(opts)
|
@@ -193,7 +194,7 @@ input, as inlined types in requests, for example, are ignored.
|
|
193
194
|
end
|
194
195
|
parser.order!
|
195
196
|
|
196
|
-
doc = load_source(input_name)
|
197
|
+
doc = Common.load_source(input_name)
|
197
198
|
return 2 if doc.nil?
|
198
199
|
|
199
200
|
components.items = doc.dig(*path) || {}
|
@@ -210,7 +211,7 @@ input, as inlined types in requests, for example, are ignored.
|
|
210
211
|
end
|
211
212
|
# Filter reference counts that are not for type in equivalent or typematch.
|
212
213
|
# Could check for pretty-printed output format here.
|
213
|
-
dump_result(output_name, YAML.dump(report, line_width: 80), 3)
|
214
|
+
Common.dump_result(output_name, YAML.dump(report, line_width: 80), 3)
|
214
215
|
end
|
215
216
|
|
216
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
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,24 +1,24 @@
|
|
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 = ' '
|
21
|
-
opts.summary_width =
|
21
|
+
opts.summary_width = 20
|
22
22
|
opts.banner = 'Usage: openapi-generate [options] generator-names...'
|
23
23
|
opts.separator ''
|
24
24
|
opts.separator 'Options:'
|
@@ -28,13 +28,16 @@ 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
|
-
During load each generator can add and modify tasks via Gen
|
40
|
+
During load each generator can add and modify tasks via Gen singleton:
|
38
41
|
#{Gen.document.strip}
|
39
42
|
|
40
43
|
After all generators have loaded succesfully, tasks are run.
|
@@ -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?
|
51
|
+
return OpenAPISourceTools::Common.aargh("Not a directory: #{output_dir}", 3) unless File.directory?(output_dir)
|
48
52
|
|
49
|
-
a = load_source(input_name)
|
53
|
+
a = OpenAPISourceTools::Common.load_source(input_name)
|
50
54
|
return 2 if a.nil?
|
51
|
-
|
52
|
-
gen = Generator.new(a, input_name, 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)
|
data/bin/openapi-merge
CHANGED
@@ -1,13 +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/common'
|
7
|
+
require_relative '../lib/openapi/sourcetools/common'
|
8
8
|
require 'optparse'
|
9
|
-
require 'yaml'
|
10
9
|
require 'set'
|
10
|
+
include OpenAPISourceTools
|
11
11
|
|
12
12
|
def raise_se(message)
|
13
13
|
raise StandardError, message
|
@@ -149,16 +149,16 @@ allowed only to append to the merged document, not re-define anything in it.
|
|
149
149
|
max_depths['tags'] = 1
|
150
150
|
merged = {}
|
151
151
|
ARGV.each do |filename|
|
152
|
-
s = load_source(filename)
|
152
|
+
s = Common.load_source(filename)
|
153
153
|
return 2 if s.nil?
|
154
154
|
add_undefined(merged, s, filename, [], max_depths)
|
155
155
|
rescue StandardError => e
|
156
|
-
return aargh(e.to_s, 4)
|
156
|
+
return Common.aargh(e.to_s, 4)
|
157
157
|
end
|
158
158
|
|
159
159
|
prune(merged) unless keep
|
160
160
|
|
161
|
-
dump_result(output_file,
|
161
|
+
Common.dump_result(output_file, merged, 3)
|
162
162
|
end
|
163
163
|
|
164
164
|
exit(main) if defined?($unit_test).nil?
|