cycode 1.9.6.dev2__tar.gz → 1.9.6.dev4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/PKG-INFO +1 -1
- cycode-1.9.6.dev4/cycode/__init__.py +1 -0
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cli/commands/scan/code_scanner.py +35 -13
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cli/commands/scan/pre_commit/pre_commit_command.py +2 -2
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cli/exceptions/handle_scan_errors.py +8 -5
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cli/files_collector/repository_documents.py +7 -7
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cli/files_collector/sca/sca_code_scanner.py +9 -7
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cli/printers/console_printer.py +4 -2
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cli/printers/json_printer.py +4 -2
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cli/printers/printer_base.py +1 -1
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cli/printers/tables/sca_table_printer.py +2 -3
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cli/printers/tables/table_printer.py +1 -1
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cli/printers/tables/table_printer_base.py +8 -2
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cli/printers/text_printer.py +19 -13
- cycode-1.9.6.dev4/cycode/cli/utils/git_proxy.py +76 -0
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cyclient/scan_client.py +13 -1
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/pyproject.toml +1 -1
- cycode-1.9.6.dev2/cycode/__init__.py +0 -1
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/README.md +0 -0
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cli/__init__.py +0 -0
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cli/commands/__init__.py +0 -0
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cli/commands/auth/__init__.py +0 -0
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cli/commands/auth/auth_command.py +0 -0
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cli/commands/auth/auth_manager.py +0 -0
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cli/commands/configure/__init__.py +0 -0
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cli/commands/configure/configure_command.py +0 -0
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cli/commands/ignore/__init__.py +0 -0
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cli/commands/ignore/ignore_command.py +0 -0
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cli/commands/main_cli.py +0 -0
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cli/commands/report/__init__.py +0 -0
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cli/commands/report/report_command.py +0 -0
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cli/commands/report/sbom/__init__.py +0 -0
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cli/commands/report/sbom/common.py +0 -0
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cli/commands/report/sbom/path/__init__.py +0 -0
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cli/commands/report/sbom/path/path_command.py +0 -0
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cli/commands/report/sbom/repository_url/__init__.py +0 -0
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cli/commands/report/sbom/repository_url/repository_url_command.py +0 -0
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cli/commands/report/sbom/sbom_command.py +0 -0
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cli/commands/report/sbom/sbom_report_file.py +0 -0
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cli/commands/scan/__init__.py +0 -0
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cli/commands/scan/commit_history/__init__.py +0 -0
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cli/commands/scan/commit_history/commit_history_command.py +0 -0
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cli/commands/scan/path/__init__.py +0 -0
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cli/commands/scan/path/path_command.py +0 -0
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cli/commands/scan/pre_commit/__init__.py +0 -0
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cli/commands/scan/pre_receive/__init__.py +0 -0
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cli/commands/scan/pre_receive/pre_receive_command.py +0 -0
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cli/commands/scan/repository/__init__.py +0 -0
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cli/commands/scan/repository/repository_command.py +0 -0
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cli/commands/scan/scan_ci/__init__.py +0 -0
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cli/commands/scan/scan_ci/ci_integrations.py +0 -0
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cli/commands/scan/scan_ci/scan_ci_command.py +0 -0
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cli/commands/scan/scan_command.py +0 -0
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cli/commands/version/__init__.py +0 -0
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cli/commands/version/version_command.py +0 -0
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cli/config.py +0 -0
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cli/config.yaml +0 -0
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cli/consts.py +0 -0
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cli/exceptions/__init__.py +0 -0
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cli/exceptions/custom_exceptions.py +0 -0
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cli/exceptions/handle_report_sbom_errors.py +0 -0
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cli/files_collector/__init__.py +0 -0
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cli/files_collector/excluder.py +0 -0
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cli/files_collector/iac/__init__.py +0 -0
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cli/files_collector/iac/tf_content_generator.py +0 -0
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cli/files_collector/models/__init__.py +0 -0
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cli/files_collector/models/in_memory_zip.py +0 -0
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cli/files_collector/path_documents.py +0 -0
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cli/files_collector/sca/__init__.py +0 -0
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cli/files_collector/sca/maven/__init__.py +0 -0
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cli/files_collector/sca/maven/base_restore_maven_dependencies.py +0 -0
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cli/files_collector/sca/maven/restore_gradle_dependencies.py +0 -0
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cli/files_collector/sca/maven/restore_maven_dependencies.py +0 -0
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cli/files_collector/zip_documents.py +0 -0
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cli/main.py +0 -0
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cli/models.py +0 -0
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cli/printers/__init__.py +0 -0
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cli/printers/tables/__init__.py +0 -0
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cli/printers/tables/table.py +0 -0
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cli/printers/tables/table_models.py +0 -0
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cli/user_settings/__init__.py +0 -0
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cli/user_settings/base_file_manager.py +0 -0
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cli/user_settings/config_file_manager.py +0 -0
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cli/user_settings/configuration_manager.py +0 -0
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cli/user_settings/credentials_manager.py +0 -0
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cli/user_settings/jwt_creator.py +0 -0
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cli/utils/__init__.py +0 -0
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cli/utils/enum_utils.py +0 -0
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cli/utils/get_api_client.py +0 -0
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cli/utils/path_utils.py +0 -0
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cli/utils/progress_bar.py +0 -0
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cli/utils/scan_batch.py +0 -0
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cli/utils/scan_utils.py +0 -0
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cli/utils/shell_executor.py +0 -0
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cli/utils/string_utils.py +0 -0
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cli/utils/task_timer.py +0 -0
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cli/utils/yaml_utils.py +0 -0
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cyclient/__init__.py +0 -0
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cyclient/auth_client.py +0 -0
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cyclient/client_creator.py +0 -0
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cyclient/config.py +0 -0
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cyclient/config.yaml +0 -0
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cyclient/config_dev.py +0 -0
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cyclient/cycode_client.py +0 -0
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cyclient/cycode_client_base.py +0 -0
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cyclient/cycode_dev_based_client.py +0 -0
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cyclient/cycode_token_based_client.py +0 -0
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cyclient/headers.py +0 -0
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cyclient/models.py +0 -0
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cyclient/report_client.py +0 -0
- {cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cyclient/scan_config_base.py +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = '1.9.6.dev4' # DON'T TOUCH. Placeholder. Will be filled automatically on poetry build from Git Tag
|
|
@@ -7,7 +7,6 @@ from typing import TYPE_CHECKING, Callable, Dict, List, Optional, Tuple
|
|
|
7
7
|
from uuid import UUID, uuid4
|
|
8
8
|
|
|
9
9
|
import click
|
|
10
|
-
from git import NULL_TREE, Repo
|
|
11
10
|
|
|
12
11
|
from cycode.cli import consts
|
|
13
12
|
from cycode.cli.config import configuration_manager
|
|
@@ -28,9 +27,8 @@ from cycode.cli.files_collector.zip_documents import zip_documents
|
|
|
28
27
|
from cycode.cli.models import CliError, Document, DocumentDetections, LocalScanResult, Severity
|
|
29
28
|
from cycode.cli.printers import ConsolePrinter
|
|
30
29
|
from cycode.cli.utils import scan_utils
|
|
31
|
-
from cycode.cli.utils.
|
|
32
|
-
|
|
33
|
-
)
|
|
30
|
+
from cycode.cli.utils.git_proxy import git_proxy
|
|
31
|
+
from cycode.cli.utils.path_utils import get_path_by_os
|
|
34
32
|
from cycode.cli.utils.progress_bar import ScanProgressBarSection
|
|
35
33
|
from cycode.cli.utils.scan_batch import run_parallel_batched_scan
|
|
36
34
|
from cycode.cli.utils.scan_utils import set_issue_detected
|
|
@@ -148,14 +146,14 @@ def _enrich_scan_result_with_data_from_detection_rules(
|
|
|
148
146
|
|
|
149
147
|
def _get_scan_documents_thread_func(
|
|
150
148
|
context: click.Context, is_git_diff: bool, is_commit_range: bool, scan_parameters: dict
|
|
151
|
-
) -> Callable[[List[Document]], Tuple[str, CliError, LocalScanResult]]:
|
|
149
|
+
) -> Tuple[Callable[[List[Document]], Tuple[str, CliError, LocalScanResult]], str]:
|
|
152
150
|
cycode_client = context.obj['client']
|
|
153
151
|
scan_type = context.obj['scan_type']
|
|
154
152
|
severity_threshold = context.obj['severity_threshold']
|
|
155
153
|
sync_option = context.obj['sync']
|
|
156
154
|
command_scan_type = context.info_name
|
|
157
|
-
|
|
158
|
-
scan_parameters['aggregation_id'] =
|
|
155
|
+
aggregation_id = str(_generate_unique_id())
|
|
156
|
+
scan_parameters['aggregation_id'] = aggregation_id
|
|
159
157
|
|
|
160
158
|
def _scan_batch_thread_func(batch: List[Document]) -> Tuple[str, CliError, LocalScanResult]:
|
|
161
159
|
local_scan_result = error = error_message = None
|
|
@@ -224,7 +222,7 @@ def _get_scan_documents_thread_func(
|
|
|
224
222
|
|
|
225
223
|
return scan_id, error, local_scan_result
|
|
226
224
|
|
|
227
|
-
return _scan_batch_thread_func
|
|
225
|
+
return _scan_batch_thread_func, aggregation_id
|
|
228
226
|
|
|
229
227
|
|
|
230
228
|
def scan_commit_range(
|
|
@@ -244,7 +242,7 @@ def scan_commit_range(
|
|
|
244
242
|
documents_to_scan = []
|
|
245
243
|
commit_ids_to_scan = []
|
|
246
244
|
|
|
247
|
-
repo =
|
|
245
|
+
repo = git_proxy.get_repo(path)
|
|
248
246
|
total_commits_count = int(repo.git.rev_list('--count', commit_range))
|
|
249
247
|
logger.debug('Calculating diffs for %s commits in the commit range %s', total_commits_count, commit_range)
|
|
250
248
|
|
|
@@ -261,7 +259,7 @@ def scan_commit_range(
|
|
|
261
259
|
|
|
262
260
|
commit_id = commit.hexsha
|
|
263
261
|
commit_ids_to_scan.append(commit_id)
|
|
264
|
-
parent = commit.parents[0] if commit.parents else
|
|
262
|
+
parent = commit.parents[0] if commit.parents else git_proxy.get_null_tree()
|
|
265
263
|
diff = commit.diff(parent, create_patch=True, R=True)
|
|
266
264
|
commit_documents_to_scan = []
|
|
267
265
|
for blob in diff:
|
|
@@ -313,11 +311,16 @@ def scan_documents(
|
|
|
313
311
|
)
|
|
314
312
|
return
|
|
315
313
|
|
|
316
|
-
scan_batch_thread_func = _get_scan_documents_thread_func(
|
|
314
|
+
scan_batch_thread_func, aggregation_id = _get_scan_documents_thread_func(
|
|
315
|
+
context, is_git_diff, is_commit_range, scan_parameters
|
|
316
|
+
)
|
|
317
317
|
errors, local_scan_results = run_parallel_batched_scan(
|
|
318
318
|
scan_batch_thread_func, documents_to_scan, progress_bar=progress_bar
|
|
319
319
|
)
|
|
320
|
-
|
|
320
|
+
aggregation_report_url = _try_get_aggregation_report_url_if_needed(
|
|
321
|
+
scan_parameters, context.obj['client'], context.obj['scan_type']
|
|
322
|
+
)
|
|
323
|
+
set_aggregation_report_url(context, aggregation_report_url)
|
|
321
324
|
progress_bar.set_section_length(ScanProgressBarSection.GENERATE_REPORT, 1)
|
|
322
325
|
progress_bar.update(ScanProgressBarSection.GENERATE_REPORT)
|
|
323
326
|
progress_bar.stop()
|
|
@@ -326,6 +329,25 @@ def scan_documents(
|
|
|
326
329
|
print_results(context, local_scan_results, errors)
|
|
327
330
|
|
|
328
331
|
|
|
332
|
+
def set_aggregation_report_url(context: click.Context, aggregation_report_url: Optional[str] = None) -> None:
|
|
333
|
+
context.obj['aggregation_report_url'] = aggregation_report_url
|
|
334
|
+
|
|
335
|
+
|
|
336
|
+
def _try_get_aggregation_report_url_if_needed(
|
|
337
|
+
scan_parameters: dict, cycode_client: 'ScanClient', scan_type: str
|
|
338
|
+
) -> Optional[str]:
|
|
339
|
+
aggregation_id = scan_parameters.get('aggregation_id')
|
|
340
|
+
if not scan_parameters.get('report'):
|
|
341
|
+
return None
|
|
342
|
+
if aggregation_id is None:
|
|
343
|
+
return None
|
|
344
|
+
try:
|
|
345
|
+
report_url_response = cycode_client.get_scan_aggregation_report_url(aggregation_id, scan_type)
|
|
346
|
+
return report_url_response.report_url
|
|
347
|
+
except Exception as e:
|
|
348
|
+
logger.debug('Failed to get aggregation report url: %s', str(e))
|
|
349
|
+
|
|
350
|
+
|
|
329
351
|
def scan_commit_range_documents(
|
|
330
352
|
context: click.Context,
|
|
331
353
|
from_documents_to_scan: List[Document],
|
|
@@ -664,7 +686,7 @@ def get_scan_parameters(context: click.Context, paths: Tuple[str]) -> dict:
|
|
|
664
686
|
|
|
665
687
|
def try_get_git_remote_url(path: str) -> Optional[str]:
|
|
666
688
|
try:
|
|
667
|
-
remote_url =
|
|
689
|
+
remote_url = git_proxy.get_repo(path).remotes[0].config_reader.get('url')
|
|
668
690
|
logger.debug('Found Git remote URL, %s', {'remote_url': remote_url, 'path': path})
|
|
669
691
|
return remote_url
|
|
670
692
|
except Exception as e:
|
{cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cli/commands/scan/pre_commit/pre_commit_command.py
RENAMED
|
@@ -2,7 +2,6 @@ import os
|
|
|
2
2
|
from typing import List
|
|
3
3
|
|
|
4
4
|
import click
|
|
5
|
-
from git import Repo
|
|
6
5
|
|
|
7
6
|
from cycode.cli import consts
|
|
8
7
|
from cycode.cli.commands.scan.code_scanner import scan_documents, scan_sca_pre_commit
|
|
@@ -12,6 +11,7 @@ from cycode.cli.files_collector.repository_documents import (
|
|
|
12
11
|
get_diff_file_path,
|
|
13
12
|
)
|
|
14
13
|
from cycode.cli.models import Document
|
|
14
|
+
from cycode.cli.utils.git_proxy import git_proxy
|
|
15
15
|
from cycode.cli.utils.path_utils import (
|
|
16
16
|
get_path_by_os,
|
|
17
17
|
)
|
|
@@ -31,7 +31,7 @@ def pre_commit_command(context: click.Context, ignored_args: List[str]) -> None:
|
|
|
31
31
|
scan_sca_pre_commit(context)
|
|
32
32
|
return
|
|
33
33
|
|
|
34
|
-
diff_files =
|
|
34
|
+
diff_files = git_proxy.get_repo(os.getcwd()).index.diff('HEAD', create_patch=True, R=True)
|
|
35
35
|
|
|
36
36
|
progress_bar.set_section_length(ScanProgressBarSection.PREPARE_LOCAL_FILES, len(diff_files))
|
|
37
37
|
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
from typing import Optional
|
|
2
2
|
|
|
3
3
|
import click
|
|
4
|
-
from git import InvalidGitRepositoryError
|
|
5
4
|
|
|
6
5
|
from cycode.cli.exceptions import custom_exceptions
|
|
7
6
|
from cycode.cli.models import CliError, CliErrors
|
|
8
7
|
from cycode.cli.printers import ConsolePrinter
|
|
8
|
+
from cycode.cli.utils.git_proxy import git_proxy
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
def handle_scan_exception(
|
|
@@ -13,7 +13,7 @@ def handle_scan_exception(
|
|
|
13
13
|
) -> Optional[CliError]:
|
|
14
14
|
context.obj['did_fail'] = True
|
|
15
15
|
|
|
16
|
-
ConsolePrinter(context).print_exception()
|
|
16
|
+
ConsolePrinter(context).print_exception(e)
|
|
17
17
|
|
|
18
18
|
errors: CliErrors = {
|
|
19
19
|
custom_exceptions.NetworkError: CliError(
|
|
@@ -49,7 +49,7 @@ def handle_scan_exception(
|
|
|
49
49
|
'Please make sure that your file is well formed '
|
|
50
50
|
'and execute the scan again',
|
|
51
51
|
),
|
|
52
|
-
|
|
52
|
+
git_proxy.get_invalid_git_repository_error(): CliError(
|
|
53
53
|
soft_fail=False,
|
|
54
54
|
code='invalid_git_error',
|
|
55
55
|
message='The path you supplied does not correlate to a git repository. '
|
|
@@ -69,10 +69,13 @@ def handle_scan_exception(
|
|
|
69
69
|
ConsolePrinter(context).print_error(error)
|
|
70
70
|
return None
|
|
71
71
|
|
|
72
|
+
unknown_error = CliError(code='unknown_error', message=str(e))
|
|
73
|
+
|
|
72
74
|
if return_exception:
|
|
73
|
-
return
|
|
75
|
+
return unknown_error
|
|
74
76
|
|
|
75
77
|
if isinstance(e, click.ClickException):
|
|
76
78
|
raise e
|
|
77
79
|
|
|
78
|
-
|
|
80
|
+
ConsolePrinter(context).print_error(unknown_error)
|
|
81
|
+
exit(1)
|
|
@@ -4,6 +4,7 @@ from typing import TYPE_CHECKING, Iterator, List, Optional, Tuple, Union
|
|
|
4
4
|
from cycode.cli import consts
|
|
5
5
|
from cycode.cli.files_collector.sca import sca_code_scanner
|
|
6
6
|
from cycode.cli.models import Document
|
|
7
|
+
from cycode.cli.utils.git_proxy import git_proxy
|
|
7
8
|
from cycode.cli.utils.path_utils import get_file_content, get_path_by_os
|
|
8
9
|
|
|
9
10
|
if TYPE_CHECKING:
|
|
@@ -13,8 +14,6 @@ if TYPE_CHECKING:
|
|
|
13
14
|
|
|
14
15
|
from cycode.cli.utils.progress_bar import BaseProgressBar, ProgressBarSection
|
|
15
16
|
|
|
16
|
-
from git import Repo
|
|
17
|
-
|
|
18
17
|
|
|
19
18
|
def should_process_git_object(obj: 'Blob', _: int) -> bool:
|
|
20
19
|
return obj.type == 'blob' and obj.size > 0
|
|
@@ -23,14 +22,14 @@ def should_process_git_object(obj: 'Blob', _: int) -> bool:
|
|
|
23
22
|
def get_git_repository_tree_file_entries(
|
|
24
23
|
path: str, branch: str
|
|
25
24
|
) -> Union[Iterator['IndexObjUnion'], Iterator['TraversedTreeTup']]:
|
|
26
|
-
return
|
|
25
|
+
return git_proxy.get_repo(path).tree(branch).traverse(predicate=should_process_git_object)
|
|
27
26
|
|
|
28
27
|
|
|
29
28
|
def parse_commit_range(commit_range: str, path: str) -> Tuple[str, str]:
|
|
30
29
|
from_commit_rev = None
|
|
31
30
|
to_commit_rev = None
|
|
32
31
|
|
|
33
|
-
for commit in
|
|
32
|
+
for commit in git_proxy.get_repo(path).iter_commits(rev=commit_range):
|
|
34
33
|
if not to_commit_rev:
|
|
35
34
|
to_commit_rev = commit.hexsha
|
|
36
35
|
from_commit_rev = commit.hexsha
|
|
@@ -52,7 +51,7 @@ def get_pre_commit_modified_documents(
|
|
|
52
51
|
git_head_documents = []
|
|
53
52
|
pre_committed_documents = []
|
|
54
53
|
|
|
55
|
-
repo =
|
|
54
|
+
repo = git_proxy.get_repo(os.getcwd())
|
|
56
55
|
diff_files = repo.index.diff(consts.GIT_HEAD_COMMIT_REV, create_patch=True, R=True)
|
|
57
56
|
progress_bar.set_section_length(progress_bar_section, len(diff_files))
|
|
58
57
|
for file in diff_files:
|
|
@@ -82,7 +81,7 @@ def get_commit_range_modified_documents(
|
|
|
82
81
|
from_commit_documents = []
|
|
83
82
|
to_commit_documents = []
|
|
84
83
|
|
|
85
|
-
repo =
|
|
84
|
+
repo = git_proxy.get_repo(path)
|
|
86
85
|
diff = repo.commit(from_commit_rev).diff(to_commit_rev)
|
|
87
86
|
|
|
88
87
|
modified_files_diff = [
|
|
@@ -131,7 +130,8 @@ def _get_end_commit_from_branch_update_details(update_details: str) -> str:
|
|
|
131
130
|
def _get_oldest_unupdated_commit_for_branch(commit: str) -> Optional[str]:
|
|
132
131
|
# get a list of commits by chronological order that are not in the remote repository yet
|
|
133
132
|
# more info about rev-list command: https://git-scm.com/docs/git-rev-list
|
|
134
|
-
|
|
133
|
+
repo = git_proxy.get_repo(os.getcwd())
|
|
134
|
+
not_updated_commits = repo.git.rev_list(commit, '--topo-order', '--reverse', '--not', '--all')
|
|
135
135
|
|
|
136
136
|
commits = not_updated_commits.splitlines()
|
|
137
137
|
if not commits:
|
|
@@ -2,16 +2,18 @@ import os
|
|
|
2
2
|
from typing import TYPE_CHECKING, Dict, List, Optional
|
|
3
3
|
|
|
4
4
|
import click
|
|
5
|
-
from git import GitCommandError, Repo
|
|
6
5
|
|
|
7
6
|
from cycode.cli import consts
|
|
8
7
|
from cycode.cli.files_collector.sca.maven.restore_gradle_dependencies import RestoreGradleDependencies
|
|
9
8
|
from cycode.cli.files_collector.sca.maven.restore_maven_dependencies import RestoreMavenDependencies
|
|
10
9
|
from cycode.cli.models import Document
|
|
10
|
+
from cycode.cli.utils.git_proxy import git_proxy
|
|
11
11
|
from cycode.cli.utils.path_utils import get_file_content, get_file_dir, join_paths
|
|
12
12
|
from cycode.cyclient import logger
|
|
13
13
|
|
|
14
14
|
if TYPE_CHECKING:
|
|
15
|
+
from git import Repo
|
|
16
|
+
|
|
15
17
|
from cycode.cli.files_collector.sca.maven.base_restore_maven_dependencies import BaseRestoreMavenDependencies
|
|
16
18
|
|
|
17
19
|
BUILD_GRADLE_FILE_NAME = 'build.gradle'
|
|
@@ -27,7 +29,7 @@ def perform_pre_commit_range_scan_actions(
|
|
|
27
29
|
to_commit_documents: List[Document],
|
|
28
30
|
to_commit_rev: str,
|
|
29
31
|
) -> None:
|
|
30
|
-
repo =
|
|
32
|
+
repo = git_proxy.get_repo(path)
|
|
31
33
|
add_ecosystem_related_files_if_exists(from_commit_documents, repo, from_commit_rev)
|
|
32
34
|
add_ecosystem_related_files_if_exists(to_commit_documents, repo, to_commit_rev)
|
|
33
35
|
|
|
@@ -35,13 +37,13 @@ def perform_pre_commit_range_scan_actions(
|
|
|
35
37
|
def perform_pre_hook_range_scan_actions(
|
|
36
38
|
git_head_documents: List[Document], pre_committed_documents: List[Document]
|
|
37
39
|
) -> None:
|
|
38
|
-
repo =
|
|
40
|
+
repo = git_proxy.get_repo(os.getcwd())
|
|
39
41
|
add_ecosystem_related_files_if_exists(git_head_documents, repo, consts.GIT_HEAD_COMMIT_REV)
|
|
40
42
|
add_ecosystem_related_files_if_exists(pre_committed_documents)
|
|
41
43
|
|
|
42
44
|
|
|
43
45
|
def add_ecosystem_related_files_if_exists(
|
|
44
|
-
documents: List[Document], repo: Optional[Repo] = None, commit_rev: Optional[str] = None
|
|
46
|
+
documents: List[Document], repo: Optional['Repo'] = None, commit_rev: Optional[str] = None
|
|
45
47
|
) -> None:
|
|
46
48
|
documents_to_add: List[Document] = []
|
|
47
49
|
for doc in documents:
|
|
@@ -56,7 +58,7 @@ def add_ecosystem_related_files_if_exists(
|
|
|
56
58
|
|
|
57
59
|
|
|
58
60
|
def get_doc_ecosystem_related_project_files(
|
|
59
|
-
doc: Document, documents: List[Document], ecosystem: str, commit_rev: Optional[str], repo: Optional[Repo]
|
|
61
|
+
doc: Document, documents: List[Document], ecosystem: str, commit_rev: Optional[str], repo: Optional['Repo']
|
|
60
62
|
) -> List[Document]:
|
|
61
63
|
documents_to_add: List[Document] = []
|
|
62
64
|
for ecosystem_project_file in consts.PROJECT_FILES_BY_ECOSYSTEM_MAP.get(ecosystem):
|
|
@@ -136,10 +138,10 @@ def get_manifest_file_path(document: Document, is_monitor_action: bool, project_
|
|
|
136
138
|
return join_paths(project_path, document.path) if is_monitor_action else document.path
|
|
137
139
|
|
|
138
140
|
|
|
139
|
-
def get_file_content_from_commit(repo: Repo, commit: str, file_path: str) -> Optional[str]:
|
|
141
|
+
def get_file_content_from_commit(repo: 'Repo', commit: str, file_path: str) -> Optional[str]:
|
|
140
142
|
try:
|
|
141
143
|
return repo.git.show(f'{commit}:{file_path}')
|
|
142
|
-
except
|
|
144
|
+
except git_proxy.get_git_command_error():
|
|
143
145
|
return None
|
|
144
146
|
|
|
145
147
|
|
|
@@ -28,13 +28,15 @@ class ConsolePrinter:
|
|
|
28
28
|
self.context = context
|
|
29
29
|
self.scan_type = self.context.obj.get('scan_type')
|
|
30
30
|
self.output_type = self.context.obj.get('output')
|
|
31
|
-
|
|
31
|
+
self.aggregation_report_url = self.context.obj.get('aggregation_report_url')
|
|
32
32
|
self._printer_class = self._AVAILABLE_PRINTERS.get(self.output_type)
|
|
33
33
|
if self._printer_class is None:
|
|
34
34
|
raise CycodeError(f'"{self.output_type}" output type is not supported.')
|
|
35
35
|
|
|
36
36
|
def print_scan_results(
|
|
37
|
-
self,
|
|
37
|
+
self,
|
|
38
|
+
local_scan_results: List['LocalScanResult'],
|
|
39
|
+
errors: Optional[Dict[str, 'CliError']] = None,
|
|
38
40
|
) -> None:
|
|
39
41
|
printer = self._get_scan_printer()
|
|
40
42
|
printer.print_scan_results(local_scan_results, errors)
|
|
@@ -28,13 +28,15 @@ class JsonPrinter(PrinterBase):
|
|
|
28
28
|
scan_ids = []
|
|
29
29
|
report_urls = []
|
|
30
30
|
detections = []
|
|
31
|
+
aggregation_report_url = self.context.obj.get('aggregation_report_url')
|
|
32
|
+
if aggregation_report_url:
|
|
33
|
+
report_urls.append(aggregation_report_url)
|
|
31
34
|
|
|
32
35
|
for local_scan_result in local_scan_results:
|
|
33
36
|
scan_ids.append(local_scan_result.scan_id)
|
|
34
37
|
|
|
35
|
-
if local_scan_result.report_url:
|
|
38
|
+
if not aggregation_report_url and local_scan_result.report_url:
|
|
36
39
|
report_urls.append(local_scan_result.report_url)
|
|
37
|
-
|
|
38
40
|
for document_detections in local_scan_result.document_detections:
|
|
39
41
|
detections.extend(document_detections.detections)
|
|
40
42
|
|
|
@@ -43,7 +43,7 @@ class PrinterBase(ABC):
|
|
|
43
43
|
# gets the most recent exception caught by an except clause
|
|
44
44
|
message = f'Error: {traceback.format_exc()}'
|
|
45
45
|
else:
|
|
46
|
-
traceback_message = ''.join(traceback.format_exception(e))
|
|
46
|
+
traceback_message = ''.join(traceback.format_exception(None, e, e.__traceback__))
|
|
47
47
|
message = f'Error: {traceback_message}'
|
|
48
48
|
|
|
49
49
|
click.secho(message, err=True, fg=self.RED_COLOR_NAME)
|
|
@@ -13,7 +13,6 @@ from cycode.cli.utils.string_utils import shortcut_dependency_paths
|
|
|
13
13
|
if TYPE_CHECKING:
|
|
14
14
|
from cycode.cli.models import LocalScanResult
|
|
15
15
|
|
|
16
|
-
|
|
17
16
|
column_builder = ColumnInfoBuilder()
|
|
18
17
|
|
|
19
18
|
# Building must have strict order. Represents the order of the columns in the table (from left to right)
|
|
@@ -29,7 +28,6 @@ LICENSE_COLUMN = column_builder.build(name='License')
|
|
|
29
28
|
DIRECT_DEPENDENCY_COLUMN = column_builder.build(name='Direct Dependency')
|
|
30
29
|
DEVELOPMENT_DEPENDENCY_COLUMN = column_builder.build(name='Development Dependency')
|
|
31
30
|
|
|
32
|
-
|
|
33
31
|
COLUMN_WIDTHS_CONFIG: ColumnWidths = {
|
|
34
32
|
REPOSITORY_COLUMN: 2,
|
|
35
33
|
CODE_PROJECT_COLUMN: 2,
|
|
@@ -42,6 +40,7 @@ COLUMN_WIDTHS_CONFIG: ColumnWidths = {
|
|
|
42
40
|
|
|
43
41
|
class ScaTablePrinter(TablePrinterBase):
|
|
44
42
|
def _print_results(self, local_scan_results: List['LocalScanResult']) -> None:
|
|
43
|
+
aggregation_report_url = self.context.obj.get('aggregation_report_url')
|
|
45
44
|
detections_per_policy_id = self._extract_detections_per_policy_id(local_scan_results)
|
|
46
45
|
for policy_id, detections in detections_per_policy_id.items():
|
|
47
46
|
table = self._get_table(policy_id)
|
|
@@ -53,7 +52,7 @@ class ScaTablePrinter(TablePrinterBase):
|
|
|
53
52
|
self._print_summary_issues(len(detections), self._get_title(policy_id))
|
|
54
53
|
self._print_table(table)
|
|
55
54
|
|
|
56
|
-
self._print_report_urls(local_scan_results)
|
|
55
|
+
self._print_report_urls(local_scan_results, aggregation_report_url)
|
|
57
56
|
|
|
58
57
|
@staticmethod
|
|
59
58
|
def _get_title(policy_id: str) -> str:
|
|
@@ -63,7 +63,7 @@ class TablePrinter(TablePrinterBase):
|
|
|
63
63
|
self._enrich_table_with_values(table, detection, document_detections.document)
|
|
64
64
|
|
|
65
65
|
self._print_table(table)
|
|
66
|
-
self._print_report_urls(local_scan_results)
|
|
66
|
+
self._print_report_urls(local_scan_results, self.context.obj.get('aggregation_report_url'))
|
|
67
67
|
|
|
68
68
|
def _get_table(self) -> Table:
|
|
69
69
|
table = Table()
|
|
@@ -58,9 +58,15 @@ class TablePrinterBase(PrinterBase, abc.ABC):
|
|
|
58
58
|
click.echo(table.get_table().draw())
|
|
59
59
|
|
|
60
60
|
@staticmethod
|
|
61
|
-
def _print_report_urls(
|
|
61
|
+
def _print_report_urls(
|
|
62
|
+
local_scan_results: List['LocalScanResult'],
|
|
63
|
+
aggregation_report_url: Optional[str] = None,
|
|
64
|
+
) -> None:
|
|
62
65
|
report_urls = [scan_result.report_url for scan_result in local_scan_results if scan_result.report_url]
|
|
63
|
-
if not report_urls:
|
|
66
|
+
if not report_urls and not aggregation_report_url:
|
|
67
|
+
return
|
|
68
|
+
if aggregation_report_url:
|
|
69
|
+
click.echo(f'Report URL: {aggregation_report_url}')
|
|
64
70
|
return
|
|
65
71
|
|
|
66
72
|
click.echo('Report URLs:')
|
|
@@ -39,10 +39,11 @@ class TextPrinter(PrinterBase):
|
|
|
39
39
|
|
|
40
40
|
for local_scan_result in local_scan_results:
|
|
41
41
|
for document_detections in local_scan_result.document_detections:
|
|
42
|
-
self._print_document_detections(
|
|
43
|
-
document_detections, local_scan_result.scan_id, local_scan_result.report_url
|
|
44
|
-
)
|
|
42
|
+
self._print_document_detections(document_detections, local_scan_result.scan_id)
|
|
45
43
|
|
|
44
|
+
report_urls = [scan_result.report_url for scan_result in local_scan_results if scan_result.report_url]
|
|
45
|
+
|
|
46
|
+
self._print_report_urls(report_urls, self.context.obj.get('aggregation_report_url'))
|
|
46
47
|
if not errors:
|
|
47
48
|
return
|
|
48
49
|
|
|
@@ -55,18 +56,14 @@ class TextPrinter(PrinterBase):
|
|
|
55
56
|
click.echo(f'- {scan_id}: ', nl=False)
|
|
56
57
|
self.print_error(error)
|
|
57
58
|
|
|
58
|
-
def _print_document_detections(
|
|
59
|
-
self, document_detections: DocumentDetections, scan_id: str, report_url: Optional[str]
|
|
60
|
-
) -> None:
|
|
59
|
+
def _print_document_detections(self, document_detections: DocumentDetections, scan_id: str) -> None:
|
|
61
60
|
document = document_detections.document
|
|
62
61
|
lines_to_display = self._get_lines_to_display_count()
|
|
63
62
|
for detection in document_detections.detections:
|
|
64
|
-
self._print_detection_summary(detection, document.path, scan_id
|
|
63
|
+
self._print_detection_summary(detection, document.path, scan_id)
|
|
65
64
|
self._print_detection_code_segment(detection, document, lines_to_display)
|
|
66
65
|
|
|
67
|
-
def _print_detection_summary(
|
|
68
|
-
self, detection: Detection, document_path: str, scan_id: str, report_url: Optional[str]
|
|
69
|
-
) -> None:
|
|
66
|
+
def _print_detection_summary(self, detection: Detection, document_path: str, scan_id: str) -> None:
|
|
70
67
|
detection_name = detection.type if self.scan_type == SECRET_SCAN_TYPE else detection.message
|
|
71
68
|
detection_name_styled = click.style(detection_name, fg='bright_red', bold=True)
|
|
72
69
|
|
|
@@ -74,8 +71,6 @@ class TextPrinter(PrinterBase):
|
|
|
74
71
|
detection_sha_message = f'\nSecret SHA: {detection_sha}' if detection_sha else ''
|
|
75
72
|
|
|
76
73
|
scan_id_message = f'\nScan ID: {scan_id}'
|
|
77
|
-
report_url_message = f'\nReport URL: {report_url}' if report_url else ''
|
|
78
|
-
|
|
79
74
|
detection_commit_id = detection.detection_details.get('commit_id')
|
|
80
75
|
detection_commit_id_message = f'\nCommit SHA: {detection_commit_id}' if detection_commit_id else ''
|
|
81
76
|
|
|
@@ -88,7 +83,6 @@ class TextPrinter(PrinterBase):
|
|
|
88
83
|
f'(rule ID: {detection.detection_rule_id}) in file: {click.format_filename(document_path)} '
|
|
89
84
|
f'{detection_sha_message}'
|
|
90
85
|
f'{scan_id_message}'
|
|
91
|
-
f'{report_url_message}'
|
|
92
86
|
f'{detection_commit_id_message}'
|
|
93
87
|
f'{company_guidelines_message}'
|
|
94
88
|
f' ⛔'
|
|
@@ -101,6 +95,18 @@ class TextPrinter(PrinterBase):
|
|
|
101
95
|
|
|
102
96
|
self._print_detection_from_file(detection, document, code_segment_size)
|
|
103
97
|
|
|
98
|
+
@staticmethod
|
|
99
|
+
def _print_report_urls(report_urls: List[str], aggregation_report_url: Optional[str] = None) -> None:
|
|
100
|
+
if not report_urls and not aggregation_report_url:
|
|
101
|
+
return
|
|
102
|
+
if aggregation_report_url:
|
|
103
|
+
click.echo(f'Report URL: {aggregation_report_url}')
|
|
104
|
+
return
|
|
105
|
+
|
|
106
|
+
click.echo('Report URLs:')
|
|
107
|
+
for report_url in report_urls:
|
|
108
|
+
click.echo(f'- {report_url}')
|
|
109
|
+
|
|
104
110
|
@staticmethod
|
|
105
111
|
def _get_code_segment_start_line(detection_line: int, code_segment_size: int) -> int:
|
|
106
112
|
start_line = detection_line - math.ceil(code_segment_size / 2)
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import types
|
|
2
|
+
from abc import ABC, abstractmethod
|
|
3
|
+
from typing import TYPE_CHECKING, Optional, Type
|
|
4
|
+
|
|
5
|
+
_GIT_ERROR_MESSAGE = """
|
|
6
|
+
Cycode CLI needs the git executable to be installed on the system.
|
|
7
|
+
Git executable must be available in the PATH.
|
|
8
|
+
Git 1.7.x or newer is required.
|
|
9
|
+
You can help Cycode CLI to locate the Git executable
|
|
10
|
+
by setting the GIT_PYTHON_GIT_EXECUTABLE=<path/to/git> environment variable.
|
|
11
|
+
""".strip().replace('\n', ' ')
|
|
12
|
+
|
|
13
|
+
try:
|
|
14
|
+
import git
|
|
15
|
+
except ImportError:
|
|
16
|
+
git = None
|
|
17
|
+
|
|
18
|
+
if TYPE_CHECKING:
|
|
19
|
+
from git import PathLike, Repo
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class GitProxyError(Exception):
|
|
23
|
+
pass
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class _AbstractGitProxy(ABC):
|
|
27
|
+
@abstractmethod
|
|
28
|
+
def get_repo(self, path: Optional['PathLike'] = None, *args, **kwargs) -> 'Repo':
|
|
29
|
+
...
|
|
30
|
+
|
|
31
|
+
@abstractmethod
|
|
32
|
+
def get_null_tree(self) -> object:
|
|
33
|
+
...
|
|
34
|
+
|
|
35
|
+
@abstractmethod
|
|
36
|
+
def get_invalid_git_repository_error(self) -> Type[BaseException]:
|
|
37
|
+
...
|
|
38
|
+
|
|
39
|
+
@abstractmethod
|
|
40
|
+
def get_git_command_error(self) -> Type[BaseException]:
|
|
41
|
+
...
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
class _DummyGitProxy(_AbstractGitProxy):
|
|
45
|
+
def get_repo(self, path: Optional['PathLike'] = None, *args, **kwargs) -> 'Repo':
|
|
46
|
+
raise RuntimeError(_GIT_ERROR_MESSAGE)
|
|
47
|
+
|
|
48
|
+
def get_null_tree(self) -> object:
|
|
49
|
+
raise RuntimeError(_GIT_ERROR_MESSAGE)
|
|
50
|
+
|
|
51
|
+
def get_invalid_git_repository_error(self) -> Type[BaseException]:
|
|
52
|
+
return GitProxyError
|
|
53
|
+
|
|
54
|
+
def get_git_command_error(self) -> Type[BaseException]:
|
|
55
|
+
return GitProxyError
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
class _GitProxy(_AbstractGitProxy):
|
|
59
|
+
def get_repo(self, path: Optional['PathLike'] = None, *args, **kwargs) -> 'Repo':
|
|
60
|
+
return git.Repo(path, *args, **kwargs)
|
|
61
|
+
|
|
62
|
+
def get_null_tree(self) -> object:
|
|
63
|
+
return git.NULL_TREE
|
|
64
|
+
|
|
65
|
+
def get_invalid_git_repository_error(self) -> Type[BaseException]:
|
|
66
|
+
return git.InvalidGitRepositoryError
|
|
67
|
+
|
|
68
|
+
def get_git_command_error(self) -> Type[BaseException]:
|
|
69
|
+
return git.GitCommandError
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def get_git_proxy(git_module: Optional[types.ModuleType]) -> _AbstractGitProxy:
|
|
73
|
+
return _GitProxy() if git_module else _DummyGitProxy()
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
git_proxy = get_git_proxy(git)
|
|
@@ -59,7 +59,7 @@ class ScanClient:
|
|
|
59
59
|
self, scan_type: str, should_use_scan_service: bool = False, should_use_sync_flow: bool = False
|
|
60
60
|
) -> str:
|
|
61
61
|
service_path = self.scan_config.get_service_name(scan_type, should_use_scan_service)
|
|
62
|
-
controller_path = self.get_scan_controller_path(scan_type)
|
|
62
|
+
controller_path = self.get_scan_controller_path(scan_type, should_use_scan_service)
|
|
63
63
|
flow_type = self.get_scan_flow_type(should_use_sync_flow)
|
|
64
64
|
return f'{service_path}/{controller_path}{flow_type}'
|
|
65
65
|
|
|
@@ -92,6 +92,12 @@ class ScanClient:
|
|
|
92
92
|
response = self.scan_cycode_client.get(url_path=self.get_scan_report_url_path(scan_id, scan_type))
|
|
93
93
|
return models.ScanReportUrlResponseSchema().build_dto(response.json())
|
|
94
94
|
|
|
95
|
+
def get_scan_aggregation_report_url(self, aggregation_id: str, scan_type: str) -> models.ScanReportUrlResponse:
|
|
96
|
+
response = self.scan_cycode_client.get(
|
|
97
|
+
url_path=self.get_scan_aggregation_report_url_path(aggregation_id, scan_type)
|
|
98
|
+
)
|
|
99
|
+
return models.ScanReportUrlResponseSchema().build_dto(response.json())
|
|
100
|
+
|
|
95
101
|
def get_zipped_file_scan_async_url_path(self, scan_type: str, should_use_sync_flow: bool = False) -> str:
|
|
96
102
|
async_scan_type = self.scan_config.get_async_scan_type(scan_type)
|
|
97
103
|
async_entity_type = self.scan_config.get_async_entity_type(scan_type)
|
|
@@ -155,6 +161,12 @@ class ScanClient:
|
|
|
155
161
|
def get_scan_report_url_path(self, scan_id: str, scan_type: str) -> str:
|
|
156
162
|
return f'{self.get_scan_service_url_path(scan_type, should_use_scan_service=True)}/reportUrl/{scan_id}'
|
|
157
163
|
|
|
164
|
+
def get_scan_aggregation_report_url_path(self, aggregation_id: str, scan_type: str) -> str:
|
|
165
|
+
return (
|
|
166
|
+
f'{self.get_scan_service_url_path(scan_type, should_use_scan_service=True)}'
|
|
167
|
+
f'/reportUrlByAggregationId/{aggregation_id}'
|
|
168
|
+
)
|
|
169
|
+
|
|
158
170
|
def get_scan_details(self, scan_type: str, scan_id: str) -> models.ScanDetailsResponse:
|
|
159
171
|
path = self.get_scan_details_path(scan_type, scan_id)
|
|
160
172
|
response = self.scan_cycode_client.get(url_path=path)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "cycode"
|
|
3
|
-
version = "1.9.6.
|
|
3
|
+
version = "1.9.6.dev4" # DON'T TOUCH. Placeholder. Will be filled automatically on poetry build from Git Tag
|
|
4
4
|
description = "Boost security in your dev lifecycle via SAST, SCA, Secrets & IaC scanning."
|
|
5
5
|
keywords=["secret-scan", "cycode", "devops", "token", "secret", "security", "cycode", "code"]
|
|
6
6
|
authors = ["Cycode <support@cycode.com>"]
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = '1.9.6.dev2' # DON'T TOUCH. Placeholder. Will be filled automatically on poetry build from Git Tag
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cli/commands/report/sbom/path/path_command.py
RENAMED
|
File without changes
|
{cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cli/commands/report/sbom/repository_url/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cli/commands/scan/pre_receive/pre_receive_command.py
RENAMED
|
File without changes
|
|
File without changes
|
{cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cli/commands/scan/repository/repository_command.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{cycode-1.9.6.dev2 → cycode-1.9.6.dev4}/cycode/cli/files_collector/iac/tf_content_generator.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|