Skip to content

Commit 0947a93

Browse files
CM-55749-Add scan entrypoint marker file (#372)
1 parent b3f7f9d commit 0947a93

File tree

3 files changed

+64
-0
lines changed

3 files changed

+64
-0
lines changed

cycode/cli/apps/scan/code_scanner.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import os
12
import time
23
from platform import platform
34
from typing import TYPE_CHECKING, Callable, Optional
@@ -21,6 +22,7 @@
2122
from cycode.cli.files_collector.sca.sca_file_collector import add_sca_dependencies_tree_documents_if_needed
2223
from cycode.cli.files_collector.zip_documents import zip_documents
2324
from cycode.cli.models import CliError, Document, LocalScanResult
25+
from cycode.cli.utils.path_utils import get_absolute_path, get_path_by_os
2426
from cycode.cli.utils.progress_bar import ScanProgressBarSection
2527
from cycode.cli.utils.scan_batch import run_parallel_batched_scan
2628
from cycode.cli.utils.scan_utils import (
@@ -53,6 +55,20 @@ def scan_disk_files(ctx: typer.Context, paths: tuple[str, ...]) -> None:
5355
paths,
5456
is_cycodeignore_allowed=is_cycodeignore_allowed_by_scan_config(ctx),
5557
)
58+
59+
# Add entrypoint.cycode file at root path to mark the scan root (only for single path)
60+
if len(paths) == 1:
61+
root_path = paths[0]
62+
absolute_root_path = get_absolute_path(root_path)
63+
entrypoint_path = get_path_by_os(os.path.join(absolute_root_path, consts.CYCODE_ENTRYPOINT_FILENAME))
64+
entrypoint_document = Document(
65+
entrypoint_path,
66+
'', # Empty file content
67+
is_git_diff_format=False,
68+
absolute_path=entrypoint_path,
69+
)
70+
documents.append(entrypoint_document)
71+
5672
add_sca_dependencies_tree_documents_if_needed(ctx, scan_type, documents)
5773
scan_documents(ctx, documents, get_scan_parameters(ctx, paths))
5874
except Exception as e:

cycode/cli/consts.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
IAC_SCAN_SUPPORTED_FILE_PREFIXES = ('dockerfile', 'containerfile')
1919

2020
CYCODEIGNORE_FILENAME = '.cycodeignore'
21+
CYCODE_ENTRYPOINT_FILENAME = 'entrypoint.cycode'
2122

2223
SECRET_SCAN_FILE_EXTENSIONS_TO_IGNORE = (
2324
'.DS_Store',

tests/cli/commands/scan/test_code_scanner.py

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
import os
2+
from os.path import normpath
3+
from unittest.mock import MagicMock, Mock, patch
24

35
from cycode.cli import consts
6+
from cycode.cli.apps.scan.code_scanner import scan_disk_files
47
from cycode.cli.files_collector.file_excluder import _is_file_relevant_for_sca_scan
58
from cycode.cli.files_collector.path_documents import _generate_document
69
from cycode.cli.models import Document
@@ -72,3 +75,47 @@ def test_generate_document() -> None:
7275
assert isinstance(generated_tfplan_document, Document)
7376
assert generated_tfplan_document.path.endswith('.tf')
7477
assert generated_tfplan_document.is_git_diff_format == is_git_diff
78+
79+
80+
@patch('cycode.cli.apps.scan.code_scanner.get_relevant_documents')
81+
@patch('cycode.cli.apps.scan.code_scanner.scan_documents')
82+
@patch('cycode.cli.apps.scan.code_scanner.get_scan_parameters')
83+
def test_entrypoint_cycode_added_to_documents(
84+
mock_get_scan_parameters: Mock,
85+
mock_scan_documents: Mock,
86+
mock_get_relevant_documents: Mock,
87+
) -> None:
88+
"""Test that entrypoint.cycode file is added to documents in scan_disk_files."""
89+
# Arrange
90+
mock_ctx = MagicMock()
91+
mock_ctx.obj = {
92+
'scan_type': consts.SAST_SCAN_TYPE,
93+
'progress_bar': MagicMock(),
94+
}
95+
mock_get_scan_parameters.return_value = {}
96+
97+
mock_documents = [
98+
Document('/test/path/file1.py', 'content1', is_git_diff_format=False),
99+
Document('/test/path/file2.js', 'content2', is_git_diff_format=False),
100+
]
101+
mock_get_relevant_documents.return_value = mock_documents.copy()
102+
test_path = '/Users/test/repositories'
103+
104+
# Act
105+
scan_disk_files(mock_ctx, (test_path,))
106+
107+
# Assert
108+
call_args = mock_scan_documents.call_args
109+
documents_passed = call_args[0][1]
110+
111+
# Verify entrypoint document was added
112+
entrypoint_docs = [doc for doc in documents_passed if doc.path.endswith(consts.CYCODE_ENTRYPOINT_FILENAME)]
113+
assert len(entrypoint_docs) == 1
114+
115+
entrypoint_doc = entrypoint_docs[0]
116+
# Normalize paths for cross-platform compatibility
117+
expected_path = normpath(os.path.join(os.path.abspath(test_path), consts.CYCODE_ENTRYPOINT_FILENAME))
118+
assert normpath(entrypoint_doc.path) == expected_path
119+
assert entrypoint_doc.content == ''
120+
assert entrypoint_doc.is_git_diff_format is False
121+
assert normpath(entrypoint_doc.absolute_path) == normpath(entrypoint_doc.path)

0 commit comments

Comments
 (0)