module MinimumTerm::Conversion
Public Class Methods
data_structures_from_blueprint_ast(filename)
click to toggle source
# File lib/minimum-term/conversion.rb, line 102 def self.data_structures_from_blueprint_ast(filename) c = JSON.parse(open(filename).read)['ast']['content'].first return [] unless c c['content'] end
mson_to_ast_json(filename)
click to toggle source
# File lib/minimum-term/conversion.rb, line 108 def self.mson_to_ast_json(filename) input = filename output = filename.gsub(/\.\w+$/, '.blueprint-ast.json') parse_result = FFI::MemoryPointer.new :pointer RedSnow::Binding.drafter_c_parse(open(input).read, 0, parse_result) parse_result = parse_result.get_pointer(0) status = -1 result = '' unless parse_result.null? status = 0 result = parse_result.read_string end File.open(output, 'w'){ |f| f.puts(result) } output ensure RedSnow::Memory.free(parse_result) end
mson_to_json_schema(filename:, keep_intermediary_files: false, verbose: false)
click to toggle source
# File lib/minimum-term/conversion.rb, line 9 def self.mson_to_json_schema(filename:, keep_intermediary_files: false, verbose: false) begin mson_to_json_schema!(filename: filename, keep_intermediary_files: keep_intermediary_files, verbose: verbose) puts "OK ".green + filename if verbose true rescue puts "ERROR ".red + filename if verbose false end end
mson_to_json_schema!(filename:, keep_intermediary_files: false, verbose: true)
click to toggle source
# File lib/minimum-term/conversion.rb, line 20 def self.mson_to_json_schema!(filename:, keep_intermediary_files: false, verbose: true) # For now, we'll use the containing directory's name as a scope service_scope = File.dirname(filename).split(File::SEPARATOR).last.underscore # Parse MSON to an apiary blueprint AST # (see https://github.com/apiaryio/api-blueprint/wiki/API-Blueprint-Map) ast_file = mson_to_ast_json(filename) # Pluck out Data structures from it data_structures = data_structures_from_blueprint_ast(ast_file) # Generate json schema from each contained data structure schema = { "$schema" => "http://json-schema.org/draft-04/schema#", "title" => service_scope, "definitions" => {}, "type" => "object", "properties" => {}, } # The scope for the data structure is the name of the service # publishing the object. So if we're parsing a 'consume' schema, # the containing objects are alredy scoped (because a consume # schema says 'i consume object X from service Y'. basename = File.basename(filename) if basename.end_with?("publish.mson") data_structure_autoscope = service_scope elsif basename.end_with?("consume.mson") data_structure_autoscope = nil else raise Error, "Invalid filename #{basename}, can't tell if it's a publish or consume schema" end # The json schema we're constructing contains every known # object type in the 'definitions'. So if we have definitions for # the objects User, Post and Tag, the schema will look like this: # # { # "$schema": "..." # # "definitions": { # "user": { "type": "object", "properties": { ... }} # "post": { "type": "object", "properties": { ... }} # "tag": { "type": "object", "properties": { ... }} # } # # "properties": { # "user": "#/definitions/user" # "post": "#/definitions/post" # "tag": "#/definitions/tag" # } # # } # # So when testing an object of type `user` against this schema, # we need to wrap it as: # # { # user: { # "your": "actual", # "data": "goes here" # } # } # data_structures.each do |data| id = data['name']['literal'] json= DataStructure.new(id, data, data_structure_autoscope).to_json member = json.delete('title') schema['definitions'][member] = json schema['properties'][member] = {"$ref" => "#/definitions/#{member}"} end # Write it in a file outfile = filename.gsub(/\.\w+$/, '.schema.json') File.open(outfile, 'w'){ |f| f.puts JSON.pretty_generate(schema) } # Clean up FileUtils.rm_f(ast_file) unless keep_intermediary_files true end