codecov-cli 0.2.2__tar.gz → 0.3.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {codecov-cli-0.2.2/codecov_cli.egg-info → codecov-cli-0.3.1}/PKG-INFO +1 -1
- codecov-cli-0.3.1/codecov_cli/__init__.py +1 -0
- {codecov-cli-0.2.2 → codecov-cli-0.3.1}/codecov_cli/commands/labelanalysis.py +59 -30
- {codecov-cli-0.2.2 → codecov-cli-0.3.1}/codecov_cli/helpers/config.py +1 -1
- {codecov-cli-0.2.2 → codecov-cli-0.3.1}/codecov_cli/main.py +5 -4
- {codecov-cli-0.2.2 → codecov-cli-0.3.1}/codecov_cli/runners/python_standard_runner.py +37 -24
- {codecov-cli-0.2.2 → codecov-cli-0.3.1}/codecov_cli/runners/types.py +3 -2
- {codecov-cli-0.2.2 → codecov-cli-0.3.1}/codecov_cli/services/staticanalysis/analyzers/general.py +21 -4
- {codecov-cli-0.2.2 → codecov-cli-0.3.1/codecov_cli.egg-info}/PKG-INFO +1 -1
- {codecov-cli-0.2.2 → codecov-cli-0.3.1}/codecov_cli.egg-info/requires.txt +1 -1
- {codecov-cli-0.2.2 → codecov-cli-0.3.1}/setup.py +1 -1
- codecov-cli-0.2.2/codecov_cli/__init__.py +0 -1
- {codecov-cli-0.2.2 → codecov-cli-0.3.1}/LICENSE +0 -0
- {codecov-cli-0.2.2 → codecov-cli-0.3.1}/MANIFEST.in +0 -0
- {codecov-cli-0.2.2 → codecov-cli-0.3.1}/README.md +0 -0
- {codecov-cli-0.2.2 → codecov-cli-0.3.1}/codecov_cli/commands/__init__.py +0 -0
- {codecov-cli-0.2.2 → codecov-cli-0.3.1}/codecov_cli/commands/base_picking.py +0 -0
- {codecov-cli-0.2.2 → codecov-cli-0.3.1}/codecov_cli/commands/commit.py +0 -0
- {codecov-cli-0.2.2 → codecov-cli-0.3.1}/codecov_cli/commands/create_report_result.py +0 -0
- {codecov-cli-0.2.2 → codecov-cli-0.3.1}/codecov_cli/commands/empty_upload.py +0 -0
- {codecov-cli-0.2.2 → codecov-cli-0.3.1}/codecov_cli/commands/get_report_results.py +0 -0
- {codecov-cli-0.2.2 → codecov-cli-0.3.1}/codecov_cli/commands/report.py +0 -0
- {codecov-cli-0.2.2 → codecov-cli-0.3.1}/codecov_cli/commands/send_notifications.py +0 -0
- {codecov-cli-0.2.2 → codecov-cli-0.3.1}/codecov_cli/commands/staticanalysis.py +0 -0
- {codecov-cli-0.2.2 → codecov-cli-0.3.1}/codecov_cli/commands/upload.py +0 -0
- {codecov-cli-0.2.2 → codecov-cli-0.3.1}/codecov_cli/commands/upload_process.py +0 -0
- {codecov-cli-0.2.2 → codecov-cli-0.3.1}/codecov_cli/fallbacks.py +0 -0
- {codecov-cli-0.2.2 → codecov-cli-0.3.1}/codecov_cli/helpers/__init__.py +0 -0
- {codecov-cli-0.2.2 → codecov-cli-0.3.1}/codecov_cli/helpers/ci_adapters/__init__.py +0 -0
- {codecov-cli-0.2.2 → codecov-cli-0.3.1}/codecov_cli/helpers/ci_adapters/appveyor_ci.py +0 -0
- {codecov-cli-0.2.2 → codecov-cli-0.3.1}/codecov_cli/helpers/ci_adapters/azure_pipelines.py +0 -0
- {codecov-cli-0.2.2 → codecov-cli-0.3.1}/codecov_cli/helpers/ci_adapters/base.py +0 -0
- {codecov-cli-0.2.2 → codecov-cli-0.3.1}/codecov_cli/helpers/ci_adapters/bitbucket_ci.py +0 -0
- {codecov-cli-0.2.2 → codecov-cli-0.3.1}/codecov_cli/helpers/ci_adapters/bitrise_ci.py +0 -0
- {codecov-cli-0.2.2 → codecov-cli-0.3.1}/codecov_cli/helpers/ci_adapters/buildkite.py +0 -0
- {codecov-cli-0.2.2 → codecov-cli-0.3.1}/codecov_cli/helpers/ci_adapters/circleci.py +0 -0
- {codecov-cli-0.2.2 → codecov-cli-0.3.1}/codecov_cli/helpers/ci_adapters/cirrus_ci.py +0 -0
- {codecov-cli-0.2.2 → codecov-cli-0.3.1}/codecov_cli/helpers/ci_adapters/codebuild.py +0 -0
- {codecov-cli-0.2.2 → codecov-cli-0.3.1}/codecov_cli/helpers/ci_adapters/droneci.py +0 -0
- {codecov-cli-0.2.2 → codecov-cli-0.3.1}/codecov_cli/helpers/ci_adapters/github_actions.py +0 -0
- {codecov-cli-0.2.2 → codecov-cli-0.3.1}/codecov_cli/helpers/ci_adapters/gitlab_ci.py +0 -0
- {codecov-cli-0.2.2 → codecov-cli-0.3.1}/codecov_cli/helpers/ci_adapters/heroku.py +0 -0
- {codecov-cli-0.2.2 → codecov-cli-0.3.1}/codecov_cli/helpers/ci_adapters/jenkins.py +0 -0
- {codecov-cli-0.2.2 → codecov-cli-0.3.1}/codecov_cli/helpers/ci_adapters/local.py +0 -0
- {codecov-cli-0.2.2 → codecov-cli-0.3.1}/codecov_cli/helpers/ci_adapters/teamcity.py +0 -0
- {codecov-cli-0.2.2 → codecov-cli-0.3.1}/codecov_cli/helpers/ci_adapters/travis_ci.py +0 -0
- {codecov-cli-0.2.2 → codecov-cli-0.3.1}/codecov_cli/helpers/ci_adapters/woodpeckerci.py +0 -0
- {codecov-cli-0.2.2 → codecov-cli-0.3.1}/codecov_cli/helpers/encoder.py +0 -0
- {codecov-cli-0.2.2 → codecov-cli-0.3.1}/codecov_cli/helpers/folder_searcher.py +0 -0
- {codecov-cli-0.2.2 → codecov-cli-0.3.1}/codecov_cli/helpers/git.py +0 -0
- {codecov-cli-0.2.2 → codecov-cli-0.3.1}/codecov_cli/helpers/logging_utils.py +0 -0
- {codecov-cli-0.2.2 → codecov-cli-0.3.1}/codecov_cli/helpers/options.py +0 -0
- {codecov-cli-0.2.2 → codecov-cli-0.3.1}/codecov_cli/helpers/request.py +0 -0
- {codecov-cli-0.2.2 → codecov-cli-0.3.1}/codecov_cli/helpers/validators.py +0 -0
- {codecov-cli-0.2.2 → codecov-cli-0.3.1}/codecov_cli/helpers/versioning_systems.py +0 -0
- {codecov-cli-0.2.2 → codecov-cli-0.3.1}/codecov_cli/plugins/__init__.py +0 -0
- {codecov-cli-0.2.2 → codecov-cli-0.3.1}/codecov_cli/plugins/compress_pycoverage_contexts.py +0 -0
- {codecov-cli-0.2.2 → codecov-cli-0.3.1}/codecov_cli/plugins/gcov.py +0 -0
- {codecov-cli-0.2.2 → codecov-cli-0.3.1}/codecov_cli/plugins/pycoverage.py +0 -0
- {codecov-cli-0.2.2 → codecov-cli-0.3.1}/codecov_cli/plugins/types.py +0 -0
- {codecov-cli-0.2.2 → codecov-cli-0.3.1}/codecov_cli/plugins/xcode.py +0 -0
- {codecov-cli-0.2.2 → codecov-cli-0.3.1}/codecov_cli/runners/__init__.py +0 -0
- {codecov-cli-0.2.2 → codecov-cli-0.3.1}/codecov_cli/runners/dan_runner.py +0 -0
- {codecov-cli-0.2.2 → codecov-cli-0.3.1}/codecov_cli/services/__init__.py +0 -0
- {codecov-cli-0.2.2 → codecov-cli-0.3.1}/codecov_cli/services/commit/__init__.py +0 -0
- {codecov-cli-0.2.2 → codecov-cli-0.3.1}/codecov_cli/services/commit/base_picking.py +0 -0
- {codecov-cli-0.2.2 → codecov-cli-0.3.1}/codecov_cli/services/empty_upload/__init__.py +0 -0
- {codecov-cli-0.2.2 → codecov-cli-0.3.1}/codecov_cli/services/report/__init__.py +0 -0
- {codecov-cli-0.2.2 → codecov-cli-0.3.1}/codecov_cli/services/staticanalysis/__init__.py +0 -0
- {codecov-cli-0.2.2 → codecov-cli-0.3.1}/codecov_cli/services/staticanalysis/analyzers/__init__.py +0 -0
- {codecov-cli-0.2.2 → codecov-cli-0.3.1}/codecov_cli/services/staticanalysis/analyzers/javascript_es6/__init__.py +0 -0
- {codecov-cli-0.2.2 → codecov-cli-0.3.1}/codecov_cli/services/staticanalysis/analyzers/javascript_es6/node_wrappers.py +0 -0
- {codecov-cli-0.2.2 → codecov-cli-0.3.1}/codecov_cli/services/staticanalysis/analyzers/python/__init__.py +0 -0
- {codecov-cli-0.2.2 → codecov-cli-0.3.1}/codecov_cli/services/staticanalysis/analyzers/python/node_wrappers.py +0 -0
- {codecov-cli-0.2.2 → codecov-cli-0.3.1}/codecov_cli/services/staticanalysis/exceptions.py +0 -0
- {codecov-cli-0.2.2 → codecov-cli-0.3.1}/codecov_cli/services/staticanalysis/finders.py +0 -0
- {codecov-cli-0.2.2 → codecov-cli-0.3.1}/codecov_cli/services/staticanalysis/types.py +0 -0
- {codecov-cli-0.2.2 → codecov-cli-0.3.1}/codecov_cli/services/upload/__init__.py +0 -0
- {codecov-cli-0.2.2 → codecov-cli-0.3.1}/codecov_cli/services/upload/coverage_file_finder.py +0 -0
- {codecov-cli-0.2.2 → codecov-cli-0.3.1}/codecov_cli/services/upload/legacy_upload_sender.py +0 -0
- {codecov-cli-0.2.2 → codecov-cli-0.3.1}/codecov_cli/services/upload/network_finder.py +0 -0
- {codecov-cli-0.2.2 → codecov-cli-0.3.1}/codecov_cli/services/upload/upload_collector.py +0 -0
- {codecov-cli-0.2.2 → codecov-cli-0.3.1}/codecov_cli/services/upload/upload_sender.py +0 -0
- {codecov-cli-0.2.2 → codecov-cli-0.3.1}/codecov_cli/services/upload_completion/__init__.py +0 -0
- {codecov-cli-0.2.2 → codecov-cli-0.3.1}/codecov_cli/types.py +0 -0
- {codecov-cli-0.2.2 → codecov-cli-0.3.1}/codecov_cli.egg-info/SOURCES.txt +0 -0
- {codecov-cli-0.2.2 → codecov-cli-0.3.1}/codecov_cli.egg-info/dependency_links.txt +0 -0
- {codecov-cli-0.2.2 → codecov-cli-0.3.1}/codecov_cli.egg-info/entry_points.txt +0 -0
- {codecov-cli-0.2.2 → codecov-cli-0.3.1}/codecov_cli.egg-info/top_level.txt +0 -0
- {codecov-cli-0.2.2 → codecov-cli-0.3.1}/languages/languages.c +0 -0
- {codecov-cli-0.2.2 → codecov-cli-0.3.1}/languages/treesitterjavascript/src/parser.c +0 -0
- {codecov-cli-0.2.2 → codecov-cli-0.3.1}/languages/treesitterjavascript/src/scanner.c +0 -0
- {codecov-cli-0.2.2 → codecov-cli-0.3.1}/languages/treesitterjavascript/src/tree_sitter/parser.h +0 -0
- {codecov-cli-0.2.2 → codecov-cli-0.3.1}/languages/treesitterpython/src/parser.c +0 -0
- {codecov-cli-0.2.2 → codecov-cli-0.3.1}/languages/treesitterpython/src/scanner.cc +0 -0
- {codecov-cli-0.2.2 → codecov-cli-0.3.1}/languages/treesitterpython/src/tree_sitter/parser.h +0 -0
- {codecov-cli-0.2.2 → codecov-cli-0.3.1}/setup.cfg +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.3.1"
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import json
|
|
2
1
|
import logging
|
|
2
|
+
import pathlib
|
|
3
3
|
import time
|
|
4
|
-
from typing import List
|
|
4
|
+
from typing import List, Optional
|
|
5
5
|
|
|
6
6
|
import click
|
|
7
7
|
import requests
|
|
@@ -55,9 +55,16 @@ logger = logging.getLogger("codecovcli")
|
|
|
55
55
|
@click.option(
|
|
56
56
|
"--dry-run",
|
|
57
57
|
"dry_run",
|
|
58
|
-
help=
|
|
58
|
+
help='Print list of tests to run and options that need to be added to the test runner as a space-separated list to stdout. Format is ATS_TESTS_TO_RUN="<options> <test_1> <test_2> ... <test_n>"',
|
|
59
59
|
is_flag=True,
|
|
60
60
|
)
|
|
61
|
+
@click.option(
|
|
62
|
+
"--dry-run-output-path",
|
|
63
|
+
"dry_run_output_path",
|
|
64
|
+
help="Prints the dry-run list into dry_run_output_path (in addition to stdout)",
|
|
65
|
+
type=pathlib.Path,
|
|
66
|
+
default=None,
|
|
67
|
+
)
|
|
61
68
|
@click.pass_context
|
|
62
69
|
def label_analysis(
|
|
63
70
|
ctx: click.Context,
|
|
@@ -67,6 +74,7 @@ def label_analysis(
|
|
|
67
74
|
runner_name: str,
|
|
68
75
|
max_wait_time: str,
|
|
69
76
|
dry_run: bool,
|
|
77
|
+
dry_run_output_path: Optional[pathlib.Path],
|
|
70
78
|
):
|
|
71
79
|
enterprise_url = ctx.obj.get("enterprise_url")
|
|
72
80
|
logger.debug(
|
|
@@ -137,7 +145,12 @@ def label_analysis(
|
|
|
137
145
|
# Retry it
|
|
138
146
|
eid = _send_labelanalysis_request(payload, url, token_header)
|
|
139
147
|
if eid is None:
|
|
140
|
-
_fallback_to_collected_labels(
|
|
148
|
+
_fallback_to_collected_labels(
|
|
149
|
+
requested_labels,
|
|
150
|
+
runner,
|
|
151
|
+
dry_run=dry_run,
|
|
152
|
+
dry_run_output_path=dry_run_output_path,
|
|
153
|
+
)
|
|
141
154
|
return
|
|
142
155
|
|
|
143
156
|
has_result = False
|
|
@@ -151,13 +164,25 @@ def label_analysis(
|
|
|
151
164
|
)
|
|
152
165
|
resp_json = resp_data.json()
|
|
153
166
|
if resp_json["state"] == "finished":
|
|
167
|
+
logger.info(
|
|
168
|
+
"Received list of tests from Codecov",
|
|
169
|
+
extra=dict(
|
|
170
|
+
extra_log_attributes=dict(
|
|
171
|
+
processing_errors=resp_json.get("errors", [])
|
|
172
|
+
)
|
|
173
|
+
),
|
|
174
|
+
)
|
|
154
175
|
request_result = _potentially_calculate_absent_labels(
|
|
155
|
-
|
|
176
|
+
resp_json["result"], requested_labels
|
|
156
177
|
)
|
|
157
178
|
if not dry_run:
|
|
158
179
|
runner.process_labelanalysis_result(request_result)
|
|
159
180
|
else:
|
|
160
|
-
_dry_run_output(
|
|
181
|
+
_dry_run_output(
|
|
182
|
+
LabelAnalysisRequestResult(request_result),
|
|
183
|
+
runner,
|
|
184
|
+
dry_run_output_path,
|
|
185
|
+
)
|
|
161
186
|
return
|
|
162
187
|
if resp_json["state"] == "error":
|
|
163
188
|
logger.error(
|
|
@@ -165,7 +190,10 @@ def label_analysis(
|
|
|
165
190
|
extra=dict(extra_log_attributes=dict(resp_json=resp_json)),
|
|
166
191
|
)
|
|
167
192
|
_fallback_to_collected_labels(
|
|
168
|
-
collected_labels=requested_labels,
|
|
193
|
+
collected_labels=requested_labels,
|
|
194
|
+
runner=runner,
|
|
195
|
+
dry_run=dry_run,
|
|
196
|
+
dry_run_output_path=dry_run_output_path,
|
|
169
197
|
)
|
|
170
198
|
return
|
|
171
199
|
if max_wait_time and (time.monotonic() - start_wait) > max_wait_time:
|
|
@@ -173,7 +201,10 @@ def label_analysis(
|
|
|
173
201
|
f"Exceeded max waiting time of {max_wait_time} seconds. Running all tests.",
|
|
174
202
|
)
|
|
175
203
|
_fallback_to_collected_labels(
|
|
176
|
-
collected_labels=requested_labels,
|
|
204
|
+
collected_labels=requested_labels,
|
|
205
|
+
runner=runner,
|
|
206
|
+
dry_run=dry_run,
|
|
207
|
+
dry_run_output_path=dry_run_output_path,
|
|
177
208
|
)
|
|
178
209
|
return
|
|
179
210
|
logger.info("Waiting more time for result...")
|
|
@@ -183,14 +214,6 @@ def label_analysis(
|
|
|
183
214
|
def _potentially_calculate_absent_labels(
|
|
184
215
|
request_result, requested_labels
|
|
185
216
|
) -> LabelAnalysisRequestResult:
|
|
186
|
-
logger.info(
|
|
187
|
-
"Received list of tests from Codecov",
|
|
188
|
-
extra=dict(
|
|
189
|
-
extra_log_attributes=dict(
|
|
190
|
-
processing_errors=request_result.get("errors", [])
|
|
191
|
-
)
|
|
192
|
-
),
|
|
193
|
-
)
|
|
194
217
|
if request_result["absent_labels"]:
|
|
195
218
|
# This means that Codecov already calculated everything for us
|
|
196
219
|
final_result = LabelAnalysisRequestResult(request_result)
|
|
@@ -285,20 +308,23 @@ def _send_labelanalysis_request(payload, url, token_header):
|
|
|
285
308
|
return eid
|
|
286
309
|
|
|
287
310
|
|
|
288
|
-
def _dry_run_output(
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
311
|
+
def _dry_run_output(
|
|
312
|
+
result: LabelAnalysisRequestResult,
|
|
313
|
+
runner: LabelAnalysisRunnerInterface,
|
|
314
|
+
dry_run_output_path: Optional[pathlib.Path],
|
|
315
|
+
):
|
|
316
|
+
labels_to_run = list(
|
|
317
|
+
set(
|
|
318
|
+
result.absent_labels
|
|
319
|
+
+ result.global_level_labels
|
|
320
|
+
+ result.present_diff_labels
|
|
321
|
+
)
|
|
296
322
|
)
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
323
|
+
output = runner.dry_run_runner_options + sorted(labels_to_run)
|
|
324
|
+
if dry_run_output_path is not None:
|
|
325
|
+
with open(dry_run_output_path, "w") as fd:
|
|
326
|
+
fd.write(" ".join(output) + "\n")
|
|
327
|
+
click.echo(f"ATS_TESTS_TO_RUN=\"{' '.join(output)}\"")
|
|
302
328
|
|
|
303
329
|
|
|
304
330
|
def _fallback_to_collected_labels(
|
|
@@ -306,6 +332,7 @@ def _fallback_to_collected_labels(
|
|
|
306
332
|
runner: LabelAnalysisRunnerInterface,
|
|
307
333
|
*,
|
|
308
334
|
dry_run: bool = False,
|
|
335
|
+
dry_run_output_path: Optional[pathlib.Path] = None,
|
|
309
336
|
) -> dict:
|
|
310
337
|
logger.info("Trying to fallback on collected labels")
|
|
311
338
|
if collected_labels:
|
|
@@ -321,6 +348,8 @@ def _fallback_to_collected_labels(
|
|
|
321
348
|
if not dry_run:
|
|
322
349
|
return runner.process_labelanalysis_result(fake_response)
|
|
323
350
|
else:
|
|
324
|
-
return _dry_run_output(
|
|
351
|
+
return _dry_run_output(
|
|
352
|
+
LabelAnalysisRequestResult(fake_response), runner, dry_run_output_path
|
|
353
|
+
)
|
|
325
354
|
logger.error("Cannot fallback to collected labels because no labels were collected")
|
|
326
355
|
raise click.ClickException("Failed to get list of labels to run")
|
|
@@ -15,6 +15,6 @@ def load_cli_config(codecov_yml_path: pathlib.Path):
|
|
|
15
15
|
with open(codecov_yml_path, "r") as file_stream:
|
|
16
16
|
return yaml.safe_load(file_stream.read())
|
|
17
17
|
logger.warning(
|
|
18
|
-
f"
|
|
18
|
+
f"Config file {codecov_yml_path} not found, or is not a file. Ignoring config."
|
|
19
19
|
)
|
|
20
20
|
return None
|
|
@@ -20,6 +20,8 @@ from codecov_cli.helpers.config import load_cli_config
|
|
|
20
20
|
from codecov_cli.helpers.logging_utils import configure_logger
|
|
21
21
|
from codecov_cli.helpers.versioning_systems import get_versioning_system
|
|
22
22
|
|
|
23
|
+
from . import __version__
|
|
24
|
+
|
|
23
25
|
logger = logging.getLogger("codecovcli")
|
|
24
26
|
|
|
25
27
|
|
|
@@ -34,13 +36,14 @@ logger = logging.getLogger("codecovcli")
|
|
|
34
36
|
@click.option(
|
|
35
37
|
"--codecov-yml-path",
|
|
36
38
|
type=click.Path(path_type=pathlib.Path),
|
|
39
|
+
default=pathlib.Path("codecov.yml"),
|
|
37
40
|
)
|
|
38
41
|
@click.option(
|
|
39
42
|
"--enterprise-url", "--url", "-u", help="Change the upload host (Enterprise use)"
|
|
40
43
|
)
|
|
41
44
|
@click.option("-v", "--verbose", "verbose", help="Use verbose logging", is_flag=True)
|
|
42
45
|
@click.pass_context
|
|
43
|
-
@click.version_option()
|
|
46
|
+
@click.version_option(__version__, prog_name="codecovcli")
|
|
44
47
|
def cli(
|
|
45
48
|
ctx: click.Context,
|
|
46
49
|
auto_load_params_from: typing.Optional[str],
|
|
@@ -52,9 +55,7 @@ def cli(
|
|
|
52
55
|
ctx.help_option_names = ["-h", "--help"]
|
|
53
56
|
ctx.obj["ci_adapter"] = get_ci_adapter(auto_load_params_from)
|
|
54
57
|
ctx.obj["versioning_system"] = get_versioning_system()
|
|
55
|
-
ctx.obj["codecov_yaml"] = (
|
|
56
|
-
load_cli_config(codecov_yml_path) if codecov_yml_path else None
|
|
57
|
-
)
|
|
58
|
+
ctx.obj["codecov_yaml"] = load_cli_config(codecov_yml_path)
|
|
58
59
|
if ctx.obj["codecov_yaml"] is None:
|
|
59
60
|
logger.debug("No codecov_yaml found")
|
|
60
61
|
ctx.obj["enterprise_url"] = enterprise_url
|
|
@@ -53,30 +53,21 @@ class PythonStandardRunnerConfigParams(dict):
|
|
|
53
53
|
"""
|
|
54
54
|
return self.get("strict_mode", False)
|
|
55
55
|
|
|
56
|
-
@property
|
|
57
|
-
def include_curr_dir(self) -> bool:
|
|
58
|
-
"""
|
|
59
|
-
Only valid for 'strict mode'
|
|
60
|
-
Account for the difference 'pytest' vs 'python -m pytest'
|
|
61
|
-
https://docs.pytest.org/en/7.1.x/how-to/usage.html#calling-pytest-through-python-m-pytest
|
|
62
|
-
"""
|
|
63
|
-
return self.get("include_curr_dir", True)
|
|
64
|
-
|
|
65
56
|
|
|
66
57
|
def _include_curr_dir(method):
|
|
67
58
|
"""
|
|
68
59
|
Account for the difference 'pytest' vs 'python -m pytest'
|
|
69
60
|
https://docs.pytest.org/en/7.1.x/how-to/usage.html#calling-pytest-through-python-m-pytest
|
|
61
|
+
Used only in strict_mode
|
|
70
62
|
"""
|
|
71
63
|
|
|
72
64
|
def call_method(self, *args, **kwargs):
|
|
73
|
-
include_curr_dir = self.params.include_curr_dir
|
|
74
65
|
curr_dir = getcwd()
|
|
75
|
-
|
|
76
|
-
|
|
66
|
+
path.append(curr_dir)
|
|
67
|
+
|
|
77
68
|
result = method(self, *args, **kwargs)
|
|
78
|
-
|
|
79
|
-
|
|
69
|
+
|
|
70
|
+
path.remove(curr_dir)
|
|
80
71
|
return result
|
|
81
72
|
|
|
82
73
|
return call_method
|
|
@@ -106,6 +97,9 @@ def _execute_pytest_subprocess(
|
|
|
106
97
|
|
|
107
98
|
|
|
108
99
|
class PythonStandardRunner(LabelAnalysisRunnerInterface):
|
|
100
|
+
|
|
101
|
+
dry_run_runner_options = ["--cov-context=test"]
|
|
102
|
+
|
|
109
103
|
def __init__(self, config_params: Optional[dict] = None) -> None:
|
|
110
104
|
super().__init__()
|
|
111
105
|
if config_params is None:
|
|
@@ -150,10 +144,25 @@ class PythonStandardRunner(LabelAnalysisRunnerInterface):
|
|
|
150
144
|
if p.exitcode != 0 or (result != pytest.ExitCode.OK and result != 0):
|
|
151
145
|
message = f"Pytest exited with non-zero code {result}."
|
|
152
146
|
message += "\nThis is likely not a problem with label-analysis. Check pytest's output and options."
|
|
153
|
-
|
|
147
|
+
if capture_output:
|
|
148
|
+
# If pytest failed but we captured its output the user won't know what's wrong
|
|
149
|
+
# So we need to include that in the error message
|
|
150
|
+
message += "\nPYTEST OUTPUT:"
|
|
151
|
+
message += "\n" + output
|
|
152
|
+
else:
|
|
153
|
+
message += "\n(you can check pytest options on the logs before the test session start)"
|
|
154
154
|
raise click.ClickException(message)
|
|
155
155
|
return output
|
|
156
156
|
|
|
157
|
+
def parse_captured_output_error(self, exp: CalledProcessError) -> str:
|
|
158
|
+
result = ""
|
|
159
|
+
for out_stream in [exp.stdout, exp.stderr]:
|
|
160
|
+
if out_stream:
|
|
161
|
+
if type(out_stream) is bytes:
|
|
162
|
+
out_stream = out_stream.decode()
|
|
163
|
+
result += "\n" + out_stream
|
|
164
|
+
return result
|
|
165
|
+
|
|
157
166
|
def _execute_pytest(self, pytest_args: List[str], capture_output: bool = True):
|
|
158
167
|
"""Handles calling pytest using subprocess.run.
|
|
159
168
|
Raises Exception if pytest fails
|
|
@@ -170,7 +179,14 @@ class PythonStandardRunner(LabelAnalysisRunnerInterface):
|
|
|
170
179
|
except CalledProcessError as exp:
|
|
171
180
|
message = f"Pytest exited with non-zero code {exp.returncode}."
|
|
172
181
|
message += "\nThis is likely not a problem with label-analysis. Check pytest's output and options."
|
|
173
|
-
|
|
182
|
+
|
|
183
|
+
if capture_output:
|
|
184
|
+
# If pytest failed but we captured its output the user won't know what's wrong
|
|
185
|
+
# So we need to include that in the error message
|
|
186
|
+
message += "\nPYTEST OUTPUT:"
|
|
187
|
+
message += self.parse_captured_output_error(exp)
|
|
188
|
+
else:
|
|
189
|
+
message += "\n(you can check pytest options on the logs before the test session start)"
|
|
174
190
|
raise click.ClickException(message)
|
|
175
191
|
if capture_output:
|
|
176
192
|
return result.stdout.decode()
|
|
@@ -230,14 +246,10 @@ class PythonStandardRunner(LabelAnalysisRunnerInterface):
|
|
|
230
246
|
]
|
|
231
247
|
command_array = default_options + tests_to_run
|
|
232
248
|
logger.info(
|
|
233
|
-
"Running tests. (run in verbose mode to get list of tests executed)"
|
|
234
|
-
extra=dict(
|
|
235
|
-
extra_log_attributes=dict(
|
|
236
|
-
pytest_options=default_options,
|
|
237
|
-
executed_tests_count=len(tests_to_run),
|
|
238
|
-
)
|
|
239
|
-
),
|
|
249
|
+
"Running tests. (run in verbose mode to get list of tests executed)"
|
|
240
250
|
)
|
|
251
|
+
logger.info(f" pytest options: \"{' '.join(default_options)}\"")
|
|
252
|
+
logger.info(f" executed tests: {len(tests_to_run)}")
|
|
241
253
|
logger.debug(
|
|
242
254
|
"List of tests executed",
|
|
243
255
|
extra=dict(extra_log_attributes=dict(executed_tests=tests_to_run)),
|
|
@@ -246,5 +258,6 @@ class PythonStandardRunner(LabelAnalysisRunnerInterface):
|
|
|
246
258
|
output = self._execute_pytest_strict(command_array, capture_output=False)
|
|
247
259
|
else:
|
|
248
260
|
output = self._execute_pytest(command_array, capture_output=False)
|
|
249
|
-
logger.info("Finished running tests successfully")
|
|
261
|
+
logger.info(f"Finished running {len(tests_to_run)} tests successfully")
|
|
262
|
+
logger.info(f" pytest options: \"{' '.join(default_options)}\"")
|
|
250
263
|
logger.debug(output)
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from typing import List
|
|
1
|
+
from typing import Dict, List
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
# This is supposed to be a TypedDict,
|
|
@@ -23,7 +23,8 @@ class LabelAnalysisRequestResult(dict):
|
|
|
23
23
|
|
|
24
24
|
|
|
25
25
|
class LabelAnalysisRunnerInterface(object):
|
|
26
|
-
params = None
|
|
26
|
+
params: Dict = None
|
|
27
|
+
dry_run_runner_options: List[str] = []
|
|
27
28
|
|
|
28
29
|
def collect_tests(self) -> List[str]:
|
|
29
30
|
raise NotImplementedError()
|
{codecov-cli-0.2.2 → codecov-cli-0.3.1}/codecov_cli/services/staticanalysis/analyzers/general.py
RENAMED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import hashlib
|
|
2
|
+
from collections import deque
|
|
2
3
|
|
|
3
4
|
|
|
4
5
|
class BaseAnalyzer(object):
|
|
@@ -16,10 +17,26 @@ class BaseAnalyzer(object):
|
|
|
16
17
|
count += 1
|
|
17
18
|
return count
|
|
18
19
|
|
|
19
|
-
def _get_max_nested_conditional(self,
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
20
|
+
def _get_max_nested_conditional(self, head):
|
|
21
|
+
"""Iterates over all nodes in a function body and returns the max nested conditional depth.
|
|
22
|
+
Uses BFS to avoid recursion calls (so we don't throw RecursionError)
|
|
23
|
+
"""
|
|
24
|
+
nodes_to_visit = deque()
|
|
25
|
+
nodes_to_visit.append([head, int(head.type in self.condition_statements)])
|
|
26
|
+
max_nested_depth = 0
|
|
27
|
+
|
|
28
|
+
while nodes_to_visit:
|
|
29
|
+
curr_node, curr_depth = nodes_to_visit.popleft()
|
|
30
|
+
max_nested_depth = max(max_nested_depth, curr_depth)
|
|
31
|
+
# Here is where the depth might change
|
|
32
|
+
# If the current node is a conditional
|
|
33
|
+
is_curr_conditional = curr_node.type in self.condition_statements
|
|
34
|
+
|
|
35
|
+
# Enqueue all child nodes of the curr_node
|
|
36
|
+
for child in curr_node.children:
|
|
37
|
+
nodes_to_visit.append([child, curr_depth + is_curr_conditional])
|
|
38
|
+
|
|
39
|
+
return max_nested_depth
|
|
23
40
|
|
|
24
41
|
def _get_complexity_metrics(self, body_node):
|
|
25
42
|
number_conditions = self._count_elements(
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "0.2.2"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{codecov-cli-0.2.2 → codecov-cli-0.3.1}/codecov_cli/services/staticanalysis/analyzers/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{codecov-cli-0.2.2 → codecov-cli-0.3.1}/languages/treesitterjavascript/src/tree_sitter/parser.h
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|