danger-jacoco-instacart 0.1.9

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 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