diff --git a/codecov-cli/codecov_cli/branding.py b/codecov-cli/codecov_cli/branding.py new file mode 100644 index 00000000..d65d2693 --- /dev/null +++ b/codecov-cli/codecov_cli/branding.py @@ -0,0 +1,6 @@ +from enum import Enum + + +class Branding(Enum): + CODECOV = "codecov" + PREVENT = "prevent" diff --git a/codecov-cli/codecov_cli/commands/base_picking.py b/codecov-cli/codecov_cli/commands/base_picking.py index f9852945..778677ea 100644 --- a/codecov-cli/codecov_cli/commands/base_picking.py +++ b/codecov-cli/codecov_cli/commands/base_picking.py @@ -4,7 +4,12 @@ import click import sentry_sdk -from codecov_cli.fallbacks import CodecovOption, FallbackFieldEnum +from codecov_cli.fallbacks import ( + BrandedCodecovOption, + BrandedOption, + CodecovOption, + FallbackFieldEnum, +) from codecov_cli.helpers.args import get_cli_args from codecov_cli.helpers.encoder import slug_without_subgroups_is_invalid from codecov_cli.services.commit.base_picking import base_picking_logic @@ -29,16 +34,17 @@ ) @click.option( "--slug", - cls=CodecovOption, + cls=BrandedCodecovOption, fallback_field=FallbackFieldEnum.slug, help="owner/repo slug", - envvar="CODECOV_SLUG", + envvar="SLUG", ) @click.option( "-t", "--token", + cls=BrandedOption, help="Codecov upload token", - envvar="CODECOV_TOKEN", + envvar="TOKEN", ) @click.option( "--service", diff --git a/codecov-cli/codecov_cli/fallbacks.py b/codecov-cli/codecov_cli/fallbacks.py index 2c8f9b33..c7804ef6 100644 --- a/codecov-cli/codecov_cli/fallbacks.py +++ b/codecov-cli/codecov_cli/fallbacks.py @@ -39,3 +39,18 @@ def get_default( if res is not None: return res return None + + +class BrandedOption(click.Option): + def resolve_envvar_value(self, ctx: click.Context) -> typing.Optional[str]: + actual_var = self.envvar + self.envvar = [ + f"{brand.value.upper()}_{actual_var}" for brand in ctx.obj["branding"] + ] + res = super().resolve_envvar_value(ctx) + self.envvar = actual_var + return res + + +class BrandedCodecovOption(CodecovOption, BrandedOption): + pass diff --git a/codecov-cli/codecov_cli/helpers/options.py b/codecov-cli/codecov_cli/helpers/options.py index ae22c633..1d663b10 100644 --- a/codecov-cli/codecov_cli/helpers/options.py +++ b/codecov-cli/codecov_cli/helpers/options.py @@ -1,6 +1,11 @@ import click -from codecov_cli.fallbacks import CodecovOption, FallbackFieldEnum +from codecov_cli.fallbacks import ( + BrandedCodecovOption, + BrandedOption, + CodecovOption, + FallbackFieldEnum, +) from codecov_cli.helpers.git import GitService _global_options = [ @@ -31,16 +36,17 @@ "-t", "--token", help="Codecov upload token", - envvar="CODECOV_TOKEN", + cls=BrandedOption, + envvar="TOKEN", ), click.option( "-r", "--slug", "slug", - cls=CodecovOption, + cls=BrandedCodecovOption, fallback_field=FallbackFieldEnum.slug, help="owner/repo slug used instead of the private repo token in Self-hosted", - envvar="CODECOV_SLUG", + envvar="SLUG", ), ] diff --git a/codecov-cli/codecov_cli/main.py b/codecov-cli/codecov_cli/main.py index ba537b87..2568ef99 100644 --- a/codecov-cli/codecov_cli/main.py +++ b/codecov-cli/codecov_cli/main.py @@ -5,7 +5,7 @@ import click from codecov_cli import __version__ -from codecov_cli.opentelemetry import init_telem +from codecov_cli.branding import Branding from codecov_cli.commands.base_picking import pr_base_picking from codecov_cli.commands.commit import create_commit from codecov_cli.commands.create_report_result import create_report_results @@ -23,6 +23,7 @@ from codecov_cli.helpers.config import load_cli_config from codecov_cli.helpers.logging_utils import configure_logger from codecov_cli.helpers.versioning_systems import get_versioning_system +from codecov_cli.opentelemetry import init_telem logger = logging.getLogger("codecovcli") @@ -70,7 +71,7 @@ def cli( ctx.default_map = {ctx.invoked_subcommand: {"token": token}} ctx.obj["enterprise_url"] = enterprise_url ctx.obj["disable_telem"] = disable_telem - + ctx.obj["branding"] = [Branding.CODECOV] init_telem(ctx.obj) diff --git a/codecov-cli/pyproject.toml b/codecov-cli/pyproject.toml index 468a7d4e..38b12c3f 100644 --- a/codecov-cli/pyproject.toml +++ b/codecov-cli/pyproject.toml @@ -42,7 +42,5 @@ build-backend = "setuptools.build_meta" packages = ["codecov_cli"] [tool.pytest.ini_options] -env = [ - "CODECOV_ENV=test", -] +env = ["CODECOV_ENV=test"] diff --git a/codecov-cli/tests/test_fallbacks.py b/codecov-cli/tests/test_fallbacks.py new file mode 100644 index 00000000..b0490431 --- /dev/null +++ b/codecov-cli/tests/test_fallbacks.py @@ -0,0 +1,33 @@ +import click + +from codecov_cli.fallbacks import BrandedOption +from codecov_cli.branding import Branding + +from click.testing import CliRunner + + +@click.group() +@click.pass_context +def cli(ctx): + ctx.obj = {} + ctx.obj["branding"] = [Branding.CODECOV, Branding.PREVENT] + + +@cli.command() +@click.option("--test", cls=BrandedOption, envvar="TEST") +@click.pass_context +def hello_world(ctx, test): + click.echo(f"{test}") + + +def test_branded_option(): + runner = CliRunner() + + result = runner.invoke(cli, ["hello-world"], env={"CODECOV_TEST": "hello_codecov"}) + assert result.output == "hello_codecov\n" + + result = runner.invoke(cli, ["hello-world"], env={"PREVENT_TEST": "hello_prevent"}) + assert result.output == "hello_prevent\n" + + result = runner.invoke(cli, ["hello-world"]) + assert result.output == "None\n" diff --git a/prevent-cli/preventcli_commands b/prevent-cli/preventcli_commands index c1293074..e166ee68 100644 --- a/prevent-cli/preventcli_commands +++ b/prevent-cli/preventcli_commands @@ -2,7 +2,7 @@ Usage: sentry-prevent-cli [OPTIONS] COMMAND [ARGS]... Options: --auto-load-params-from [CircleCI|GithubActions|GitlabCI|Bitbucket|Bitrise|AppVeyor|Woodpecker|Heroku|DroneCI|BuildKite|AzurePipelines|Jenkins|CirrusCI|Teamcity|Travis|AWSCodeBuild|GoogleCloudBuild|Local] - --codecov-yml-path PATH + --yml-path PATH -u, --enterprise-url, --url TEXT Change the upload host (Enterprise use) -v, --verbose Use verbose logging diff --git a/prevent-cli/pyproject.toml b/prevent-cli/pyproject.toml index 1c6aa486..390186a6 100644 --- a/prevent-cli/pyproject.toml +++ b/prevent-cli/pyproject.toml @@ -4,9 +4,8 @@ version = "0.1.0" description = "Add your description here" readme = "README.md" license-files = ["LICENSE"] -authors = [ - { name = "joseph-sentry", email = "joseph.sawaya@sentry.io" } -] +authors = [{ name = "Sentry", email = "oss@sentry.io" }] + requires-python = ">=3.9" dependencies = [ "codecov-cli>=10.4.0", @@ -20,8 +19,8 @@ requires = ["setuptools"] build-backend = "setuptools.build_meta" [tool.setuptools] -package-dir = {"" = "src"} +package-dir = { "" = "src" } packages = ["prevent_cli"] [tool.uv.sources] -codecov-cli = {path = "../codecov-cli"} +codecov-cli = { path = "../codecov-cli", editable = true } diff --git a/prevent-cli/src/prevent_cli/main.py b/prevent-cli/src/prevent_cli/main.py index 335dd4a1..37742c5b 100644 --- a/prevent-cli/src/prevent_cli/main.py +++ b/prevent-cli/src/prevent_cli/main.py @@ -3,9 +3,8 @@ import typing import click - from codecov_cli import __version__ -from codecov_cli.opentelemetry import init_telem +from codecov_cli.branding import Branding from codecov_cli.commands.base_picking import pr_base_picking from codecov_cli.commands.commit import create_commit from codecov_cli.commands.create_report_result import create_report_results @@ -21,6 +20,7 @@ from codecov_cli.helpers.config import load_cli_config from codecov_cli.helpers.logging_utils import configure_logger from codecov_cli.helpers.versioning_systems import get_versioning_system +from codecov_cli.opentelemetry import init_telem logger = logging.getLogger("codecovcli") @@ -33,8 +33,14 @@ case_sensitive=False, ), ) +@click.option( + "--yml-path", + type=click.Path(path_type=pathlib.Path), + default=None, +) @click.option( "--codecov-yml-path", + hidden=True, type=click.Path(path_type=pathlib.Path), default=None, ) @@ -50,24 +56,31 @@ def cli( ctx: click.Context, auto_load_params_from: typing.Optional[str], - codecov_yml_path: pathlib.Path, + yml_path: typing.Optional[pathlib.Path], + codecov_yml_path: typing.Optional[pathlib.Path], enterprise_url: str, verbose: bool = False, disable_telem: bool = False, ): + branding = [Branding.PREVENT, Branding.CODECOV] ctx.obj["cli_args"] = ctx.params ctx.obj["cli_args"]["version"] = f"cli-{__version__}" configure_logger(logger, log_level=(logging.DEBUG if verbose else logging.INFO)) ctx.help_option_names = ["-h", "--help"] ctx.obj["ci_adapter"] = get_ci_adapter(auto_load_params_from) ctx.obj["versioning_system"] = get_versioning_system() - ctx.obj["codecov_yaml"] = load_cli_config(codecov_yml_path) + ctx.obj["codecov_yaml"] = load_cli_config(yml_path or codecov_yml_path) if ctx.obj["codecov_yaml"] is None: - logger.debug("No codecov_yaml found") - elif (token := ctx.obj["codecov_yaml"].get("codecov", {}).get("token")) is not None: - ctx.default_map = {ctx.invoked_subcommand: {"token": token}} + logger.debug("No yaml found") + else: + token = ctx.obj["codecov_yaml"].get("codecov", {}).get("token") or ctx.obj[ + "codecov_yaml" + ].get("prevent", {}).get("token") + if token is not None: + ctx.default_map = {ctx.invoked_subcommand: {"token": token}} ctx.obj["enterprise_url"] = enterprise_url ctx.obj["disable_telem"] = disable_telem + ctx.obj["branding"] = branding init_telem(ctx.obj) diff --git a/prevent-cli/uv.lock b/prevent-cli/uv.lock index 7d2003cf..05e1d78b 100644 --- a/prevent-cli/uv.lock +++ b/prevent-cli/uv.lock @@ -100,7 +100,7 @@ wheels = [ [[package]] name = "codecov-cli" version = "11.0.3" -source = { directory = "../codecov-cli" } +source = { editable = "../codecov-cli" } dependencies = [ { name = "click" }, { name = "ijson" }, @@ -219,7 +219,7 @@ dependencies = [ ] [package.metadata] -requires-dist = [{ name = "codecov-cli", directory = "../codecov-cli" }] +requires-dist = [{ name = "codecov-cli", editable = "../codecov-cli" }] [[package]] name = "pyyaml"