Skip to content

Commit 00e29e5

Browse files
fix: configurable rebranding (#7)
- 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 9f34ed8 commit 00e29e5

File tree

11 files changed

+105
-28
lines changed

11 files changed

+105
-28
lines changed
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+
BrandedCodecovOption,
9+
BrandedOption,
10+
CodecovOption,
11+
FallbackFieldEnum,
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) -> typing.Optional[str]:
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+
BrandedCodecovOption,
5+
BrandedOption,
6+
CodecovOption,
7+
FallbackFieldEnum,
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: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import click
66

77
from codecov_cli import __version__
8-
from codecov_cli.opentelemetry import init_telem
8+
from codecov_cli.branding import Branding
99
from codecov_cli.commands.base_picking import pr_base_picking
1010
from codecov_cli.commands.commit import create_commit
1111
from codecov_cli.commands.create_report_result import create_report_results
@@ -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.opentelemetry import init_telem
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

codecov-cli/pyproject.toml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,5 @@ build-backend = "setuptools.build_meta"
4242
packages = ["codecov_cli"]
4343

4444
[tool.pytest.ini_options]
45-
env = [
46-
"CODECOV_ENV=test",
47-
]
45+
env = ["CODECOV_ENV=test"]
4846

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"

prevent-cli/preventcli_commands

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ Usage: sentry-prevent-cli [OPTIONS] COMMAND [ARGS]...
22

33
Options:
44
--auto-load-params-from [CircleCI|GithubActions|GitlabCI|Bitbucket|Bitrise|AppVeyor|Woodpecker|Heroku|DroneCI|BuildKite|AzurePipelines|Jenkins|CirrusCI|Teamcity|Travis|AWSCodeBuild|GoogleCloudBuild|Local]
5-
--codecov-yml-path PATH
5+
--yml-path PATH
66
-u, --enterprise-url, --url TEXT
77
Change the upload host (Enterprise use)
88
-v, --verbose Use verbose logging

prevent-cli/pyproject.toml

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,8 @@ version = "0.1.0"
44
description = "Add your description here"
55
readme = "README.md"
66
license-files = ["LICENSE"]
7-
authors = [
8-
{ name = "joseph-sentry", email = "joseph.sawaya@sentry.io" }
9-
]
7+
authors = [{ name = "Sentry", email = "oss@sentry.io" }]
8+
109
requires-python = ">=3.9"
1110
dependencies = [
1211
"codecov-cli>=10.4.0",
@@ -20,8 +19,8 @@ requires = ["setuptools"]
2019
build-backend = "setuptools.build_meta"
2120

2221
[tool.setuptools]
23-
package-dir = {"" = "src"}
22+
package-dir = { "" = "src" }
2423
packages = ["prevent_cli"]
2524

2625
[tool.uv.sources]
27-
codecov-cli = {path = "../codecov-cli"}
26+
codecov-cli = { path = "../codecov-cli", editable = true }

prevent-cli/src/prevent_cli/main.py

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,8 @@
33
import typing
44

55
import click
6-
76
from codecov_cli import __version__
8-
from codecov_cli.opentelemetry import init_telem
7+
from codecov_cli.branding import Branding
98
from codecov_cli.commands.base_picking import pr_base_picking
109
from codecov_cli.commands.commit import create_commit
1110
from codecov_cli.commands.create_report_result import create_report_results
@@ -21,6 +20,7 @@
2120
from codecov_cli.helpers.config import load_cli_config
2221
from codecov_cli.helpers.logging_utils import configure_logger
2322
from codecov_cli.helpers.versioning_systems import get_versioning_system
23+
from codecov_cli.opentelemetry import init_telem
2424

2525
logger = logging.getLogger("codecovcli")
2626

@@ -33,8 +33,14 @@
3333
case_sensitive=False,
3434
),
3535
)
36+
@click.option(
37+
"--yml-path",
38+
type=click.Path(path_type=pathlib.Path),
39+
default=None,
40+
)
3641
@click.option(
3742
"--codecov-yml-path",
43+
hidden=True,
3844
type=click.Path(path_type=pathlib.Path),
3945
default=None,
4046
)
@@ -50,24 +56,31 @@
5056
def cli(
5157
ctx: click.Context,
5258
auto_load_params_from: typing.Optional[str],
53-
codecov_yml_path: pathlib.Path,
59+
yml_path: typing.Optional[pathlib.Path],
60+
codecov_yml_path: typing.Optional[pathlib.Path],
5461
enterprise_url: str,
5562
verbose: bool = False,
5663
disable_telem: bool = False,
5764
):
65+
branding = [Branding.PREVENT, Branding.CODECOV]
5866
ctx.obj["cli_args"] = ctx.params
5967
ctx.obj["cli_args"]["version"] = f"cli-{__version__}"
6068
configure_logger(logger, log_level=(logging.DEBUG if verbose else logging.INFO))
6169
ctx.help_option_names = ["-h", "--help"]
6270
ctx.obj["ci_adapter"] = get_ci_adapter(auto_load_params_from)
6371
ctx.obj["versioning_system"] = get_versioning_system()
64-
ctx.obj["codecov_yaml"] = load_cli_config(codecov_yml_path)
72+
ctx.obj["codecov_yaml"] = load_cli_config(yml_path or codecov_yml_path)
6573
if ctx.obj["codecov_yaml"] is None:
66-
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}}
74+
logger.debug("No yaml found")
75+
else:
76+
token = ctx.obj["codecov_yaml"].get("codecov", {}).get("token") or ctx.obj[
77+
"codecov_yaml"
78+
].get("prevent", {}).get("token")
79+
if token is not None:
80+
ctx.default_map = {ctx.invoked_subcommand: {"token": token}}
6981
ctx.obj["enterprise_url"] = enterprise_url
7082
ctx.obj["disable_telem"] = disable_telem
83+
ctx.obj["branding"] = branding
7184

7285
init_telem(ctx.obj)
7386

0 commit comments

Comments
 (0)