DebugClients/Python3/coverage/cmdline.py

changeset 0
de9c2efb9d02
child 29
391dc0bc4ae5
equal deleted inserted replaced
-1:000000000000 0:de9c2efb9d02
1 """Command-line support for Coverage."""
2
3 import getopt, sys
4
5 from .execfile import run_python_file
6
7 USAGE = r"""
8 Coverage version %(__version__)s
9 Measure, collect, and report on code coverage in Python programs.
10
11 Usage:
12
13 coverage -x [-p] [-L] MODULE.py [ARG1 ARG2 ...]
14 Execute the module, passing the given command-line arguments, collecting
15 coverage data. With the -p option, include the machine name and process
16 ID in the .coverage file name. With -L, measure coverage even inside the
17 Python installed library, which isn't done by default.
18
19 coverage -e
20 Erase collected coverage data.
21
22 coverage -c
23 Combine data from multiple coverage files (as created by -p option above)
24 and store it into a single file representing the union of the coverage.
25
26 coverage -r [-m] [-i] [-o DIR,...] [FILE1 FILE2 ...]
27 Report on the statement coverage for the given files. With the -m
28 option, show line numbers of the statements that weren't executed.
29
30 coverage -b -d DIR [-i] [-o DIR,...] [FILE1 FILE2 ...]
31 Create an HTML report of the coverage of the given files. Each file gets
32 its own page, with the file listing decorated to show executed, excluded,
33 and missed lines.
34
35 coverage -a [-d DIR] [-i] [-o DIR,...] [FILE1 FILE2 ...]
36 Make annotated copies of the given files, marking statements that
37 are executed with > and statements that are missed with !.
38
39 -d DIR
40 Write output files for -b or -a to this directory.
41
42 -i Ignore errors while reporting or annotating.
43
44 -o DIR,...
45 Omit reporting or annotating files when their filename path starts with
46 a directory listed in the omit list.
47 e.g. coverage -i -r -o c:\python25,lib\enthought\traits
48
49 -h Print this help.
50
51 Coverage data is saved in the file .coverage by default. Set the
52 COVERAGE_FILE environment variable to save it somewhere else.
53 """.strip()
54
55
56 class CoverageScript:
57 """The command-line interface to Coverage."""
58
59 def __init__(self):
60 import coverage
61 self.covpkg = coverage
62 self.coverage = None
63
64 def help(self, error=None):
65 """Display an error message, or the usage for Coverage."""
66 if error:
67 print(error)
68 print("Use -h for help.")
69 else:
70 print((USAGE % self.covpkg.__dict__))
71
72 def command_line(self, argv, help_fn=None):
73 """The bulk of the command line interface to Coverage.
74
75 `argv` is the argument list to process.
76 `help_fn` is the help function to use when something goes wrong.
77
78 """
79 # Collect the command-line options.
80 help_fn = help_fn or self.help
81 OK, ERR = 0, 1
82 settings = {}
83 optmap = {
84 '-a': 'annotate',
85 '-b': 'html',
86 '-c': 'combine',
87 '-d:': 'directory=',
88 '-e': 'erase',
89 '-h': 'help',
90 '-i': 'ignore-errors',
91 '-L': 'pylib',
92 '-m': 'show-missing',
93 '-p': 'parallel-mode',
94 '-r': 'report',
95 '-x': 'execute',
96 '-o:': 'omit=',
97 }
98 short_opts = ''.join([o[1:] for o in list(optmap.keys())])
99 long_opts = list(optmap.values())
100 options, args = getopt.getopt(argv, short_opts, long_opts)
101 for o, a in options:
102 if o in optmap:
103 settings[optmap[o]] = True
104 elif o + ':' in optmap:
105 settings[optmap[o + ':']] = a
106 elif o[2:] in long_opts:
107 settings[o[2:]] = True
108 elif o[2:] + '=' in long_opts:
109 settings[o[2:]+'='] = a
110
111 if settings.get('help'):
112 help_fn()
113 return OK
114
115 # Check for conflicts and problems in the options.
116 for i in ['erase', 'execute']:
117 for j in ['annotate', 'html', 'report', 'combine']:
118 if settings.get(i) and settings.get(j):
119 help_fn("You can't specify the '%s' and '%s' "
120 "options at the same time." % (i, j))
121 return ERR
122
123 args_needed = (settings.get('execute')
124 or settings.get('annotate')
125 or settings.get('html')
126 or settings.get('report'))
127 action = (settings.get('erase')
128 or settings.get('combine')
129 or args_needed)
130 if not action:
131 help_fn(
132 "You must specify at least one of -e, -x, -c, -r, -a, or -b."
133 )
134 return ERR
135 if not args_needed and args:
136 help_fn("Unexpected arguments: %s" % " ".join(args))
137 return ERR
138
139 # Do something.
140 self.coverage = self.covpkg.coverage(
141 data_suffix = bool(settings.get('parallel-mode')),
142 cover_pylib = settings.get('pylib')
143 )
144
145 if settings.get('erase'):
146 self.coverage.erase()
147 else:
148 self.coverage.load()
149
150 if settings.get('execute'):
151 if not args:
152 help_fn("Nothing to do.")
153 return ERR
154
155 # Run the script.
156 self.coverage.start()
157 try:
158 run_python_file(args[0], args)
159 finally:
160 self.coverage.stop()
161 self.coverage.save()
162
163 if settings.get('combine'):
164 self.coverage.combine()
165 self.coverage.save()
166
167 # Remaining actions are reporting, with some common options.
168 show_missing = settings.get('show-missing')
169 directory = settings.get('directory=')
170 report_args = {
171 'morfs': args,
172 'ignore_errors': settings.get('ignore-errors'),
173 }
174
175 omit = settings.get('omit=')
176 if omit:
177 omit = omit.split(',')
178 report_args['omit_prefixes'] = omit
179
180 if settings.get('report'):
181 self.coverage.report(show_missing=show_missing, **report_args)
182 if settings.get('annotate'):
183 self.coverage.annotate(directory=directory, **report_args)
184 if settings.get('html'):
185 self.coverage.html_report(directory=directory, **report_args)
186
187 return OK
188
189
190 def main():
191 """The main entrypoint to Coverage.
192
193 This is installed as the script entrypoint.
194
195 """
196 return CoverageScript().command_line(sys.argv[1:])

eric ide

mercurial