Skip to content

Commit d778209

Browse files
authored
CM-62406: handle more pre-push types gracefully (#433)
1 parent c404e4c commit d778209

File tree

3 files changed

+44
-37
lines changed

3 files changed

+44
-37
lines changed

cycode/cli/apps/scan/pre_push/pre_push_command.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,10 @@ def pre_push_command(
4444
timeout = configuration_manager.get_pre_push_command_timeout(command_scan_type)
4545
with TimeoutAfter(timeout):
4646
push_update_details = parse_pre_push_input()
47+
if not push_update_details:
48+
logger.info('No pre-push input found, nothing to scan')
49+
return
50+
4751
commit_range = calculate_pre_push_commit_range(push_update_details)
4852
if not commit_range:
4953
logger.info(

cycode/cli/files_collector/commit_range_documents.py

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ def parse_pre_receive_input() -> str:
228228
return pre_receive_input.splitlines()[0]
229229

230230

231-
def parse_pre_push_input() -> str:
231+
def parse_pre_push_input() -> Optional[str]:
232232
"""Parse input to pre-push hook details.
233233
234234
Example input:
@@ -237,13 +237,11 @@ def parse_pre_push_input() -> str:
237237
refs/heads/main 9cf90954ef26e7c58284f8ebf7dcd0fcf711152a refs/heads/main 973a96d3e925b65941f7c47fa16129f1577d499f
238238
refs/heads/feature-branch 3378e52dcfa47fb11ce3a4a520bea5f85d5d0bf3 refs/heads/feature-branch 59564ef68745bca38c42fc57a7822efd519a6bd9
239239
240-
:return: First, push update details (input's first line)
240+
:return: First push update details (input's first line), or None if no input was provided
241241
""" # noqa: E501
242242
pre_push_input = _read_hook_input_from_stdin()
243243
if not pre_push_input:
244-
raise ValueError(
245-
'Pre push input was not found. Make sure that you are using this command only in pre-push hook'
246-
)
244+
return None
247245

248246
# each line represents a branch push request, handle the first one only
249247
return pre_push_input.splitlines()[0]
@@ -332,6 +330,15 @@ def calculate_pre_push_commit_range(push_update_details: str) -> Optional[str]:
332330
"""
333331
local_ref, local_object_name, remote_ref, remote_object_name = push_update_details.split()
334332

333+
# Tag pushes don't contain file diffs that need scanning
334+
if local_ref.startswith('refs/tags/') or remote_ref.startswith('refs/tags/'):
335+
logger.info('Skipping scan for tag push: %s -> %s', local_ref, remote_ref)
336+
return None
337+
338+
# If deleting a ref (local_object_name is all zeros), no need to scan
339+
if local_object_name == consts.EMPTY_COMMIT_SHA:
340+
return None
341+
335342
if remote_object_name == consts.EMPTY_COMMIT_SHA:
336343
try:
337344
repo = git_proxy.get_repo(os.getcwd())
@@ -356,10 +363,6 @@ def calculate_pre_push_commit_range(push_update_details: str) -> Optional[str]:
356363
logger.debug('Failed to get repo for pre-push commit range calculation: %s', exc_info=e)
357364
return consts.COMMIT_RANGE_ALL_COMMITS
358365

359-
# If deleting a branch (local_object_name is all zeros), no need to scan
360-
if local_object_name == consts.EMPTY_COMMIT_SHA:
361-
return None
362-
363366
# For updates to existing branches, scan from remote to local
364367
return f'{remote_object_name}..{local_object_name}'
365368

tests/cli/files_collector/test_commit_range_documents.py

Lines changed: 28 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -392,15 +392,15 @@ def test_parse_branch_deletion_input(self) -> None:
392392
result = parse_pre_push_input()
393393
assert result == pre_push_input
394394

395-
def test_parse_empty_input_raises_error(self) -> None:
396-
"""Test that empty input raises ValueError."""
397-
with patch('sys.stdin', StringIO('')), pytest.raises(ValueError, match='Pre push input was not found'):
398-
parse_pre_push_input()
395+
def test_parse_empty_input_returns_none(self) -> None:
396+
"""Test that empty input returns None instead of raising."""
397+
with patch('sys.stdin', StringIO('')):
398+
assert parse_pre_push_input() is None
399399

400-
def test_parse_whitespace_only_input_raises_error(self) -> None:
401-
"""Test that whitespace-only input raises ValueError."""
402-
with patch('sys.stdin', StringIO(' \n\t ')), pytest.raises(ValueError, match='Pre push input was not found'):
403-
parse_pre_push_input()
400+
def test_parse_whitespace_only_input_returns_none(self) -> None:
401+
"""Test that whitespace-only input returns None instead of raising."""
402+
with patch('sys.stdin', StringIO(' \n\t ')):
403+
assert parse_pre_push_input() is None
404404

405405

406406
class TestGetDefaultBranchesForMergeBase:
@@ -758,26 +758,23 @@ def test_calculate_range_parsing_push_details(self) -> None:
758758
result = calculate_pre_push_commit_range(push_details)
759759
assert result == '789xyz456abc..abc123def456'
760760

761-
def test_calculate_range_with_tags(self) -> None:
762-
"""Test calculating commit range when pushing tags."""
761+
def test_calculate_range_with_new_tag_push_returns_none(self) -> None:
762+
"""Test that pushing a new tag returns None (no scanning needed)."""
763763
push_details = f'refs/tags/v1.0.0 1234567890abcdef refs/tags/v1.0.0 {consts.EMPTY_COMMIT_SHA}'
764+
result = calculate_pre_push_commit_range(push_details)
765+
assert result is None
764766

765-
with temporary_git_repository() as (temp_dir, repo):
766-
# Create a commit
767-
test_file = os.path.join(temp_dir, 'test.py')
768-
with open(test_file, 'w') as f:
769-
f.write("print('test')")
770-
771-
repo.index.add(['test.py'])
772-
commit = repo.index.commit('Test commit')
773-
774-
# Create tag
775-
repo.create_tag('v1.0.0', commit)
767+
def test_calculate_range_with_tag_deletion_returns_none(self) -> None:
768+
"""Test that deleting a tag returns None (no scanning needed)."""
769+
push_details = f'refs/tags/v1.0.0 {consts.EMPTY_COMMIT_SHA} refs/tags/v1.0.0 1234567890abcdef'
770+
result = calculate_pre_push_commit_range(push_details)
771+
assert result is None
776772

777-
with patch('os.getcwd', return_value=temp_dir):
778-
result = calculate_pre_push_commit_range(push_details)
779-
# For new tags, should try to find a merge base or fall back to --all
780-
assert result in [f'{commit.hexsha}..{commit.hexsha}', '--all']
773+
def test_calculate_range_with_tag_update_returns_none(self) -> None:
774+
"""Test that updating a tag returns None (no scanning needed)."""
775+
push_details = 'refs/tags/v1.0.0 1234567890abcdef refs/tags/v1.0.0 0987654321fedcba'
776+
result = calculate_pre_push_commit_range(push_details)
777+
assert result is None
781778

782779

783780
class TestPrePushHookIntegration:
@@ -805,12 +802,15 @@ def test_simulate_pre_push_hook_input_format(self) -> None:
805802
# Test that we can calculate the commit range for each case
806803
commit_range = calculate_pre_push_commit_range(parsed)
807804

808-
if consts.EMPTY_COMMIT_SHA in push_input:
809-
if push_input.startswith('refs/heads/') and push_input.split()[1] == consts.EMPTY_COMMIT_SHA:
805+
if push_input.startswith('refs/tags/'):
806+
# Tag pushes - should return None (no scanning needed)
807+
assert commit_range is None
808+
elif consts.EMPTY_COMMIT_SHA in push_input:
809+
if push_input.split()[1] == consts.EMPTY_COMMIT_SHA:
810810
# Branch deletion - should return None
811811
assert commit_range is None
812812
else:
813-
# New branch/tag - should return a range or --all
813+
# New branch - should return a range or --all
814814
assert commit_range is not None
815815
else:
816816
# Regular update - should return proper range

0 commit comments

Comments
 (0)