Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions coveralls/git.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,9 +97,10 @@ def git_info() -> dict[str, dict[str, Any]]:
'message': gitlog('%s'),
}
remotes = [
{'name': line.split()[0], 'url': line.split()[1]}
{'name': parts[0], 'url': parts[1]}
for line in run_command('git', 'remote', '-v').splitlines()
if '(fetch)' in line
if '(fetch)' in line and len(line.split()) >= 2
for parts in [line.split()]
]
except (CoverallsException, OSError) as ex:
# When git is not available, try env vars as per Coveralls docs:
Expand Down
47 changes: 47 additions & 0 deletions tests/test_git_malformed_remote.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
"""Tests for handling malformed git remote output."""
import os
import unittest.mock
from coveralls.git import git_info


class MalformedRemoteTest(unittest.TestCase):
@unittest.mock.patch('coveralls.git.run_command')
@unittest.mock.patch.dict(
os.environ,
{'GITHUB_ACTIONS': 'true', 'GITHUB_REF': 'refs/heads/main'},
clear=True,
)
def test_git_info_handles_malformed_remote_fetch_line(self, mock_run_command):
"""
Regression test: git remote -v can output malformed lines containing
'(fetch)' that have fewer than 2 space-separated tokens. The parser
must skip these gracefully instead of raising an IndexError.
"""
def run_side_effect(*args):
if args == ('git', 'remote', '-v'):
# Simulate a malformed remote line followed by a valid one
return '(fetch)\norigin https://github.com/user/repo.git (fetch)\n'
if args == ('git', '--no-pager', 'log', '-1', '--pretty=format:%H'):
return 'abc123'
if args == ('git', '--no-pager', 'log', '-1', '--pretty=format:%aN'):
return 'Test Author'
if args == ('git', '--no-pager', 'log', '-1', '--pretty=format:%ae'):
return 'test@example.com'
if args == ('git', '--no-pager', 'log', '-1', '--pretty=format:%cN'):
return 'Test Committer'
if args == ('git', '--no-pager', 'log', '-1', '--pretty=format:%ce'):
return 'committer@example.com'
if args == ('git', '--no-pager', 'log', '-1', '--pretty=format:%s'):
return 'test commit'
raise AssertionError(f'Unexpected git command: {args}')

mock_run_command.side_effect = run_side_effect

# This should NOT raise an IndexError
result = git_info()

# The malformed line should be skipped; only the valid remote should appear
assert result['git']['remotes'] == [{
'name': 'origin',
'url': 'https://github.com/user/repo.git',
}]