1##
2# Copyright (c) 2023 Apple Inc. All rights reserved.
3#
4# @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5#
6# This file contains Original Code and/or Modifications of Original Code
7# as defined in and that are subject to the Apple Public Source License
8# Version 2.0 (the 'License'). You may not use this file except in
9# compliance with the License. The rights granted to you under the License
10# may not be used to create, or enable the creation or redistribution of,
11# unlawful or unlicensed copies of an Apple operating system, or to
12# circumvent, violate, or enable the circumvention or violation of, any
13# terms of an Apple operating system software license agreement.
14#
15# Please obtain a copy of the License at
16# http://www.opensource.apple.com/apsl/ and read it before using this file.
17#
18# The Original Code and all software distributed under the License are
19# distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20# EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21# INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22# FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23# Please see the License for the specific language governing rights and
24# limitations under the License.
25#
26# @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27##
28
29""" Source code coverage report
30
31    This module tracks source code coverage if requried modules are installed.
32    Coverage tracking is disabled when the `coverage` library is missing.
33"""
34
35import contextlib
36
37try:
38    import coverage
39    COVERAGE_ENABLED = True
40except ImportError:
41    COVERAGE_ENABLED = False
42
43
44def cov_start():
45    """ Start coverage tracking. """
46
47    if not COVERAGE_ENABLED:
48        return None
49
50    cov = coverage.Coverage(auto_data=True)
51    cov.load()
52    cov.start()
53
54    return cov
55
56def cov_stop(cov):
57    """ Stop coverage tracking. """
58
59    if not cov:
60        return
61
62    cov.stop()
63    cov.save()
64
65def cov_html(directory):
66    """ Produce HRML report from current coverage data. """
67
68    if not COVERAGE_ENABLED:
69        print("Coverage module not installed.")
70        return
71
72    cov = coverage.Coverage(auto_data=True)
73    cov.load()
74    cov.html_report(directory=directory,
75                    include=[
76                        '*/lldbmacros/*'
77                    ],
78                    omit=[
79                        '*/lldbmacros/tests/*'
80                    ])
81
82
83class CoverageContext(contextlib.AbstractContextManager):
84    """ Coverage tracking context manager. """
85
86    def __init__(self):
87        self._cov = None
88
89    def __enter__(self):
90        self._cov = cov_start()
91        return super().__enter__()
92
93    def __exit__(self, __exc_type, __exc_value, __traceback):
94        cov_stop(self._cov)
95        return super().__exit__(__exc_type, __exc_value, __traceback)
96