pmdtester 1.0.0.pre.beta2 → 1.1.1
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/.ci/build.sh +67 -0
- data/.ci/files/env.gpg +1 -0
- data/.ci/inc/install-openjdk.inc +26 -0
- data/.ci/manual-integration-tests.sh +20 -0
- data/.github/workflows/build.yml +39 -0
- data/.github/workflows/manual-integration-tests.yml +32 -0
- data/.gitignore +9 -0
- data/.hoerc +1 -0
- data/.rubocop.yml +21 -2
- data/.rubocop_todo.yml +7 -8
- data/.ruby-version +1 -0
- data/Gemfile +1 -13
- data/History.md +108 -0
- data/Manifest.txt +60 -0
- data/README.rdoc +130 -7
- data/Rakefile +31 -17
- data/bin/pmdtester +1 -1
- data/config/all-java.xml +1 -1
- data/config/design.xml +1 -1
- data/config/projectlist_1_0_0.xsd +2 -1
- data/config/projectlist_1_1_0.xsd +31 -0
- data/lib/pmdtester.rb +48 -0
- data/lib/pmdtester/builders/liquid_renderer.rb +73 -0
- data/lib/pmdtester/builders/pmd_report_builder.rb +133 -64
- data/lib/pmdtester/builders/project_builder.rb +100 -0
- data/lib/pmdtester/builders/project_hasher.rb +126 -0
- data/lib/pmdtester/builders/rule_set_builder.rb +95 -51
- data/lib/pmdtester/builders/simple_progress_logger.rb +27 -0
- data/lib/pmdtester/builders/summary_report_builder.rb +62 -120
- data/lib/pmdtester/cmd.rb +15 -1
- data/lib/pmdtester/collection_by_file.rb +55 -0
- data/lib/pmdtester/parsers/options.rb +33 -10
- data/lib/pmdtester/parsers/pmd_report_document.rb +79 -29
- data/lib/pmdtester/parsers/projects_parser.rb +2 -6
- data/lib/pmdtester/pmd_branch_detail.rb +36 -13
- data/lib/pmdtester/pmd_configerror.rb +62 -0
- data/lib/pmdtester/pmd_error.rb +34 -34
- data/lib/pmdtester/pmd_report_detail.rb +10 -13
- data/lib/pmdtester/pmd_tester_utils.rb +57 -0
- data/lib/pmdtester/pmd_violation.rb +66 -26
- data/lib/pmdtester/project.rb +28 -25
- data/lib/pmdtester/report_diff.rb +194 -70
- data/lib/pmdtester/resource_locator.rb +4 -0
- data/lib/pmdtester/runner.rb +82 -57
- data/pmdtester.gemspec +64 -0
- data/resources/_includes/diff_pill_row.html +6 -0
- data/resources/css/bootstrap.min.css +7 -0
- data/resources/css/datatables.min.css +36 -0
- data/resources/css/pmd-tester.css +131 -0
- data/resources/js/bootstrap.min.js +7 -0
- data/resources/js/code-snippets.js +66 -0
- data/resources/js/datatables.min.js +726 -0
- data/resources/js/jquery-3.2.1.slim.min.js +4 -0
- data/resources/js/jquery.min.js +2 -0
- data/resources/js/popper.min.js +5 -0
- data/resources/js/project-report.js +136 -0
- data/resources/project_diff_report.html +205 -0
- data/resources/project_index.html +102 -0
- metadata +117 -44
- data/.travis.yml +0 -22
- data/lib/pmdtester/builders/diff_builder.rb +0 -35
- data/lib/pmdtester/builders/diff_report_builder.rb +0 -226
- data/lib/pmdtester/builders/html_report_builder.rb +0 -34
- data/lib/pmdtester/pmdtester.rb +0 -17
- data/resources/css/maven-base.css +0 -155
- data/resources/css/maven-theme.css +0 -171
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require 'nokogiri'
|
|
4
|
-
require_relative '../project'
|
|
5
|
-
require_relative '../resource_locator'
|
|
6
4
|
|
|
7
5
|
module PmdTester
|
|
8
6
|
# The ProjectsParser is a class responsible of parsing
|
|
@@ -13,9 +11,7 @@ module PmdTester
|
|
|
13
11
|
document = Nokogiri::XML(File.read(list_file))
|
|
14
12
|
|
|
15
13
|
errors = schema.validate(document)
|
|
16
|
-
unless errors.empty?
|
|
17
|
-
raise ProjectsParserException.new(errors), "Schema validate failed: In #{list_file}"
|
|
18
|
-
end
|
|
14
|
+
raise ProjectsParserException.new(errors), "Schema validate failed: In #{list_file}" unless errors.empty?
|
|
19
15
|
|
|
20
16
|
projects = []
|
|
21
17
|
document.xpath('//project').each do |project|
|
|
@@ -25,7 +21,7 @@ module PmdTester
|
|
|
25
21
|
end
|
|
26
22
|
|
|
27
23
|
def schema_file_path
|
|
28
|
-
ResourceLocator.locate('config/
|
|
24
|
+
ResourceLocator.locate('config/projectlist_1_1_0.xsd')
|
|
29
25
|
end
|
|
30
26
|
end
|
|
31
27
|
|
|
@@ -1,16 +1,20 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require 'json'
|
|
4
|
-
require_relative './pmd_report_detail'
|
|
5
4
|
|
|
6
5
|
module PmdTester
|
|
7
6
|
# This class represents all details about branch of pmd
|
|
8
7
|
class PmdBranchDetail
|
|
8
|
+
include PmdTester
|
|
9
|
+
|
|
9
10
|
attr_accessor :branch_last_sha
|
|
10
11
|
attr_accessor :branch_last_message
|
|
11
12
|
attr_accessor :branch_name
|
|
12
13
|
# The branch's execution time on all standard projects
|
|
13
14
|
attr_accessor :execution_time
|
|
15
|
+
attr_accessor :jdk_version
|
|
16
|
+
attr_accessor :language
|
|
17
|
+
attr_accessor :pull_request
|
|
14
18
|
|
|
15
19
|
def self.branch_filename(branch_name)
|
|
16
20
|
branch_name&.tr('/', '_')
|
|
@@ -23,32 +27,51 @@ module PmdTester
|
|
|
23
27
|
branch_filename = PmdBranchDetail.branch_filename(branch_name)
|
|
24
28
|
@base_branch_dir = "target/reports/#{branch_filename}" unless @branch_name.nil?
|
|
25
29
|
@execution_time = 0
|
|
30
|
+
# the result of command 'java -version' is going to stderr
|
|
31
|
+
@jdk_version = Cmd.stderr_of('java -version')
|
|
32
|
+
@language = ENV['LANG'] # the locale
|
|
33
|
+
|
|
34
|
+
prnum = ENV[PR_NUM_ENV_VAR]
|
|
35
|
+
@pull_request = prnum == 'false' ? nil : prnum
|
|
26
36
|
end
|
|
27
37
|
|
|
28
|
-
def load
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
hash
|
|
38
|
+
def self.load(branch_name, logger)
|
|
39
|
+
details = PmdBranchDetail.new(branch_name)
|
|
40
|
+
if File.exist?(details.path_to_save_file)
|
|
41
|
+
hash = JSON.parse(File.read(details.path_to_save_file))
|
|
42
|
+
details.branch_last_sha = hash['branch_last_sha']
|
|
43
|
+
details.branch_last_message = hash['branch_last_message']
|
|
44
|
+
details.branch_name = hash['branch_name']
|
|
45
|
+
details.execution_time = hash['execution_time']
|
|
46
|
+
details.jdk_version = hash['jdk_version']
|
|
47
|
+
details.language = hash['language']
|
|
48
|
+
details.pull_request = hash['pull_request']
|
|
36
49
|
else
|
|
37
|
-
|
|
50
|
+
details.jdk_version = ''
|
|
51
|
+
details.language = ''
|
|
52
|
+
logger&.warn "#{details.path_to_save_file} doesn't exist!"
|
|
38
53
|
end
|
|
54
|
+
details
|
|
39
55
|
end
|
|
40
56
|
|
|
41
57
|
def save
|
|
42
58
|
hash = { branch_last_sha: @branch_last_sha,
|
|
43
59
|
branch_last_message: @branch_last_message,
|
|
44
60
|
branch_name: @branch_name,
|
|
45
|
-
execution_time: @execution_time
|
|
46
|
-
|
|
61
|
+
execution_time: @execution_time,
|
|
62
|
+
jdk_version: @jdk_version,
|
|
63
|
+
language: @language,
|
|
64
|
+
pull_request: @pull_request }
|
|
65
|
+
|
|
66
|
+
FileUtils.mkdir_p(@base_branch_dir) unless File.directory?(@base_branch_dir)
|
|
67
|
+
|
|
68
|
+
file = File.new(path_to_save_file, 'w')
|
|
47
69
|
file.puts JSON.generate(hash)
|
|
48
70
|
file.close
|
|
71
|
+
self
|
|
49
72
|
end
|
|
50
73
|
|
|
51
|
-
def
|
|
74
|
+
def path_to_save_file
|
|
52
75
|
"#{@base_branch_dir}/branch_info.json"
|
|
53
76
|
end
|
|
54
77
|
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module PmdTester
|
|
4
|
+
# This class represents a 'configerror' element of Pmd xml report
|
|
5
|
+
# and which Pmd branch the 'configerror' is from
|
|
6
|
+
class PmdConfigError
|
|
7
|
+
# The pmd branch type, 'base' or 'patch'
|
|
8
|
+
attr_reader :branch
|
|
9
|
+
|
|
10
|
+
# The schema of 'configerror' node:
|
|
11
|
+
# <xs:complexType name="configerror">
|
|
12
|
+
# <xs:attribute name="rule" type="xs:string" use="required" />
|
|
13
|
+
# <xs:attribute name="msg" type="xs:string" use="required" />
|
|
14
|
+
# </xs:complexType>
|
|
15
|
+
attr_reader :attrs
|
|
16
|
+
attr_accessor :old_error
|
|
17
|
+
|
|
18
|
+
def initialize(attrs, branch)
|
|
19
|
+
@attrs = attrs
|
|
20
|
+
|
|
21
|
+
@changed = false
|
|
22
|
+
@branch = branch
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def rulename
|
|
26
|
+
@attrs['rule']
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def msg
|
|
30
|
+
@attrs['msg']
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def sort_key
|
|
34
|
+
rulename
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def changed?
|
|
38
|
+
@changed
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def eql?(other)
|
|
42
|
+
rulename.eql?(other.rulename) && msg.eql?(other.msg)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def try_merge?(other)
|
|
46
|
+
if branch != BASE &&
|
|
47
|
+
branch != other.branch &&
|
|
48
|
+
rulename == other.rulename &&
|
|
49
|
+
!changed? # not already changed
|
|
50
|
+
@changed = true
|
|
51
|
+
@old_error = other
|
|
52
|
+
true
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
false
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def hash
|
|
59
|
+
[rulename, msg].hash
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
data/lib/pmdtester/pmd_error.rb
CHANGED
|
@@ -1,30 +1,10 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module PmdTester
|
|
4
|
-
# This class is used to store pmd errors and its size.
|
|
5
|
-
class PmdErrors
|
|
6
|
-
attr_reader :errors
|
|
7
|
-
attr_reader :errors_size
|
|
8
|
-
|
|
9
|
-
def initialize
|
|
10
|
-
# key:filename as String => value:PmdError Array
|
|
11
|
-
@errors = {}
|
|
12
|
-
@errors_size = 0
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
def add_error_by_filename(filename, error)
|
|
16
|
-
if @errors.key?(filename)
|
|
17
|
-
@errors[filename].push(error)
|
|
18
|
-
else
|
|
19
|
-
@errors.store(filename, [error])
|
|
20
|
-
end
|
|
21
|
-
@errors_size += 1
|
|
22
|
-
end
|
|
23
|
-
end
|
|
24
|
-
|
|
25
4
|
# This class represents a 'error' element of Pmd xml report
|
|
26
5
|
# and which Pmd branch the 'error' is from
|
|
27
6
|
class PmdError
|
|
7
|
+
include PmdTester
|
|
28
8
|
# The pmd branch type, 'base' or 'patch'
|
|
29
9
|
attr_reader :branch
|
|
30
10
|
|
|
@@ -37,31 +17,51 @@ module PmdTester
|
|
|
37
17
|
# </xs:extension>
|
|
38
18
|
# </xs:simpleContent>
|
|
39
19
|
# </xs:complexType>
|
|
40
|
-
|
|
41
|
-
attr_accessor :
|
|
42
|
-
|
|
43
|
-
def initialize(attrs, branch)
|
|
44
|
-
@attrs = attrs
|
|
20
|
+
attr_accessor :stack_trace
|
|
21
|
+
attr_accessor :old_error
|
|
22
|
+
attr_reader :filename, :short_message
|
|
45
23
|
|
|
24
|
+
def initialize(branch:, filename:, short_message:)
|
|
46
25
|
@branch = branch
|
|
47
|
-
@
|
|
26
|
+
@stack_trace = ''
|
|
27
|
+
@changed = false
|
|
28
|
+
@short_message = short_message
|
|
29
|
+
@filename = filename
|
|
48
30
|
end
|
|
49
31
|
|
|
50
|
-
def
|
|
51
|
-
|
|
32
|
+
def short_filename
|
|
33
|
+
filename.gsub(%r{([^/]*+/)+}, '')
|
|
52
34
|
end
|
|
53
35
|
|
|
54
|
-
def
|
|
55
|
-
@
|
|
36
|
+
def changed?
|
|
37
|
+
@changed
|
|
56
38
|
end
|
|
57
39
|
|
|
58
40
|
def eql?(other)
|
|
59
|
-
filename.eql?(other.filename) &&
|
|
60
|
-
|
|
41
|
+
filename.eql?(other.filename) &&
|
|
42
|
+
short_message.eql?(other.short_message) &&
|
|
43
|
+
stack_trace.eql?(other.stack_trace)
|
|
61
44
|
end
|
|
62
45
|
|
|
63
46
|
def hash
|
|
64
|
-
[filename,
|
|
47
|
+
[filename, stack_trace].hash
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def sort_key
|
|
51
|
+
filename
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def try_merge?(other)
|
|
55
|
+
if branch != BASE &&
|
|
56
|
+
branch != other.branch &&
|
|
57
|
+
filename == other.filename &&
|
|
58
|
+
!changed? # not already changed
|
|
59
|
+
@changed = true
|
|
60
|
+
@old_error = other
|
|
61
|
+
true
|
|
62
|
+
else
|
|
63
|
+
false
|
|
64
|
+
end
|
|
65
65
|
end
|
|
66
66
|
end
|
|
67
67
|
end
|
|
@@ -7,12 +7,12 @@ module PmdTester
|
|
|
7
7
|
class PmdReportDetail
|
|
8
8
|
attr_accessor :execution_time
|
|
9
9
|
attr_accessor :timestamp
|
|
10
|
-
|
|
10
|
+
attr_accessor :working_dir
|
|
11
11
|
|
|
12
|
-
def initialize
|
|
13
|
-
@execution_time =
|
|
14
|
-
@timestamp =
|
|
15
|
-
@working_dir =
|
|
12
|
+
def initialize(execution_time: 0, timestamp: '', working_dir: Dir.getwd)
|
|
13
|
+
@execution_time = execution_time
|
|
14
|
+
@timestamp = timestamp
|
|
15
|
+
@working_dir = working_dir
|
|
16
16
|
end
|
|
17
17
|
|
|
18
18
|
def save(report_info_path)
|
|
@@ -22,16 +22,13 @@ module PmdTester
|
|
|
22
22
|
file.close
|
|
23
23
|
end
|
|
24
24
|
|
|
25
|
-
def load(report_info_path)
|
|
25
|
+
def self.load(report_info_path)
|
|
26
26
|
if File.exist?(report_info_path)
|
|
27
|
-
hash = JSON.parse(File.read(report_info_path))
|
|
28
|
-
|
|
29
|
-
@timestamp = hash['timestamp']
|
|
30
|
-
@working_dir = hash['working_dir']
|
|
31
|
-
hash
|
|
27
|
+
hash = JSON.parse(File.read(report_info_path), symbolize_names: true)
|
|
28
|
+
PmdReportDetail.new(**hash)
|
|
32
29
|
else
|
|
33
|
-
|
|
34
|
-
|
|
30
|
+
PmdTester.logger.warn("#{report_info_path} doesn't exist")
|
|
31
|
+
PmdReportDetail.new
|
|
35
32
|
end
|
|
36
33
|
end
|
|
37
34
|
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module PmdTester
|
|
4
|
+
# Some functions that that don't belong in a specific class,
|
|
5
|
+
module PmdTesterUtils
|
|
6
|
+
include PmdTester
|
|
7
|
+
|
|
8
|
+
# Parse the base and the patch report, compute their diff
|
|
9
|
+
# Returns a +ReportDiff+
|
|
10
|
+
def build_report_diff(base_report_file, patch_report_file, base_info, patch_info, filter_set = nil)
|
|
11
|
+
base_details = PmdReportDetail.load(base_info)
|
|
12
|
+
patch_details = PmdReportDetail.load(patch_info)
|
|
13
|
+
|
|
14
|
+
base_report = parse_pmd_report(base_report_file, BASE, base_details, filter_set)
|
|
15
|
+
patch_report = parse_pmd_report(patch_report_file, PATCH, patch_details)
|
|
16
|
+
|
|
17
|
+
logger.info 'Calculating diffs'
|
|
18
|
+
ReportDiff.new(base_report: base_report, patch_report: patch_report)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# Parse the +report_file+ to produce a +Report+.
|
|
22
|
+
# For the schema of xml reports, refer to http://pmd.sourceforge.net/report_2_0_0.xsd
|
|
23
|
+
def parse_pmd_report(report_file, branch, report_details, filter_set = nil)
|
|
24
|
+
require 'nokogiri'
|
|
25
|
+
|
|
26
|
+
logger.info "Parsing #{report_file}"
|
|
27
|
+
doc = PmdReportDocument.new(branch, report_details.working_dir, filter_set)
|
|
28
|
+
parser = Nokogiri::XML::SAX::Parser.new(doc)
|
|
29
|
+
parser.parse_file(report_file) if File.exist?(report_file)
|
|
30
|
+
Report.new(
|
|
31
|
+
report_document: doc,
|
|
32
|
+
|
|
33
|
+
timestamp: report_details.timestamp,
|
|
34
|
+
exec_time: report_details.execution_time
|
|
35
|
+
)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# Fill the report_diff field of every project
|
|
39
|
+
def compute_project_diffs(projects, base_branch, patch_branch, filter_set = nil)
|
|
40
|
+
projects.each do |project|
|
|
41
|
+
logger.info "Preparing report for #{project.name}"
|
|
42
|
+
logger.info " with filter #{filter_set}" unless filter_set.nil?
|
|
43
|
+
project.compute_report_diff(base_branch, patch_branch, filter_set)
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# Build the diff reports and write them all
|
|
48
|
+
def build_html_reports(projects, base_branch_details, patch_branch_details, filter_set = nil)
|
|
49
|
+
compute_project_diffs(projects, base_branch_details.branch_name, patch_branch_details.branch_name,
|
|
50
|
+
filter_set)
|
|
51
|
+
|
|
52
|
+
SummaryReportBuilder.new.write_all_projects(projects,
|
|
53
|
+
base_branch_details,
|
|
54
|
+
patch_branch_details)
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
@@ -1,23 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module PmdTester
|
|
4
|
-
# This class is used to store pmd violations and its size.
|
|
5
|
-
class PmdViolations
|
|
6
|
-
attr_reader :violations
|
|
7
|
-
attr_reader :violations_size
|
|
8
|
-
|
|
9
|
-
def initialize
|
|
10
|
-
# key:filename as String => value:PmdViolation Array
|
|
11
|
-
@violations = {}
|
|
12
|
-
@violations_size = 0
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
def add_violations_by_filename(filename, violations)
|
|
16
|
-
@violations.store(filename, violations)
|
|
17
|
-
@violations_size += violations.size
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
|
-
|
|
21
4
|
# This class represents a 'violation' element of Pmd xml report
|
|
22
5
|
# and which pmd branch the 'violation' is from
|
|
23
6
|
class PmdViolation
|
|
@@ -44,23 +27,80 @@ module PmdTester
|
|
|
44
27
|
# </xs:simpleContent>
|
|
45
28
|
# </xs:complexType>
|
|
46
29
|
|
|
47
|
-
attr_reader :
|
|
48
|
-
attr_accessor :
|
|
30
|
+
attr_reader :fname, :info_url, :line, :old_line, :old_message, :rule_name, :ruleset_name
|
|
31
|
+
attr_accessor :message
|
|
49
32
|
|
|
50
|
-
|
|
51
|
-
|
|
33
|
+
# rubocop:disable Metrics/ParameterLists
|
|
34
|
+
# Disable it: how is replacing a long parameter list with a single hash helping?
|
|
35
|
+
def initialize(branch:, fname:, info_url:, bline:, rule_name:, ruleset_name:)
|
|
52
36
|
@branch = branch
|
|
53
|
-
@
|
|
37
|
+
@fname = fname
|
|
38
|
+
@message = ''
|
|
39
|
+
|
|
40
|
+
@info_url = info_url
|
|
41
|
+
@line = bline
|
|
42
|
+
@rule_name = rule_name
|
|
43
|
+
|
|
44
|
+
@ruleset_name = ruleset_name
|
|
45
|
+
|
|
46
|
+
@changed = false
|
|
47
|
+
@old_message = nil
|
|
48
|
+
@old_line = nil
|
|
49
|
+
end
|
|
50
|
+
# rubocop:enable Metrics/ParameterLists
|
|
51
|
+
|
|
52
|
+
def line_move?(other)
|
|
53
|
+
message.eql?(other.message) && (line - other.line).abs <= 5
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def try_merge?(other)
|
|
57
|
+
if branch != BASE && branch != other.branch && rule_name == other.rule_name &&
|
|
58
|
+
!changed? && # not already changed
|
|
59
|
+
(line == other.line || line_move?(other))
|
|
60
|
+
@changed = true
|
|
61
|
+
@old_message = other.message
|
|
62
|
+
@old_line = other.line
|
|
63
|
+
true
|
|
64
|
+
else
|
|
65
|
+
false
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# only makes sense if this is a diff
|
|
70
|
+
def added?
|
|
71
|
+
branch != BASE && !changed?
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# only makes sense if this is a diff
|
|
75
|
+
def changed?
|
|
76
|
+
@changed
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# only makes sense if this is a diff
|
|
80
|
+
def removed?
|
|
81
|
+
branch == BASE
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def sort_key
|
|
85
|
+
line
|
|
54
86
|
end
|
|
55
87
|
|
|
56
88
|
def eql?(other)
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
89
|
+
rule_name.eql?(other.rule_name) &&
|
|
90
|
+
line.eql?(other.line) &&
|
|
91
|
+
fname.eql?(other.fname) &&
|
|
92
|
+
message.eql?(other.message)
|
|
60
93
|
end
|
|
61
94
|
|
|
62
95
|
def hash
|
|
63
|
-
[
|
|
96
|
+
[line, rule_name, message].hash
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def to_liquid
|
|
100
|
+
{
|
|
101
|
+
'branch' => branch,
|
|
102
|
+
'changed' => changed?
|
|
103
|
+
}
|
|
64
104
|
end
|
|
65
105
|
end
|
|
66
106
|
end
|