deep-cover 0.1.1 → 0.1.2
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/.rspec +1 -0
- data/.travis.yml +3 -1
- data/Rakefile +1 -1
- data/bin/selfcov +1 -1
- data/deep_cover.gemspec +2 -1
- data/lib/deep_cover/analyser.rb +1 -2
- data/lib/deep_cover/analyser/base.rb +20 -6
- data/lib/deep_cover/analyser/covered_code_source.rb +0 -12
- data/lib/deep_cover/analyser/node.rb +11 -1
- data/lib/deep_cover/analyser/optionally_covered.rb +14 -0
- data/lib/deep_cover/auto_run.rb +36 -32
- data/lib/deep_cover/backports.rb +9 -0
- data/lib/deep_cover/base.rb +8 -1
- data/lib/deep_cover/cli/debugger.rb +6 -4
- data/lib/deep_cover/cli/deep_cover.rb +37 -6
- data/lib/deep_cover/cli/instrumented_clone_reporter.rb +50 -32
- data/lib/deep_cover/config.rb +16 -7
- data/lib/deep_cover/coverage.rb +8 -9
- data/lib/deep_cover/covered_code.rb +17 -18
- data/lib/deep_cover/node/base.rb +28 -4
- data/lib/deep_cover/node/branch.rb +10 -7
- data/lib/deep_cover/node/def.rb +2 -2
- data/lib/deep_cover/node/empty_body.rb +1 -1
- data/lib/deep_cover/node/mixin/can_augment_children.rb +1 -2
- data/lib/deep_cover/node/mixin/execution_location.rb +9 -6
- data/lib/deep_cover/node/mixin/has_child.rb +16 -17
- data/lib/deep_cover/node/mixin/has_tracker.rb +2 -6
- data/lib/deep_cover/node/mixin/rewriting.rb +9 -8
- data/lib/deep_cover/node/send.rb +57 -48
- data/lib/deep_cover/node/{boolean.rb → short_circuit.rb} +0 -0
- data/lib/deep_cover/reporter/istanbul.rb +2 -3
- data/lib/deep_cover/tools.rb +2 -1
- data/lib/deep_cover/tools/dasherize.rb +8 -0
- data/lib/deep_cover/tools/dump_covered_code.rb +12 -6
- data/lib/deep_cover/tools/format_char_cover.rb +2 -3
- data/lib/deep_cover/tools/slice.rb +7 -0
- data/lib/deep_cover/version.rb +1 -1
- metadata +7 -18
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cbe670bee3fca431efa3a04244d724b26deb7ede
|
4
|
+
data.tar.gz: a8f57f090a6fb004bb0b328901885b84f00548ca
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d7d097733ac9da1e9e482f9c56ad96533f18da22f90c60ed3c009fcc7f2f8c4db1a099d5fb0051682157cd9a0d322c546e060f6b17438609ab839901b19a9aa2
|
7
|
+
data.tar.gz: 6e0f37c3293bed959adba222707bc77b31c233cf02e62f65ecef70bdfb24b8acc600b9b1ceccaf818b7f094dcb450e35d2ef9ff4bc6dc96b58582a14e0389dfb
|
data/.rspec
CHANGED
data/.travis.yml
CHANGED
data/Rakefile
CHANGED
data/bin/selfcov
CHANGED
@@ -9,7 +9,7 @@ end
|
|
9
9
|
require "deep_cover"
|
10
10
|
|
11
11
|
if covered_path.nil?
|
12
|
-
covered_path = DeepCover::Tools.
|
12
|
+
covered_path = DeepCover::Tools.dump_covered_code_and_save('./lib', dest_path: '../covered_deep_cover')
|
13
13
|
puts "Covered code generation done. Output in", covered_path
|
14
14
|
exec 'bin/selfcov', covered_path
|
15
15
|
else
|
data/deep_cover.gemspec
CHANGED
@@ -22,6 +22,8 @@ Gem::Specification.new do |spec|
|
|
22
22
|
spec.require_paths = ["lib"]
|
23
23
|
|
24
24
|
### Runtime dependencies
|
25
|
+
spec.required_ruby_version = ">= 2.0.0"
|
26
|
+
|
25
27
|
spec.add_runtime_dependency 'parser'
|
26
28
|
spec.add_runtime_dependency 'backports', '>= 3.10.1'
|
27
29
|
spec.add_runtime_dependency 'binding_of_caller'
|
@@ -29,7 +31,6 @@ Gem::Specification.new do |spec|
|
|
29
31
|
# CLI
|
30
32
|
spec.add_runtime_dependency "term-ansicolor"
|
31
33
|
spec.add_runtime_dependency "highline"
|
32
|
-
spec.add_runtime_dependency "ruby-progressbar", '<1.9.0'
|
33
34
|
spec.add_runtime_dependency 'with_progress'
|
34
35
|
spec.add_runtime_dependency 'slop', '~> 4.0'
|
35
36
|
|
data/lib/deep_cover/analyser.rb
CHANGED
@@ -19,6 +19,5 @@ module DeepCover
|
|
19
19
|
require_relative_dir 'analyser'
|
20
20
|
|
21
21
|
Analyser.include Analyser::IgnoreUncovered, Analyser::Base
|
22
|
-
|
23
|
-
CoveredCode.include Analyser::CoveredCodeSource::CoveredCodeExtension
|
22
|
+
Analyser.extend Analyser::OptionallyCovered
|
24
23
|
end
|
@@ -3,15 +3,10 @@ module DeepCover
|
|
3
3
|
attr_reader :source, :options
|
4
4
|
|
5
5
|
def initialize(source, **options)
|
6
|
-
@source = source
|
6
|
+
@source = to_source(source, **options)
|
7
7
|
@options = options
|
8
8
|
end
|
9
9
|
|
10
|
-
# Basic coercion mechanism
|
11
|
-
def to_analyser
|
12
|
-
self
|
13
|
-
end
|
14
|
-
|
15
10
|
# Looking exclusively at our subset of nodes, returns the node's direct descendants
|
16
11
|
def node_children(node)
|
17
12
|
@source.node_children(node)
|
@@ -47,5 +42,24 @@ module DeepCover
|
|
47
42
|
def covered_code
|
48
43
|
@source.covered_code
|
49
44
|
end
|
45
|
+
|
46
|
+
protected
|
47
|
+
|
48
|
+
def convert(covered_code, **options)
|
49
|
+
Analyser::Node.new(covered_code, **options)
|
50
|
+
end
|
51
|
+
|
52
|
+
def to_source(source, **options)
|
53
|
+
case source
|
54
|
+
when Analyser
|
55
|
+
source
|
56
|
+
when CoveredCode
|
57
|
+
convert(source, **options)
|
58
|
+
when Node
|
59
|
+
convert(source.covered_code, **options)
|
60
|
+
else
|
61
|
+
raise ArgumentError, "expected Analyser, Node or CoveredCode, got #{source.class}"
|
62
|
+
end
|
63
|
+
end
|
50
64
|
end
|
51
65
|
end
|
@@ -15,17 +15,5 @@ module DeepCover
|
|
15
15
|
def node_runs(node)
|
16
16
|
node.execution_count if node.executable?
|
17
17
|
end
|
18
|
-
|
19
|
-
module NodeExtension
|
20
|
-
def to_analyser
|
21
|
-
Analyser::CoveredCodeSource.new(covered_code)
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
module CoveredCodeExtension
|
26
|
-
def to_analyser
|
27
|
-
Analyser::CoveredCodeSource.new(self)
|
28
|
-
end
|
29
|
-
end
|
30
18
|
end
|
31
19
|
end
|
@@ -1,11 +1,21 @@
|
|
1
1
|
module DeepCover
|
2
2
|
class Analyser::Node < Analyser
|
3
3
|
def is_raise?(node)
|
4
|
-
node.is_a?(Node::Send) && (node.
|
4
|
+
node.is_a?(Node::Send) && (node.message == :raise || node.message == :exit)
|
5
5
|
end
|
6
6
|
|
7
7
|
def is_default_argument?(node)
|
8
8
|
node.parent.is_a?(Node::Optarg)
|
9
9
|
end
|
10
|
+
|
11
|
+
def is_case_implicit_else?(node)
|
12
|
+
parent = node.parent
|
13
|
+
node.is_a?(Node::EmptyBody) && parent.is_a?(Node::Case) && !parent.has_else?
|
14
|
+
end
|
15
|
+
|
16
|
+
protected
|
17
|
+
def convert(node, **)
|
18
|
+
Analyser::CoveredCodeSource.new(node)
|
19
|
+
end
|
10
20
|
end
|
11
21
|
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module DeepCover
|
2
|
+
module Analyser::OptionallyCovered
|
3
|
+
def optionally_covered
|
4
|
+
@optionally_covered ||= Analyser
|
5
|
+
.constants.map{|c| Analyser.const_get(c)}
|
6
|
+
.select{|klass| klass < Analyser }
|
7
|
+
.flat_map do |klass|
|
8
|
+
klass.instance_methods(false).map {|m| m.match(/^is_(.*)\?$/); $1 }
|
9
|
+
end
|
10
|
+
.compact
|
11
|
+
.map(&:to_sym)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
data/lib/deep_cover/auto_run.rb
CHANGED
@@ -3,47 +3,51 @@ require 'pry'
|
|
3
3
|
|
4
4
|
module DeepCover
|
5
5
|
module AutoRun
|
6
|
-
|
6
|
+
class Runner
|
7
|
+
def initialize(covered_path)
|
8
|
+
@covered_path = covered_path
|
9
|
+
end
|
7
10
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
11
|
+
def run!
|
12
|
+
detect
|
13
|
+
load
|
14
|
+
after_tests { save }
|
15
|
+
end
|
12
16
|
|
13
|
-
|
14
|
-
|
15
|
-
|
17
|
+
private
|
18
|
+
def detect
|
19
|
+
Coverage.saved? @covered_path
|
20
|
+
end
|
16
21
|
|
17
|
-
|
18
|
-
|
19
|
-
|
22
|
+
def load
|
23
|
+
@coverage = Coverage.load(@covered_path, with_trackers: false)
|
24
|
+
end
|
20
25
|
|
21
|
-
|
22
|
-
|
23
|
-
if defined?(Minitest)
|
24
|
-
puts "Registering with Minitest"
|
25
|
-
use_at_exit = false
|
26
|
-
Minitest.after_run { yield }
|
26
|
+
def save
|
27
|
+
@coverage.save_trackers(@covered_path)
|
27
28
|
end
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
29
|
+
|
30
|
+
def after_tests
|
31
|
+
use_at_exit = true
|
32
|
+
if defined?(Minitest)
|
33
|
+
use_at_exit = false
|
34
|
+
Minitest.after_run { yield }
|
35
|
+
end
|
36
|
+
if defined?(Rspec)
|
37
|
+
use_at_exit = false
|
38
|
+
RSpec.configure do |config|
|
39
|
+
config.after(:suite) { yield }
|
40
|
+
end
|
41
|
+
end
|
42
|
+
if use_at_exit
|
43
|
+
at_exit { yield }
|
33
44
|
end
|
34
|
-
end
|
35
|
-
if use_at_exit
|
36
|
-
puts "Using at_exit"
|
37
|
-
at_exit { yield }
|
38
45
|
end
|
39
46
|
end
|
40
47
|
|
41
|
-
def run!
|
42
|
-
|
43
|
-
|
44
|
-
after_tests { save }
|
48
|
+
def self.run!(covered_path)
|
49
|
+
Runner.new(covered_path).run! unless @already_setup
|
50
|
+
@already_setup = true
|
45
51
|
end
|
46
|
-
|
47
|
-
run!
|
48
52
|
end
|
49
53
|
end
|
data/lib/deep_cover/backports.rb
CHANGED
@@ -2,6 +2,15 @@
|
|
2
2
|
class Module
|
3
3
|
public :prepend # Public in Ruby 2.1+.
|
4
4
|
end
|
5
|
+
require 'pathname'
|
6
|
+
class Pathname
|
7
|
+
def write(*args)
|
8
|
+
File.write(to_path, *args)
|
9
|
+
end unless method_defined? :write
|
10
|
+
def binwrite(*args)
|
11
|
+
File.binwrite(to_path, *args)
|
12
|
+
end unless method_defined? :binwrite
|
13
|
+
end
|
5
14
|
require 'backports/2.1.0/module/include'
|
6
15
|
require 'backports/2.1.0/enumerable/to_h'
|
7
16
|
require 'backports/2.4.0/false_class/dup'
|
data/lib/deep_cover/base.rb
CHANGED
@@ -17,7 +17,7 @@ module DeepCover
|
|
17
17
|
end
|
18
18
|
|
19
19
|
def line_coverage(filename)
|
20
|
-
coverage.line_coverage(handle_relative_filename(filename),
|
20
|
+
coverage.line_coverage(handle_relative_filename(filename), **config)
|
21
21
|
end
|
22
22
|
|
23
23
|
def covered_code(filename)
|
@@ -51,5 +51,12 @@ module DeepCover
|
|
51
51
|
filename += '.rb' unless filename =~ /\.rb$/
|
52
52
|
filename
|
53
53
|
end
|
54
|
+
|
55
|
+
def parser
|
56
|
+
Parser::CurrentRuby.new.tap do |parser|
|
57
|
+
parser.diagnostics.all_errors_are_fatal = true
|
58
|
+
parser.diagnostics.ignore_warnings = true
|
59
|
+
end
|
60
|
+
end
|
54
61
|
end
|
55
62
|
end
|
@@ -21,11 +21,13 @@ module DeepCover
|
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
24
|
-
|
24
|
+
attr_reader :options
|
25
|
+
def initialize(source, filename: '(source)', lineno: 1, pry: false, **options)
|
25
26
|
@source = source
|
26
27
|
@filename = filename
|
27
28
|
@lineno = lineno
|
28
29
|
@pry = pry
|
30
|
+
@options = options
|
29
31
|
end
|
30
32
|
|
31
33
|
def show
|
@@ -41,8 +43,8 @@ module DeepCover
|
|
41
43
|
puts "Line Coverage: Builtin | DeepCover | DeepCover Strict:\n"
|
42
44
|
begin
|
43
45
|
builtin_line_coverage = builtin_coverage(@source, @filename, @lineno)
|
44
|
-
our_line_coverage = our_coverage(@source, @filename, @lineno)
|
45
|
-
our_strict_line_coverage = our_coverage(@source, @filename, @lineno, allow_partial: false)
|
46
|
+
our_line_coverage = our_coverage(@source, @filename, @lineno, **options)
|
47
|
+
our_strict_line_coverage = our_coverage(@source, @filename, @lineno, allow_partial: false, **options)
|
46
48
|
lines = format(builtin_line_coverage, our_line_coverage, our_strict_line_coverage, source: @source)
|
47
49
|
puts number_lines(lines, lineno: @lineno)
|
48
50
|
rescue Exception => e
|
@@ -72,7 +74,7 @@ module DeepCover
|
|
72
74
|
def show_char_coverage
|
73
75
|
puts "\nChar coverage:\n"
|
74
76
|
|
75
|
-
puts format_char_cover(covered_code, show_whitespace: !!ENV['W'])
|
77
|
+
puts format_char_cover(covered_code, show_whitespace: !!ENV['W'], **options)
|
76
78
|
end
|
77
79
|
|
78
80
|
def pry
|
@@ -13,16 +13,38 @@ module DeepCover
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def show_help
|
16
|
-
puts
|
16
|
+
puts menu
|
17
17
|
end
|
18
18
|
|
19
|
-
|
20
|
-
|
19
|
+
class Parser < Struct.new(:delegate)
|
20
|
+
def method_missing(method, *args, &block)
|
21
|
+
options = args.last
|
22
|
+
if options.is_a?(Hash) && options.has_key?(:default)
|
23
|
+
args[-2] += " [#{options[:default]}]"
|
24
|
+
end
|
25
|
+
delegate.public_send(method, *args, &block)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def parse
|
30
|
+
Slop.parse do |o|
|
31
|
+
yield Parser.new(o)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def menu
|
36
|
+
@menu ||= parse do |o|
|
21
37
|
o.banner = "usage: deep-cover [options] [path/to/app/or/gem]"
|
22
38
|
o.separator ''
|
23
39
|
o.string '-o', '--output', 'output folder', default: './coverage'
|
24
40
|
o.string '-c', '--command', 'command to run tests', default: 'rake'
|
25
|
-
|
41
|
+
o.bool '--bundle', 'run bundle before the tests', default: true
|
42
|
+
o.separator 'Coverage options'
|
43
|
+
@ignore_uncovered_map = Analyser.optionally_covered.map do |option|
|
44
|
+
default = Config::DEFAULTS[:ignore_uncovered].include?(option)
|
45
|
+
o.bool "--ignore-#{Tools.dasherize(option)}", "", default: default
|
46
|
+
[:"ignore_#{option}", option]
|
47
|
+
end.to_h
|
26
48
|
o.separator ''
|
27
49
|
o.separator 'For testing purposes:'
|
28
50
|
o.string '-e', '--expression', 'test ruby expression instead of a covering a path'
|
@@ -35,10 +57,19 @@ module DeepCover
|
|
35
57
|
end
|
36
58
|
end
|
37
59
|
|
60
|
+
def convert_options(options)
|
61
|
+
iu = options[:ignore_uncovered] = []
|
62
|
+
@ignore_uncovered_map.each do |cli_option, option|
|
63
|
+
iu << option if options.delete(cli_option)
|
64
|
+
end
|
65
|
+
options
|
66
|
+
end
|
67
|
+
|
38
68
|
def go
|
69
|
+
options = convert_options(menu.to_h)
|
39
70
|
if options[:expression]
|
40
|
-
Debugger.new(options[:expression], pry: options[:debug]).show
|
41
|
-
elsif (path =
|
71
|
+
Debugger.new(options[:expression], pry: options[:debug], **options).show
|
72
|
+
elsif (path = menu.arguments.first)
|
42
73
|
InstrumentedCloneReporter.new(path, **options).run
|
43
74
|
else
|
44
75
|
show_help
|
@@ -5,24 +5,21 @@ module DeepCover
|
|
5
5
|
module CLI
|
6
6
|
class InstrumentedCloneReporter
|
7
7
|
include Tools
|
8
|
-
attr_reader :dest_path
|
9
8
|
|
10
9
|
def initialize(gem_path, command: 'rake', **options)
|
11
10
|
@command = command
|
12
11
|
@options = options
|
13
|
-
@root_path =
|
14
|
-
|
15
|
-
@gem_relative_path = '' # Typical case
|
16
|
-
else
|
12
|
+
@root_path = gem_path = Pathname.new(gem_path).expand_path
|
13
|
+
unless @root_path.join('Gemfile').exist?
|
17
14
|
# E.g. rails/activesupport
|
18
|
-
@
|
19
|
-
@root_path
|
20
|
-
raise "Can't find Gemfile" unless File.exist?(File.join(@root_path, 'Gemfile'))
|
15
|
+
@root_path = @root_path.dirname
|
16
|
+
raise "Can't find Gemfile" unless @root_path.join('Gemfile').exist?
|
21
17
|
end
|
22
|
-
@dest_root =
|
23
|
-
@dest_root = Dir.mktmpdir("deep_cover_test") unless
|
18
|
+
@dest_root = Pathname('~/test_deep_cover').expand_path
|
19
|
+
@dest_root = Pathname.new(Dir.mktmpdir("deep_cover_test")) unless @dest_root.exist?
|
24
20
|
`rm -rf #{@dest_root}/* #{@dest_root}/.*`
|
25
|
-
|
21
|
+
gem_relative_path = gem_path.relative_path_from(@root_path)
|
22
|
+
@main_path = @dest_root.join(gem_relative_path)
|
26
23
|
end
|
27
24
|
|
28
25
|
def copy
|
@@ -32,24 +29,34 @@ module DeepCover
|
|
32
29
|
def patch_ruby_file(ruby_file)
|
33
30
|
content = File.read(ruby_file)
|
34
31
|
# Insert our code after leading comments:
|
35
|
-
content.sub!(/^((#.*\n+)*)/, '
|
32
|
+
content.sub!(/^((#.*\n+)*)/, "#{$1}require 'deep_cover/auto_run';DeepCover::AutoRun.run! '#{@dest_root}';")
|
36
33
|
File.write(ruby_file, content)
|
37
34
|
end
|
38
35
|
|
36
|
+
def each_gem_path
|
37
|
+
return to_enum __method__ unless block_given?
|
38
|
+
if @main_path.join('lib').exist?
|
39
|
+
yield @main_path
|
40
|
+
else # Rails style
|
41
|
+
Pathname.glob(@main_path.join('*/lib')).each{|p| yield p.dirname}
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
39
45
|
def patch_main_ruby_files
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
46
|
+
each_gem_path do |dest_path|
|
47
|
+
main = dest_path.join('lib/*.rb')
|
48
|
+
Dir.glob(main).each do |main|
|
49
|
+
puts "Patching #{main}"
|
50
|
+
patch_ruby_file(main)
|
51
|
+
end
|
44
52
|
end
|
45
53
|
end
|
46
54
|
|
47
55
|
def patch_gemfile
|
48
|
-
gemfile =
|
49
|
-
gemfile = File.expand_path(File.join(dest_path, '..', 'Gemfile')) unless File.exist?(gemfile)
|
56
|
+
gemfile = @dest_root.join('Gemfile')
|
50
57
|
content = File.read(gemfile)
|
51
58
|
unless content =~ /gem 'deep-cover'/
|
52
|
-
puts "Patching Gemfile"
|
59
|
+
puts "Patching Gemfile #{gemfile}"
|
53
60
|
File.write(gemfile, [
|
54
61
|
"# This file was modified by DeepCover",
|
55
62
|
content,
|
@@ -57,18 +64,15 @@ module DeepCover
|
|
57
64
|
'',
|
58
65
|
].join("\n"))
|
59
66
|
end
|
60
|
-
Bundler.with_clean_env do
|
61
|
-
`cd #{dest_path} && bundle`
|
62
|
-
end
|
63
67
|
end
|
64
68
|
|
65
69
|
def patch_rubocop
|
66
|
-
path =
|
67
|
-
return unless
|
70
|
+
path = @dest_root.join('.rubocop.yml')
|
71
|
+
return unless path.exist?
|
68
72
|
puts "Patching .rubocop.yml"
|
69
|
-
config = YAML.load(
|
70
|
-
((config['AllCops'] ||= {})['Exclude'] ||= []) << 'lib/**/*'
|
71
|
-
|
73
|
+
config = YAML.load(path.read.gsub(/(?<!\w)lib(?!\w)/, 'lib_original'))
|
74
|
+
((config['AllCops'] ||= {})['Exclude'] ||= []) << 'lib/**/*' << 'app/**/*'
|
75
|
+
path.write("# This file was modified by DeepCover\n" + YAML.dump(config))
|
72
76
|
end
|
73
77
|
|
74
78
|
def patch
|
@@ -78,25 +82,39 @@ module DeepCover
|
|
78
82
|
end
|
79
83
|
|
80
84
|
def cover
|
81
|
-
|
82
|
-
|
85
|
+
coverage = Coverage.new
|
86
|
+
each_gem_path do |dest_path|
|
87
|
+
`cp -R #{dest_path}/lib #{dest_path}/lib_original`
|
88
|
+
Tools.dump_covered_code(File.join(dest_path, 'lib_original'),
|
89
|
+
coverage: coverage, root_path: @dest_root.to_s,
|
90
|
+
dest_path: File.join(dest_path, 'lib'))
|
91
|
+
end
|
92
|
+
coverage.save(@dest_root.to_s)
|
83
93
|
end
|
84
94
|
|
85
95
|
def process
|
86
96
|
Bundler.with_clean_env do
|
87
|
-
system("cd #{
|
97
|
+
system("cd #{@main_path} && #{@command}")
|
88
98
|
end
|
89
99
|
end
|
90
100
|
|
91
101
|
def report
|
92
|
-
coverage = Coverage.load @
|
93
|
-
puts coverage.report(dir: @
|
102
|
+
coverage = Coverage.load @dest_root.to_s
|
103
|
+
puts coverage.report(dir: @dest_root.to_s, **@options)
|
104
|
+
end
|
105
|
+
|
106
|
+
def bundle
|
107
|
+
puts "Running `bundle install`"
|
108
|
+
Bundler.with_clean_env do
|
109
|
+
`cd #{@dest_root} && bundle`
|
110
|
+
end
|
94
111
|
end
|
95
112
|
|
96
113
|
def run
|
97
114
|
copy
|
98
115
|
cover
|
99
116
|
patch
|
117
|
+
bundle if @options.fetch(:bundle, true)
|
100
118
|
process
|
101
119
|
report
|
102
120
|
end
|