Skip to content

Commit 9d9c32c

Browse files
committed
fix: configurable rebranding
- accept unbranded --yml-path in the new cli - add configurable rebranding for options expecting env vars - make the branding configurable through the click context user data obj - add the BrandedOption and CodecovBrandedOption classes for having env vars for the options follow the branding passed in the context - also makes the codecov-cli source in the prevent-cli pyproject editable
1 parent c281903 commit 9d9c32c

10 files changed

Lines changed: 1052 additions & 23 deletions

File tree

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
from enum import Enum
2+
3+
4+
class Branding(Enum):
5+
CODECOV = "codecov"
6+
PREVENT = "prevent"

codecov-cli/codecov_cli/commands/base_picking.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,12 @@
44
import click
55
import sentry_sdk
66

7-
from codecov_cli.fallbacks import CodecovOption, FallbackFieldEnum
7+
from codecov_cli.fallbacks import (
8+
CodecovOption,
9+
FallbackFieldEnum,
10+
BrandedOption,
11+
BrandedCodecovOption,
12+
)
813
from codecov_cli.helpers.args import get_cli_args
914
from codecov_cli.helpers.encoder import slug_without_subgroups_is_invalid
1015
from codecov_cli.services.commit.base_picking import base_picking_logic
@@ -29,16 +34,17 @@
2934
)
3035
@click.option(
3136
"--slug",
32-
cls=CodecovOption,
37+
cls=BrandedCodecovOption,
3338
fallback_field=FallbackFieldEnum.slug,
3439
help="owner/repo slug",
35-
envvar="CODECOV_SLUG",
40+
envvar="SLUG",
3641
)
3742
@click.option(
3843
"-t",
3944
"--token",
45+
cls=BrandedOption,
4046
help="Codecov upload token",
41-
envvar="CODECOV_TOKEN",
47+
envvar="TOKEN",
4248
)
4349
@click.option(
4450
"--service",

codecov-cli/codecov_cli/fallbacks.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,3 +39,18 @@ def get_default(
3939
if res is not None:
4040
return res
4141
return None
42+
43+
44+
class BrandedOption(click.Option):
45+
def resolve_envvar_value(self, ctx: click.Context) -> str | None:
46+
actual_var = self.envvar
47+
self.envvar = [
48+
f"{brand.value.upper()}_{actual_var}" for brand in ctx.obj["branding"]
49+
]
50+
res = super().resolve_envvar_value(ctx)
51+
self.envvar = actual_var
52+
return res
53+
54+
55+
class BrandedCodecovOption(CodecovOption, BrandedOption):
56+
pass

codecov-cli/codecov_cli/helpers/options.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
import click
22

3-
from codecov_cli.fallbacks import CodecovOption, FallbackFieldEnum
3+
from codecov_cli.fallbacks import (
4+
CodecovOption,
5+
FallbackFieldEnum,
6+
BrandedCodecovOption,
7+
BrandedOption,
8+
)
49
from codecov_cli.helpers.git import GitService
510

611
_global_options = [
@@ -31,16 +36,17 @@
3136
"-t",
3237
"--token",
3338
help="Codecov upload token",
34-
envvar="CODECOV_TOKEN",
39+
cls=BrandedOption,
40+
envvar="TOKEN",
3541
),
3642
click.option(
3743
"-r",
3844
"--slug",
3945
"slug",
40-
cls=CodecovOption,
46+
cls=BrandedCodecovOption,
4147
fallback_field=FallbackFieldEnum.slug,
4248
help="owner/repo slug used instead of the private repo token in Self-hosted",
43-
envvar="CODECOV_SLUG",
49+
envvar="SLUG",
4450
),
4551
]
4652

codecov-cli/codecov_cli/main.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
from codecov_cli.helpers.config import load_cli_config
2424
from codecov_cli.helpers.logging_utils import configure_logger
2525
from codecov_cli.helpers.versioning_systems import get_versioning_system
26+
from codecov_cli.branding import Branding
2627

2728
logger = logging.getLogger("codecovcli")
2829

@@ -70,7 +71,7 @@ def cli(
7071
ctx.default_map = {ctx.invoked_subcommand: {"token": token}}
7172
ctx.obj["enterprise_url"] = enterprise_url
7273
ctx.obj["disable_telem"] = disable_telem
73-
74+
ctx.obj["branding"] = [Branding.CODECOV]
7475
init_telem(ctx.obj)
7576

7677

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import click
2+
3+
from codecov_cli.fallbacks import BrandedOption
4+
from codecov_cli.branding import Branding
5+
6+
from click.testing import CliRunner
7+
8+
9+
@click.group()
10+
@click.pass_context
11+
def cli(ctx):
12+
ctx.obj = {}
13+
ctx.obj["branding"] = [Branding.CODECOV, Branding.PREVENT]
14+
15+
16+
@cli.command()
17+
@click.option("--test", cls=BrandedOption, envvar="TEST")
18+
@click.pass_context
19+
def hello_world(ctx, test):
20+
click.echo(f"{test}")
21+
22+
23+
def test_branded_option():
24+
runner = CliRunner()
25+
26+
result = runner.invoke(cli, ["hello-world"], env={"CODECOV_TEST": "hello_codecov"})
27+
assert result.output == "hello_codecov\n"
28+
29+
result = runner.invoke(cli, ["hello-world"], env={"PREVENT_TEST": "hello_prevent"})
30+
assert result.output == "hello_prevent\n"
31+
32+
result = runner.invoke(cli, ["hello-world"])
33+
assert result.output == "None\n"

codecov-cli/uv.lock

Lines changed: 680 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

prevent-cli/pyproject.toml

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,7 @@ name = "prevent-cli"
33
version = "0.1.0"
44
description = "Add your description here"
55
readme = "README.md"
6-
authors = [
7-
{ name = "joseph-sentry", email = "joseph.sawaya@sentry.io" }
8-
]
6+
authors = [{ name = "joseph-sentry", email = "joseph.sawaya@sentry.io" }]
97
requires-python = ">=3.9"
108
dependencies = [
119
"click==8.*",
@@ -30,9 +28,8 @@ requires = ["setuptools"]
3028
build-backend = "setuptools.build_meta"
3129

3230
[tool.setuptools]
33-
package-dir = {"" = "src"}
31+
package-dir = { "" = "src" }
3432
packages = ["prevent_cli"]
3533

3634
[tool.uv.sources]
37-
codecov-cli = {path = "../codecov-cli"}
38-
35+
codecov-cli = { path = "../codecov-cli", editable = true }

prevent-cli/src/prevent_cli/main.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
from codecov_cli.helpers.config import load_cli_config
2222
from codecov_cli.helpers.logging_utils import configure_logger
2323
from codecov_cli.helpers.versioning_systems import get_versioning_system
24+
from codecov_cli.branding import Branding
2425

2526
logger = logging.getLogger("codecovcli")
2627

@@ -34,6 +35,7 @@
3435
),
3536
)
3637
@click.option(
38+
"--yml-path",
3739
"--codecov-yml-path",
3840
type=click.Path(path_type=pathlib.Path),
3941
default=None,
@@ -50,7 +52,7 @@
5052
def cli(
5153
ctx: click.Context,
5254
auto_load_params_from: typing.Optional[str],
53-
codecov_yml_path: pathlib.Path,
55+
yml_path: pathlib.Path,
5456
enterprise_url: str,
5557
verbose: bool = False,
5658
disable_telem: bool = False,
@@ -61,13 +63,18 @@ def cli(
6163
ctx.help_option_names = ["-h", "--help"]
6264
ctx.obj["ci_adapter"] = get_ci_adapter(auto_load_params_from)
6365
ctx.obj["versioning_system"] = get_versioning_system()
64-
ctx.obj["codecov_yaml"] = load_cli_config(codecov_yml_path)
66+
ctx.obj["codecov_yaml"] = load_cli_config(yml_path)
6567
if ctx.obj["codecov_yaml"] is None:
6668
logger.debug("No codecov_yaml found")
67-
elif (token := ctx.obj["codecov_yaml"].get("codecov", {}).get("token")) is not None:
68-
ctx.default_map = {ctx.invoked_subcommand: {"token": token}}
69+
else:
70+
token = ctx.obj["codecov_yaml"].get("codecov", {}).get("token") or ctx.obj[
71+
"codecov_yaml"
72+
].get("prevent", {}).get("token")
73+
if token is not None:
74+
ctx.default_map = {ctx.invoked_subcommand: {"token": token}}
6975
ctx.obj["enterprise_url"] = enterprise_url
7076
ctx.obj["disable_telem"] = disable_telem
77+
ctx.obj["branding"] = [Branding.PREVENT, Branding.CODECOV]
7178

7279
init_telem(ctx.obj)
7380

0 commit comments

Comments
 (0)