Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add allow empty coverage flag #54

Merged
merged 2 commits into from
Apr 10, 2023
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
13 changes: 9 additions & 4 deletions .ameba.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,14 @@
Metrics/CyclomaticComplexity:
Description: Disallows methods with a cyclomatic complexity higher than `MaxComplexity`
MaxComplexity: 10
Excluded:
- src/coverage_reporter/parsers/lcov_parser.cr
- src/coverage_reporter/parsers/gcov_parser.cr
- src/coverage_reporter/parsers/coveragepy_parser.cr
Enabled: true
Severity: Warning
Excluded:
- src/coverage_reporter/parsers/lcov_parser.cr
- src/coverage_reporter/parsers/gcov_parser.cr
- src/coverage_reporter/parsers/coveragepy_parser.cr

Lint/PercentArrays:
Enabled: true
Excluded:
- spec/coverage_reporter/cli/cmd_spec.cr
17 changes: 10 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,25 +77,28 @@ coveralls --debug --dry-run

```
$ coveralls -h
Coveralls Coverage Reporter v0.2.11
Coveralls Coverage Reporter v0.3.3
Usage: coveralls [options]
-rTOKEN, --repo-token=TOKEN Sets coveralls repo token, overrides settings in yaml or environment variable
-cPATH, --config-path=PATH Set the coveralls yaml config file location, will default to check '.coveralls.yml'
-bPATH, --base-path=PATH Path to the root folder of the project the coverage was collected in
-fFILENAME, --file=FILENAME Coverage artifact file to be reported, e.g. coverage/lcov.info (detected by default)
-jFLAG, --job-flag=FLAG Coverage job flag name, e.g. Unit Tests
-cr=REF, --compare-ref=REF Git branch name to compare the coverage with
-cs=SHA, --compare-sha=SHA Git commit SHA to compare the coverage with
-p, --parallel Set the parallel flag. Requires webhook for completion (coveralls --done)
-cf, --carryforward Comma-separated list of parallel job flags
-d, --done Call webhook after all parallel jobs (-p) done
-n, --no-logo Do not show Coveralls logo in logs
-q, --quiet Suppress all output
--format=FORMAT Force coverage file format, supported formats: lcov, simplecov, cobertura, jacoco, gcov, golang, python
--allow-empty Allow empty coverage results and exit 0
--compare-ref=REF Git branch name to compare the coverage with
--compare-sha=SHA Git commit SHA to compare the coverage with
--carryforward=FLAGS Comma-separated list of parallel job flags
--service-name=NAME Build service name override
--service-job-id=ID Build job override
--service-build-url=URL Build URL override
--service-job-url=URL Build job URL override
--service-branch=NAME Branch name override
--service-pull-request=NUMBER PR number override
-n, --no-logo Do not show Coveralls logo in logs
-q, --quiet Suppress all output
--debug Debug mode: data being sent to Coveralls will be printed to console
--dry-run Dry run (no request sent)
-v, --version Show version
Expand Down Expand Up @@ -154,7 +157,7 @@ coveralls -f coverage.xml
- Drone
- Buildkite

[Docs on environment variables for other CI support.](https://docs.coveralls.io/supported-ci-services#insert-your-ci-here)
[Docs on environment variables for other CI support.](https://docs.coveralls.io/ci-services#option-1-use-common-environment-variables)

## Extending Support

Expand Down
5 changes: 4 additions & 1 deletion doc/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ These variables are always used if provided.
| `COVERALLS_ENDPOINT` | Coveralls API endpoint. Default: `https://coveralls.io` |
| `COVERALLS_RUN_AT` | A date string for the time that the job ran in RFC 3339 format. Default: current timestamp. |
| `COVERALLS_FLAG_NAME` | Job flag name, e.g. "Unit", "Functional", or "Integration". Will be shown in the Coveralls UI. |
| `COVERALLS_PARALLEL` | set to true when running jobs in parallel, requires a completion webhook. More info here: https://docs.coveralls.io/parallel-build-webhook |
| `COVERALLS_PARALLEL` | set to true when running jobs in parallel, requires a completion webhook. More info here: https://docs.coveralls.io/api-parallel-build-webhook |
| `COVERALLS_CARRYFORWARD_FLAGS` | Comma-separated list of parallel job flags to use carry-forwarding for. |
| `COVERALLS_COMPARE_REF` | Git branch name to compare current report results with. |
| `COVERALLS_COMPARE_SHA` | Git commit SHA to compare current report results with. |
Expand Down Expand Up @@ -62,4 +62,7 @@ repo_name: myorg/myrepo

# The name of your build system
service_name: my-ci

# Coveralls endpoint
endpoint: https://coveralls.io
```
44 changes: 44 additions & 0 deletions spec/coverage_reporter/cli/cmd_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,14 @@ Spectator.describe CoverageReporter::Cli do
after_each { ENV.clear }

describe ".run" do
it "applies defaults" do
reporter = subject.run %w(--dry-run)

expect(reporter.fail_empty).to eq true
expect(reporter.dry_run).to eq true
expect(reporter.parallel).to eq false
end

it "parses overrides" do
reporter = subject.run %w(--service-name overriden --dry-run --no-logo)

Expand All @@ -35,5 +43,41 @@ Spectator.describe CoverageReporter::Cli do
expect(reporter.dry_run).to eq true
expect(reporter.overrides.try(&.to_h)).to eq({} of Symbol => String)
end

it "accepts --allow-empty option" do
reporter = subject.run %w(
--allow-empty
--dry-run
)

expect(reporter.fail_empty).to eq false
end

it "accepts --carryforward option" do
reporter = subject.run %w(
--carryforward "1,2,3"
--dry-run
)

expect(reporter.carryforward).to eq "\"1,2,3\""
end

it "accepts --format option" do
reporter = subject.run %w(
--format lcov
--dry-run
)

expect(reporter.coverage_format).to eq "lcov"
end

it "accepts --filename option" do
reporter = subject.run %w(
--file spec/fixtures/lcov/test.lcov
--dry-run
)

expect(reporter.coverage_file).to eq "spec/fixtures/lcov/test.lcov"
end
end
end
18 changes: 18 additions & 0 deletions spec/coverage_reporter/reporter_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ Spectator.describe CoverageReporter::Reporter do
coverage_file: coverage_file,
coverage_format: coverage_format,
dry_run: false,
fail_empty: fail_empty,
job_flag_name: job_flag_name,
overrides: nil,
parallel: parallel,
Expand All @@ -25,6 +26,7 @@ Spectator.describe CoverageReporter::Reporter do
let(config_path) { nil }
let(coverage_file) { nil }
let(coverage_format) { nil }
let(fail_empty) { true }
let(job_flag_name) { nil }
let(parallel) { false }
let(repo_token) { "test-token" }
Expand Down Expand Up @@ -77,6 +79,22 @@ Spectator.describe CoverageReporter::Reporter do
expect { subject.report }
.to raise_error(CoverageReporter::Reporter::NoSourceFiles)
end

it "makes it fail" do
subject.report
rescue ex : CoverageReporter::Reporter::NoSourceFiles
expect(ex.fail?).to eq true
end

context "when fail_empty is false" do
let(fail_empty) { false }

it "doesn't fail" do
subject.report
rescue ex : CoverageReporter::Reporter::NoSourceFiles
expect(ex.fail?).to eq false
end
end
end
end

Expand Down
5 changes: 5 additions & 0 deletions src/coverage_reporter/base_exception.cr
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
module CoverageReporter
# Exception used in utility logic just to be catched and printed.
class BaseException < Exception
property? fail : Bool

def initialize(@fail : Bool = true)
super()
end
end
end
43 changes: 28 additions & 15 deletions src/coverage_reporter/cli/cmd.cr
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,7 @@ module CoverageReporter::Cli

def run(args = ARGV)
opts = parse_args(args)
red = Colorize::Color256.new(196)
if opts.no_logo?
Log.info "⭐️ Coveralls.io Coverage Reporter v#{CoverageReporter::VERSION}"
else
Log.info " "
Log.info "⠀⠀⠀⠀⠀⠀#{"⣿".colorize(red)}"
Log.info "⠀⠀⠀⠀⠀#{"⣼⣿⣧".colorize(red)}⠀⠀⠀⠀⠀⠀⠀ ⣠⣶⣾⣿⡇⢀⣴⣾⣿⣷⣆ ⣿⣿⠀⣰⣿⡟⢸⣿⣿⣿⡇ ⣿⣿⣿⣷⣦⠀⠀⢠⣿⣿⣿⠀⠀⣿⣿⠁⠀⣼⣿⡇⠀⢀⣴⣾⣿⡷"
Log.info "#{"⠶⣶⣶⣶⣾⣿⣿⣿⣷⣶⣶⣶⠶".colorize(red)} ⣸⣿⡟ ⠀⢠⣿⣿⠃⠈⣿⣿⠀⣿⣿⢠⣿⡿⠀⣿⣿⣧⣤⠀⢸⣿⡇⣠⣿⡿⠀⢠⣿⡟⣿⣿⠀⢸⣿⡿⠀⠀⣿⣿⠃⠀⢸⣿⣧⣄"
Log.info "⠀⠀#{"⠙⢻⣿⣿⣿⣿⣿⡟⠋⠁".colorize(red)}⠀⠀ ⣿⣿⡇⠀ ⢸⣿⣿⠀⣸⣿⡟⠀⣿⣿⣾⡿⠁ ⣿⣿⠛⠛⠀⣿⣿⢿⣿⣏⠀⢀⣿⣿⣁⣿⣿⠀⣾⣿⡇⠀⢸⣿⡿⠀⠀⡀⠙⣿⣿⡆"
Log.info "⠀⠀#{"⢠⣿⣿⣿⠿⣿⣿⣿⡄".colorize(red)}⠀⠀⠀ ⠙⢿⣿⣿⠇⠈⠿⣿⣿⡿⠋⠀⠀⢿⣿⡿⠁⠀⢸⣿⣿⣿⡇⢸⣿⣿⠀⣿⣿⣄⣾⣿⠛⠛⣿⣿⢠⣿⣿⣿ ⣼⣿⣿⣿ ⣿⣿⡿⠋⠀"
Log.info "⠀#{"⢀⣾⠟⠋⠀⠀⠀⠙⠻⣷⡀".colorize(red)}⠀⠀"
Log.info " "
Log.info " v#{CoverageReporter::VERSION}\n\n"
end
greet(opts.no_logo?)

reporter = CoverageReporter::Reporter.new(
base_path: opts.base_path,
Expand All @@ -31,6 +18,7 @@ module CoverageReporter::Cli
coverage_file: opts.filename,
coverage_format: opts.format,
dry_run: opts.dry_run?,
fail_empty: !opts.allow_empty?,
job_flag_name: opts.job_flag_name,
overrides: opts.overrides,
parallel: opts.parallel?,
Expand All @@ -44,7 +32,10 @@ module CoverageReporter::Cli
end

reporter
rescue ex : BaseException | Socket::Error
rescue ex : BaseException
Log.error ex.message
exit(ex.fail? ? 1 : 0)
rescue ex : Socket::Error
Log.error ex.message
exit 1
rescue ex : ArgumentError
Expand Down Expand Up @@ -92,6 +83,7 @@ module CoverageReporter::Cli
property? parallel_done = false
property? dry_run = false
property? debug = false
property? allow_empty = false

# CI options overrides
property service_name : String?
Expand Down Expand Up @@ -170,6 +162,10 @@ module CoverageReporter::Cli
opts.format = format.presence
end

parser.on("--allow-empty", "Allow empty coverage results and exit 0") do
opts.allow_empty = true
end

parser.on("--compare-ref=REF", "Git branch name to compare the coverage with") do |ref|
opts.compare_ref = ref.presence
end
Expand Down Expand Up @@ -237,4 +233,21 @@ module CoverageReporter::Cli
puts option_parser
exit 1
end

private def greet(no_logo : Bool)
red = Colorize::Color256.new(196)
if no_logo
Log.info "⭐️ Coveralls.io Coverage Reporter v#{CoverageReporter::VERSION}"
else
Log.info " "
Log.info "⠀⠀⠀⠀⠀⠀#{"⣿".colorize(red)}"
Log.info "⠀⠀⠀⠀⠀#{"⣼⣿⣧".colorize(red)}⠀⠀⠀⠀⠀⠀⠀ ⣠⣶⣾⣿⡇⢀⣴⣾⣿⣷⣆ ⣿⣿⠀⣰⣿⡟⢸⣿⣿⣿⡇ ⣿⣿⣿⣷⣦⠀⠀⢠⣿⣿⣿⠀⠀⣿⣿⠁⠀⣼⣿⡇⠀⢀⣴⣾⣿⡷"
Log.info "#{"⠶⣶⣶⣶⣾⣿⣿⣿⣷⣶⣶⣶⠶".colorize(red)} ⣸⣿⡟ ⠀⢠⣿⣿⠃⠈⣿⣿⠀⣿⣿⢠⣿⡿⠀⣿⣿⣧⣤⠀⢸⣿⡇⣠⣿⡿⠀⢠⣿⡟⣿⣿⠀⢸⣿⡿⠀⠀⣿⣿⠃⠀⢸⣿⣧⣄"
Log.info "⠀⠀#{"⠙⢻⣿⣿⣿⣿⣿⡟⠋⠁".colorize(red)}⠀⠀ ⣿⣿⡇⠀ ⢸⣿⣿⠀⣸⣿⡟⠀⣿⣿⣾⡿⠁ ⣿⣿⠛⠛⠀⣿⣿⢿⣿⣏⠀⢀⣿⣿⣁⣿⣿⠀⣾⣿⡇⠀⢸⣿⡿⠀⠀⡀⠙⣿⣿⡆"
Log.info "⠀⠀#{"⢠⣿⣿⣿⠿⣿⣿⣿⡄".colorize(red)}⠀⠀⠀ ⠙⢿⣿⣿⠇⠈⠿⣿⣿⡿⠋⠀⠀⢿⣿⡿⠁⠀⢸⣿⣿⣿⡇⢸⣿⣿⠀⣿⣿⣄⣾⣿⠛⠛⣿⣿⢠⣿⣿⣿ ⣼⣿⣿⣿ ⣿⣿⡿⠋⠀"
Log.info "⠀#{"⢀⣾⠟⠋⠀⠀⠀⠙⠻⣷⡀".colorize(red)}⠀⠀"
Log.info " "
Log.info " v#{CoverageReporter::VERSION}\n\n"
end
end
end
2 changes: 2 additions & 0 deletions src/coverage_reporter/parser.cr
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ module CoverageReporter

class NotFound < BaseException
def initialize(@filename : String)
super()
end

def message
Expand All @@ -35,6 +36,7 @@ module CoverageReporter

class InvalidCoverageFormat < BaseException
def initialize(@format : String?)
super()
end

def message
Expand Down
4 changes: 3 additions & 1 deletion src/coverage_reporter/reporter.cr
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ module CoverageReporter
coverage_file,
coverage_format,
dry_run,
fail_empty,
job_flag_name,
overrides,
parallel,
Expand All @@ -30,6 +31,7 @@ module CoverageReporter
@coverage_file : String?,
@coverage_format : String?,
@dry_run : Bool,
@fail_empty : Bool,
@job_flag_name : String?,
@overrides : CI::Options?,
@parallel : Bool,
Expand All @@ -48,7 +50,7 @@ module CoverageReporter
coverage_format: coverage_format,
base_path: base_path,
).parse
raise NoSourceFiles.new unless source_files.size > 0
raise NoSourceFiles.new(fail_empty) unless source_files.size > 0

api = Api::Jobs.new(config, parallel, source_files, Git.info(config))

Expand Down