Class: Ree::PackageSchemaLoader

Inherits:
Object
  • Object
show all
Defined in:
lib/ree/core/package_schema_loader.rb

Constant Summary collapse

Schema =

Sample Package.schema.json {

"schema_type": "package",
"schema_version": "1.2.3",
"name": "accounts",
"entry_path": "package/accounts.rb",
"depends_on": [
  {
    "name": "clock",
  },
  {
    "name": "test_utils",
  }
],
"env_vars": [
  {
    "name": "accounts.string_var",
    "doc": null
  },
  {
    "name": "accounts.integer_var",
    "doc": "integer value"
  }
],
"objects": [
  {
    "name": "accounts_cfg",
    "schema": "schemas/accounts/accounts_cfg.schema.json"
  },
  {
    "name": "transaction",
    "schema": "schemas/accounts/transaction.schema.json"
  }
]

}

Ree::PackageSchema

Instance Method Summary collapse

Instance Method Details

#call(abs_schema_path, existing_package = nil) ⇒ Ree::Package

Parameters:

  • abs_schema_path (String)

    Absolute path to package Package.schema.json file

  • existing_package (Nilor[Ree::Package]) (defaults to: nil)

    Loaded package

Returns:



48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
# File 'lib/ree/core/package_schema_loader.rb', line 48

def call(abs_schema_path, existing_package = nil)
  if !File.exist?(abs_schema_path)
    raise Ree::Error.new("File not found: #{abs_schema_path}", :invalid_package_schema)
  end

  json_schema = begin
    JSON.load_file(abs_schema_path)
  rescue
    raise Ree::Error.new("Invalid content: #{abs_schema_path}", :invalid_package_schema)
  end

  schema_type = json_schema.fetch(Schema::SCHEMA_TYPE)

  if schema_type != Schema::PACKAGE
    raise Ree::Error.new("Invalid schema type: #{abs_schema_path}", :invalid_package_schema)
  end

  schema_version = json_schema.fetch(Schema::SCHEMA_VERSION) { Schema::SCHEMA_VERSION_NUMBER }
  entry_rpath = json_schema.fetch(Schema::ENTRY_PATH)
  package_name = json_schema.fetch(Schema::NAME).to_sym

  root_dir = if existing_package && existing_package.gem?
    Ree.gem(existing_package.gem_name).dir
  else
    Ree.root_dir
  end

  schema_rpath = Pathname
    .new(abs_schema_path)
    .relative_path_from(Pathname.new(root_dir))
    .to_s

  object_store = {}
  deps_store = {}
  vars_store = {}

  package = if existing_package
    existing_package
      .set_schema_version(schema_version)
      .set_entry_rpath(entry_rpath)
      .set_schema_rpath(schema_rpath)
  else
    Ree::Package.new(
      schema_version,
      package_name,
      entry_rpath,
      schema_rpath,
      nil
    )
  end

  package.set_schema_loaded

  json_schema.fetch(Schema::OBJECTS).each do |item|
    name = item[Schema::Objects::NAME].to_s
    schema_rpath = item[Schema::Objects::SCHEMA].to_s
    list = [name, schema_rpath]
    tags = item[Schema::Objects::TAGS] || []

    if list.reject(&:empty?).size != list.size
      raise Ree::Error.new("invalid object data for #{item.inspect}: #{abs_schema_path}", :invalid_package_schema)
    end

    if object_store.has_key?(name)
      raise Ree::Error.new("duplicate object name for '#{item[:name]}': #{abs_schema_path}", :invalid_package_schema)
    end

    object_store[name] = true

    object = Ree::Object.new(
      name.to_sym,
      schema_rpath,
      Ree::PathHelper.object_rpath(schema_rpath),
    )

    object.add_tags(tags)
    object.set_package(package.name)

    package.set_object(object)
  end

  deps = json_schema.fetch(Schema::DEPENDS_ON).map do |item|
    name = item[Schema::DependsOn::NAME].to_sym
    list = [name]

    if list.reject(&:empty?).size != list.size
      raise Ree::Error.new("invalid depends_on for: #{item.inspect}", :invalid_package_schema)
    end

    if deps_store.has_key?(name)
      raise Ree::Error.new("duplicate depends_on name for '#{item[:name]}'", :invalid_package_schema)
    end

    deps_store[name] = true
    Ree::PackageDep.new(name)
  end

  package.set_deps(deps)

  env_vars = json_schema.fetch(Schema::ENV_VARS).map do |item|
    name = item[Schema::EnvVars::NAME].to_s
    doc = item[Schema::EnvVars::DOC]
    list = [name]

    if list.reject(&:empty?).size != list.size
      raise Ree::Error.new("invalid env_var for: #{item.inspect}", :invalid_package_schema)
    end

    if vars_store.has_key?(name)
      raise Ree::Error.new("duplicate env_var name for '#{item[:name]}'", :invalid_package_schema)
    end

    vars_store[name] = true

    Ree::PackageEnvVar.new(name, doc)
  end

  package.set_env_vars(env_vars)

  tags = json_schema.fetch(Schema::TAGS)
  package.set_tags(tags)

  package
end