Skip to content

Commit 56cadac

Browse files
authored
[Workflow] Expand code-format-helper.py error reporting (#69686)
* Consider the darker/clang-format command to have failed if the exit code is non-zero, regardless of the stdout/stderr output. * Propagate stderr from the formatter command to the script's caller (and into the GitHub log). * On success, dump stdout to the caller, so it ends up in GitHub's log. I'm not sure what this would ever be, but if it exists, it should be preserved. * Just before the script exits, if any formatter failed, print a line showing which formatters failed.
1 parent 1ab44d5 commit 56cadac

File tree

1 file changed

+44
-37
lines changed

1 file changed

+44
-37
lines changed

llvm/utils/git/code-format-helper.py

Lines changed: 44 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,8 @@ def format_run(
3636
) -> str | None:
3737
raise NotImplementedError()
3838

39-
def pr_comment_text(self, diff: str) -> str:
39+
def pr_comment_text_for_diff(self, diff: str) -> str:
4040
return f"""
41-
{self.comment_tag}
42-
4341
:warning: {self.friendly_name}, {self.name} found issues in your code. :warning:
4442
4543
<details>
@@ -73,39 +71,40 @@ def find_comment(
7371
return comment
7472
return None
7573

76-
def update_pr(self, diff: str, args: argparse.Namespace) -> None:
74+
def update_pr(
75+
self, comment_text: str, args: argparse.Namespace, create_new: bool
76+
) -> None:
7777
repo = github.Github(args.token).get_repo(args.repo)
7878
pr = repo.get_issue(args.issue_number).as_pull_request()
7979

80-
existing_comment = self.find_comment(pr)
81-
pr_text = self.pr_comment_text(diff)
82-
83-
if existing_comment:
84-
existing_comment.edit(pr_text)
85-
else:
86-
pr.as_issue().create_comment(pr_text)
87-
88-
def update_pr_success(self, args: argparse.Namespace) -> None:
89-
repo = github.Github(args.token).get_repo(args.repo)
90-
pr = repo.get_issue(args.issue_number).as_pull_request()
80+
comment_text = self.comment_tag + "\n\n" + comment_text
9181

9282
existing_comment = self.find_comment(pr)
9383
if existing_comment:
94-
existing_comment.edit(
95-
f"""
96-
{self.comment_tag}
97-
:white_check_mark: With the latest revision this PR passed the {self.friendly_name}.
98-
"""
99-
)
84+
existing_comment.edit(comment_text)
85+
elif create_new:
86+
pr.as_issue().create_comment(comment_text)
10087

10188
def run(self, changed_files: list[str], args: argparse.Namespace) -> bool:
10289
diff = self.format_run(changed_files, args)
103-
if diff:
104-
self.update_pr(diff, args)
90+
if diff is None:
91+
comment_text = f"""
92+
:white_check_mark: With the latest revision this PR passed the {self.friendly_name}.
93+
"""
94+
self.update_pr(comment_text, args, create_new=False)
95+
return True
96+
elif len(diff) > 0:
97+
comment_text = self.pr_comment_text_for_diff(diff)
98+
self.update_pr(comment_text, args, create_new=True)
10599
return False
106100
else:
107-
self.update_pr_success(args)
108-
return True
101+
# The formatter failed but didn't output a diff (e.g. some sort of
102+
# infrastructure failure).
103+
comment_text = f"""
104+
:warning: The {self.friendly_name} failed without printing a diff. Check the logs for stderr output. :warning:
105+
"""
106+
self.update_pr(comment_text, args, create_new=False)
107+
return False
109108

110109

111110
class ClangFormatHelper(FormatHelper):
@@ -123,7 +122,7 @@ def libcxx_excluded_files(self) -> list[str]:
123122

124123
def should_be_excluded(self, path: str) -> bool:
125124
if path in self.libcxx_excluded_files:
126-
print(f"Excluding file {path}")
125+
print(f"{self.name}: Excluding file {path}")
127126
return True
128127
return False
129128

@@ -152,12 +151,15 @@ def format_run(
152151
print(f"Running: {' '.join(cf_cmd)}")
153152
self.cf_cmd = cf_cmd
154153
proc = subprocess.run(cf_cmd, capture_output=True)
154+
sys.stdout.write(proc.stderr.decode("utf-8"))
155155

156-
# formatting needed
157-
if proc.returncode == 1:
156+
if proc.returncode != 0:
157+
# formatting needed, or the command otherwise failed
158+
print(f"error: {self.name} exited with code {proc.returncode}")
158159
return proc.stdout.decode("utf-8")
159-
160-
return None
160+
else:
161+
sys.stdout.write(proc.stdout.decode("utf-8"))
162+
return None
161163

162164

163165
class DarkerFormatHelper(FormatHelper):
@@ -193,12 +195,15 @@ def format_run(
193195
print(f"Running: {' '.join(darker_cmd)}")
194196
self.darker_cmd = darker_cmd
195197
proc = subprocess.run(darker_cmd, capture_output=True)
198+
sys.stdout.write(proc.stderr.decode("utf-8"))
196199

197-
# formatting needed
198-
if proc.returncode == 1:
200+
if proc.returncode != 0:
201+
# formatting needed, or the command otherwise failed
202+
print(f"error: {self.name} exited with code {proc.returncode}")
199203
return proc.stdout.decode("utf-8")
200-
201-
return None
204+
else:
205+
sys.stdout.write(proc.stdout.decode("utf-8"))
206+
return None
202207

203208

204209
ALL_FORMATTERS = (DarkerFormatHelper(), ClangFormatHelper())
@@ -236,9 +241,11 @@ def format_run(
236241
if args.changed_files:
237242
changed_files = args.changed_files.split(",")
238243

239-
exit_code = 0
244+
failed_formatters = []
240245
for fmt in ALL_FORMATTERS:
241246
if not fmt.run(changed_files, args):
242-
exit_code = 1
247+
failed_formatters.append(fmt.name)
243248

244-
sys.exit(exit_code)
249+
if len(failed_formatters) > 0:
250+
print(f"error: some formatters failed: {' '.join(failed_formatters)}")
251+
sys.exit(1)

0 commit comments

Comments
 (0)