openapi-sourcetools 0.6.0 → 0.7.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: 9320a1d6d4202c453fb7065f00bc534206b1c780560ae443cd30293f27827595
4
- data.tar.gz: af45eabe9a8f392c705398957cf276acb39923655207ffda12ee8d93e1c072a0
3
+ metadata.gz: 211083083a2a3c53321234416ffff41bd1d00320a5ebbdab3ccdcd49576653b3
4
+ data.tar.gz: 34535443138a6308869974d62e79321d9ec9dbb3f46434c19d571075044751e1
5
5
  SHA512:
6
- metadata.gz: 1f81cae3adb06d42d3bf5361615a0a21ca42346d08b1f8b83462116668d2ad61ec05ac707e723d910bbe55eb29699129ba13570b44504581e92597242ab3d810
7
- data.tar.gz: 656959f866321cd68814fed2ef1c9121fe1db36674cb7fbd49f9f2a652e5f43a29d6b1d491a2197278577084d1328e01f99fd1eff8fca1c7ef7d6299ed512b17
6
+ metadata.gz: 3c4a5361e25a1cf7903b6038a32f4a94cf42579c0c4fefb21f885fae996c219a02eef322fd91d694dfe0ff668314685b990d3128ca7e6a98c3f30660639494d0
7
+ data.tar.gz: a563ba480140037e0ef91dbdc89fb62a2175954897726717976760879a74bf8284d673d3a259ce338b7b7493c84fd6c1f5cf4246b90ee42ae1959d3b31c7b21f
@@ -67,7 +67,7 @@ replaces the original with reference.
67
67
  replace_headers(doc.fetch('paths', {}), components)
68
68
  bury(doc, path, components.items) unless components.items.empty?
69
69
 
70
- dump_result(output_name, YAML.dump(doc, line_width: 1_000_000), 3)
70
+ dump_result(output_name, doc, 3)
71
71
  end
72
72
 
73
73
  exit(main) if (defined? $unit_test).nil?
@@ -66,7 +66,7 @@ replaces the original with reference.
66
66
  replace_parameters(doc.fetch('paths', {}), components)
67
67
  bury(doc, path, components.items) unless components.items.empty?
68
68
 
69
- dump_result(output_name, YAML.dump(doc, line_width: 1_000_000), 3)
69
+ dump_result(output_name, doc, 3)
70
70
  end
71
71
 
72
72
  exit(main) if defined?($unit_test).nil?
@@ -66,7 +66,7 @@ replaces the original with reference.
66
66
  replace_responses(doc.fetch('paths', {}), components)
67
67
  bury(doc, path, components.items) unless components.items.empty?
68
68
 
69
- dump_result(output_name, YAML.dump(doc, line_width: 1_000_000), 3)
69
+ dump_result(output_name, doc, 3)
70
70
  end
71
71
 
72
72
  exit(main) if (defined? $unit_test).nil?
@@ -98,7 +98,7 @@ Loads API document in OpenAPI format and adds a schema for each inline type.
98
98
  return 4 unless replace_inlines(doc, components)
99
99
  bury(doc, path, components.items) unless components.items.empty?
100
100
 
101
- dump_result(output_name, YAML.dump(doc, line_width: 1_000_000), 3)
101
+ dump_result(output_name, doc, 3)
102
102
  end
103
103
 
104
104
  exit(main) if (defined? $unit_test).nil?
data/bin/openapi-generate CHANGED
@@ -16,7 +16,6 @@ def main
16
16
  input_name = nil
17
17
  output_dir = nil
18
18
 
19
- ENV['POSIXLY_CORRECT'] = '1'
20
19
  parser = OptionParser.new do |opts|
21
20
  opts.summary_indent = ' '
22
21
  opts.summary_width = 26
@@ -32,7 +31,7 @@ def main
32
31
  opts.on('-h', '--help', 'Print this help and exit.') do
33
32
  $stdout.puts %(#{opts}
34
33
  Loads API document in OpenAPI format and generator names. Built-in generator
35
- loaders accept the following:
34
+ or additional document loaders accept the following:
36
35
  #{Loaders.document.strip}
37
36
 
38
37
  During load each generator can add and modify tasks via Gen module:
@@ -43,7 +42,7 @@ After all generators have loaded succesfully, tasks are run.
43
42
  exit 0
44
43
  end
45
44
  end
46
- parser.parse!
45
+ parser.order!
47
46
 
48
47
  return aargh('Generator names must be given.', 1) if ARGV.empty?
49
48
 
@@ -0,0 +1,123 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ # Copyright © 2024 Ismo Kärkkäinen
5
+ # Licensed under Universal Permissive License. See LICENSE.txt.
6
+
7
+ require_relative '../lib/common'
8
+ require 'optparse'
9
+ require 'yaml'
10
+
11
+ def path2pieces(s)
12
+ s.split('/').reject { |p| p.empty? }
13
+ end
14
+
15
+ def pieces2path(p)
16
+ "/#{p.join('/')}"
17
+ end
18
+
19
+ def add(s, path)
20
+ s.empty? ? path : (s + path)
21
+ end
22
+
23
+ def remove_complete_prefix(prefix, path)
24
+ return nil if prefix.empty? || path.size < prefix.size
25
+ prefix.size.times do |idx|
26
+ return nil unless prefix[idx] == path[idx]
27
+ end
28
+ path[prefix.size...path.size]
29
+ end
30
+
31
+ def remove(s, path)
32
+ remove_complete_prefix(s, path) || path
33
+ end
34
+
35
+ def replace(o, s, path)
36
+ p = remove_complete_prefix(o, path)
37
+ p.nil? ? path : (s + p)
38
+ end
39
+
40
+ def add_op(s)
41
+ s = path2pieces(s)
42
+ Proc.new { |path| add(s, path) }
43
+ end
44
+
45
+ def remove_op(s)
46
+ s = path2pieces(s)
47
+ Proc.new { |path| remove(s, path) }
48
+ end
49
+
50
+ def replace_op(orig, s)
51
+ o = path2pieces(orig)
52
+ s = path2pieces(s)
53
+ Proc.new { |path| replace(o, s, path) }
54
+ end
55
+
56
+ def perform_operations(paths, operations)
57
+ out = {}
58
+ paths.each do |path, value|
59
+ operations.each do |op|
60
+ path = pieces2path(op.call(path2pieces(path)))
61
+ end
62
+ out[path] = value
63
+ end
64
+ out
65
+ end
66
+
67
+ def main
68
+ input_name = nil
69
+ output_name = nil
70
+ operations = []
71
+ orig = nil
72
+
73
+ parser = OptionParser.new do |opts|
74
+ opts.summary_indent = ' '
75
+ opts.summary_width = 26
76
+ opts.banner = 'Usage: openapi-modifypaths [options]'
77
+ opts.separator ''
78
+ opts.separator 'Options:'
79
+ opts.on('-i', '--input FILE', 'Read API spec from FILE, not stdin.') do |f|
80
+ exit(aargh("Expected string to replace PREFIX.", 1)) unless orig.nil?
81
+ input_name = f
82
+ end
83
+ opts.on('-o', '--output FILE', 'Output to FILE, not stdout.') do |f|
84
+ exit(aargh("Expected string to replace PREFIX.", 1)) unless orig.nil?
85
+ output_name = f
86
+ end
87
+ opts.on('-a', '--add STR', 'Add prefix STR to all paths.') do |s|
88
+ exit(aargh("Expected string to replace PREFIX.", 1)) unless orig.nil?
89
+ operations.push(add_op(s))
90
+ end
91
+ opts.on('-d', '--delete PREFIX', 'Delete PREFIX when present.') do |s|
92
+ exit(aargh("Expected string to replace PREFIX.", 1)) unless orig.nil?
93
+ operations.push(remove_op(s))
94
+ end
95
+ opts.on('-r', '--replace PREFIX STR', 'Replace PREFIX with STR when present.') do |s|
96
+ exit(aargh('Empty string to replace.', 1)) if s.empty?
97
+ orig = s
98
+ end
99
+ opts.on('-h', '--help', 'Print this help and exit.') do
100
+ $stdout.puts %(#{opts}
101
+
102
+ Loads API document in OpenAPI format and changes paths according to options.
103
+ STR and PREFIX are expected to be parts of a path surrounded by /.
104
+ )
105
+ exit 0
106
+ end
107
+ end
108
+ parser.order! do |s|
109
+ exit(aargh("String without option: #{s}", 1)) if orig.nil?
110
+ operations.push(replace_op(orig, s))
111
+ orig = nil
112
+ end
113
+
114
+ doc = load_source(input_name)
115
+ return 2 if doc.nil?
116
+
117
+ p = perform_operations(doc.fetch('paths', {}), operations)
118
+ doc['paths'] = p unless p.empty?
119
+
120
+ dump_result(output_name, doc, 3)
121
+ end
122
+
123
+ main if defined?($unit_test).nil?
data/lib/common.rb CHANGED
@@ -54,6 +54,7 @@ rescue StandardError => e
54
54
  end
55
55
 
56
56
  def dump_result(output, doc, error_return)
57
+ doc = YAML.dump(doc, line_width: 1_000_000) unless doc.is_a?(String)
57
58
  if output.nil?
58
59
  $stdout.puts doc
59
60
  else
data/lib/docs.rb ADDED
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright © 2024 Ismo Kärkkäinen
4
+ # Licensed under Universal Permissive License. See LICENSE.txt.
5
+
6
+ require_relative 'common'
7
+
8
+
9
+ class Docs
10
+ attr_reader :docs
11
+
12
+ def initialize
13
+ @docs = {}
14
+ end
15
+
16
+ def method_missing(method_name, *args)
17
+ name = method_name.to_s
18
+ if name.end_with?('=')
19
+ name = name[0...(name.size - 1)]
20
+ super unless @docs.key?(name)
21
+ @docs[name] = args.first
22
+ return args.first
23
+ end
24
+ super unless @docs.key?(name)
25
+ @docs[name]
26
+ end
27
+
28
+ def add(name, content)
29
+ return false if docs.key?(name)
30
+ @docs[name] = content
31
+ true
32
+ end
33
+ end
data/lib/gen.rb CHANGED
@@ -5,56 +5,73 @@
5
5
 
6
6
  require_relative 'task'
7
7
  require_relative 'helper'
8
+ require_relative 'docs'
9
+ require_relative 'output'
8
10
 
9
11
 
10
12
  module Gen
11
- def self.mod_attr_reader(symbol, docstr = nil)
12
- attr_reader(symbol)
13
- module_function(symbol)
13
+ def self.add_doc(symbol, docstr)
14
14
  return if docstr.nil?
15
- @docsrc = [] unless Gen.instance_variable_defined?('@docsrc')
15
+ @docsrc = [] unless instance_variable_defined?('@docsrc')
16
16
  @docsrc.push("- #{symbol.to_s} : #{docstr}")
17
17
  end
18
18
 
19
- def self.mod_attr_accessor(symbol, docstr = nil)
19
+ def self.read_attr(symbol, default)
20
+ return if symbol.nil?
21
+ attr_reader(symbol)
22
+ module_function(symbol)
23
+ instance_variable_set("@#{symbol.to_s}", default)
24
+ end
25
+
26
+ def self.mod_attr2_reader(symbol, symbol2, docstr = nil, default = nil)
27
+ read_attr(symbol, default)
28
+ read_attr(symbol2, default)
29
+ add_doc(symbol, docstr)
30
+ end
31
+
32
+ def self.mod_attr_reader(symbol, docstr = nil, default = nil)
33
+ mod_attr2_reader(symbol, nil, docstr, default)
34
+ end
35
+
36
+ def self.rw_attr(symbol, default)
20
37
  attr_accessor(symbol)
21
38
  module_function(symbol)
22
39
  s = symbol.to_s
23
40
  module_function((s + '=').to_sym)
24
- return if docstr.nil?
25
- @docsrc = [] unless Gen.instance_variable_defined?('@docsrc')
26
- @docsrc.push("- #{s} : #{docstr}")
41
+ instance_variable_set("@#{s}", default)
42
+ end
43
+
44
+ def self.mod_attr2_accessor(symbol, symbol2, docstr = nil, default = nil)
45
+ rw_attr(symbol, default)
46
+ rw_attr(symbol2, default) unless symbol2.nil?
47
+ add_doc(symbol, docstr)
48
+ end
49
+
50
+ def self.mod_attr_accessor(symbol, docstr = nil, default = nil)
51
+ mod_attr2_accessor(symbol, nil, docstr, default)
27
52
  end
28
53
 
29
54
  mod_attr_reader :doc, 'OpenAPI document.'
30
55
  mod_attr_reader :outdir, 'Output directory name.'
56
+ mod_attr_reader :d, 'Other documents object.', Docs.new
31
57
  mod_attr_accessor :in_name, 'OpenAPI document name, nil if stdin.'
32
58
  mod_attr_accessor :in_basename, 'OpenAPI document basename, nil if stdin.'
33
- mod_attr_accessor :tasks, 'Tasks array.'
34
- mod_attr_accessor :g, 'Hash for storing values visible to all tasks.'
59
+ mod_attr_accessor :tasks, 'Tasks array.', []
60
+ mod_attr_accessor :g, 'Hash for storing values visible to all tasks.', {}
35
61
  mod_attr_accessor :a, 'Intended for instance with defined attributes.'
36
62
  mod_attr_accessor :h, 'Instance of class with helper methods.'
37
- mod_attr_accessor :t, 'Current task instance.'
63
+ mod_attr2_accessor :task, :t, 'Current task instance.'
38
64
  mod_attr_accessor :task_index, 'Current task index.'
39
- mod_attr_accessor :loaders, 'Array of generator loader methods.'
65
+ mod_attr_accessor :loaders, 'Array of generator loader methods.', []
66
+ mod_attr2_accessor :output, :o, 'Output-related methods.', Output.new
40
67
 
41
68
  def self.setup(document_content, input_name, output_directory)
42
69
  @doc = document_content
43
70
  @outdir = output_directory
44
- if input_name.nil?
45
- @in_name = nil
46
- @in_basename = nil
47
- else
71
+ unless input_name.nil?
48
72
  @in_name = File.basename(input_name)
49
73
  @in_basename = File.basename(input_name, '.*')
50
74
  end
51
- @tasks = []
52
- @g = {}
53
- @a = nil
54
- @h = nil
55
- @t = nil
56
- @task_index = nil
57
- @loaders = []
58
75
  add_task(task: HelperTask.new)
59
76
  end
60
77
 
data/lib/generate.rb CHANGED
@@ -8,6 +8,7 @@ require_relative 'common'
8
8
  require_relative 'loaders'
9
9
  require_relative 'gen'
10
10
 
11
+
11
12
  def executable_bits_on(mode)
12
13
  mode = mode.to_s(8).split('')
13
14
  mode.size.times do |k|
data/lib/helper.rb CHANGED
@@ -10,7 +10,7 @@ class Helper
10
10
  attr_reader :doc, :parents
11
11
  attr_accessor :parent_parameters
12
12
 
13
- # Stores the nearesh Hash for each Hash.
13
+ # Stores the nearest Hash for each Hash.
14
14
  def store_parents(obj, parent = nil)
15
15
  if obj.is_a?(Hash)
16
16
  @parents[obj.object_id] = parent
@@ -26,8 +26,6 @@ class Helper
26
26
 
27
27
  def initialize(doc)
28
28
  @doc = doc
29
- # For each hash in doc, set parent?
30
- # Build an object_id to parent object mapping and use parent method?
31
29
  @parents = {}
32
30
  store_parents(@doc)
33
31
  end
data/lib/loaders.rb CHANGED
@@ -3,6 +3,9 @@
3
3
  # Copyright © 2024 Ismo Kärkkäinen
4
4
  # Licensed under Universal Permissive License. See LICENSE.txt.
5
5
 
6
+
7
+ # Original loader functions. These are accessible via Gen.loaders. New loaders
8
+ # should be added there.
6
9
  module Loaders
7
10
 
8
11
  GEM_PREFIX = 'gem:'
@@ -37,14 +40,56 @@ module Loaders
37
40
  true
38
41
  end
39
42
 
43
+ YAML_PREFIX = 'yaml:'
44
+ YAML_EXTS = [ '.yaml', '.yml' ]
45
+
46
+ def self.yaml_loader(name)
47
+ d = name.downcase
48
+ if d.start_with?(YAML_PREFIX)
49
+ name = name.slice(YAML_PREFIX.size...name.size)
50
+ else
51
+ return false if (YAML_EXTS.index { |s| d.end_with?(s) }).nil?
52
+ end
53
+ n, sep, f = name.partition(':')
54
+ raise StandardError, "No name given." if n.empty?
55
+ raise StandardError, "No filename given." if f.empty?
56
+ doc = YAML.safe_load(File.read(f))
57
+ raise StandardError, "#{name} #{n} exists already." unless Gen.d.add(n, doc)
58
+ true
59
+ rescue Errno::ENOENT
60
+ raise StandardError, "Not found: #{f}\n#{e.to_s}"
61
+ rescue Exception => e
62
+ raise StandardError, "Failed to read as YAML: #{f}\n#{e.to_s}"
63
+ end
64
+
65
+ BIN_PREFIX = 'bin:'
66
+
67
+ def self.bin_loader(name)
68
+ return false unless name.downcase.start_with?(BIN_PREFIX)
69
+ n, sep, f = name.slice(BIN_PREFIX.size...name.size).partition(':')
70
+ raise StandardError, "No name given." if n.empty?
71
+ raise StandardError, "No filename given." if f.empty?
72
+ doc = IO.binread(f)
73
+ raise StandardError, "#{name} #{n} exists already." unless Gen.d.add(n, doc)
74
+ true
75
+ rescue Errno::ENOENT
76
+ raise StandardError, "Not found: #{f}\n#{e.to_s}"
77
+ rescue Exception => e
78
+ raise StandardError, "Failed to read #{f}\n#{e.to_s}"
79
+ end
80
+
40
81
  def self.loaders
41
- [ method(:gem_loader), method(:ruby_loader) ]
82
+ pre = @preloaders
83
+ [ method(:gem_loader), method(:ruby_loader), method(:yaml_loader), method(:bin_loader) ]
42
84
  end
43
85
 
44
86
  def self.document
45
87
  %(
46
88
  - #{Loaders::GEM_PREFIX}gem_name : requires the gem.
47
89
  - ruby_file#{Loaders::RUBY_EXT} : changes to Ruby file directory and requires the file.
90
+ - #{Loaders::YAML_PREFIX}name:filename : Loads YAML file into Gen.d.name.
91
+ - name:filename.{#{(Loaders::YAML_EXTS.map { |s| s[1...s.size] }).join('|')}} : Loads YAML file into Gen.d.name.
92
+ - #{Loaders::BIN_PREFIX}name:filename : Loads binary file into Gen.d.name.
48
93
  )
49
94
  end
50
95
 
data/lib/output.rb ADDED
@@ -0,0 +1,58 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright © 2024 Ismo Kärkkäinen
4
+ # Licensed under Universal Permissive License. See LICENSE.txt.
5
+
6
+ require_relative 'task'
7
+
8
+
9
+ class Output
10
+ # For indentation.
11
+ attr_accessor :indent_character, :indent_step
12
+ attr_accessor :tab, :tab_replaces_count
13
+ attr_accessor :last_indent
14
+
15
+ def initialize
16
+ @indent_character = ' '
17
+ @indent_step = 4
18
+ @tab = "\t"
19
+ @tab_replaces_count = 0
20
+ @last_indent = 0
21
+ end
22
+
23
+ def join(blocks, separator = "\n")
24
+ indented = []
25
+ blocks.flatten!
26
+ indent = 0
27
+ blocks.each do |block|
28
+ if block.nil?
29
+ indent = 0
30
+ elsif block.is_a?(Integer)
31
+ indent += block
32
+ elsif block.is_a?(TrueClass)
33
+ indent += @indent_step
34
+ elsif block.is_a?(FalseClass)
35
+ indent -= @indent_step
36
+ else
37
+ block = block.to_s unless block.is_a?(String)
38
+ if indent.zero?
39
+ indented.push(block)
40
+ next
41
+ end
42
+ if 0 < @tab_replaces_count
43
+ tabs = @tab * (indent / @tab_replaces_count)
44
+ chars = @indent_character * (indent % @tab_replaces_count)
45
+ else
46
+ tabs = ''
47
+ chars = @indent_character * indent
48
+ end
49
+ lines = block.lines(chomp: true)
50
+ lines.each do |line|
51
+ indented.push("#{tabs}#{chars}#{line}")
52
+ end
53
+ end
54
+ end
55
+ @last_indent = indent
56
+ indented.join(separator)
57
+ end
58
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: openapi-sourcetools
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ismo Kärkkäinen
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-07-17 00:00:00.000000000 Z
11
+ date: 2024-08-07 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: |2
14
14
 
@@ -25,6 +25,7 @@ executables:
25
25
  - openapi-frequencies
26
26
  - openapi-generate
27
27
  - openapi-merge
28
+ - openapi-modifypaths
28
29
  - openapi-processpaths
29
30
  extensions: []
30
31
  extra_rdoc_files: []
@@ -38,13 +39,16 @@ files:
38
39
  - bin/openapi-frequencies
39
40
  - bin/openapi-generate
40
41
  - bin/openapi-merge
42
+ - bin/openapi-modifypaths
41
43
  - bin/openapi-processpaths
42
44
  - lib/apiobjects.rb
43
45
  - lib/common.rb
46
+ - lib/docs.rb
44
47
  - lib/gen.rb
45
48
  - lib/generate.rb
46
49
  - lib/helper.rb
47
50
  - lib/loaders.rb
51
+ - lib/output.rb
48
52
  - lib/task.rb
49
53
  homepage: https://xn--ismo-krkkinen-gfbd.fi/openapi-sourcetools/index.html
50
54
  licenses: