dcm 0.1.39 → 0.1.41
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/lib/codinginfo.rb +68 -75
- data/lib/file_cache.rb +9 -5
- data/lib/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 893d24fa86203061555148240254ace73ba85975d36f9449cd74f599c88ee08e
|
|
4
|
+
data.tar.gz: 89b17bfb7cee34c53740ef746caed7dc04dad53db24cf261b186ce561f0b870c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e0288e78d05b9839d1ba4fc52613122f42b998143e6809ec940755325386c94c877d7347afafaf40f5c3d97fa0a2d7ed28eecfad897ad337093b8f98fef16b4f
|
|
7
|
+
data.tar.gz: d7d35172ec067a7ec121f4d5412a763f477f2cd5a9723f9daa1b9893b0dbf4748153d014af85dce13dbcf0173db5cda43733e1cca14c6fb8e41727cd4cb9246f
|
data/lib/codinginfo.rb
CHANGED
|
@@ -1,51 +1,21 @@
|
|
|
1
1
|
require_relative "file_cache"
|
|
2
2
|
|
|
3
3
|
class Codinginfo
|
|
4
|
-
CVAR_PREFIX_REGEXP =
|
|
5
|
-
PARAM_ASSIGNMENT_HEADERS = { name: /Parameter/, cvar: /Schalter/, package: /Komponente/ }
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
def match?(label)
|
|
22
|
-
# assignments
|
|
23
|
-
# .values
|
|
24
|
-
# .select { _1.name == name }
|
|
25
|
-
# .map { combine(_1) }
|
|
26
|
-
# .any? { label.name.match?(_1.label_prefix) }
|
|
27
|
-
label.name.match?(label_prefix)
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
def label_prefix
|
|
31
|
-
@label_prefix ||= if package
|
|
32
|
-
[name, package, value].join("_") + "."
|
|
33
|
-
else
|
|
34
|
-
/^#{name}_([A-Za-z0-9]+_)?#{value}\./
|
|
35
|
-
end
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
def to_s = "#{name}=#{value}"
|
|
39
|
-
def ==(other) = name == other.name
|
|
40
|
-
|
|
41
|
-
def combine(other)
|
|
42
|
-
fail "Cannot combine #{name} with #{other.name}" unless self == other
|
|
43
|
-
|
|
44
|
-
self.class.new \
|
|
45
|
-
name: name,
|
|
46
|
-
package: package || other.package,
|
|
47
|
-
value: value || other.value
|
|
48
|
-
end
|
|
4
|
+
CVAR_PREFIX_REGEXP = /\ACVAR_[A-Za-z0-9_]+_\d+\./
|
|
5
|
+
PARAM_ASSIGNMENT_HEADERS = { name: /Parameter/, cvar: /Schalter/, package: /Komponente|Component/ }
|
|
6
|
+
|
|
7
|
+
# Coded labels carry the CVAR value of their variant in the name:
|
|
8
|
+
#
|
|
9
|
+
# CVAR_Market_FooBar_1.PAR_FooBar_cnt_DeacCyc with package
|
|
10
|
+
# CVAR_Obd_3.Foo_Supported without package
|
|
11
|
+
# \_______________/ \_______________________/
|
|
12
|
+
# prefix parameter
|
|
13
|
+
#
|
|
14
|
+
# The spreadsheet assigns each parameter to a CVAR (and package) and
|
|
15
|
+
# lists each variant's CVAR values. Together they define the prefix.
|
|
16
|
+
|
|
17
|
+
Assignment = Data.define(:cvar, :package) do
|
|
18
|
+
def prefix(value) = [cvar, package, value].compact.join("_") + "."
|
|
49
19
|
end
|
|
50
20
|
|
|
51
21
|
class Variant
|
|
@@ -53,10 +23,10 @@ class Codinginfo
|
|
|
53
23
|
@properties = headers.zip(row).to_h
|
|
54
24
|
end
|
|
55
25
|
|
|
56
|
-
def
|
|
57
|
-
@
|
|
26
|
+
def cvar_values
|
|
27
|
+
@cvar_values ||= @properties
|
|
58
28
|
.select { |key, _| key.start_with?("CVAR_") }
|
|
59
|
-
.
|
|
29
|
+
.transform_values(&:to_i)
|
|
60
30
|
end
|
|
61
31
|
|
|
62
32
|
def attributes
|
|
@@ -66,27 +36,42 @@ class Codinginfo
|
|
|
66
36
|
.select { |_, val| val == 0 || val == 1 || val == "-" }
|
|
67
37
|
end
|
|
68
38
|
|
|
39
|
+
# Is the label coded for one of this variant's CVAR values? The package
|
|
40
|
+
# is unknown here, so any single-word package is accepted.
|
|
69
41
|
def has_matching_cvar?(label)
|
|
70
|
-
|
|
42
|
+
matching_prefix.match?(label.name)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def prefix_for(assignment)
|
|
46
|
+
value = cvar_values.fetch(assignment.cvar) do
|
|
47
|
+
fail "Variant #{description} has no value for #{assignment.cvar}"
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
assignment.prefix(value)
|
|
71
51
|
end
|
|
72
52
|
|
|
73
53
|
def description = @properties[:swfk_id]
|
|
54
|
+
|
|
55
|
+
private
|
|
56
|
+
|
|
57
|
+
def matching_prefix
|
|
58
|
+
@matching_prefix ||= cvar_values
|
|
59
|
+
.map { |cvar, value| "#{Regexp.escape(cvar)}_(?:[A-Za-z0-9]+_)?#{value}" }
|
|
60
|
+
.then { /\A(?:#{_1.join("|")})\./ }
|
|
61
|
+
end
|
|
74
62
|
end
|
|
75
63
|
|
|
76
64
|
def initialize(filepath, filter, nocache: false)
|
|
77
65
|
@filter = filter
|
|
78
|
-
@variants = []
|
|
79
66
|
|
|
80
67
|
parsed = nocache ? parse_xlsx(filepath) : FileCache.get(filepath) { parse_xlsx(filepath) }
|
|
81
68
|
|
|
82
69
|
@headers = parsed[:headers]
|
|
83
70
|
@assignments = parsed[:assignments]
|
|
84
71
|
|
|
85
|
-
parsed[:rows]
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
@variants << Variant.new(@headers, row)
|
|
89
|
-
end
|
|
72
|
+
@variants = parsed[:rows]
|
|
73
|
+
.select { filter.match?(@headers, _1) }
|
|
74
|
+
.map { Variant.new(@headers, _1) }
|
|
90
75
|
end
|
|
91
76
|
|
|
92
77
|
def variant
|
|
@@ -107,21 +92,20 @@ class Codinginfo
|
|
|
107
92
|
def unflatten_list(list)
|
|
108
93
|
fail "No variants found matching #{@filter}" if @variants.empty?
|
|
109
94
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
variants_description
|
|
95
|
+
labels = list.flat_map do |label|
|
|
96
|
+
next label unless has_cvar_assignment?(label)
|
|
97
|
+
|
|
98
|
+
@variants.map { add_cvar_prefix(label, _1) }
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
# Variants sharing a CVAR value yield identical labels
|
|
102
|
+
Ecu::LabelList.new(labels.uniq(&:name), variants_description)
|
|
119
103
|
end
|
|
120
104
|
|
|
121
105
|
def flatten_list(list)
|
|
122
106
|
list
|
|
123
107
|
.select { !cvar_coded?(_1) || variant.has_matching_cvar?(_1) }
|
|
124
|
-
.map_int {
|
|
108
|
+
.map_int { remove_cvar_prefix(_1) }
|
|
125
109
|
.with(headers: variants_description)
|
|
126
110
|
end
|
|
127
111
|
|
|
@@ -139,22 +123,22 @@ class Codinginfo
|
|
|
139
123
|
@assignments.key?(label.name)
|
|
140
124
|
end
|
|
141
125
|
|
|
142
|
-
def add_cvar_prefix(
|
|
143
|
-
variant
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
.then { _1.combine(@assignments[name]) }
|
|
147
|
-
.then { _1.label_prefix + name }
|
|
126
|
+
def add_cvar_prefix(label, variant)
|
|
127
|
+
prefix = variant.prefix_for(@assignments.fetch(label.name))
|
|
128
|
+
|
|
129
|
+
label.with(name: prefix + label.name)
|
|
148
130
|
end
|
|
149
131
|
|
|
150
|
-
def remove_cvar_prefix(
|
|
151
|
-
|
|
132
|
+
def remove_cvar_prefix(label)
|
|
133
|
+
return label unless cvar_coded?(label)
|
|
134
|
+
|
|
135
|
+
label.with(name: label.name.sub(CVAR_PREFIX_REGEXP, ""))
|
|
152
136
|
end
|
|
153
137
|
|
|
154
138
|
private
|
|
155
139
|
|
|
156
140
|
def parse_xlsx(filepath)
|
|
157
|
-
require "simple_xlsx_reader"
|
|
141
|
+
require "simple_xlsx_reader"
|
|
158
142
|
|
|
159
143
|
doc = SimpleXlsxReader.open(filepath)
|
|
160
144
|
headers = []
|
|
@@ -176,16 +160,25 @@ class Codinginfo
|
|
|
176
160
|
doc.sheets
|
|
177
161
|
.find { _1.name == "Parameterdefinition" }
|
|
178
162
|
.tap { fail "Cannot find sheet Parameterdefinition" if _1.nil? }
|
|
163
|
+
.tap { fail "Cannot find headers for Parameterdefinition" unless param_headers_present?(_1.rows.first) }
|
|
179
164
|
.rows
|
|
180
165
|
.each(headers: PARAM_ASSIGNMENT_HEADERS) do |row|
|
|
181
166
|
next if row[:cvar].nil?
|
|
182
167
|
|
|
183
|
-
assignments[row[:name]] =
|
|
168
|
+
assignments[row[:name]] = Assignment.new(row[:cvar], row[:package])
|
|
184
169
|
end
|
|
185
170
|
|
|
186
171
|
{ headers: headers, rows: rows, assignments: assignments }
|
|
187
172
|
end
|
|
188
173
|
|
|
174
|
+
# The reader accepts a header row matching at least one header; a misspelt
|
|
175
|
+
# one would otherwise surface much later as nil values.
|
|
176
|
+
def param_headers_present?(header_row)
|
|
177
|
+
return false unless header_row
|
|
178
|
+
|
|
179
|
+
PARAM_ASSIGNMENT_HEADERS.values.all? { |regexp| header_row.any? { _1.match?(regexp) } }
|
|
180
|
+
end
|
|
181
|
+
|
|
189
182
|
def parse_headers!(headers, row)
|
|
190
183
|
return false unless row[1]&.match?(/SWFK-ID/)
|
|
191
184
|
return false unless row[1]&.match?(/CVAR_BeguData/)
|
data/lib/file_cache.rb
CHANGED
|
@@ -25,11 +25,10 @@ class FileCache
|
|
|
25
25
|
end
|
|
26
26
|
|
|
27
27
|
def cache!
|
|
28
|
-
|
|
28
|
+
hit = read_cache if cached?
|
|
29
|
+
return hit unless hit.nil?
|
|
29
30
|
|
|
30
31
|
yield.tap { write_cache(_1) }
|
|
31
|
-
rescue
|
|
32
|
-
yield
|
|
33
32
|
end
|
|
34
33
|
|
|
35
34
|
def clear!
|
|
@@ -50,12 +49,17 @@ class FileCache
|
|
|
50
49
|
File.mtime(filepath) < File.mtime(cachefilepath)
|
|
51
50
|
end
|
|
52
51
|
|
|
52
|
+
# An unreadable cache (e.g. written by an older version) counts as a miss
|
|
53
53
|
def read_cache
|
|
54
|
-
Marshal.load(File.
|
|
54
|
+
Marshal.load(File.binread(cachefilepath))
|
|
55
|
+
rescue ArgumentError, TypeError, EOFError, SystemCallError
|
|
56
|
+
nil
|
|
55
57
|
end
|
|
56
58
|
|
|
57
59
|
def write_cache(obj)
|
|
58
|
-
File.
|
|
60
|
+
File.binwrite(cachefilepath, Marshal.dump(obj))
|
|
61
|
+
rescue SystemCallError
|
|
62
|
+
# A failed write must not fail the command
|
|
59
63
|
end
|
|
60
64
|
|
|
61
65
|
def cachefilepath
|
data/lib/version.rb
CHANGED