stepmod-utils 0.3.23 → 0.3.25
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/test-concept-generation.yml +38 -0
- data/.gitignore +3 -0
- data/.rubocop.yml +3 -0
- data/exe/stepmod-annotate-all +27 -14
- data/exe/stepmod-extract-changes +57 -0
- data/exe/stepmod-extract-concepts +165 -0
- data/lib/stepmod/utils/change.rb +74 -0
- data/lib/stepmod/utils/change_collection.rb +50 -0
- data/lib/stepmod/utils/change_edition.rb +60 -0
- data/lib/stepmod/utils/change_edition_collection.rb +38 -0
- data/lib/stepmod/utils/changes_extractor.rb +194 -0
- data/lib/stepmod/utils/concept.rb +40 -10
- data/lib/stepmod/utils/converters/description.rb +22 -0
- data/lib/stepmod/utils/express_bibdata.rb +111 -0
- data/lib/stepmod/utils/smrl_description_converter.rb +1 -0
- data/lib/stepmod/utils/stepmod_file_annotator.rb +215 -14
- data/lib/stepmod/utils/term.rb +18 -5
- data/lib/stepmod/utils/terms_extractor.rb +253 -292
- data/lib/stepmod/utils/version.rb +1 -1
- data/stepmod-utils.gemspec +2 -1
- metadata +31 -11
- data/exe/stepmod-build-resource-docs-cache +0 -20
- data/exe/stepmod-extract-terms +0 -237
- data/exe/stepmod-find-express-files +0 -24
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 46ea2364546e11b067f0d3d21e78d0a1df701ec5189aeb94d08461d551b22786
|
4
|
+
data.tar.gz: ab5adf48414ca093c86ff2fbe12155ff7eab79102412f1c1f9949ee5e7eac591
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 16eb837cff97033e742a20f2513ca426f69d41bb49cce9956c450f41c90290bd3404083c378a40b0ac6c35a68c974c57db1b11e5919cc6a1d5da9b65845b310b
|
7
|
+
data.tar.gz: c3df83672ebda912b592c487698b61e1e19e91cc31da78959dae7d3f4d3836b6a1940d78e33eec34dca92815fe7385e0289f3170303f989187132e1ef21ebc82
|
@@ -0,0 +1,38 @@
|
|
1
|
+
name: test-concept-generation
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
branches: [ main ]
|
6
|
+
tags: [ v* ]
|
7
|
+
pull_request:
|
8
|
+
|
9
|
+
jobs:
|
10
|
+
generate_yaml_concepts:
|
11
|
+
runs-on: ubuntu-latest
|
12
|
+
steps:
|
13
|
+
- name: Checkout
|
14
|
+
uses: actions/checkout@v3
|
15
|
+
|
16
|
+
- name: Setup Ruby
|
17
|
+
uses: ruby/setup-ruby@v1
|
18
|
+
with:
|
19
|
+
ruby-version: '3.1'
|
20
|
+
bundler-cache: true
|
21
|
+
|
22
|
+
- name: Check out iso-10303-stepmod-wg12 repo
|
23
|
+
uses: actions/checkout@v3
|
24
|
+
with:
|
25
|
+
repository: metanorma/iso-10303-stepmod-wg12
|
26
|
+
token: ${{ secrets.METANORMA_CI_PAT_TOKEN }}
|
27
|
+
path: iso-10303-stepmod-wg12
|
28
|
+
|
29
|
+
- name: Generate Annotated EXPRESS files
|
30
|
+
run: bundle exec stepmod-annotate-all ./iso-10303-stepmod-wg12
|
31
|
+
|
32
|
+
- name: Generate Concept YAML files
|
33
|
+
working-directory: iso-10303-stepmod-wg12
|
34
|
+
run: |
|
35
|
+
bundle exec stepmod-extract-concepts \
|
36
|
+
-p ./data \
|
37
|
+
-i ./repository_index.xml \
|
38
|
+
-o ./output-yaml
|
data/.gitignore
CHANGED
data/.rubocop.yml
CHANGED
data/exe/stepmod-annotate-all
CHANGED
@@ -5,14 +5,28 @@ require "stepmod/utils/stepmod_file_annotator"
|
|
5
5
|
|
6
6
|
stepmod_dir = ARGV.first || Dir.pwd
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
files
|
15
|
-
|
8
|
+
def all_express_files(stepmod_dir)
|
9
|
+
index_file = File.read(File.join(stepmod_dir, "repository_index.xml"))
|
10
|
+
index = Nokogiri::XML(index_file).root
|
11
|
+
|
12
|
+
files = []
|
13
|
+
index.xpath("modules/module").each do |item|
|
14
|
+
files << "#{stepmod_dir}/data/modules/#{item['name']}/arm.exp"
|
15
|
+
files << "#{stepmod_dir}/data/modules/#{item['name']}/mim.exp"
|
16
|
+
end
|
17
|
+
|
18
|
+
index.xpath("resources/resource").each do |item|
|
19
|
+
files << "#{stepmod_dir}/data/resources/#{item['name']}/#{item['name']}.exp"
|
20
|
+
end
|
21
|
+
|
22
|
+
index.xpath("business_object_models/business_object_model").each do |item|
|
23
|
+
files << "#{stepmod_dir}/data/business_object_models/#{item['name']}/bom.exp"
|
24
|
+
files << "#{stepmod_dir}/data/business_object_models/#{item['name']}/DomainModel.exp"
|
25
|
+
end
|
26
|
+
|
27
|
+
files.filter { |file| File.exist?(file) }
|
28
|
+
end
|
29
|
+
|
16
30
|
MAX_THREADS = 1 #[2, Concurrent.processor_count].max * 2
|
17
31
|
MAX_QUEUE_SIZE = MAX_THREADS * 4
|
18
32
|
# https://github.com/ruby-concurrency/concurrent-ruby/blob/master/docs-source/thread_pools.md
|
@@ -22,14 +36,16 @@ pool = Concurrent::ThreadPoolExecutor.new(
|
|
22
36
|
max_queue: MAX_QUEUE_SIZE,
|
23
37
|
fallback_policy: :caller_runs,
|
24
38
|
)
|
39
|
+
|
40
|
+
files = all_express_files(stepmod_dir)
|
41
|
+
|
25
42
|
files.each_slice(MAX_QUEUE_SIZE) do |batch|
|
26
43
|
puts("Queueing next batch")
|
27
44
|
batch.each do |file|
|
28
45
|
pool.post do
|
29
|
-
puts
|
46
|
+
puts "#{Thread.current.object_id}: Queued processing #{file}"
|
30
47
|
annotated = Stepmod::Utils::StepmodFileAnnotator.new(
|
31
48
|
express_file: file,
|
32
|
-
resource_docs_cache_file: resource_docs_cache_file,
|
33
49
|
stepmod_dir: stepmod_dir
|
34
50
|
).call
|
35
51
|
|
@@ -40,11 +56,8 @@ files.each_slice(MAX_QUEUE_SIZE) do |batch|
|
|
40
56
|
file.puts(annotated)
|
41
57
|
end
|
42
58
|
|
43
|
-
puts
|
59
|
+
puts "#{Thread.current.object_id}: Done processing #{File.basename(file)} => #{annotated_file_path}."
|
44
60
|
end
|
45
61
|
end
|
46
62
|
pool.shutdown
|
47
63
|
end
|
48
|
-
|
49
|
-
# cleanup
|
50
|
-
`rm "#{resource_docs_cache_file}"`
|
@@ -0,0 +1,57 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# resolve bin path, ignoring symlinks
|
4
|
+
require "pathname"
|
5
|
+
bin_file = Pathname.new(__FILE__).realpath
|
6
|
+
|
7
|
+
# add self to libpath
|
8
|
+
$:.unshift File.expand_path("../../lib", bin_file)
|
9
|
+
|
10
|
+
# Fixes https://github.com/rubygems/rubygems/issues/1420
|
11
|
+
require "rubygems/specification"
|
12
|
+
|
13
|
+
module Gem
|
14
|
+
class Specification
|
15
|
+
def this; self; end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
require "bundler/setup"
|
20
|
+
require "stepmod/utils/changes_extractor"
|
21
|
+
require "optparse"
|
22
|
+
|
23
|
+
def log(message)
|
24
|
+
puts "[stepmod-utils] #{message}"
|
25
|
+
end
|
26
|
+
|
27
|
+
options = {}
|
28
|
+
OptionParser.new do |opts|
|
29
|
+
opts.banner = "Usage: #{$0} [options]"
|
30
|
+
|
31
|
+
opts.on(
|
32
|
+
"-p",
|
33
|
+
"--path STEPMOD_DATA_PATH",
|
34
|
+
String,
|
35
|
+
"Path to STEPmod data directory",
|
36
|
+
) do |path|
|
37
|
+
options[:stepmod_dir] = path
|
38
|
+
end
|
39
|
+
|
40
|
+
opts.on_tail("-h", "--help", "Show this message") do
|
41
|
+
puts opts
|
42
|
+
exit
|
43
|
+
end
|
44
|
+
end.parse!
|
45
|
+
|
46
|
+
stepmod_dir = options[:stepmod_dir]
|
47
|
+
if stepmod_dir.nil?
|
48
|
+
raise StandardError.new("STEPmod data path not set, set with the `-p` option")
|
49
|
+
else
|
50
|
+
log "STEPmod data path: `#{stepmod_dir}`"
|
51
|
+
end
|
52
|
+
|
53
|
+
changes = Stepmod::Utils::ChangesExtractor.call(
|
54
|
+
stepmod_dir: Pathname.new(stepmod_dir).realpath,
|
55
|
+
)
|
56
|
+
|
57
|
+
changes.save_to_files
|
@@ -0,0 +1,165 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: UTF-8
|
3
|
+
|
4
|
+
require "fileutils"
|
5
|
+
# resolve bin path, ignoring symlinks
|
6
|
+
require "pathname"
|
7
|
+
bin_file = Pathname.new(__FILE__).realpath
|
8
|
+
|
9
|
+
# add self to libpath
|
10
|
+
$:.unshift File.expand_path("../../lib", bin_file)
|
11
|
+
|
12
|
+
# Fixes https://github.com/rubygems/rubygems/issues/1420
|
13
|
+
require "rubygems/specification"
|
14
|
+
|
15
|
+
module Gem
|
16
|
+
class Specification
|
17
|
+
def this; self; end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
require "bundler/setup"
|
22
|
+
require_relative "../lib/stepmod/utils/terms_extractor"
|
23
|
+
require "optparse"
|
24
|
+
|
25
|
+
def log(message)
|
26
|
+
puts "[stepmod-utils] #{message}"
|
27
|
+
end
|
28
|
+
|
29
|
+
options = {}
|
30
|
+
OptionParser.new do |opts|
|
31
|
+
opts.banner = "Usage: #{$0} [options]"
|
32
|
+
|
33
|
+
opts.on(
|
34
|
+
"-p",
|
35
|
+
"--path STEPMOD_DATA_PATH",
|
36
|
+
String,
|
37
|
+
"Path to STEPmod data directory",
|
38
|
+
) do |path|
|
39
|
+
options[:stepmod_dir] = path
|
40
|
+
end
|
41
|
+
|
42
|
+
opts.on(
|
43
|
+
"-i",
|
44
|
+
"--index INDEX_PATH",
|
45
|
+
String,
|
46
|
+
"Path to repository_index.xml",
|
47
|
+
) do |path|
|
48
|
+
unless path.nil?
|
49
|
+
options[:index_path] = Pathname.new(path).to_s
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
opts.on(
|
54
|
+
"-o",
|
55
|
+
"--output INDEX_PATH",
|
56
|
+
String,
|
57
|
+
"Path to output directory",
|
58
|
+
) do |path|
|
59
|
+
unless path.nil?
|
60
|
+
options[:output_dir] = Pathname.new(path).to_s
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
opts.on_tail("-h", "--help", "Show this message") do
|
65
|
+
puts opts
|
66
|
+
exit
|
67
|
+
end
|
68
|
+
end.parse!
|
69
|
+
|
70
|
+
stepmod_dir = options[:stepmod_dir]
|
71
|
+
if stepmod_dir.nil?
|
72
|
+
raise StandardError.new(
|
73
|
+
"STEPmod data path not set, set with the `-p` option.",
|
74
|
+
)
|
75
|
+
else
|
76
|
+
log "STEPmod data path: `#{stepmod_dir}`"
|
77
|
+
end
|
78
|
+
|
79
|
+
default_index_path = File.join(stepmod_dir, "repository_index.xml")
|
80
|
+
index_path = options[:index_path] || default_index_path
|
81
|
+
if File.exist?(index_path)
|
82
|
+
log "Repository index path: `#{index_path}`"
|
83
|
+
else
|
84
|
+
raise StandardError.new(
|
85
|
+
"Index file not present at #{index_path}, set with the `-i` option.",
|
86
|
+
)
|
87
|
+
end
|
88
|
+
|
89
|
+
default_output_dir = File.join(stepmod_dir, "output_yaml")
|
90
|
+
output_dir = options[:output_dir] || default_output_dir
|
91
|
+
unless File.directory?(output_dir)
|
92
|
+
FileUtils.mkdir_p(output_dir)
|
93
|
+
end
|
94
|
+
log "Output directory path: `#{output_dir}`"
|
95
|
+
|
96
|
+
_general_concepts,
|
97
|
+
resource_concepts,
|
98
|
+
_parsed_bibliography,
|
99
|
+
_part_concepts,
|
100
|
+
part_resources,
|
101
|
+
part_modules = Stepmod::Utils::TermsExtractor.call(stepmod_dir, index_path)
|
102
|
+
|
103
|
+
def part_to_title(bibdata)
|
104
|
+
{
|
105
|
+
41 => "Fundamentals of product description and support",
|
106
|
+
42 => "Geometric and topological representation",
|
107
|
+
43 => "Foundation representation",
|
108
|
+
44 => "Product structure, concept and configuration",
|
109
|
+
45 => "Material and other engineering properties",
|
110
|
+
46 => "Visual presentation",
|
111
|
+
47 => "Shape tolerance",
|
112
|
+
51 => "Mathematical representation",
|
113
|
+
}[bibdata.part.to_i] || bibdata.title_en
|
114
|
+
end
|
115
|
+
|
116
|
+
# rubocop:disable Layout/LineLength
|
117
|
+
IMAGE_REPLACEMENTS = {
|
118
|
+
"image::eq01.gif[]" => "stem:[H(A,B) = max {h(A, B), h(B,A)}]",
|
119
|
+
"image::eq02.gif[]" => "stem:[max_{a in A} { min_{b in B} d(a,b) }]",
|
120
|
+
"image::vector_z_c.gif[]" => "stem:[bar z_{c}]",
|
121
|
+
"image::one_direction_repeat_factor_expression.gif[]" => "stem:[I + k cdot R; k = -1, 1]",
|
122
|
+
"image::two_direction_repeat_factor_expression.gif[]" => "stem:[I + k_1 cdot R_1 + k_2 cdot R_2; k_1, k_2 = -1, 0, 1, k^2_1 + k^2_2 != 0]",
|
123
|
+
}.freeze
|
124
|
+
|
125
|
+
TEXT_REPLACEMENTS = {
|
126
|
+
' (see <module_ref linkend="ply_orientation_specification:4_entities:figure:f2"> Figure 2</module_ref>)' => "",
|
127
|
+
' (see <module_ref linkend="ply_orientation_specification:4_entities:figure:f3"> Figure 3</module_ref>)' => "",
|
128
|
+
}.freeze
|
129
|
+
# rubocop:enable Layout/LineLength
|
130
|
+
|
131
|
+
def replace_content(content)
|
132
|
+
IMAGE_REPLACEMENTS.each_pair do |k, v|
|
133
|
+
content.gsub!(k, v)
|
134
|
+
end
|
135
|
+
TEXT_REPLACEMENTS.each_pair do |k, v|
|
136
|
+
content.gsub!(k, v)
|
137
|
+
end
|
138
|
+
|
139
|
+
content
|
140
|
+
end
|
141
|
+
|
142
|
+
part_resources.each do |(_bibdata, current_part_resources)|
|
143
|
+
current_part_resources.save_to_files(output_dir)
|
144
|
+
end
|
145
|
+
log "INFO: part_resources written to yaml files"
|
146
|
+
|
147
|
+
part_modules.sort_by do |(bibdata, _part_modules_arm, _part_modules_mim)|
|
148
|
+
bibdata.part.to_i
|
149
|
+
end.each do |(_bibdata, part_modules_arm, part_modules_mim)|
|
150
|
+
unless part_modules_arm.empty?
|
151
|
+
part_modules_arm.values.map do |managed_concept|
|
152
|
+
managed_concept.save_to_files(output_dir)
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
unless part_modules_mim.empty?
|
157
|
+
part_modules_mim.values.map do |managed_concept|
|
158
|
+
managed_concept.save_to_files(output_dir)
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
162
|
+
log "INFO: part_modules written to yaml files"
|
163
|
+
|
164
|
+
resource_concepts.save_to_files(output_dir)
|
165
|
+
log "INFO: resource_concepts written to yaml files"
|
@@ -0,0 +1,74 @@
|
|
1
|
+
require "psych"
|
2
|
+
require "stepmod/utils/change_edition"
|
3
|
+
require "stepmod/utils/change_edition_collection"
|
4
|
+
|
5
|
+
module Stepmod
|
6
|
+
module Utils
|
7
|
+
class Change
|
8
|
+
attr_accessor :schema_name
|
9
|
+
attr_reader :change_editions
|
10
|
+
|
11
|
+
MODULE_TYPES = {
|
12
|
+
arm: "arm",
|
13
|
+
mim: "mim",
|
14
|
+
arm_longform: "arm_lf",
|
15
|
+
mim_longform: "mim_lf",
|
16
|
+
}.freeze
|
17
|
+
|
18
|
+
def initialize(stepmod_dir:, schema_name:, type:)
|
19
|
+
@stepmod_dir = stepmod_dir
|
20
|
+
@change_editions = Stepmod::Utils::ChangeEditionCollection.new
|
21
|
+
@schema_name = schema_name
|
22
|
+
@type = type
|
23
|
+
end
|
24
|
+
|
25
|
+
def resource?
|
26
|
+
!module?
|
27
|
+
end
|
28
|
+
|
29
|
+
def module?
|
30
|
+
MODULE_TYPES.key?(@type.to_sym) || MODULE_TYPES.value?(@type.to_s)
|
31
|
+
end
|
32
|
+
|
33
|
+
def add_change_edition(change_edition)
|
34
|
+
@change_editions[change_edition[:version]] = change_edition
|
35
|
+
end
|
36
|
+
|
37
|
+
def fetch_change_edition(version)
|
38
|
+
@change_editions[version]
|
39
|
+
end
|
40
|
+
alias_method :[], :fetch_change_edition
|
41
|
+
|
42
|
+
def save_to_file
|
43
|
+
File.write(filepath(@type), Psych.dump(to_h))
|
44
|
+
end
|
45
|
+
|
46
|
+
def to_h
|
47
|
+
{
|
48
|
+
"schema" => schema_name,
|
49
|
+
"change_edition" => change_editions.to_h,
|
50
|
+
}
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
def filepath(type)
|
56
|
+
File.join(
|
57
|
+
@stepmod_dir,
|
58
|
+
"data",
|
59
|
+
base_folder,
|
60
|
+
schema_name,
|
61
|
+
"#{MODULE_TYPES[type.to_sym] || schema_name}.changes.yaml",
|
62
|
+
)
|
63
|
+
end
|
64
|
+
|
65
|
+
def base_folder
|
66
|
+
if resource?
|
67
|
+
"resources"
|
68
|
+
else
|
69
|
+
"modules"
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require "stepmod/utils/change"
|
2
|
+
|
3
|
+
module Stepmod
|
4
|
+
module Utils
|
5
|
+
class ChangeCollection
|
6
|
+
def initialize(stepmod_dir:)
|
7
|
+
@stepmod_dir = stepmod_dir
|
8
|
+
@changes = {}
|
9
|
+
end
|
10
|
+
|
11
|
+
def fetch_or_initialize(change, type)
|
12
|
+
schema = schema_name(change)
|
13
|
+
|
14
|
+
@changes[schema_identifier(schema, type)] ||= Change.new(
|
15
|
+
type: type,
|
16
|
+
stepmod_dir: @stepmod_dir,
|
17
|
+
schema_name: schema,
|
18
|
+
)
|
19
|
+
end
|
20
|
+
|
21
|
+
def fetch(change, type)
|
22
|
+
schema = schema_name(change)
|
23
|
+
@changes[schema_identifier(schema, type)]
|
24
|
+
end
|
25
|
+
|
26
|
+
def save_to_files
|
27
|
+
@changes.values.each(&:save_to_file)
|
28
|
+
end
|
29
|
+
|
30
|
+
def count
|
31
|
+
@changes.keys.count
|
32
|
+
end
|
33
|
+
alias_method :size, :count
|
34
|
+
|
35
|
+
def each(&block)
|
36
|
+
@changes.values.each(&block)
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def schema_name(change)
|
42
|
+
change.is_a?(Stepmod::Utils::Change) ? change.schema_name : change
|
43
|
+
end
|
44
|
+
|
45
|
+
def schema_identifier(schema_name, type)
|
46
|
+
"#{schema_name}_#{type}"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
module Stepmod
|
2
|
+
module Utils
|
3
|
+
class ChangeEdition
|
4
|
+
attr_accessor :version, :description
|
5
|
+
attr_reader :additions, :modifications, :deletions, :mapping
|
6
|
+
|
7
|
+
def initialize(options)
|
8
|
+
@version = options[:version]
|
9
|
+
@description = options[:description]
|
10
|
+
self.additions = options[:additions] || []
|
11
|
+
self.modifications = options[:modifications] || []
|
12
|
+
self.deletions = options[:deletions] || []
|
13
|
+
self.mapping = options[:mapping] || []
|
14
|
+
end
|
15
|
+
|
16
|
+
def additions=(additions)
|
17
|
+
validate_type("additions", additions, Array)
|
18
|
+
|
19
|
+
@additions = additions
|
20
|
+
end
|
21
|
+
|
22
|
+
def modifications=(modifications)
|
23
|
+
validate_type("modifications", modifications, Array)
|
24
|
+
|
25
|
+
@modifications = modifications
|
26
|
+
end
|
27
|
+
|
28
|
+
def deletions=(deletions)
|
29
|
+
validate_type("deletions", deletions, Array)
|
30
|
+
|
31
|
+
@deletions = deletions
|
32
|
+
end
|
33
|
+
|
34
|
+
def mapping=(mapping)
|
35
|
+
validate_type("mapping", mapping, Array)
|
36
|
+
|
37
|
+
@mapping = mapping
|
38
|
+
end
|
39
|
+
|
40
|
+
def to_h
|
41
|
+
{
|
42
|
+
"version" => version,
|
43
|
+
"description" => description,
|
44
|
+
"additions" => additions,
|
45
|
+
"modifications" => modifications,
|
46
|
+
"deletions" => deletions,
|
47
|
+
"mapping" => mapping,
|
48
|
+
}.reject { |_k, v| v.nil? || v.empty? }
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
def validate_type(column, value, type)
|
54
|
+
error = "#{column} must be of type ::#{type}, Got ::#{value.class}"
|
55
|
+
|
56
|
+
raise error unless value.is_a?(type)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require "stepmod/utils/change_edition"
|
2
|
+
|
3
|
+
module Stepmod
|
4
|
+
module Utils
|
5
|
+
class ChangeEditionCollection
|
6
|
+
def initialize
|
7
|
+
@collection = {}
|
8
|
+
end
|
9
|
+
|
10
|
+
def fetch_or_initialize(version)
|
11
|
+
@collection[version] ||=
|
12
|
+
Stepmod::Utils::ChangeEdition.new(version: version)
|
13
|
+
end
|
14
|
+
|
15
|
+
def to_h
|
16
|
+
@collection.values.map(&:to_h)
|
17
|
+
end
|
18
|
+
|
19
|
+
def []=(version, change_edition)
|
20
|
+
klass = Stepmod::Utils::ChangeEdition
|
21
|
+
@collection[version] = if change_edition.is_a?(klass)
|
22
|
+
change_edition
|
23
|
+
else
|
24
|
+
klass.new(change_edition)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def [](version)
|
29
|
+
@collection[version]
|
30
|
+
end
|
31
|
+
|
32
|
+
def count
|
33
|
+
@collection.values.count
|
34
|
+
end
|
35
|
+
alias_method :size, :count
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|