Last active
March 6, 2020 05:35
-
-
Save lighty/e0800fbe5dcfb16ccc2d3c721e5e188c to your computer and use it in GitHub Desktop.
openapi3形式で書かれた、肥大化したスキーマ定義ファイルを分割する
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# '#/components/schemas/BadRequest' | |
# → components/schemas/BadRequest.yml | |
# '#/components/responses/unauthorized' | |
# → components/responses.yml#/unauthorized | |
require 'yaml' | |
require 'fileutils' | |
require 'pry' | |
class RelativeDocumentReferecer | |
def self.execute(root, depth) | |
new(root, depth).execute | |
end | |
def initialize(root, depth) | |
@root = root | |
@depth = depth | |
end | |
def execute | |
lookup(root) | |
root | |
end | |
# hashで、keyが$refならconvert | |
# hashかarrayならlookup | |
# そうでないならなにもしない | |
def lookup(object) | |
if object.is_a? Array | |
object.each { |value| lookup(value) if value.is_a?(Hash) || value.is_a?(Array) } | |
else | |
object.each do |key, value| | |
set_converted_value(object, key, value) if key === "$ref" | |
lookup(value) if value.is_a?(Hash) || value.is_a?(Array) | |
end | |
end | |
end | |
def set_converted_value(object, key, value) | |
object[key] = convert(value) | |
end | |
def convert(ref) | |
# componentから取得することしか考えない | |
if ref.split('/')[2] === 'schemas' | |
"../" * depth + "#{ref.split('/')[1..3].join('/')}.yml" | |
else | |
"../" * depth + "#{ref.split('/')[1..2].join('/')}.yml#/#{ref.split('/')[3]}" | |
end | |
end | |
private | |
attr :root, :depth | |
end | |
class PathsObject | |
attr_accessor :path, :path_item_objects | |
def initialize(path, path_item_objects) | |
@path = path | |
@path_item_objects = path_item_objects | |
end | |
def to_file | |
make_directory | |
convert_ref | |
YAML.dump(path_item_objects, File.open( File.join(directory, file_name) , 'w') ) | |
end | |
def make_directory | |
FileUtils.mkdir_p( directory ) | |
rescue => e | |
puts "path: #{@path}" | |
throw e | |
end | |
def interlevel_directory | |
@path.split('/').length > 2 ? @path.split('/')[1..-2].map {|dir| dir.gsub(/[{}]/,"")} : '' | |
end | |
def directory | |
File.join( 'paths' , interlevel_directory) | |
end | |
def file_name | |
"#{@path.split('/').pop.gsub(/[{}]/,"")}.yml" | |
end | |
def ref | |
File.join(directory, file_name) | |
end | |
def convert_ref | |
RelativeDocumentReferecer.execute(path_item_objects, 1 + interlevel_directory.size) | |
end | |
end | |
class ComponentsObjectFieldObject | |
attr_accessor :field_name, :field_object | |
def initialize(field_name, field_object) | |
@field_name = field_name | |
@field_object = field_object | |
end | |
def to_file | |
convert_ref | |
YAML.dump(field_object, File.open( File.join(directory, file_name) , 'w') ) | |
end | |
def directory | |
'components' | |
end | |
def file_name | |
"#{field_name}.yml" | |
end | |
def ref | |
File.join(directory, file_name) | |
end | |
def convert_ref | |
RelativeDocumentReferecer.execute(field_object, 1) | |
end | |
end | |
class SchemaObject | |
attr_accessor :schema_name, :schema_object | |
def initialize(schema_name, schema_object) | |
@schema_name = schema_name | |
@schema_object = schema_object | |
end | |
def to_file | |
convert_ref | |
YAML.dump(schema_object, File.open( File.join(directory, file_name) , 'w') ) | |
end | |
def directory | |
'components/schemas' | |
end | |
def file_name | |
"#{schema_name}.yml" | |
end | |
def ref | |
File.join(directory, file_name) | |
end | |
def convert_ref | |
RelativeDocumentReferecer.execute(schema_object, 2) | |
end | |
end | |
open_api_object = YAML.load_file 'swagger_original.yml' | |
open_api_object.keys.each do |open_api_object_field| | |
if open_api_object_field === "paths" | |
FileUtils.mkdir_p('paths') | |
paths_objects = open_api_object[open_api_object_field] | |
paths_objects.keys.each do |path| | |
path_object = PathsObject.new(path, paths_objects[path]) # 一つのpathオブジェクト。postなどがキー | |
path_object.to_file | |
open_api_object[open_api_object_field][path] = { "$ref" => path_object.ref } | |
end | |
end | |
if open_api_object_field === "components" | |
FileUtils.mkdir_p('components') | |
components_objects = open_api_object[open_api_object_field] | |
components_objects.keys.each do |components_object_field| | |
if components_object_field === 'schemas' | |
FileUtils.mkdir_p('components/schemas') | |
schmas = components_objects[components_object_field] | |
schmas.keys.each do |schema_name| | |
schema_object = SchemaObject.new(schema_name, schmas[schema_name]) | |
schema_object.to_file | |
open_api_object[open_api_object_field][components_object_field][schema_name] = { "$ref" => schema_object.ref } | |
end | |
else | |
field_object = ComponentsObjectFieldObject.new(components_object_field, components_objects[components_object_field]) | |
field_object.to_file | |
open_api_object[open_api_object_field][components_object_field] = { "$ref" => field_object.ref } | |
end | |
end | |
end | |
end | |
YAML.dump(open_api_object, File.open( 'swagger_root.yml', 'w')) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment