Skip to content

Commit d0e9a8e

Browse files
authored
CM-51974 - Fix Git remote url resolving by searching in parent dirs; fix handling of multiplied paths to scan (#335)
1 parent 5f874a5 commit d0e9a8e

File tree

2 files changed

+39
-20
lines changed

2 files changed

+39
-20
lines changed

cycode/cli/apps/scan/remote_url_resolver.py

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -99,17 +99,46 @@ def _try_to_get_plastic_remote_url(path: str) -> Optional[str]:
9999

100100
def _try_get_git_remote_url(path: str) -> Optional[str]:
101101
try:
102-
remote_url = git_proxy.get_repo(path).remotes[0].config_reader.get('url')
103-
logger.debug('Found Git remote URL, %s', {'remote_url': remote_url, 'path': path})
102+
repo = git_proxy.get_repo(path, search_parent_directories=True)
103+
remote_url = repo.remotes[0].config_reader.get('url')
104+
logger.debug('Found Git remote URL, %s', {'remote_url': remote_url, 'repo_path': repo.working_dir})
104105
return remote_url
105-
except Exception:
106-
logger.debug('Failed to get Git remote URL. Probably not a Git repository')
106+
except Exception as e:
107+
logger.debug('Failed to get Git remote URL. Probably not a Git repository', exc_info=e)
107108
return None
108109

109110

110-
def try_get_any_remote_url(path: str) -> Optional[str]:
111+
def _try_get_any_remote_url(path: str) -> Optional[str]:
111112
remote_url = _try_get_git_remote_url(path)
112113
if not remote_url:
113114
remote_url = _try_to_get_plastic_remote_url(path)
114115

115116
return remote_url
117+
118+
119+
def get_remote_url_scan_parameter(paths: tuple[str, ...]) -> Optional[str]:
120+
remote_urls = set()
121+
for path in paths:
122+
# FIXME(MarshalX): perf issue. This looping will produce:
123+
# - len(paths) Git subprocess calls in the worst case
124+
# - len(paths)*2 Plastic SCM subprocess calls
125+
remote_url = _try_get_any_remote_url(path)
126+
if remote_url:
127+
remote_urls.add(remote_url)
128+
129+
if len(remote_urls) == 1:
130+
# we are resolving remote_url only if all paths belong to the same repo (identical remote URLs),
131+
# otherwise, the behavior is undefined
132+
remote_url = remote_urls.pop()
133+
134+
logger.debug(
135+
'Single remote URL found. Scan will be associated with organization, %s', {'remote_url': remote_url}
136+
)
137+
return remote_url
138+
139+
logger.debug(
140+
'Multiple different remote URLs found. Scan will not be associated with organization, %s',
141+
{'remote_urls': remote_urls},
142+
)
143+
144+
return None

cycode/cli/apps/scan/scan_parameters.py

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
import os
21
from typing import Optional
32

43
import typer
54

6-
from cycode.cli.apps.scan.remote_url_resolver import try_get_any_remote_url
5+
from cycode.cli.apps.scan.remote_url_resolver import get_remote_url_scan_parameter
76
from cycode.cli.utils.scan_utils import generate_unique_scan_id
87
from cycode.logger import get_logger
98

@@ -29,18 +28,9 @@ def get_scan_parameters(ctx: typer.Context, paths: Optional[tuple[str, ...]] = N
2928

3029
scan_parameters['paths'] = paths
3130

32-
if len(paths) != 1:
33-
logger.debug('Multiple paths provided, going to ignore remote url')
34-
return scan_parameters
35-
36-
if not os.path.isdir(paths[0]):
37-
logger.debug('Path is not a directory, going to ignore remote url')
38-
return scan_parameters
39-
40-
remote_url = try_get_any_remote_url(paths[0])
41-
if remote_url:
42-
# TODO(MarshalX): remove hardcode in context
43-
ctx.obj['remote_url'] = remote_url
44-
scan_parameters['remote_url'] = remote_url
31+
remote_url = get_remote_url_scan_parameter(paths)
32+
# TODO(MarshalX): remove hardcode in context
33+
ctx.obj['remote_url'] = remote_url
34+
scan_parameters['remote_url'] = remote_url
4535

4636
return scan_parameters

0 commit comments

Comments
 (0)