Skip to content

Commit efef4d4

Browse files
committed
add git service option to all commands and get its defaul value from repo's url
2 parents 97ba3ff + 015fe1c commit efef4d4

25 files changed

Lines changed: 626 additions & 148 deletions

codecov_cli/commands/upload.py

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,20 @@ def _turn_env_vars_into_dict(ctx, params, value):
147147
@click.option(
148148
"--plugin", "plugin_names", multiple=True, default=["xcode", "gcov", "pycoverage"]
149149
)
150+
@click.option(
151+
"-Z",
152+
"--fail-on-error",
153+
"fail_on_error",
154+
is_flag=True,
155+
help="Exit with non-zero code in case of error uploading.",
156+
)
157+
@click.option(
158+
"-d",
159+
"--dry-run",
160+
"dry_run",
161+
is_flag=True,
162+
help="Don't upload files to Codecov",
163+
)
150164
@click.option("--use-new-uploader", "is_using_new_uploader", default=False)
151165
@click.option(
152166
"--git-service",
@@ -175,6 +189,8 @@ def do_upload(
175189
slug: typing.Optional[str],
176190
pull_request_number: typing.Optional[str],
177191
is_using_new_uploader: bool,
192+
fail_on_error: bool,
193+
dry_run: bool,
178194
git_service: typing.Optional[str],
179195
):
180196
versioning_system = ctx.obj["versioning_system"]
@@ -228,5 +244,7 @@ def do_upload(
228244
slug=slug,
229245
pull_request_number=pull_request_number,
230246
is_using_new_uploader=is_using_new_uploader,
231-
git_service=git_service
247+
fail_on_error=fail_on_error,
248+
dry_run=dry_run,
249+
git_service=git_service,
232250
)

codecov_cli/helpers/ci_adapters/__init__.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
from codecov_cli.helpers.ci_adapters.jenkins import JenkinsAdapter
1515
from codecov_cli.helpers.ci_adapters.local import LocalAdapter
1616
from codecov_cli.helpers.ci_adapters.teamcity import TeamcityAdapter
17+
from codecov_cli.helpers.ci_adapters.travis_ci import TravisCIAdapter
1718
from codecov_cli.helpers.ci_adapters.woodpeckerci import WoodpeckerCIAdapter
1819

1920
logger = logging.getLogger("codecovcli")
@@ -23,12 +24,14 @@ def get_ci_adapter(provider_name: str = None):
2324
if provider_name:
2425
for provider in get_ci_providers_list():
2526
if provider.get_service_name().lower() == provider_name.lower():
27+
logger.debug(f"Using ci service from provider name: {provider_name}")
2628
return provider
2729
else:
2830
for provider in get_ci_providers_list():
2931
if provider.detect():
30-
logger.info(f"Found ci service {provider._get_service()}")
32+
logger.info(f"ci service found: {provider._get_service()}")
3133
return provider
34+
logger.warning("No ci adapter found")
3235
return None
3336

3437

@@ -48,6 +51,7 @@ def get_ci_providers_list():
4851
JenkinsAdapter(),
4952
CirrusCIAdapter(),
5053
TeamcityAdapter(),
54+
TravisCIAdapter(),
5155
# local adapter should always be the last one
5256
LocalAdapter(),
5357
]

codecov_cli/helpers/ci_adapters/base.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,6 @@ def get_service_name(self):
9797
Returns: string
9898
"""
9999
raise NotImplementedError("`get_service_name()` must be implemented.")
100-
100+
101101
def _get_git_service(self):
102102
return None
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import os
2+
3+
from codecov_cli.helpers.ci_adapters.base import CIAdapterBase
4+
5+
6+
class TravisCIAdapter(CIAdapterBase):
7+
# https://docs.travis-ci.com/user/environment-variables/#default-environment-variables
8+
def detect(self) -> bool:
9+
return (
10+
bool(os.getenv("CI"))
11+
and bool(os.getenv("TRAVIS"))
12+
and not bool(os.getenv("SHIPPABLE"))
13+
)
14+
15+
def _get_commit_sha(self):
16+
return os.getenv("TRAVIS_PULL_REQUEST_SHA") or os.getenv("TRAVIS_COMMIT")
17+
18+
def _get_build_url(self):
19+
return os.getenv("TRAVIS_BUILD_WEB_URL")
20+
21+
def _get_build_code(self):
22+
return os.getenv("TRAVIS_JOB_NUMBER")
23+
24+
def _get_job_code(self):
25+
return os.getenv("TRAVIS_JOB_ID")
26+
27+
def _get_pull_request_number(self):
28+
# The pull request number if the current job is a pull request, “false” if it’s not a pull request.
29+
pr_num = os.getenv("TRAVIS_PULL_REQUEST")
30+
return pr_num if pr_num != "false" else None
31+
32+
def _get_slug(self):
33+
return os.getenv("TRAVIS_REPO_SLUG")
34+
35+
def _get_branch(self):
36+
if os.getenv("TRAVIS_BRANCH") != os.getenv("TRAVIS_TAG"):
37+
return os.getenv("TRAVIS_PULL_REQUEST_BRANCH") or os.getenv("TRAVIS_BRANCH")
38+
return None
39+
40+
def _get_service(self):
41+
return "travis"
42+
43+
def get_service_name(self):
44+
return "Travis"

codecov_cli/helpers/git.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import logging
22
import re
3-
from urllib.parse import urlparse
43
from enum import Enum
4+
from urllib.parse import urlparse
55

66
slug_regex = re.compile(r"[^/\s]+\/[^/\s]+$")
77

codecov_cli/helpers/logging_utils.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,12 @@ def emit(self, record):
5858
self.handleError(record)
5959

6060

61-
def configure_logger(logger):
62-
ch = ClickHandler()
63-
ch.setFormatter(ColorFormatter())
64-
logger.addHandler(ch)
61+
def configure_logger(logger: logging.Logger, log_level=logging.INFO):
62+
# This if exists to avoid an issue where extra handlers would be added by tests that use runner.invoke()
63+
# Which would cause subsequent tests to failed due to repeated log lines
64+
if not logger.hasHandlers():
65+
ch = ClickHandler()
66+
ch.setFormatter(ColorFormatter())
67+
logger.addHandler(ch)
6568
logger.propagate = False
66-
logger.setLevel(logging.DEBUG)
69+
logger.setLevel(log_level)

codecov_cli/helpers/request.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,13 @@ def request_result(resp):
4747
)
4848

4949

50-
def log_warnings_and_errors_if_any(sending_result: RequestResult, process_desc):
50+
def log_warnings_and_errors_if_any(
51+
sending_result: RequestResult, process_desc: str, fail_on_error: bool = False
52+
):
53+
logger.debug(
54+
f"Process {process_desc} complete.",
55+
extra=dict(extra_log_attributes=dict(result=sending_result)),
56+
)
5157
if sending_result.warnings:
5258
number_warnings = len(sending_result.warnings)
5359
pluralization = "s" if number_warnings > 1 else ""
@@ -58,3 +64,5 @@ def log_warnings_and_errors_if_any(sending_result: RequestResult, process_desc):
5864
logger.warning(f"Warning {ind + 1}: {w.message}")
5965
if sending_result.error is not None:
6066
logger.error(f"{process_desc} failed: {sending_result.error.description}")
67+
if fail_on_error:
68+
exit(1)

codecov_cli/helpers/versioning_systems.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,18 @@
1+
import logging
12
import subprocess
23
import typing
34
from pathlib import Path
45

56
from codecov_cli.fallbacks import FallbackFieldEnum
6-
from codecov_cli.helpers.git import parse_slug, parse_git_service
7+
from codecov_cli.helpers.git import parse_git_service, parse_slug
8+
9+
logger = logging.getLogger("codecovcli")
710

811

912
class VersioningSystemInterface(object):
13+
def __repr__(self) -> str:
14+
return str(type(self))
15+
1016
def get_fallback_value(
1117
self, fallback_field: FallbackFieldEnum
1218
) -> typing.Optional[str]:
@@ -24,6 +30,7 @@ def list_relevant_files(
2430
def get_versioning_system() -> VersioningSystemInterface:
2531
for klass in [GitVersioningSystem, NoVersioningSystem]:
2632
if klass.is_available():
33+
logger.debug(f"versioning system found: {klass}")
2734
return klass()
2835

2936

codecov_cli/main.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,21 +30,27 @@
3030
type=click.Path(path_type=pathlib.Path),
3131
)
3232
@click.option("--enterprise-url")
33+
@click.option("-v", "--verbose", "verbose", help="Use verbose logging", is_flag=True)
3334
@click.pass_context
3435
def cli(
3536
ctx: click.Context,
3637
auto_load_params_from: typing.Optional[str],
3738
codecov_yml_path: pathlib.Path,
3839
enterprise_url: str,
40+
verbose: bool = False,
3941
):
40-
configure_logger(logger)
42+
configure_logger(logger, log_level=(logging.DEBUG if verbose else logging.INFO))
4143
ctx.obj["ci_adapter"] = get_ci_adapter(auto_load_params_from)
4244
ctx.obj["versioning_system"] = get_versioning_system()
4345
ctx.obj["codecov_yaml"] = (
4446
yaml.safe_load(codecov_yml_path.read())
4547
if codecov_yml_path is not None
4648
else None
4749
)
50+
if ctx.obj["codecov_yaml"]:
51+
logger.debug(f"Using codecov_yaml from {codecov_yml_path}")
52+
else:
53+
logger.debug("No codecov_yaml found")
4854

4955

5056
cli.add_command(do_upload)

codecov_cli/plugins/__init__.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import logging
12
import typing
23
from importlib import import_module
34

@@ -7,14 +8,23 @@
78
from codecov_cli.plugins.pycoverage import Pycoverage
89
from codecov_cli.plugins.xcode import XcodePlugin
910

11+
logger = logging.getLogger("codecovcli")
12+
1013

1114
class NoopPlugin(object):
1215
def run_preparation(self, collector):
1316
pass
1417

1518

1619
def select_preparation_plugins(cli_config: typing.Dict, plugin_names: typing.List[str]):
17-
return [_get_plugin(cli_config, p) for p in plugin_names]
20+
plugins = [_get_plugin(cli_config, p) for p in plugin_names]
21+
logger.debug(
22+
"Selected preparation plugins",
23+
extra=dict(
24+
extra_log_attributes=dict(selected_plugins=list(map(type, plugins)))
25+
),
26+
)
27+
return plugins
1828

1929

2030
def _load_plugin_from_yaml(plugin_dict: typing.Dict):

0 commit comments

Comments
 (0)