Skip to content

Commit 0e0f23e

Browse files
committed
Report removal of final newline
If a file does not end in a newline, then every line added to the end of the file results in a diff to the previous final line. An example using `\n` to symbolize end of line characters: https://github.com/arduino-libraries/Servo\n https://github.com/arduino-libraries/Stepper When another line is added at the end: https://github.com/arduino-libraries/Servo\n https://github.com/arduino-libraries/Stepper\n https://github.com/arduino-libraries/FooBar you can see there is necessarily a diff on line 2 even though the editor did not touch that line. For this reason, it is best practices to always retain a newline at the end of files. In addition to it being common practice, the GitHub web editor automatically adds this newline. Between this and my expectation that people would either add URLs to the top of the list or in alphabetical order, leaving the distant end of the file alone, I was hoping that this would not be a common problem with the library submission system, but this is simply not a realistic expectation. What I hadn’t considered is that the person to suffer for this formatting is the next to add a URL to the end of the file. Because of this “ghost diff”, the submission system sees this PR as a modification to an existing item on the list rather than an addition. I think this will be best handled by detecting and dealing with the problem at its introduction, rather than attempting to make the system resilient to a missing final newline.
1 parent 8252c14 commit 0e0f23e

File tree

5 files changed

+77
-23
lines changed

5 files changed

+77
-23
lines changed

main.go

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ type request struct {
7474
Submissions []submissionType `json:"submissions"` // Data for submitted libraries.
7575
IndexEntry string `json:"indexEntry"` // Entry that will be made to the Library Manager index source file when the submission is accepted.
7676
IndexerLogsURLs string `json:"indexerLogsURLs"` // List of URLs where the logs from the Library Manager indexer for each submission are available for view.
77+
Error string `json:"error"` // Error message.
7778
}
7879

7980
// submissionType is the type of the data for each individual library submitted in the request.
@@ -127,7 +128,7 @@ func main() {
127128
}
128129
var req request
129130
var submissionURLs []string
130-
req.Type, req.ArduinoLintLibraryManagerSetting, submissionURLs = parseDiff(rawDiff, *listNameArgument)
131+
req.Type, req.Error, req.ArduinoLintLibraryManagerSetting, submissionURLs = parseDiff(rawDiff, *listNameArgument)
131132

132133
// Process the submissions.
133134
var indexEntries []string
@@ -177,18 +178,24 @@ func errorExit(message string) {
177178
os.Exit(1)
178179
}
179180

180-
// parseDiff parses the request diff and returns the request type, `arduino-lint --library-manager` setting, and list of submission URLs.
181-
func parseDiff(rawDiff []byte, listName string) (string, string, []string) {
181+
// parseDiff parses the request diff and returns the request type, request error, `arduino-lint --library-manager` setting, and list of submission URLs.
182+
func parseDiff(rawDiff []byte, listName string) (string, string, string, []string) {
182183
var submissionURLs []string
183184

185+
// Check if the PR has removed the final newline from a file, which would cause a spurious diff for the next PR if merged.
186+
// Unfortunately, the diff package does not have this capability (only to detect missing newline in the original file).
187+
if bytes.Contains(rawDiff, []byte("\\ No newline at end of file")) {
188+
return "invalid", "Pull request removes newline from the end of a file.%0APlease add a blank line to the end of the file.", "", nil
189+
}
190+
184191
diffs, err := diff.ParseMultiFileDiff(rawDiff)
185192
if err != nil {
186193
panic(err)
187194
}
188195

189196
if (len(diffs) != 1) || (diffs[0].OrigName[2:] != listName) || (diffs[0].OrigName[2:] != diffs[0].NewName[2:]) { // Git diffs have a a/ or b/ prefix on file names.
190197
// This is not a Library Manager submission.
191-
return "other", "", nil
198+
return "other", "", "", nil
192199
}
193200

194201
var addedCount int
@@ -227,7 +234,7 @@ func parseDiff(rawDiff []byte, listName string) (string, string, []string) {
227234
arduinoLintLibraryManagerSetting = "update"
228235
}
229236

230-
return requestType, arduinoLintLibraryManagerSetting, submissionURLs
237+
return requestType, "", arduinoLintLibraryManagerSetting, submissionURLs
231238
}
232239

233240
// populateSubmission does the checks on the submission that aren't provided by Arduino Lint and gathers the necessary data on it.

main_test.go

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,9 @@ index cff484d..e14c179 100644
4646
+https://github.com/foo/bar
4747
`)
4848

49-
requestType, arduinoLintLibraryManagerSetting, submissionURLs := parseDiff(diff, "repositories.txt")
49+
requestType, requestError, arduinoLintLibraryManagerSetting, submissionURLs := parseDiff(diff, "repositories.txt")
5050
assert.Equal(t, "other", requestType, testName)
51+
assert.Equal(t, "", requestError, testName)
5152
assert.Equal(t, "", arduinoLintLibraryManagerSetting, testName)
5253
assert.Nil(t, submissionURLs, testName)
5354

@@ -62,8 +63,9 @@ index d4edde0..807b76d 100644
6263
+hello
6364
`)
6465

65-
requestType, arduinoLintLibraryManagerSetting, submissionURLs = parseDiff(diff, "repositories.txt")
66+
requestType, requestError, arduinoLintLibraryManagerSetting, submissionURLs = parseDiff(diff, "repositories.txt")
6667
assert.Equal(t, "other", requestType, testName)
68+
assert.Equal(t, "", requestError, testName)
6769
assert.Equal(t, "", arduinoLintLibraryManagerSetting, testName)
6870
assert.Nil(t, submissionURLs, testName)
6971

@@ -80,8 +82,9 @@ index cff484d..e14c179 100644
8082
+https://github.com/foo/bar
8183
`)
8284

83-
requestType, arduinoLintLibraryManagerSetting, submissionURLs = parseDiff(diff, "repositories.txt")
85+
requestType, requestError, arduinoLintLibraryManagerSetting, submissionURLs = parseDiff(diff, "repositories.txt")
8486
assert.Equal(t, "other", requestType, testName)
87+
assert.Equal(t, "", requestError, testName)
8588
assert.Equal(t, "", arduinoLintLibraryManagerSetting, testName)
8689
assert.Nil(t, submissionURLs, testName)
8790

@@ -96,8 +99,9 @@ index cff484d..9f67763 100644
9699
+https://github.com/foo/baz
97100
`)
98101

99-
requestType, arduinoLintLibraryManagerSetting, submissionURLs = parseDiff(diff, "repositories.txt")
102+
requestType, requestError, arduinoLintLibraryManagerSetting, submissionURLs = parseDiff(diff, "repositories.txt")
100103
assert.Equal(t, "submission", requestType, testName)
104+
assert.Equal(t, "", requestError, testName)
101105
assert.Equal(t, "submit", arduinoLintLibraryManagerSetting, testName)
102106
assert.ElementsMatch(t, submissionURLs, []string{"https://github.com/foo/bar", "https://github.com/foo/baz"}, testName)
103107

@@ -112,10 +116,11 @@ index cff484d..1b0b80b 100644
112116
\ No newline at end of file
113117
`)
114118

115-
requestType, arduinoLintLibraryManagerSetting, submissionURLs = parseDiff(diff, "repositories.txt")
116-
assert.Equal(t, "submission", requestType, testName)
117-
assert.Equal(t, "submit", arduinoLintLibraryManagerSetting, testName)
118-
assert.ElementsMatch(t, submissionURLs, []string{"https://github.com/foo/bar"}, testName)
119+
requestType, requestError, arduinoLintLibraryManagerSetting, submissionURLs = parseDiff(diff, "repositories.txt")
120+
assert.Equal(t, "invalid", requestType, testName)
121+
assert.Equal(t, "Pull request removes newline from the end of a file.%0APlease add a blank line to the end of the file.", requestError, testName)
122+
assert.Equal(t, "", arduinoLintLibraryManagerSetting, testName)
123+
assert.Nil(t, submissionURLs, testName)
119124

120125
testName = "Submission w/ blank line"
121126
diff = []byte(`
@@ -125,11 +130,12 @@ index cff484d..1b0b80b 100644
125130
+++ b/repositories.txt
126131
@@ -3391,0 +3392 @@ https://github.com/lbernstone/plotutils
127132
+https://github.com/foo/bar
128-
\ No newline at end of file
133+
+
129134
`)
130135

131-
requestType, arduinoLintLibraryManagerSetting, submissionURLs = parseDiff(diff, "repositories.txt")
136+
requestType, requestError, arduinoLintLibraryManagerSetting, submissionURLs = parseDiff(diff, "repositories.txt")
132137
assert.Equal(t, "submission", requestType, testName)
138+
assert.Equal(t, "", requestError, testName)
133139
assert.Equal(t, "submit", arduinoLintLibraryManagerSetting, testName)
134140
assert.ElementsMatch(t, submissionURLs, []string{"https://github.com/foo/bar"}, testName)
135141

@@ -143,8 +149,9 @@ index cff484d..38e11d8 100644
143149
-https://github.com/arduino-libraries/Ethernet
144150
`)
145151

146-
requestType, arduinoLintLibraryManagerSetting, submissionURLs = parseDiff(diff, "repositories.txt")
152+
requestType, requestError, arduinoLintLibraryManagerSetting, submissionURLs = parseDiff(diff, "repositories.txt")
147153
assert.Equal(t, "removal", requestType, testName)
154+
assert.Equal(t, "", requestError, testName)
148155
assert.Equal(t, "", arduinoLintLibraryManagerSetting, testName)
149156
assert.Nil(t, submissionURLs, testName)
150157

@@ -159,8 +166,9 @@ index cff484d..8b401a1 100644
159166
+https://github.com/foo/bar
160167
`)
161168

162-
requestType, arduinoLintLibraryManagerSetting, submissionURLs = parseDiff(diff, "repositories.txt")
169+
requestType, requestError, arduinoLintLibraryManagerSetting, submissionURLs = parseDiff(diff, "repositories.txt")
163170
assert.Equal(t, "modification", requestType, testName)
171+
assert.Equal(t, "", requestError, testName)
164172
assert.Equal(t, "update", arduinoLintLibraryManagerSetting, testName)
165173
assert.Equal(t, submissionURLs, []string{"https://github.com/foo/bar"}, testName)
166174
}

test/test_all.py

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,16 +21,30 @@
2121

2222

2323
@pytest.mark.parametrize(
24-
"repopath_folder_name, expected_type, expected_submissions, expected_indexentry, expected_indexerlogsurls",
24+
"repopath_folder_name,"
25+
"expected_type,"
26+
"expected_error,"
27+
"expected_submissions,"
28+
"expected_indexentry,"
29+
"expected_indexerlogsurls",
2530
[
26-
("list-deleted-diff", "other", None, "", ""),
27-
("multi-file-diff", "other", None, "", ""),
28-
("non-list-diff", "other", None, "", ""),
29-
("list-rename-diff", "other", None, "", ""),
30-
("removal", "removal", None, "", ""),
31+
("list-deleted-diff", "other", "", None, "", ""),
32+
("multi-file-diff", "other", "", None, "", ""),
33+
("non-list-diff", "other", "", None, "", ""),
34+
("list-rename-diff", "other", "", None, "", ""),
35+
(
36+
"no-final-newline-diff",
37+
"invalid",
38+
"Pull request removes newline from the end of a file.%0APlease add a blank line to the end of the file.",
39+
None,
40+
"",
41+
"",
42+
),
43+
("removal", "removal", "", None, "", ""),
3144
(
3245
"modification",
3346
"modification",
47+
"",
3448
[
3549
{
3650
"submissionURL": "https://github.com/arduino-libraries/ArduinoCloudThing",
@@ -48,6 +62,7 @@
4862
(
4963
"url-error",
5064
"submission",
65+
"",
5166
[
5267
{
5368
"submissionURL": "foo",
@@ -65,6 +80,7 @@
6580
(
6681
"url-404",
6782
"submission",
83+
"",
6884
[
6985
{
7086
"submissionURL": "http://httpstat.us/404",
@@ -82,6 +98,7 @@
8298
(
8399
"not-supported-git-host",
84100
"submission",
101+
"",
85102
[
86103
{
87104
"submissionURL": "https://example.com",
@@ -101,6 +118,7 @@
101118
(
102119
"not-git-clone-url",
103120
"submission",
121+
"",
104122
[
105123
{
106124
"submissionURL": "https://github.com/arduino-libraries/ArduinoCloudThing/releases",
@@ -119,6 +137,7 @@
119137
(
120138
"already-in-library-manager",
121139
"submission",
140+
"",
122141
[
123142
{
124143
"submissionURL": "https://github.com/arduino-libraries/Servo",
@@ -136,6 +155,7 @@
136155
(
137156
"type-arduino",
138157
"submission",
158+
"",
139159
[
140160
{
141161
"submissionURL": "https://github.com/arduino-libraries/ArduinoCloudThing",
@@ -153,6 +173,7 @@
153173
(
154174
"type-partner",
155175
"submission",
176+
"",
156177
[
157178
{
158179
"submissionURL": "https://github.com/ms-iot/virtual-shields-arduino",
@@ -170,6 +191,7 @@
170191
(
171192
"type-recommended",
172193
"submission",
194+
"",
173195
[
174196
{
175197
"submissionURL": "https://github.com/adafruit/Adafruit_TinyFlash",
@@ -187,6 +209,7 @@
187209
(
188210
"type-contributed",
189211
"submission",
212+
"",
190213
[
191214
{
192215
"submissionURL": "https://github.com/sparkfun/SparkFun_Ublox_Arduino_Library",
@@ -205,6 +228,7 @@
205228
(
206229
"no-tags",
207230
"submission",
231+
"",
208232
[
209233
{
210234
"submissionURL": "https://github.com/arduino/cloud-examples",
@@ -224,6 +248,7 @@
224248
(
225249
"no-library-properties",
226250
"submission",
251+
"",
227252
[
228253
{
229254
"submissionURL": "https://github.com/arduino-libraries/WiFiLink-Firmware",
@@ -242,6 +267,7 @@
242267
(
243268
"duplicates-in-submission",
244269
"submission",
270+
"",
245271
[
246272
{
247273
"submissionURL": "https://github.com/arduino-libraries/ArduinoCloudThing",
@@ -273,6 +299,7 @@ def test_request(
273299
run_command,
274300
repopath_folder_name,
275301
expected_type,
302+
expected_error,
276303
expected_submissions,
277304
expected_indexentry,
278305
expected_indexerlogsurls,
@@ -286,6 +313,7 @@ def test_request(
286313

287314
request = json.loads(result.stdout)
288315
assert request["type"] == expected_type
316+
assert request["error"] == expected_error
289317
assert request["submissions"] == expected_submissions
290318
assert request["indexEntry"] == expected_indexentry
291319
assert request["submissions"] == expected_submissions
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
diff --git a/repositories.txt b/repositories.txt
2+
index c080a7a..dcba162 100644
3+
--- a/repositories.txt
4+
+++ b/repositories.txt
5+
@@ -1,2 +1,3 @@
6+
https://github.com/arduino-libraries/Servo
7+
https://github.com/arduino-libraries/Stepper
8+
+https://github.com/arduino-libraries/ArduinoCloudThing
9+
\ No newline at end of file
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
https://github.com/arduino-libraries/Servo
2+
https://github.com/arduino-libraries/Stepper

0 commit comments

Comments
 (0)