recog 2.3.21 → 3.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (120) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +1 -1
  3. data/README.md +42 -16
  4. data/Rakefile +2 -9
  5. data/lib/recog/db.rb +2 -1
  6. data/lib/recog/db_manager.rb +1 -1
  7. data/lib/recog/fingerprint.rb +33 -6
  8. data/lib/recog/fingerprint_parse_error.rb +10 -0
  9. data/lib/recog/verifier.rb +9 -9
  10. data/lib/recog/verify_reporter.rb +17 -6
  11. data/lib/recog/version.rb +1 -1
  12. data/{bin → recog/bin}/recog_match +0 -1
  13. data/{xml → recog/xml}/apache_modules.xml +0 -0
  14. data/{xml → recog/xml}/apache_os.xml +98 -56
  15. data/{xml → recog/xml}/architecture.xml +15 -1
  16. data/recog/xml/dhcp_vendor_class.xml +206 -0
  17. data/{xml → recog/xml}/dns_versionbind.xml +16 -13
  18. data/{xml → recog/xml}/favicons.xml +297 -47
  19. data/{xml → recog/xml}/fingerprints.xsd +9 -1
  20. data/{xml → recog/xml}/ftp_banners.xml +160 -156
  21. data/{xml → recog/xml}/h323_callresp.xml +101 -101
  22. data/{xml → recog/xml}/hp_pjl_id.xml +84 -84
  23. data/{xml → recog/xml}/html_title.xml +727 -34
  24. data/{xml → recog/xml}/http_cookies.xml +160 -77
  25. data/{xml → recog/xml}/http_servers.xml +556 -283
  26. data/{xml → recog/xml}/http_wwwauth.xml +190 -75
  27. data/{xml → recog/xml}/imap_banners.xml +5 -5
  28. data/{xml → recog/xml}/ldap_searchresult.xml +0 -0
  29. data/{xml → recog/xml}/mdns_device-info_txt.xml +389 -26
  30. data/{xml → recog/xml}/mdns_workstation_txt.xml +0 -0
  31. data/{xml → recog/xml}/mysql_banners.xml +1 -1
  32. data/{xml → recog/xml}/mysql_error.xml +0 -0
  33. data/{xml → recog/xml}/nntp_banners.xml +11 -8
  34. data/{xml → recog/xml}/ntp_banners.xml +97 -97
  35. data/{xml → recog/xml}/operating_system.xml +95 -80
  36. data/{xml → recog/xml}/pop_banners.xml +23 -23
  37. data/{xml → recog/xml}/rsh_resp.xml +3 -3
  38. data/{xml → recog/xml}/rtsp_servers.xml +0 -0
  39. data/{xml → recog/xml}/sip_banners.xml +43 -5
  40. data/{xml → recog/xml}/sip_user_agents.xml +175 -27
  41. data/{xml → recog/xml}/smb_native_lm.xml +5 -5
  42. data/{xml → recog/xml}/smb_native_os.xml +25 -25
  43. data/{xml → recog/xml}/smtp_banners.xml +147 -146
  44. data/{xml → recog/xml}/smtp_debug.xml +0 -0
  45. data/{xml → recog/xml}/smtp_ehlo.xml +1 -1
  46. data/{xml → recog/xml}/smtp_expn.xml +0 -0
  47. data/{xml → recog/xml}/smtp_help.xml +11 -11
  48. data/{xml → recog/xml}/smtp_mailfrom.xml +0 -0
  49. data/{xml → recog/xml}/smtp_noop.xml +2 -2
  50. data/{xml → recog/xml}/smtp_quit.xml +0 -0
  51. data/{xml → recog/xml}/smtp_rcptto.xml +0 -0
  52. data/{xml → recog/xml}/smtp_rset.xml +0 -0
  53. data/{xml → recog/xml}/smtp_turn.xml +0 -0
  54. data/{xml → recog/xml}/smtp_vrfy.xml +0 -0
  55. data/{xml → recog/xml}/snmp_sysdescr.xml +1570 -1430
  56. data/{xml → recog/xml}/snmp_sysobjid.xml +38 -27
  57. data/{xml → recog/xml}/ssh_banners.xml +16 -10
  58. data/{xml → recog/xml}/telnet_banners.xml +238 -21
  59. data/{xml → recog/xml}/tls_jarm.xml +56 -6
  60. data/{xml → recog/xml}/x11_banners.xml +3 -3
  61. data/{xml → recog/xml}/x509_issuers.xml +49 -1
  62. data/{xml → recog/xml}/x509_subjects.xml +139 -38
  63. data/recog.gemspec +9 -5
  64. data/spec/data/external_example_fingerprint/hp_printer_ex_01.txt +1 -0
  65. data/spec/data/external_example_fingerprint/hp_printer_ex_02.txt +1 -0
  66. data/spec/data/external_example_fingerprint.xml +8 -0
  67. data/spec/data/external_example_illegal_path_fingerprint.xml +7 -0
  68. data/spec/lib/recog/db_spec.rb +84 -61
  69. data/spec/lib/recog/fingerprint_spec.rb +4 -4
  70. data/spec/lib/recog/verify_reporter_spec.rb +73 -4
  71. data/spec/spec_helper.rb +4 -0
  72. metadata +65 -134
  73. data/.github/ISSUE_TEMPLATE/bug_report.md +0 -37
  74. data/.github/ISSUE_TEMPLATE/feature_request.md +0 -17
  75. data/.github/ISSUE_TEMPLATE/fingerprint_request.md +0 -27
  76. data/.github/PULL_REQUEST_TEMPLATE +0 -24
  77. data/.github/SECURITY.md +0 -35
  78. data/.github/workflows/ci.yml +0 -26
  79. data/.gitignore +0 -23
  80. data/.rspec +0 -3
  81. data/.ruby-gemset +0 -1
  82. data/.ruby-version +0 -1
  83. data/.snyk +0 -10
  84. data/.travis.yml +0 -25
  85. data/CONTRIBUTING.md +0 -270
  86. data/bin/recog_cleanup +0 -16
  87. data/bin/recog_export +0 -81
  88. data/bin/recog_standardize +0 -148
  89. data/bin/recog_verify +0 -64
  90. data/cpe-remap.yaml +0 -343
  91. data/features/data/failing_banners_fingerprints.xml +0 -20
  92. data/features/data/matching_banners_fingerprints.xml +0 -23
  93. data/features/data/multiple_banners_fingerprints.xml +0 -32
  94. data/features/data/no_tests.xml +0 -3
  95. data/features/data/sample_banner.txt +0 -2
  96. data/features/data/successful_tests.xml +0 -18
  97. data/features/data/tests_with_failures.xml +0 -20
  98. data/features/data/tests_with_warnings.xml +0 -17
  99. data/features/match.feature +0 -36
  100. data/features/support/aruba.rb +0 -3
  101. data/features/support/env.rb +0 -6
  102. data/features/verify.feature +0 -48
  103. data/identifiers/README.md +0 -70
  104. data/identifiers/fields.txt +0 -104
  105. data/identifiers/hw_device.txt +0 -78
  106. data/identifiers/hw_family.txt +0 -113
  107. data/identifiers/hw_product.txt +0 -410
  108. data/identifiers/os_architecture.txt +0 -10
  109. data/identifiers/os_device.txt +0 -75
  110. data/identifiers/os_family.txt +0 -233
  111. data/identifiers/os_product.txt +0 -340
  112. data/identifiers/service_family.txt +0 -249
  113. data/identifiers/service_product.txt +0 -752
  114. data/identifiers/vendor.txt +0 -798
  115. data/lib/recog/verifier_factory.rb +0 -13
  116. data/misc/convert_mysql_err +0 -61
  117. data/misc/order.xsl +0 -17
  118. data/requirements.txt +0 -2
  119. data/spec/lib/fingerprint_self_test_spec.rb +0 -174
  120. data/update_cpes.py +0 -250
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 972b7cc1ae69526b61f221eeefce61d192ccf4b1603342f94195bf6cd2ddba95
4
- data.tar.gz: 807831da5cdfd3160bca893367c92f4b817514758b996968829253f548d19709
3
+ metadata.gz: ca2e3909b1b60418e80721625975ab8025e8dcaaaee59754dccb128b25661f00
4
+ data.tar.gz: 68be49a8c47fc1bb2b6a0f64d02c18a8fc29b67ee60b62060542be2216979e5c
5
5
  SHA512:
6
- metadata.gz: a923e57f1f34fb74358756372fc3d3d08c20f0a0b9b1088905f57f4b09a2a56b2d9d4940d39e609ff50c164d15e285c9e1707032864d55f969a7ed4d72e68de5
7
- data.tar.gz: 62d17cd2cdf9c3a6d35b36e4ace9c20744d42cfd99a2e90f65e463540fceb551f35f7572179af261c8881116aeadc51986e371631dc451df31081d52d79a58c1
6
+ metadata.gz: 2e0f749e0a8b313a8ba9845c39aa72ce08108e4c5b4e3785d689ae9e726aeb72b31b23da6e1e4610fff4dcd1caad966ee9578ab887a425cf2f414ee377b7b001
7
+ data.tar.gz: 7714d9bca0d70f27efd756460f0f167a46c69ee45c38da8a70bdfb5271256decb92375c8281efe67529e5b7e3a897b3e3e2fc20b7a62075b12db9abf940635a6
data/LICENSE CHANGED
@@ -1,5 +1,5 @@
1
1
  Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
2
- Source: https://github.com/rapid7/recog
2
+ Source: https://github.com/rapid7/recog-ruby
3
3
 
4
4
  Files: *
5
5
  Copyright: 2014, Rapid7, Inc.
data/README.md CHANGED
@@ -1,41 +1,50 @@
1
- # Recog: A Recognition Framework
1
+ # Recog-Ruby: A Recognition Framework
2
2
 
3
3
  [![Gem Version](https://badge.fury.io/rb/recog.svg)](http://badge.fury.io/rb/recog)
4
- [![Build Status](https://travis-ci.org/rapid7/recog.svg?branch=master)](https://travis-ci.org/rapid7/recog)
4
+ [![CI Workflow](https://github.com/rapid7/recog-ruby/actions/workflows/ci.yml/badge.svg)](https://github.com/rapid7/recog-ruby/actions/workflows/ci.yml)
5
5
 
6
6
 
7
- Recog is a framework for identifying products, services, operating systems, and hardware by matching fingerprints against data returned from various network probes. Recog makes it simple to extract useful information from web server banners, snmp system description fields, and a whole lot more.
7
+ Recog is a framework for identifying products, services, operating systems, and hardware by matching fingerprints against data returned from various network probes. Recog makes it simple to extract useful information from web server banners, SNMP system description fields, and a whole lot more.
8
8
 
9
- Recog is open source, please see the [LICENSE](https://raw.githubusercontent.com/rapid7/recog/master/LICENSE) file for more information.
9
+ The Recog-Ruby repository contains the Ruby language implementation of the Recog recognition framework library and the [Recog](https://github.com/rapid7/recog) content, XML fingerprint files, as a git submodule. That makes it easy to develop, test, and use the contained fingerprints.
10
+
11
+ Recog-Ruby is open source, please see the [LICENSE](LICENSE) file for more information.
10
12
 
11
13
  ## Table of Contents
12
14
 
15
+ 1. [Repository split](#repository-split)
13
16
  1. [Installation](#installation)
14
17
  1. [Maturity](#maturity)
15
18
  1. [Fingerprints](#fingerprints)
16
19
  1. [Contributing](#contributing)
17
20
 
21
+ ## Repository split
22
+
23
+ On March 31, 2022, the Recog content - XML fingerprint files and utilities - were split from the Recog framework library implementation. The original [Recog](https://github.com/rapid7/recog) repository now contains the Recog content and the [Recog-Ruby](https://github.com/rapid7/recog-ruby) repository contains the Ruby language implementation. The Recog content is included in Recog-Ruby as a git submodule and is nested under the `recog` directory. All post-split Recog gem versions equal or greater than 3.0.0 will: 1. contain the XML fingerprint directory under the `recog` directory, and 2. only include the `recog_match` tool since the other tools are focused on fingerprint management.
24
+
25
+ [^back to top](#recog-ruby-a-recognition-framework)
26
+
18
27
  ## Installation
19
28
 
20
- Recog consists of both XML fingerprint files and an assortment of code, mostly in Ruby, that makes it easy to develop, test, and use the contained fingerprints. In order to use the included ruby code, a recent version of Ruby (2.31+) is required, along with Rubygems and the `bundler` gem. Once these dependencies are in place, use the following commands to grab the latest source code and install any additional dependencies.
29
+ In order to use the included Ruby code, a recent version of Ruby (2.31+) is required, along with Rubygems and the `bundler` gem. Once these dependencies are in place, use the following commands to grab the latest source code and install any additional dependencies.
21
30
 
22
31
  ```shell
23
- $ git clone git@github.com:rapid7/recog.git
24
- $ cd recog
32
+ $ git clone --recurse-submodules git@github.com:rapid7/recog-ruby.git
33
+ $ cd recog-ruby
25
34
  $ bundle install
26
35
  ```
27
36
 
28
- [^back to top](#recog-a-recognition-framework)
37
+ [^back to top](#recog-ruby-a-recognition-framework)
29
38
 
30
39
  ## Maturity
31
40
 
32
- Please note that while the XML fingerprints themselves are quite stable and well-tested, the Ruby codebase in Recog is still fairly new and subject to change quickly. Please contact us (research[at]rapid7.com) before leveraging the Recog code within any production projects.
41
+ Please note that while the XML fingerprints themselves are quite stable and well-tested, the Ruby codebase is still fairly new and subject to change quickly. Please contact us (research[at]rapid7.com) before leveraging the Recog code within any production projects.
33
42
 
34
- [^back to top](#recog-a-recognition-framework)
43
+ [^back to top](#recog-ruby-a-recognition-framework)
35
44
 
36
45
  ## Fingerprints
37
46
 
38
- The fingerprints within Recog are stored in XML files, each of which is designed to match a specific protocol response string or field. For example, the file [ssh_banners.xml](https://github.com/rapid7/recog/blob/master/xml/ssh_banners.xml) can determine the os, vendor, and sometimes hardware product by matching the initial SSH daemon banner string.
47
+ The fingerprints within [Recog](https://github.com/rapid7/recog) are stored in XML files, each of which is designed to match a specific protocol response string or field. For example, the file [ssh_banners.xml](https://github.com/rapid7/recog/blob/master/xml/ssh_banners.xml) can determine the os, vendor, and sometimes hardware product by matching the initial SSH daemon banner string.
39
48
 
40
49
  A fingerprint file consists of an XML document like the following:
41
50
 
@@ -69,19 +78,36 @@ The `param` elements contain a `pos` attribute, which indicates what capture fie
69
78
 
70
79
  The `example` string can be base64 encoded to permit the use of unprintable characters. To signal this to Recog an `_encoding` attribute with the value of `base64` is added to the `example` element. Based64 encoded text that is longer than 80 characters may be wrapped with newlines as shown below to aid in readability.
71
80
 
72
- ````xml
81
+ ```xml
73
82
  <example _encoding="base64">
74
83
  dGllczGEAAAAlQQWMS4yLjg0MC4xMTM1NTYuMS40LjgwMAQuZGF0YS5yZW1vdmVkLjCEAAAAK
75
84
  AQdZG9tYWluQ29udHJvbGxlckZ1bmN0aW9uYWxpdHkxhAAAAAMEATc=
76
85
  </example>
77
- ````
86
+ ```
87
+
88
+ Additionally, examples can be placed in a directory with the same base name as the XML file, in the same directory as the XML file:
89
+
90
+ ```
91
+ xml/services.xml
92
+ xml/services/file1
93
+ xml/services/file2
94
+ ...
95
+ ```
96
+
97
+ They can then be loaded using the `_filename` attribute:
98
+
99
+ ```xml
100
+ <example _filename="file1"/>
101
+ ```
102
+
103
+ This is useful for long examples.
78
104
 
79
- [^back to top](#recog-a-recognition-framework)
105
+ [^back to top](#recog-ruby-a-recognition-framework)
80
106
 
81
107
  ## Contributing
82
108
 
83
- The users and maintainers of Recog would greatly appreciate any contributions
109
+ The users and maintainers of Recog-Ruby would greatly appreciate any contributions
84
110
  you can make to the project. For guidelines and instructions please see
85
111
  [CONTRIBUTING.MD](CONTRIBUTING.md)
86
112
 
87
- [^back to top](#recog-a-recognition-framework)
113
+ [^back to top](#recog-ruby-a-recognition-framework)
data/Rakefile CHANGED
@@ -2,7 +2,7 @@ require "bundler/gem_tasks"
2
2
 
3
3
  require 'rspec/core/rake_task'
4
4
  RSpec::Core::RakeTask.new do |t|
5
- t.pattern = "spec/**/*_spec.rb"
5
+ t.pattern = ['spec/**/*_spec.rb', 'recog/spec/**/*_spec.rb']
6
6
  end
7
7
 
8
8
  require 'yard'
@@ -11,12 +11,5 @@ YARD::Rake::YardocTask.new do |t|
11
11
  t.files = ['lib/**/*.rb', '-', 'README.md']
12
12
  end
13
13
 
14
- require 'cucumber'
15
- require 'cucumber/rake/task'
16
-
17
- Cucumber::Rake::Task.new(:features) do |t|
18
- t.cucumber_opts = "features --format pretty"
19
- end
20
-
21
14
  task :default => [ :tests, :yard ]
22
- task :tests => [ :spec, :features ]
15
+ task :tests => [ :spec ]
data/lib/recog/db.rb CHANGED
@@ -66,10 +66,11 @@ class DB
66
66
 
67
67
  end
68
68
 
69
+ filepath = self.path.sub(/\.xml$/, '')
69
70
  @match_key = File.basename(self.path).sub(/\.xml$/, '') unless @match_key
70
71
 
71
72
  xml.xpath('/fingerprints/fingerprint').each do |fprint|
72
- @fingerprints << Fingerprint.new(fprint, @match_key, @protocol)
73
+ @fingerprints << Fingerprint.new(fprint, @match_key, @protocol, filepath)
73
74
  end
74
75
 
75
76
  xml = nil
@@ -5,7 +5,7 @@ class DBManager
5
5
 
6
6
  attr_accessor :path, :databases
7
7
 
8
- DefaultDatabasePath = File.expand_path( File.join( File.dirname(__FILE__), "..", "..", "xml") )
8
+ DefaultDatabasePath = File.expand_path(File.join(File.expand_path(__dir__), ["..", "..", "recog", "xml"]))
9
9
 
10
10
  def initialize(path = DefaultDatabasePath)
11
11
  self.path = path
@@ -5,6 +5,7 @@ module Recog
5
5
  class Fingerprint
6
6
  require 'set'
7
7
 
8
+ require 'recog/fingerprint_parse_error'
8
9
  require 'recog/fingerprint/regexp_factory'
9
10
  require 'recog/fingerprint/test'
10
11
 
@@ -28,19 +29,27 @@ class Fingerprint
28
29
  # @return (see #parse_examples)
29
30
  attr_reader :tests
30
31
 
32
+ # The line number of the XML entity in the source file for this
33
+ # fingerprint.
34
+ #
35
+ # @return [Integer] The line number of this entity.
36
+ attr_reader :line
37
+
31
38
  # @param xml [Nokogiri::XML::Element]
32
39
  # @param match_key [String] See Recog::DB
33
40
  # @param protocol [String] Protocol such as ftp, mssql, http, etc.
34
- def initialize(xml, match_key=nil, protocol=nil)
41
+ # @param example_path [String] Directory path for fingerprint example files
42
+ def initialize(xml, match_key=nil, protocol=nil, example_path=nil)
35
43
  @match_key = match_key
36
44
  @protocol = protocol
37
45
  @name = parse_description(xml)
38
46
  @regex = create_regexp(xml)
47
+ @line = xml.line
39
48
  @params = {}
40
49
  @tests = []
41
50
 
42
51
  @protocol.downcase! if @protocol
43
- parse_examples(xml)
52
+ parse_examples(xml, example_path)
44
53
  parse_params(xml)
45
54
  end
46
55
 
@@ -160,6 +169,7 @@ class Fingerprint
160
169
  # look for the presence of test cases
161
170
  if tests.size == 0
162
171
  yield :warn, "'#{@name}' has no test cases"
172
+ return
163
173
  end
164
174
 
165
175
  # make sure each test case passes
@@ -176,6 +186,7 @@ class Fingerprint
176
186
  # out correctly and match the capture group values we expect.
177
187
  test.attributes.each do |k, v|
178
188
  next if k == '_encoding'
189
+ next if k == '_filename'
179
190
  if !result.has_key?(k) || result[k] != v
180
191
  message = "'#{@name}' failed to find expected capture group #{k} '#{v}'. Result was #{result[k]}"
181
192
  status = :fail
@@ -223,8 +234,8 @@ class Fingerprint
223
234
  capture_group_used.each do |param_name, param_used|
224
235
  if !param_used
225
236
  message = "'#{@name}' is missing an example that checks for parameter '#{param_name}' " +
226
- "messsage which is derived from a capture group"
227
- yield :warn, message
237
+ "which is derived from a capture group"
238
+ yield :fail, message
228
239
  end
229
240
  end
230
241
  end
@@ -247,14 +258,30 @@ class Fingerprint
247
258
  end
248
259
 
249
260
  # @param xml [Nokogiri::XML::Element]
261
+ # @param example_path [String] Directory path for fingerprint example files
250
262
  # @return [void]
251
- def parse_examples(xml)
263
+ def parse_examples(xml, example_path)
252
264
  elements = xml.xpath('example')
253
265
 
254
266
  elements.each do |elem|
255
267
  # convert nokogiri Attributes into a hash of name => value
256
268
  attrs = elem.attributes.values.reduce({}) { |a,e| a.merge(e.name => e.value) }
257
- @tests << Test.new(elem.content, attrs)
269
+ if attrs["_filename"]
270
+ contents = ""
271
+ filename = attrs["_filename"]
272
+ fn = File.expand_path(File.join(example_path, filename))
273
+ unless fn.start_with?(File.expand_path(example_path) + File::Separator)
274
+ raise FingerprintParseError.new("an example specifies an illegal file path '#{filename}'", line_number = @line)
275
+ end
276
+
277
+ File.open(fn, "rb") do |file|
278
+ contents = file.read
279
+ contents.force_encoding(Encoding::ASCII_8BIT)
280
+ end
281
+ @tests << Test.new(contents, attrs)
282
+ else
283
+ @tests << Test.new(elem.content, attrs)
284
+ end
258
285
  end
259
286
 
260
287
  nil
@@ -0,0 +1,10 @@
1
+ module Recog
2
+ class FingerprintParseError < StandardError
3
+ attr_reader :line_number
4
+
5
+ def initialize(msg, line_number=nil)
6
+ @line_number = line_number
7
+ super(msg)
8
+ end
9
+ end
10
+ end
@@ -1,23 +1,23 @@
1
1
  module Recog
2
2
  class Verifier
3
- attr_reader :fingerprints, :reporter
3
+ attr_reader :db, :reporter
4
4
 
5
- def initialize(fingerprints, reporter)
6
- @fingerprints = fingerprints
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 "WARN: #{message}"
18
+ reporter.warning message, fp.line
19
19
  when :fail
20
- reporter.failure "FAIL: #{message}"
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 "WARN: #{message}"
28
+ reporter.warning message, fp.line
29
29
  when :fail
30
- reporter.failure "FAIL: #{message}"
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
@@ -1,3 +1,3 @@
1
1
  module Recog
2
- VERSION = '2.3.21'
2
+ VERSION = '3.0.1'
3
3
  end
@@ -1,6 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- $:.unshift(File.expand_path(File.join(File.dirname(__FILE__), "..", "lib")))
4
3
  require 'optparse'
5
4
  require 'ostruct'
6
5
  require 'recog'
File without changes