Skip to content

Commit ba6f0ed

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 ba6f0ed

File tree

5 files changed

+107
-29
lines changed

5 files changed

+107
-29
lines changed

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

+25-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,39 @@ 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) do |e|
57+
e.gsub!(dir, '') if e.respond_to?(:gsub!)
58+
end
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
7572
end
7673
end
7774
end

script/git-pre-commit

+3-1
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@
44
# base directory is up two levels, not just one.
55
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && cd ../.. && pwd )"
66

7+
cd "$DIR"
8+
79
# Make sure we can use git correctly
8-
cd "$DIR" && git rev-parse --verify HEAD >/dev/null 2>&1
10+
git rev-parse --verify HEAD >/dev/null 2>&1
911
if [ $? -ne 0 ]; then
1012
echo "Unable to determine revision of this git repo"
1113
exit 1

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

+49
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,19 @@
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
168181
end
169182

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

0 commit comments

Comments
 (0)