Skip to content

Commit 4c23ceb

Browse files
cortinicometa-codesync[bot]
authored andcommitted
Report formatting fixes on pull requests
Summary: Add a GitHub Actions formatting check that runs the repository-wide formatter check and posts line-level suggested fixes through the GitHub API for files that need reformatting. Changelog: [Internal] Differential Revision: D119487616
1 parent 89cb63c commit 4c23ceb

5 files changed

Lines changed: 558 additions & 1 deletion

File tree

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
/**
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*
7+
* @format
8+
*/
9+
10+
'use strict';
11+
12+
const {
13+
changedFilesFromPatch,
14+
commentableRightLines,
15+
parsePatch,
16+
} = require('../reportFormattingErrors');
17+
18+
describe('reportFormattingErrors', () => {
19+
test('converts formatter hunks into minimal suggestions', () => {
20+
const patch = `diff --git a/example.js b/example.js
21+
--- a/example.js
22+
+++ b/example.js
23+
@@ -10,3 +10,3 @@
24+
unchanged
25+
-const value={answer:42};
26+
+const value = {answer: 42};
27+
unchanged
28+
`;
29+
30+
expect(parsePatch(patch)).toEqual([
31+
{
32+
path: 'example.js',
33+
startLine: 11,
34+
endLine: 11,
35+
replacement: 'const value = {answer: 42};',
36+
},
37+
]);
38+
});
39+
40+
test('tracks lines that can receive right-side review comments', () => {
41+
const lines = commentableRightLines(`@@ -4,2 +4,3 @@
42+
context
43+
-old
44+
+new
45+
+added
46+
`);
47+
48+
expect([...lines]).toEqual([4, 5, 6]);
49+
});
50+
51+
test.each(['../../../etc/passwd', '/absolute/path', `\0evil`])(
52+
'rejects unsafe patch path %p',
53+
unsafePath => {
54+
const patch = `diff --git a/file b/file
55+
--- a/file
56+
+++ b/${unsafePath}
57+
@@ -1 +1 @@
58+
-old
59+
+new
60+
`;
61+
62+
expect(parsePatch(patch)).toEqual([]);
63+
expect(changedFilesFromPatch(patch)).toEqual([]);
64+
},
65+
);
66+
67+
test('parses multiple files without carrying hunk state across headers', () => {
68+
const patch = `diff --git a/one.js b/one.js
69+
--- a/one.js
70+
+++ b/one.js
71+
@@ -1 +1 @@
72+
-one
73+
+first
74+
diff --git a/two.js b/two.js
75+
--- a/two.js
76+
+++ b/two.js
77+
@@ -2 +2 @@
78+
-two
79+
+second
80+
`;
81+
82+
expect(parsePatch(patch)).toEqual([
83+
{path: 'one.js', startLine: 1, endLine: 1, replacement: 'first'},
84+
{path: 'two.js', startLine: 2, endLine: 2, replacement: 'second'},
85+
]);
86+
expect(changedFilesFromPatch(patch)).toEqual(['one.js', 'two.js']);
87+
});
88+
89+
test('reports files even when a hunk cannot become a suggestion', () => {
90+
const patch = `diff --git a/example.js b/example.js
91+
--- a/example.js
92+
+++ b/example.js
93+
@@ -1 +1 @@
94+
-old
95+
+\`\`\`unsafe suggestion fence
96+
`;
97+
98+
expect(parsePatch(patch)).toEqual([]);
99+
expect(changedFilesFromPatch(patch)).toEqual(['example.js']);
100+
});
101+
102+
test('ignores non-hunk lines when collecting commentable lines', () => {
103+
const lines = commentableRightLines(`@@ -4 +4 @@
104+
+new
105+
index 123..456 100644
106+
`);
107+
108+
expect([...lines]).toEqual([4]);
109+
});
110+
});

0 commit comments

Comments
 (0)