xcov 0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/LICENSE +21 -0
- data/README.md +50 -0
- data/assets/images/file_cpp.png +0 -0
- data/assets/images/file_objc.png +0 -0
- data/assets/images/file_swift.png +0 -0
- data/assets/images/xcov_logo.png +0 -0
- data/assets/javascripts/application.js +1 -0
- data/assets/javascripts/bootstrap.min.js +7 -0
- data/assets/javascripts/jquery.min.js +5 -0
- data/assets/javascripts/main.js +11 -0
- data/assets/stylesheets/application.css +1 -0
- data/assets/stylesheets/bootstrap.min.css +5 -0
- data/assets/stylesheets/main.css +206 -0
- data/assets/stylesheets/opensans.css +24 -0
- data/bin/xcov +6 -0
- data/lib/xcov-core.rb +47 -0
- data/lib/xcov-core/bin/xcov-core +0 -0
- data/lib/xcov-core/version.rb +5 -0
- data/lib/xcov.rb +34 -0
- data/lib/xcov/commands_generator.rb +51 -0
- data/lib/xcov/error_handler.rb +46 -0
- data/lib/xcov/manager.rb +13 -0
- data/lib/xcov/model/base.rb +47 -0
- data/lib/xcov/model/function.rb +28 -0
- data/lib/xcov/model/report.rb +53 -0
- data/lib/xcov/model/source.rb +64 -0
- data/lib/xcov/model/target.rb +48 -0
- data/lib/xcov/options.rb +69 -0
- data/lib/xcov/runner.rb +79 -0
- data/lib/xcov/slack_poster.rb +40 -0
- data/lib/xcov/version.rb +6 -0
- data/views/file.erb +14 -0
- data/views/function.erb +10 -0
- data/views/report.erb +64 -0
- data/views/target.erb +20 -0
- metadata +254 -0
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
require "commander"
|
|
2
|
+
require "fastlane_core"
|
|
3
|
+
|
|
4
|
+
HighLine.track_eof = false
|
|
5
|
+
|
|
6
|
+
module Xcov
|
|
7
|
+
class CommandsGenerator
|
|
8
|
+
|
|
9
|
+
include Commander::Methods
|
|
10
|
+
|
|
11
|
+
FastlaneCore::CommanderGenerator.new.generate(Xcov::Options.available_options)
|
|
12
|
+
|
|
13
|
+
def self.start
|
|
14
|
+
FastlaneCore::UpdateChecker.start_looking_for_update("xcov")
|
|
15
|
+
new.run
|
|
16
|
+
ensure
|
|
17
|
+
FastlaneCore::UpdateChecker.show_update_status("xcov", Xcov::VERSION)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def convert_options(options)
|
|
21
|
+
o = options.__hash__.dup
|
|
22
|
+
o.delete(:verbose)
|
|
23
|
+
o
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def run
|
|
27
|
+
program :version, Xcov::VERSION
|
|
28
|
+
program :description, Xcov::DESCRIPTION
|
|
29
|
+
program :help, "Author", "Carlos Vidal <nakioparkour@gmail.com>"
|
|
30
|
+
program :help, "Website", "http://www.nakiostudio.com"
|
|
31
|
+
program :help, "GitHub", "https://github.com/nakiostudio/xcov"
|
|
32
|
+
program :help_formatter, :compact
|
|
33
|
+
|
|
34
|
+
global_option("--verbose") { $verbose = true }
|
|
35
|
+
|
|
36
|
+
command :report do |c|
|
|
37
|
+
c.syntax = "Xcov"
|
|
38
|
+
c.description = Xcov::DESCRIPTION
|
|
39
|
+
c.action do |_args, options|
|
|
40
|
+
config = FastlaneCore::Configuration.create(Xcov::Options.available_options, convert_options(options))
|
|
41
|
+
Xcov::Manager.new.work(config)
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
default_command :report
|
|
46
|
+
|
|
47
|
+
run!
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
end
|
|
51
|
+
end
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
|
|
2
|
+
module Xcov
|
|
3
|
+
class ErrorHandler
|
|
4
|
+
|
|
5
|
+
class << self
|
|
6
|
+
# @param [String] The output of the errored build
|
|
7
|
+
# This method should raise an exception in any case, as the return code indicated a failed build
|
|
8
|
+
def handle_error(output)
|
|
9
|
+
# The order of the handling below is import
|
|
10
|
+
case output
|
|
11
|
+
when /US\-ASCII/
|
|
12
|
+
print "Your shell environment is not correctly configured"
|
|
13
|
+
print "Instead of UTF-8 your shell uses US-ASCII"
|
|
14
|
+
print "Please add the following to your '~/.bashrc':"
|
|
15
|
+
print ""
|
|
16
|
+
print " export LANG=en_US.UTF-8"
|
|
17
|
+
print " export LANGUAGE=en_US.UTF-8"
|
|
18
|
+
print " export LC_ALL=en_US.UTF-8"
|
|
19
|
+
print ""
|
|
20
|
+
print "You'll have to restart your shell session after updating the file."
|
|
21
|
+
print "If you are using zshell or another shell, make sure to edit the correct bash file."
|
|
22
|
+
print "For more information visit this stackoverflow answer:"
|
|
23
|
+
print "https://stackoverflow.com/a/17031697/445598"
|
|
24
|
+
when /CoverageNotFound/
|
|
25
|
+
print "Unable to find any .xccoverage file."
|
|
26
|
+
print "Make sure you have enabled 'Gather code coverage' setting on your scheme settings."
|
|
27
|
+
print "Alternatively you can provide the full path to your .xccoverage file."
|
|
28
|
+
when /Executed/
|
|
29
|
+
# this is *really* important:
|
|
30
|
+
# we don't want to raise an exception here
|
|
31
|
+
# as we handle this in runner.rb at a later point
|
|
32
|
+
# after parsing the actual test results
|
|
33
|
+
return
|
|
34
|
+
end
|
|
35
|
+
raise "Error processing coverage file - see the log above".red
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
private
|
|
39
|
+
|
|
40
|
+
def print(text)
|
|
41
|
+
Helper.log.error text.red
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
end
|
|
46
|
+
end
|
data/lib/xcov/manager.rb
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
require "fastlane_core"
|
|
2
|
+
|
|
3
|
+
module Xcov
|
|
4
|
+
class Manager
|
|
5
|
+
|
|
6
|
+
def work(options)
|
|
7
|
+
Xcov.config = options
|
|
8
|
+
FastlaneCore::PrintTable.print_values(config: options, hide_keys: [:slack_url], title: "Summary for xCov #{Xcov::VERSION}")
|
|
9
|
+
Runner.new.run
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
require 'erb'
|
|
2
|
+
|
|
3
|
+
module Xcov
|
|
4
|
+
class Base
|
|
5
|
+
|
|
6
|
+
attr_accessor :name
|
|
7
|
+
attr_accessor :coverage
|
|
8
|
+
attr_accessor :displayable_coverage
|
|
9
|
+
attr_accessor :coverage_color
|
|
10
|
+
|
|
11
|
+
attr_accessor :id
|
|
12
|
+
|
|
13
|
+
def create_displayable_coverage
|
|
14
|
+
"%.0f%%" % [(@coverage*100)]
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def create_coverage_color
|
|
18
|
+
if @coverage > 0.8
|
|
19
|
+
return "#1FCB32"
|
|
20
|
+
elsif @coverage > 0.65
|
|
21
|
+
return "#FCFF00"
|
|
22
|
+
elsif @coverage > 0.5
|
|
23
|
+
return "#FF9C00"
|
|
24
|
+
else
|
|
25
|
+
return "#FF0000"
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def create_summary
|
|
30
|
+
if @coverage > 0.8
|
|
31
|
+
return "Overall coverage is good"
|
|
32
|
+
elsif @coverage > 0.65
|
|
33
|
+
return "There is room for improvement"
|
|
34
|
+
elsif @coverage > 0.5
|
|
35
|
+
return "Almost unmaintainable"
|
|
36
|
+
else
|
|
37
|
+
return "Keep calm and leave the boat"
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Class methods
|
|
42
|
+
def self.template(name)
|
|
43
|
+
ERB.new(File.read(File.join(File.dirname(__FILE__), "../../../views/", "#{name}.erb")))
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
end
|
|
47
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
require 'cgi'
|
|
2
|
+
|
|
3
|
+
module Xcov
|
|
4
|
+
class Function < Xcov::Base
|
|
5
|
+
|
|
6
|
+
def initialize (name, coverage)
|
|
7
|
+
@name = CGI::escapeHTML(name)
|
|
8
|
+
@coverage = coverage
|
|
9
|
+
@displayable_coverage = self.create_displayable_coverage
|
|
10
|
+
@coverage_color = self.create_coverage_color
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def print_description
|
|
14
|
+
puts "\t\t\t#{@name} (#{@displayable_coverage})"
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def html_value
|
|
18
|
+
Function.template("function").result(binding)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# Class methods
|
|
22
|
+
|
|
23
|
+
def self.map (dictionary)
|
|
24
|
+
Function.new(dictionary["name"], dictionary["coverage"])
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
|
|
2
|
+
module Xcov
|
|
3
|
+
class Report < Xcov::Base
|
|
4
|
+
|
|
5
|
+
attr_accessor :coverage
|
|
6
|
+
attr_accessor :targets
|
|
7
|
+
attr_accessor :summary
|
|
8
|
+
attr_accessor :target_templates
|
|
9
|
+
|
|
10
|
+
def initialize (targets)
|
|
11
|
+
@targets = targets
|
|
12
|
+
@coverage = average_coverage(targets)
|
|
13
|
+
@displayable_coverage = self.create_displayable_coverage
|
|
14
|
+
@coverage_color = self.create_coverage_color
|
|
15
|
+
@summary = self.create_summary
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def average_coverage targets
|
|
19
|
+
coverage = 0
|
|
20
|
+
targets.each do |target|
|
|
21
|
+
coverage = coverage + target.coverage
|
|
22
|
+
end
|
|
23
|
+
coverage / targets.count
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def print_description
|
|
27
|
+
puts "Total coverage: (#{@coverage})"
|
|
28
|
+
@targets.each do |target|
|
|
29
|
+
target.print_description
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def html_value
|
|
34
|
+
@target_templates = ""
|
|
35
|
+
@targets.each do |target|
|
|
36
|
+
@target_templates << target.html_value
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
Function.template("report").result(binding)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# Class methods
|
|
43
|
+
|
|
44
|
+
def self.map dictionary
|
|
45
|
+
targets = dictionary["targets"]
|
|
46
|
+
.select { |target| !target["name"].include?(".xctest") }
|
|
47
|
+
.map { |target| Target.map(target)}
|
|
48
|
+
|
|
49
|
+
Report.new(targets)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
end
|
|
53
|
+
end
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
require 'cgi'
|
|
2
|
+
|
|
3
|
+
module Xcov
|
|
4
|
+
class Source < Xcov::Base
|
|
5
|
+
|
|
6
|
+
attr_accessor :name
|
|
7
|
+
attr_accessor :type
|
|
8
|
+
attr_accessor :coverage
|
|
9
|
+
attr_accessor :functions
|
|
10
|
+
attr_accessor :function_templates
|
|
11
|
+
|
|
12
|
+
def initialize (name, coverage, functions)
|
|
13
|
+
@name = CGI::escapeHTML(name)
|
|
14
|
+
@coverage = coverage
|
|
15
|
+
@functions = functions
|
|
16
|
+
@displayable_coverage = self.create_displayable_coverage
|
|
17
|
+
@coverage_color = self.create_coverage_color
|
|
18
|
+
@id = Digest::SHA1.hexdigest(name)
|
|
19
|
+
@type = Source.type(name)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def print_description
|
|
23
|
+
puts "\t\t#{@name} (#{@coverage})"
|
|
24
|
+
@functions.each do |function|
|
|
25
|
+
function.print_description
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def html_value
|
|
30
|
+
@function_templates = ""
|
|
31
|
+
@functions.each do |function|
|
|
32
|
+
@function_templates << function.html_value
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
Function.template("file").result(binding)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# Class methods
|
|
39
|
+
|
|
40
|
+
def self.map (dictionary)
|
|
41
|
+
name = dictionary["name"]
|
|
42
|
+
coverage = dictionary["coverage"]
|
|
43
|
+
functions = dictionary["functions"].map { |function| Function.map(function)}
|
|
44
|
+
|
|
45
|
+
Source.new(name, coverage, functions)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def self.type (name)
|
|
49
|
+
types_map = {
|
|
50
|
+
".swift" => "swift",
|
|
51
|
+
".m" => "objc",
|
|
52
|
+
".cpp" => "cpp",
|
|
53
|
+
".mm" => "cpp"
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
extension = File.extname(name)
|
|
57
|
+
type = types_map[extension]
|
|
58
|
+
type = "objc" if type.nil?
|
|
59
|
+
|
|
60
|
+
type
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
end
|
|
64
|
+
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
require 'cgi'
|
|
2
|
+
|
|
3
|
+
module Xcov
|
|
4
|
+
class Target < Xcov::Base
|
|
5
|
+
|
|
6
|
+
attr_accessor :name
|
|
7
|
+
attr_accessor :coverage
|
|
8
|
+
attr_accessor :files
|
|
9
|
+
attr_accessor :file_templates
|
|
10
|
+
|
|
11
|
+
def initialize (name, coverage, files)
|
|
12
|
+
@name = CGI::escapeHTML(name)
|
|
13
|
+
@coverage = coverage
|
|
14
|
+
@files = files
|
|
15
|
+
@displayable_coverage = self.create_displayable_coverage
|
|
16
|
+
@coverage_color = self.create_coverage_color
|
|
17
|
+
@id = Digest::SHA1.hexdigest(name)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def print_description
|
|
21
|
+
puts "\t#{@name} (#{@coverage})"
|
|
22
|
+
@files.each do |file|
|
|
23
|
+
file.print_description
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def html_value
|
|
28
|
+
@file_templates = ""
|
|
29
|
+
@files.each do |file|
|
|
30
|
+
@file_templates << file.html_value
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
Function.template("target").result(binding)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Class methods
|
|
37
|
+
|
|
38
|
+
def self.map (dictionary)
|
|
39
|
+
name = dictionary["name"]
|
|
40
|
+
coverage = dictionary["coverage"]
|
|
41
|
+
files = dictionary["files"].map { |file| Source.map(file)}
|
|
42
|
+
files = files.sort! { |lhs, rhs| lhs.coverage <=> rhs.coverage }
|
|
43
|
+
|
|
44
|
+
Target.new(name, coverage, files)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
end
|
|
48
|
+
end
|
data/lib/xcov/options.rb
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
require "fastlane_core"
|
|
2
|
+
require "credentials_manager"
|
|
3
|
+
|
|
4
|
+
module Xcov
|
|
5
|
+
class Options
|
|
6
|
+
|
|
7
|
+
def self.available_options
|
|
8
|
+
containing = FastlaneCore::Helper.fastlane_enabled? ? './fastlane' : '.'
|
|
9
|
+
|
|
10
|
+
[
|
|
11
|
+
FastlaneCore::ConfigItem.new(key: :workspace,
|
|
12
|
+
short_option: "-w",
|
|
13
|
+
env_name: "XCOV_WORKSPACE",
|
|
14
|
+
optional: true,
|
|
15
|
+
description: "Path the workspace file",
|
|
16
|
+
verify_block: proc do |value|
|
|
17
|
+
v = File.expand_path(value.to_s)
|
|
18
|
+
raise "Workspace file not found at path '#{v}'".red unless File.exist?(v)
|
|
19
|
+
raise "Workspace file invalid".red unless File.directory?(v)
|
|
20
|
+
raise "Workspace file is not a workspace, must end with .xcworkspace".red unless v.include?(".xcworkspace")
|
|
21
|
+
end),
|
|
22
|
+
FastlaneCore::ConfigItem.new(key: :project,
|
|
23
|
+
short_option: "-p",
|
|
24
|
+
optional: true,
|
|
25
|
+
env_name: "XCOV_PROJECT",
|
|
26
|
+
description: "Path the project file",
|
|
27
|
+
verify_block: proc do |value|
|
|
28
|
+
v = File.expand_path(value.to_s)
|
|
29
|
+
raise "Project file not found at path '#{v}'".red unless File.exist?(v)
|
|
30
|
+
raise "Project file invalid".red unless File.directory?(v)
|
|
31
|
+
raise "Project file is not a project file, must end with .xcodeproj".red unless v.include?(".xcodeproj")
|
|
32
|
+
end),
|
|
33
|
+
FastlaneCore::ConfigItem.new(key: :scheme,
|
|
34
|
+
short_option: "-s",
|
|
35
|
+
optional: true,
|
|
36
|
+
env_name: "XCOV_SCHEME",
|
|
37
|
+
description: "The project's scheme. Make sure it's marked as `Shared`"),
|
|
38
|
+
FastlaneCore::ConfigItem.new(key: :derived_data_path,
|
|
39
|
+
short_option: "-j",
|
|
40
|
+
env_name: "XCOV_DERIVED_DATA_PATH",
|
|
41
|
+
description: "The directory where build products and other derived data will go",
|
|
42
|
+
optional: true),
|
|
43
|
+
FastlaneCore::ConfigItem.new(key: :output_directory,
|
|
44
|
+
short_option: "-o",
|
|
45
|
+
env_name: "XCOV_OUTPUT_DIRECTORY",
|
|
46
|
+
description: "The directory in which all reports will be stored",
|
|
47
|
+
default_value: File.join(containing, "xcov_report")),
|
|
48
|
+
FastlaneCore::ConfigItem.new(key: :slack_url,
|
|
49
|
+
short_option: "-i",
|
|
50
|
+
env_name: "SLACK_URL",
|
|
51
|
+
description: "Create an Incoming WebHook for your Slack group to post results there",
|
|
52
|
+
optional: true,
|
|
53
|
+
verify_block: proc do |value|
|
|
54
|
+
raise "Invalid URL, must start with https://" unless value.start_with? "https://"
|
|
55
|
+
end),
|
|
56
|
+
FastlaneCore::ConfigItem.new(key: :slack_channel,
|
|
57
|
+
short_option: "-e",
|
|
58
|
+
env_name: "XCOV_SLACK_CHANNEL",
|
|
59
|
+
description: "#channel or @username",
|
|
60
|
+
optional: true),
|
|
61
|
+
FastlaneCore::ConfigItem.new(key: :skip_slack,
|
|
62
|
+
description: "Don't publish to slack, even when an URL is given",
|
|
63
|
+
is_string: false,
|
|
64
|
+
default_value: false)
|
|
65
|
+
]
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
end
|
|
69
|
+
end
|
data/lib/xcov/runner.rb
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
require 'pty'
|
|
2
|
+
require 'open3'
|
|
3
|
+
require 'fileutils'
|
|
4
|
+
require 'terminal-table'
|
|
5
|
+
require 'xcov-core'
|
|
6
|
+
require 'pathname'
|
|
7
|
+
require 'json'
|
|
8
|
+
|
|
9
|
+
module Xcov
|
|
10
|
+
class Runner
|
|
11
|
+
|
|
12
|
+
def run
|
|
13
|
+
report_json = parse_xccoverage
|
|
14
|
+
generate_xcov_report(report_json)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def parse_xccoverage
|
|
18
|
+
# Find .xccoverage file
|
|
19
|
+
product_builds_path = Pathname.new(Xcov.project.default_build_settings(key: "SYMROOT"))
|
|
20
|
+
test_logs_path = product_builds_path.parent.parent + "Logs/Test/"
|
|
21
|
+
xccoverage_files = Dir["#{test_logs_path}*.xccoverage"].sort_by { |filename| File.mtime(filename) }
|
|
22
|
+
|
|
23
|
+
unless test_logs_path.directory? && !xccoverage_files.empty?
|
|
24
|
+
ErrorHandler.handle_error("CoverageNotFound")
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
Xcov::Core::Parser.parse(xccoverage_files.first)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def generate_xcov_report report_json
|
|
31
|
+
# Create output path
|
|
32
|
+
output_path = Xcov.config[:output_directory]
|
|
33
|
+
FileUtils.mkdir_p(output_path)
|
|
34
|
+
resources_path = File.join(output_path, "resources")
|
|
35
|
+
FileUtils.mkdir_p(resources_path)
|
|
36
|
+
|
|
37
|
+
# Copy images to output resources folder
|
|
38
|
+
Dir[File.join(File.dirname(__FILE__), "../../assets/images/*")].each do |path|
|
|
39
|
+
FileUtils.cp_r(path, resources_path)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# Copy stylesheets to output resources folder
|
|
43
|
+
Dir[File.join(File.dirname(__FILE__), "../../assets/stylesheets/*")].each do |path|
|
|
44
|
+
FileUtils.cp_r(path, resources_path)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# Copy javascripts to output resources folder
|
|
48
|
+
Dir[File.join(File.dirname(__FILE__), "../../assets/javascripts/*")].each do |path|
|
|
49
|
+
FileUtils.cp_r(path, resources_path)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# Convert report to xCov model objects
|
|
53
|
+
report = Report.map(report_json)
|
|
54
|
+
|
|
55
|
+
# Create HTML report
|
|
56
|
+
File.open(File.join(output_path, "index.html"), "wb") do |file|
|
|
57
|
+
file.puts report.html_value
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# Post result
|
|
61
|
+
SlackPoster.new.run(report)
|
|
62
|
+
|
|
63
|
+
# Print output
|
|
64
|
+
table_rows = []
|
|
65
|
+
report.targets.each do |target|
|
|
66
|
+
table_rows << [target.name, target.displayable_coverage]
|
|
67
|
+
end
|
|
68
|
+
puts Terminal::Table.new({
|
|
69
|
+
title: "xCov Coverage Report".green,
|
|
70
|
+
rows: table_rows
|
|
71
|
+
})
|
|
72
|
+
puts ""
|
|
73
|
+
|
|
74
|
+
# Raise exception in case of failure
|
|
75
|
+
raise "Unable to create coverage report" if report.nil?
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
end
|
|
79
|
+
end
|