Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for test result ingestion in the CLI #347

Merged
merged 16 commits into from
Jan 25, 2024
Merged
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
40 changes: 24 additions & 16 deletions codecov_cli/commands/upload.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ def _turn_env_vars_into_dict(ctx, params, value):
"-s",
"--dir",
"--coverage-files-search-root-folder",
"coverage_files_search_root_folder",
"--files-search-root-folder",
"files_search_root_folder",
help="Folder where to search for coverage files",
type=click.Path(path_type=pathlib.Path),
default=pathlib.Path.cwd,
Expand All @@ -42,7 +43,8 @@ def _turn_env_vars_into_dict(ctx, params, value):
click.option(
"--exclude",
"--coverage-files-search-exclude-folder",
"coverage_files_search_exclude_folders",
"--files-search-exclude-folder",
"files_search_exclude_folders",
help="Folders to exclude from search",
type=click.Path(path_type=pathlib.Path),
multiple=True,
Expand All @@ -52,7 +54,8 @@ def _turn_env_vars_into_dict(ctx, params, value):
"-f",
"--file",
"--coverage-files-search-direct-file",
"coverage_files_search_explicitly_listed_files",
"--files-search-direct-file",
"files_search_explicitly_listed_files",
help="Explicit files to upload. These will be added to the coverage files found for upload. If you wish to only upload the specified files, please consider using --disable-search to disable uploading other files.",
type=click.Path(path_type=pathlib.Path),
multiple=True,
Expand Down Expand Up @@ -155,6 +158,12 @@ def _turn_env_vars_into_dict(ctx, params, value):
is_flag=True,
help="Raise no excpetions when no coverage reports found.",
),
click.option(
"--report-type",
help="The type of the file to upload, coverage by default. Possible values are: testing, coverage.",
default="coverage",
type=click.Choice(["coverage", "test_results"]),
),
]


Expand All @@ -179,9 +188,9 @@ def do_upload(
flags: typing.List[str],
name: typing.Optional[str],
network_root_folder: pathlib.Path,
coverage_files_search_root_folder: pathlib.Path,
coverage_files_search_exclude_folders: typing.List[pathlib.Path],
coverage_files_search_explicitly_listed_files: typing.List[pathlib.Path],
files_search_root_folder: pathlib.Path,
files_search_exclude_folders: typing.List[pathlib.Path],
files_search_explicitly_listed_files: typing.List[pathlib.Path],
disable_search: bool,
disable_file_fixes: bool,
token: typing.Optional[str],
Expand All @@ -194,6 +203,7 @@ def do_upload(
dry_run: bool,
git_service: typing.Optional[str],
handle_no_reports_found: bool,
report_type: str,
):
versioning_system = ctx.obj["versioning_system"]
codecov_yaml = ctx.obj["codecov_yaml"] or {}
Expand All @@ -204,6 +214,7 @@ def do_upload(
"Starting upload processing",
extra=dict(
extra_log_attributes=dict(
upload_file_type=report_type,
commit_sha=commit_sha,
report_code=report_code,
build_code=build_code,
Expand All @@ -213,9 +224,9 @@ def do_upload(
flags=flags,
name=name,
network_root_folder=network_root_folder,
coverage_files_search_root_folder=coverage_files_search_root_folder,
coverage_files_search_exclude_folders=coverage_files_search_exclude_folders,
coverage_files_search_explicitly_listed_files=coverage_files_search_explicitly_listed_files,
files_search_root_folder=files_search_root_folder,
files_search_exclude_folders=files_search_exclude_folders,
files_search_explicitly_listed_files=files_search_explicitly_listed_files,
plugin_names=plugin_names,
token=token,
branch=branch,
Expand All @@ -233,6 +244,7 @@ def do_upload(
cli_config,
versioning_system,
ci_adapter,
upload_file_type=report_type,
commit_sha=commit_sha,
report_code=report_code,
build_code=build_code,
Expand All @@ -242,13 +254,9 @@ def do_upload(
flags=flags,
name=name,
network_root_folder=network_root_folder,
coverage_files_search_root_folder=coverage_files_search_root_folder,
coverage_files_search_exclude_folders=list(
coverage_files_search_exclude_folders
),
coverage_files_search_explicitly_listed_files=list(
coverage_files_search_explicitly_listed_files
),
files_search_root_folder=files_search_root_folder,
files_search_exclude_folders=list(files_search_exclude_folders),
files_search_explicitly_listed_files=list(files_search_explicitly_listed_files),
plugin_names=plugin_names,
token=token,
branch=branch,
Expand Down
39 changes: 21 additions & 18 deletions codecov_cli/commands/upload_process.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@
flags: typing.List[str],
name: typing.Optional[str],
network_root_folder: pathlib.Path,
coverage_files_search_root_folder: pathlib.Path,
coverage_files_search_exclude_folders: typing.List[pathlib.Path],
coverage_files_search_explicitly_listed_files: typing.List[pathlib.Path],
files_search_root_folder: pathlib.Path,
files_search_exclude_folders: typing.List[pathlib.Path],
files_search_explicitly_listed_files: typing.List[pathlib.Path],
disable_search: bool,
disable_file_fixes: bool,
token: typing.Optional[str],
Expand All @@ -48,6 +48,7 @@
git_service: typing.Optional[str],
parent_sha: typing.Optional[str],
handle_no_reports_found: bool,
report_type: str,
):
logger.debug(
"Starting upload process",
Expand All @@ -62,9 +63,9 @@
flags=flags,
name=name,
network_root_folder=network_root_folder,
coverage_files_search_root_folder=coverage_files_search_root_folder,
coverage_files_search_exclude_folders=coverage_files_search_exclude_folders,
coverage_files_search_explicitly_listed_files=coverage_files_search_explicitly_listed_files,
files_search_root_folder=files_search_root_folder,
files_search_exclude_folders=files_search_exclude_folders,
files_search_explicitly_listed_files=files_search_explicitly_listed_files,
plugin_names=plugin_names,
token=token,
branch=branch,
Expand All @@ -90,15 +91,16 @@
git_service=git_service,
fail_on_error=True,
)
ctx.invoke(
create_report,
token=token,
code=report_code,
fail_on_error=True,
commit_sha=commit_sha,
slug=slug,
git_service=git_service,
)
if report_type == "coverage":
ctx.invoke(

Check warning on line 95 in codecov_cli/commands/upload_process.py

View check run for this annotation

Codecov / codecov/patch

codecov_cli/commands/upload_process.py#L94-L95

Added lines #L94 - L95 were not covered by tests
create_report,
token=token,
code=report_code,
fail_on_error=True,
commit_sha=commit_sha,
slug=slug,
git_service=git_service,
)
ctx.invoke(
do_upload,
commit_sha=commit_sha,
Expand All @@ -110,9 +112,9 @@
flags=flags,
name=name,
network_root_folder=network_root_folder,
coverage_files_search_root_folder=coverage_files_search_root_folder,
coverage_files_search_exclude_folders=coverage_files_search_exclude_folders,
coverage_files_search_explicitly_listed_files=coverage_files_search_explicitly_listed_files,
files_search_root_folder=files_search_root_folder,
files_search_exclude_folders=files_search_exclude_folders,
files_search_explicitly_listed_files=files_search_explicitly_listed_files,
disable_search=disable_search,
token=token,
plugin_names=plugin_names,
Expand All @@ -125,4 +127,5 @@
git_service=git_service,
handle_no_reports_found=handle_no_reports_found,
disable_file_fixes=disable_file_fixes,
report_type=report_type,
)
28 changes: 17 additions & 11 deletions codecov_cli/services/upload/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from codecov_cli.helpers.request import log_warnings_and_errors_if_any
from codecov_cli.helpers.versioning_systems import VersioningSystemInterface
from codecov_cli.plugins import select_preparation_plugins
from codecov_cli.services.upload.coverage_file_finder import select_coverage_file_finder
from codecov_cli.services.upload.file_finder import select_file_finder
from codecov_cli.services.upload.legacy_upload_sender import LegacyUploadSender
from codecov_cli.services.upload.network_finder import select_network_finder
from codecov_cli.services.upload.upload_collector import UploadCollector
Expand All @@ -34,14 +34,15 @@ def do_upload_logic(
flags: typing.List[str],
name: typing.Optional[str],
network_root_folder: Path,
coverage_files_search_root_folder: Path,
coverage_files_search_exclude_folders: typing.List[Path],
coverage_files_search_explicitly_listed_files: typing.List[Path],
files_search_root_folder: Path,
files_search_exclude_folders: typing.List[Path],
files_search_explicitly_listed_files: typing.List[Path],
plugin_names: typing.List[str],
token: str,
branch: typing.Optional[str],
slug: typing.Optional[str],
pull_request_number: typing.Optional[str],
upload_file_type: str = "coverage",
use_legacy_uploader: bool = False,
fail_on_error: bool = False,
dry_run: bool = False,
Expand All @@ -51,19 +52,23 @@ def do_upload_logic(
handle_no_reports_found: bool = False,
disable_file_fixes: bool = False,
):
preparation_plugins = select_preparation_plugins(cli_config, plugin_names)
coverage_file_selector = select_coverage_file_finder(
coverage_files_search_root_folder,
coverage_files_search_exclude_folders,
coverage_files_search_explicitly_listed_files,
if upload_file_type == "coverage":
preparation_plugins = select_preparation_plugins(cli_config, plugin_names)
elif upload_file_type == "test_results":
preparation_plugins = []
file_selector = select_file_finder(
files_search_root_folder,
files_search_exclude_folders,
files_search_explicitly_listed_files,
disable_search,
upload_file_type,
)
network_finder = select_network_finder(versioning_system)
collector = UploadCollector(
preparation_plugins, network_finder, coverage_file_selector, disable_file_fixes
preparation_plugins, network_finder, file_selector, disable_file_fixes
)
try:
upload_data = collector.generate_upload_data()
upload_data = collector.generate_upload_data(upload_file_type)
except click.ClickException as exp:
if handle_no_reports_found:
logger.info(
Expand Down Expand Up @@ -103,6 +108,7 @@ def do_upload_logic(
token,
env_vars,
report_code,
upload_file_type,
name,
branch,
slug,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@
"test_cov.xml",
]

test_results_files_patterns = [
"*junit*",
]

coverage_files_excluded_patterns = [
"*.am",
Expand Down Expand Up @@ -134,6 +137,10 @@
"*.zip",
]

test_results_files_excluded_patterns = (
coverage_files_patterns + coverage_files_excluded_patterns
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

smart

)


default_folders_to_ignore = [
"vendor",
Expand Down Expand Up @@ -170,49 +177,53 @@
]


class CoverageFileFinder(object):
class FileFinder(object):
def __init__(
self,
project_root: Path = None,
folders_to_ignore: typing.List[str] = None,
explicitly_listed_files: typing.List[Path] = None,
disable_search: bool = False,
report_type: str = "coverage",
):
self.project_root = project_root or Path(os.getcwd())
self.folders_to_ignore = folders_to_ignore or []
self.explicitly_listed_files = explicitly_listed_files or None
self.disable_search = disable_search
self.report_type = report_type

def find_coverage_files(self) -> typing.List[UploadCollectionResultFile]:
regex_patterns_to_exclude = globs_to_regex(coverage_files_excluded_patterns)
coverage_files_paths = []
user_coverage_files_paths = []
def find_files(self) -> typing.List[UploadCollectionResultFile]:
if self.report_type == "coverage":
files_excluded_patterns = coverage_files_excluded_patterns
files_patterns = coverage_files_patterns
elif self.report_type == "test_results":
files_excluded_patterns = test_results_files_excluded_patterns
files_patterns = test_results_files_patterns
regex_patterns_to_exclude = globs_to_regex(files_excluded_patterns)
files_paths = []
user_files_paths = []
if self.explicitly_listed_files:
user_coverage_files_paths = self.get_user_specified_coverage_files(
regex_patterns_to_exclude
)
user_files_paths = self.get_user_specified_files(regex_patterns_to_exclude)
if not self.disable_search:
regex_patterns_to_include = globs_to_regex(coverage_files_patterns)
coverage_files_paths = search_files(
regex_patterns_to_include = globs_to_regex(files_patterns)
files_paths = search_files(
self.project_root,
default_folders_to_ignore + self.folders_to_ignore,
filename_include_regex=regex_patterns_to_include,
filename_exclude_regex=regex_patterns_to_exclude,
)
result_files = [
UploadCollectionResultFile(path)
for path in coverage_files_paths
if coverage_files_paths
UploadCollectionResultFile(path) for path in files_paths if files_paths
]
user_result_files = [
UploadCollectionResultFile(path)
for path in user_coverage_files_paths
if user_coverage_files_paths
for path in user_files_paths
if user_files_paths
]

return list(set(result_files + user_result_files))

def get_user_specified_coverage_files(self, regex_patterns_to_exclude):
def get_user_specified_files(self, regex_patterns_to_exclude):
user_filenames_to_include = []
files_excluded_but_user_includes = []
for file in self.explicitly_listed_files:
Expand All @@ -230,7 +241,7 @@ def get_user_specified_coverage_files(self, regex_patterns_to_exclude):
multipart_include_regex = globs_to_regex(
[str(path.resolve()) for path in self.explicitly_listed_files]
)
user_coverage_files_paths = list(
user_files_paths = list(
search_files(
self.project_root,
default_folders_to_ignore + self.folders_to_ignore,
Expand All @@ -241,7 +252,7 @@ def get_user_specified_coverage_files(self, regex_patterns_to_exclude):
)
not_found_files = []
for filepath in self.explicitly_listed_files:
if filepath.resolve() not in user_coverage_files_paths:
if filepath.resolve() not in user_files_paths:
not_found_files.append(filepath)

if not_found_files:
Expand All @@ -250,15 +261,20 @@ def get_user_specified_coverage_files(self, regex_patterns_to_exclude):
extra=dict(extra_log_attributes=dict(not_found_files=not_found_files)),
)

return user_coverage_files_paths
return user_files_paths


def select_coverage_file_finder(
root_folder_to_search, folders_to_ignore, explicitly_listed_files, disable_search
def select_file_finder(
root_folder_to_search,
folders_to_ignore,
explicitly_listed_files,
disable_search,
report_type="coverage",
):
return CoverageFileFinder(
return FileFinder(
root_folder_to_search,
folders_to_ignore,
explicitly_listed_files,
disable_search,
report_type,
)
Loading
Loading