Skip to content

Commit 8168fdf

Browse files
author
Brice Figureau
committed
Fix github#187,github#188 CompilationDir not supporting complex or multiple values
There were two cases where CompilationDir wasn't filtering out changes: * if the parameter value is an arbitrary data structure (ie hash, array or mix of both) * if the parameter value is a string containing more than one occurence of the compilation dir It turns out that both can be fixed by just replacing the compilation dirs in both the new and old values with empty strings and comparing what's left. It's probably much slower than the original string-only implementation but covers much more cases as demonstrated by github#187 and github#188.
1 parent 8774031 commit 8168fdf

File tree

4 files changed

+107
-28
lines changed

4 files changed

+107
-28
lines changed

lib/octocatalog-diff/catalog-diff/filter/compilation_dir.rb

+26-28
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# frozen_string_literal: true
22

33
require_relative '../filter'
4+
require_relative '../../util/util'
45

56
module OctocatalogDiff
67
module CatalogDiff
@@ -35,43 +36,40 @@ def filtered?(diff, options = {})
3536

3637
# Check for a change where the difference in a parameter exactly corresponds to the difference in the
3738
# compilation directory.
38-
if diff.change? && (diff.old_value.is_a?(String) || diff.new_value.is_a?(String))
39-
from_before = nil
40-
from_after = nil
41-
from_match = false
42-
to_before = nil
43-
to_after = nil
44-
to_match = false
45-
46-
if diff.old_value =~ /^(.*)#{dir2}(.*)$/m
47-
from_before = Regexp.last_match(1) || ''
48-
from_after = Regexp.last_match(2) || ''
49-
from_match = true
50-
end
51-
52-
if diff.new_value =~ /^(.*)#{dir1}(.*)$/m
53-
to_before = Regexp.last_match(1) || ''
54-
to_after = Regexp.last_match(2) || ''
55-
to_match = true
56-
end
57-
58-
if from_match && to_match && to_before == from_before && to_after == from_after
59-
message = "Resource key #{diff.type}[#{diff.title}] #{diff.structure.join(' => ')}"
60-
message += ' appears to depend on catalog compilation directory. Suppressed from results.'
61-
@logger.warn message
62-
return true
63-
end
64-
65-
if from_match || to_match
39+
if diff.change?
40+
o = remove_compilation_dir(diff.old_value, dir2)
41+
n = remove_compilation_dir(diff.new_value, dir1)
42+
if ((o == diff.old_value) ^ (n == diff.new_value))
6643
message = "Resource key #{diff.type}[#{diff.title}] #{diff.structure.join(' => ')}"
6744
message += ' may depend on catalog compilation directory, but there may be differences.'
6845
message += ' This is included in results for now, but please verify.'
6946
@logger.warn message
7047
end
48+
return o == n
7149
end
7250

7351
false
7452
end
53+
54+
def remove_compilation_dir(v, dir)
55+
value = OctocatalogDiff::Util::Util.deep_dup(v)
56+
traverse(value) { |e|
57+
e.gsub!(dir, '') if e.respond_to?(:gsub!)
58+
}
59+
value
60+
end
61+
62+
def traverse(a)
63+
case a
64+
when Array
65+
a.map { |v| traverse(v, &Proc.new) }
66+
when Hash
67+
traverse(a.values, &Proc.new)
68+
else
69+
yield a
70+
end
71+
end
72+
7573
end
7674
end
7775
end

spec/octocatalog-diff/fixtures/catalogs/compilation-dir-1.json

+17
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,23 @@
5353
"parameters": {
5454
"dir": "/path/to/catalog1/onetime"
5555
}
56+
},
57+
{
58+
"type": "Varies_Due_To_Compilation_Dir_5",
59+
"title": "Common Title",
60+
"tags": [
61+
"ignoreme"
62+
],
63+
"exported": false,
64+
"parameters": {
65+
"dir": {
66+
"component": [
67+
"path",
68+
"/path/to/catalog1/twotimes",
69+
"otherpath"
70+
]
71+
}
72+
}
5673
}
5774
],
5875
"classes": [

spec/octocatalog-diff/fixtures/catalogs/compilation-dir-2.json

+13
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,19 @@
5353
"parameters": {
5454
"dir": "/path/to/catalog2/twotimes"
5555
}
56+
},
57+
{
58+
"type": "Varies_Due_To_Compilation_Dir_5",
59+
"title": "Common Title",
60+
"tags": [
61+
"ignoreme"
62+
],
63+
"exported": false,
64+
"parameters": {
65+
"dir": {
66+
"component": [ "path", "/path/to/catalog2/twotimes", "otherpath" ]
67+
}
68+
}
5669
}
5770
],
5871
"classes": [

spec/octocatalog-diff/tests/catalog-diff/filter/compilation_dir_spec.rb

+51
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,20 @@
165165
diff_obj = OctocatalogDiff::API::V1::Diff.factory(diff)
166166
expect(subject.filtered?(diff_obj, opts)).to eq(false)
167167
end
168+
169+
it 'should remove a change where directories appear more than one time' do
170+
diff = [
171+
'~',
172+
"Varies_Due_To_Compilation_Dir_3\fCommon Title\fparameters\fdir",
173+
'command -a /path/to/catalog1/something -b common-stuff -a /path/to/catalog1/otherthing',
174+
'command -a /path/to/catalog2/something -b common-stuff -a /path/to/catalog2/otherthing',
175+
{ 'file' => nil, 'line' => nil },
176+
{ 'file' => nil, 'line' => nil }
177+
]
178+
diff_obj = OctocatalogDiff::API::V1::Diff.factory(diff)
179+
expect(subject.filtered?(diff_obj, opts)).to eq(true)
180+
end
181+
168182
end
169183

170184
context '~ partial indeterminate matches' do
@@ -190,4 +204,41 @@
190204
expect(@logger_str.string).to match(/WARN.*Varies_Due_To_Compilation_Dir_3\[Common Title\] parameters => dir.+differences/)
191205
end
192206
end
207+
208+
context '~ array value changes' do
209+
let(:diff) do
210+
[
211+
'~',
212+
"Varies_Due_To_Compilation_Dir_3\fCommon Title\fparameters\fdir",
213+
['something that doesn\'t change', '/path/to/catalog1', 'something else'],
214+
['something that doesn\'t change', '/path/to/catalog2', 'something else'],
215+
{ 'file' => nil, 'line' => nil },
216+
{ 'file' => nil, 'line' => nil }
217+
]
218+
end
219+
220+
it 'should remove a change where directories are a full match' do
221+
diff_obj = OctocatalogDiff::API::V1::Diff.factory(diff)
222+
expect(subject.filtered?(diff_obj, opts)).to eq(true)
223+
end
224+
end
225+
226+
context '~ nested hash changes' do
227+
let(:diff) do
228+
[
229+
'~',
230+
"Varies_Due_To_Compilation_Dir_3\fCommon Title\fparameters\fdir",
231+
{ 'value' => { 'path' => [ 'thing', '/path/to/catalog1/file', 'otherthing' ] } },
232+
{ 'value' => { 'path' => [ 'thing', '/path/to/catalog2/file', 'otherthing' ] } },
233+
{ 'file' => nil, 'line' => nil },
234+
{ 'file' => nil, 'line' => nil }
235+
]
236+
end
237+
238+
it 'should remove a change where directories are a full match' do
239+
diff_obj = OctocatalogDiff::API::V1::Diff.factory(diff)
240+
expect(subject.filtered?(diff_obj, opts)).to eq(true)
241+
end
242+
end
243+
193244
end

0 commit comments

Comments
 (0)