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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 96740d6528de476007a4f312fa8889887e77a27d4a693924531813188a3cd60b
4
- data.tar.gz: 867240182ffe77c721fe7ffa8ee53b77383db9954cffa9c4de723e652ec90780
3
+ metadata.gz: 46ea2364546e11b067f0d3d21e78d0a1df701ec5189aeb94d08461d551b22786
4
+ data.tar.gz: ab5adf48414ca093c86ff2fbe12155ff7eab79102412f1c1f9949ee5e7eac591
5
5
  SHA512:
6
- metadata.gz: 6e5b71123d326d72e7f6f64269238e2c0db08cec4033794a1a104088d8ae3c0b7e9b005b2551bb2541b06d676fb6959120a7bd1aac30c3cc63068e581206d8c3
7
- data.tar.gz: 9aba582cd94d7c7b85fd9bc8ad2e718c0bf23f6609a86de46393c55a85bda496fecbe9f8c847fd073a5aa1ca351148917520a490d695769fde21d118428fbe98
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*
data/.rubocop.yml CHANGED
@@ -6,5 +6,8 @@ inherit_from:
6
6
  # local repo-specific modifications
7
7
  # ...
8
8
 
9
+ Style/MultilineMethodCallIndentation:
10
+ EnforcedStyle: aligned
11
+
9
12
  AllCops:
10
13
  TargetRubyVersion: 2.5
@@ -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
@@ -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