Skip to content

Commit e5a15c1

Browse files
committed
feat: --format=total writes just the total number
1 parent 30f1ecf commit e5a15c1

File tree

6 files changed

+36
-14
lines changed

6 files changed

+36
-14
lines changed

CHANGES.rst

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,13 @@ Unreleased
2121
----------
2222

2323
- Text reporting with ``coverage report`` now has a ``--format=`` option.
24-
The original style (``--format=text``) is the default. Now you can also
25-
use ``--format=markdown`` to get the table in Markdown format, thanks to
26-
Steve Oswald in `pull 1479`_, closing `issue 1418`_.
24+
The original style (``--format=text``) is the default.
25+
26+
- Using ``--format=markdown`` will write the table in Markdown format, thanks
27+
to Steve Oswald in `pull 1479`_, closing `issue 1418`_.
28+
29+
- Using ``--format=total`` will write a single total number to the
30+
output. This can be useful for making badges or writing status updates.
2731

2832
- Fixed a mis-measurement of a strange use of wildcard alternatives in
2933
match/case statements, closing `issue 1421`_.

coverage/cmdline.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ class Opts:
9898
)
9999
format = optparse.make_option(
100100
'', '--format', action='store', metavar="FORMAT",
101-
help="Output format, either text (default) or markdown",
101+
help="Output format, either text (default), markdown, or total.",
102102
)
103103
help = optparse.make_option(
104104
'-h', '--help', action='store_true',

coverage/control.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -924,7 +924,7 @@ def report(
924924
`file` is a file-like object, suitable for writing.
925925
926926
`output_format` determines the format, either "text" (the default),
927-
or "markdown".
927+
"markdown", or "total".
928928
929929
`include` is a list of file name patterns. Files that match will be
930930
included in the report. Files matching `omit` will not be included in

coverage/summary.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ def __init__(self, coverage):
1919
self.config = self.coverage.config
2020
self.branches = coverage.get_data().has_arcs()
2121
self.outfile = None
22+
self.output_format = self.config.format or "text"
2223
self.fr_analysis = []
2324
self.skipped_count = 0
2425
self.empty_count = 0
@@ -159,6 +160,15 @@ def report(self, morfs, outfile=None):
159160
if not self.total.n_files and not self.skipped_count:
160161
raise NoDataError("No data to report.")
161162

163+
if self.output_format == "total":
164+
self.write(self.total.pc_covered_str)
165+
else:
166+
self.tabular_report()
167+
168+
return self.total.n_statements and self.total.pc_covered
169+
170+
def tabular_report(self):
171+
"""Writes tabular report formats."""
162172
# Prepare the header line and column sorting.
163173
header = ["Name", "Stmts", "Miss"]
164174
if self.branches:
@@ -221,15 +231,12 @@ def report(self, morfs, outfile=None):
221231
file_suffix = 's' if self.empty_count > 1 else ''
222232
end_lines.append(f"\n{self.empty_count} empty file{file_suffix} skipped.")
223233

224-
text_format = self.config.format or "text"
225-
if text_format == "markdown":
234+
if self.output_format == "markdown":
226235
formatter = self._report_markdown
227236
else:
228237
formatter = self._report_text
229238
formatter(header, lines_values, total_line, end_lines)
230239

231-
return self.total.n_statements and self.total.pc_covered
232-
233240
def report_one_file(self, fr, analysis):
234241
"""Report on just one file, the callback from report()."""
235242
nums = analysis.numbers

doc/cmd.rst

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -518,7 +518,8 @@ as a percentage.
518518
file. Defaults to '.coverage'. [env: COVERAGE_FILE]
519519
--fail-under=MIN Exit with a status of 2 if the total coverage is less
520520
than MIN.
521-
--format=FORMAT Output format, either text (default) or markdown
521+
--format=FORMAT Output format, either text (default), markdown, or
522+
total.
522523
-i, --ignore-errors Ignore errors while reading source files.
523524
--include=PAT1,PAT2,...
524525
Include only files whose paths match one of these
@@ -541,7 +542,7 @@ as a percentage.
541542
--rcfile=RCFILE Specify configuration file. By default '.coveragerc',
542543
'setup.cfg', 'tox.ini', and 'pyproject.toml' are
543544
tried. [env: COVERAGE_RCFILE]
544-
.. [[[end]]] (checksum: 8c671de502a388159689082d906f786a)
545+
.. [[[end]]] (checksum: 167272a29d9e7eb017a592a0e0747a06)
545546
546547
The ``-m`` flag also shows the line numbers of missing statements::
547548

@@ -592,9 +593,11 @@ decimal point in coverage percentages, defaulting to none.
592593

593594
The ``--sort`` option is the name of a column to sort the report by.
594595

595-
The ``--format`` option controls the style of the table. ``--format=text``
596+
The ``--format`` option controls the style of the report. ``--format=text``
596597
creates plain text tables as shown above. ``--format=markdown`` creates
597-
Markdown tables.
598+
Markdown tables. ``--format=total`` writes out a single number, the total
599+
coverage percentage as shown at the end of the tables, but without a percent
600+
sign.
598601

599602
Other common reporting options are described above in :ref:`cmd_reporting`.
600603
These options can also be set in your .coveragerc file. See

tests/test_summary.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,9 @@ def foo():
439439
squeezed = self.squeezed_lines(report)
440440
assert squeezed[4] == "1 file skipped due to complete coverage."
441441

442+
total = self.get_report(cov, output_format="total", skip_covered=True)
443+
assert total == "100\n"
444+
442445
def test_report_skip_covered_longfilename(self):
443446
self.make_file("long_______________filename.py", """
444447
def foo():
@@ -829,7 +832,7 @@ def missing(x, y):
829832
cov = coverage.Coverage(source=["."])
830833
self.start_import_stop(cov, "mymissing")
831834
assert self.stdout() == 'y\nz\n'
832-
report = self.get_report(cov,squeeze=False, output_format="markdown", show_missing=True)
835+
report = self.get_report(cov, squeeze=False, output_format="markdown", show_missing=True)
833836

834837
# | Name | Stmts | Miss | Cover | Missing |
835838
# |------------- | -------: | -------: | ------: | --------: |
@@ -840,6 +843,11 @@ def missing(x, y):
840843
assert report_lines[2] == "| mymissing.py | 14 | 3 | 79% | 3-4, 10 |"
841844
assert report_lines[3] == "| **TOTAL** | **14** | **3** | **79%** | |"
842845

846+
assert self.get_report(cov, output_format="total") == "79\n"
847+
assert self.get_report(cov, output_format="total", precision=2) == "78.57\n"
848+
assert self.get_report(cov, output_format="total", precision=4) == "78.5714\n"
849+
850+
843851
class ReportingReturnValueTest(CoverageTest):
844852
"""Tests of reporting functions returning values."""
845853

0 commit comments

Comments
 (0)