expressir 2.1.17 → 2.1.19

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.
@@ -0,0 +1,249 @@
1
+ require "pathname"
2
+
3
+ module Expressir
4
+ # Coverage module for calculating documentation coverage of EXPRESS entities
5
+ module Coverage
6
+ # Mapping of EXPRESS entity type names to their corresponding class names
7
+ ENTITY_TYPE_MAP = {
8
+ "TYPE" => "Expressir::Model::Declarations::Type",
9
+ "ENTITY" => "Expressir::Model::Declarations::Entity",
10
+ "CONSTANT" => "Expressir::Model::Declarations::Constant",
11
+ "FUNCTION" => "Expressir::Model::Declarations::Function",
12
+ "RULE" => "Expressir::Model::Declarations::Rule",
13
+ "PROCEDURE" => "Expressir::Model::Declarations::Procedure",
14
+ "SUBTYPE_CONSTRAINT" => "Expressir::Model::Declarations::SubtypeConstraint",
15
+ }.freeze
16
+ # Represents a documentation coverage report for EXPRESS schemas
17
+ class Report
18
+ attr_reader :repository, :schema_reports, :total_entities, :documented_entities,
19
+ :undocumented_entities
20
+
21
+ # Initialize a coverage report
22
+ # @param repository [Expressir::Model::Repository] The repository to analyze
23
+ # @param skip_types [Array<String>] Array of entity type names to skip from coverage
24
+ def initialize(repository, skip_types = [])
25
+ @repository = repository
26
+ @skip_types = skip_types
27
+ @schema_reports = []
28
+ @total_entities = []
29
+ @documented_entities = []
30
+ @undocumented_entities = []
31
+
32
+ process_repository
33
+ end
34
+
35
+ # Create a report from a repository
36
+ # @param repository [Expressir::Model::Repository] The repository to analyze
37
+ # @param skip_types [Array<String>] Array of entity type names to skip from coverage
38
+ # @return [Report] The coverage report
39
+ def self.from_repository(repository, skip_types = [])
40
+ new(repository, skip_types)
41
+ end
42
+
43
+ # Create a report from a schema file
44
+ # @param path [String] Path to the schema file
45
+ # @param skip_types [Array<String>] Array of entity type names to skip from coverage
46
+ # @return [Report] The coverage report
47
+ def self.from_file(path, skip_types = [])
48
+ repository = Expressir::Express::Parser.from_file(path)
49
+ new(repository, skip_types)
50
+ end
51
+
52
+ # Calculate the overall coverage percentage
53
+ # @return [Float] The coverage percentage
54
+ def coverage_percentage
55
+ return 100.0 if @total_entities.empty?
56
+
57
+ (@documented_entities.size.to_f / @total_entities.size) * 100
58
+ end
59
+
60
+ # Get file-level reports
61
+ # @return [Array<Hash>] Array of file report hashes
62
+ def file_reports
63
+ @schema_reports.map do |report|
64
+ absolute_path = report[:schema].file
65
+ relative_path = begin
66
+ Pathname.new(absolute_path).relative_path_from(Pathname.pwd).to_s
67
+ rescue ArgumentError
68
+ # If paths are on different drives or otherwise incompatible,
69
+ # fall back to the absolute path
70
+ absolute_path
71
+ end
72
+
73
+ {
74
+ "file" => relative_path,
75
+ "file_basename" => File.basename(absolute_path),
76
+ "directory" => File.dirname(absolute_path),
77
+ "total" => report[:total].size,
78
+ "documented" => report[:documented].size,
79
+ "undocumented" => report[:undocumented],
80
+ "coverage" => report[:coverage],
81
+ }
82
+ end
83
+ end
84
+
85
+ # Get directory-level reports
86
+ # @return [Array<Hash>] Array of directory report hashes
87
+ def directory_reports
88
+ # Group by directory (absolute path)
89
+ by_directory = file_reports.group_by { |r| r["directory"] }
90
+
91
+ # Aggregate stats for each directory
92
+ by_directory.map do |directory, reports|
93
+ # Convert directory to relative path
94
+ relative_directory = begin
95
+ Pathname.new(directory).relative_path_from(Pathname.pwd).to_s
96
+ rescue ArgumentError
97
+ # If paths are on different drives or otherwise incompatible,
98
+ # fall back to the absolute path
99
+ directory
100
+ end
101
+
102
+ total = reports.sum { |r| r["total"] }
103
+ documented = reports.sum { |r| r["documented"] }
104
+ coverage = total.positive? ? (documented.to_f / total) * 100 : 100.0
105
+
106
+ {
107
+ "directory" => relative_directory,
108
+ "total" => total,
109
+ "documented" => documented,
110
+ "undocumented" => total - documented,
111
+ "coverage" => coverage,
112
+ "files" => reports.size,
113
+ }
114
+ end
115
+ end
116
+
117
+ # Convert report to a hash representation
118
+ # @return [Hash] The report as a hash
119
+ def to_h
120
+ {
121
+ "overall" => {
122
+ "total" => @total_entities.size,
123
+ "documented" => @documented_entities.size,
124
+ "undocumented" => @undocumented_entities.size,
125
+ "coverage" => coverage_percentage,
126
+ },
127
+ "directories" => directory_reports,
128
+ "files" => file_reports,
129
+ }
130
+ end
131
+
132
+ private
133
+
134
+ # Process the repository and collect coverage information
135
+ def process_repository
136
+ return unless @repository
137
+
138
+ @repository.schemas.each do |schema|
139
+ schema_report = process_schema(schema)
140
+ @schema_reports << schema_report
141
+
142
+ @total_entities.concat(schema_report[:total])
143
+ @documented_entities.concat(schema_report[:documented])
144
+ @undocumented_entities.concat(schema_report[:undocumented].map do |entity|
145
+ { schema: schema.id, entity: entity }
146
+ end)
147
+ end
148
+ end
149
+
150
+ # Process a schema and collect coverage information
151
+ # @param schema [Expressir::Model::Declarations::Schema] The schema to analyze
152
+ # @return [Hash] A hash with coverage information
153
+ def process_schema(schema)
154
+ entities = Expressir::Coverage.find_entities(schema, @skip_types)
155
+ documented = entities.select { |e| Expressir::Coverage.entity_documented?(e) }
156
+ undocumented = entities - documented
157
+
158
+ coverage = entities.empty? ? 100.0 : (documented.size.to_f / entities.size) * 100
159
+
160
+ {
161
+ schema: schema,
162
+ total: entities,
163
+ documented: documented,
164
+ undocumented: undocumented.map { |e| format_entity(e) },
165
+ coverage: coverage,
166
+ }
167
+ end
168
+
169
+ # Format an entity for display
170
+ # @param entity [Expressir::Model::ModelElement] The entity to format
171
+ # @return [Hash] A hash with type and name of the entity
172
+ def format_entity(entity)
173
+ # Get class name (e.g., "Type" from "Expressir::Model::Declarations::Type")
174
+ type_name = entity.class.name.split("::").last
175
+
176
+ # Convert to EXPRESS convention (e.g., "TYPE")
177
+ express_type = type_name.upcase
178
+
179
+ # Return structured format
180
+ {
181
+ "type" => express_type,
182
+ "name" => entity.id.to_s,
183
+ }
184
+ end
185
+ end
186
+
187
+ # Check if an entity has documentation (remarks)
188
+ # @param entity [Expressir::Model::ModelElement] The entity to check
189
+ # @return [Boolean] True if the entity has documentation
190
+ def self.entity_documented?(entity)
191
+ # Check for direct remarks
192
+ if entity.respond_to?(:remarks) && entity.remarks && !entity.remarks.empty?
193
+ return true
194
+ end
195
+
196
+ # Check for remark_items
197
+ if entity.respond_to?(:remark_items) && entity.remark_items && !entity.remark_items.empty?
198
+ return true
199
+ end
200
+
201
+ # For schema entities, check if there's a remark_item with their ID
202
+ if entity.parent.respond_to?(:remark_items) && entity.parent.remark_items
203
+ entity_id = entity.id.to_s.downcase
204
+ entity.parent.remark_items.any? do |item|
205
+ item.id.to_s.downcase == entity_id || item.id.to_s.downcase.include?("#{entity_id}.")
206
+ end
207
+ else
208
+ false
209
+ end
210
+ end
211
+
212
+ # Find all entities in a schema
213
+ # @param schema [Expressir::Model::Declarations::Schema] The schema to analyze
214
+ # @param skip_types [Array<String>] Array of entity type names to skip from coverage
215
+ # @return [Array<Expressir::Model::ModelElement>] Array of entities
216
+ def self.find_entities(schema, skip_types = [])
217
+ entities = []
218
+
219
+ # Add all schema-level entities
220
+ entities.concat(schema.constants) if schema.constants
221
+ entities.concat(schema.types) if schema.types
222
+ entities.concat(schema.entities) if schema.entities
223
+ entities.concat(schema.functions) if schema.functions
224
+ entities.concat(schema.rules) if schema.rules
225
+ entities.concat(schema.procedures) if schema.procedures
226
+ entities.concat(schema.subtype_constraints) if schema.subtype_constraints
227
+
228
+ # Add enumeration items from types (only if TYPE is not being skipped)
229
+ unless skip_types.include?("TYPE")
230
+ schema.types&.each do |type|
231
+ if type.respond_to?(:enumeration_items) && type.enumeration_items
232
+ entities.concat(type.enumeration_items)
233
+ end
234
+ end
235
+ end
236
+
237
+ # Filter out any nil elements and ensure all have IDs
238
+ entities = entities.compact.select { |e| e.respond_to?(:id) && e.id }
239
+
240
+ # Filter out skipped entity types
241
+ if skip_types.any?
242
+ skip_classes = skip_types.map { |type| ENTITY_TYPE_MAP[type] }.compact
243
+ entities = entities.reject { |entity| skip_classes.include?(entity.class.name) }
244
+ end
245
+
246
+ entities
247
+ end
248
+ end
249
+ end
@@ -219,13 +219,15 @@ module Expressir
219
219
  " ",
220
220
  ].join
221
221
  end,
222
- *if node.supertype_attribute && node.id
222
+ *if node.supertype_attribute && node.id != node.supertype_attribute.attribute.id
223
223
  [
224
224
  "RENAMED",
225
225
  " ",
226
+ node.id,
227
+ " ",
226
228
  ].join
227
229
  end,
228
- *if node.id
230
+ *if node.id && !node.supertype_attribute
229
231
  [
230
232
  node.id,
231
233
  " ",
@@ -67,7 +67,7 @@ module Expressir
67
67
  end
68
68
  rule(:aliasStmt) do
69
69
  (tALIAS >> variableId >> tFOR >> generalRef >> qualifier.repeat.as(:qualifier) >>
70
- op_delim >> stmt.repeat(1).as(:stmt) >> tEND_ALIAS >> (op_delim.as(:op_delim2))).as(:aliasStmt)
70
+ op_delim >> stmt.repeat(1).as(:stmt) >> tEND_ALIAS >> op_delim.as(:op_delim2)).as(:aliasStmt)
71
71
  end
72
72
  rule(:anyKeyword) { KEYWORDS.map { |kw| send("t#{kw}") }.inject(:|) }
73
73
  rule(:arrayType) do
@@ -116,7 +116,7 @@ module Expressir
116
116
  rule(:element) { (expression >> (op_colon >> repetition).maybe).as(:element) }
117
117
  rule(:embeddedRemark) { (str("(*") >> (str("*)").absent? >> (embeddedRemark | any)).repeat >> str("*)")).as(:embeddedRemark) }
118
118
  rule(:encodedCharacter) { (octet >> octet >> octet >> octet) }
119
- rule(:encodedStringLiteral) { cts((str('"') >> (encodedCharacter.repeat(1)) >> str('"')).as(:str)).as(:encodedStringLiteral) }
119
+ rule(:encodedStringLiteral) { cts((str('"') >> encodedCharacter.repeat(1) >> str('"')).as(:str)).as(:encodedStringLiteral) }
120
120
  rule(:entityBody) do
121
121
  (explicitAttr.repeat.as(:explicitAttr) >> deriveClause.maybe >> inverseClause.maybe >> uniqueClause.maybe >> whereClause.maybe).as(:entityBody)
122
122
  end
@@ -149,7 +149,7 @@ module Expressir
149
149
  rule(:functionHead) do
150
150
  (tFUNCTION >> functionId >>
151
151
  (op_leftparen >> (formalParameter >> (op_delim >> formalParameter).repeat).as(:listOf_formalParameter) >> op_rightparen).maybe >>
152
- op_colon >> parameterType >> (op_delim.as(:op_delim2))).as(:functionHead)
152
+ op_colon >> parameterType >> op_delim.as(:op_delim2)).as(:functionHead)
153
153
  end
154
154
  rule(:functionId) { simpleId.as(:functionId) }
155
155
  rule(:functionRef) { functionId.as(:functionRef) }
@@ -181,7 +181,7 @@ module Expressir
181
181
  rule(:intervalItem) { simpleExpression.as(:intervalItem) }
182
182
  rule(:intervalLow) { simpleExpression.as(:intervalLow) }
183
183
  rule(:interval) do
184
- (op_left_curly_brace >> intervalLow >> intervalOp >> intervalItem >> (intervalOp.as(:intervalOp2)) >>
184
+ (op_left_curly_brace >> intervalLow >> intervalOp >> intervalItem >> intervalOp.as(:intervalOp2) >>
185
185
  intervalHigh >> op_right_curly_brace).as(:interval)
186
186
  end
187
187
  rule(:intervalOp) { (op_less_equal | op_less_than).as(:intervalOp) }
@@ -256,7 +256,7 @@ module Expressir
256
256
  rule(:procedureHead) do
257
257
  (tPROCEDURE >> procedureId >>
258
258
  (op_leftparen >> (procedureHeadParameter >>
259
- (op_delim >> procedureHeadParameter).repeat).as(:listOf_procedureHeadParameter) >> op_rightparen).maybe >> (op_delim.as(:op_delim2))).as(:procedureHead)
259
+ (op_delim >> procedureHeadParameter).repeat).as(:listOf_procedureHeadParameter) >> op_rightparen).maybe >> op_delim.as(:op_delim2)).as(:procedureHead)
260
260
  end
261
261
  rule(:procedureId) { simpleId.as(:procedureId) }
262
262
  rule(:procedureRef) { procedureId.as(:procedureRef) }
@@ -281,7 +281,7 @@ module Expressir
281
281
  end
282
282
  rule(:renameId) { (constantId | entityId | functionId | procedureId | typeId).as(:renameId) }
283
283
  rule(:repeatControl) { (incrementControl.maybe >> whileControl.maybe >> untilControl.maybe).as(:repeatControl) }
284
- rule(:repeatStmt) { (tREPEAT >> repeatControl >> op_delim >> stmt.repeat(1).as(:stmt) >> tEND_REPEAT >> (op_delim.as(:op_delim2))).as(:repeatStmt) }
284
+ rule(:repeatStmt) { (tREPEAT >> repeatControl >> op_delim >> stmt.repeat(1).as(:stmt) >> tEND_REPEAT >> op_delim.as(:op_delim2)).as(:repeatStmt) }
285
285
  rule(:repetition) { numericExpression.as(:repetition) }
286
286
  rule(:resourceOrRename) { (resourceRef >> (tAS >> renameId).maybe).as(:resourceOrRename) }
287
287
  rule(:resourceRef) { (constantRef | entityRef | functionRef | procedureRef | typeRef).as(:resourceRef) }
@@ -301,7 +301,7 @@ module Expressir
301
301
  schemaBodyDeclaration.repeat.as(:schemaBodyDeclaration)).as(:schemaBody)
302
302
  end
303
303
  rule(:schemaDecl) do
304
- (tSCHEMA >> schemaId >> schemaVersionId.maybe >> op_delim >> schemaBody >> tEND_SCHEMA >> (op_delim.as(:op_delim2))).as(:schemaDecl)
304
+ (tSCHEMA >> schemaId >> schemaVersionId.maybe >> op_delim >> schemaBody >> tEND_SCHEMA >> op_delim.as(:op_delim2)).as(:schemaDecl)
305
305
  end
306
306
  rule(:schemaId) { simpleId.as(:schemaId) }
307
307
  rule(:schemaRef) { schemaId.as(:schemaRef) }
@@ -353,7 +353,7 @@ module Expressir
353
353
  (tTOTAL_OVER >> op_leftparen >> (entityRef >> (op_comma >> entityRef).repeat).as(:listOf_entityRef) >> op_rightparen >> op_delim).as(:totalOver)
354
354
  end
355
355
  rule(:typeDecl) do
356
- (tTYPE >> typeId >> op_equals >> underlyingType >> op_delim >> whereClause.maybe >> tEND_TYPE >> (op_delim.as(:op_delim2))).as(:typeDecl)
356
+ (tTYPE >> typeId >> op_equals >> underlyingType >> op_delim >> whereClause.maybe >> tEND_TYPE >> op_delim.as(:op_delim2)).as(:typeDecl)
357
357
  end
358
358
  rule(:typeId) { simpleId.as(:typeId) }
359
359
  rule(:typeLabelId) { simpleId.as(:typeLabelId) }
@@ -363,7 +363,7 @@ module Expressir
363
363
  rule(:unaryOp) { (op_plus | op_minus | tNOT).as(:unaryOp) }
364
364
  rule(:underlyingType) { (concreteTypes | constructedTypes).as(:underlyingType) }
365
365
  rule(:uniqueClause) do
366
- (tUNIQUE >> (uniqueRule >> op_delim >> (uniqueRule >> (op_delim.as(:op_delim2))).repeat).as(:listOf_uniqueRule)).as(:uniqueClause)
366
+ (tUNIQUE >> (uniqueRule >> op_delim >> (uniqueRule >> op_delim.as(:op_delim2)).repeat).as(:listOf_uniqueRule)).as(:uniqueClause)
367
367
  end
368
368
  rule(:uniqueRule) do
369
369
  ((ruleLabelId >> op_colon).maybe >> (referencedAttribute >> (op_comma >> referencedAttribute).repeat).as(:listOf_referencedAttribute)).as(:uniqueRule)
@@ -88,7 +88,7 @@ module Expressir
88
88
  private_methods.grep(/^visit_/).map do |name|
89
89
  rulename = name.to_s.sub(/^visit_/, "").gsub(/_([a-z])/) { $1.upcase }
90
90
  [rulename.to_sym, name.to_sym]
91
- end
91
+ end,
92
92
  ]
93
93
  end
94
94
 
@@ -104,7 +104,7 @@ module Expressir
104
104
  else
105
105
  [k, to_ctx(v, k)]
106
106
  end
107
- end
107
+ end,
108
108
  ]
109
109
  Ctx.new nodes, name
110
110
  when Array
@@ -581,7 +581,13 @@ module Expressir
581
581
  ctx__redeclared_attribute__qualified_attribute = ctx__redeclared_attribute&.qualified_attribute
582
582
  ctx__redeclared_attribute__attribute_id = ctx__redeclared_attribute&.attribute_id
583
583
 
584
- id = visit_if(ctx__attribute_id || ctx__redeclared_attribute__attribute_id)
584
+ attribute_qualifier = ctx__redeclared_attribute__qualified_attribute&.attribute_qualifier
585
+ attribute_id = attribute_qualifier&.attribute_ref&.attribute_id
586
+ ctx__redeclared_attribute__qualified_attribute__attribute_qualifier_attribute_id = attribute_id
587
+
588
+ id = visit_if(ctx__attribute_id ||
589
+ ctx__redeclared_attribute__attribute_id ||
590
+ ctx__redeclared_attribute__qualified_attribute__attribute_qualifier_attribute_id)
585
591
  supertype_attribute = visit_if(ctx__redeclared_attribute__qualified_attribute)
586
592
 
587
593
  Model::Declarations::Attribute.new(
@@ -806,9 +812,8 @@ module Expressir
806
812
  type = visit_if(ctx__parameter_type)
807
813
  expression = visit_if(ctx__expression)
808
814
 
809
- Model::Declarations::Attribute.new(
810
- id: attribute.id, # reuse
811
- kind: Model::Declarations::Attribute::DERIVED,
815
+ Model::Declarations::DerivedAttribute.new(
816
+ id: attribute.id,
812
817
  supertype_attribute: attribute.supertype_attribute, # reuse
813
818
  type: type,
814
819
  expression: expression,
@@ -1428,9 +1433,8 @@ module Expressir
1428
1433
  visit(ctx__attribute_ref)
1429
1434
  end
1430
1435
 
1431
- Model::Declarations::Attribute.new(
1436
+ Model::Declarations::InverseAttribute.new(
1432
1437
  id: attribute.id, # reuse
1433
- kind: Model::Declarations::Attribute::INVERSE,
1434
1438
  supertype_attribute: attribute.supertype_attribute, # reuse
1435
1439
  type: type,
1436
1440
  expression: expression,
@@ -0,0 +1,25 @@
1
+ module Expressir
2
+ module Model
3
+ module Declarations
4
+ # Specified in ISO 10303-11:2004
5
+ # - section 9.2.1 Attributes
6
+ class DerivedAttribute < Attribute
7
+ include Identifier
8
+
9
+ DERIVED = "DERIVED".freeze
10
+
11
+ attribute :kind, :string, default: -> { DERIVED }
12
+ attribute :_class, :string, default: -> { send(:name) }
13
+
14
+ key_value do
15
+ map "_class", to: :_class, render_default: true
16
+ map "kind", to: :kind, render_default: true
17
+ map "supertype_attribute", to: :supertype_attribute
18
+ map "optional", to: :optional
19
+ map "type", to: :type
20
+ map "expression", to: :expression
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,25 @@
1
+ module Expressir
2
+ module Model
3
+ module Declarations
4
+ # Specified in ISO 10303-11:2004
5
+ # - section 9.2.1 Attributes
6
+ class InverseAttribute < Attribute
7
+ include Identifier
8
+
9
+ INVERSE = "INVERSE".freeze
10
+
11
+ attribute :kind, :string, default: -> { INVERSE }
12
+ attribute :_class, :string, default: -> { send(:name) }
13
+
14
+ key_value do
15
+ map "_class", to: :_class, render_default: true
16
+ map "kind", to: :kind, render_default: true
17
+ map "supertype_attribute", to: :supertype_attribute
18
+ map "optional", to: :optional
19
+ map "type", to: :type
20
+ map "expression", to: :expression
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -56,6 +56,8 @@ module Expressir
56
56
  "Expressir::Model::DataTypes::Set",
57
57
  "Expressir::Model::DataTypes::String" =>
58
58
  "Expressir::Model::DataTypes::String",
59
+ "Expressir::Model::Declarations::DerivedAttribute" =>
60
+ "Expressir::Model::Declarations::DerivedAttribute",
59
61
  "Expressir::Model::Declarations::Attribute" =>
60
62
  "Expressir::Model::Declarations::Attribute",
61
63
  "Expressir::Model::Declarations::Constant" =>
@@ -1,3 +1,3 @@
1
1
  module Expressir
2
- VERSION = "2.1.17".freeze
2
+ VERSION = "2.1.19".freeze
3
3
  end
data/lib/expressir.rb CHANGED
@@ -3,6 +3,7 @@ require_relative "expressir/version"
3
3
  require_relative "expressir/cli"
4
4
  require_relative "expressir/config"
5
5
  require_relative "expressir/benchmark"
6
+ require_relative "expressir/coverage"
6
7
  require "lutaml/model"
7
8
  require "liquid" # To enable Lutaml::Model::Liquefiable
8
9
 
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: expressir
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.17
4
+ version: 2.1.19
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2025-03-24 00:00:00.000000000 Z
11
+ date: 2025-06-04 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: base64
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: benchmark-ips
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -80,6 +94,34 @@ dependencies:
80
94
  - - "~>"
81
95
  - !ruby/object:Gem::Version
82
96
  version: '2.0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: ruby-progressbar
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '1.11'
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '1.11'
111
+ - !ruby/object:Gem::Dependency
112
+ name: terminal-table
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '3.0'
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: '3.0'
83
125
  - !ruby/object:Gem::Dependency
84
126
  name: thor
85
127
  requirement: !ruby/object:Gem::Requirement
@@ -142,10 +184,18 @@ files:
142
184
  - lib/expressir.rb
143
185
  - lib/expressir/benchmark.rb
144
186
  - lib/expressir/cli.rb
187
+ - lib/expressir/commands/base.rb
188
+ - lib/expressir/commands/benchmark.rb
189
+ - lib/expressir/commands/benchmark_cache.rb
190
+ - lib/expressir/commands/clean.rb
191
+ - lib/expressir/commands/coverage.rb
192
+ - lib/expressir/commands/format.rb
193
+ - lib/expressir/commands/validate.rb
194
+ - lib/expressir/commands/version.rb
145
195
  - lib/expressir/config.rb
196
+ - lib/expressir/coverage.rb
146
197
  - lib/expressir/express/cache.rb
147
198
  - lib/expressir/express/error.rb
148
- - lib/expressir/express/express_remarks_decorator.rb
149
199
  - lib/expressir/express/formatter.rb
150
200
  - lib/expressir/express/hyperlink_formatter.rb
151
201
  - lib/expressir/express/model_visitor.rb
@@ -175,11 +225,13 @@ files:
175
225
  - lib/expressir/model/data_types/string.rb
176
226
  - lib/expressir/model/declarations/attribute.rb
177
227
  - lib/expressir/model/declarations/constant.rb
228
+ - lib/expressir/model/declarations/derived_attribute.rb
178
229
  - lib/expressir/model/declarations/entity.rb
179
230
  - lib/expressir/model/declarations/function.rb
180
231
  - lib/expressir/model/declarations/interface.rb
181
232
  - lib/expressir/model/declarations/interface_item.rb
182
233
  - lib/expressir/model/declarations/interfaced_item.rb
234
+ - lib/expressir/model/declarations/inverse_attribute.rb
183
235
  - lib/expressir/model/declarations/parameter.rb
184
236
  - lib/expressir/model/declarations/procedure.rb
185
237
  - lib/expressir/model/declarations/remark_item.rb
@@ -1,54 +0,0 @@
1
- module Expressir
2
- module Express
3
- class ExpressRemarksDecorator
4
- RELATIVE_PREFIX_MACRO_REGEXP = /^(link|image|video|audio|include)(:+)?(?![^\/:]+:\/\/|[A-Z]:\/|\/)([^:\[]+)(\[.*\])?$/.freeze
5
-
6
- attr_reader :remark, :options
7
-
8
- def self.call(remark, options)
9
- new(remark, options).call
10
- end
11
-
12
- def initialize(remark, options)
13
- @remark = remark
14
- @options = options
15
- end
16
-
17
- def call
18
- result = remark
19
- if options["relative_path_prefix"]
20
- result = update_relative_paths(result,
21
- options["relative_path_prefix"])
22
- end
23
- result
24
- end
25
-
26
- private
27
-
28
- def update_relative_paths(string, path_prefix)
29
- string
30
- .split("\n")
31
- .map do |line|
32
- if line.match?(RELATIVE_PREFIX_MACRO_REGEXP)
33
- prefix_relative_paths(line, path_prefix)
34
- else
35
- line
36
- end
37
- end
38
- .join("\n")
39
- end
40
-
41
- def prefix_relative_paths(line, path_prefix)
42
- line.gsub(RELATIVE_PREFIX_MACRO_REGEXP) do |_match|
43
- prefixed_path = File.join(path_prefix, $3.strip)
44
- # When we are dealing with a relative path of a template:
45
- # ../path/to/file we need to transform it into
46
- # the absolute one because `image::` macro wont understand it other way
47
- prefixed_path = File.absolute_path(prefixed_path) if prefixed_path.start_with?("../")
48
- full_path = File.expand_path(prefixed_path)
49
- "#{$1}#{$2}#{full_path}#{$4}"
50
- end
51
- end
52
- end
53
- end
54
- end