stepmod-utils 0.3.24 → 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 92d04b3c30620d813fbff40cfa84ed809f0129440dd1f6be45c4206aaa44a12e
4
- data.tar.gz: 54289d1067ccba3a61cd0ca07bd5455081efe70aae946811cf8028f6e77afb9a
3
+ metadata.gz: 46ea2364546e11b067f0d3d21e78d0a1df701ec5189aeb94d08461d551b22786
4
+ data.tar.gz: ab5adf48414ca093c86ff2fbe12155ff7eab79102412f1c1f9949ee5e7eac591
5
5
  SHA512:
6
- metadata.gz: e83145314175c1797f8de0fe08bdbf3ba95e06346b49f80beb3cdadb31d1b2423cb60230d869b91850de3685b0fb6c805a2b4ddebbfd72ff2b55ffde234f4d9f
7
- data.tar.gz: 309a341bead6e54225f14101c3bea989f2f7873409c4d8e1fedbc6e8b2144d3e21ed2034c5ebcfd76279d73234a84e8d0d67c86fb77e1e1b715f6f1ba2ad661b
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
@@ -9,4 +9,7 @@
9
9
 
10
10
  # rspec failure tracking
11
11
  .rspec_status
12
+ .rubocop*
12
13
  Gemfile.lock
14
+
15
+ .rubocop-https*
@@ -5,14 +5,28 @@ require "stepmod/utils/stepmod_file_annotator"
5
5
 
6
6
  stepmod_dir = ARGV.first || Dir.pwd
7
7
 
8
- # build resource_docs cache
9
- resource_docs_cache_file = `mktemp`
10
- `"#{File.join(__dir__,
11
- "stepmod-build-resource-docs-cache")}" "#{stepmod_dir}" > "#{resource_docs_cache_file}"`
12
-
13
- # annotate each file
14
- files = `"#{File.join(__dir__,
15
- "stepmod-find-express-files")}" "#{stepmod_dir}"`.strip.split("\n")
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("#{Thread.current.object_id}: Queued processing #{file}")
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("#{Thread.current.object_id}: Done processing #{File.basename(file)} => #{annotated_file_path}.")
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
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
  # encoding: UTF-8
3
3
 
4
- require "pry"
4
+ require "fileutils"
5
5
  # resolve bin path, ignoring symlinks
6
6
  require "pathname"
7
7
  bin_file = Pathname.new(__FILE__).realpath
@@ -50,6 +50,17 @@ OptionParser.new do |opts|
50
50
  end
51
51
  end
52
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
+
53
64
  opts.on_tail("-h", "--help", "Show this message") do
54
65
  puts opts
55
66
  exit
@@ -67,7 +78,7 @@ end
67
78
 
68
79
  default_index_path = File.join(stepmod_dir, "repository_index.xml")
69
80
  index_path = options[:index_path] || default_index_path
70
- if File.exists?(index_path)
81
+ if File.exist?(index_path)
71
82
  log "Repository index path: `#{index_path}`"
72
83
  else
73
84
  raise StandardError.new(
@@ -75,6 +86,13 @@ else
75
86
  )
76
87
  end
77
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
+
78
96
  _general_concepts,
79
97
  resource_concepts,
80
98
  _parsed_bibliography,
@@ -122,28 +140,26 @@ def replace_content(content)
122
140
  end
123
141
 
124
142
  part_resources.each do |(_bibdata, current_part_resources)|
125
- current_part_resources.save_to_files("./")
143
+ current_part_resources.save_to_files(output_dir)
126
144
  end
127
145
  log "INFO: part_resources written to yaml files"
128
146
 
129
-
130
- log "INFO: written summary file to: 04x-stepmod-entities-resources.adoc"
131
147
  part_modules.sort_by do |(bibdata, _part_modules_arm, _part_modules_mim)|
132
148
  bibdata.part.to_i
133
149
  end.each do |(_bibdata, part_modules_arm, part_modules_mim)|
134
150
  unless part_modules_arm.empty?
135
151
  part_modules_arm.values.map do |managed_concept|
136
- managed_concept.save_to_files("./")
152
+ managed_concept.save_to_files(output_dir)
137
153
  end
138
154
  end
139
155
 
140
156
  unless part_modules_mim.empty?
141
157
  part_modules_mim.values.map do |managed_concept|
142
- managed_concept.save_to_files("./")
158
+ managed_concept.save_to_files(output_dir)
143
159
  end
144
160
  end
145
161
  end
146
162
  log "INFO: part_modules written to yaml files"
147
163
 
148
- resource_concepts.save_to_files("./")
164
+ resource_concepts.save_to_files(output_dir)
149
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
@@ -0,0 +1,194 @@
1
+ require "nokogiri"
2
+ require "stepmod/utils/change_collection"
3
+ require "stepmod/utils/smrl_description_converter"
4
+
5
+ module Stepmod
6
+ module Utils
7
+ class ChangesExtractor
8
+ MODULE_TYPES = %w[arm mim arm_longform mim_longform].freeze
9
+
10
+ attr_accessor :stepmod_dir
11
+
12
+ def self.call(stepmod_dir:, stdout: $stdout)
13
+ new(stepmod_dir: stepmod_dir, stdout: stdout).call
14
+ end
15
+
16
+ def initialize(stepmod_dir:, stdout: $stdout)
17
+ @stdout = stdout
18
+ @stepmod_dir = stepmod_dir
19
+ @collection = Stepmod::Utils::ChangeCollection.new(
20
+ stepmod_dir: stepmod_dir,
21
+ )
22
+ end
23
+
24
+ def call
25
+ all_resource_changes_files.each do |resource_change_file|
26
+ xml_changes = Nokogiri::XML(File.read(resource_change_file)).root
27
+ add_resource_changes_to_collection(xml_changes, @collection)
28
+ end
29
+
30
+ all_modules_changes_files.each do |module_change_file|
31
+ xml_changes = Nokogiri::XML(File.read(module_change_file)).root
32
+ schema_name = Pathname.new(module_change_file).parent.basename.to_s
33
+ add_module_changes_to_collection(xml_changes, @collection, schema_name)
34
+ end
35
+
36
+ @collection
37
+ end
38
+
39
+ private
40
+
41
+ # rubocop:disable Metrics/MethodLength
42
+ def add_resource_changes_to_collection(xml_data, collection)
43
+ xml_data.xpath("//changes").each do |changes_node|
44
+ changes_node.xpath("change_edition").each do |change_edition_node|
45
+ options = {
46
+ version: change_edition_node.attr("version"),
47
+ description: Stepmod::Utils::SmrlDescriptionConverter.convert(
48
+ change_edition_node.at("description"),
49
+ ),
50
+ }
51
+
52
+ add_resource_changes(
53
+ collection,
54
+ change_edition_node,
55
+ options,
56
+ )
57
+ end
58
+ end
59
+ end
60
+
61
+ def add_module_changes_to_collection(xml_data, collection, schema_name)
62
+ xml_data.xpath("//changes").each do |changes_node|
63
+ changes_node.xpath("change").each do |change_node|
64
+ options = {
65
+ schema_name: schema_name,
66
+ version: change_node.attr("version"),
67
+ description: converted_description(change_node.at("description")),
68
+ }
69
+
70
+ MODULE_TYPES.each do |type|
71
+ add_module_changes(
72
+ collection,
73
+ change_node,
74
+ options,
75
+ type,
76
+ )
77
+ end
78
+ end
79
+ end
80
+ end
81
+
82
+ def add_resource_changes(collection, change_node, options)
83
+ change_node.xpath("schema.changes").each do |changes|
84
+ schema_name = correct_schema_name(changes.attr("schema_name"))
85
+ change = collection.fetch_or_initialize(schema_name, "schema")
86
+
87
+ change_edition = extract_change_edition(changes, options)
88
+ change.add_change_edition(change_edition)
89
+ end
90
+ end
91
+
92
+ def add_module_changes(collection, change_node, options, type)
93
+ options[:type] = type
94
+ # assuming there will only be one change related to a type in the
95
+ # same version.
96
+ changes = change_node.xpath("#{type}.changes").first
97
+ schema_name = options[:schema_name]
98
+ change = collection.fetch_or_initialize(schema_name, type)
99
+
100
+ change_edition = extract_change_edition(changes, options)
101
+ change.add_change_edition(change_edition)
102
+
103
+ if type == "arm"
104
+ add_mapping_changes(collection, change_node, options)
105
+ end
106
+ end
107
+
108
+ def add_mapping_changes(collection, change_node, options)
109
+ change_edition = collection
110
+ .fetch_or_initialize(options[:schema_name], "arm")
111
+ .change_editions
112
+ .fetch_or_initialize(options[:version])
113
+
114
+ change_edition.mapping = extract_mapping_changes(change_node)
115
+ end
116
+
117
+ def extract_mapping_changes(change_node)
118
+ mappings = []
119
+
120
+ change_node.xpath("mapping.changes").each do |changes|
121
+ changes.xpath("mapping.change").each do |change|
122
+ mappings << { "change" => change.text }
123
+ end
124
+
125
+ changes.xpath("description").each do |change|
126
+ mappings << { "description" => change.text }
127
+ end
128
+ end
129
+
130
+ mappings
131
+ end
132
+
133
+ def extract_change_edition(schema_changes, options)
134
+ type = options[:type] || "schema"
135
+ addition_nodes = schema_changes&.xpath("#{type}.additions") || []
136
+ modification_nodes = schema_changes&.xpath("#{type}.modifications") || []
137
+ deletion_nodes = schema_changes&.xpath("#{type}.deletions") || []
138
+
139
+ {
140
+ version: options[:version],
141
+ description: options[:description],
142
+ additions: extract_modified_objects(addition_nodes),
143
+ modifications: extract_modified_objects(modification_nodes),
144
+ deletions: extract_modified_objects(deletion_nodes),
145
+ }
146
+ end
147
+ # rubocop:enable Metrics/MethodLength
148
+
149
+ def extract_modified_objects(nodes)
150
+ nodes.map do |node|
151
+ node.xpath("modified.object").map do |object|
152
+ {
153
+ type: object.attr("type"),
154
+ name: object.attr("name"),
155
+ description: converted_description(object.at("description")),
156
+ interfaced_items: object.attr("interfaced.items"),
157
+ }.compact
158
+ end
159
+ end.flatten
160
+ end
161
+
162
+ def converted_description(description)
163
+ return if description.to_s.empty?
164
+
165
+ Stepmod::Utils::SmrlDescriptionConverter.convert(description)
166
+ end
167
+
168
+ def all_resource_changes_files
169
+ Dir.glob(
170
+ File.join(stepmod_dir, "data", "resource_docs", "*", "resource.xml"),
171
+ )
172
+ end
173
+
174
+ def all_modules_changes_files
175
+ Dir.glob(
176
+ File.join(stepmod_dir, "data", "modules", "*", "module.xml"),
177
+ )
178
+ end
179
+
180
+ # rubocop:disable Layout/LineLength
181
+ def correct_schema_name(schema_name)
182
+ schema_name_corrector = {
183
+ "material_property_definition" => "material_property_definition_schema",
184
+ "qualified_measure" => "qualified_measure_schema",
185
+ "material_property_representation" => "material_property_representation_schema",
186
+ "annotated_3d_model_data_quality_criteria" => "annotated_3d_model_data_quality_criteria_schema",
187
+ }
188
+
189
+ schema_name_corrector[schema_name] || schema_name
190
+ end
191
+ # rubocop:enable Layout/LineLength
192
+ end
193
+ end
194
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Stepmod
4
+ module Utils
5
+ module Converters
6
+ class Description < ReverseAdoc::Converters::Base
7
+ def convert(node, state = {})
8
+ treat_children(node, state)
9
+ end
10
+
11
+ private
12
+
13
+ def treat_children(node, state)
14
+ res = node.children.map { |child| treat(child, state) }
15
+ res.map(&:strip).reject(&:empty?).join("\n\n")
16
+ end
17
+ end
18
+
19
+ ReverseAdoc::Converters.register :description, Description.new
20
+ end
21
+ end
22
+ end
@@ -6,6 +6,7 @@ require "stepmod/utils/converters/blockquote"
6
6
  require "stepmod/utils/converters/br"
7
7
  require "stepmod/utils/converters/bypass"
8
8
  require "stepmod/utils/converters/code"
9
+ require "stepmod/utils/converters/description"
9
10
  require "stepmod/utils/converters/drop"
10
11
  require "stepmod/utils/converters/em_express_description"
11
12
  require "stepmod/utils/converters/example"
@@ -12,13 +12,13 @@ require "pubid-iso"
12
12
  module Stepmod
13
13
  module Utils
14
14
  class StepmodFileAnnotator
15
- attr_reader :express_file, :resource_docs_cache_file, :stepmod_dir
15
+ attr_reader :express_file, :resource_docs_cache, :stepmod_dir
16
16
 
17
17
  # @param express_file [String] path to the exp file needed to annotate
18
- # @param resource_docs_cache_file [String] output of ./stepmod-build-resource-docs-cache
19
- def initialize(express_file:, resource_docs_cache_file:, stepmod_dir: nil)
18
+ # @param resource_docs_cache [String] output of ./stepmod-build-resource-docs-cache
19
+ def initialize(express_file:, stepmod_dir: nil)
20
20
  @express_file = express_file
21
- @resource_docs_cache_file = resource_docs_cache_file
21
+ @resource_docs_cache = resource_docs_schemas(stepmod_dir)
22
22
  @stepmod_dir = stepmod_dir || Dir.pwd
23
23
  @added_bibdata = {}
24
24
 
@@ -28,6 +28,23 @@ module Stepmod
28
28
  .id
29
29
  end
30
30
 
31
+ def resource_docs_schemas(stepmod_dir)
32
+ filepath = File.join(stepmod_dir, "data/resource_docs/*/resource.xml")
33
+
34
+ schemas = {}
35
+ Dir.glob(filepath).each do |resource_docs_file|
36
+ match = resource_docs_file.match("data/resource_docs/([^/]+)/resource.xml")
37
+ resource_docs_dir = match.captures[0]
38
+
39
+ resource_docs = Nokogiri::XML(File.read(resource_docs_file)).root
40
+ resource_docs.xpath("schema").each do |schema|
41
+ schemas[schema["name"]] = resource_docs_dir
42
+ end
43
+ end
44
+
45
+ schemas
46
+ end
47
+
31
48
  def call
32
49
  match = File.basename(express_file).match('^(arm|mim|bom)\.exp$')
33
50
  descriptions_base = match ? "#{match.captures[0]}_descriptions.xml" : "descriptions.xml"
@@ -39,7 +56,7 @@ module Stepmod
39
56
  converted_description = ""
40
57
  base_linked = ""
41
58
 
42
- if File.exists?(descriptions_file)
59
+ if File.exist?(descriptions_file)
43
60
  descriptions = Nokogiri::XML(File.read(descriptions_file)).root
44
61
  added_resource_descriptions = {}
45
62
 
@@ -81,7 +98,7 @@ module Stepmod
81
98
  resource_docs_file_path(stepmod_dir, bib_file_name)
82
99
  end
83
100
 
84
- output_express << if bib_file && File.exists?(bib_file)
101
+ output_express << if bib_file && File.exist?(bib_file)
85
102
  prepend_bibdata(
86
103
  converted_description || "",
87
104
  # bib_file will not be present for resouces
@@ -107,10 +124,6 @@ module Stepmod
107
124
  file_content.gsub("(*)", "(`*`)")
108
125
  end
109
126
 
110
- def resource_docs_cache
111
- @resource_docs_cache ||= JSON.parse(File.read(resource_docs_cache_file))
112
- end
113
-
114
127
  def convert_from_description_text(descriptions_file, description)
115
128
  Dir.chdir(File.dirname(descriptions_file)) do
116
129
  wrapper = "<ext_descriptions>#{description}</ext_descriptions>"
@@ -16,6 +16,7 @@ module Stepmod
16
16
  # TODO: we may want a command line option to override this in the future
17
17
  ACCEPTED_STAGES = %w(IS DIS FDIS TS).freeze
18
18
  WITHDRAWN_STATUS = "withdrawn".freeze
19
+ REDUNDENT_NOTE_REGEX = /^An? .*? is a type of \{\{[^}]*\}\}\s*?\.?$/.freeze
19
20
 
20
21
  attr_reader :stepmod_path,
21
22
  :stepmod_dir,
@@ -86,8 +87,8 @@ module Stepmod
86
87
  arm_path = Pathname.new("#{stepmod_dir}/modules/#{x['name']}/arm_annotated.exp")
87
88
  mim_path = Pathname.new("#{stepmod_dir}/modules/#{x['name']}/mim_annotated.exp")
88
89
 
89
- files << arm_path if File.exists? arm_path
90
- files << mim_path if File.exists? mim_path
90
+ files << arm_path if File.exist? arm_path
91
+ files << mim_path if File.exist? mim_path
91
92
  end
92
93
 
93
94
  # Should ignore these because the `<resource_docs>` elements do not provide any EXPRESS schemas
@@ -104,7 +105,7 @@ module Stepmod
104
105
  next if x['status'] == WITHDRAWN_STATUS
105
106
 
106
107
  path = Pathname.new("#{stepmod_dir}/resources/#{x['name']}/#{x['name']}_annotated.exp")
107
- files << path if File.exists? path
108
+ files << path if File.exist? path
108
109
  end
109
110
 
110
111
  # Should ignore these because we are skiping Clause 3 terms
@@ -318,6 +319,8 @@ module Stepmod
318
319
  old_definition = trim_definition(entity.remarks.first)
319
320
  definition = generate_entity_definition(entity, domain)
320
321
 
322
+ notes = [old_definition].reject { |note| redundant_note?(note) }
323
+
321
324
  Stepmod::Utils::Concept.new(
322
325
  designations: [
323
326
  {
@@ -336,7 +339,7 @@ module Stepmod
336
339
  "link" => "https://www.iso.org/standard/32858.html",
337
340
  },
338
341
  ],
339
- notes: [old_definition].compact,
342
+ notes: notes,
340
343
  language_code: "en",
341
344
  part: bibdata.part,
342
345
  schema: schema,
@@ -512,6 +515,10 @@ module Stepmod
512
515
  REMARK
513
516
  end.join
514
517
  end
518
+
519
+ def redundant_note?(note)
520
+ note && note.match?(REDUNDENT_NOTE_REGEX) && !note.include?("\n")
521
+ end
515
522
  end
516
523
  end
517
524
  end
@@ -1,5 +1,5 @@
1
1
  module Stepmod
2
2
  module Utils
3
- VERSION = "0.3.24".freeze
3
+ VERSION = "0.3.25".freeze
4
4
  end
5
5
  end
@@ -33,7 +33,7 @@ Gem::Specification.new do |spec|
33
33
 
34
34
  spec.add_runtime_dependency "concurrent-ruby"
35
35
  spec.add_runtime_dependency "expressir"
36
- spec.add_runtime_dependency "glossarist-new", "~> 1.0.1"
36
+ spec.add_runtime_dependency "glossarist", "~> 1.0.5"
37
37
  spec.add_runtime_dependency "indefinite_article"
38
38
  spec.add_runtime_dependency "ptools"
39
39
  spec.add_runtime_dependency "pubid-iso"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: stepmod-utils
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.24
4
+ version: 0.3.25
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-11-24 00:00:00.000000000 Z
11
+ date: 2023-04-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: concurrent-ruby
@@ -39,19 +39,19 @@ dependencies:
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
- name: glossarist-new
42
+ name: glossarist
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: 1.0.1
47
+ version: 1.0.5
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: 1.0.1
54
+ version: 1.0.5
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: indefinite_article
57
57
  requirement: !ruby/object:Gem::Requirement
@@ -171,17 +171,16 @@ email:
171
171
  - open.source@ribose.com
172
172
  executables:
173
173
  - stepmod-annotate-all
174
- - stepmod-build-resource-docs-cache
175
174
  - stepmod-convert-express-description
176
175
  - stepmod-convert-express-resource
177
- - stepmod-extract-terms
178
- - stepmod-extract-yaml-terms
179
- - stepmod-find-express-files
176
+ - stepmod-extract-changes
177
+ - stepmod-extract-concepts
180
178
  extensions: []
181
179
  extra_rdoc_files: []
182
180
  files:
183
181
  - ".github/workflows/rake.yml"
184
182
  - ".github/workflows/release.yml"
183
+ - ".github/workflows/test-concept-generation.yml"
185
184
  - ".gitignore"
186
185
  - ".hound.yml"
187
186
  - ".rspec"
@@ -194,14 +193,17 @@ files:
194
193
  - bin/console
195
194
  - bin/setup
196
195
  - exe/stepmod-annotate-all
197
- - exe/stepmod-build-resource-docs-cache
198
196
  - exe/stepmod-convert-express-description
199
197
  - exe/stepmod-convert-express-resource
200
- - exe/stepmod-extract-terms
201
- - exe/stepmod-extract-yaml-terms
202
- - exe/stepmod-find-express-files
198
+ - exe/stepmod-extract-changes
199
+ - exe/stepmod-extract-concepts
203
200
  - lib/stepmod/utils.rb
204
201
  - lib/stepmod/utils/bibdata.rb
202
+ - lib/stepmod/utils/change.rb
203
+ - lib/stepmod/utils/change_collection.rb
204
+ - lib/stepmod/utils/change_edition.rb
205
+ - lib/stepmod/utils/change_edition_collection.rb
206
+ - lib/stepmod/utils/changes_extractor.rb
205
207
  - lib/stepmod/utils/cleaner.rb
206
208
  - lib/stepmod/utils/concept.rb
207
209
  - lib/stepmod/utils/converters/a.rb
@@ -215,6 +217,7 @@ files:
215
217
  - lib/stepmod/utils/converters/dd.rb
216
218
  - lib/stepmod/utils/converters/def.rb
217
219
  - lib/stepmod/utils/converters/definition.rb
220
+ - lib/stepmod/utils/converters/description.rb
218
221
  - lib/stepmod/utils/converters/dl.rb
219
222
  - lib/stepmod/utils/converters/drop.rb
220
223
  - lib/stepmod/utils/converters/dt.rb
@@ -287,7 +290,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
287
290
  - !ruby/object:Gem::Version
288
291
  version: '0'
289
292
  requirements: []
290
- rubygems_version: 3.3.7
293
+ rubygems_version: 3.3.26
291
294
  signing_key:
292
295
  specification_version: 4
293
296
  summary: Stepmod-utils is a toolkit that works on STEPmod data.
@@ -1,20 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require "nokogiri"
4
- require "json"
5
-
6
- stepmod_dir = ARGV.first || Dir.pwd
7
-
8
- schemas = {}
9
- Dir.glob(File.join(stepmod_dir,
10
- "data/resource_docs/*/resource.xml")).each do |resource_docs_file|
11
- match = resource_docs_file.match("data/resource_docs/([^/]+)/resource.xml")
12
- resource_docs_dir = match.captures[0]
13
-
14
- resource_docs = Nokogiri::XML(File.read(resource_docs_file)).root
15
- resource_docs.xpath("schema").each do |schema|
16
- schemas[schema["name"]] = resource_docs_dir
17
- end
18
- end
19
-
20
- puts JSON.pretty_generate(schemas)
@@ -1,237 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # encoding: UTF-8
3
-
4
- require "pry"
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 "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("-p", "--path STEPMOD_DATA_PATH", String, "Path to STEPmod data directory") do |path|
34
- options[:stepmod_dir] = path
35
- end
36
-
37
- opts.on("-i", "--index INDEX_PATH", String, "Path to repository_index.xml") do |path|
38
- unless path.nil?
39
- options[:index_path] = Pathname.new(path).to_s
40
- end
41
- end
42
-
43
- opts.on_tail("-h", "--help", "Show this message") do
44
- puts opts
45
- exit
46
- end
47
- end.parse!
48
-
49
- stepmod_dir = options[:stepmod_dir]
50
- if stepmod_dir.nil?
51
- raise StandardError.new("STEPmod data path not set, set with the `-p` option.")
52
- else
53
- log "STEPmod data path: `#{stepmod_dir}`"
54
- end
55
-
56
- index_path = options[:index_path] || File.join(stepmod_dir, "repository_index.xml")
57
- unless File.exists?(index_path)
58
- raise StandardError.new("Index file not present at #{index_path}, set with the `-i` option.")
59
- else
60
- log "Repository index path: `#{index_path}`"
61
- end
62
-
63
- general_concepts,
64
- resource_concepts,
65
- parsed_bibliography,
66
- part_concepts,
67
- part_resources,
68
- part_modules = Stepmod::Utils::TermsExtractor.call(stepmod_dir, index_path)
69
-
70
- def part_to_title(bibdata)
71
- case bibdata.part.to_i
72
- when 41
73
- "Fundamentals of product description and support"
74
- when 42
75
- "Geometric and topological representation"
76
- when 43
77
- "Foundation representation"
78
- when 44
79
- "Product structure, concept and configuration"
80
- when 45
81
- "Material and other engineering properties"
82
- when 46
83
- "Visual presentation"
84
- when 47
85
- "Shape tolerance"
86
- when 51
87
- "Mathematical representation"
88
- else
89
- bibdata.title_en
90
- end
91
- end
92
-
93
- IMAGE_REPLACEMENTS = {
94
- 'image::eq01.gif[]' => 'stem:[H(A,B) = max {h(A, B), h(B,A)}]',
95
- 'image::eq02.gif[]' => 'stem:[max_{a in A} { min_{b in B} d(a,b) }]',
96
- 'image::vector_z_c.gif[]' => 'stem:[bar z_{c}]',
97
- 'image::one_direction_repeat_factor_expression.gif[]' => 'stem:[I + k cdot R; k = -1, 1]',
98
- '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]',
99
- }
100
-
101
- TEXT_REPLACEMENTS = {
102
- ' (see <module_ref linkend="ply_orientation_specification:4_entities:figure:f2"> Figure 2</module_ref>)' => '',
103
- ' (see <module_ref linkend="ply_orientation_specification:4_entities:figure:f3"> Figure 3</module_ref>)' => ''
104
- }
105
-
106
- def replace_content(content)
107
- IMAGE_REPLACEMENTS.each_pair do |k, v|
108
- content.gsub!(k, v)
109
- end
110
- TEXT_REPLACEMENTS.each_pair do |k, v|
111
- content.gsub!(k, v)
112
- end
113
-
114
- content
115
- end
116
-
117
- ## Skip all Clause 3 terms
118
- # part_concepts.each do |(bibdata, current_part_concepts)|
119
- # current_part_concepts = current_part_concepts.to_a.map do |n|
120
- # n.localizations["en"]
121
- # end
122
- # fn = "03x-stepmod-#{bibdata.part}.adoc"
123
- # File.open(fn, "w") do |file|
124
- # file.puts("== #{part_to_title(bibdata)}\n\n")
125
- # file.puts(replace_images(current_part_concepts.map(&:to_mn_adoc).join("\n")))
126
- # end
127
- # log "INFO: written to: #{fn}"
128
- # end
129
-
130
- # File.open("03x-stepmod.adoc", "w") do |file|
131
- # part_concepts.sort_by do |(bibdata, current_part_concepts)|
132
- # bibdata.part.to_i
133
- # end.each do |(bibdata, current_part_concepts)|
134
- # fn = "03x-stepmod-#{bibdata.part}.adoc"
135
- # file.puts("\ninclude::#{fn}[]\n")
136
- # end
137
- # end
138
-
139
- # log "INFO: written summary file to: 03x-stepmod.adoc"
140
-
141
- part_resources.each do |(bibdata, current_part_resources)|
142
- current_part_resources = current_part_resources.to_a.map do |n|
143
- n.localizations["en"]
144
- end
145
- fn = "04x-stepmod-entities-resources-#{bibdata.part}.adoc"
146
- File.open(fn, "w") do |file|
147
- # file.puts("== #{part_to_title(bibdata)}\n\n")
148
- file.puts(replace_content(current_part_resources.map(&:to_mn_adoc).join("\n")))
149
- end
150
- log "INFO: written to: #{fn}"
151
- end
152
-
153
- File.open("04x-stepmod-entities-resources.adoc", "w") do |file|
154
- part_resources.sort_by do |(bibdata, current_part_resources)|
155
- bibdata.part.to_i
156
- end.each do |(bibdata, current_part_resources)|
157
- fn = "04x-stepmod-entities-resources-#{bibdata.part}.adoc"
158
- file.puts("\ninclude::#{fn}[]\n")
159
- end
160
- end
161
-
162
- log "INFO: written summary file to: 04x-stepmod-entities-resources.adoc"
163
-
164
- part_modules.sort_by do |(bibdata, part_modules_arm, part_modules_mim)|
165
- bibdata.part.to_i
166
- end.each do |(bibdata, part_modules_arm, part_modules_mim)|
167
- fn = "05x-stepmod-entities-modules-#{bibdata.part}.adoc"
168
- File.open(fn, "w") do |file|
169
- file.puts("")
170
-
171
- unless part_modules_arm.empty?
172
- schema_name = part_modules_arm.first.first
173
- concepts = part_modules_arm.first.last.to_a.map do |n|
174
- n.localizations["en"]
175
- end
176
-
177
- # puts "SCHEMA NAME ARM: #{schema_name}"
178
- file.puts("== #{schema_name}\n\n")
179
- file.puts(concepts.map(&:to_mn_adoc).join("\n"))
180
- end
181
-
182
- file.puts("")
183
-
184
- unless part_modules_mim.empty?
185
- schema_name = part_modules_mim.first.first
186
-
187
- # puts "SCHEMA NAME MIM: #{schema_name}"
188
- concepts = part_modules_mim.first.last.to_a.map do |n|
189
- n.localizations["en"]
190
- end
191
- file.puts("== #{schema_name}\n\n")
192
- file.puts(replace_content(concepts.map(&:to_mn_adoc).join("\n")))
193
- end
194
- end
195
-
196
- log "INFO: written to: #{fn}"
197
- end
198
-
199
- File.open("05x-stepmod-entities-modules.adoc", "w") do |file|
200
- part_modules.sort_by do |(bibdata, part_modules_arm, part_modules_mim)|
201
- bibdata.part.to_i
202
- end.each do |(bibdata, part_modules_arm, part_modules_mim)|
203
- fn = "05x-stepmod-entities-modules-#{bibdata.part}.adoc"
204
- file.puts("\ninclude::#{fn}[]\n")
205
- end
206
- end
207
-
208
- log "INFO: written summary file to: 05x-stepmod-entities-modules.adoc"
209
-
210
- ## Skipping all Clause 3 terms
211
- # File.open("031-stepmod-general.adoc", "w") do |file|
212
- # file.puts(
213
- # replace_images(
214
- # general_concepts.to_a.map do |n|
215
- # n.localizations["en"]
216
- # end.map(&:to_mn_adoc).join("\n")
217
- # )
218
- # )
219
- # end
220
-
221
- # log "INFO: written to: 031-stepmod-general.adoc"
222
-
223
- File.open("041-stepmod-entities-resources.adoc", "w") do |file|
224
- file.puts(
225
- replace_content(
226
- resource_concepts.to_a.map do |n|
227
- n.localizations["en"]
228
- end.map(&:to_mn_adoc).join("\n")
229
- )
230
- )
231
- end
232
- log "INFO: written to: 041-stepmod-entities-resources.adoc"
233
-
234
- File.open("991-generated-bibliography.adoc", "w") do |file|
235
- file.puts(parsed_bibliography.map(&:to_mn_adoc).sort.uniq.join("\n"))
236
- end
237
- log "INFO: written to: 991-generated-bibliography.adoc"
@@ -1,24 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require "nokogiri"
4
-
5
- stepmod_dir = ARGV.first || Dir.pwd
6
-
7
- index = Nokogiri::XML(File.read(File.join(stepmod_dir,
8
- "repository_index.xml"))).root
9
-
10
- files = []
11
- index.xpath("modules/module").each do |item|
12
- files << "#{stepmod_dir}/data/modules/#{item['name']}/arm.exp"
13
- files << "#{stepmod_dir}/data/modules/#{item['name']}/mim.exp"
14
- end
15
- index.xpath("resources/resource").each do |item|
16
- files << "#{stepmod_dir}/data/resources/#{item['name']}/#{item['name']}.exp"
17
- end
18
- index.xpath("business_object_models/business_object_model").each do |item|
19
- files << "#{stepmod_dir}/data/business_object_models/#{item['name']}/bom.exp"
20
- files << "#{stepmod_dir}/data/business_object_models/#{item['name']}/DomainModel.exp"
21
- end
22
-
23
- existing_files = files.filter { |file| File.exists?(file) }
24
- puts existing_files