cycode 3.0.1.dev1__tar.gz → 3.0.2.dev2__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-3.0.1.dev1 → cycode-3.0.2.dev2}/PKG-INFO +1 -1
- cycode-3.0.2.dev2/cycode/__init__.py +1 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/apps/scan/code_scanner.py +6 -6
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/apps/scan/pre_commit/pre_commit_command.py +2 -2
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/apps/scan/repository/repository_command.py +2 -2
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/apps/scan/scan_command.py +8 -1
- cycode-3.0.2.dev2/cycode/cli/files_collector/excluder.py +174 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/files_collector/models/in_memory_zip.py +18 -8
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/files_collector/path_documents.py +4 -2
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/files_collector/sca/base_restore_dependencies.py +4 -5
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/files_collector/sca/go/restore_go_dependencies.py +0 -3
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/files_collector/sca/maven/restore_maven_dependencies.py +23 -21
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/files_collector/sca/ruby/restore_ruby_dependencies.py +0 -6
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/files_collector/sca/sbt/restore_sbt_dependencies.py +0 -6
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/files_collector/sca/sca_code_scanner.py +12 -9
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cyclient/models.py +16 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cyclient/scan_client.py +32 -2
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/pyproject.toml +1 -1
- cycode-3.0.1.dev1/cycode/__init__.py +0 -1
- cycode-3.0.1.dev1/cycode/cli/files_collector/excluder.py +0 -161
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/LICENCE +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/README.md +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/__main__.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/__init__.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/app.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/apps/__init__.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/apps/ai_remediation/__init__.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/apps/ai_remediation/ai_remediation_command.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/apps/ai_remediation/apply_fix.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/apps/ai_remediation/print_remediation.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/apps/auth/__init__.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/apps/auth/auth_command.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/apps/auth/auth_common.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/apps/auth/auth_manager.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/apps/auth/models.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/apps/configure/__init__.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/apps/configure/configure_command.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/apps/configure/consts.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/apps/configure/messages.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/apps/configure/prompts.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/apps/ignore/__init__.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/apps/ignore/ignore_command.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/apps/report/__init__.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/apps/report/report_command.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/apps/report/sbom/__init__.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/apps/report/sbom/common.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/apps/report/sbom/path/__init__.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/apps/report/sbom/path/path_command.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/apps/report/sbom/repository_url/__init__.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/apps/report/sbom/repository_url/repository_url_command.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/apps/report/sbom/sbom_command.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/apps/report/sbom/sbom_report_file.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/apps/scan/__init__.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/apps/scan/commit_history/__init__.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/apps/scan/commit_history/commit_history_command.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/apps/scan/path/__init__.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/apps/scan/path/path_command.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/apps/scan/pre_commit/__init__.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/apps/scan/pre_receive/__init__.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/apps/scan/pre_receive/pre_receive_command.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/apps/scan/repository/__init__.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/apps/scan/scan_ci/__init__.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/apps/scan/scan_ci/ci_integrations.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/apps/scan/scan_ci/scan_ci_command.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/apps/status/__init__.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/apps/status/get_cli_status.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/apps/status/models.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/apps/status/status_command.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/apps/status/version_command.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/cli_types.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/config.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/console.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/consts.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/exceptions/__init__.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/exceptions/custom_exceptions.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/exceptions/handle_ai_remediation_errors.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/exceptions/handle_auth_errors.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/exceptions/handle_errors.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/exceptions/handle_report_sbom_errors.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/exceptions/handle_scan_errors.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/files_collector/__init__.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/files_collector/iac/__init__.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/files_collector/iac/tf_content_generator.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/files_collector/models/__init__.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/files_collector/repository_documents.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/files_collector/sca/__init__.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/files_collector/sca/go/__init__.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/files_collector/sca/maven/__init__.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/files_collector/sca/maven/restore_gradle_dependencies.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/files_collector/sca/npm/__init__.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/files_collector/sca/npm/restore_npm_dependencies.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/files_collector/sca/nuget/__init__.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/files_collector/sca/nuget/restore_nuget_dependencies.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/files_collector/sca/ruby/__init__.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/files_collector/sca/sbt/__init__.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/files_collector/walk_ignore.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/files_collector/zip_documents.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/logger.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/main.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/models.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/printers/__init__.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/printers/console_printer.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/printers/json_printer.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/printers/printer_base.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/printers/rich_printer.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/printers/tables/__init__.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/printers/tables/sca_table_printer.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/printers/tables/table.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/printers/tables/table_models.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/printers/tables/table_printer.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/printers/tables/table_printer_base.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/printers/text_printer.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/printers/utils/__init__.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/printers/utils/code_snippet_syntax.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/printers/utils/detection_data.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/printers/utils/detection_ordering/__init__.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/printers/utils/detection_ordering/common_ordering.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/printers/utils/detection_ordering/sca_ordering.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/printers/utils/rich_helpers.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/user_settings/__init__.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/user_settings/base_file_manager.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/user_settings/config_file_manager.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/user_settings/configuration_manager.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/user_settings/credentials_manager.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/user_settings/jwt_creator.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/utils/__init__.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/utils/enum_utils.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/utils/get_api_client.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/utils/git_proxy.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/utils/ignore_utils.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/utils/jwt_utils.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/utils/path_utils.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/utils/progress_bar.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/utils/scan_batch.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/utils/scan_utils.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/utils/sentry.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/utils/shell_executor.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/utils/string_utils.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/utils/task_timer.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/utils/version_checker.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/utils/yaml_utils.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/config.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cyclient/__init__.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cyclient/auth_client.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cyclient/client_creator.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cyclient/config.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cyclient/config_dev.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cyclient/cycode_client.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cyclient/cycode_client_base.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cyclient/cycode_dev_based_client.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cyclient/cycode_token_based_client.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cyclient/headers.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cyclient/logger.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cyclient/report_client.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cyclient/scan_config_base.py +0 -0
- {cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/logger.py +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = '3.0.2.dev2' # DON'T TOUCH. Placeholder. Will be filled automatically on poetry build from Git Tag
|
|
@@ -15,7 +15,7 @@ from cycode.cli.config import configuration_manager
|
|
|
15
15
|
from cycode.cli.console import console
|
|
16
16
|
from cycode.cli.exceptions import custom_exceptions
|
|
17
17
|
from cycode.cli.exceptions.handle_scan_errors import handle_scan_exception
|
|
18
|
-
from cycode.cli.files_collector.excluder import
|
|
18
|
+
from cycode.cli.files_collector.excluder import excluder
|
|
19
19
|
from cycode.cli.files_collector.models.in_memory_zip import InMemoryZip
|
|
20
20
|
from cycode.cli.files_collector.path_documents import get_relevant_documents
|
|
21
21
|
from cycode.cli.files_collector.repository_documents import (
|
|
@@ -56,8 +56,8 @@ def scan_sca_pre_commit(ctx: typer.Context, repo_path: str) -> None:
|
|
|
56
56
|
progress_bar_section=ScanProgressBarSection.PREPARE_LOCAL_FILES,
|
|
57
57
|
repo_path=repo_path,
|
|
58
58
|
)
|
|
59
|
-
git_head_documents = exclude_irrelevant_documents_to_scan(scan_type, git_head_documents)
|
|
60
|
-
pre_committed_documents = exclude_irrelevant_documents_to_scan(scan_type, pre_committed_documents)
|
|
59
|
+
git_head_documents = excluder.exclude_irrelevant_documents_to_scan(scan_type, git_head_documents)
|
|
60
|
+
pre_committed_documents = excluder.exclude_irrelevant_documents_to_scan(scan_type, pre_committed_documents)
|
|
61
61
|
sca_code_scanner.perform_pre_hook_range_scan_actions(repo_path, git_head_documents, pre_committed_documents)
|
|
62
62
|
scan_commit_range_documents(
|
|
63
63
|
ctx,
|
|
@@ -77,8 +77,8 @@ def scan_sca_commit_range(ctx: typer.Context, path: str, commit_range: str) -> N
|
|
|
77
77
|
from_commit_documents, to_commit_documents = get_commit_range_modified_documents(
|
|
78
78
|
progress_bar, ScanProgressBarSection.PREPARE_LOCAL_FILES, path, from_commit_rev, to_commit_rev
|
|
79
79
|
)
|
|
80
|
-
from_commit_documents = exclude_irrelevant_documents_to_scan(scan_type, from_commit_documents)
|
|
81
|
-
to_commit_documents = exclude_irrelevant_documents_to_scan(scan_type, to_commit_documents)
|
|
80
|
+
from_commit_documents = excluder.exclude_irrelevant_documents_to_scan(scan_type, from_commit_documents)
|
|
81
|
+
to_commit_documents = excluder.exclude_irrelevant_documents_to_scan(scan_type, to_commit_documents)
|
|
82
82
|
sca_code_scanner.perform_pre_commit_range_scan_actions(
|
|
83
83
|
path, from_commit_documents, from_commit_rev, to_commit_documents, to_commit_rev
|
|
84
84
|
)
|
|
@@ -288,7 +288,7 @@ def scan_commit_range(
|
|
|
288
288
|
{'path': path, 'commit_range': commit_range, 'commit_id': commit_id},
|
|
289
289
|
)
|
|
290
290
|
|
|
291
|
-
documents_to_scan.extend(exclude_irrelevant_documents_to_scan(scan_type, commit_documents_to_scan))
|
|
291
|
+
documents_to_scan.extend(excluder.exclude_irrelevant_documents_to_scan(scan_type, commit_documents_to_scan))
|
|
292
292
|
|
|
293
293
|
logger.debug('List of commit ids to scan, %s', {'commit_ids': commit_ids_to_scan})
|
|
294
294
|
logger.debug('Starting to scan commit range (it may take a few minutes)')
|
{cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/apps/scan/pre_commit/pre_commit_command.py
RENAMED
|
@@ -5,7 +5,7 @@ import typer
|
|
|
5
5
|
|
|
6
6
|
from cycode.cli import consts
|
|
7
7
|
from cycode.cli.apps.scan.code_scanner import get_scan_parameters, scan_documents, scan_sca_pre_commit
|
|
8
|
-
from cycode.cli.files_collector.excluder import
|
|
8
|
+
from cycode.cli.files_collector.excluder import excluder
|
|
9
9
|
from cycode.cli.files_collector.repository_documents import (
|
|
10
10
|
get_diff_file_content,
|
|
11
11
|
get_diff_file_path,
|
|
@@ -45,5 +45,5 @@ def pre_commit_command(
|
|
|
45
45
|
progress_bar.update(ScanProgressBarSection.PREPARE_LOCAL_FILES)
|
|
46
46
|
documents_to_scan.append(Document(get_path_by_os(get_diff_file_path(file)), get_diff_file_content(file)))
|
|
47
47
|
|
|
48
|
-
documents_to_scan = exclude_irrelevant_documents_to_scan(scan_type, documents_to_scan)
|
|
48
|
+
documents_to_scan = excluder.exclude_irrelevant_documents_to_scan(scan_type, documents_to_scan)
|
|
49
49
|
scan_documents(ctx, documents_to_scan, get_scan_parameters(ctx), is_git_diff=True)
|
{cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/apps/scan/repository/repository_command.py
RENAMED
|
@@ -7,7 +7,7 @@ import typer
|
|
|
7
7
|
from cycode.cli import consts
|
|
8
8
|
from cycode.cli.apps.scan.code_scanner import get_scan_parameters, scan_documents
|
|
9
9
|
from cycode.cli.exceptions.handle_scan_errors import handle_scan_exception
|
|
10
|
-
from cycode.cli.files_collector.excluder import
|
|
10
|
+
from cycode.cli.files_collector.excluder import excluder
|
|
11
11
|
from cycode.cli.files_collector.repository_documents import get_git_repository_tree_file_entries
|
|
12
12
|
from cycode.cli.files_collector.sca.sca_code_scanner import perform_pre_scan_documents_actions
|
|
13
13
|
from cycode.cli.logger import logger
|
|
@@ -57,7 +57,7 @@ def repository_command(
|
|
|
57
57
|
)
|
|
58
58
|
)
|
|
59
59
|
|
|
60
|
-
documents_to_scan = exclude_irrelevant_documents_to_scan(scan_type, documents_to_scan)
|
|
60
|
+
documents_to_scan = excluder.exclude_irrelevant_documents_to_scan(scan_type, documents_to_scan)
|
|
61
61
|
|
|
62
62
|
perform_pre_scan_documents_actions(ctx, scan_type, documents_to_scan)
|
|
63
63
|
|
|
@@ -9,6 +9,7 @@ from cycode.cli.consts import (
|
|
|
9
9
|
ISSUE_DETECTED_STATUS_CODE,
|
|
10
10
|
NO_ISSUES_STATUS_CODE,
|
|
11
11
|
)
|
|
12
|
+
from cycode.cli.files_collector.excluder import excluder
|
|
12
13
|
from cycode.cli.utils import scan_utils
|
|
13
14
|
from cycode.cli.utils.get_api_client import get_scan_cycode_client
|
|
14
15
|
from cycode.cli.utils.sentry import add_breadcrumb
|
|
@@ -138,13 +139,19 @@ def scan_command(
|
|
|
138
139
|
|
|
139
140
|
ctx.obj['show_secret'] = show_secret
|
|
140
141
|
ctx.obj['soft_fail'] = soft_fail
|
|
141
|
-
ctx.obj['client'] = get_scan_cycode_client(ctx)
|
|
142
142
|
ctx.obj['scan_type'] = scan_type
|
|
143
143
|
ctx.obj['sync'] = sync
|
|
144
144
|
ctx.obj['severity_threshold'] = severity_threshold
|
|
145
145
|
ctx.obj['monitor'] = monitor
|
|
146
146
|
ctx.obj['report'] = report
|
|
147
147
|
|
|
148
|
+
scan_client = get_scan_cycode_client(ctx)
|
|
149
|
+
ctx.obj['client'] = scan_client
|
|
150
|
+
|
|
151
|
+
remote_scan_config = scan_client.get_scan_configuration_safe(scan_type)
|
|
152
|
+
if remote_scan_config:
|
|
153
|
+
excluder.apply_scan_config(str(scan_type), remote_scan_config)
|
|
154
|
+
|
|
148
155
|
if export_type and export_file:
|
|
149
156
|
console_printer = ctx.obj['console_printer']
|
|
150
157
|
console_printer.enable_recording(export_type, export_file)
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
from typing import TYPE_CHECKING
|
|
2
|
+
|
|
3
|
+
from cycode.cli import consts
|
|
4
|
+
from cycode.cli.config import configuration_manager
|
|
5
|
+
from cycode.cli.user_settings.config_file_manager import ConfigFileManager
|
|
6
|
+
from cycode.cli.utils.path_utils import get_file_size, is_binary_file, is_sub_path
|
|
7
|
+
from cycode.cli.utils.string_utils import get_content_size, is_binary_content
|
|
8
|
+
from cycode.logger import get_logger
|
|
9
|
+
|
|
10
|
+
if TYPE_CHECKING:
|
|
11
|
+
from cycode.cli.models import Document
|
|
12
|
+
from cycode.cli.utils.progress_bar import BaseProgressBar, ProgressBarSection
|
|
13
|
+
from cycode.cyclient import models
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
logger = get_logger('File Excluder')
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def _is_subpath_of_cycode_configuration_folder(filename: str) -> bool:
|
|
20
|
+
return (
|
|
21
|
+
is_sub_path(configuration_manager.global_config_file_manager.get_config_directory_path(), filename)
|
|
22
|
+
or is_sub_path(configuration_manager.local_config_file_manager.get_config_directory_path(), filename)
|
|
23
|
+
or filename.endswith(ConfigFileManager.get_config_file_route())
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def _is_path_configured_in_exclusions(scan_type: str, file_path: str) -> bool:
|
|
28
|
+
exclusions_by_path = configuration_manager.get_exclusions_by_scan_type(scan_type).get(
|
|
29
|
+
consts.EXCLUSIONS_BY_PATH_SECTION_NAME, []
|
|
30
|
+
)
|
|
31
|
+
return any(is_sub_path(exclusion_path, file_path) for exclusion_path in exclusions_by_path)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def _does_file_exceed_max_size_limit(filename: str) -> bool:
|
|
35
|
+
return get_file_size(filename) > consts.FILE_MAX_SIZE_LIMIT_IN_BYTES
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def _does_document_exceed_max_size_limit(content: str) -> bool:
|
|
39
|
+
return get_content_size(content) > consts.FILE_MAX_SIZE_LIMIT_IN_BYTES
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def _is_file_relevant_for_sca_scan(filename: str) -> bool:
|
|
43
|
+
if any(sca_excluded_path in filename for sca_excluded_path in consts.SCA_EXCLUDED_PATHS):
|
|
44
|
+
logger.debug(
|
|
45
|
+
'The file is irrelevant because it is from the inner path of node_modules, %s', {'filename': filename}
|
|
46
|
+
)
|
|
47
|
+
return False
|
|
48
|
+
|
|
49
|
+
return True
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
class Excluder:
|
|
53
|
+
def __init__(self) -> None:
|
|
54
|
+
self._scannable_extensions: dict[str, tuple[str, ...]] = {
|
|
55
|
+
consts.IAC_SCAN_TYPE: consts.IAC_SCAN_SUPPORTED_FILES,
|
|
56
|
+
consts.SCA_SCAN_TYPE: consts.SCA_CONFIGURATION_SCAN_SUPPORTED_FILES,
|
|
57
|
+
}
|
|
58
|
+
self._non_scannable_extensions: dict[str, tuple[str, ...]] = {
|
|
59
|
+
consts.SECRET_SCAN_TYPE: consts.SECRET_SCAN_FILE_EXTENSIONS_TO_IGNORE,
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
def apply_scan_config(self, scan_type: str, scan_config: 'models.ScanConfiguration') -> None:
|
|
63
|
+
if scan_config.scannable_extensions:
|
|
64
|
+
self._scannable_extensions[scan_type] = tuple(scan_config.scannable_extensions)
|
|
65
|
+
|
|
66
|
+
def _is_file_extension_supported(self, scan_type: str, filename: str) -> bool:
|
|
67
|
+
filename = filename.lower()
|
|
68
|
+
|
|
69
|
+
scannable_extensions = self._scannable_extensions.get(scan_type)
|
|
70
|
+
if scannable_extensions:
|
|
71
|
+
return filename.endswith(scannable_extensions)
|
|
72
|
+
|
|
73
|
+
non_scannable_extensions = self._non_scannable_extensions.get(scan_type)
|
|
74
|
+
if non_scannable_extensions:
|
|
75
|
+
return not filename.endswith(non_scannable_extensions)
|
|
76
|
+
|
|
77
|
+
return True
|
|
78
|
+
|
|
79
|
+
def _is_relevant_file_to_scan_common(self, scan_type: str, filename: str) -> bool:
|
|
80
|
+
if _is_subpath_of_cycode_configuration_folder(filename):
|
|
81
|
+
logger.debug(
|
|
82
|
+
'The document is irrelevant because it is in the Cycode configuration directory, %s',
|
|
83
|
+
{'filename': filename, 'configuration_directory': consts.CYCODE_CONFIGURATION_DIRECTORY},
|
|
84
|
+
)
|
|
85
|
+
return False
|
|
86
|
+
|
|
87
|
+
if _is_path_configured_in_exclusions(scan_type, filename):
|
|
88
|
+
logger.debug(
|
|
89
|
+
'The document is irrelevant because its path is in the ignore paths list, %s', {'filename': filename}
|
|
90
|
+
)
|
|
91
|
+
return False
|
|
92
|
+
|
|
93
|
+
if not self._is_file_extension_supported(scan_type, filename):
|
|
94
|
+
logger.debug(
|
|
95
|
+
'The document is irrelevant because its extension is not supported, %s',
|
|
96
|
+
{'scan_type': scan_type, 'filename': filename},
|
|
97
|
+
)
|
|
98
|
+
return False
|
|
99
|
+
|
|
100
|
+
return True
|
|
101
|
+
|
|
102
|
+
def _is_relevant_file_to_scan(self, scan_type: str, filename: str) -> bool:
|
|
103
|
+
if not self._is_relevant_file_to_scan_common(scan_type, filename):
|
|
104
|
+
return False
|
|
105
|
+
|
|
106
|
+
if is_binary_file(filename):
|
|
107
|
+
logger.debug('The file is irrelevant because it is a binary file, %s', {'filename': filename})
|
|
108
|
+
return False
|
|
109
|
+
|
|
110
|
+
if scan_type != consts.SCA_SCAN_TYPE and _does_file_exceed_max_size_limit(filename):
|
|
111
|
+
logger.debug(
|
|
112
|
+
'The file is irrelevant because it has exceeded the maximum size limit, %s',
|
|
113
|
+
{
|
|
114
|
+
'max_file_size': consts.FILE_MAX_SIZE_LIMIT_IN_BYTES,
|
|
115
|
+
'file_size': get_file_size(filename),
|
|
116
|
+
'filename': filename,
|
|
117
|
+
},
|
|
118
|
+
)
|
|
119
|
+
return False
|
|
120
|
+
|
|
121
|
+
return not (scan_type == consts.SCA_SCAN_TYPE and not _is_file_relevant_for_sca_scan(filename))
|
|
122
|
+
|
|
123
|
+
def _is_relevant_document_to_scan(self, scan_type: str, filename: str, content: str) -> bool:
|
|
124
|
+
if not self._is_relevant_file_to_scan_common(scan_type, filename):
|
|
125
|
+
return False
|
|
126
|
+
|
|
127
|
+
if is_binary_content(content):
|
|
128
|
+
logger.debug('The document is irrelevant because it is a binary file, %s', {'filename': filename})
|
|
129
|
+
return False
|
|
130
|
+
|
|
131
|
+
if scan_type != consts.SCA_SCAN_TYPE and _does_document_exceed_max_size_limit(content):
|
|
132
|
+
logger.debug(
|
|
133
|
+
'The document is irrelevant because it has exceeded the maximum size limit, %s',
|
|
134
|
+
{
|
|
135
|
+
'max_document_size': consts.FILE_MAX_SIZE_LIMIT_IN_BYTES,
|
|
136
|
+
'document_size': get_content_size(content),
|
|
137
|
+
'filename': filename,
|
|
138
|
+
},
|
|
139
|
+
)
|
|
140
|
+
return False
|
|
141
|
+
|
|
142
|
+
return True
|
|
143
|
+
|
|
144
|
+
def exclude_irrelevant_files(
|
|
145
|
+
self,
|
|
146
|
+
progress_bar: 'BaseProgressBar',
|
|
147
|
+
progress_bar_section: 'ProgressBarSection',
|
|
148
|
+
scan_type: str,
|
|
149
|
+
filenames: list[str],
|
|
150
|
+
) -> list[str]:
|
|
151
|
+
relevant_files = []
|
|
152
|
+
for filename in filenames:
|
|
153
|
+
progress_bar.update(progress_bar_section)
|
|
154
|
+
if self._is_relevant_file_to_scan(scan_type, filename):
|
|
155
|
+
relevant_files.append(filename)
|
|
156
|
+
|
|
157
|
+
is_sub_path.cache_clear() # free up memory
|
|
158
|
+
|
|
159
|
+
return relevant_files
|
|
160
|
+
|
|
161
|
+
def exclude_irrelevant_documents_to_scan(
|
|
162
|
+
self, scan_type: str, documents_to_scan: list['Document']
|
|
163
|
+
) -> list['Document']:
|
|
164
|
+
logger.debug('Excluding irrelevant documents to scan')
|
|
165
|
+
|
|
166
|
+
relevant_documents = []
|
|
167
|
+
for document in documents_to_scan:
|
|
168
|
+
if self._is_relevant_document_to_scan(scan_type, document.path, document.content):
|
|
169
|
+
relevant_documents.append(document)
|
|
170
|
+
|
|
171
|
+
return relevant_documents
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
excluder = Excluder()
|
|
@@ -1,25 +1,28 @@
|
|
|
1
|
+
from collections import defaultdict
|
|
1
2
|
from io import BytesIO
|
|
3
|
+
from pathlib import Path
|
|
2
4
|
from sys import getsizeof
|
|
3
|
-
from typing import
|
|
5
|
+
from typing import Optional
|
|
4
6
|
from zipfile import ZIP_DEFLATED, ZipFile
|
|
5
7
|
|
|
6
8
|
from cycode.cli.user_settings.configuration_manager import ConfigurationManager
|
|
7
9
|
from cycode.cli.utils.path_utils import concat_unique_id
|
|
8
10
|
|
|
9
|
-
if TYPE_CHECKING:
|
|
10
|
-
from pathlib import Path
|
|
11
|
-
|
|
12
11
|
|
|
13
12
|
class InMemoryZip:
|
|
14
13
|
def __init__(self) -> None:
|
|
15
14
|
self.configuration_manager = ConfigurationManager()
|
|
16
15
|
|
|
17
|
-
# Create the in-memory file-like object
|
|
18
16
|
self.in_memory_zip = BytesIO()
|
|
19
|
-
self.zip = ZipFile(self.in_memory_zip, 'a', ZIP_DEFLATED, False)
|
|
17
|
+
self.zip = ZipFile(self.in_memory_zip, mode='a', compression=ZIP_DEFLATED, allowZip64=False)
|
|
18
|
+
|
|
19
|
+
self._files_count = 0
|
|
20
|
+
self._extension_statistics = defaultdict(int)
|
|
20
21
|
|
|
21
22
|
def append(self, filename: str, unique_id: Optional[str], content: str) -> None:
|
|
22
|
-
|
|
23
|
+
self._files_count += 1
|
|
24
|
+
self._extension_statistics[Path(filename).suffix] += 1
|
|
25
|
+
|
|
23
26
|
if unique_id:
|
|
24
27
|
filename = concat_unique_id(filename, unique_id)
|
|
25
28
|
|
|
@@ -28,7 +31,6 @@ class InMemoryZip:
|
|
|
28
31
|
def close(self) -> None:
|
|
29
32
|
self.zip.close()
|
|
30
33
|
|
|
31
|
-
# to bytes
|
|
32
34
|
def read(self) -> bytes:
|
|
33
35
|
self.in_memory_zip.seek(0)
|
|
34
36
|
return self.in_memory_zip.read()
|
|
@@ -40,3 +42,11 @@ class InMemoryZip:
|
|
|
40
42
|
@property
|
|
41
43
|
def size(self) -> int:
|
|
42
44
|
return getsizeof(self.in_memory_zip)
|
|
45
|
+
|
|
46
|
+
@property
|
|
47
|
+
def files_count(self) -> int:
|
|
48
|
+
return self._files_count
|
|
49
|
+
|
|
50
|
+
@property
|
|
51
|
+
def extension_statistics(self) -> dict[str, int]:
|
|
52
|
+
return dict(self._extension_statistics)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import os
|
|
2
2
|
from typing import TYPE_CHECKING
|
|
3
3
|
|
|
4
|
-
from cycode.cli.files_collector.excluder import
|
|
4
|
+
from cycode.cli.files_collector.excluder import excluder
|
|
5
5
|
from cycode.cli.files_collector.iac.tf_content_generator import (
|
|
6
6
|
generate_tf_content_from_tfplan,
|
|
7
7
|
generate_tfplan_document_name,
|
|
@@ -54,7 +54,9 @@ def _get_relevant_files(
|
|
|
54
54
|
progress_bar_section_len = len(all_files_to_scan) * 2
|
|
55
55
|
progress_bar.set_section_length(progress_bar_section, progress_bar_section_len)
|
|
56
56
|
|
|
57
|
-
relevant_files_to_scan = exclude_irrelevant_files(
|
|
57
|
+
relevant_files_to_scan = excluder.exclude_irrelevant_files(
|
|
58
|
+
progress_bar, progress_bar_section, scan_type, all_files_to_scan
|
|
59
|
+
)
|
|
58
60
|
|
|
59
61
|
# after finishing the first processing (excluding),
|
|
60
62
|
# we must update the progress bar stage with respect of excluded files.
|
{cycode-3.0.1.dev1 → cycode-3.0.2.dev2}/cycode/cli/files_collector/sca/base_restore_dependencies.py
RENAMED
|
@@ -59,14 +59,13 @@ class BaseRestoreDependencies(ABC):
|
|
|
59
59
|
manifest_file_path = self.get_manifest_file_path(document)
|
|
60
60
|
restore_file_path = build_dep_tree_path(document.absolute_path, self.get_lock_file_name())
|
|
61
61
|
relative_restore_file_path = build_dep_tree_path(document.path, self.get_lock_file_name())
|
|
62
|
-
working_directory_path = self.get_working_directory(document)
|
|
63
62
|
|
|
64
63
|
if not self.verify_restore_file_already_exist(restore_file_path):
|
|
65
64
|
output = execute_commands(
|
|
66
|
-
self.get_commands(manifest_file_path),
|
|
67
|
-
self.command_timeout,
|
|
65
|
+
commands=self.get_commands(manifest_file_path),
|
|
66
|
+
timeout=self.command_timeout,
|
|
68
67
|
output_file_path=restore_file_path if self.create_output_file_manually else None,
|
|
69
|
-
working_directory=
|
|
68
|
+
working_directory=self.get_working_directory(document),
|
|
70
69
|
)
|
|
71
70
|
if output is None: # one of the commands failed
|
|
72
71
|
return None
|
|
@@ -75,7 +74,7 @@ class BaseRestoreDependencies(ABC):
|
|
|
75
74
|
return Document(relative_restore_file_path, restore_file_content, self.is_git_diff)
|
|
76
75
|
|
|
77
76
|
def get_working_directory(self, document: Document) -> Optional[str]:
|
|
78
|
-
return
|
|
77
|
+
return os.path.dirname(document.absolute_path)
|
|
79
78
|
|
|
80
79
|
@staticmethod
|
|
81
80
|
def verify_restore_file_already_exist(restore_file_path: str) -> bool:
|
|
@@ -30,34 +30,36 @@ class RestoreMavenDependencies(BaseRestoreDependencies):
|
|
|
30
30
|
return join_paths('target', MAVEN_CYCLONE_DEP_TREE_FILE_NAME)
|
|
31
31
|
|
|
32
32
|
def try_restore_dependencies(self, document: Document) -> Optional[Document]:
|
|
33
|
-
restore_dependencies_document = super().try_restore_dependencies(document)
|
|
34
33
|
manifest_file_path = self.get_manifest_file_path(document)
|
|
35
34
|
if document.content is None:
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
35
|
+
return self.restore_from_secondary_command(document, manifest_file_path)
|
|
36
|
+
|
|
37
|
+
restore_dependencies_document = super().try_restore_dependencies(document)
|
|
38
|
+
if restore_dependencies_document is None:
|
|
39
|
+
return None
|
|
40
|
+
|
|
41
|
+
restore_dependencies_document.content = get_file_content(
|
|
42
|
+
join_paths(get_file_dir(manifest_file_path), self.get_lock_file_name())
|
|
43
|
+
)
|
|
43
44
|
|
|
44
45
|
return restore_dependencies_document
|
|
45
46
|
|
|
46
|
-
def restore_from_secondary_command(
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
backup_restore_content = execute_commands(secondary_restore_command, self.command_timeout)
|
|
52
|
-
restore_dependencies_document = Document(
|
|
53
|
-
build_dep_tree_path(document.path, MAVEN_DEP_TREE_FILE_NAME), backup_restore_content, self.is_git_diff
|
|
47
|
+
def restore_from_secondary_command(self, document: Document, manifest_file_path: str) -> Optional[Document]:
|
|
48
|
+
restore_content = execute_commands(
|
|
49
|
+
commands=create_secondary_restore_commands(manifest_file_path),
|
|
50
|
+
timeout=self.command_timeout,
|
|
51
|
+
working_directory=self.get_working_directory(document),
|
|
54
52
|
)
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
restore_dependencies = restore_dependencies_document
|
|
58
|
-
restore_dependencies.content = get_file_content(MAVEN_DEP_TREE_FILE_NAME)
|
|
53
|
+
if restore_content is None:
|
|
54
|
+
return None
|
|
59
55
|
|
|
60
|
-
|
|
56
|
+
restore_file_path = build_dep_tree_path(document.absolute_path, MAVEN_DEP_TREE_FILE_NAME)
|
|
57
|
+
return Document(
|
|
58
|
+
path=build_dep_tree_path(document.path, MAVEN_DEP_TREE_FILE_NAME),
|
|
59
|
+
content=get_file_content(restore_file_path),
|
|
60
|
+
is_git_diff_format=self.is_git_diff,
|
|
61
|
+
absolute_path=restore_file_path,
|
|
62
|
+
)
|
|
61
63
|
|
|
62
64
|
|
|
63
65
|
def create_secondary_restore_commands(manifest_file_path: str) -> list[list[str]]:
|
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
import os
|
|
2
|
-
from typing import Optional
|
|
3
|
-
|
|
4
1
|
from cycode.cli.files_collector.sca.base_restore_dependencies import BaseRestoreDependencies
|
|
5
2
|
from cycode.cli.models import Document
|
|
6
3
|
|
|
@@ -17,6 +14,3 @@ class RestoreRubyDependencies(BaseRestoreDependencies):
|
|
|
17
14
|
|
|
18
15
|
def get_lock_file_name(self) -> str:
|
|
19
16
|
return RUBY_LOCK_FILE_NAME
|
|
20
|
-
|
|
21
|
-
def get_working_directory(self, document: Document) -> Optional[str]:
|
|
22
|
-
return os.path.dirname(document.absolute_path)
|
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
import os
|
|
2
|
-
from typing import Optional
|
|
3
|
-
|
|
4
1
|
from cycode.cli.files_collector.sca.base_restore_dependencies import BaseRestoreDependencies
|
|
5
2
|
from cycode.cli.models import Document
|
|
6
3
|
|
|
@@ -17,6 +14,3 @@ class RestoreSbtDependencies(BaseRestoreDependencies):
|
|
|
17
14
|
|
|
18
15
|
def get_lock_file_name(self) -> str:
|
|
19
16
|
return SBT_LOCK_FILE_NAME
|
|
20
|
-
|
|
21
|
-
def get_working_directory(self, document: Document) -> Optional[str]:
|
|
22
|
-
return os.path.dirname(document.absolute_path)
|
|
@@ -92,17 +92,16 @@ def get_project_file_ecosystem(document: Document) -> Optional[str]:
|
|
|
92
92
|
|
|
93
93
|
def try_restore_dependencies(
|
|
94
94
|
ctx: typer.Context,
|
|
95
|
-
documents_to_add: dict[str, Document],
|
|
96
95
|
restore_dependencies: 'BaseRestoreDependencies',
|
|
97
96
|
document: Document,
|
|
98
|
-
) ->
|
|
97
|
+
) -> Optional[Document]:
|
|
99
98
|
if not restore_dependencies.is_project(document):
|
|
100
|
-
return
|
|
99
|
+
return None
|
|
101
100
|
|
|
102
101
|
restore_dependencies_document = restore_dependencies.restore(document)
|
|
103
102
|
if restore_dependencies_document is None:
|
|
104
103
|
logger.warning('Error occurred while trying to generate dependencies tree, %s', {'filename': document.path})
|
|
105
|
-
return
|
|
104
|
+
return None
|
|
106
105
|
|
|
107
106
|
if restore_dependencies_document.content is None:
|
|
108
107
|
logger.warning('Error occurred while trying to generate dependencies tree, %s', {'filename': document.path})
|
|
@@ -114,10 +113,7 @@ def try_restore_dependencies(
|
|
|
114
113
|
manifest_file_path = get_manifest_file_path(document, is_monitor_action, project_path)
|
|
115
114
|
logger.debug('Succeeded to generate dependencies tree on path: %s', manifest_file_path)
|
|
116
115
|
|
|
117
|
-
|
|
118
|
-
logger.debug('Duplicate document on restore for path: %s', restore_dependencies_document.path)
|
|
119
|
-
else:
|
|
120
|
-
documents_to_add[restore_dependencies_document.path] = restore_dependencies_document
|
|
116
|
+
return restore_dependencies_document
|
|
121
117
|
|
|
122
118
|
|
|
123
119
|
def add_dependencies_tree_document(
|
|
@@ -128,7 +124,14 @@ def add_dependencies_tree_document(
|
|
|
128
124
|
|
|
129
125
|
for restore_dependencies in restore_dependencies_list:
|
|
130
126
|
for document in documents_to_scan:
|
|
131
|
-
try_restore_dependencies(ctx,
|
|
127
|
+
restore_dependencies_document = try_restore_dependencies(ctx, restore_dependencies, document)
|
|
128
|
+
if restore_dependencies_document is None:
|
|
129
|
+
continue
|
|
130
|
+
|
|
131
|
+
if restore_dependencies_document.path in documents_to_add:
|
|
132
|
+
logger.debug('Duplicate document on restore for path: %s', restore_dependencies_document.path)
|
|
133
|
+
else:
|
|
134
|
+
documents_to_add[restore_dependencies_document.path] = restore_dependencies_document
|
|
132
135
|
|
|
133
136
|
# mutate original list using slice assignment
|
|
134
137
|
documents_to_scan[:] = list(documents_to_add.values())
|
|
@@ -500,3 +500,19 @@ class SupportedModulesPreferencesSchema(Schema):
|
|
|
500
500
|
@post_load
|
|
501
501
|
def build_dto(self, data: dict[str, Any], **_) -> 'SupportedModulesPreferences':
|
|
502
502
|
return SupportedModulesPreferences(**data)
|
|
503
|
+
|
|
504
|
+
|
|
505
|
+
@dataclass
|
|
506
|
+
class ScanConfiguration:
|
|
507
|
+
scannable_extensions: list[str]
|
|
508
|
+
|
|
509
|
+
|
|
510
|
+
class ScanConfigurationSchema(Schema):
|
|
511
|
+
class Meta:
|
|
512
|
+
unknown = EXCLUDE
|
|
513
|
+
|
|
514
|
+
scannable_extensions = fields.List(fields.String(), allow_none=True)
|
|
515
|
+
|
|
516
|
+
@post_load
|
|
517
|
+
def build_dto(self, data: dict[str, Any], **_) -> 'ScanConfiguration':
|
|
518
|
+
return ScanConfiguration(**data)
|
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
import json
|
|
2
2
|
from copy import deepcopy
|
|
3
|
-
from typing import TYPE_CHECKING, Union
|
|
3
|
+
from typing import TYPE_CHECKING, Optional, Union
|
|
4
4
|
from uuid import UUID
|
|
5
5
|
|
|
6
6
|
from requests import Response
|
|
7
7
|
|
|
8
8
|
from cycode.cli import consts
|
|
9
9
|
from cycode.cli.config import configuration_manager
|
|
10
|
-
from cycode.cli.exceptions.custom_exceptions import CycodeError
|
|
10
|
+
from cycode.cli.exceptions.custom_exceptions import CycodeError, RequestHttpError
|
|
11
11
|
from cycode.cli.files_collector.models.in_memory_zip import InMemoryZip
|
|
12
12
|
from cycode.cyclient import models
|
|
13
13
|
from cycode.cyclient.cycode_client_base import CycodeClientBase
|
|
14
|
+
from cycode.cyclient.logger import logger
|
|
14
15
|
|
|
15
16
|
if TYPE_CHECKING:
|
|
16
17
|
from cycode.cyclient.scan_config_base import ScanConfigBase
|
|
@@ -100,12 +101,19 @@ class ScanClient:
|
|
|
100
101
|
is_commit_range: bool = False,
|
|
101
102
|
) -> models.ScanInitializationResponse:
|
|
102
103
|
files = {'file': ('multiple_files_scan.zip', zip_file.read())}
|
|
104
|
+
|
|
105
|
+
compression_manifest = {
|
|
106
|
+
'file_count_by_extension': zip_file.extension_statistics,
|
|
107
|
+
'file_count': zip_file.files_count,
|
|
108
|
+
}
|
|
109
|
+
|
|
103
110
|
response = self.scan_cycode_client.post(
|
|
104
111
|
url_path=self.get_zipped_file_scan_async_url_path(scan_type),
|
|
105
112
|
data={
|
|
106
113
|
'is_git_diff': is_git_diff,
|
|
107
114
|
'scan_parameters': json.dumps(scan_parameters),
|
|
108
115
|
'is_commit_range': is_commit_range,
|
|
116
|
+
'compression_manifest': json.dumps(compression_manifest),
|
|
109
117
|
},
|
|
110
118
|
files=files,
|
|
111
119
|
)
|
|
@@ -245,3 +253,25 @@ class ScanClient:
|
|
|
245
253
|
@staticmethod
|
|
246
254
|
def parse_scan_response(response: Response) -> models.ScanResult:
|
|
247
255
|
return models.ScanResultSchema().load(response.json())
|
|
256
|
+
|
|
257
|
+
def get_scan_configuration_path(self, scan_type: str) -> str:
|
|
258
|
+
correct_scan_type = self.scan_config.get_async_scan_type(scan_type)
|
|
259
|
+
return f'{self.get_scan_service_url_path(scan_type)}/{correct_scan_type}/configuration'
|
|
260
|
+
|
|
261
|
+
def get_scan_configuration(self, scan_type: str) -> models.ScanConfiguration:
|
|
262
|
+
response = self.scan_cycode_client.get(
|
|
263
|
+
url_path=self.get_scan_configuration_path(scan_type),
|
|
264
|
+
hide_response_content_log=self._hide_response_log,
|
|
265
|
+
)
|
|
266
|
+
return models.ScanConfigurationSchema().load(response.json())
|
|
267
|
+
|
|
268
|
+
def get_scan_configuration_safe(self, scan_type: str) -> Optional['models.ScanConfiguration']:
|
|
269
|
+
try:
|
|
270
|
+
return self.get_scan_configuration(scan_type)
|
|
271
|
+
except RequestHttpError as e:
|
|
272
|
+
if e.status_code == 404:
|
|
273
|
+
logger.debug(
|
|
274
|
+
'Remote scan configuration is not supported for this scan type: %s', {'scan_type': scan_type}
|
|
275
|
+
)
|
|
276
|
+
else:
|
|
277
|
+
logger.debug('Failed to get remote scan configuration: %s', {'scan_type': scan_type}, exc_info=e)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "cycode"
|
|
3
|
-
version = "3.0.
|
|
3
|
+
version = "3.0.2.dev2" # 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__ = '3.0.1.dev1' # DON'T TOUCH. Placeholder. Will be filled automatically on poetry build from Git Tag
|