lib/jimmy/domain.rb in jimmy-0.1.0 vs lib/jimmy/domain.rb in jimmy-0.1.1

- old
+ new

@@ -1,48 +1,95 @@ require 'uri' require 'pathname' +require 'json' +require 'json-schema' require_relative 'schema_creation' module Jimmy class Domain - attr_reader :root, :types + attr_reader :root, :types, :partials def initialize(root) - @root = URI(root) - @schemas = {} - @types = {} + @root = URI(root) + @schemas = {} + @types = {} + @partials = {} + @import_paths = [] end def domain self end - def import_path(path) + def import(path) path = Pathname(path) unless path.is_a? Pathname - @types = import_schemas(path + 'types', path).map { |k, v| [k.to_sym, v] }.to_h - @schemas = import_schemas(path, path, 'types/') + @import_paths << path unless @import_paths.include? path + + glob path, only: 'types' do |name, schema| + @types[name.to_sym] = schema + end + + glob path, only: 'partials' do |name| + partial_path = path + 'partials' + "#{name}.rb" + @partials[name] = [partial_path.read, partial_path.to_s] + end + + glob path, ignore: %r`^(types|partials)/` do |name, schema| + @schemas[name] = schema + end end + def autoload_type(name) + # TODO: protect from circular dependency + return if types.key? name + @import_paths.each do |import_path| + path = import_path + "types/#{name}.rb" + if path.file? + @types[name] = load_schema_from_path(path, name) + return true + end + end + false + end + def [](schema_name) @schemas[schema_name.to_s] end + def export(path = nil) + path = Pathname(path) if path.is_a? String + raise 'Please specify an export directory' unless path.is_a?(Pathname) && (path.directory? || !path.exist?) + path.mkpath + @schemas.each { |name, schema| export_schema schema, path + "#{name.to_s}.json" } + @types.each { |name, schema| export_schema schema, path + 'types' + "#{name.to_s}.json" } + end + private - def import_schemas(path, base_path, reject_prefix = nil) - result = {} - Dir[path + '**/*.rb'].each do |full_path| + def glob(base_path, only: '.', ignore: nil, &block) + lookup_path = base_path + only + Dir[lookup_path + '**/*.rb'].each do |full_path| full_path = Pathname(full_path) - relative_path = full_path.relative_path_from(path) - next if reject_prefix && relative_path.to_s.start_with?(reject_prefix) - base_name = relative_path.to_s[0..-4] - schema = instance_eval(full_path.read, full_path.to_s).schema - schema.name = full_path.relative_path_from(base_path).to_s[0..-4] - result[base_name] = schema + relative_path = full_path.relative_path_from(lookup_path) + next if ignore === relative_path.to_s + args = [relative_path.to_s[0..-4]] + args << load_schema_from_path(full_path, full_path.relative_path_from(base_path).to_s[0..-4]) if block.arity == 2 + yield *args end - result + end + + def load_schema_from_path(path, name) + instance_eval(path.read, path.to_s).schema.tap do |schema| + schema.name = name.to_s + JSON::Validator.add_schema JSON::Schema.new(schema.to_h, nil) + end + end + + def export_schema(schema, target_path) + target_path.parent.mkpath + target_path.write JSON.pretty_generate(schema.to_h) end SchemaCreation.apply_to self end