Skip to content
This repository was archived by the owner on Jan 10, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
### `0.4.1`
- #133 Write down to file when using the formatter

### `0.4.0`
- #130 Split uploader from formatter

Expand Down
2 changes: 1 addition & 1 deletion lib/codecov.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

class SimpleCov::Formatter::Codecov
def format(result, disable_net_blockers = true)
report = Codecov::SimpleCov::Formatter.format(result)
report = Codecov::SimpleCov::Formatter.new.format(result)
Codecov::Uploader.upload(report, disable_net_blockers)
end
end
199 changes: 99 additions & 100 deletions lib/codecov/formatter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,122 +4,121 @@

require_relative 'version'

module Codecov::SimpleCov
class Formatter
def self.format(report)
result = {
'meta' => {
'version' => "codecov-ruby/v#{::Codecov::VERSION}"
module Codecov
module SimpleCov
class Formatter
RESULT_FILE_NAME = 'codecov-result.json'

def format(report)
result = {
'meta' => {
'version' => "codecov-ruby/v#{::Codecov::VERSION}"
}
}
}
result.update(result_to_codecov(report))
result
end

private

# Format SimpleCov coverage data for the Codecov.io API.
#
# @param result [SimpleCov::Result] The coverage data to process.
# @return [Hash]
def self.result_to_codecov(result)
{
'codecov' => result_to_codecov_report(result),
'coverage' => result_to_codecov_coverage(result),
'messages' => result_to_codecov_messages(result)
}
end
result.update(result_to_codecov(report))

def self.result_to_codecov_report(result)
report = file_network.join("\n").concat("\n")
report.concat({ 'coverage' => result_to_codecov_coverage(result) }.to_json)
end

def self.file_network
invalid_file_types = [
'woff', 'eot', 'otf', # fonts
'gif', 'png', 'jpg', 'jpeg', 'psd', # images
'ptt', 'pptx', 'numbers', 'pages', 'md', 'txt', 'xlsx', 'docx', 'doc', 'pdf', 'csv', # docs
'yml', 'yaml', '.gitignore'
].freeze

invalid_directories = [
'node_modules/',
'public/',
'storage/',
'tmp/',
'vendor/'
]

puts [green('==>'), 'Appending file network'].join(' ')
network = []
Dir['**/*'].keep_if do |file|
if File.file?(file) && !file.end_with?(*invalid_file_types) && invalid_directories.none? { |dir| file.include?(dir) }
network.push(file)
result_path = File.join(::SimpleCov.coverage_path, RESULT_FILE_NAME)
if File.writable?(result_path)
File.write(result_path, result['codecov'])
puts "Coverage report generated to #{result_path}.\#{result}"

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@thomasrockhu Was it intended to leave the result in this logging statement? Printing the fairly large (depending on the number of tests) result adds significant clutter to the logged test output.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@davidrunger no not at all, apologies for the spam. I'll make a PR this week and release a new version that prints a shortened version (e.g. 4 ish lines?). Is that acceptable?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@thomasrockhu : No worries; not a big deal! :) Although personally I'd probably prefer that no lines be printed when it is successful, I can on the other hand certainly understand the possible benefits for debugging purposes, and printing 4ish lines also sounds fine to me. 👍Thanks!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@davidrunger, this has been updated in 0.4.3. Let me know if you run into issues!

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you, @thomasrockhu ! 🙇‍♂️ Version 0.4.3 works great. 👍

else
puts "Could not write coverage report to file #{result_path}.\n#{result}"
end

result
end

network.push('<<<<<< network')
network
end
private

# Format SimpleCov coverage data for the Codecov.io API.
#
# @param result [SimpleCov::Result] The coverage data to process.
# @return [Hash]
def result_to_codecov(result)
{
'codecov' => result_to_codecov_report(result),
'coverage' => result_to_codecov_coverage(result),
'messages' => result_to_codecov_messages(result)
}
end

# Format SimpleCov coverage data for the Codecov.io coverage API.
#
# @param result [SimpleCov::Result] The coverage data to process.
# @return [Hash<String, Array>]
def self.result_to_codecov_coverage(result)
result.files.each_with_object({}) do |file, memo|
memo[shortened_filename(file)] = file_to_codecov(file)
def result_to_codecov_report(result)
report = file_network.join("\n").concat("\n")
report.concat({ 'coverage' => result_to_codecov_coverage(result) }.to_json)
end
end

# Format SimpleCov coverage data for the Codecov.io messages API.
#
# @param result [SimpleCov::Result] The coverage data to process.
# @return [Hash<String, Hash>]
def self.result_to_codecov_messages(result)
result.files.each_with_object({}) do |file, memo|
memo[shortened_filename(file)] = file.lines.each_with_object({}) do |line, lines_memo|
lines_memo[line.line_number.to_s] = 'skipped' if line.skipped?
def file_network
invalid_file_types = [
'woff', 'eot', 'otf', # fonts
'gif', 'png', 'jpg', 'jpeg', 'psd', # images
'ptt', 'pptx', 'numbers', 'pages', 'md', 'txt', 'xlsx', 'docx', 'doc', 'pdf', 'csv', # docs
'yml', 'yaml', '.gitignore'
].freeze

invalid_directories = [
'node_modules/',
'public/',
'storage/',
'tmp/',
'vendor/'
]

network = []
Dir['**/*'].keep_if do |file|
if File.file?(file) && !file.end_with?(*invalid_file_types) && invalid_directories.none? { |dir| file.include?(dir) }
network.push(file)
end
end

network.push('<<<<<< network')
network
end
end

# Format coverage data for a single file for the Codecov.io API.
#
# @param file [SimpleCov::SourceFile] The file to process.
# @return [Array<nil, Integer>]
def self.file_to_codecov(file)
# Initial nil is required to offset line numbers.
[nil] + file.lines.map do |line|
if line.skipped?
nil
else
line.coverage
# Format SimpleCov coverage data for the Codecov.io coverage API.
#
# @param result [SimpleCov::Result] The coverage data to process.
# @return [Hash<String, Array>]
def result_to_codecov_coverage(result)
result.files.each_with_object({}) do |file, memo|
memo[shortened_filename(file)] = file_to_codecov(file)
end
end
end

# Get a filename relative to the project root. Based on
# https://github.com/colszowka/simplecov-html, copyright Christoph Olszowka.
#
# @param file [SimpleCov::SourceFile] The file to use.
# @return [String]
def self.shortened_filename(file)
file.filename.gsub(/^#{SimpleCov.root}/, '.').gsub(%r{^\./}, '')
end

# Convenience color methods
def self.black(str)
str.nil? ? '' : "\e[30m#{str}\e[0m"
end
# Format SimpleCov coverage data for the Codecov.io messages API.
#
# @param result [SimpleCov::Result] The coverage data to process.
# @return [Hash<String, Hash>]
def result_to_codecov_messages(result)
result.files.each_with_object({}) do |file, memo|
memo[shortened_filename(file)] = file.lines.each_with_object({}) do |line, lines_memo|
lines_memo[line.line_number.to_s] = 'skipped' if line.skipped?
end
end
end

def self.red(str)
str.nil? ? '' : "\e[31m#{str}\e[0m"
end
# Format coverage data for a single file for the Codecov.io API.
#
# @param file [SimpleCov::SourceFile] The file to process.
# @return [Array<nil, Integer>]
def file_to_codecov(file)
# Initial nil is required to offset line numbers.
[nil] + file.lines.map do |line|
if line.skipped?
nil
else
line.coverage
end
end
end

def self.green(str)
str.nil? ? '' : "\e[32m#{str}\e[0m"
# Get a filename relative to the project root. Based on
# https://github.com/colszowka/simplecov-html, copyright Christoph Olszowka.
#
# @param file [SimpleCov::SourceFile] The file to use.
# @return [String]
def shortened_filename(file)
file.filename.gsub(/^#{::SimpleCov.root}/, '.').gsub(%r{^\./}, '')
end
end
end
end
2 changes: 1 addition & 1 deletion lib/codecov/version.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# frozen_string_literal: true

module Codecov
VERSION = '0.4.0'
VERSION = '0.4.1'
end
12 changes: 6 additions & 6 deletions test/test_codecov.rb
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,10 @@ def upload(success = true)
WebMock.enable!
formatter = SimpleCov::Formatter::Codecov.new
result = stub('SimpleCov::Result', files: [
stub_file('/path/lib/something.rb', [1, 0, 0, nil, 1, nil]),
stub_file('/path/lib/somefile.rb', [1, nil, 1, 1, 1, 0, 0, nil, 1, nil])
stub_file('path/lib/something.rb', [1, 0, 0, nil, 1, nil]),
stub_file('path/lib/somefile.rb', [1, nil, 1, 1, 1, 0, 0, nil, 1, nil])
])
SimpleCov.stubs(:root).returns('/path')
SimpleCov.stubs(:root).returns('path')
success_stubs if success
data = formatter.format(result, false)
puts data
Expand Down Expand Up @@ -665,10 +665,10 @@ def test_filenames_are_shortened_correctly

formatter = SimpleCov::Formatter::Codecov.new
result = stub('SimpleCov::Result', files: [
stub_file('/path/lib/something.rb', []),
stub_file('/path/path/lib/path_somefile.rb', [])
stub_file('path/lib/something.rb', []),
stub_file('path/path/lib/path_somefile.rb', [])
])
SimpleCov.stubs(:root).returns('/path')
SimpleCov.stubs(:root).returns('path')
data = formatter.format(result)
puts data
puts data['params']
Expand Down