danger-jacoco-instacart 0.1.9

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 3d530223d70949352c71cbbe7a3dbc9b0d115be972c1d552b21db2038d087f95
4
+ data.tar.gz: d1d13f2a765308281c73c09d5d0be71e43b891105e7e282c2b875ca858b3b048
5
+ SHA512:
6
+ metadata.gz: 36934680ed93f9ce29accbce38a1ce77471dd75eaf198ef96738f274b6d8edb05440beca43f500cedd99df42687c3b792b480784543686b4fedfff3f3eebf26d
7
+ data.tar.gz: 2a38f6f4ee1cfaf21301e2f1b5a36073eef9d26aa46ab3c4bae5cba03157e5602771333232e8d9366eb5aa74d3d8df7e1cf7131169414595944d6a96e084c82e
@@ -0,0 +1,20 @@
1
+ version: 2
2
+ updates:
3
+ - package-ecosystem: bundler
4
+ directory: "/"
5
+ schedule:
6
+ interval: weekly
7
+ time: "19:00"
8
+ open-pull-requests-limit: 10
9
+ ignore:
10
+ - dependency-name: listen
11
+ versions:
12
+ - 3.4.1
13
+ - 3.5.0
14
+ - dependency-name: rubocop
15
+ versions:
16
+ - 1.10.0
17
+ - 1.11.0
18
+ - 1.12.0
19
+ - 1.8.1
20
+ - 1.9.1
@@ -0,0 +1,13 @@
1
+ name: ci
2
+ on: [push]
3
+ jobs:
4
+ test:
5
+ runs-on: ubuntu-18.04
6
+ steps:
7
+ - uses: actions/checkout@v1
8
+ - uses: actions/setup-ruby@v1
9
+ with:
10
+ ruby-version: '2.6.x'
11
+ - run: gem install bundler
12
+ - run: bundle install
13
+ - run: bundle exec rake spec
@@ -0,0 +1,23 @@
1
+ name: deploy-release
2
+ on:
3
+ push:
4
+ tags: '*'
5
+ jobs:
6
+ test:
7
+ runs-on: ubuntu-latest
8
+ steps:
9
+ - uses: actions/checkout@v1
10
+ - uses: actions/setup-ruby@v1
11
+ with:
12
+ ruby-version: '2.6.x'
13
+ - run: gem install bundler
14
+ - run: bundle install
15
+ - run: bundle exec rake spec
16
+ - name: setup credentials
17
+ env:
18
+ RUBYGEMS_API_KEY: ${{ secrets.RUBYGEMS_API_KEY }}
19
+ run: |
20
+ mkdir -p ~/.gem
21
+ echo -e "---\r\n:rubygems_api_key: $RUBYGEMS_API_KEY" > ~/.gem/credentials
22
+ chmod 0600 ~/.gem/credentials
23
+ - run: bundle exec rake release
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ .DS_Store
2
+ pkg
3
+ .idea/
4
+ Gemfile.lock
data/.rubocop.yml ADDED
@@ -0,0 +1,6 @@
1
+ Metrics/LineLength:
2
+ Max: 120
3
+ Metrics/MethodLength:
4
+ Max: 20
5
+ Metrics/AbcSize:
6
+ Max: 20
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ # Specify your gem's dependencies in danger-jacoco.gemspec
6
+ gemspec
data/Guardfile ADDED
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ # A guardfile for making Danger Plugins
4
+ # For more info see https://github.com/guard/guard#readme
5
+
6
+ # To run, use `bundle exec guard`.
7
+
8
+ guard :rspec, cmd: 'bundle exec rspec' do
9
+ require 'guard/rspec/dsl'
10
+ dsl = Guard::RSpec::Dsl.new(self)
11
+
12
+ # RSpec files
13
+ rspec = dsl.rspec
14
+ watch(rspec.spec_helper) { rspec.spec_dir }
15
+ watch(rspec.spec_support) { rspec.spec_dir }
16
+ watch(rspec.spec_files)
17
+
18
+ # Ruby files
19
+ ruby = dsl.ruby
20
+ dsl.watch_spec_files_for(ruby.lib_files)
21
+ end
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2016 Anton Malinskiy <anton@malinskiy.com>
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,38 @@
1
+ # danger-jacoco
2
+
3
+ **danger-jacoco** is the [Danger](https://github.com/danger/danger) plugin of
4
+ to validate the code coverage of the files changed
5
+
6
+ ## Installation
7
+
8
+ ```
9
+ sudo gem install danger-jacoco
10
+ ```
11
+
12
+ ## Usage
13
+
14
+ Add
15
+
16
+ ```ruby
17
+ jacoco.minimum_project_coverage_percentage = 50 # default 0
18
+ jacoco.minimum_package_coverage_map = { # optional (default is empty)
19
+ 'com/package/' => 55,
20
+ 'com/package/more/specific/' => 15
21
+ }
22
+ jacoco.minimum_class_coverage_map = { # optional (default is empty)
23
+ 'com/package/more/specific/ClassName' => 15
24
+ }
25
+ jacoco.minimum_class_coverage_percentage = 75 # default 0
26
+ jacoco.files_extension = [".java"] # default [".kt", ".java"]
27
+ jacoco.report("path/to/jacoco.xml", "http://jacoco-html-reports/")
28
+ ```
29
+
30
+ to your `Dangerfile`
31
+
32
+ ## Development
33
+
34
+ 1. Clone this repo
35
+ 2. Run `bundle install` to setup dependencies.
36
+ 3. Run `bundle exec rake spec` to run the tests.
37
+ 4. Use `bundle exec guard` to automatically have tests run as you make changes.
38
+ 5. Make your changes.
data/Rakefile ADDED
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/gem_tasks'
4
+ require 'rspec/core/rake_task'
5
+ require 'rubocop/rake_task'
6
+
7
+ RSpec::Core::RakeTask.new(:specs)
8
+
9
+ task default: :specs
10
+
11
+ task :spec do
12
+ Rake::Task['specs'].invoke
13
+ Rake::Task['rubocop'].invoke
14
+ Rake::Task['spec_docs'].invoke
15
+ end
16
+
17
+ desc 'Run RuboCop on the lib/specs directory'
18
+ RuboCop::RakeTask.new(:rubocop) do |task|
19
+ task.patterns = ['lib/**/*.rb', 'spec/**/*.rb']
20
+ end
21
+
22
+ desc 'Ensure that the plugin passes `danger plugins lint`'
23
+ task :spec_docs do
24
+ sh 'bundle exec danger plugins lint'
25
+ end
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ lib = File.expand_path('lib', __dir__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+ require 'jacoco/gem_version'
6
+
7
+ Gem::Specification.new do |spec|
8
+ spec.name = 'danger-jacoco-instacart'
9
+ spec.version = Jacoco::VERSION
10
+ spec.authors = ['Anton Malinskiy', 'Alexander Bezverhni']
11
+ spec.email = ['anton@malinskiy.com', 'bezverhni@gmail.com']
12
+ spec.description = 'A short description of danger-jacoco. This is a forked version of https://github.com/Malinskiy/danger-jacoco that suits Instacart needs.'
13
+ spec.summary = 'A longer description of danger-jacoco.'
14
+ spec.homepage = 'https://github.com/alexanderbezverhni/danger-jacoco'
15
+ spec.license = 'MIT'
16
+
17
+ spec.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
18
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
19
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
20
+ spec.require_paths = ['lib']
21
+ spec.required_ruby_version = '>= 2.6'
22
+
23
+ spec.add_runtime_dependency 'danger-plugin-api', '~> 1.0'
24
+ spec.add_runtime_dependency 'nokogiri-happymapper', '~> 0.6'
25
+
26
+ # General ruby development
27
+ spec.add_development_dependency 'bundler', '~> 2.0'
28
+ spec.add_development_dependency 'rake', '~> 13.0'
29
+
30
+ # Testing support
31
+ spec.add_development_dependency 'rspec', '~> 3.7'
32
+
33
+ # Linting code and docs
34
+ spec.add_development_dependency 'rubocop', '~> 1.14'
35
+ spec.add_development_dependency 'yard', '~> 0.9'
36
+
37
+ # Makes testing easy via `bundle exec guard`
38
+ spec.add_development_dependency 'guard', '~> 2.14'
39
+ spec.add_development_dependency 'guard-rspec', '~> 4.7'
40
+
41
+ # If you want to work on older builds of ruby
42
+ spec.add_development_dependency 'listen', '3.5.1'
43
+
44
+ # This gives you the chance to run a REPL inside your tests
45
+ # via:
46
+ #
47
+ # require 'pry'
48
+ # binding.pry
49
+ #
50
+ # This will stop test execution and let you inspect the results
51
+ spec.add_development_dependency 'pry'
52
+ end
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'jacoco/gem_version'
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'jacoco/plugin'
4
+
5
+ require 'jacoco/dom_parser'
6
+ require 'jacoco/model/class'
7
+ require 'jacoco/model/counter'
8
+ require 'jacoco/model/group'
9
+ require 'jacoco/model/method'
10
+ require 'jacoco/model/package'
11
+ require 'jacoco/model/report'
12
+ require 'jacoco/model/session_info'
13
+ require 'jacoco/model/sourcefile'
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Jacoco
4
+ # DOM parser for Jacoco report
5
+ class DOMParser
6
+ def self.read_path(path)
7
+ DOMParser.new.read_path(path)
8
+ end
9
+
10
+ def self.read_string(string)
11
+ DOMParser.new.read_string(string)
12
+ end
13
+
14
+ def read_path(path)
15
+ file = File.read(path)
16
+ read_string(file)
17
+ end
18
+
19
+ def read_string(string)
20
+ Report.parse(string)
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Jacoco
4
+ VERSION = '0.1.9'
5
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'happymapper'
4
+ require 'jacoco/model/counter'
5
+ require 'jacoco/model/method'
6
+
7
+ module Jacoco
8
+ # Jacoco Class model
9
+ class Class
10
+ include HappyMapper
11
+
12
+ tag 'class'
13
+
14
+ attribute :name, String
15
+
16
+ has_many :methods, Jacoco::Method, xpath: '.'
17
+ has_many :counters, Jacoco::Counter, xpath: '.'
18
+ end
19
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'happymapper'
4
+
5
+ module Jacoco
6
+ # Jacoco counter model
7
+ class Counter
8
+ include HappyMapper
9
+
10
+ tag 'counter'
11
+
12
+ attribute :type, String
13
+ attribute :missed, Integer
14
+ attribute :covered, Integer
15
+ end
16
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'happymapper'
4
+ require 'jacoco/model/group'
5
+ require 'jacoco/model/package'
6
+ require 'jacoco/model/counter'
7
+
8
+ module Jacoco
9
+ # Jacoco group model
10
+ class Group
11
+ include HappyMapper
12
+
13
+ tag 'group'
14
+
15
+ attribute :name, String
16
+ has_many :groups, Jacoco::Group, xpath: '.'
17
+ has_many :packages, Jacoco::Package, xpath: '.'
18
+ has_many :counters, Jacoco::Counter, xpath: '.'
19
+ end
20
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'happymapper'
4
+ require 'jacoco/model/counter'
5
+ require 'jacoco/model/method'
6
+
7
+ module Jacoco
8
+ # Jacoco line model
9
+ class Line
10
+ include HappyMapper
11
+
12
+ tag 'line'
13
+
14
+ attribute :line_number, Integer, tag: 'nr'
15
+ attribute :missed_instructions, Integer, tag: 'mi'
16
+ attribute :covered_instructions, Integer, tag: 'ci'
17
+ attribute :missed_branches, Integer, tag: 'mb'
18
+ attribute :covered_branches, Integer, tag: 'cb'
19
+ end
20
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'happymapper'
4
+ require 'jacoco/model/counter'
5
+
6
+ module Jacoco
7
+ # Jacoco method model
8
+ class Method
9
+ include HappyMapper
10
+
11
+ tag 'method'
12
+ attribute :name, String
13
+ attribute :desc, String
14
+ attribute :line, Integer
15
+
16
+ has_many :counters, Jacoco::Counter, xpath: '.'
17
+ end
18
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'happymapper'
4
+ require 'jacoco/model/class'
5
+ require 'jacoco/model/sourcefile'
6
+
7
+ module Jacoco
8
+ # Jacoco package model
9
+ class Package
10
+ include HappyMapper
11
+
12
+ tag 'package'
13
+
14
+ attribute :name, String
15
+ has_many :sourcefiles, Jacoco::Sourcefile, xpath: '.'
16
+ has_many :class_names, Jacoco::Class, xpath: '.'
17
+ has_many :counters, Jacoco::Counter, xpath: '.'
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'happymapper'
4
+ require 'jacoco/model/session_info'
5
+
6
+ module Jacoco
7
+ # Jacoco report model
8
+ class Report
9
+ include HappyMapper
10
+
11
+ tag 'report'
12
+ attribute :name, String
13
+
14
+ has_many :session_infos, Jacoco::SessionInfo, xpath: '.'
15
+ has_many :groups, Jacoco::Group, xpath: '.'
16
+ has_many :packages, Jacoco::Package, xpath: '.'
17
+ has_many :counters, Jacoco::Counter, xpath: '.'
18
+ end
19
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'happymapper'
4
+
5
+ module Jacoco
6
+ # Jacoco sessioninfo model
7
+ class SessionInfo
8
+ include HappyMapper
9
+
10
+ tag 'sessioninfo'
11
+
12
+ attribute :id, String
13
+ attribute :start, Integer
14
+ attribute :dump, Integer
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'happymapper'
4
+
5
+ module Jacoco
6
+ # Jacoco sourcefile model
7
+ class Sourcefile
8
+ include HappyMapper
9
+
10
+ tag 'sourcefile'
11
+
12
+ attribute :name, String
13
+
14
+ has_many :counters, Jacoco::Counter, xpath: '.'
15
+ end
16
+ end
@@ -0,0 +1,218 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'jacoco/sax_parser'
4
+
5
+ module Danger
6
+ # Verify code coverage inside your projects
7
+ # This is done using the jacoco output
8
+ # Results are passed out as a table in markdown
9
+ #
10
+ # @example Verify coverage
11
+ # jacoco.minimum_project_coverage_percentage = 50
12
+ #
13
+ # @example Verify coverage per package
14
+ # jacoco.minimum_package_coverage_map = { # optional (default is empty)
15
+ # 'com/package/' => 55,
16
+ # 'com/package/more/specific/' => 15
17
+ # }
18
+ #
19
+ # @see Anton Malinskiy/danger-jacoco
20
+ # @tags jacoco, coverage, java, android, kotlin
21
+ #
22
+ class DangerJacoco < Plugin # rubocop:disable Metrics/ClassLength
23
+ attr_accessor :minimum_project_coverage_percentage, :minimum_class_coverage_percentage, :files_extension,
24
+ :minimum_package_coverage_map, :minimum_class_coverage_map, :fail_no_coverage_data_found, :title
25
+
26
+ # Initialize the plugin with configured parameters or defaults
27
+ def setup
28
+ @minimum_project_coverage_percentage = 0 unless minimum_project_coverage_percentage
29
+ @minimum_class_coverage_percentage = 0 unless minimum_class_coverage_percentage
30
+ @minimum_package_coverage_map = {} unless minimum_package_coverage_map
31
+ @minimum_class_coverage_map = {} unless minimum_class_coverage_map
32
+ @files_extension = ['.kt', '.java'] unless files_extension
33
+ @title = 'JaCoCo' unless title
34
+ end
35
+
36
+ # Parses the xml output of jacoco to Ruby model classes
37
+ # This is slow since it's basically DOM parsing
38
+ #
39
+ # @path path to the xml output of jacoco
40
+ #
41
+ def parse(path)
42
+ Jacoco::DOMParser.read_path(path)
43
+ end
44
+
45
+ # This is a fast report based on SAX parser
46
+ #
47
+ # @path path to the xml output of jacoco
48
+ # @report_url URL where html report hosted
49
+ # @delimiter git.modified_files returns full paths to the
50
+ # changed files. We need to get the class from this path to check the
51
+ # Jacoco report,
52
+ #
53
+ # e.g. src/java/com/example/SomeJavaClass.java -> com/example/SomeJavaClass
54
+ # e.g. src/kotlin/com/example/SomeKotlinClass.kt -> com/example/SomeKotlinClass
55
+ #
56
+ # The default value supposes that you're using gradle structure,
57
+ # that is your path to source files is something like
58
+ #
59
+ # Java => blah/blah/java/slashed_package/Source.java
60
+ # Kotlin => blah/blah/kotlin/slashed_package/Source.kt
61
+ #
62
+ def report(path, report_url = '', delimiter = %r{/java/|/kotlin/}, fail_no_coverage_data_found: true)
63
+ @fail_no_coverage_data_found = fail_no_coverage_data_found
64
+
65
+ setup
66
+ classes = classes(delimiter)
67
+
68
+ parser = Jacoco::SAXParser.new(classes)
69
+ Nokogiri::XML::SAX::Parser.new(parser).parse(File.open(path))
70
+
71
+ total_covered = total_coverage(path)
72
+
73
+ report_markdown = "### #{title} Code Coverage #{total_covered[:covered]}% #{total_covered[:status]}\n"
74
+ report_markdown += "| Class | Covered | Meta | Status |\n"
75
+ report_markdown += "|:---|:---:|:---:|:---:|\n"
76
+ class_coverage_above_minimum = markdown_class(parser, report_markdown, report_url)
77
+ markdown(report_markdown)
78
+
79
+ report_fails(class_coverage_above_minimum, total_covered)
80
+ end
81
+
82
+ # Select modified and added files in this PR
83
+ def classes(delimiter)
84
+ git = @dangerfile.git
85
+ affected_files = git.modified_files + git.added_files
86
+ affected_files.select { |file| files_extension.reduce(false) { |state, el| state || file.end_with?(el) } }
87
+ .map { |file| file.split('.').first.split(delimiter)[1] }
88
+ end
89
+
90
+ # It returns a specific class code coverage and an emoji status as well
91
+ def report_class(jacoco_class)
92
+ report_result = {
93
+ covered: 'No coverage data found : -',
94
+ status: ':black_joker:',
95
+ required_coverage_percentage: 'No coverage data found : -'
96
+ }
97
+
98
+ counter = coverage_counter(jacoco_class)
99
+ unless counter.nil?
100
+ coverage = (counter.covered.fdiv(counter.covered + counter.missed) * 100).floor
101
+ required_coverage = required_class_coverage(jacoco_class)
102
+ status = coverage_status(coverage, required_coverage)
103
+
104
+ report_result = {
105
+ covered: coverage,
106
+ status: status,
107
+ required_coverage_percentage: required_coverage
108
+ }
109
+ end
110
+
111
+ report_result
112
+ end
113
+
114
+ # Determines the required coverage for the class
115
+ def required_class_coverage(jacoco_class)
116
+ key = minimum_class_coverage_map.keys.detect { |k| jacoco_class.name.match(k) } || jacoco_class.name
117
+ required_coverage = minimum_class_coverage_map[key]
118
+ required_coverage = package_coverage(jacoco_class.name) if required_coverage.nil?
119
+ required_coverage = minimum_class_coverage_percentage if required_coverage.nil?
120
+ required_coverage
121
+ end
122
+
123
+ # it returns the most suitable coverage by package name to class or nil
124
+ def package_coverage(class_name)
125
+ path = class_name
126
+ package_parts = class_name.split('/')
127
+ package_parts.reverse_each do |item|
128
+ size = item.size
129
+ path = path[0...-size]
130
+ coverage = minimum_package_coverage_map[path]
131
+ path = path[0...-1] unless path.empty?
132
+ return coverage unless coverage.nil?
133
+ end
134
+ nil
135
+ end
136
+
137
+ # it returns an emoji for coverage status
138
+ def coverage_status(coverage, minimum_percentage)
139
+ if coverage < (minimum_percentage / 2) then ':skull:'
140
+ elsif coverage < minimum_percentage then ':warning:'
141
+ else ':white_check_mark:'
142
+ end
143
+ end
144
+
145
+ # It returns total of project code coverage and an emoji status as well
146
+ def total_coverage(report_path)
147
+ jacoco_report = Nokogiri::XML(File.open(report_path))
148
+
149
+ report = jacoco_report.xpath('report/counter').select { |item| item['type'] == 'INSTRUCTION' }
150
+ missed_instructions = report.first['missed'].to_f
151
+ covered_instructions = report.first['covered'].to_f
152
+ total_instructions = missed_instructions + covered_instructions
153
+ covered_percentage = (covered_instructions * 100 / total_instructions).round(2)
154
+ coverage_status = coverage_status(covered_percentage, minimum_project_coverage_percentage)
155
+
156
+ {
157
+ covered: covered_percentage,
158
+ status: coverage_status
159
+ }
160
+ end
161
+
162
+ private
163
+
164
+ def coverage_counter(jacoco_class)
165
+ counters = jacoco_class.counters
166
+ branch_counter = counters.detect { |e| e.type.eql? 'BRANCH' }
167
+ line_counter = counters.detect { |e| e.type.eql? 'LINE' }
168
+ counter = branch_counter.nil? ? line_counter : branch_counter
169
+
170
+ if counter.nil?
171
+ no_coverage_data_found_message = "No coverage data found for #{jacoco_class.name}"
172
+
173
+ raise no_coverage_data_found_message if @fail_no_coverage_data_found.instance_of?(TrueClass)
174
+
175
+ warn no_coverage_data_found_message
176
+ end
177
+
178
+ counter
179
+ end
180
+
181
+ # rubocop:disable Style/SignalException
182
+ def report_fails(class_coverage_above_minimum, total_covered)
183
+ if total_covered[:covered] < minimum_project_coverage_percentage
184
+ # fail danger if total coverage is smaller than minimum_project_coverage_percentage
185
+ covered = total_covered[:covered]
186
+ fail("Total coverage of #{covered}%. Improve this to at least #{minimum_project_coverage_percentage}%")
187
+ end
188
+
189
+ return if class_coverage_above_minimum
190
+
191
+ fail("Class coverage is below minimum. Improve to at least #{minimum_class_coverage_percentage}%")
192
+ end
193
+ # rubocop:enable Style/SignalException
194
+
195
+ def markdown_class(parser, report_markdown, report_url)
196
+ class_coverage_above_minimum = true
197
+ parser.classes.each do |jacoco_class| # Check metrics for each classes
198
+ rp = report_class(jacoco_class)
199
+ rl = report_link(jacoco_class.name, report_url)
200
+ ln = "| #{rl} | #{rp[:covered]}% | #{rp[:required_coverage_percentage]}% | #{rp[:status]} |\n"
201
+ report_markdown << ln
202
+
203
+ class_coverage_above_minimum &&= rp[:covered] >= rp[:required_coverage_percentage]
204
+ end
205
+
206
+ class_coverage_above_minimum
207
+ end
208
+
209
+ def report_link(class_name, report_url)
210
+ if report_url.empty?
211
+ "`#{class_name}`"
212
+ else
213
+ report_filepath = "#{class_name.gsub(%r{/(?=[^/]*/.)}, '.')}.html"
214
+ "[`#{class_name}`](#{report_url + report_filepath})"
215
+ end
216
+ end
217
+ end
218
+ end
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'nokogiri'
4
+
5
+ module Jacoco
6
+ # Sax parser for quickly finding class elements in Jacoco report
7
+ class SAXParser < Nokogiri::XML::SAX::Document
8
+ attr_accessor :class_names, :classes
9
+
10
+ def initialize(classes)
11
+ super()
12
+ @class_names = classes
13
+ @classes = []
14
+ @current_class = nil
15
+ @subelement_index = 0
16
+ end
17
+
18
+ def start_element(name, attrs = [])
19
+ case name
20
+ when 'class'
21
+ start_class(attrs)
22
+ when 'counter'
23
+ start_counter(attrs)
24
+ end
25
+
26
+ @subelement_index += 1
27
+ end
28
+
29
+ def start_counter(attrs)
30
+ return unless !@current_class.nil? && @subelement_index == 1
31
+
32
+ counter = Jacoco::Counter.new
33
+ counter.type = Hash[attrs]['type']
34
+ counter.missed = Hash[attrs]['missed'].to_i
35
+ counter.covered = Hash[attrs]['covered'].to_i
36
+
37
+ @current_class.counters.push(counter)
38
+ end
39
+
40
+ def start_class(attrs)
41
+ @subelement_index = 0
42
+
43
+ return unless @class_names.include?(Hash[attrs]['name'])
44
+
45
+ c = Jacoco::Class.new
46
+ c.name = Hash[attrs]['name']
47
+ c.counters = []
48
+ @current_class = c
49
+ @classes.push c
50
+ end
51
+
52
+ def characters(string); end
53
+
54
+ def end_element(name)
55
+ @subelement_index -= 1
56
+ @current_class = nil if name.eql? 'class'
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,42 @@
1
+ <?xml version="1.0" encoding="UTF-8" standalone="yes"?><!DOCTYPE report PUBLIC "-//JACOCO//DTD Report 1.0//EN"
2
+ "report.dtd">
3
+ <report name="test_report">
4
+ <sessioninfo id="test-id" start="1480057517395" dump="1480057526412"/>
5
+ <package name="com/example">
6
+ <class name="com/example/CachedRepository">
7
+ <method name="&lt;init&gt;" desc="()V" line="17">
8
+ <counter type="INSTRUCTION" missed="0" covered="11"/>
9
+ <counter type="LINE" missed="0" covered="5"/>
10
+ <counter type="COMPLEXITY" missed="0" covered="1"/>
11
+ <counter type="METHOD" missed="0" covered="1"/>
12
+ </method>
13
+ <counter type="INSTRUCTION" missed="0" covered="46"/>
14
+ <counter type="LINE" missed="0" covered="14"/>
15
+ <counter type="COMPLEXITY" missed="5" covered="7"/>
16
+ <counter type="METHOD" missed="0" covered="7"/>
17
+ <counter type="CLASS" missed="0" covered="1"/>
18
+ <counter type="BRANCH" missed="2" covered="2" />
19
+ </class>
20
+ <sourcefile name="CachedRepository.java">
21
+ <line nr="16" mi="0" ci="2" mb="0" cb="0"/>
22
+ <line nr="17" mi="0" ci="3" mb="0" cb="0"/>
23
+ <counter type="INSTRUCTION" missed="2" covered="98"/>
24
+ <counter type="LINE" missed="2" covered="19"/>
25
+ <counter type="COMPLEXITY" missed="2" covered="11"/>
26
+ <counter type="METHOD" missed="2" covered="11"/>
27
+ <counter type="CLASS" missed="2" covered="4"/>
28
+ </sourcefile>
29
+ <counter type="INSTRUCTION" missed="80" covered="324"/>
30
+ <counter type="BRANCH" missed="4" covered="4"/>
31
+ <counter type="LINE" missed="24" covered="68"/>
32
+ <counter type="COMPLEXITY" missed="11" covered="39"/>
33
+ <counter type="METHOD" missed="9" covered="37"/>
34
+ <counter type="CLASS" missed="2" covered="10"/>
35
+ </package>
36
+ <counter type="INSTRUCTION" missed="39399" covered="19321"/>
37
+ <counter type="BRANCH" missed="3463" covered="1039"/>
38
+ <counter type="LINE" missed="9611" covered="3974"/>
39
+ <counter type="COMPLEXITY" missed="5517" covered="1444"/>
40
+ <counter type="METHOD" missed="3382" covered="1120"/>
41
+ <counter type="CLASS" missed="491" covered="370"/>
42
+ </report>
@@ -0,0 +1,34 @@
1
+ <?xml version="1.0" encoding="UTF-8" standalone="yes"?><!DOCTYPE report PUBLIC "-//JACOCO//DTD Report 1.0//EN"
2
+ "report.dtd">
3
+ <report name="test_report">
4
+ <sessioninfo id="test-id" start="1480057517395" dump="1480057526412"/>
5
+ <package name="com/example">
6
+ <class name="com/example/CachedRepository">
7
+ <method name="&lt;init&gt;" desc="()V" line="17">
8
+ <counter type="INSTRUCTION" missed="0" covered="11"/>
9
+ <counter type="COMPLEXITY" missed="0" covered="1"/>
10
+ <counter type="METHOD" missed="0" covered="1"/>
11
+ </method>
12
+ <counter type="INSTRUCTION" missed="0" covered="46"/>
13
+ <counter type="COMPLEXITY" missed="5" covered="7"/>
14
+ <counter type="METHOD" missed="0" covered="7"/>
15
+ <counter type="CLASS" missed="0" covered="1"/>
16
+ </class>
17
+ <sourcefile name="CachedRepository.java">
18
+ <line nr="16" mi="0" ci="2" mb="0" cb="0"/>
19
+ <line nr="17" mi="0" ci="3" mb="0" cb="0"/>
20
+ <counter type="INSTRUCTION" missed="2" covered="98"/>
21
+ <counter type="COMPLEXITY" missed="2" covered="11"/>
22
+ <counter type="METHOD" missed="2" covered="11"/>
23
+ <counter type="CLASS" missed="2" covered="4"/>
24
+ </sourcefile>
25
+ <counter type="INSTRUCTION" missed="80" covered="324"/>
26
+ <counter type="COMPLEXITY" missed="11" covered="39"/>
27
+ <counter type="METHOD" missed="9" covered="37"/>
28
+ <counter type="CLASS" missed="2" covered="10"/>
29
+ </package>
30
+ <counter type="INSTRUCTION" missed="39399" covered="19321"/>
31
+ <counter type="COMPLEXITY" missed="5517" covered="1444"/>
32
+ <counter type="METHOD" missed="3382" covered="1120"/>
33
+ <counter type="CLASS" missed="491" covered="370"/>
34
+ </report>
@@ -0,0 +1,178 @@
1
+ # frozen_string_literal: true
2
+
3
+ # rubocop:disable Layout/LineLength
4
+ # rubocop:disable Metrics/ModuleLength
5
+ # rubocop:disable Metrics/BlockLength
6
+
7
+ require File.expand_path('spec_helper', __dir__)
8
+
9
+ module Danger
10
+ describe Danger::DangerJacoco do
11
+ it 'should be a plugin' do
12
+ expect(Danger::DangerJacoco.new(nil)).to be_a Danger::Plugin
13
+ end
14
+
15
+ #
16
+ # You should test your custom attributes and methods here
17
+ #
18
+ describe 'with Dangerfile' do
19
+ before do
20
+ @dangerfile = testing_dangerfile
21
+ @my_plugin = @dangerfile.jacoco
22
+
23
+ modified_files = ['src/java/com/example/CachedRepository.java']
24
+ added_files = ['src/java/Blah.java']
25
+
26
+ allow(@dangerfile.git).to receive(:modified_files).and_return(modified_files)
27
+ allow(@dangerfile.git).to receive(:added_files).and_return(added_files)
28
+ end
29
+
30
+ it :report do
31
+ path_a = "#{File.dirname(__FILE__)}/fixtures/output_a.xml"
32
+
33
+ @my_plugin.minimum_project_coverage_percentage = 50
34
+ @my_plugin.minimum_class_coverage_map = { 'com/example/CachedRepository' => 100 }
35
+
36
+ @my_plugin.report path_a
37
+
38
+ expect(@dangerfile.status_report[:errors]).to eq(['Total coverage of 32.9%. Improve this to at least 50%',
39
+ 'Class coverage is below minimum. Improve to at least 0%'])
40
+ expect(@dangerfile.status_report[:markdowns][0].message).to include('### JaCoCo Code Coverage 32.9% :warning:')
41
+ expect(@dangerfile.status_report[:markdowns][0].message).to include('| Class | Covered | Meta | Status |')
42
+ expect(@dangerfile.status_report[:markdowns][0].message).to include('|:---|:---:|:---:|:---:|')
43
+ expect(@dangerfile.status_report[:markdowns][0].message).to include('| `com/example/CachedRepository` | 50% | 100% | :warning: |')
44
+ end
45
+
46
+ it 'test regex class coverage' do
47
+ path_a = "#{File.dirname(__FILE__)}/fixtures/output_a.xml"
48
+
49
+ @my_plugin.minimum_project_coverage_percentage = 50
50
+ @my_plugin.minimum_class_coverage_map = { '.*Repository' => 60 }
51
+
52
+ @my_plugin.report path_a
53
+
54
+ expect(@dangerfile.status_report[:markdowns][0].message).to include('| `com/example/CachedRepository` | 50% | 60% | :warning: |')
55
+ end
56
+
57
+ it 'test with package coverage' do
58
+ path_a = "#{File.dirname(__FILE__)}/fixtures/output_a.xml"
59
+
60
+ @my_plugin.minimum_project_coverage_percentage = 50
61
+ @my_plugin.minimum_package_coverage_map = { 'com/example/' => 70 }
62
+
63
+ @my_plugin.report path_a
64
+
65
+ expect(@dangerfile.status_report[:markdowns][0].message).to include('| `com/example/CachedRepository` | 50% | 70% | :warning: |')
66
+ end
67
+
68
+ it 'test with bigger overlapped package coverage' do
69
+ path_a = "#{File.dirname(__FILE__)}/fixtures/output_a.xml"
70
+
71
+ @my_plugin.minimum_project_coverage_percentage = 50
72
+ @my_plugin.minimum_package_coverage_map = {
73
+ 'com/example/' => 70,
74
+ 'com/' => 90
75
+ }
76
+
77
+ @my_plugin.report path_a
78
+
79
+ expect(@dangerfile.status_report[:markdowns][0].message).to include('| `com/example/CachedRepository` | 50% | 70% | :warning: |')
80
+ end
81
+
82
+ it 'test with lower overlapped package coverage' do
83
+ path_a = "#{File.dirname(__FILE__)}/fixtures/output_a.xml"
84
+
85
+ @my_plugin.minimum_project_coverage_percentage = 50
86
+ @my_plugin.minimum_package_coverage_map = {
87
+ 'com/example/' => 77,
88
+ 'com/' => 30
89
+ }
90
+
91
+ @my_plugin.report path_a
92
+
93
+ expect(@dangerfile.status_report[:markdowns][0].message).to include('| `com/example/CachedRepository` | 50% | 77% | :warning: |')
94
+ end
95
+
96
+ it 'test with overlapped package coverage and bigger class coverage' do
97
+ path_a = "#{File.dirname(__FILE__)}/fixtures/output_a.xml"
98
+
99
+ @my_plugin.minimum_project_coverage_percentage = 50
100
+ @my_plugin.minimum_package_coverage_map = {
101
+ 'com/example/' => 77,
102
+ 'com/' => 30
103
+ }
104
+ @my_plugin.minimum_class_coverage_map = { 'com/example/CachedRepository' => 100 }
105
+
106
+ @my_plugin.report path_a
107
+
108
+ expect(@dangerfile.status_report[:markdowns][0].message).to include('| `com/example/CachedRepository` | 50% | 100% | :warning: |')
109
+ end
110
+
111
+ it 'test with overlapped package coverage and lowwer class coverage' do
112
+ path_a = "#{File.dirname(__FILE__)}/fixtures/output_a.xml"
113
+
114
+ @my_plugin.minimum_project_coverage_percentage = 50
115
+ @my_plugin.minimum_package_coverage_map = {
116
+ 'com/example/' => 90,
117
+ 'com/' => 85
118
+ }
119
+ @my_plugin.minimum_class_coverage_map = { 'com/example/CachedRepository' => 80 }
120
+
121
+ @my_plugin.report path_a
122
+
123
+ expect(@dangerfile.status_report[:markdowns][0].message).to include('| `com/example/CachedRepository` | 50% | 80% | :warning: |')
124
+ end
125
+
126
+ it 'adds a link to report' do
127
+ path_a = "#{File.dirname(__FILE__)}/fixtures/output_a.xml"
128
+
129
+ @my_plugin.minimum_class_coverage_percentage = 80
130
+ @my_plugin.minimum_project_coverage_percentage = 50
131
+
132
+ @my_plugin.report(path_a, 'http://test.com/')
133
+
134
+ expect(@dangerfile.status_report[:markdowns][0].message).to include('| [`com/example/CachedRepository`](http://test.com/com.example/CachedRepository.html) | 50% | 80% | :warning: |')
135
+ end
136
+
137
+ it 'When option "fail_no_coverage_data_found" is set to optionally fail, it doesn\'t fail the execution' do
138
+ path_a = "#{File.dirname(__FILE__)}/fixtures/output_a.xml"
139
+
140
+ @my_plugin.minimum_class_coverage_percentage = 80
141
+ @my_plugin.minimum_project_coverage_percentage = 50
142
+
143
+ expect { @my_plugin.report(path_a, fail_no_coverage_data_found: true) }.to_not raise_error(RuntimeError)
144
+ end
145
+
146
+ it 'When option "fail_no_coverage_data_found" is not set, the execution fails on empty data' do
147
+ path_a = "#{File.dirname(__FILE__)}/fixtures/output_b.xml"
148
+
149
+ @my_plugin.minimum_class_coverage_percentage = 80
150
+ @my_plugin.minimum_project_coverage_percentage = 50
151
+
152
+ expect { @my_plugin.report path_a }.to raise_error(RuntimeError)
153
+ end
154
+
155
+ it 'When option "fail_no_coverage_data_found" is set to optionally fail, the execution fails on empty data' do
156
+ path_a = "#{File.dirname(__FILE__)}/fixtures/output_b.xml"
157
+
158
+ @my_plugin.minimum_class_coverage_percentage = 80
159
+ @my_plugin.minimum_project_coverage_percentage = 50
160
+
161
+ expect { @my_plugin.report path_a, fail_no_coverage_data_found: true }.to raise_error(RuntimeError)
162
+ end
163
+
164
+ it 'When option "fail_no_coverage_data_found" is set to optionally warn (not fail), the execution doesn\'t fail on empty data' do
165
+ path_a = "#{File.dirname(__FILE__)}/fixtures/output_b.xml"
166
+
167
+ @my_plugin.minimum_class_coverage_percentage = 80
168
+ @my_plugin.minimum_project_coverage_percentage = 50
169
+
170
+ expect { @my_plugin.report path_a, fail_no_coverage_data_found: false }.to_not raise_error(RuntimeError)
171
+ end
172
+ end
173
+ end
174
+ end
175
+
176
+ # rubocop:enable Layout/LineLength
177
+ # rubocop:enable Metrics/ModuleLength
178
+ # rubocop:enable Metrics/BlockLength
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'pathname'
4
+ ROOT = Pathname.new(File.expand_path('..', __dir__))
5
+ $LOAD_PATH.unshift("#{ROOT}lib".to_s)
6
+ $LOAD_PATH.unshift("#{ROOT}spec".to_s)
7
+
8
+ require 'bundler/setup'
9
+ require 'pry'
10
+
11
+ require 'rspec'
12
+ require 'danger'
13
+
14
+ # Use coloured output, it's the best.
15
+ RSpec.configure do |config|
16
+ config.filter_gems_from_backtrace 'bundler'
17
+ config.color = true
18
+ config.tty = true
19
+ end
20
+
21
+ RSpec::Expectations.configuration.on_potential_false_positives = :nothing
22
+
23
+ require 'danger_plugin'
24
+
25
+ # These functions are a subset of https://github.com/danger/danger/blob/master/spec/spec_helper.rb
26
+ # If you are expanding these files, see if it's already been done ^.
27
+
28
+ # A silent version of the user interface,
29
+ # it comes with an extra function `.string` which will
30
+ # strip all ANSI colours from the string.
31
+
32
+ # rubocop:disable Lint/NestedMethodDefinition
33
+ def testing_ui
34
+ @output = StringIO.new
35
+ def @output.winsize
36
+ [20, 9999]
37
+ end
38
+
39
+ cork = Cork::Board.new(out: @output)
40
+ def cork.string
41
+ out.string.gsub(/\e\[([;\d]+)?m/, '')
42
+ end
43
+ cork
44
+ end
45
+ # rubocop:enable Lint/NestedMethodDefinition
46
+
47
+ # Example environment (ENV) that would come from
48
+ # running a PR on TravisCI
49
+ def testing_env
50
+ {
51
+ 'HAS_JOSH_K_SEAL_OF_APPROVAL' => 'true',
52
+ 'TRAVIS_PULL_REQUEST' => '800',
53
+ 'TRAVIS_REPO_SLUG' => 'artsy/eigen',
54
+ 'TRAVIS_COMMIT_RANGE' => '759adcbd0d8f...13c4dc8bb61d',
55
+ 'DANGER_GITHUB_API_TOKEN' => '123sbdq54erfsd3422gdfio'
56
+ }
57
+ end
58
+
59
+ # A stubbed out Dangerfile for use in tests
60
+ def testing_dangerfile
61
+ env = Danger::EnvironmentManager.new(testing_env)
62
+ Danger::Dangerfile.new(env, testing_ui)
63
+ end
metadata ADDED
@@ -0,0 +1,234 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: danger-jacoco-instacart
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.9
5
+ platform: ruby
6
+ authors:
7
+ - Anton Malinskiy
8
+ - Alexander Bezverhni
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2022-08-23 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: danger-plugin-api
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - "~>"
19
+ - !ruby/object:Gem::Version
20
+ version: '1.0'
21
+ type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - "~>"
26
+ - !ruby/object:Gem::Version
27
+ version: '1.0'
28
+ - !ruby/object:Gem::Dependency
29
+ name: nokogiri-happymapper
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - "~>"
33
+ - !ruby/object:Gem::Version
34
+ version: '0.6'
35
+ type: :runtime
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - "~>"
40
+ - !ruby/object:Gem::Version
41
+ version: '0.6'
42
+ - !ruby/object:Gem::Dependency
43
+ name: bundler
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - "~>"
47
+ - !ruby/object:Gem::Version
48
+ version: '2.0'
49
+ type: :development
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - "~>"
54
+ - !ruby/object:Gem::Version
55
+ version: '2.0'
56
+ - !ruby/object:Gem::Dependency
57
+ name: rake
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - "~>"
61
+ - !ruby/object:Gem::Version
62
+ version: '13.0'
63
+ type: :development
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - "~>"
68
+ - !ruby/object:Gem::Version
69
+ version: '13.0'
70
+ - !ruby/object:Gem::Dependency
71
+ name: rspec
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - "~>"
75
+ - !ruby/object:Gem::Version
76
+ version: '3.7'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - "~>"
82
+ - !ruby/object:Gem::Version
83
+ version: '3.7'
84
+ - !ruby/object:Gem::Dependency
85
+ name: rubocop
86
+ requirement: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - "~>"
89
+ - !ruby/object:Gem::Version
90
+ version: '1.14'
91
+ type: :development
92
+ prerelease: false
93
+ version_requirements: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - "~>"
96
+ - !ruby/object:Gem::Version
97
+ version: '1.14'
98
+ - !ruby/object:Gem::Dependency
99
+ name: yard
100
+ requirement: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - "~>"
103
+ - !ruby/object:Gem::Version
104
+ version: '0.9'
105
+ type: :development
106
+ prerelease: false
107
+ version_requirements: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - "~>"
110
+ - !ruby/object:Gem::Version
111
+ version: '0.9'
112
+ - !ruby/object:Gem::Dependency
113
+ name: guard
114
+ requirement: !ruby/object:Gem::Requirement
115
+ requirements:
116
+ - - "~>"
117
+ - !ruby/object:Gem::Version
118
+ version: '2.14'
119
+ type: :development
120
+ prerelease: false
121
+ version_requirements: !ruby/object:Gem::Requirement
122
+ requirements:
123
+ - - "~>"
124
+ - !ruby/object:Gem::Version
125
+ version: '2.14'
126
+ - !ruby/object:Gem::Dependency
127
+ name: guard-rspec
128
+ requirement: !ruby/object:Gem::Requirement
129
+ requirements:
130
+ - - "~>"
131
+ - !ruby/object:Gem::Version
132
+ version: '4.7'
133
+ type: :development
134
+ prerelease: false
135
+ version_requirements: !ruby/object:Gem::Requirement
136
+ requirements:
137
+ - - "~>"
138
+ - !ruby/object:Gem::Version
139
+ version: '4.7'
140
+ - !ruby/object:Gem::Dependency
141
+ name: listen
142
+ requirement: !ruby/object:Gem::Requirement
143
+ requirements:
144
+ - - '='
145
+ - !ruby/object:Gem::Version
146
+ version: 3.5.1
147
+ type: :development
148
+ prerelease: false
149
+ version_requirements: !ruby/object:Gem::Requirement
150
+ requirements:
151
+ - - '='
152
+ - !ruby/object:Gem::Version
153
+ version: 3.5.1
154
+ - !ruby/object:Gem::Dependency
155
+ name: pry
156
+ requirement: !ruby/object:Gem::Requirement
157
+ requirements:
158
+ - - ">="
159
+ - !ruby/object:Gem::Version
160
+ version: '0'
161
+ type: :development
162
+ prerelease: false
163
+ version_requirements: !ruby/object:Gem::Requirement
164
+ requirements:
165
+ - - ">="
166
+ - !ruby/object:Gem::Version
167
+ version: '0'
168
+ description: A short description of danger-jacoco. This is a forked version of https://github.com/Malinskiy/danger-jacoco
169
+ that suits Instacart needs.
170
+ email:
171
+ - anton@malinskiy.com
172
+ - bezverhni@gmail.com
173
+ executables: []
174
+ extensions: []
175
+ extra_rdoc_files: []
176
+ files:
177
+ - ".github/dependabot.yml"
178
+ - ".github/workflows/ci.yaml"
179
+ - ".github/workflows/release.yaml"
180
+ - ".gitignore"
181
+ - ".rubocop.yml"
182
+ - Gemfile
183
+ - Guardfile
184
+ - LICENSE.txt
185
+ - README.md
186
+ - Rakefile
187
+ - danger-jacoco.gemspec
188
+ - lib/danger_jacoco.rb
189
+ - lib/danger_plugin.rb
190
+ - lib/jacoco/dom_parser.rb
191
+ - lib/jacoco/gem_version.rb
192
+ - lib/jacoco/model/class.rb
193
+ - lib/jacoco/model/counter.rb
194
+ - lib/jacoco/model/group.rb
195
+ - lib/jacoco/model/line.rb
196
+ - lib/jacoco/model/method.rb
197
+ - lib/jacoco/model/package.rb
198
+ - lib/jacoco/model/report.rb
199
+ - lib/jacoco/model/session_info.rb
200
+ - lib/jacoco/model/sourcefile.rb
201
+ - lib/jacoco/plugin.rb
202
+ - lib/jacoco/sax_parser.rb
203
+ - spec/fixtures/output_a.xml
204
+ - spec/fixtures/output_b.xml
205
+ - spec/jacoco_spec.rb
206
+ - spec/spec_helper.rb
207
+ homepage: https://github.com/alexanderbezverhni/danger-jacoco
208
+ licenses:
209
+ - MIT
210
+ metadata: {}
211
+ post_install_message:
212
+ rdoc_options: []
213
+ require_paths:
214
+ - lib
215
+ required_ruby_version: !ruby/object:Gem::Requirement
216
+ requirements:
217
+ - - ">="
218
+ - !ruby/object:Gem::Version
219
+ version: '2.6'
220
+ required_rubygems_version: !ruby/object:Gem::Requirement
221
+ requirements:
222
+ - - ">="
223
+ - !ruby/object:Gem::Version
224
+ version: '0'
225
+ requirements: []
226
+ rubygems_version: 3.1.2
227
+ signing_key:
228
+ specification_version: 4
229
+ summary: A longer description of danger-jacoco.
230
+ test_files:
231
+ - spec/fixtures/output_a.xml
232
+ - spec/fixtures/output_b.xml
233
+ - spec/jacoco_spec.rb
234
+ - spec/spec_helper.rb