1#!/usr/local/bin/python3.8
2"""Provides an entry point for python scripts and python modules on the controller with the current python interpreter and optional code coverage collection."""
3from __future__ import (absolute_import, division, print_function)
4__metaclass__ = type
5
6import os
7import sys
8
9
10def main():
11    """Main entry point."""
12    name = os.path.basename(__file__)
13    args = [sys.executable]
14
15    coverage_config = os.environ.get('COVERAGE_CONF')
16    coverage_output = os.environ.get('COVERAGE_FILE')
17
18    if coverage_config:
19        if coverage_output:
20            args += ['-m', 'coverage.__main__', 'run', '--rcfile', coverage_config]
21        else:
22            if sys.version_info >= (3, 4):
23                # noinspection PyUnresolvedReferences
24                import importlib.util
25
26                # noinspection PyUnresolvedReferences
27                found = bool(importlib.util.find_spec('coverage'))
28            else:
29                # noinspection PyDeprecation
30                import imp
31
32                try:
33                    # noinspection PyDeprecation
34                    imp.find_module('coverage')
35                    found = True
36                except ImportError:
37                    found = False
38
39            if not found:
40                exit('ERROR: Could not find `coverage` module. Did you use a virtualenv created without --system-site-packages or with the wrong interpreter?')
41
42    if name == 'python.py':
43        if sys.argv[1] == '-c':
44            # prevent simple misuse of python.py with -c which does not work with coverage
45            sys.exit('ERROR: Use `python -c` instead of `python.py -c` to avoid errors when code coverage is collected.')
46    elif name == 'pytest':
47        args += ['-m', 'pytest']
48    else:
49        args += [find_executable(name)]
50
51    args += sys.argv[1:]
52
53    os.execv(args[0], args)
54
55
56def find_executable(name):
57    """
58    :type name: str
59    :rtype: str
60    """
61    path = os.environ.get('PATH', os.path.defpath)
62    seen = set([os.path.abspath(__file__)])
63
64    for base in path.split(os.path.pathsep):
65        candidate = os.path.abspath(os.path.join(base, name))
66
67        if candidate in seen:
68            continue
69
70        seen.add(candidate)
71
72        if os.path.exists(candidate) and os.access(candidate, os.F_OK | os.X_OK):
73            return candidate
74
75    raise Exception('Executable "%s" not found in path: %s' % (name, path))
76
77
78if __name__ == '__main__':
79    main()
80