diff --git a/CHANGES.rst b/CHANGES.rst index f48b8ad70..7977b1a5b 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -24,6 +24,9 @@ want to know what's different in 5.0 since 4.5.x, see :ref:`whatsnew5x`. Unreleased ---------- +- The ``coverage html`` command now prints a message indicating where the HTML + report was written. Fixes `issue 1195`_. + - Unrecognized options in the configuration file are no longer errors. They are now warnings, to ease the use of coverage across versions. Fixes `issue 1035`_. @@ -32,6 +35,7 @@ Unreleased unsupported type." (`issue 1010`_). .. _issue 1035: https://github.com/nedbat/coveragepy/issues/1035 +.. _issue 1195: https://github.com/nedbat/coveragepy/issues/1195 .. _changes_60b1: diff --git a/coverage/cmdline.py b/coverage/cmdline.py index 111be9f45..14921145a 100644 --- a/coverage/cmdline.py +++ b/coverage/cmdline.py @@ -574,6 +574,7 @@ def command_line(self, argv): concurrency=options.concurrency, check_preimported=True, context=options.context, + messages=True, ) if options.action == "debug": diff --git a/coverage/control.py b/coverage/control.py index c45b12458..958c98da0 100644 --- a/coverage/control.py +++ b/coverage/control.py @@ -103,6 +103,7 @@ def __init__( auto_data=False, timid=None, branch=None, config_file=True, source=None, source_pkgs=None, omit=None, include=None, debug=None, concurrency=None, check_preimported=False, context=None, + messages=False, ): # pylint: disable=too-many-arguments """ Many of these arguments duplicate and override values that can be @@ -173,6 +174,9 @@ def __init__( `context` is a string to use as the :ref:`static context ` label for collected data. + If `messages` is true, some messages will be printed to stdout + indicating what is happening. + .. versionadded:: 4.0 The `concurrency` parameter. @@ -185,6 +189,9 @@ def __init__( .. versionadded:: 5.3 The `source_pkgs` parameter. + .. versionadded:: 6.0 + The `messages` parameter. + """ # data_file=None means no disk file at all. data_file missing means # use the value from the config file. @@ -205,6 +212,7 @@ def __init__( self._warn_unimported_source = True self._warn_preimported_source = check_preimported self._no_warn_slugs = None + self._messages = messages # A record of all the warnings that have been issued. self._warnings = [] @@ -372,6 +380,11 @@ def _warn(self, msg, slug=None, once=False): if once: self._no_warn_slugs.append(slug) + def _message(self, msg): + """Write a message to the user, if configured to do so.""" + if self._messages: + print(msg) + def get_option(self, option_name): """Get an option from the configuration. @@ -969,7 +982,8 @@ def html_report( html_skip_empty=skip_empty, precision=precision, ): reporter = HtmlReporter(self) - return reporter.report(morfs) + ret = reporter.report(morfs) + return ret def xml_report( self, morfs=None, outfile=None, ignore_errors=None, diff --git a/coverage/html.py b/coverage/html.py index 15f35a66d..95e3aa446 100644 --- a/coverage/html.py +++ b/coverage/html.py @@ -363,7 +363,9 @@ def index_file(self): 'totals': self.totals, }) - write_html(os.path.join(self.directory, "index.html"), html) + index_file = os.path.join(self.directory, "index.html") + write_html(index_file, html) + self.coverage._message(f"Wrote HTML report to {index_file}") # Write the latest hashes for next time. self.incr.write() diff --git a/tests/test_cmdline.py b/tests/test_cmdline.py index b214473c9..caaa43c8d 100644 --- a/tests/test_cmdline.py +++ b/tests/test_cmdline.py @@ -55,7 +55,7 @@ class BaseCmdLineTest(CoverageTest): _defaults.Coverage( cover_pylib=None, data_suffix=None, timid=None, branch=None, config_file=True, source=None, include=None, omit=None, debug=None, - concurrency=None, check_preimported=True, context=None, + concurrency=None, check_preimported=True, context=None, messages=True, ) DEFAULT_KWARGS = {name: kw for name, _, kw in _defaults.mock_calls} diff --git a/tests/test_plugins.py b/tests/test_plugins.py index ca0e6dac4..18c085077 100644 --- a/tests/test_plugins.py +++ b/tests/test_plugins.py @@ -6,6 +6,7 @@ import inspect import io import os.path +import re from xml.etree import ElementTree import pytest @@ -256,7 +257,7 @@ def coverage_init(reg, options): out = self.run_command("coverage run main_file.py") assert out == "MAIN\n" out = self.run_command("coverage html") - assert out == "" + assert re.fullmatch(r"Wrote HTML report to htmlcov[/\\]index.html\n", out) @pytest.mark.skipif(env.C_TRACER, reason="This test is only about PyTracer.") diff --git a/tests/test_process.py b/tests/test_process.py index 58915b876..5510efe56 100644 --- a/tests/test_process.py +++ b/tests/test_process.py @@ -1298,7 +1298,7 @@ def test_accented_dot_py(self): # The HTML report uses ascii-encoded HTML entities. out = self.run_command("coverage html") - assert out == "" + assert re.fullmatch(r"Wrote HTML report to htmlcov[/\\]index.html\n", out) self.assert_exists("htmlcov/h\xe2t_py.html") with open("htmlcov/index.html") as indexf: index = indexf.read() @@ -1331,7 +1331,7 @@ def test_accented_directory(self): # The HTML report uses ascii-encoded HTML entities. out = self.run_command("coverage html") - assert out == "" + assert re.fullmatch(r"Wrote HTML report to htmlcov[/\\]index.html\n", out) self.assert_exists("htmlcov/d_5786906b6f0ffeb4_accented_py.html") with open("htmlcov/index.html") as indexf: index = indexf.read()