Skip to content

Commit ac2b8dc

Browse files
committed
[Workflow] Expand code-format-helper.py error reporting
* Consider the darker/clang-format command to have failed if the exit code is non-zero, regardless of the stdout/stderr output. * Allow stderr from the formatter command to propagate 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. Replace [str] with list[str] to satisfy mypy/pytype.
1 parent 8a96d1d commit ac2b8dc

File tree

1 file changed

+45
-39
lines changed

1 file changed

+45
-39
lines changed

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

Lines changed: 45 additions & 39 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,41 @@ 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:
89+
print(f"Formatter {self.name} ({self.friendly_name}):")
10290
diff = self.format_run(changed_files, args)
103-
if diff:
104-
self.update_pr(diff, args)
91+
if diff is None:
92+
comment_text = f"""
93+
:white_check_mark: With the latest revision this PR passed the {self.friendly_name}.
94+
"""
95+
self.update_pr(comment_text, args, create_new=False)
96+
return True
97+
elif len(diff) > 0:
98+
comment_text = self.pr_comment_text_for_diff(diff)
99+
self.update_pr(comment_text, args, create_new=True)
105100
return False
106101
else:
107-
self.update_pr_success(args)
108-
return True
102+
# The formatter failed but didn't output a diff (e.g. some sort of
103+
# infrastructure failure).
104+
comment_text = f"""
105+
:warning: The {self.friendly_name} failed without printing a diff. Check the logs for stderr output. :warning:
106+
"""
107+
self.update_pr(comment_text, args, create_new=False)
108+
return False
109109

110110

111111
class ClangFormatHelper(FormatHelper):
@@ -151,21 +151,23 @@ def format_run(
151151
] + cpp_files
152152
print(f"Running: {' '.join(cf_cmd)}")
153153
self.cf_cmd = cf_cmd
154-
proc = subprocess.run(cf_cmd, capture_output=True)
154+
proc = subprocess.run(cf_cmd, stdout=subprocess.PIPE)
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):
164166
name = "darker"
165167
friendly_name = "Python code formatter"
166168

167169
@property
168-
def instructions(self):
170+
def instructions(self) -> str:
169171
return " ".join(self.darker_cmd)
170172

171173
def filter_changed_files(self, changed_files: list[str]) -> list[str]:
@@ -192,13 +194,15 @@ def format_run(
192194
] + py_files
193195
print(f"Running: {' '.join(darker_cmd)}")
194196
self.darker_cmd = darker_cmd
195-
proc = subprocess.run(darker_cmd, capture_output=True)
197+
proc = subprocess.run(darker_cmd, stdout=subprocess.PIPE)
196198

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

203207

204208
ALL_FORMATTERS = (DarkerFormatHelper(), ClangFormatHelper())
@@ -236,9 +240,11 @@ def format_run(
236240
if args.changed_files:
237241
changed_files = args.changed_files.split(",")
238242

239-
exit_code = 0
243+
failed_formatters = []
240244
for fmt in ALL_FORMATTERS:
241245
if not fmt.run(changed_files, args):
242-
exit_code = 1
246+
failed_formatters.append(fmt.name)
243247

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

0 commit comments

Comments
 (0)