-
Notifications
You must be signed in to change notification settings - Fork 44
/
Copy pathxcode.py
110 lines (94 loc) · 3.89 KB
/
xcode.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
import logging
import os
import pathlib
import re
import shutil
import subprocess
import typing
from fnmatch import translate
from codecov_cli.helpers.folder_searcher import globs_to_regex, search_files
from codecov_cli.plugins.types import PreparationPluginReturn
logger = logging.getLogger("codecovcli")
class XcodePlugin(object):
def __init__(
self,
app_name: typing.Optional[str] = None,
derived_data_folder: typing.Optional[pathlib.Path] = None,
):
self.derived_data_folder = (
derived_data_folder
or pathlib.Path("~/Library/Developer/Xcode/DerivedData").expanduser()
)
# this is to speed up processing and to build reports for the project being tested,
# if empty the plugin will build reports for every xcode project it finds
self.app_name = app_name or ""
def run_preparation(self, collector) -> PreparationPluginReturn:
logger.debug("Running xcode plugin...")
if shutil.which("xcrun") is None:
logger.warning("xcrun is not installed or can't be found.")
return
logger.debug(f"DerivedData folder: {self.derived_data_folder}")
filename_include_regex = globs_to_regex(["*.profdata"])
matched_paths = [
str(path)
for path in search_files(
folder_to_search=self.derived_data_folder,
folders_to_ignore=[],
filename_include_regex=filename_include_regex,
)
]
if not matched_paths:
logger.warning("No swift data found.")
return
logger.info(
"Running swift coverage on the following list of files:",
extra=dict(extra_log_attributes=dict(matched_paths=matched_paths)),
)
for path in matched_paths:
self.swiftcov(path, self.app_name)
return PreparationPluginReturn(success=True, messages="")
def swiftcov(self, path, app_name: str):
directory = os.path.dirname(path)
build_dir = pathlib.Path(re.sub("(Build).*", "Build", directory))
for type in ["app", "framework", "xctest"]:
filename_include_regex = re.compile(translate(f"*.{type}"))
matched_dir_paths = [
str(path)
for path in search_files(
folder_to_search=pathlib.Path(build_dir),
folders_to_ignore=[],
filename_include_regex=filename_include_regex,
search_for_directories=True,
)
]
for dir_path in matched_dir_paths:
# proj name without extension
proj = pathlib.Path(dir_path).stem
if app_name == "" or (app_name.lower() in proj.lower()):
logger.info(f"+ Building reports for {proj} {type}")
proj_path = pathlib.Path(pathlib.Path(dir_path) / proj)
dest = (
proj_path
if proj_path.is_file()
else pathlib.Path(f"{dir_path}/Contents/MacOS/{proj}")
)
output_file_name = f"{proj}.{type}.coverage.txt".replace(" ", "")
self.run_llvm_cov(output_file_name, path, dest)
def run_llvm_cov(self, output_file_name, path, dest):
with open(output_file_name, "w") as output_file:
s = subprocess.run(
[
"xcrun",
"llvm-cov",
"show",
"-instr-profile",
path,
str(dest),
],
stdout=output_file,
)
# 0 = success
if s.returncode != 0:
logger.warning(f"llvm-cov failed to produce results for {dest}")
else:
logger.info(f"Generated {output_file_name} file successfully")