cycode 1.9.5.dev5__tar.gz → 1.9.6.dev3__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.5.dev5 → cycode-1.9.6.dev3}/PKG-INFO +6 -3
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/README.md +5 -2
- cycode-1.9.6.dev3/cycode/__init__.py +1 -0
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cli/commands/auth/auth_manager.py +11 -11
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cli/commands/report/sbom/common.py +1 -1
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cli/commands/scan/code_scanner.py +67 -35
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cli/commands/scan/pre_receive/pre_receive_command.py +5 -4
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cli/files_collector/excluder.py +38 -11
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cli/files_collector/path_documents.py +1 -1
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cli/files_collector/sca/maven/base_restore_maven_dependencies.py +1 -1
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cli/files_collector/sca/sca_code_scanner.py +6 -6
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cli/files_collector/zip_documents.py +7 -6
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cli/printers/console_printer.py +4 -2
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cli/printers/json_printer.py +4 -2
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cli/printers/tables/sca_table_printer.py +2 -3
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cli/printers/tables/table_printer.py +1 -1
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cli/printers/tables/table_printer_base.py +8 -2
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cli/printers/text_printer.py +19 -13
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cli/utils/progress_bar.py +11 -6
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cli/utils/shell_executor.py +2 -2
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cyclient/config.py +18 -9
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cyclient/cycode_client_base.py +8 -2
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cyclient/headers.py +1 -1
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cyclient/scan_client.py +13 -1
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/pyproject.toml +2 -1
- cycode-1.9.5.dev5/cycode/__init__.py +0 -1
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cli/__init__.py +0 -0
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cli/commands/__init__.py +0 -0
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cli/commands/auth/__init__.py +0 -0
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cli/commands/auth/auth_command.py +0 -0
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cli/commands/configure/__init__.py +0 -0
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cli/commands/configure/configure_command.py +0 -0
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cli/commands/ignore/__init__.py +0 -0
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cli/commands/ignore/ignore_command.py +0 -0
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cli/commands/main_cli.py +0 -0
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cli/commands/report/__init__.py +0 -0
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cli/commands/report/report_command.py +0 -0
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cli/commands/report/sbom/__init__.py +0 -0
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cli/commands/report/sbom/path/__init__.py +0 -0
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cli/commands/report/sbom/path/path_command.py +0 -0
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cli/commands/report/sbom/repository_url/__init__.py +0 -0
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cli/commands/report/sbom/repository_url/repository_url_command.py +0 -0
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cli/commands/report/sbom/sbom_command.py +0 -0
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cli/commands/report/sbom/sbom_report_file.py +0 -0
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cli/commands/scan/__init__.py +0 -0
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cli/commands/scan/commit_history/__init__.py +0 -0
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cli/commands/scan/commit_history/commit_history_command.py +0 -0
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cli/commands/scan/path/__init__.py +0 -0
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cli/commands/scan/path/path_command.py +0 -0
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cli/commands/scan/pre_commit/__init__.py +0 -0
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cli/commands/scan/pre_commit/pre_commit_command.py +0 -0
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cli/commands/scan/pre_receive/__init__.py +0 -0
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cli/commands/scan/repository/__init__.py +0 -0
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cli/commands/scan/repository/repository_command.py +0 -0
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cli/commands/scan/scan_ci/__init__.py +0 -0
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cli/commands/scan/scan_ci/ci_integrations.py +0 -0
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cli/commands/scan/scan_ci/scan_ci_command.py +0 -0
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cli/commands/scan/scan_command.py +0 -0
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cli/commands/version/__init__.py +0 -0
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cli/commands/version/version_command.py +0 -0
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cli/config.py +0 -0
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cli/config.yaml +0 -0
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cli/consts.py +0 -0
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cli/exceptions/__init__.py +0 -0
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cli/exceptions/custom_exceptions.py +0 -0
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cli/exceptions/handle_report_sbom_errors.py +0 -0
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cli/exceptions/handle_scan_errors.py +0 -0
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cli/files_collector/__init__.py +0 -0
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cli/files_collector/iac/__init__.py +0 -0
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cli/files_collector/iac/tf_content_generator.py +0 -0
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cli/files_collector/models/__init__.py +0 -0
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cli/files_collector/models/in_memory_zip.py +0 -0
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cli/files_collector/repository_documents.py +0 -0
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cli/files_collector/sca/__init__.py +0 -0
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cli/files_collector/sca/maven/__init__.py +0 -0
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cli/files_collector/sca/maven/restore_gradle_dependencies.py +0 -0
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cli/files_collector/sca/maven/restore_maven_dependencies.py +0 -0
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cli/main.py +0 -0
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cli/models.py +0 -0
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cli/printers/__init__.py +0 -0
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cli/printers/printer_base.py +0 -0
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cli/printers/tables/__init__.py +0 -0
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cli/printers/tables/table.py +0 -0
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cli/printers/tables/table_models.py +0 -0
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cli/user_settings/__init__.py +0 -0
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cli/user_settings/base_file_manager.py +0 -0
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cli/user_settings/config_file_manager.py +0 -0
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cli/user_settings/configuration_manager.py +0 -0
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cli/user_settings/credentials_manager.py +0 -0
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cli/user_settings/jwt_creator.py +0 -0
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cli/utils/__init__.py +0 -0
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cli/utils/enum_utils.py +0 -0
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cli/utils/get_api_client.py +0 -0
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cli/utils/path_utils.py +0 -0
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cli/utils/scan_batch.py +0 -0
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cli/utils/scan_utils.py +0 -0
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cli/utils/string_utils.py +0 -0
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cli/utils/task_timer.py +0 -0
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cli/utils/yaml_utils.py +0 -0
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cyclient/__init__.py +0 -0
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cyclient/auth_client.py +0 -0
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cyclient/client_creator.py +0 -0
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cyclient/config.yaml +0 -0
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cyclient/config_dev.py +0 -0
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cyclient/cycode_client.py +0 -0
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cyclient/cycode_dev_based_client.py +0 -0
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cyclient/cycode_token_based_client.py +0 -0
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cyclient/models.py +0 -0
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cyclient/report_client.py +0 -0
- {cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cyclient/scan_config_base.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: cycode
|
|
3
|
-
Version: 1.9.
|
|
3
|
+
Version: 1.9.6.dev3
|
|
4
4
|
Summary: Boost security in your dev lifecycle via SAST, SCA, Secrets & IaC scanning.
|
|
5
5
|
Home-page: https://github.com/cycodehq/cycode-cli
|
|
6
6
|
License: MIT
|
|
@@ -557,9 +557,12 @@ Secret SHA: a44081db3296c84b82d12a35c446a3cba19411dddfa0380134c75f7b3973bff0
|
|
|
557
557
|
|
|
558
558
|
### Soft Fail
|
|
559
559
|
|
|
560
|
-
|
|
560
|
+
Using the soft fail feature will not fail the CI/CD step within the pipeline if the Cycode scan detects an issue.
|
|
561
|
+
If an issue occurs during the Cycode scan, using a soft fail feature will automatically execute with success (`0`) to avoid interference.
|
|
561
562
|
|
|
562
|
-
|
|
563
|
+
To configure this feature, add the `--soft-fail` option to any type of scan. This will force the scan results to succeed (exit code `0`).
|
|
564
|
+
|
|
565
|
+
Scan results are assigned with a value of exit code `1` when issues are found in the scan results; this will result in a failure within the CI/CD tool. Use the option `--soft-fail` to force the results with the exit code `0` to have no impact (i.e., to have a successful result).
|
|
563
566
|
|
|
564
567
|
### Example Scan Results
|
|
565
568
|
|
|
@@ -519,9 +519,12 @@ Secret SHA: a44081db3296c84b82d12a35c446a3cba19411dddfa0380134c75f7b3973bff0
|
|
|
519
519
|
|
|
520
520
|
### Soft Fail
|
|
521
521
|
|
|
522
|
-
|
|
522
|
+
Using the soft fail feature will not fail the CI/CD step within the pipeline if the Cycode scan detects an issue.
|
|
523
|
+
If an issue occurs during the Cycode scan, using a soft fail feature will automatically execute with success (`0`) to avoid interference.
|
|
523
524
|
|
|
524
|
-
|
|
525
|
+
To configure this feature, add the `--soft-fail` option to any type of scan. This will force the scan results to succeed (exit code `0`).
|
|
526
|
+
|
|
527
|
+
Scan results are assigned with a value of exit code `1` when issues are found in the scan results; this will result in a failure within the CI/CD tool. Use the option `--soft-fail` to force the results with the exit code `0` to have no impact (i.e., to have a successful result).
|
|
525
528
|
|
|
526
529
|
### Example Scan Results
|
|
527
530
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = '1.9.6.dev3' # DON'T TOUCH. Placeholder. Will be filled automatically on poetry build from Git Tag
|
|
@@ -29,20 +29,20 @@ class AuthManager:
|
|
|
29
29
|
self.auth_client = AuthClient()
|
|
30
30
|
|
|
31
31
|
def authenticate(self) -> None:
|
|
32
|
-
logger.debug('
|
|
32
|
+
logger.debug('Generating PKCE code pair')
|
|
33
33
|
code_challenge, code_verifier = self._generate_pkce_code_pair()
|
|
34
34
|
|
|
35
|
-
logger.debug('
|
|
35
|
+
logger.debug('Starting authentication session')
|
|
36
36
|
session_id = self.start_session(code_challenge)
|
|
37
|
-
logger.debug('
|
|
37
|
+
logger.debug('Authentication session created, %s', {'session_id': session_id})
|
|
38
38
|
|
|
39
|
-
logger.debug('
|
|
39
|
+
logger.debug('Opening browser and redirecting to Cycode login page')
|
|
40
40
|
self.redirect_to_login_page(code_challenge, session_id)
|
|
41
41
|
|
|
42
|
-
logger.debug('
|
|
42
|
+
logger.debug('Getting API token')
|
|
43
43
|
api_token = self.get_api_token(session_id, code_verifier)
|
|
44
44
|
|
|
45
|
-
logger.debug('
|
|
45
|
+
logger.debug('Saving API token')
|
|
46
46
|
self.save_api_token(api_token)
|
|
47
47
|
|
|
48
48
|
def start_session(self, code_challenge: str) -> str:
|
|
@@ -56,20 +56,20 @@ class AuthManager:
|
|
|
56
56
|
def get_api_token(self, session_id: str, code_verifier: str) -> 'ApiToken':
|
|
57
57
|
api_token = self.get_api_token_polling(session_id, code_verifier)
|
|
58
58
|
if api_token is None:
|
|
59
|
-
raise AuthProcessError('
|
|
59
|
+
raise AuthProcessError('API token pulling is completed, but the token is missing')
|
|
60
60
|
return api_token
|
|
61
61
|
|
|
62
62
|
def get_api_token_polling(self, session_id: str, code_verifier: str) -> 'ApiToken':
|
|
63
63
|
end_polling_time = time.time() + self.POLLING_TIMEOUT_IN_SECONDS
|
|
64
64
|
while time.time() < end_polling_time:
|
|
65
|
-
logger.debug('
|
|
65
|
+
logger.debug('Trying to get API token...')
|
|
66
66
|
api_token_polling_response = self.auth_client.get_api_token(session_id, code_verifier)
|
|
67
67
|
if self._is_api_token_process_completed(api_token_polling_response):
|
|
68
|
-
logger.debug('
|
|
68
|
+
logger.debug('Got API token process completion response')
|
|
69
69
|
return api_token_polling_response.api_token
|
|
70
70
|
if self._is_api_token_process_failed(api_token_polling_response):
|
|
71
|
-
logger.debug('
|
|
72
|
-
raise AuthProcessError('
|
|
71
|
+
logger.debug('Got API token process failure response')
|
|
72
|
+
raise AuthProcessError('Error while obtaining API token')
|
|
73
73
|
time.sleep(self.POLLING_WAIT_INTERVAL_IN_SECONDS)
|
|
74
74
|
|
|
75
75
|
raise AuthProcessError('session expired')
|
|
@@ -70,7 +70,7 @@ def send_report_feedback(
|
|
|
70
70
|
|
|
71
71
|
client.report_status(report_execution_id, scan_status)
|
|
72
72
|
except Exception as e:
|
|
73
|
-
logger.debug(
|
|
73
|
+
logger.debug('Failed to send report feedback', exc_info=e)
|
|
74
74
|
|
|
75
75
|
|
|
76
76
|
def create_sbom_report(
|
|
@@ -148,14 +148,14 @@ def _enrich_scan_result_with_data_from_detection_rules(
|
|
|
148
148
|
|
|
149
149
|
def _get_scan_documents_thread_func(
|
|
150
150
|
context: click.Context, is_git_diff: bool, is_commit_range: bool, scan_parameters: dict
|
|
151
|
-
) -> Callable[[List[Document]], Tuple[str, CliError, LocalScanResult]]:
|
|
151
|
+
) -> Tuple[Callable[[List[Document]], Tuple[str, CliError, LocalScanResult]], str]:
|
|
152
152
|
cycode_client = context.obj['client']
|
|
153
153
|
scan_type = context.obj['scan_type']
|
|
154
154
|
severity_threshold = context.obj['severity_threshold']
|
|
155
155
|
sync_option = context.obj['sync']
|
|
156
156
|
command_scan_type = context.info_name
|
|
157
|
-
|
|
158
|
-
scan_parameters['aggregation_id'] =
|
|
157
|
+
aggregation_id = str(_generate_unique_id())
|
|
158
|
+
scan_parameters['aggregation_id'] = aggregation_id
|
|
159
159
|
|
|
160
160
|
def _scan_batch_thread_func(batch: List[Document]) -> Tuple[str, CliError, LocalScanResult]:
|
|
161
161
|
local_scan_result = error = error_message = None
|
|
@@ -200,7 +200,7 @@ def _get_scan_documents_thread_func(
|
|
|
200
200
|
scan_id = local_scan_result.scan_id
|
|
201
201
|
|
|
202
202
|
logger.debug(
|
|
203
|
-
'
|
|
203
|
+
'Processing scan results, %s',
|
|
204
204
|
{
|
|
205
205
|
'all_violations_count': detections_count,
|
|
206
206
|
'relevant_violations_count': relevant_detections_count,
|
|
@@ -224,7 +224,7 @@ def _get_scan_documents_thread_func(
|
|
|
224
224
|
|
|
225
225
|
return scan_id, error, local_scan_result
|
|
226
226
|
|
|
227
|
-
return _scan_batch_thread_func
|
|
227
|
+
return _scan_batch_thread_func, aggregation_id
|
|
228
228
|
|
|
229
229
|
|
|
230
230
|
def scan_commit_range(
|
|
@@ -246,14 +246,14 @@ def scan_commit_range(
|
|
|
246
246
|
|
|
247
247
|
repo = Repo(path)
|
|
248
248
|
total_commits_count = int(repo.git.rev_list('--count', commit_range))
|
|
249
|
-
logger.debug(
|
|
249
|
+
logger.debug('Calculating diffs for %s commits in the commit range %s', total_commits_count, commit_range)
|
|
250
250
|
|
|
251
251
|
progress_bar.set_section_length(ScanProgressBarSection.PREPARE_LOCAL_FILES, total_commits_count)
|
|
252
252
|
|
|
253
253
|
scanned_commits_count = 0
|
|
254
254
|
for commit in repo.iter_commits(rev=commit_range):
|
|
255
255
|
if _does_reach_to_max_commits_to_scan_limit(commit_ids_to_scan, max_commits_count):
|
|
256
|
-
logger.debug(
|
|
256
|
+
logger.debug('Reached to max commits to scan count. Going to scan only %s last commits', max_commits_count)
|
|
257
257
|
progress_bar.update(ScanProgressBarSection.PREPARE_LOCAL_FILES, total_commits_count - scanned_commits_count)
|
|
258
258
|
break
|
|
259
259
|
|
|
@@ -284,7 +284,7 @@ def scan_commit_range(
|
|
|
284
284
|
scanned_commits_count += 1
|
|
285
285
|
|
|
286
286
|
logger.debug('List of commit ids to scan, %s', {'commit_ids': commit_ids_to_scan})
|
|
287
|
-
logger.debug('Starting to scan commit range (
|
|
287
|
+
logger.debug('Starting to scan commit range (it may take a few minutes)')
|
|
288
288
|
|
|
289
289
|
scan_documents(context, documents_to_scan, is_git_diff=True, is_commit_range=True)
|
|
290
290
|
return None
|
|
@@ -307,16 +307,22 @@ def scan_documents(
|
|
|
307
307
|
ConsolePrinter(context).print_error(
|
|
308
308
|
CliError(
|
|
309
309
|
code='no_relevant_files',
|
|
310
|
-
message='Error: The scan could not be completed - relevant files to scan are not found.'
|
|
310
|
+
message='Error: The scan could not be completed - relevant files to scan are not found. '
|
|
311
|
+
'Enable verbose mode to see more details.',
|
|
311
312
|
)
|
|
312
313
|
)
|
|
313
314
|
return
|
|
314
315
|
|
|
315
|
-
scan_batch_thread_func = _get_scan_documents_thread_func(
|
|
316
|
+
scan_batch_thread_func, aggregation_id = _get_scan_documents_thread_func(
|
|
317
|
+
context, is_git_diff, is_commit_range, scan_parameters
|
|
318
|
+
)
|
|
316
319
|
errors, local_scan_results = run_parallel_batched_scan(
|
|
317
320
|
scan_batch_thread_func, documents_to_scan, progress_bar=progress_bar
|
|
318
321
|
)
|
|
319
|
-
|
|
322
|
+
aggregation_report_url = _try_get_aggregation_report_url_if_needed(
|
|
323
|
+
scan_parameters, context.obj['client'], context.obj['scan_type']
|
|
324
|
+
)
|
|
325
|
+
set_aggregation_report_url(context, aggregation_report_url)
|
|
320
326
|
progress_bar.set_section_length(ScanProgressBarSection.GENERATE_REPORT, 1)
|
|
321
327
|
progress_bar.update(ScanProgressBarSection.GENERATE_REPORT)
|
|
322
328
|
progress_bar.stop()
|
|
@@ -325,6 +331,25 @@ def scan_documents(
|
|
|
325
331
|
print_results(context, local_scan_results, errors)
|
|
326
332
|
|
|
327
333
|
|
|
334
|
+
def set_aggregation_report_url(context: click.Context, aggregation_report_url: Optional[str] = None) -> None:
|
|
335
|
+
context.obj['aggregation_report_url'] = aggregation_report_url
|
|
336
|
+
|
|
337
|
+
|
|
338
|
+
def _try_get_aggregation_report_url_if_needed(
|
|
339
|
+
scan_parameters: dict, cycode_client: 'ScanClient', scan_type: str
|
|
340
|
+
) -> Optional[str]:
|
|
341
|
+
aggregation_id = scan_parameters.get('aggregation_id')
|
|
342
|
+
if not scan_parameters.get('report'):
|
|
343
|
+
return None
|
|
344
|
+
if aggregation_id is None:
|
|
345
|
+
return None
|
|
346
|
+
try:
|
|
347
|
+
report_url_response = cycode_client.get_scan_aggregation_report_url(aggregation_id, scan_type)
|
|
348
|
+
return report_url_response.report_url
|
|
349
|
+
except Exception as e:
|
|
350
|
+
logger.debug('Failed to get aggregation report url: %s', str(e))
|
|
351
|
+
|
|
352
|
+
|
|
328
353
|
def scan_commit_range_documents(
|
|
329
354
|
context: click.Context,
|
|
330
355
|
from_documents_to_scan: List[Document],
|
|
@@ -392,7 +417,7 @@ def scan_commit_range_documents(
|
|
|
392
417
|
scan_id = local_scan_result.scan_id
|
|
393
418
|
|
|
394
419
|
logger.debug(
|
|
395
|
-
'
|
|
420
|
+
'Processing commit range scan results, %s',
|
|
396
421
|
{
|
|
397
422
|
'all_violations_count': detections_count,
|
|
398
423
|
'relevant_violations_count': relevant_detections_count,
|
|
@@ -475,7 +500,7 @@ def perform_scan_async(
|
|
|
475
500
|
scan_parameters: dict,
|
|
476
501
|
) -> ZippedFileScanResult:
|
|
477
502
|
scan_async_result = cycode_client.zipped_file_scan_async(zipped_documents, scan_type, scan_parameters)
|
|
478
|
-
logger.debug('scan request has been triggered successfully,
|
|
503
|
+
logger.debug('Async scan request has been triggered successfully, %s', {'scan_id': scan_async_result.scan_id})
|
|
479
504
|
|
|
480
505
|
return poll_scan_results(
|
|
481
506
|
cycode_client,
|
|
@@ -492,7 +517,7 @@ def perform_scan_sync(
|
|
|
492
517
|
scan_parameters: dict,
|
|
493
518
|
) -> ZippedFileScanResult:
|
|
494
519
|
scan_results = cycode_client.zipped_file_scan_sync(zipped_documents, scan_type, scan_parameters)
|
|
495
|
-
logger.debug('scan request has been triggered successfully,
|
|
520
|
+
logger.debug('Sync scan request has been triggered successfully, %s', {'scan_id': scan_results.id})
|
|
496
521
|
return ZippedFileScanResult(
|
|
497
522
|
did_detect=True,
|
|
498
523
|
detections_per_file=_map_detections_per_file(scan_results.detection_messages),
|
|
@@ -512,7 +537,9 @@ def perform_commit_range_scan_async(
|
|
|
512
537
|
from_commit_zipped_documents, to_commit_zipped_documents, scan_type, scan_parameters
|
|
513
538
|
)
|
|
514
539
|
|
|
515
|
-
logger.debug(
|
|
540
|
+
logger.debug(
|
|
541
|
+
'Async commit range scan request has been triggered successfully, %s', {'scan_id': scan_async_result.scan_id}
|
|
542
|
+
)
|
|
516
543
|
return poll_scan_results(
|
|
517
544
|
cycode_client, scan_async_result.scan_id, scan_type, scan_parameters.get('report'), timeout
|
|
518
545
|
)
|
|
@@ -552,11 +579,12 @@ def poll_scan_results(
|
|
|
552
579
|
|
|
553
580
|
|
|
554
581
|
def print_debug_scan_details(scan_details_response: 'ScanDetailsResponse') -> None:
|
|
555
|
-
logger.debug(
|
|
556
|
-
|
|
582
|
+
logger.debug(
|
|
583
|
+
'Scan update, %s', {'scan_id': scan_details_response.id, 'scan_status': scan_details_response.scan_status}
|
|
584
|
+
)
|
|
557
585
|
|
|
558
586
|
if scan_details_response.message:
|
|
559
|
-
logger.debug(
|
|
587
|
+
logger.debug('Scan message: %s', scan_details_response.message)
|
|
560
588
|
|
|
561
589
|
|
|
562
590
|
def print_results(
|
|
@@ -569,14 +597,16 @@ def print_results(
|
|
|
569
597
|
def get_document_detections(
|
|
570
598
|
scan_result: ZippedFileScanResult, documents_to_scan: List[Document]
|
|
571
599
|
) -> List[DocumentDetections]:
|
|
572
|
-
logger.debug('
|
|
600
|
+
logger.debug('Getting document detections')
|
|
573
601
|
|
|
574
602
|
document_detections = []
|
|
575
603
|
for detections_per_file in scan_result.detections_per_file:
|
|
576
604
|
file_name = get_path_by_os(detections_per_file.file_name)
|
|
577
605
|
commit_id = detections_per_file.commit_id
|
|
578
606
|
|
|
579
|
-
logger.debug(
|
|
607
|
+
logger.debug(
|
|
608
|
+
'Going to find the document of the violated file., %s', {'file_name': file_name, 'commit_id': commit_id}
|
|
609
|
+
)
|
|
580
610
|
|
|
581
611
|
document = _get_document_by_file_name(documents_to_scan, file_name, commit_id)
|
|
582
612
|
document_detections.append(DocumentDetections(document=document, detections=detections_per_file.detections))
|
|
@@ -659,10 +689,10 @@ def get_scan_parameters(context: click.Context, paths: Tuple[str]) -> dict:
|
|
|
659
689
|
def try_get_git_remote_url(path: str) -> Optional[str]:
|
|
660
690
|
try:
|
|
661
691
|
remote_url = Repo(path).remotes[0].config_reader.get('url')
|
|
662
|
-
logger.debug(
|
|
692
|
+
logger.debug('Found Git remote URL, %s', {'remote_url': remote_url, 'path': path})
|
|
663
693
|
return remote_url
|
|
664
694
|
except Exception as e:
|
|
665
|
-
logger.debug('Failed to get
|
|
695
|
+
logger.debug('Failed to get Git remote URL', exc_info=e)
|
|
666
696
|
return None
|
|
667
697
|
|
|
668
698
|
|
|
@@ -719,15 +749,15 @@ def _should_exclude_detection(detection: Detection, exclusions: Dict) -> bool:
|
|
|
719
749
|
exclusions_by_value = exclusions.get(consts.EXCLUSIONS_BY_VALUE_SECTION_NAME, [])
|
|
720
750
|
if _is_detection_sha_configured_in_exclusions(detection, exclusions_by_value):
|
|
721
751
|
logger.debug(
|
|
722
|
-
'Going to ignore violations because
|
|
723
|
-
{'
|
|
752
|
+
'Going to ignore violations because they are on the values-to-ignore list, %s',
|
|
753
|
+
{'value_sha': detection.detection_details.get('sha512', '')},
|
|
724
754
|
)
|
|
725
755
|
return True
|
|
726
756
|
|
|
727
757
|
exclusions_by_sha = exclusions.get(consts.EXCLUSIONS_BY_SHA_SECTION_NAME, [])
|
|
728
758
|
if _is_detection_sha_configured_in_exclusions(detection, exclusions_by_sha):
|
|
729
759
|
logger.debug(
|
|
730
|
-
'Going to ignore violations because
|
|
760
|
+
'Going to ignore violations because they are on the SHA ignore list, %s',
|
|
731
761
|
{'sha': detection.detection_details.get('sha512', '')},
|
|
732
762
|
)
|
|
733
763
|
return True
|
|
@@ -737,7 +767,7 @@ def _should_exclude_detection(detection: Detection, exclusions: Dict) -> bool:
|
|
|
737
767
|
detection_rule = detection.detection_rule_id
|
|
738
768
|
if detection_rule in exclusions_by_rule:
|
|
739
769
|
logger.debug(
|
|
740
|
-
'Going to ignore violations because
|
|
770
|
+
'Going to ignore violations because they are on the Rule ID ignore list, %s',
|
|
741
771
|
{'detection_rule': detection_rule},
|
|
742
772
|
)
|
|
743
773
|
return True
|
|
@@ -747,7 +777,7 @@ def _should_exclude_detection(detection: Detection, exclusions: Dict) -> bool:
|
|
|
747
777
|
package = _get_package_name(detection)
|
|
748
778
|
if package in exclusions_by_package:
|
|
749
779
|
logger.debug(
|
|
750
|
-
'Going to ignore violations because
|
|
780
|
+
'Going to ignore violations because they are on the packages-to-ignore list, %s', {'package': package}
|
|
751
781
|
)
|
|
752
782
|
return True
|
|
753
783
|
|
|
@@ -810,7 +840,7 @@ def _report_scan_status(
|
|
|
810
840
|
|
|
811
841
|
cycode_client.report_scan_status(scan_type, scan_id, scan_status, should_use_scan_service)
|
|
812
842
|
except Exception as e:
|
|
813
|
-
logger.debug('Failed to report scan status
|
|
843
|
+
logger.debug('Failed to report scan status', exc_info=e)
|
|
814
844
|
|
|
815
845
|
|
|
816
846
|
def _generate_unique_id() -> UUID:
|
|
@@ -868,7 +898,7 @@ def _try_get_report_url_if_needed(
|
|
|
868
898
|
report_url_response = cycode_client.get_scan_report_url(scan_id, scan_type)
|
|
869
899
|
return report_url_response.report_url
|
|
870
900
|
except Exception as e:
|
|
871
|
-
logger.debug('Failed to get report
|
|
901
|
+
logger.debug('Failed to get report URL', exc_info=e)
|
|
872
902
|
|
|
873
903
|
|
|
874
904
|
def wait_for_detections_creation(
|
|
@@ -883,16 +913,18 @@ def wait_for_detections_creation(
|
|
|
883
913
|
while time.time() < end_polling_time:
|
|
884
914
|
scan_persisted_detections_count = cycode_client.get_scan_detections_count(scan_type, scan_id)
|
|
885
915
|
logger.debug(
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
916
|
+
'Excepting %s detections, got %s detections (%s more; %s seconds left)',
|
|
917
|
+
expected_detections_count,
|
|
918
|
+
scan_persisted_detections_count,
|
|
919
|
+
expected_detections_count - scan_persisted_detections_count,
|
|
920
|
+
round(end_polling_time - time.time()),
|
|
889
921
|
)
|
|
890
922
|
if scan_persisted_detections_count == expected_detections_count:
|
|
891
923
|
return
|
|
892
924
|
|
|
893
925
|
time.sleep(consts.DETECTIONS_COUNT_VERIFICATION_WAIT_INTERVAL_IN_SECONDS)
|
|
894
926
|
|
|
895
|
-
logger.debug(
|
|
927
|
+
logger.debug('%s detections has been created', scan_persisted_detections_count)
|
|
896
928
|
raise custom_exceptions.ScanAsyncError(
|
|
897
929
|
f'Failed to wait for detections to be created after {polling_timeout} seconds'
|
|
898
930
|
)
|
|
@@ -905,14 +937,14 @@ def _map_detections_per_file(detections: List[dict]) -> List[DetectionsPerFile]:
|
|
|
905
937
|
detection['message'] = detection['correlation_message']
|
|
906
938
|
file_name = _get_file_name_from_detection(detection)
|
|
907
939
|
if file_name is None:
|
|
908
|
-
logger.debug('
|
|
940
|
+
logger.debug('File name is missing from detection with ID %s', detection.get('id'))
|
|
909
941
|
continue
|
|
910
942
|
if detections_per_files.get(file_name) is None:
|
|
911
943
|
detections_per_files[file_name] = [DetectionSchema().load(detection)]
|
|
912
944
|
else:
|
|
913
945
|
detections_per_files[file_name].append(DetectionSchema().load(detection))
|
|
914
946
|
except Exception as e:
|
|
915
|
-
logger.debug('Failed to parse detection
|
|
947
|
+
logger.debug('Failed to parse detection', exc_info=e)
|
|
916
948
|
continue
|
|
917
949
|
|
|
918
950
|
return [
|
{cycode-1.9.5.dev5 → cycode-1.9.6.dev3}/cycode/cli/commands/scan/pre_receive/pre_receive_command.py
RENAMED
|
@@ -32,14 +32,14 @@ def pre_receive_command(context: click.Context, ignored_args: List[str]) -> None
|
|
|
32
32
|
|
|
33
33
|
if should_skip_pre_receive_scan():
|
|
34
34
|
logger.info(
|
|
35
|
-
'A scan has been skipped as per your request.'
|
|
36
|
-
'
|
|
35
|
+
'A scan has been skipped as per your request. '
|
|
36
|
+
'Please note that this may leave your system vulnerable to secrets that have not been detected.'
|
|
37
37
|
)
|
|
38
38
|
return
|
|
39
39
|
|
|
40
40
|
if is_verbose_mode_requested_in_pre_receive_scan():
|
|
41
41
|
enable_verbose_mode(context)
|
|
42
|
-
logger.debug('Verbose mode enabled
|
|
42
|
+
logger.debug('Verbose mode enabled: all log levels will be displayed.')
|
|
43
43
|
|
|
44
44
|
command_scan_type = context.info_name
|
|
45
45
|
timeout = configuration_manager.get_pre_receive_command_timeout(command_scan_type)
|
|
@@ -51,7 +51,8 @@ def pre_receive_command(context: click.Context, ignored_args: List[str]) -> None
|
|
|
51
51
|
commit_range = calculate_pre_receive_commit_range(branch_update_details)
|
|
52
52
|
if not commit_range:
|
|
53
53
|
logger.info(
|
|
54
|
-
'No new commits found for pushed branch, %s',
|
|
54
|
+
'No new commits found for pushed branch, %s',
|
|
55
|
+
{'branch_update_details': branch_update_details},
|
|
55
56
|
)
|
|
56
57
|
return
|
|
57
58
|
|
|
@@ -62,23 +62,36 @@ def _does_document_exceed_max_size_limit(content: str) -> bool:
|
|
|
62
62
|
|
|
63
63
|
def _is_relevant_file_to_scan(scan_type: str, filename: str) -> bool:
|
|
64
64
|
if _is_subpath_of_cycode_configuration_folder(filename):
|
|
65
|
-
logger.debug(
|
|
65
|
+
logger.debug(
|
|
66
|
+
'The file is irrelevant because it is in the Cycode configuration directory, %s',
|
|
67
|
+
{'filename': filename, 'configuration_directory': consts.CYCODE_CONFIGURATION_DIRECTORY},
|
|
68
|
+
)
|
|
66
69
|
return False
|
|
67
70
|
|
|
68
71
|
if _is_path_configured_in_exclusions(scan_type, filename):
|
|
69
|
-
logger.debug('file is irrelevant because
|
|
72
|
+
logger.debug('The file is irrelevant because its path is in the ignore paths list, %s', {'filename': filename})
|
|
70
73
|
return False
|
|
71
74
|
|
|
72
75
|
if not _is_file_extension_supported(scan_type, filename):
|
|
73
|
-
logger.debug(
|
|
76
|
+
logger.debug(
|
|
77
|
+
'The file is irrelevant because its extension is not supported, %s',
|
|
78
|
+
{'scan_type': scan_type, 'filename': filename},
|
|
79
|
+
)
|
|
74
80
|
return False
|
|
75
81
|
|
|
76
82
|
if is_binary_file(filename):
|
|
77
|
-
logger.debug('file is irrelevant because it is binary file, %s', {'filename': filename})
|
|
83
|
+
logger.debug('The file is irrelevant because it is a binary file, %s', {'filename': filename})
|
|
78
84
|
return False
|
|
79
85
|
|
|
80
86
|
if scan_type != consts.SCA_SCAN_TYPE and _does_file_exceed_max_size_limit(filename):
|
|
81
|
-
logger.debug(
|
|
87
|
+
logger.debug(
|
|
88
|
+
'The file is irrelevant because it has exceeded the maximum size limit, %s',
|
|
89
|
+
{
|
|
90
|
+
'max_file_size': consts.FILE_MAX_SIZE_LIMIT_IN_BYTES,
|
|
91
|
+
'file_size': get_file_size(filename),
|
|
92
|
+
'filename': filename,
|
|
93
|
+
},
|
|
94
|
+
)
|
|
82
95
|
return False
|
|
83
96
|
|
|
84
97
|
if scan_type == consts.SCA_SCAN_TYPE and not _is_file_relevant_for_sca_scan(filename):
|
|
@@ -89,7 +102,9 @@ def _is_relevant_file_to_scan(scan_type: str, filename: str) -> bool:
|
|
|
89
102
|
|
|
90
103
|
def _is_file_relevant_for_sca_scan(filename: str) -> bool:
|
|
91
104
|
if any(sca_excluded_path in filename for sca_excluded_path in consts.SCA_EXCLUDED_PATHS):
|
|
92
|
-
logger.debug(
|
|
105
|
+
logger.debug(
|
|
106
|
+
'The file is irrelevant because it is from the inner path of node_modules, %s', {'filename': filename}
|
|
107
|
+
)
|
|
93
108
|
return False
|
|
94
109
|
|
|
95
110
|
return True
|
|
@@ -98,27 +113,39 @@ def _is_file_relevant_for_sca_scan(filename: str) -> bool:
|
|
|
98
113
|
def _is_relevant_document_to_scan(scan_type: str, filename: str, content: str) -> bool:
|
|
99
114
|
if _is_subpath_of_cycode_configuration_folder(filename):
|
|
100
115
|
logger.debug(
|
|
101
|
-
'document is irrelevant because it is in
|
|
116
|
+
'The document is irrelevant because it is in the Cycode configuration directory, %s',
|
|
117
|
+
{'filename': filename, 'configuration_directory': consts.CYCODE_CONFIGURATION_DIRECTORY},
|
|
102
118
|
)
|
|
103
119
|
return False
|
|
104
120
|
|
|
105
121
|
if _is_path_configured_in_exclusions(scan_type, filename):
|
|
106
122
|
logger.debug(
|
|
107
|
-
'document is irrelevant because
|
|
123
|
+
'The document is irrelevant because its path is in the ignore paths list, %s', {'filename': filename}
|
|
108
124
|
)
|
|
109
125
|
return False
|
|
110
126
|
|
|
111
127
|
if not _is_file_extension_supported(scan_type, filename):
|
|
112
|
-
logger.debug(
|
|
128
|
+
logger.debug(
|
|
129
|
+
'The document is irrelevant because its extension is not supported, %s',
|
|
130
|
+
{'scan_type': scan_type, 'filename': filename},
|
|
131
|
+
)
|
|
113
132
|
return False
|
|
114
133
|
|
|
115
134
|
if is_binary_content(content):
|
|
116
|
-
logger.debug('document is irrelevant because it is binary, %s', {'filename': filename})
|
|
135
|
+
logger.debug('The document is irrelevant because it is a binary file, %s', {'filename': filename})
|
|
117
136
|
return False
|
|
118
137
|
|
|
119
138
|
if scan_type != consts.SCA_SCAN_TYPE and _does_document_exceed_max_size_limit(content):
|
|
120
|
-
logger.debug(
|
|
139
|
+
logger.debug(
|
|
140
|
+
'The document is irrelevant because it has exceeded the maximum size limit, %s',
|
|
141
|
+
{
|
|
142
|
+
'max_document_size': consts.FILE_MAX_SIZE_LIMIT_IN_BYTES,
|
|
143
|
+
'document_size': get_content_size(content),
|
|
144
|
+
'filename': filename,
|
|
145
|
+
},
|
|
146
|
+
)
|
|
121
147
|
return False
|
|
148
|
+
|
|
122
149
|
return True
|
|
123
150
|
|
|
124
151
|
|
|
@@ -74,7 +74,7 @@ def _get_relevant_files(
|
|
|
74
74
|
progress_bar.set_section_length(progress_bar_section, progress_bar_section_len)
|
|
75
75
|
|
|
76
76
|
logger.debug(
|
|
77
|
-
'Found all relevant files for scanning %s', {'paths': paths, 'file_to_scan_count': len(relevant_files_to_scan)}
|
|
77
|
+
'Found all relevant files for scanning, %s', {'paths': paths, 'file_to_scan_count': len(relevant_files_to_scan)}
|
|
78
78
|
)
|
|
79
79
|
|
|
80
80
|
return relevant_files_to_scan
|
|
@@ -17,7 +17,7 @@ def execute_command(command: List[str], file_name: str, command_timeout: int) ->
|
|
|
17
17
|
try:
|
|
18
18
|
dependencies = shell(command, command_timeout)
|
|
19
19
|
except Exception as e:
|
|
20
|
-
logger.debug('Failed to restore dependencies shell
|
|
20
|
+
logger.debug('Failed to restore dependencies via shell command, %s', {'filename': file_name}, exc_info=e)
|
|
21
21
|
return None
|
|
22
22
|
|
|
23
23
|
return dependencies
|
|
@@ -47,7 +47,7 @@ def add_ecosystem_related_files_if_exists(
|
|
|
47
47
|
for doc in documents:
|
|
48
48
|
ecosystem = get_project_file_ecosystem(doc)
|
|
49
49
|
if ecosystem is None:
|
|
50
|
-
logger.debug('
|
|
50
|
+
logger.debug('Failed to resolve project file ecosystem: %s', doc.path)
|
|
51
51
|
continue
|
|
52
52
|
|
|
53
53
|
documents_to_add.extend(get_doc_ecosystem_related_project_files(doc, documents, ecosystem, commit_rev, repo))
|
|
@@ -94,20 +94,20 @@ def try_restore_dependencies(
|
|
|
94
94
|
if restore_dependencies.is_project(document):
|
|
95
95
|
restore_dependencies_document = restore_dependencies.restore(document)
|
|
96
96
|
if restore_dependencies_document is None:
|
|
97
|
-
logger.warning('Error occurred while trying to generate dependencies tree
|
|
97
|
+
logger.warning('Error occurred while trying to generate dependencies tree, %s', {'filename': document.path})
|
|
98
98
|
return
|
|
99
99
|
|
|
100
100
|
if restore_dependencies_document.content is None:
|
|
101
|
-
logger.warning('Error occurred while trying to generate dependencies tree
|
|
101
|
+
logger.warning('Error occurred while trying to generate dependencies tree, %s', {'filename': document.path})
|
|
102
102
|
restore_dependencies_document.content = ''
|
|
103
103
|
else:
|
|
104
104
|
is_monitor_action = context.obj.get('monitor')
|
|
105
105
|
project_path = context.params.get('path')
|
|
106
106
|
manifest_file_path = get_manifest_file_path(document, is_monitor_action, project_path)
|
|
107
|
-
logger.debug(
|
|
107
|
+
logger.debug('Succeeded to generate dependencies tree on path: %s', manifest_file_path)
|
|
108
108
|
|
|
109
109
|
if restore_dependencies_document.path in documents_to_add:
|
|
110
|
-
logger.debug(
|
|
110
|
+
logger.debug('Duplicate document on restore for path: %s', restore_dependencies_document.path)
|
|
111
111
|
else:
|
|
112
112
|
documents_to_add[restore_dependencies_document.path] = restore_dependencies_document
|
|
113
113
|
|
|
@@ -147,5 +147,5 @@ def perform_pre_scan_documents_actions(
|
|
|
147
147
|
context: click.Context, scan_type: str, documents_to_scan: List[Document], is_git_diff: bool = False
|
|
148
148
|
) -> None:
|
|
149
149
|
if scan_type == consts.SCA_SCAN_TYPE and not context.obj.get(consts.SCA_SKIP_RESTORE_DEPENDENCIES_FLAG):
|
|
150
|
-
logger.debug('Perform pre
|
|
150
|
+
logger.debug('Perform pre-scan document add_dependencies_tree_document action')
|
|
151
151
|
add_dependencies_tree_document(context, documents_to_scan, is_git_diff)
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import timeit
|
|
2
2
|
from pathlib import Path
|
|
3
3
|
from typing import List, Optional
|
|
4
4
|
|
|
@@ -22,25 +22,26 @@ def zip_documents(scan_type: str, documents: List[Document], zip_file: Optional[
|
|
|
22
22
|
if zip_file is None:
|
|
23
23
|
zip_file = InMemoryZip()
|
|
24
24
|
|
|
25
|
-
start_zip_creation_time =
|
|
25
|
+
start_zip_creation_time = timeit.default_timer()
|
|
26
26
|
|
|
27
27
|
for index, document in enumerate(documents):
|
|
28
28
|
_validate_zip_file_size(scan_type, zip_file.size)
|
|
29
29
|
|
|
30
30
|
logger.debug(
|
|
31
|
-
'
|
|
31
|
+
'Adding file to ZIP, %s',
|
|
32
|
+
{'index': index, 'filename': document.path, 'unique_id': document.unique_id},
|
|
32
33
|
)
|
|
33
34
|
zip_file.append(document.path, document.unique_id, document.content)
|
|
34
35
|
|
|
35
36
|
zip_file.close()
|
|
36
37
|
|
|
37
|
-
end_zip_creation_time =
|
|
38
|
+
end_zip_creation_time = timeit.default_timer()
|
|
38
39
|
zip_creation_time = int(end_zip_creation_time - start_zip_creation_time)
|
|
39
|
-
logger.debug('
|
|
40
|
+
logger.debug('Finished to create ZIP file, %s', {'zip_creation_time': zip_creation_time})
|
|
40
41
|
|
|
41
42
|
if zip_file.configuration_manager.get_debug_flag():
|
|
42
43
|
zip_file_path = Path.joinpath(Path.cwd(), f'{scan_type}_scan_{end_zip_creation_time}.zip')
|
|
43
|
-
logger.debug('
|
|
44
|
+
logger.debug('Writing ZIP file to disk, %s', {'zip_file_path': zip_file_path})
|
|
44
45
|
zip_file.write_on_disk(zip_file_path)
|
|
45
46
|
|
|
46
47
|
return zip_file
|
|
@@ -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)
|