Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion codecov-cli/codecov_cli/commands/upload.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,10 @@ def _turn_env_vars_into_dict(ctx, params, value):
"--name",
help="Custom defined name of the upload. Visible in Codecov UI",
cls=CodecovOption,
fallback_field=FallbackFieldEnum.build_code,
fallback_fields=(
FallbackFieldEnum.job_name,
FallbackFieldEnum.build_code,
),
),
click.option(
"-B",
Expand Down
46 changes: 34 additions & 12 deletions codecov-cli/codecov_cli/fallbacks.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,31 @@ class FallbackFieldEnum(Enum):
pull_request_number = auto()
service = auto()
slug = auto()
job_name = auto()


_FIELDS_WITH_VERSIONING_FALLBACK = frozenset(
{
FallbackFieldEnum.branch,
FallbackFieldEnum.commit_sha,
FallbackFieldEnum.slug,
FallbackFieldEnum.git_service,
}
)


class CodecovOption(click.Option):
fallback_fields: typing.Optional[tuple[FallbackFieldEnum, ...]]

def __init__(self, *args, **kwargs):
self.fallback_field = kwargs.pop("fallback_field", None)
fallback_fields = kwargs.pop("fallback_fields", None)
fallback_field = kwargs.pop("fallback_field", None)
if fallback_fields is not None:
self.fallback_fields = tuple(fallback_fields)
elif fallback_field is not None:
self.fallback_fields = (fallback_field,)
else:
self.fallback_fields = None
super().__init__(*args, **kwargs)

def get_default(
Expand All @@ -27,17 +47,19 @@ def get_default(
res = super().get_default(ctx, call=call)
if res is not None:
return res
if self.fallback_field is not None:
if ctx.obj.get("ci_adapter") is not None:
res = ctx.obj.get("ci_adapter").get_fallback_value(self.fallback_field)
if res is not None:
return res
if ctx.obj.get("versioning_system") is not None:
res = ctx.obj.get("versioning_system").get_fallback_value(
self.fallback_field
)
if res is not None:
return res
if self.fallback_fields is not None:
for field in self.fallback_fields:
if ctx.obj.get("ci_adapter") is not None:
res = ctx.obj.get("ci_adapter").get_fallback_value(field)
if res is not None:
return res
if (
ctx.obj.get("versioning_system") is not None
and field in _FIELDS_WITH_VERSIONING_FALLBACK
):
res = ctx.obj.get("versioning_system").get_fallback_value(field)
if res is not None:
return res
return None


Expand Down
8 changes: 8 additions & 0 deletions codecov-cli/codecov_cli/helpers/ci_adapters/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ def __init__(self):
FallbackFieldEnum.pull_request_number: self._get_pull_request_number,
FallbackFieldEnum.job_code: self._get_job_code,
FallbackFieldEnum.git_service: self._get_git_service,
FallbackFieldEnum.job_name: self._get_job_name,
}

def get_fallback_value(
Expand Down Expand Up @@ -100,3 +101,10 @@ def get_service_name(self):

def _get_git_service(self):
return None

def _get_job_name(self):
"""
Name of the job that gets displayed in the Codecov UI
Returns: string
"""
return None
3 changes: 3 additions & 0 deletions codecov-cli/codecov_cli/helpers/ci_adapters/github_actions.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,3 +87,6 @@ def _get_service(self):

def get_service_name(self):
return "GithubActions"

def _get_job_name(self):
return os.getenv("GITHUB_JOB")
4 changes: 4 additions & 0 deletions codecov-cli/tests/factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ def __init__(self, values_dict: Optional[dict] = None):
FallbackFieldEnum.service: "FAKE_PROVIDER",
FallbackFieldEnum.pull_request_number: "PR_NUMBER",
FallbackFieldEnum.job_code: "JOB_CODE",
FallbackFieldEnum.job_name: None,
FallbackFieldEnum.git_service: "FAKE_PROVIDER",
}
final_values = {**default_values, **values_dict}
Expand Down Expand Up @@ -53,6 +54,9 @@ def _get_pull_request_number(self):
def _get_job_code(self):
return self.values_dict[FallbackFieldEnum.job_code]

def _get_job_name(self):
return self.values_dict.get(FallbackFieldEnum.job_name)

def get_service_name(self):
return self.values_dict[FallbackFieldEnum.git_service]

Expand Down
66 changes: 63 additions & 3 deletions codecov-cli/tests/test_fallbacks.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import click
from click.testing import CliRunner
from unittest.mock import MagicMock

from codecov_cli.fallbacks import BrandedOption
from codecov_cli.branding import Branding

from click.testing import CliRunner
from codecov_cli.fallbacks import BrandedOption, CodecovOption, FallbackFieldEnum


@click.group()
Expand Down Expand Up @@ -31,3 +31,63 @@ def test_branded_option():

result = runner.invoke(cli, ["hello-world"])
assert result.output == "None\n"


@click.group()
def codecov_cli_group():
pass


@codecov_cli_group.command()
@click.option(
"--name",
cls=CodecovOption,
fallback_fields=(
FallbackFieldEnum.job_name,
FallbackFieldEnum.build_code,
),
)
def with_name_fallback(name):
click.echo(name or "")


def test_codecov_option_fallback_fields_uses_second_when_first_is_none():
runner = CliRunner()
adapter = MagicMock()

def get_fallback(field):
return {
FallbackFieldEnum.job_name: None,
FallbackFieldEnum.build_code: "build-42",
}[field]

adapter.get_fallback_value.side_effect = get_fallback

result = runner.invoke(
codecov_cli_group,
["with-name-fallback"],
obj={"ci_adapter": adapter, "versioning_system": None},
)
assert result.exit_code == 0
assert result.output == "build-42\n"


def test_codecov_option_fallback_fields_prefers_first_when_set():
runner = CliRunner()
adapter = MagicMock()

def get_fallback(field):
return {
FallbackFieldEnum.job_name: "my-job",
FallbackFieldEnum.build_code: "build-42",
}[field]

adapter.get_fallback_value.side_effect = get_fallback

result = runner.invoke(
codecov_cli_group,
["with-name-fallback"],
obj={"ci_adapter": adapter, "versioning_system": None},
)
assert result.exit_code == 0
assert result.output == "my-job\n"
Loading