Skip to content
This repository was archived by the owner on Jul 16, 2025. It is now read-only.
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
9 changes: 8 additions & 1 deletion codecov_cli/commands/create_report_result.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,5 +37,12 @@ def create_report_results(
),
)
create_report_results_logic(
commit_sha, code, slug, git_service, token, enterprise_url, fail_on_error, args
commit_sha,
code,
slug,
git_service,
token,
enterprise_url,
fail_on_error,
args,
)
9 changes: 8 additions & 1 deletion codecov_cli/commands/empty_upload.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,5 +76,12 @@ def empty_upload(
),
)
return empty_upload_logic(
commit_sha, slug, token, git_service, enterprise_url, fail_on_error, force, args
commit_sha,
slug,
token,
git_service,
enterprise_url,
fail_on_error,
force,
args,
)
111 changes: 57 additions & 54 deletions codecov_cli/helpers/glob.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,44 +31,46 @@ def translate(pat, *, recursive=False, include_hidden=False, seps=None):
seps = (os.path.sep, os.path.altsep)
else:
seps = os.path.sep
escaped_seps = ''.join(map(re.escape, seps))
any_sep = f'[{escaped_seps}]' if len(seps) > 1 else escaped_seps
not_sep = f'[^{escaped_seps}]'
escaped_seps = "".join(map(re.escape, seps))
any_sep = f"[{escaped_seps}]" if len(seps) > 1 else escaped_seps
not_sep = f"[^{escaped_seps}]"
if include_hidden:
one_last_segment = f'{not_sep}+'
one_segment = f'{one_last_segment}{any_sep}'
any_segments = f'(?:.+{any_sep})?'
any_last_segments = '.*'
one_last_segment = f"{not_sep}+"
one_segment = f"{one_last_segment}{any_sep}"
any_segments = f"(?:.+{any_sep})?"
any_last_segments = ".*"
else:
one_last_segment = f'[^{escaped_seps}.]{not_sep}*'
one_segment = f'{one_last_segment}{any_sep}'
any_segments = f'(?:{one_segment})*'
any_last_segments = f'{any_segments}(?:{one_last_segment})?'
one_last_segment = f"[^{escaped_seps}.]{not_sep}*"
one_segment = f"{one_last_segment}{any_sep}"
any_segments = f"(?:{one_segment})*"
any_last_segments = f"{any_segments}(?:{one_last_segment})?"

results = []
parts = re.split(any_sep, pat)
last_part_idx = len(parts) - 1
for idx, part in enumerate(parts):
if part == '*':
if part == "*":
results.append(one_segment if idx < last_part_idx else one_last_segment)
elif recursive and part == '**':
elif recursive and part == "**":
if idx < last_part_idx:
if parts[idx + 1] != '**':
if parts[idx + 1] != "**":
results.append(any_segments)
else:
results.append(any_last_segments)
else:
if part:
if not include_hidden and part[0] in '*?':
results.append(r'(?!\.)')
results.extend(_translate(part, f'{not_sep}*', not_sep)[0])
if not include_hidden and part[0] in "*?":
results.append(r"(?!\.)")
results.extend(_translate(part, f"{not_sep}*", not_sep)[0])
if idx < last_part_idx:
results.append(any_sep)
res = ''.join(results)
return fr'(?s:{res})\Z'
res = "".join(results)
return rf"(?s:{res})\Z"


_re_setops_sub = re.compile(r"([&~|])").sub


_re_setops_sub = re.compile(r'([&~|])').sub
def _translate(pat, star, question_mark):
res = []
add = res.append
Expand All @@ -77,69 +79,70 @@ def _translate(pat, star, question_mark):
i, n = 0, len(pat)
while i < n:
c = pat[i]
i = i+1
if c == '*':
i = i + 1
if c == "*":
# store the position of the wildcard
star_indices.append(len(res))
add(star)
# compress consecutive `*` into one
while i < n and pat[i] == '*':
while i < n and pat[i] == "*":
i += 1
elif c == '?':
elif c == "?":
add(question_mark)
elif c == '[':
elif c == "[":
j = i
if j < n and pat[j] == '!':
j = j+1
if j < n and pat[j] == ']':
j = j+1
while j < n and pat[j] != ']':
j = j+1
if j < n and pat[j] == "!":
j = j + 1
if j < n and pat[j] == "]":
j = j + 1
while j < n and pat[j] != "]":
j = j + 1
if j >= n:
add('\\[')
add("\\[")
else:
stuff = pat[i:j]
if '-' not in stuff:
stuff = stuff.replace('\\', r'\\')
if "-" not in stuff:
stuff = stuff.replace("\\", r"\\")
else:
chunks = []
k = i+2 if pat[i] == '!' else i+1
k = i + 2 if pat[i] == "!" else i + 1
while True:
k = pat.find('-', k, j)
k = pat.find("-", k, j)
if k < 0:
break
chunks.append(pat[i:k])
i = k+1
k = k+3
i = k + 1
k = k + 3
chunk = pat[i:j]
if chunk:
chunks.append(chunk)
else:
chunks[-1] += '-'
chunks[-1] += "-"
# Remove empty ranges -- invalid in RE.
for k in range(len(chunks)-1, 0, -1):
if chunks[k-1][-1] > chunks[k][0]:
chunks[k-1] = chunks[k-1][:-1] + chunks[k][1:]
for k in range(len(chunks) - 1, 0, -1):
if chunks[k - 1][-1] > chunks[k][0]:
chunks[k - 1] = chunks[k - 1][:-1] + chunks[k][1:]
del chunks[k]
# Escape backslashes and hyphens for set difference (--).
# Hyphens that create ranges shouldn't be escaped.
stuff = '-'.join(s.replace('\\', r'\\').replace('-', r'\-')
for s in chunks)
i = j+1
stuff = "-".join(
s.replace("\\", r"\\").replace("-", r"\-") for s in chunks
)
i = j + 1
if not stuff:
# Empty range: never match.
add('(?!)')
elif stuff == '!':
add("(?!)")
elif stuff == "!":
# Negated empty range: match any character.
add('.')
add(".")
else:
# Escape set operations (&&, ~~ and ||).
stuff = _re_setops_sub(r'\\\1', stuff)
if stuff[0] == '!':
stuff = '^' + stuff[1:]
elif stuff[0] in ('^', '['):
stuff = '\\' + stuff
add(f'[{stuff}]')
stuff = _re_setops_sub(r"\\\1", stuff)
if stuff[0] == "!":
stuff = "^" + stuff[1:]
elif stuff[0] in ("^", "["):
stuff = "\\" + stuff
add(f"[{stuff}]")
else:
add(re.escape(c))
assert i == n
Expand Down
4 changes: 3 additions & 1 deletion codecov_cli/helpers/request.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,9 @@ def wrapper(*args, **kwargs):
)
sleep(backoff_time(retry))
retry += 1
raise Exception(f"Request failed after too many retries. URL: {kwargs.get('url', args[0] if args else 'Unknown')}")
raise Exception(
f"Request failed after too many retries. URL: {kwargs.get('url', args[0] if args else 'Unknown')}"
)

return wrapper

Expand Down
4 changes: 3 additions & 1 deletion codecov_cli/plugins/compress_pycoverage_contexts.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,9 @@ def run_preparation(self, collector) -> PreparationPluginReturn:
)
return PreparationPluginReturn(
success=False,
messages=[f"File to compress {self.file_to_compress} is not a file."],
messages=[
f"File to compress {self.file_to_compress} is not a file."
],
)
# Create in and out streams
fd_in = open(self.file_to_compress, "rb")
Expand Down
4 changes: 3 additions & 1 deletion codecov_cli/plugins/gcov.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,9 @@ def run_preparation(self, collector) -> PreparationPluginReturn:
logger.warning(f"{self.executable} is not installed or can't be found.")
return

filename_include_regex = globs_to_regex(["*.gcno", *self.patterns_to_include])
filename_include_regex = globs_to_regex(
["*.gcno", *self.patterns_to_include]
)
filename_exclude_regex = globs_to_regex(self.patterns_to_ignore)

matched_paths = [
Expand Down
4 changes: 3 additions & 1 deletion command_dump.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ def command_dump(commands):

if "Commands:" in split_docs:
sub_commands = [
sub_command.strip() for sub_command in split_docs[index_of + 1 :] if sub_command.strip()
sub_command.strip()
for sub_command in split_docs[index_of + 1 :]
if sub_command.strip()
]
for sub_command in sub_commands:
command_docs = "\n".join(
Expand Down
33 changes: 24 additions & 9 deletions tests/commands/test_invoke_empty_upload.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,37 @@
from codecov_cli.main import cli
from tests.factory import FakeProvider, FakeVersioningSystem


def test_invoke_empty_upload_with_create_commit(mocker):
create_commit_mock = mocker.patch("codecov_cli.commands.empty_upload.create_commit_logic")
empty_upload_mock = mocker.patch("codecov_cli.commands.empty_upload.empty_upload_logic")
create_commit_mock = mocker.patch(
"codecov_cli.commands.empty_upload.create_commit_logic"
)
empty_upload_mock = mocker.patch(
"codecov_cli.commands.empty_upload.empty_upload_logic"
)

fake_ci_provider = FakeProvider({FallbackFieldEnum.commit_sha: None})
mocker.patch("codecov_cli.main.get_ci_adapter", return_value=fake_ci_provider)

runner = CliRunner()
result = runner.invoke(cli, ["empty-upload",
"-C", "command-sha",
"--slug", "owner/repo",
"--parent-sha", "asdf",
"--branch", "main",
"--pr", 1234], obj={})
result = runner.invoke(
cli,
[
"empty-upload",
"-C",
"command-sha",
"--slug",
"owner/repo",
"--parent-sha",
"asdf",
"--branch",
"main",
"--pr",
1234,
],
obj={},
)
assert result.exit_code == 0

create_commit_mock.assert_called_once()
empty_upload_mock.assert_called_once()

12 changes: 9 additions & 3 deletions tests/services/upload/test_coverage_file_finder.py
Original file line number Diff line number Diff line change
Expand Up @@ -226,12 +226,16 @@ def test_find_coverage_files_with_directory_named_as_file(
for file in coverage_files:
file.touch()

coverage_file_finder.explicitly_listed_files = [Path("coverage.xml/coverage.xml")]
coverage_file_finder.explicitly_listed_files = [
Path("coverage.xml/coverage.xml")
]
result = sorted(
[file.get_filename() for file in coverage_file_finder.find_files()]
)
expected = [
UploadCollectionResultFile(Path(f"{project_root}/coverage.xml/coverage.xml")),
UploadCollectionResultFile(
Path(f"{project_root}/coverage.xml/coverage.xml")
),
]
expected_paths = sorted([file.get_filename() for file in expected])
assert result == expected_paths
Expand All @@ -241,7 +245,9 @@ def test_find_coverage_files_with_directory_named_as_file(
[file.get_filename() for file in coverage_file_finder.find_files()]
)
expected = [
UploadCollectionResultFile(Path(f"{project_root}/coverage.xml/coverage.xml")),
UploadCollectionResultFile(
Path(f"{project_root}/coverage.xml/coverage.xml")
),
]
expected_paths = sorted([file.get_filename() for file in expected])
assert result == expected_paths
Expand Down