recog 2.3.20 → 2.3.23
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/.github/dependabot.yml +8 -0
- data/.github/workflows/ci.yml +1 -1
- data/.github/workflows/verify.yml +89 -0
- data/.vscode/bin/monitor-recog-fingerprints.sh +54 -0
- data/.vscode/extensions.json +5 -0
- data/.vscode/settings.json +8 -0
- data/.vscode/tasks.json +77 -0
- data/CONTRIBUTING.md +8 -0
- data/README.md +17 -0
- data/bin/recog_standardize +28 -13
- data/bin/recog_verify +42 -8
- data/cpe-remap.yaml +62 -3
- data/features/data/schema_failure.xml +4 -0
- data/features/data/tests_with_failures.xml +6 -0
- data/features/support/hooks.rb +9 -0
- data/features/verify.feature +85 -21
- data/identifiers/fields.txt +6 -5
- data/identifiers/hw_device.txt +8 -0
- data/identifiers/hw_family.txt +8 -0
- data/identifiers/hw_product.txt +54 -0
- data/identifiers/os_device.txt +2 -0
- data/identifiers/os_family.txt +2 -0
- data/identifiers/os_product.txt +18 -2
- data/identifiers/service_product.txt +26 -0
- data/identifiers/vendor.txt +62 -1
- data/lib/recog/db.rb +2 -1
- data/lib/recog/fingerprint.rb +33 -6
- data/lib/recog/fingerprint_parse_error.rb +10 -0
- data/lib/recog/nizer.rb +1 -82
- data/lib/recog/verifier.rb +9 -9
- data/lib/recog/verify_reporter.rb +17 -6
- data/lib/recog/version.rb +1 -1
- data/requirements.txt +1 -1
- data/spec/data/external_example_fingerprint/hp_printer_ex_01.txt +1 -0
- data/spec/data/external_example_fingerprint/hp_printer_ex_02.txt +1 -0
- data/spec/data/external_example_fingerprint.xml +8 -0
- data/spec/data/external_example_illegal_path_fingerprint.xml +7 -0
- data/spec/lib/fingerprint_self_test_spec.rb +1 -0
- data/spec/lib/recog/db_spec.rb +84 -61
- data/spec/lib/recog/fingerprint_spec.rb +4 -4
- data/spec/lib/recog/verify_reporter_spec.rb +73 -4
- data/tools/dev/hooks/pre-commit +21 -0
- data/update_cpes.py +130 -37
- data/xml/apache_os.xml +98 -56
- data/xml/architecture.xml +15 -1
- data/xml/dhcp_vendor_class.xml +206 -0
- data/xml/dns_versionbind.xml +26 -13
- data/xml/favicons.xml +236 -47
- data/xml/fingerprints.xsd +9 -1
- data/xml/ftp_banners.xml +213 -197
- data/xml/h323_callresp.xml +101 -101
- data/xml/hp_pjl_id.xml +84 -84
- data/xml/html_title.xml +715 -45
- data/xml/http_cookies.xml +143 -80
- data/xml/http_servers.xml +510 -310
- data/xml/http_wwwauth.xml +177 -75
- data/xml/imap_banners.xml +10 -10
- data/xml/mdns_device-info_txt.xml +421 -26
- data/xml/mysql_banners.xml +3 -2
- data/xml/nntp_banners.xml +12 -9
- data/xml/ntp_banners.xml +97 -97
- data/xml/operating_system.xml +98 -83
- data/xml/pop_banners.xml +27 -27
- data/xml/rsh_resp.xml +3 -3
- data/xml/sip_banners.xml +46 -8
- data/xml/sip_user_agents.xml +180 -27
- data/xml/smb_native_lm.xml +5 -5
- data/xml/smb_native_os.xml +28 -25
- data/xml/smtp_banners.xml +258 -254
- data/xml/smtp_ehlo.xml +1 -1
- data/xml/smtp_help.xml +11 -11
- data/xml/smtp_noop.xml +2 -2
- data/xml/snmp_sysdescr.xml +1554 -1429
- data/xml/snmp_sysobjid.xml +27 -27
- data/xml/ssh_banners.xml +27 -20
- data/xml/telnet_banners.xml +256 -57
- data/xml/tls_jarm.xml +48 -6
- data/xml/x11_banners.xml +3 -3
- data/xml/x509_issuers.xml +69 -2
- data/xml/x509_subjects.xml +144 -33
- metadata +24 -4
- data/lib/recog/verifier_factory.rb +0 -13
data/lib/recog/nizer.rb
CHANGED
@@ -8,13 +8,13 @@ class Nizer
|
|
8
8
|
# Non-weighted host attributes that can be extracted from fingerprint matches
|
9
9
|
HOST_ATTRIBUTES = %W{
|
10
10
|
host.domain
|
11
|
-
host.id
|
12
11
|
host.ip
|
13
12
|
host.mac
|
14
13
|
host.name
|
15
14
|
host.time
|
16
15
|
hw.device
|
17
16
|
hw.family
|
17
|
+
hw.serial_number
|
18
18
|
hw.product
|
19
19
|
hw.vendor
|
20
20
|
}
|
@@ -264,84 +264,3 @@ class Nizer
|
|
264
264
|
|
265
265
|
end
|
266
266
|
end
|
267
|
-
|
268
|
-
=begin
|
269
|
-
|
270
|
-
Current key names:
|
271
|
-
|
272
|
-
apache.info
|
273
|
-
apache.variant
|
274
|
-
apache.variant.version
|
275
|
-
cookie
|
276
|
-
host.domain
|
277
|
-
host.id
|
278
|
-
host.ip
|
279
|
-
host.mac
|
280
|
-
host.name
|
281
|
-
host.time
|
282
|
-
hw.device
|
283
|
-
hw.family
|
284
|
-
hw.product
|
285
|
-
hw.vendor
|
286
|
-
imail.eval
|
287
|
-
jetty.info
|
288
|
-
junction.cookie
|
289
|
-
junction.name
|
290
|
-
linux.kernel.version
|
291
|
-
loadbalancer.poolname
|
292
|
-
mdaemon.unregistered
|
293
|
-
mercur.os.info
|
294
|
-
metainfo.version
|
295
|
-
metainfo.version.version
|
296
|
-
ms.nttp.version
|
297
|
-
notes.build.version
|
298
|
-
notes.intl
|
299
|
-
ntmail.id
|
300
|
-
openssh.comment
|
301
|
-
openssh.cvepatch
|
302
|
-
os.arch
|
303
|
-
os.build
|
304
|
-
os.certainty
|
305
|
-
os.device
|
306
|
-
os.edition
|
307
|
-
os.family
|
308
|
-
os.product
|
309
|
-
os.vendor
|
310
|
-
os.version
|
311
|
-
os.version.version
|
312
|
-
os.version.version.version
|
313
|
-
postfix.os.info
|
314
|
-
postoffice.build
|
315
|
-
postoffice.id
|
316
|
-
proftpd.server.name
|
317
|
-
pureftpd.config
|
318
|
-
qpopper.version
|
319
|
-
sendmail.config.version
|
320
|
-
sendmail.hpux.phne.version
|
321
|
-
sendmail.vendor.version
|
322
|
-
service.certainty
|
323
|
-
service.component.family
|
324
|
-
service.component.product
|
325
|
-
service.component.vendor
|
326
|
-
service.component.version
|
327
|
-
service.family
|
328
|
-
service.product
|
329
|
-
service.vendor
|
330
|
-
service.version
|
331
|
-
service.version.version
|
332
|
-
service.version.version.version
|
333
|
-
service.version.version.version.version
|
334
|
-
service.version.version.version.version.version
|
335
|
-
siemens.model
|
336
|
-
snmp.fpmib.oid.1
|
337
|
-
snmp.fpmib.oid.2
|
338
|
-
system.time
|
339
|
-
system.time.format
|
340
|
-
system.time.micros
|
341
|
-
system.time.millis
|
342
|
-
thttpd.mx-patch
|
343
|
-
timeout
|
344
|
-
tomcat.info
|
345
|
-
zmailer.ident
|
346
|
-
|
347
|
-
=end
|
data/lib/recog/verifier.rb
CHANGED
@@ -1,23 +1,23 @@
|
|
1
1
|
module Recog
|
2
2
|
class Verifier
|
3
|
-
attr_reader :
|
3
|
+
attr_reader :db, :reporter
|
4
4
|
|
5
|
-
def initialize(
|
6
|
-
@
|
5
|
+
def initialize(db, reporter)
|
6
|
+
@db = db
|
7
7
|
@reporter = reporter
|
8
8
|
end
|
9
9
|
|
10
10
|
def verify
|
11
|
-
reporter.report(fingerprints.count) do
|
12
|
-
fingerprints.each do |fp|
|
11
|
+
reporter.report(db.fingerprints.count) do
|
12
|
+
db.fingerprints.each do |fp|
|
13
13
|
reporter.print_name fp
|
14
14
|
|
15
15
|
fp.verify_params do |status, message|
|
16
16
|
case status
|
17
17
|
when :warn
|
18
|
-
reporter.warning
|
18
|
+
reporter.warning message, fp.line
|
19
19
|
when :fail
|
20
|
-
reporter.failure
|
20
|
+
reporter.failure message, fp.line
|
21
21
|
when :success
|
22
22
|
reporter.success(message)
|
23
23
|
end
|
@@ -25,9 +25,9 @@ class Verifier
|
|
25
25
|
fp.verify_tests do |status, message|
|
26
26
|
case status
|
27
27
|
when :warn
|
28
|
-
reporter.warning
|
28
|
+
reporter.warning message, fp.line
|
29
29
|
when :fail
|
30
|
-
reporter.failure
|
30
|
+
reporter.failure message, fp.line
|
31
31
|
when :success
|
32
32
|
reporter.success(message)
|
33
33
|
end
|
@@ -3,14 +3,18 @@ class VerifyReporter
|
|
3
3
|
attr_reader :formatter
|
4
4
|
attr_reader :success_count, :warning_count, :failure_count
|
5
5
|
|
6
|
-
def initialize(options, formatter)
|
6
|
+
def initialize(options, formatter, path=nil)
|
7
7
|
@options = options
|
8
8
|
@formatter = formatter
|
9
|
+
@path = path
|
9
10
|
reset_counts
|
10
11
|
end
|
11
12
|
|
12
13
|
def report(fingerprint_count)
|
13
14
|
reset_counts
|
15
|
+
if detail? and !@path.to_s.empty?
|
16
|
+
formatter.status_message("\n#{@path}:\n")
|
17
|
+
end
|
14
18
|
yield self
|
15
19
|
summarize(fingerprint_count) unless @options.quiet
|
16
20
|
end
|
@@ -20,15 +24,15 @@ class VerifyReporter
|
|
20
24
|
formatter.success_message("#{padding}#{text}") if detail?
|
21
25
|
end
|
22
26
|
|
23
|
-
def warning(text)
|
27
|
+
def warning(text, line=nil)
|
24
28
|
return unless @options.warnings
|
25
29
|
@warning_count += 1
|
26
|
-
formatter.warning_message("#{padding}#{text}")
|
30
|
+
formatter.warning_message("#{path_label(line)}#{padding}WARN: #{text}")
|
27
31
|
end
|
28
32
|
|
29
|
-
def failure(text)
|
33
|
+
def failure(text, line=nil)
|
30
34
|
@failure_count += 1
|
31
|
-
formatter.failure_message("#{padding}#{text}")
|
35
|
+
formatter.failure_message("#{path_label(line)}#{padding}FAIL: #{text}")
|
32
36
|
end
|
33
37
|
|
34
38
|
def print_name(fingerprint)
|
@@ -61,12 +65,19 @@ class VerifyReporter
|
|
61
65
|
@options.detail
|
62
66
|
end
|
63
67
|
|
68
|
+
def path_label(line=nil)
|
69
|
+
unless detail?
|
70
|
+
line_label = line ? line.to_s + ":" : ""
|
71
|
+
@path.to_s.empty? ? "" : "#{@path}:#{line_label} "
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
64
75
|
def padding
|
65
76
|
' ' if @options.detail
|
66
77
|
end
|
67
78
|
|
68
79
|
def summary_line
|
69
|
-
summary = "SUMMARY: Test completed with "
|
80
|
+
summary = "#{path_label}SUMMARY: Test completed with "
|
70
81
|
summary << "#{@success_count} successful"
|
71
82
|
summary << ", #{@warning_count} warnings"
|
72
83
|
summary << ", and #{@failure_count} failures"
|
data/lib/recog/version.rb
CHANGED
data/requirements.txt
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
lxml==4.6.
|
1
|
+
lxml==4.6.5
|
2
2
|
pyyaml
|
@@ -0,0 +1 @@
|
|
1
|
+
HP LaserJet 4100 Series
|
@@ -0,0 +1 @@
|
|
1
|
+
HP LaserJet 2200
|
@@ -0,0 +1,8 @@
|
|
1
|
+
<fingerprints>
|
2
|
+
<fingerprint pattern="laserjet (.*)(?: series)?" flags="REG_ICASE">
|
3
|
+
<description>HP JetDirect Printer</description>
|
4
|
+
<example _filename="hp_printer_ex_01.txt"/>
|
5
|
+
<example _filename="hp_printer_ex_02.txt"/>
|
6
|
+
<param pos="0" name="service.vendor" value="HP"/>
|
7
|
+
</fingerprint>
|
8
|
+
</fingerprints>
|
@@ -151,6 +151,7 @@ describe Recog::DB do
|
|
151
151
|
# test any extractions specified in the example
|
152
152
|
example.attributes.each_pair do |k,v|
|
153
153
|
next if k == '_encoding'
|
154
|
+
next if k == '_filename'
|
154
155
|
expect(match[k]).to eq(v), "Regex didn't extract expected value for fingerprint attribute #{k} -- got #{match[k]} instead of #{v}"
|
155
156
|
end
|
156
157
|
end
|
data/spec/lib/recog/db_spec.rb
CHANGED
@@ -1,97 +1,120 @@
|
|
1
1
|
require 'recog/db'
|
2
2
|
|
3
3
|
describe Recog::DB do
|
4
|
-
let(:xml_file) { File.expand_path File.join('spec', 'data', 'test_fingerprints.xml') }
|
5
|
-
subject { Recog::DB.new(xml_file) }
|
6
4
|
|
7
5
|
describe "#fingerprints" do
|
8
|
-
|
6
|
+
context "with inline example content" do
|
7
|
+
let(:xml_file) { File.expand_path File.join('spec', 'data', 'test_fingerprints.xml') }
|
8
|
+
subject { Recog::DB.new(xml_file) }
|
9
9
|
|
10
|
-
|
10
|
+
subject(:fingerprints) { described_class.new(xml_file).fingerprints }
|
11
11
|
|
12
|
-
|
13
|
-
subject(:entry) { described_class.new(xml_file).fingerprints[0] }
|
12
|
+
it { is_expected.to be_a(Enumerable) }
|
14
13
|
|
15
|
-
|
16
|
-
|
17
|
-
end
|
14
|
+
context "with only a pattern" do
|
15
|
+
subject(:entry) { described_class.new(xml_file).fingerprints[0] }
|
18
16
|
|
19
|
-
|
20
|
-
|
21
|
-
|
17
|
+
it "has a blank name with no description" do
|
18
|
+
expect(entry.name).to be_empty
|
19
|
+
end
|
22
20
|
|
23
|
-
|
24
|
-
|
25
|
-
|
21
|
+
it "has a pattern" do
|
22
|
+
expect(entry.regex.source).to eq(".*\\(iSeries\\).*")
|
23
|
+
end
|
24
|
+
|
25
|
+
it "has no params" do
|
26
|
+
expect(entry.params).to be_empty
|
27
|
+
end
|
26
28
|
|
27
|
-
|
28
|
-
|
29
|
+
it "has no tests" do
|
30
|
+
expect(entry.tests).to be_empty
|
31
|
+
end
|
29
32
|
end
|
30
|
-
end
|
31
33
|
|
32
|
-
|
33
|
-
|
34
|
+
context "with params" do
|
35
|
+
subject(:entry) { described_class.new(xml_file).fingerprints[1] }
|
34
36
|
|
35
|
-
|
36
|
-
|
37
|
-
|
37
|
+
it "has a name" do
|
38
|
+
expect(entry.name).to eq('PalmOS')
|
39
|
+
end
|
38
40
|
|
39
|
-
|
40
|
-
|
41
|
-
|
41
|
+
it "has a pattern" do
|
42
|
+
expect(entry.regex.source).to eq(".*\\(PalmOS\\).*")
|
43
|
+
end
|
42
44
|
|
43
|
-
|
44
|
-
|
45
|
-
|
45
|
+
it "has params" do
|
46
|
+
expect(entry.params).to eq({"os.vendor"=>[1, "Palm"], "os.device"=>[2, "General"]})
|
47
|
+
end
|
46
48
|
|
47
|
-
|
48
|
-
|
49
|
+
it "has no tests" do
|
50
|
+
expect(entry.tests).to be_empty
|
51
|
+
end
|
49
52
|
end
|
50
|
-
end
|
51
53
|
|
52
|
-
|
53
|
-
|
54
|
+
context "with pattern flags" do
|
55
|
+
subject(:entry) { described_class.new(xml_file).fingerprints[2] }
|
54
56
|
|
55
|
-
|
56
|
-
|
57
|
-
|
57
|
+
it "has a name and only uses the first value" do
|
58
|
+
expect(entry.name).to eq('HP Designjet printer')
|
59
|
+
end
|
58
60
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
61
|
+
it 'creates a Regexp with expected flags' do
|
62
|
+
expect(entry.regex).to be_a(Regexp)
|
63
|
+
expect(entry.regex.options).to eq(Recog::Fingerprint::RegexpFactory::DEFAULT_FLAGS | Regexp::IGNORECASE)
|
64
|
+
end
|
63
65
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
66
|
+
it "has a pattern" do
|
67
|
+
expect(entry.regex).to be_a(Regexp)
|
68
|
+
expect(entry.regex.source).to eq("(designjet \\S+)")
|
69
|
+
end
|
70
|
+
|
71
|
+
it "has params" do
|
72
|
+
expect(entry.params).to eq({"service.vendor"=>[0, "HP"]})
|
73
|
+
end
|
68
74
|
|
69
|
-
|
70
|
-
|
75
|
+
it "has no tests" do
|
76
|
+
expect(entry.tests).to be_empty
|
77
|
+
end
|
71
78
|
end
|
72
79
|
|
73
|
-
|
74
|
-
|
80
|
+
context "with test" do
|
81
|
+
subject(:entry) { described_class.new(xml_file).fingerprints[3] }
|
82
|
+
|
83
|
+
it "has a name" do
|
84
|
+
expect(entry.name).to eq('HP JetDirect Printer')
|
85
|
+
end
|
86
|
+
|
87
|
+
it "has a pattern" do
|
88
|
+
expect(entry.regex.source).to eq("laserjet (.*)(?: series)?")
|
89
|
+
end
|
90
|
+
|
91
|
+
it "has params" do
|
92
|
+
expect(entry.params).to eq({"service.vendor"=>[0, "HP"]})
|
93
|
+
end
|
94
|
+
|
95
|
+
it "has tests" do
|
96
|
+
expect(entry.tests.map(&:content)).to match_array(["HP LaserJet 4100 Series", "HP LaserJet 2200"])
|
97
|
+
end
|
75
98
|
end
|
76
99
|
end
|
77
100
|
|
78
|
-
context "with
|
79
|
-
|
101
|
+
context "with external example content" do
|
102
|
+
let(:xml_file) { File.expand_path File.join('spec', 'data', 'external_example_fingerprint.xml') }
|
103
|
+
subject { Recog::DB.new(xml_file) }
|
80
104
|
|
81
|
-
|
82
|
-
expect(entry.name).to eq('HP JetDirect Printer')
|
83
|
-
end
|
105
|
+
subject(:entry) { described_class.new(xml_file).fingerprints[0] }
|
84
106
|
|
85
|
-
it "has
|
86
|
-
expect(entry.
|
107
|
+
it "has tests" do
|
108
|
+
expect(entry.tests.map(&:content)).to match_array(["HP LaserJet 4100 Series", "HP LaserJet 2200"])
|
87
109
|
end
|
110
|
+
end
|
88
111
|
|
89
|
-
|
90
|
-
|
91
|
-
|
112
|
+
context "with external example content illegal path" do
|
113
|
+
let(:xml_file) { File.expand_path File.join('spec', 'data', 'external_example_illegal_path_fingerprint.xml') }
|
114
|
+
subject { Recog::DB.new(xml_file) }
|
92
115
|
|
93
|
-
it "
|
94
|
-
expect
|
116
|
+
it "raises an illegal file path error" do
|
117
|
+
expect { subject }.to raise_error(/an example specifies an illegal file path '.+'/)
|
95
118
|
end
|
96
119
|
end
|
97
120
|
end
|
@@ -75,7 +75,7 @@ describe Recog::Fingerprint do
|
|
75
75
|
let(:entry) { described_class.new(doc.xpath("//fingerprints/fingerprint")[6]) }
|
76
76
|
|
77
77
|
it "identifies when a parameter defined by a capture group is not included in one example" do
|
78
|
-
expect { |unused| entry.verify_tests_have_capture_groups(&unused) }.to yield_successive_args([:
|
78
|
+
expect { |unused| entry.verify_tests_have_capture_groups(&unused) }.to yield_successive_args([:fail, String])
|
79
79
|
end
|
80
80
|
end
|
81
81
|
|
@@ -83,7 +83,7 @@ describe Recog::Fingerprint do
|
|
83
83
|
let(:entry) { described_class.new(doc.xpath("//fingerprints/fingerprint")[7]) }
|
84
84
|
|
85
85
|
it "identifies when two parameters defined by a capture groups are not included in one example" do
|
86
|
-
expect { |unused| entry.verify_tests_have_capture_groups(&unused) }.to yield_successive_args([:
|
86
|
+
expect { |unused| entry.verify_tests_have_capture_groups(&unused) }.to yield_successive_args([:fail, String], [:fail, String])
|
87
87
|
end
|
88
88
|
end
|
89
89
|
|
@@ -92,7 +92,7 @@ describe Recog::Fingerprint do
|
|
92
92
|
let(:entry) { described_class.new(doc.xpath("//fingerprints/fingerprint")[8]) }
|
93
93
|
|
94
94
|
it "identifies when a parameter defined by a capture group is not included in one example" do
|
95
|
-
expect { |unused| entry.verify_tests_have_capture_groups(&unused) }.to yield_successive_args([:
|
95
|
+
expect { |unused| entry.verify_tests_have_capture_groups(&unused) }.to yield_successive_args([:fail, String])
|
96
96
|
end
|
97
97
|
end
|
98
98
|
|
@@ -100,7 +100,7 @@ describe Recog::Fingerprint do
|
|
100
100
|
let(:entry) { described_class.new(doc.xpath("//fingerprints/fingerprint")[9]) }
|
101
101
|
|
102
102
|
it "identifies when two parameters defined by a capture groups are not included in one example" do
|
103
|
-
expect { |unused| entry.verify_tests_have_capture_groups(&unused) }.to yield_successive_args([:
|
103
|
+
expect { |unused| entry.verify_tests_have_capture_groups(&unused) }.to yield_successive_args([:fail, String], [:fail, String])
|
104
104
|
end
|
105
105
|
end
|
106
106
|
|
@@ -7,6 +7,7 @@ describe Recog::VerifyReporter do
|
|
7
7
|
let(:summary_line) do
|
8
8
|
"SUMMARY: Test completed with 1 successful, 1 warnings, and 1 failures"
|
9
9
|
end
|
10
|
+
let(:path) { "fingerprint.xml" }
|
10
11
|
|
11
12
|
subject { Recog::VerifyReporter.new(double(detail: false, quiet: false, warnings: true), formatter) }
|
12
13
|
|
@@ -21,12 +22,12 @@ describe Recog::VerifyReporter do
|
|
21
22
|
|
22
23
|
describe "#report" do
|
23
24
|
it "prints warnings" do
|
24
|
-
expect(formatter).to receive(:warning_message).with('a warning')
|
25
|
+
expect(formatter).to receive(:warning_message).with('WARN: a warning')
|
25
26
|
run_report
|
26
27
|
end
|
27
28
|
|
28
29
|
it "prints failures" do
|
29
|
-
expect(formatter).to receive(:failure_message).with('a failure')
|
30
|
+
expect(formatter).to receive(:failure_message).with('FAIL: a failure')
|
30
31
|
run_report
|
31
32
|
end
|
32
33
|
|
@@ -49,12 +50,80 @@ describe Recog::VerifyReporter do
|
|
49
50
|
end
|
50
51
|
|
51
52
|
it "prints warnings" do
|
52
|
-
expect(formatter).to receive(:warning_message).with(' a warning')
|
53
|
+
expect(formatter).to receive(:warning_message).with(' WARN: a warning')
|
53
54
|
run_report
|
54
55
|
end
|
55
56
|
|
56
57
|
it "prints failures" do
|
57
|
-
expect(formatter).to receive(:failure_message).with(' a failure')
|
58
|
+
expect(formatter).to receive(:failure_message).with(' FAIL: a failure')
|
59
|
+
run_report
|
60
|
+
end
|
61
|
+
|
62
|
+
it "prints the fingerprint count" do
|
63
|
+
expect(formatter).to receive(:status_message).with("\nVerified 1 fingerprints:")
|
64
|
+
run_report
|
65
|
+
end
|
66
|
+
|
67
|
+
it "prints summary" do
|
68
|
+
expect(formatter).to receive(:failure_message).with(summary_line)
|
69
|
+
run_report
|
70
|
+
end
|
71
|
+
|
72
|
+
context "with no fingerprint tests" do
|
73
|
+
let(:tests) { [] }
|
74
|
+
|
75
|
+
it "does not print the name" do
|
76
|
+
expect(formatter).not_to receive(:status_message).with("\na name")
|
77
|
+
run_report
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
context "with fingerprint path" do
|
83
|
+
|
84
|
+
subject { Recog::VerifyReporter.new(double(detail: false, quiet: false, warnings: true), formatter, path) }
|
85
|
+
|
86
|
+
it "prints warnings" do
|
87
|
+
expect(formatter).to receive(:warning_message).with("#{path}: WARN: a warning")
|
88
|
+
run_report
|
89
|
+
end
|
90
|
+
|
91
|
+
it "prints failures" do
|
92
|
+
expect(formatter).to receive(:failure_message).with("#{path}: FAIL: a failure")
|
93
|
+
run_report
|
94
|
+
end
|
95
|
+
|
96
|
+
it "prints summary" do
|
97
|
+
expect(formatter).to receive(:failure_message).with("#{path}: #{summary_line}")
|
98
|
+
run_report
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
context "with fingerprint path and detail" do
|
103
|
+
subject { Recog::VerifyReporter.new(double(detail: true, quiet: false, warnings: true), formatter, path) }
|
104
|
+
|
105
|
+
it "prints the fingerprint path" do
|
106
|
+
expect(formatter).to receive(:status_message).with("\n#{path}:\n")
|
107
|
+
run_report
|
108
|
+
end
|
109
|
+
|
110
|
+
it "prints the fingerprint name" do
|
111
|
+
expect(formatter).to receive(:status_message).with("\na name")
|
112
|
+
run_report
|
113
|
+
end
|
114
|
+
|
115
|
+
it "prints successes" do
|
116
|
+
expect(formatter).to receive(:success_message).with(' passed')
|
117
|
+
run_report
|
118
|
+
end
|
119
|
+
|
120
|
+
it "prints warnings" do
|
121
|
+
expect(formatter).to receive(:warning_message).with(' WARN: a warning')
|
122
|
+
run_report
|
123
|
+
end
|
124
|
+
|
125
|
+
it "prints failures" do
|
126
|
+
expect(formatter).to receive(:failure_message).with(' FAIL: a failure')
|
58
127
|
run_report
|
59
128
|
end
|
60
129
|
|
@@ -0,0 +1,21 @@
|
|
1
|
+
#!/bin/sh
|
2
|
+
#
|
3
|
+
# Hook script to verify changes about to be committed.
|
4
|
+
# The hook should exit with non-zero status after issuing an appropriate
|
5
|
+
# message if it wants to stop the commit.
|
6
|
+
|
7
|
+
# Verify that each fingerprint asserts known identifiers.
|
8
|
+
git diff --cached --name-only --diff-filter=ACM -z xml/*.xml | xargs -0 ./bin/recog_standardize --write
|
9
|
+
|
10
|
+
# get status
|
11
|
+
status=$?
|
12
|
+
|
13
|
+
if [ $status -ne 0 ]; then
|
14
|
+
echo "Please review any new additions to the text files under 'identifiers/'."
|
15
|
+
echo "If any of these names are close to an existing name, update the offending"
|
16
|
+
echo "fingerprint to use the existing name instead. Once the fingerprints are fixed,"
|
17
|
+
echo "remove the 'extra' names from the identifiers files, and run the tool again."
|
18
|
+
exit 1
|
19
|
+
fi
|
20
|
+
|
21
|
+
exit 0
|