expressir 2.1.29 → 2.1.31
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 +4 -4
- data/.github/workflows/docs.yml +98 -0
- data/.github/workflows/links.yml +100 -0
- data/.github/workflows/rake.yml +4 -0
- data/.github/workflows/release.yml +5 -0
- data/.github/workflows/validate_schemas.yml +1 -1
- data/.gitignore +3 -0
- data/.rubocop.yml +1 -1
- data/.rubocop_todo.yml +209 -55
- data/Gemfile +2 -1
- data/README.adoc +650 -83
- data/docs/Gemfile +12 -0
- data/docs/_config.yml +141 -0
- data/docs/_guides/changes/changes-format.adoc +778 -0
- data/docs/_guides/changes/importing-eengine.adoc +898 -0
- data/docs/_guides/changes/index.adoc +396 -0
- data/docs/_guides/changes/programmatic-usage.adoc +1038 -0
- data/docs/_guides/changes/validating-changes.adoc +681 -0
- data/docs/_guides/cli/benchmark-performance.adoc +834 -0
- data/docs/_guides/cli/coverage-analysis.adoc +921 -0
- data/docs/_guides/cli/format-schemas.adoc +547 -0
- data/docs/_guides/cli/index.adoc +8 -0
- data/docs/_guides/cli/managing-changes.adoc +927 -0
- data/docs/_guides/cli/validate-ascii.adoc +645 -0
- data/docs/_guides/cli/validate-schemas.adoc +534 -0
- data/docs/_guides/index.adoc +165 -0
- data/docs/_guides/ler/creating-packages.adoc +664 -0
- data/docs/_guides/ler/index.adoc +305 -0
- data/docs/_guides/ler/loading-packages.adoc +707 -0
- data/docs/_guides/ler/package-formats.adoc +748 -0
- data/docs/_guides/ler/querying-packages.adoc +826 -0
- data/docs/_guides/ler/validating-packages.adoc +750 -0
- data/docs/_guides/liquid/basic-templates.adoc +813 -0
- data/docs/_guides/liquid/documentation-generation.adoc +1042 -0
- data/docs/_guides/liquid/drops-reference.adoc +829 -0
- data/docs/_guides/liquid/filters-and-tags.adoc +912 -0
- data/docs/_guides/liquid/index.adoc +468 -0
- data/docs/_guides/manifests/creating-manifests.adoc +483 -0
- data/docs/_guides/manifests/index.adoc +307 -0
- data/docs/_guides/manifests/resolving-manifests.adoc +557 -0
- data/docs/_guides/manifests/validating-manifests.adoc +713 -0
- data/docs/_guides/ruby-api/formatting-schemas.adoc +605 -0
- data/docs/_guides/ruby-api/index.adoc +257 -0
- data/docs/_guides/ruby-api/parsing-files.adoc +421 -0
- data/docs/_guides/ruby-api/search-engine.adoc +609 -0
- data/docs/_guides/ruby-api/working-with-repository.adoc +577 -0
- data/docs/_pages/data-model.adoc +665 -0
- data/docs/_pages/express-language.adoc +506 -0
- data/docs/_pages/getting-started.adoc +414 -0
- data/docs/_pages/index.adoc +116 -0
- data/docs/_pages/introduction.adoc +256 -0
- data/docs/_pages/ler-packages.adoc +837 -0
- data/docs/_pages/parsers.adoc +683 -0
- data/docs/_pages/schema-manifests.adoc +431 -0
- data/docs/_references/index.adoc +228 -0
- data/docs/_tutorials/creating-ler-package.adoc +735 -0
- data/docs/_tutorials/documentation-coverage.adoc +795 -0
- data/docs/_tutorials/index.adoc +221 -0
- data/docs/_tutorials/liquid-templates.adoc +806 -0
- data/docs/_tutorials/parsing-your-first-schema.adoc +522 -0
- data/docs/_tutorials/querying-schemas.adoc +751 -0
- data/docs/_tutorials/working-with-multiple-schemas.adoc +676 -0
- data/docs/index.adoc +242 -0
- data/docs/lychee.toml +84 -0
- data/examples/demo_ler_usage.sh +86 -0
- data/examples/ler/README.md +111 -0
- data/examples/ler/simple_example.ler +0 -0
- data/examples/ler/simple_schema.exp +33 -0
- data/examples/ler_build.rb +75 -0
- data/examples/ler_cli.rb +79 -0
- data/examples/ler_demo_complete.rb +276 -0
- data/examples/ler_query.rb +91 -0
- data/examples/ler_query_examples.rb +305 -0
- data/examples/ler_stats.rb +81 -0
- data/examples/phase3_demo.rb +159 -0
- data/examples/query_demo_simple.rb +131 -0
- data/expressir.gemspec +2 -0
- data/lib/expressir/changes/schema_change.rb +32 -22
- data/lib/expressir/changes/{edition_change.rb → version_change.rb} +3 -3
- data/lib/expressir/cli.rb +12 -4
- data/lib/expressir/commands/changes_import_eengine.rb +2 -2
- data/lib/expressir/commands/changes_validate.rb +1 -1
- data/lib/expressir/commands/manifest.rb +427 -0
- data/lib/expressir/commands/package.rb +1274 -0
- data/lib/expressir/commands/validate.rb +70 -37
- data/lib/expressir/commands/validate_ascii.rb +607 -0
- data/lib/expressir/commands/validate_load.rb +88 -0
- data/lib/expressir/express/formatter.rb +5 -1
- data/lib/expressir/express/formatters/remark_item_formatter.rb +25 -0
- data/lib/expressir/express/parser.rb +33 -0
- data/lib/expressir/manifest/resolver.rb +213 -0
- data/lib/expressir/manifest/validator.rb +195 -0
- data/lib/expressir/model/declarations/entity.rb +6 -0
- data/lib/expressir/model/dependency_resolver.rb +270 -0
- data/lib/expressir/model/indexes/entity_index.rb +103 -0
- data/lib/expressir/model/indexes/reference_index.rb +148 -0
- data/lib/expressir/model/indexes/type_index.rb +149 -0
- data/lib/expressir/model/interface_validator.rb +384 -0
- data/lib/expressir/model/repository.rb +400 -5
- data/lib/expressir/model/repository_validator.rb +295 -0
- data/lib/expressir/model/search_engine.rb +525 -0
- data/lib/expressir/model.rb +4 -94
- data/lib/expressir/package/builder.rb +200 -0
- data/lib/expressir/package/metadata.rb +81 -0
- data/lib/expressir/package/reader.rb +165 -0
- data/lib/expressir/schema_manifest.rb +11 -1
- data/lib/expressir/version.rb +1 -1
- data/lib/expressir.rb +16 -3
- metadata +115 -5
- data/docs/benchmarking.adoc +0 -107
- data/docs/liquid_drops.adoc +0 -1547
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "zip"
|
|
4
|
+
require "time"
|
|
5
|
+
require_relative "metadata"
|
|
6
|
+
|
|
7
|
+
module Expressir
|
|
8
|
+
module Package
|
|
9
|
+
# Builds LER packages from Repository instances
|
|
10
|
+
# Single responsibility: Create .ler ZIP packages
|
|
11
|
+
class Builder
|
|
12
|
+
# Build LER package from repository
|
|
13
|
+
# @param repository [Model::Repository] Repository to package
|
|
14
|
+
# @param output_path [String] Output .ler file path
|
|
15
|
+
# @param options [Hash] Package options
|
|
16
|
+
# @option options [String] :name Package name
|
|
17
|
+
# @option options [String] :version Package version
|
|
18
|
+
# @option options [String] :description Package description
|
|
19
|
+
# @option options [String] :express_mode ('include_all') Bundling mode
|
|
20
|
+
# @option options [String] :resolution_mode ('resolved') Resolution mode
|
|
21
|
+
# @option options [String] :serialization_format ('marshal') Serialization format
|
|
22
|
+
# @return [String] Path to created package
|
|
23
|
+
def build(repository, output_path, options = {})
|
|
24
|
+
options = normalize_options(options)
|
|
25
|
+
metadata = build_metadata(repository, options)
|
|
26
|
+
|
|
27
|
+
# Validate metadata
|
|
28
|
+
validation = metadata.validate
|
|
29
|
+
unless validation[:valid?]
|
|
30
|
+
raise ArgumentError,
|
|
31
|
+
"Invalid metadata: #{validation[:errors].join(', ')}"
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Create ZIP package
|
|
35
|
+
Zip::File.open(output_path, Zip::File::CREATE) do |zip|
|
|
36
|
+
add_metadata(zip, metadata)
|
|
37
|
+
add_schemas(zip, repository, options)
|
|
38
|
+
add_indexes(zip, repository)
|
|
39
|
+
add_manifest(zip, repository)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
output_path
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
private
|
|
46
|
+
|
|
47
|
+
# Normalize options with defaults
|
|
48
|
+
# @param options [Hash] Raw options
|
|
49
|
+
# @return [Hash] Normalized options
|
|
50
|
+
def normalize_options(options)
|
|
51
|
+
{
|
|
52
|
+
name: options[:name] || "Unnamed Package",
|
|
53
|
+
version: options[:version] || "1.0.0",
|
|
54
|
+
description: options[:description] || "",
|
|
55
|
+
express_mode: options[:express_mode] || "include_all",
|
|
56
|
+
resolution_mode: options[:resolution_mode] || "resolved",
|
|
57
|
+
serialization_format: options[:serialization_format] || "marshal",
|
|
58
|
+
}
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# Build metadata from repository and options
|
|
62
|
+
# @param repository [Model::Repository] Repository instance
|
|
63
|
+
# @param options [Hash] Package options
|
|
64
|
+
# @return [Metadata] Package metadata
|
|
65
|
+
def build_metadata(repository, options)
|
|
66
|
+
Metadata.new(
|
|
67
|
+
name: options[:name],
|
|
68
|
+
version: options[:version],
|
|
69
|
+
description: options[:description],
|
|
70
|
+
created_at: Time.now.utc.iso8601,
|
|
71
|
+
created_by: "expressir",
|
|
72
|
+
expressir_version: Expressir::VERSION,
|
|
73
|
+
express_mode: options[:express_mode],
|
|
74
|
+
resolution_mode: options[:resolution_mode],
|
|
75
|
+
serialization_format: options[:serialization_format],
|
|
76
|
+
files: count_files(repository),
|
|
77
|
+
schemas: repository.schemas.size,
|
|
78
|
+
)
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# Count files in repository
|
|
82
|
+
# @param repository [Model::Repository] Repository instance
|
|
83
|
+
# @return [Integer] File count
|
|
84
|
+
def count_files(repository)
|
|
85
|
+
repository.schemas.count(&:file)
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
# Add metadata to package
|
|
89
|
+
# @param zip [Zip::File] ZIP archive
|
|
90
|
+
# @param metadata [Metadata] Package metadata
|
|
91
|
+
# @return [void]
|
|
92
|
+
def add_metadata(zip, metadata)
|
|
93
|
+
zip.get_output_stream("metadata.yaml") do |stream|
|
|
94
|
+
stream.write(metadata.to_yaml)
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
# Add schemas to package based on resolution mode
|
|
99
|
+
# @param zip [Zip::File] ZIP archive
|
|
100
|
+
# @param repository [Model::Repository] Repository instance
|
|
101
|
+
# @param options [Hash] Package options
|
|
102
|
+
# @return [void]
|
|
103
|
+
def add_schemas(zip, repository, options)
|
|
104
|
+
case options[:resolution_mode]
|
|
105
|
+
when "resolved"
|
|
106
|
+
add_serialized_repository(zip, repository,
|
|
107
|
+
options[:serialization_format])
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
# Add EXPRESS files if include_all mode
|
|
111
|
+
if options[:express_mode] == "include_all"
|
|
112
|
+
add_express_files(zip, repository)
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
# Add serialized repository to package
|
|
117
|
+
# @param zip [Zip::File] ZIP archive
|
|
118
|
+
# @param repository [Model::Repository] Repository instance
|
|
119
|
+
# @param format [String] Serialization format
|
|
120
|
+
# @return [void]
|
|
121
|
+
def add_serialized_repository(zip, repository, format)
|
|
122
|
+
case format
|
|
123
|
+
when "marshal"
|
|
124
|
+
zip.get_output_stream("repository.marshal") do |stream|
|
|
125
|
+
stream.write(Marshal.dump(repository))
|
|
126
|
+
end
|
|
127
|
+
when "json"
|
|
128
|
+
zip.get_output_stream("repository.json") do |stream|
|
|
129
|
+
stream.write(repository.to_json)
|
|
130
|
+
end
|
|
131
|
+
when "yaml"
|
|
132
|
+
zip.get_output_stream("repository.yaml") do |stream|
|
|
133
|
+
stream.write(repository.to_yaml)
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
# Add EXPRESS files to package
|
|
139
|
+
# @param zip [Zip::File] ZIP archive
|
|
140
|
+
# @param repository [Model::Repository] Repository instance
|
|
141
|
+
# @return [void]
|
|
142
|
+
def add_express_files(zip, repository)
|
|
143
|
+
repository.schemas.each do |schema|
|
|
144
|
+
next unless schema.file && File.exist?(schema.file)
|
|
145
|
+
|
|
146
|
+
# Use schema id as filename
|
|
147
|
+
filename = "express_files/#{schema.id}.exp"
|
|
148
|
+
zip.get_output_stream(filename) do |stream|
|
|
149
|
+
stream.write(File.read(schema.file))
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
# Add indexes to package
|
|
155
|
+
# @param zip [Zip::File] ZIP archive
|
|
156
|
+
# @param repository [Model::Repository] Repository instance
|
|
157
|
+
# @return [void]
|
|
158
|
+
def add_indexes(zip, repository)
|
|
159
|
+
# Ensure indexes are built
|
|
160
|
+
repository.build_indexes if repository.entity_index.nil?
|
|
161
|
+
|
|
162
|
+
# Serialize indexes using Marshal for performance
|
|
163
|
+
zip.get_output_stream("entity_index.marshal") do |stream|
|
|
164
|
+
stream.write(Marshal.dump(repository.entity_index))
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
zip.get_output_stream("type_index.marshal") do |stream|
|
|
168
|
+
stream.write(Marshal.dump(repository.type_index))
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
zip.get_output_stream("reference_index.marshal") do |stream|
|
|
172
|
+
stream.write(Marshal.dump(repository.reference_index))
|
|
173
|
+
end
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
# Add manifest to package with rewritten paths
|
|
177
|
+
# @param zip [Zip::File] ZIP archive
|
|
178
|
+
# @param repository [Model::Repository] Repository instance
|
|
179
|
+
# @return [void]
|
|
180
|
+
def add_manifest(zip, repository)
|
|
181
|
+
# Create manifest with package-internal paths
|
|
182
|
+
manifest = Expressir::SchemaManifest.new
|
|
183
|
+
|
|
184
|
+
repository.schemas.each do |schema|
|
|
185
|
+
manifest.schemas << Expressir::SchemaManifestEntry.new(
|
|
186
|
+
id: schema.id,
|
|
187
|
+
path: "express_files/#{schema.id}.exp", # Package-internal path
|
|
188
|
+
)
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
# Set output_path to suppress relative path calculation
|
|
192
|
+
manifest.output_path = "manifest.yaml"
|
|
193
|
+
|
|
194
|
+
zip.get_output_stream("manifest.yaml") do |stream|
|
|
195
|
+
stream.write(manifest.to_yaml)
|
|
196
|
+
end
|
|
197
|
+
end
|
|
198
|
+
end
|
|
199
|
+
end
|
|
200
|
+
end
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "lutaml/model"
|
|
4
|
+
|
|
5
|
+
module Expressir
|
|
6
|
+
module Package
|
|
7
|
+
# Package metadata with serialization support
|
|
8
|
+
# Stores configuration and statistics for LER packages
|
|
9
|
+
class Metadata < Lutaml::Model::Serializable
|
|
10
|
+
attribute :name, :string
|
|
11
|
+
attribute :version, :string
|
|
12
|
+
attribute :description, :string
|
|
13
|
+
attribute :created_at, :string
|
|
14
|
+
attribute :created_by, :string, default: -> { "expressir" }
|
|
15
|
+
attribute :expressir_version, :string
|
|
16
|
+
attribute :express_mode, :string, default: -> { "include_all" }
|
|
17
|
+
attribute :resolution_mode, :string, default: -> { "resolved" }
|
|
18
|
+
attribute :serialization_format, :string, default: -> { "marshal" }
|
|
19
|
+
attribute :files, :integer
|
|
20
|
+
attribute :schemas, :integer
|
|
21
|
+
|
|
22
|
+
yaml do
|
|
23
|
+
map "name", to: :name
|
|
24
|
+
map "version", to: :version
|
|
25
|
+
map "description", to: :description
|
|
26
|
+
map "created_at", to: :created_at
|
|
27
|
+
map "created_by", to: :created_by
|
|
28
|
+
map "expressir_version", to: :expressir_version
|
|
29
|
+
map "express_mode", to: :express_mode
|
|
30
|
+
map "resolution_mode", to: :resolution_mode
|
|
31
|
+
map "serialization_format", to: :serialization_format
|
|
32
|
+
map "files", to: :files
|
|
33
|
+
map "schemas", to: :schemas
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Validate metadata configuration
|
|
37
|
+
# @return [Hash] Validation result with :valid? and :errors
|
|
38
|
+
def validate
|
|
39
|
+
errors = []
|
|
40
|
+
|
|
41
|
+
errors << "name is required" if name.nil? || name.empty?
|
|
42
|
+
errors << "version is required" if version.nil? || version.empty?
|
|
43
|
+
|
|
44
|
+
unless %w[include_all allow_external].include?(express_mode)
|
|
45
|
+
errors << "express_mode must be 'include_all' or 'allow_external'"
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
unless %w[resolved bare].include?(resolution_mode)
|
|
49
|
+
errors << "resolution_mode must be 'resolved' or 'bare'"
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
unless %w[marshal json yaml].include?(serialization_format)
|
|
53
|
+
errors << "serialization_format must be 'marshal', 'json', or 'yaml'"
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
{
|
|
57
|
+
valid?: errors.empty?,
|
|
58
|
+
errors: errors,
|
|
59
|
+
}
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# Convert metadata to hash
|
|
63
|
+
# @return [Hash] Metadata as hash
|
|
64
|
+
def to_h
|
|
65
|
+
{
|
|
66
|
+
"name" => name,
|
|
67
|
+
"version" => version,
|
|
68
|
+
"description" => description,
|
|
69
|
+
"created_at" => created_at,
|
|
70
|
+
"created_by" => created_by,
|
|
71
|
+
"expressir_version" => expressir_version,
|
|
72
|
+
"express_mode" => express_mode,
|
|
73
|
+
"resolution_mode" => resolution_mode,
|
|
74
|
+
"serialization_format" => serialization_format,
|
|
75
|
+
"files" => files,
|
|
76
|
+
"schemas" => schemas,
|
|
77
|
+
}
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "zip"
|
|
4
|
+
require_relative "metadata"
|
|
5
|
+
|
|
6
|
+
module Expressir
|
|
7
|
+
module Package
|
|
8
|
+
# Loads LER packages into Repository instances
|
|
9
|
+
# Single responsibility: Load .ler ZIP packages
|
|
10
|
+
class Reader
|
|
11
|
+
# Load repository from LER package
|
|
12
|
+
# @param package_path [String] Path to .ler file
|
|
13
|
+
# @return [Model::Repository] Loaded repository
|
|
14
|
+
def self.load(package_path)
|
|
15
|
+
new.load(package_path)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# Load repository from LER package
|
|
19
|
+
# @param package_path [String] Path to .ler file
|
|
20
|
+
# @return [Model::Repository] Loaded repository
|
|
21
|
+
def load(package_path)
|
|
22
|
+
unless File.exist?(package_path)
|
|
23
|
+
raise ArgumentError, "Package file not found: #{package_path}"
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
repository = nil
|
|
27
|
+
metadata = nil
|
|
28
|
+
|
|
29
|
+
Zip::File.open(package_path) do |zip|
|
|
30
|
+
# Read metadata first
|
|
31
|
+
metadata = load_metadata(zip)
|
|
32
|
+
|
|
33
|
+
# Load repository based on resolution mode
|
|
34
|
+
repository = if metadata.resolution_mode == "resolved"
|
|
35
|
+
load_serialized_repository(zip,
|
|
36
|
+
metadata.serialization_format)
|
|
37
|
+
else
|
|
38
|
+
load_from_express_files(zip)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Load and restore indexes
|
|
42
|
+
load_indexes(zip, repository)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
repository
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
private
|
|
49
|
+
|
|
50
|
+
# Load metadata from package
|
|
51
|
+
# @param zip [Zip::File] ZIP archive
|
|
52
|
+
# @return [Metadata] Package metadata
|
|
53
|
+
def load_metadata(zip)
|
|
54
|
+
entry = zip.find_entry("metadata.yaml")
|
|
55
|
+
raise "Metadata not found in package" unless entry
|
|
56
|
+
|
|
57
|
+
Metadata.from_yaml(entry.get_input_stream.read)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# Load serialized repository from package
|
|
61
|
+
# @param zip [Zip::File] ZIP archive
|
|
62
|
+
# @param format [String] Serialization format
|
|
63
|
+
# @return [Model::Repository] Repository instance
|
|
64
|
+
def load_serialized_repository(zip, format)
|
|
65
|
+
case format
|
|
66
|
+
when "marshal"
|
|
67
|
+
load_marshal_repository(zip)
|
|
68
|
+
when "json"
|
|
69
|
+
load_json_repository(zip)
|
|
70
|
+
when "yaml"
|
|
71
|
+
load_yaml_repository(zip)
|
|
72
|
+
else
|
|
73
|
+
raise "Unknown serialization format: #{format}"
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# Load repository from Marshal format
|
|
78
|
+
# @param zip [Zip::File] ZIP archive
|
|
79
|
+
# @return [Model::Repository] Repository instance
|
|
80
|
+
def load_marshal_repository(zip)
|
|
81
|
+
entry = zip.find_entry("repository.marshal")
|
|
82
|
+
raise "Serialized repository not found" unless entry
|
|
83
|
+
|
|
84
|
+
Marshal.load(entry.get_input_stream.read)
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# Load repository from JSON format
|
|
88
|
+
# @param zip [Zip::File] ZIP archive
|
|
89
|
+
# @return [Model::Repository] Repository instance
|
|
90
|
+
def load_json_repository(zip)
|
|
91
|
+
entry = zip.find_entry("repository.json")
|
|
92
|
+
raise "Serialized repository not found" unless entry
|
|
93
|
+
|
|
94
|
+
Model::Repository.from_json(entry.get_input_stream.read)
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
# Load repository from YAML format
|
|
98
|
+
# @param zip [Zip::File] ZIP archive
|
|
99
|
+
# @return [Model::Repository] Repository instance
|
|
100
|
+
def load_yaml_repository(zip)
|
|
101
|
+
entry = zip.find_entry("repository.yaml")
|
|
102
|
+
raise "Serialized repository not found" unless entry
|
|
103
|
+
|
|
104
|
+
Model::Repository.from_yaml(entry.get_input_stream.read)
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
# Load repository from EXPRESS files
|
|
108
|
+
# @param zip [Zip::File] ZIP archive
|
|
109
|
+
# @return [Model::Repository] Repository instance
|
|
110
|
+
def load_from_express_files(zip)
|
|
111
|
+
repository = Model::Repository.new
|
|
112
|
+
|
|
113
|
+
# Find all EXPRESS files in the package
|
|
114
|
+
express_entries = zip.entries.select do |entry|
|
|
115
|
+
entry.name.start_with?("express_files/") && entry.name.end_with?(".exp")
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
# Parse each EXPRESS file
|
|
119
|
+
express_entries.each do |entry|
|
|
120
|
+
content = entry.get_input_stream.read
|
|
121
|
+
schema = Expressir::Express::Parser.from_exp(content)
|
|
122
|
+
repository.schemas << schema.schemas.first if schema.schemas.any?
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
# Resolve references
|
|
126
|
+
repository.resolve_all_references
|
|
127
|
+
|
|
128
|
+
repository
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
# Load and restore indexes
|
|
132
|
+
# @param zip [Zip::File] ZIP archive
|
|
133
|
+
# @param repository [Model::Repository] Repository instance
|
|
134
|
+
# @return [void]
|
|
135
|
+
def load_indexes(zip, repository)
|
|
136
|
+
# Load entity index
|
|
137
|
+
entity_index_entry = zip.find_entry("entity_index.marshal")
|
|
138
|
+
if entity_index_entry
|
|
139
|
+
repository.instance_variable_set(
|
|
140
|
+
:@entity_index,
|
|
141
|
+
Marshal.load(entity_index_entry.get_input_stream.read),
|
|
142
|
+
)
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
# Load type index
|
|
146
|
+
type_index_entry = zip.find_entry("type_index.marshal")
|
|
147
|
+
if type_index_entry
|
|
148
|
+
repository.instance_variable_set(
|
|
149
|
+
:@type_index,
|
|
150
|
+
Marshal.load(type_index_entry.get_input_stream.read),
|
|
151
|
+
)
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
# Load reference index
|
|
155
|
+
reference_index_entry = zip.find_entry("reference_index.marshal")
|
|
156
|
+
if reference_index_entry
|
|
157
|
+
repository.instance_variable_set(
|
|
158
|
+
:@reference_index,
|
|
159
|
+
Marshal.load(reference_index_entry.get_input_stream.read),
|
|
160
|
+
)
|
|
161
|
+
end
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
end
|
|
@@ -75,6 +75,8 @@ module Expressir
|
|
|
75
75
|
end
|
|
76
76
|
|
|
77
77
|
def path_relative_to_absolute(relative_path)
|
|
78
|
+
return relative_path if relative_path.nil? || relative_path.empty?
|
|
79
|
+
|
|
78
80
|
eval_path = Pathname.new(relative_path)
|
|
79
81
|
return relative_path if eval_path.absolute?
|
|
80
82
|
|
|
@@ -87,12 +89,20 @@ module Expressir
|
|
|
87
89
|
end
|
|
88
90
|
|
|
89
91
|
def path_absolute_to_relative(absolute_path, container_path)
|
|
92
|
+
return absolute_path if absolute_path.nil? || absolute_path.empty?
|
|
93
|
+
|
|
90
94
|
container_path ||= @path
|
|
91
95
|
return absolute_path unless container_path
|
|
96
|
+
return absolute_path if container_path.empty?
|
|
92
97
|
|
|
93
98
|
p = Pathname.new(container_path)
|
|
94
99
|
container = p.directory? ? p.to_s : p.dirname
|
|
95
|
-
|
|
100
|
+
|
|
101
|
+
# Check if absolute_path is actually absolute
|
|
102
|
+
abs_pathname = Pathname.new(absolute_path)
|
|
103
|
+
return absolute_path unless abs_pathname.absolute?
|
|
104
|
+
|
|
105
|
+
abs_pathname.relative_path_from(container).to_s
|
|
96
106
|
end
|
|
97
107
|
|
|
98
108
|
def update_path(new_path)
|
data/lib/expressir/version.rb
CHANGED
data/lib/expressir.rb
CHANGED
|
@@ -59,6 +59,14 @@ module Expressir
|
|
|
59
59
|
autoload :Cache, "expressir/model/cache"
|
|
60
60
|
autoload :Identifier, "expressir/model/identifier"
|
|
61
61
|
autoload :Repository, "expressir/model/repository"
|
|
62
|
+
autoload :RepositoryValidator, "expressir/model/repository_validator"
|
|
63
|
+
autoload :DependencyResolver, "expressir/model/dependency_resolver"
|
|
64
|
+
|
|
65
|
+
module Indexes
|
|
66
|
+
autoload :EntityIndex, "expressir/model/indexes/entity_index"
|
|
67
|
+
autoload :TypeIndex, "expressir/model/indexes/type_index"
|
|
68
|
+
autoload :ReferenceIndex, "expressir/model/indexes/reference_index"
|
|
69
|
+
end
|
|
62
70
|
|
|
63
71
|
module DataTypes
|
|
64
72
|
autoload :Aggregate, "expressir/model/data_types/aggregate"
|
|
@@ -164,6 +172,13 @@ module Expressir
|
|
|
164
172
|
end
|
|
165
173
|
end
|
|
166
174
|
|
|
175
|
+
# Autoload for Package module classes
|
|
176
|
+
module Package
|
|
177
|
+
autoload :Metadata, "expressir/package/metadata"
|
|
178
|
+
autoload :Builder, "expressir/package/builder"
|
|
179
|
+
autoload :Reader, "expressir/package/reader"
|
|
180
|
+
end
|
|
181
|
+
|
|
167
182
|
# Autoload for Commands module classes
|
|
168
183
|
module Commands
|
|
169
184
|
autoload :Base, "expressir/commands/base"
|
|
@@ -180,10 +195,8 @@ module Expressir
|
|
|
180
195
|
# Autoload for Changes module classes
|
|
181
196
|
module Changes
|
|
182
197
|
autoload :SchemaChange, "expressir/changes/schema_change"
|
|
183
|
-
autoload :
|
|
198
|
+
autoload :VersionChange, "expressir/changes/version_change"
|
|
184
199
|
autoload :ItemChange, "expressir/changes/item_change"
|
|
185
200
|
autoload :MappingChange, "expressir/changes/mapping_change"
|
|
186
201
|
end
|
|
187
202
|
end
|
|
188
|
-
|
|
189
|
-
require_relative "expressir/model"
|