Skip to content
This repository was archived by the owner on Jul 16, 2025. It is now read-only.

Commit 8e2a4f2

Browse files
authored
Merge pull request #87 from codecov/dana/git-service
add git service option to all commands and get its default value from repo's url
2 parents 74423f2 + efef4d4 commit 8e2a4f2

File tree

16 files changed

+187
-34
lines changed

16 files changed

+187
-34
lines changed

codecov_cli/commands/commit.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import click
66

77
from codecov_cli.fallbacks import CodecovOption, FallbackFieldEnum
8+
from codecov_cli.helpers.git import GitService
89
from codecov_cli.services.commit import create_commit_logic
910

1011
logger = logging.getLogger("codecovcli")
@@ -50,10 +51,10 @@
5051
envvar="CODECOV_TOKEN",
5152
)
5253
@click.option(
53-
"--service",
54+
"--git-service",
5455
cls=CodecovOption,
55-
fallback_field=FallbackFieldEnum.service,
56-
help="Specify the service provider of the repo e.g. github",
56+
fallback_field=FallbackFieldEnum.git_service,
57+
type=click.Choice(service.value for service in GitService),
5758
)
5859
@click.pass_context
5960
def create_commit(
@@ -64,7 +65,7 @@ def create_commit(
6465
branch: typing.Optional[str],
6566
slug: typing.Optional[str],
6667
token: typing.Optional[uuid.UUID],
67-
service: typing.Optional[str],
68+
git_service: typing.Optional[str],
6869
):
6970
logger.debug(
7071
"Starting create commit process",
@@ -76,8 +77,8 @@ def create_commit(
7677
branch=branch,
7778
slug=slug,
7879
token=token,
79-
service=service,
80+
service=git_service,
8081
)
8182
),
8283
)
83-
create_commit_logic(commit_sha, parent_sha, pr, branch, slug, token, service)
84+
create_commit_logic(commit_sha, parent_sha, pr, branch, slug, token, git_service)

codecov_cli/commands/create_report_result.py

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

66
from codecov_cli.fallbacks import CodecovOption, FallbackFieldEnum
7+
from codecov_cli.helpers.git import GitService
78
from codecov_cli.services.report import create_report_results_logic
89

910
logger = logging.getLogger("codecovcli")
@@ -29,10 +30,10 @@
2930
required=True,
3031
)
3132
@click.option(
32-
"--service",
33-
help="Git service provider, e.g. github",
33+
"--git-service",
3434
cls=CodecovOption,
35-
fallback_field=FallbackFieldEnum.service,
35+
fallback_field=FallbackFieldEnum.git_service,
36+
type=click.Choice(service.value for service in GitService),
3637
)
3738
@click.option(
3839
"-t",
@@ -47,15 +48,15 @@ def create_report_results(
4748
commit_sha: str,
4849
code: str,
4950
slug: str,
50-
service: str,
51+
git_service: str,
5152
token: uuid.UUID,
5253
):
5354
logger.debug(
5455
"Creating report results",
5556
extra=dict(
5657
extra_log_attributes=dict(
57-
commit_sha=commit_sha, code=code, slug=slug, service=service
58+
commit_sha=commit_sha, code=code, slug=slug, service=git_service
5859
)
5960
),
6061
)
61-
create_report_results_logic(commit_sha, code, slug, service, token)
62+
create_report_results_logic(commit_sha, code, slug, git_service, token)

codecov_cli/commands/get_report_results.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
from codecov_cli.fallbacks import CodecovOption, FallbackFieldEnum
77
from codecov_cli.helpers.encoder import encode_slug
8+
from codecov_cli.helpers.git import GitService
89
from codecov_cli.services.report import send_reports_result_get_request
910

1011
logger = logging.getLogger("codecovcli")
@@ -30,10 +31,10 @@
3031
required=True,
3132
)
3233
@click.option(
33-
"--service",
34-
help="Git service provider, e.g. github",
34+
"--git-service",
3535
cls=CodecovOption,
36-
fallback_field=FallbackFieldEnum.service,
36+
fallback_field=FallbackFieldEnum.git_service,
37+
type=click.Choice(service.value for service in GitService),
3738
)
3839
@click.option(
3940
"-t",
@@ -48,14 +49,14 @@ def get_report_results(
4849
commit_sha: str,
4950
code: str,
5051
slug: str,
51-
service: str,
52+
git_service: str,
5253
token: uuid.UUID,
5354
):
5455
logger.debug(
5556
"Getting report results",
5657
extra=dict(
5758
extra_log_attributes=dict(
58-
commit_sha=commit_sha, code=code, slug=slug, service=service
59+
commit_sha=commit_sha, code=code, slug=slug, service=git_service
5960
)
6061
),
6162
)
@@ -64,6 +65,6 @@ def get_report_results(
6465
commit_sha=commit_sha,
6566
report_code=code,
6667
encoded_slug=encoded_slug,
67-
service=service,
68+
service=git_service,
6869
token=token,
6970
)

codecov_cli/commands/report.py

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

66
from codecov_cli.fallbacks import CodecovOption, FallbackFieldEnum
7+
from codecov_cli.helpers.git import GitService
78
from codecov_cli.services.report import create_report_logic
89

910
logger = logging.getLogger("codecovcli")
@@ -29,10 +30,10 @@
2930
required=True,
3031
)
3132
@click.option(
32-
"--service",
33-
help="Git service provider, e.g. github",
33+
"--git-service",
3434
cls=CodecovOption,
35-
fallback_field=FallbackFieldEnum.service,
35+
fallback_field=FallbackFieldEnum.git_service,
36+
type=click.Choice(service.value for service in GitService),
3637
)
3738
@click.option(
3839
"-t",
@@ -43,17 +44,17 @@
4344
)
4445
@click.pass_context
4546
def create_report(
46-
ctx, commit_sha: str, code: str, slug: str, service: str, token: uuid.UUID
47+
ctx, commit_sha: str, code: str, slug: str, git_service: str, token: uuid.UUID
4748
):
4849
logger.debug(
4950
"Starting create report process",
5051
extra=dict(
5152
extra_log_attributes=dict(
52-
commit_sha=commit_sha, code=code, slug=slug, service=service
53+
commit_sha=commit_sha, code=code, slug=slug, service=git_service
5354
)
5455
),
5556
)
56-
res = create_report_logic(commit_sha, code, slug, service, token)
57+
res = create_report_logic(commit_sha, code, slug, git_service, token)
5758
if not res.error:
5859
logger.info(
5960
"Finished creating report successfully",

codecov_cli/commands/upload.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import click
88

99
from codecov_cli.fallbacks import CodecovOption, FallbackFieldEnum
10+
from codecov_cli.helpers.git import GitService
1011
from codecov_cli.services.legacy_upload import do_upload_logic
1112

1213
logger = logging.getLogger("codecovcli")
@@ -161,6 +162,12 @@ def _turn_env_vars_into_dict(ctx, params, value):
161162
help="Don't upload files to Codecov",
162163
)
163164
@click.option("--use-new-uploader", "is_using_new_uploader", default=False)
165+
@click.option(
166+
"--git-service",
167+
cls=CodecovOption,
168+
fallback_field=FallbackFieldEnum.git_service,
169+
type=click.Choice(service.value for service in GitService),
170+
)
164171
@click.pass_context
165172
def do_upload(
166173
ctx: click.Context,
@@ -184,6 +191,7 @@ def do_upload(
184191
is_using_new_uploader: bool,
185192
fail_on_error: bool,
186193
dry_run: bool,
194+
git_service: typing.Optional[str],
187195
):
188196
versioning_system = ctx.obj["versioning_system"]
189197
codecov_yaml = ctx.obj["codecov_yaml"] or {}
@@ -210,6 +218,7 @@ def do_upload(
210218
branch=branch,
211219
slug=slug,
212220
pull_request_number=pull_request_number,
221+
git_service=git_service,
213222
)
214223
),
215224
)
@@ -237,4 +246,5 @@ def do_upload(
237246
is_using_new_uploader=is_using_new_uploader,
238247
fail_on_error=fail_on_error,
239248
dry_run=dry_run,
249+
git_service=git_service,
240250
)

codecov_cli/fallbacks.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ class FallbackFieldEnum(Enum):
1313
slug = auto()
1414
branch = auto()
1515
service = auto()
16+
git_service = auto()
1617

1718

1819
class CodecovOption(click.Option):

codecov_cli/helpers/ci_adapters/base.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ def __init__(self):
1616
FallbackFieldEnum.service: self._get_service,
1717
FallbackFieldEnum.pull_request_number: self._get_pull_request_number,
1818
FallbackFieldEnum.job_code: self._get_job_code,
19+
FallbackFieldEnum.git_service: self._get_git_service,
1920
}
2021

2122
def get_fallback_value(
@@ -96,3 +97,6 @@ def get_service_name(self):
9697
Returns: string
9798
"""
9899
raise NotImplementedError("`get_service_name()` must be implemented.")
100+
101+
def _get_git_service(self):
102+
return None

codecov_cli/helpers/git.py

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,21 @@
1+
import logging
12
import re
3+
from enum import Enum
24
from urllib.parse import urlparse
35

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

8+
logger = logging.getLogger("codecovcli")
9+
10+
11+
class GitService(Enum):
12+
GITHUB = "github"
13+
GITLAB = "gitlab"
14+
BITBUCKET = "bitbucket"
15+
GITHUB_ENTERPRISE = "github_enterprise"
16+
GITLAB_ENTERPRISE = "gitlab_enterprise"
17+
BITBUCKET_SERVER = "bitbucket_server"
18+
619

720
def parse_slug(remote_repo_url: str):
821
"""
@@ -29,3 +42,43 @@ def parse_slug(remote_repo_url: str):
2942
return None
3043

3144
return path_to_parse
45+
46+
47+
def parse_git_service(remote_repo_url: str):
48+
"""
49+
Extracts git service from git remote urls. returns None if the url is invalid
50+
51+
Possible cases we're considering:
52+
- https://github.com/codecov/codecov-cli.git returns github
53+
- [email protected]:codecov/codecov-cli.git returns github
54+
- https://[email protected]/namespace-codecov/first_repo.git returns bitbucket
55+
"""
56+
services = [service.value for service in GitService]
57+
parsed_url = urlparse(remote_repo_url)
58+
service = None
59+
60+
if remote_repo_url.startswith("https://"):
61+
netloc = parsed_url.netloc
62+
if "@" in netloc:
63+
netloc = netloc.split("@", 1)[1]
64+
if "." in netloc:
65+
netloc = netloc.split(".", 1)[0]
66+
service = netloc
67+
elif remote_repo_url.startswith("git@"):
68+
path = parsed_url.path
69+
if "@" in path:
70+
path = path.split("@", 1)[1]
71+
if ":" in path:
72+
path = path.split(":", 1)[0]
73+
if "." in path:
74+
path = path.split(".", 1)[0]
75+
service = path
76+
77+
if service in services:
78+
return service
79+
else:
80+
logger.warning(
81+
f"Service not found: {service}. Possible services are {services}",
82+
extra=dict(remote_repo_url=remote_repo_url),
83+
)
84+
return None

codecov_cli/helpers/versioning_systems.py

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from pathlib import Path
55

66
from codecov_cli.fallbacks import FallbackFieldEnum
7-
from codecov_cli.helpers.git import parse_slug
7+
from codecov_cli.helpers.git import parse_git_service, parse_slug
88

99
logger = logging.getLogger("codecovcli")
1010

@@ -76,6 +76,24 @@ def get_fallback_value(self, fallback_field: FallbackFieldEnum):
7676

7777
return parse_slug(remote_url)
7878

79+
if fallback_field == FallbackFieldEnum.git_service:
80+
# if there are multiple remotes, we will prioritize using the one called 'origin' if it exsits, else we will use the first one in 'git remote' list
81+
82+
p = subprocess.run(["git", "remote"], capture_output=True)
83+
if not p.stdout:
84+
return None
85+
86+
remotes = p.stdout.decode().strip().splitlines()
87+
remote_name = "origin" if "origin" in remotes else remotes[0]
88+
p = subprocess.run(
89+
["git", "ls-remote", "--get-url", remote_name], capture_output=True
90+
)
91+
if not p.stdout:
92+
return None
93+
94+
remote_url = p.stdout.decode().strip()
95+
return parse_git_service(remote_url)
96+
7997
return None
8098

8199
def get_network_root(self):

codecov_cli/services/legacy_upload/__init__.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ def do_upload_logic(
4747
is_using_new_uploader: bool = False,
4848
fail_on_error: bool = False,
4949
dry_run: bool = False,
50+
git_service: typing.Optional[str],
5051
):
5152
preparation_plugins = select_preparation_plugins(cli_config, plugin_names)
5253
coverage_file_selector = select_coverage_file_finder(
@@ -64,7 +65,7 @@ def do_upload_logic(
6465
else:
6566
sender = LegacyUploadSender()
6667
logger.debug(f"Selected uploader to use: {type(sender)}")
67-
service = (
68+
ci_service = (
6869
ci_adapter.get_fallback_value(FallbackFieldEnum.service)
6970
if ci_adapter is not None
7071
else None
@@ -85,7 +86,8 @@ def do_upload_logic(
8586
build_url,
8687
job_code,
8788
flags,
88-
service,
89+
ci_service,
90+
git_service,
8991
)
9092
else:
9193
logger.info("dry-run option activated. NOT sending data to Codecov.")

0 commit comments

Comments
 (0)