Skip to content

Commit 6b82e86

Browse files
committed
Add rules to check loading of URLs in package index
These rules check whether the various URLs provided in the package index data can be loaded.
1 parent 0047b7a commit 6b82e86

File tree

11 files changed

+547
-13
lines changed

11 files changed

+547
-13
lines changed

Diff for: internal/rule/ruleconfiguration/ruleconfiguration.go

+80
Original file line numberDiff line numberDiff line change
@@ -2921,4 +2921,84 @@ var configurations = []Type{
29212921
ErrorModes: []rulemode.Type{rulemode.Default},
29222922
RuleFunction: rulefunction.PackageIndexFormat,
29232923
},
2924+
{
2925+
ProjectType: projecttype.PackageIndex,
2926+
SuperprojectType: projecttype.All,
2927+
Category: "data",
2928+
Subcategory: "package",
2929+
ID: "ID003",
2930+
Brief: "dead packages[].websiteURL",
2931+
Description: "",
2932+
MessageTemplate: "Unable to load the packages[].websiteURL URL for package(s): {{.}}",
2933+
DisableModes: nil,
2934+
EnableModes: []rulemode.Type{rulemode.Default},
2935+
InfoModes: nil,
2936+
WarningModes: []rulemode.Type{rulemode.Permissive},
2937+
ErrorModes: []rulemode.Type{rulemode.Default},
2938+
RuleFunction: rulefunction.PackageIndexPackagesWebsiteURLDeadLink,
2939+
},
2940+
{
2941+
ProjectType: projecttype.PackageIndex,
2942+
SuperprojectType: projecttype.All,
2943+
Category: "data",
2944+
Subcategory: "package",
2945+
ID: "ID004",
2946+
Brief: "dead packages[].help.online",
2947+
Description: "",
2948+
MessageTemplate: "Unable to load the packages[].help.online URL for package(s): {{.}}",
2949+
DisableModes: nil,
2950+
EnableModes: []rulemode.Type{rulemode.Default},
2951+
InfoModes: nil,
2952+
WarningModes: []rulemode.Type{rulemode.Permissive},
2953+
ErrorModes: []rulemode.Type{rulemode.Default},
2954+
RuleFunction: rulefunction.PackageIndexPackagesHelpOnlineDeadLink,
2955+
},
2956+
{
2957+
ProjectType: projecttype.PackageIndex,
2958+
SuperprojectType: projecttype.All,
2959+
Category: "data",
2960+
Subcategory: "platform",
2961+
ID: "ID005",
2962+
Brief: "dead packages[].platforms[].help.online",
2963+
Description: "",
2964+
MessageTemplate: "Unable to load the packages[].platforms[].help.online URL for platforms(s): {{.}}",
2965+
DisableModes: nil,
2966+
EnableModes: []rulemode.Type{rulemode.Default},
2967+
InfoModes: nil,
2968+
WarningModes: []rulemode.Type{rulemode.Permissive},
2969+
ErrorModes: []rulemode.Type{rulemode.Default},
2970+
RuleFunction: rulefunction.PackageIndexPackagesPlatformsHelpOnlineDeadLink,
2971+
},
2972+
{
2973+
ProjectType: projecttype.PackageIndex,
2974+
SuperprojectType: projecttype.All,
2975+
Category: "data",
2976+
Subcategory: "platform",
2977+
ID: "ID006",
2978+
Brief: "dead packages[].platforms[].url",
2979+
Description: "",
2980+
MessageTemplate: "Unable to load the packages[].platforms[].url URL for platforms(s): {{.}}",
2981+
DisableModes: nil,
2982+
EnableModes: []rulemode.Type{rulemode.Default},
2983+
InfoModes: nil,
2984+
WarningModes: []rulemode.Type{rulemode.Permissive},
2985+
ErrorModes: []rulemode.Type{rulemode.Default},
2986+
RuleFunction: rulefunction.PackageIndexPackagesPlatformsURLDeadLink,
2987+
},
2988+
{
2989+
ProjectType: projecttype.PackageIndex,
2990+
SuperprojectType: projecttype.All,
2991+
Category: "data",
2992+
Subcategory: "tool",
2993+
ID: "ID007",
2994+
Brief: "dead packages[].tools[].systems[].url",
2995+
Description: "",
2996+
MessageTemplate: "Unable to load the packages[].tools[].systems[].url URL for tools(s): {{.}}",
2997+
DisableModes: nil,
2998+
EnableModes: []rulemode.Type{rulemode.Default},
2999+
InfoModes: nil,
3000+
WarningModes: []rulemode.Type{rulemode.Permissive},
3001+
ErrorModes: []rulemode.Type{rulemode.Default},
3002+
RuleFunction: rulefunction.PackageIndexPackagesToolsSystemsURLDeadLink,
3003+
},
29243004
}

Diff for: internal/rule/rulefunction/packageindex.go

+167
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
package rulefunction
1717

1818
import (
19+
"strings"
20+
1921
"github.com/arduino/arduino-lint/internal/project/packageindex"
2022
"github.com/arduino/arduino-lint/internal/project/projectdata"
2123
"github.com/arduino/arduino-lint/internal/rule/ruleresult"
@@ -83,3 +85,168 @@ func PackageIndexFormat() (result ruleresult.Type, output string) {
8385

8486
return ruleresult.Pass, ""
8587
}
88+
89+
// PackageIndexPackagesWebsiteURLDeadLink checks for dead links in packages[].websiteURL.
90+
func PackageIndexPackagesWebsiteURLDeadLink() (result ruleresult.Type, output string) {
91+
if projectdata.PackageIndexLoadError() != nil {
92+
return ruleresult.NotRun, "Error loading package index"
93+
}
94+
95+
nonCompliantIDs := []string{}
96+
for _, data := range projectdata.PackageIndexPackages() {
97+
url, ok := data.Object["websiteURL"].(string)
98+
if !ok {
99+
continue
100+
}
101+
102+
if url == "" {
103+
continue
104+
}
105+
106+
if checkURL(url) == nil {
107+
continue
108+
}
109+
110+
nonCompliantIDs = append(nonCompliantIDs, data.ID)
111+
}
112+
113+
if len(nonCompliantIDs) > 0 {
114+
return ruleresult.Fail, strings.Join(nonCompliantIDs, ", ")
115+
}
116+
117+
return ruleresult.Pass, ""
118+
}
119+
120+
// PackageIndexPackagesHelpOnlineDeadLink checks for dead links in packages[].help.online.
121+
func PackageIndexPackagesHelpOnlineDeadLink() (result ruleresult.Type, output string) {
122+
if projectdata.PackageIndexLoadError() != nil {
123+
return ruleresult.NotRun, "Error loading package index"
124+
}
125+
126+
nonCompliantIDs := []string{}
127+
for _, data := range projectdata.PackageIndexPackages() {
128+
help, ok := data.Object["help"].(map[string]interface{})
129+
if !ok {
130+
continue
131+
}
132+
133+
url, ok := help["online"].(string)
134+
if !ok {
135+
continue
136+
}
137+
138+
if url == "" {
139+
continue
140+
}
141+
142+
if checkURL(url) == nil {
143+
continue
144+
}
145+
146+
nonCompliantIDs = append(nonCompliantIDs, data.ID)
147+
}
148+
149+
if len(nonCompliantIDs) > 0 {
150+
return ruleresult.Fail, strings.Join(nonCompliantIDs, ", ")
151+
}
152+
153+
return ruleresult.Pass, ""
154+
}
155+
156+
// PackageIndexPackagesPlatformsHelpOnlineDeadLink checks for dead links in packages[].platforms[].help.online.
157+
func PackageIndexPackagesPlatformsHelpOnlineDeadLink() (result ruleresult.Type, output string) {
158+
if projectdata.PackageIndexLoadError() != nil {
159+
return ruleresult.NotRun, "Error loading package index"
160+
}
161+
162+
nonCompliantIDs := []string{}
163+
for _, data := range projectdata.PackageIndexPlatforms() {
164+
help, ok := data.Object["help"].(map[string]interface{})
165+
if !ok {
166+
continue
167+
}
168+
169+
url, ok := help["online"].(string)
170+
if !ok {
171+
continue
172+
}
173+
174+
if url == "" {
175+
continue
176+
}
177+
178+
if checkURL(url) == nil {
179+
continue
180+
}
181+
182+
nonCompliantIDs = append(nonCompliantIDs, data.ID)
183+
}
184+
185+
if len(nonCompliantIDs) > 0 {
186+
return ruleresult.Fail, strings.Join(nonCompliantIDs, ", ")
187+
}
188+
189+
return ruleresult.Pass, ""
190+
}
191+
192+
// PackageIndexPackagesPlatformsURLDeadLink checks for dead links in packages[].platforms[].url.
193+
func PackageIndexPackagesPlatformsURLDeadLink() (result ruleresult.Type, output string) {
194+
if projectdata.PackageIndexLoadError() != nil {
195+
return ruleresult.NotRun, "Error loading package index"
196+
}
197+
198+
nonCompliantIDs := []string{}
199+
for _, data := range projectdata.PackageIndexPlatforms() {
200+
url, ok := data.Object["url"].(string)
201+
if !ok {
202+
continue
203+
}
204+
205+
if url == "" {
206+
continue
207+
}
208+
209+
if checkURL(url) == nil {
210+
continue
211+
}
212+
213+
nonCompliantIDs = append(nonCompliantIDs, data.ID)
214+
}
215+
216+
if len(nonCompliantIDs) > 0 {
217+
return ruleresult.Fail, strings.Join(nonCompliantIDs, ", ")
218+
}
219+
220+
return ruleresult.Pass, ""
221+
}
222+
223+
// PackageIndexPackagesToolsSystemsURLDeadLink checks for dead links in packages[].tools[].systems[].url.
224+
func PackageIndexPackagesToolsSystemsURLDeadLink() (result ruleresult.Type, output string) {
225+
if projectdata.PackageIndexLoadError() != nil {
226+
return ruleresult.NotRun, "Error loading package index"
227+
}
228+
229+
nonCompliantIDs := []string{}
230+
for _, data := range projectdata.PackageIndexSystems() {
231+
url, ok := data.Object["url"].(string)
232+
if !ok {
233+
continue
234+
}
235+
236+
if url == "" {
237+
continue
238+
}
239+
240+
if checkURL(url) == nil {
241+
continue
242+
}
243+
244+
nonCompliantIDs = append(nonCompliantIDs, data.ID)
245+
}
246+
247+
if len(nonCompliantIDs) > 0 {
248+
return ruleresult.Fail, strings.Join(nonCompliantIDs, ", ")
249+
}
250+
251+
return ruleresult.Pass, ""
252+
}

Diff for: internal/rule/rulefunction/packageindex_test.go

+51
Original file line numberDiff line numberDiff line change
@@ -110,3 +110,54 @@ func TestPackageIndexFormat(t *testing.T) {
110110

111111
checkPackageIndexRuleFunction(PackageIndexFormat, testTables, t)
112112
}
113+
114+
func TestPackageIndexPackagesWebsiteURLDeadLink(t *testing.T) {
115+
testTables := []packageIndexRuleFunctionTestTable{
116+
{"Invalid JSON", "invalid-JSON", ruleresult.NotRun, ""},
117+
{"Dead URLs", "packages-websiteurl-dead", ruleresult.Fail, "^myboard1, myboard2$"},
118+
{"Invalid URL", "packages-websiteurl-invalid", ruleresult.Fail, "^myboard$"},
119+
{"Valid URL", "valid-package-index", ruleresult.Pass, ""},
120+
}
121+
122+
checkPackageIndexRuleFunction(PackageIndexPackagesWebsiteURLDeadLink, testTables, t)
123+
}
124+
125+
func TestPackageIndexPackagesHelpOnlineDeadLink(t *testing.T) {
126+
testTables := []packageIndexRuleFunctionTestTable{
127+
{"Invalid JSON", "invalid-JSON", ruleresult.NotRun, ""},
128+
{"Dead URLs", "packages-help-online-dead", ruleresult.Fail, "^myboard1, myboard2$"},
129+
{"Valid URL", "valid-package-index", ruleresult.Pass, ""},
130+
}
131+
132+
checkPackageIndexRuleFunction(PackageIndexPackagesHelpOnlineDeadLink, testTables, t)
133+
}
134+
135+
func TestPackageIndexPackagesPlatformsHelpOnlineDeadLink(t *testing.T) {
136+
testTables := []packageIndexRuleFunctionTestTable{
137+
{"Invalid JSON", "invalid-JSON", ruleresult.NotRun, ""},
138+
{"Dead URLs", "packages-platforms-help-online-dead", ruleresult.Fail, "^myboard:avr@1\\.0\\.0, myboard:samd@1\\.0\\.0$"},
139+
{"Valid URL", "valid-package-index", ruleresult.Pass, ""},
140+
}
141+
142+
checkPackageIndexRuleFunction(PackageIndexPackagesPlatformsHelpOnlineDeadLink, testTables, t)
143+
}
144+
145+
func TestPackageIndexPackagesPlatformsURLDeadLink(t *testing.T) {
146+
testTables := []packageIndexRuleFunctionTestTable{
147+
{"Invalid JSON", "invalid-JSON", ruleresult.NotRun, ""},
148+
{"Dead URLs", "packages-platforms-url-dead", ruleresult.Fail, "^myboard:avr@1\\.0\\.0, myboard:samd@1\\.0\\.0$"},
149+
{"Valid URL", "valid-package-index", ruleresult.Pass, ""},
150+
}
151+
152+
checkPackageIndexRuleFunction(PackageIndexPackagesPlatformsURLDeadLink, testTables, t)
153+
}
154+
155+
func TestPackageIndexPackagesToolsSystemsURLDeadLink(t *testing.T) {
156+
testTables := []packageIndexRuleFunctionTestTable{
157+
{"Invalid JSON", "invalid-JSON", ruleresult.NotRun, ""},
158+
{"Dead URLs", "packages-tools-systems-url-dead", ruleresult.Fail, "^myboard:CMSIS@4\\.0\\.0-atmel - arm-linux-gnueabihf, myboard:CMSIS@4\\.0\\.0-atmel - i686-mingw32$"},
159+
{"Valid URL", "valid-package-index", ruleresult.Pass, ""},
160+
}
161+
162+
checkPackageIndexRuleFunction(PackageIndexPackagesToolsSystemsURLDeadLink, testTables, t)
163+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{
2+
"packages": [
3+
{
4+
"name": "myboard1",
5+
"maintainer": "Jane Developer",
6+
"websiteURL": "http://example.com",
7+
"email": "[email protected]",
8+
"help": {
9+
"online": "http://httpstat.us/403"
10+
},
11+
"platforms": [],
12+
"tools": []
13+
},
14+
{
15+
"name": "myboard2",
16+
"maintainer": "Jane Developer",
17+
"websiteURL": "http://example.com",
18+
"email": "[email protected]",
19+
"help": {
20+
"online": "http://httpstat.us/404"
21+
},
22+
"platforms": [],
23+
"tools": []
24+
}
25+
]
26+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
{
2+
"packages": [
3+
{
4+
"name": "myboard",
5+
"maintainer": "Jane Developer",
6+
"websiteURL": "http://example.com",
7+
"email": "[email protected]",
8+
"help": {
9+
"online": "http://example.com"
10+
},
11+
"platforms": [
12+
{
13+
"name": "My AVR Board",
14+
"architecture": "avr",
15+
"version": "1.0.0",
16+
"category": "Contributed",
17+
"help": {
18+
"online": "http://httpstat.us/403"
19+
},
20+
"url": "https://janedeveloper.github.io/myboard/myboard-1.0.0.zip",
21+
"archiveFileName": "myboard-1.0.0.zip",
22+
"checksum": "SHA-256:ec3ff8a1dc96d3ba6f432b9b837a35fd4174a34b3d2927de1d51010e8b94f9f1",
23+
"size": "15005",
24+
"boards": [],
25+
"toolsDependencies": []
26+
},
27+
{
28+
"name": "My SAMD Board",
29+
"architecture": "samd",
30+
"version": "1.0.0",
31+
"category": "Contributed",
32+
"help": {
33+
"online": "http://httpstat.us/404"
34+
},
35+
"url": "https://janedeveloper.github.io/myboard/myboard-1.0.0.zip",
36+
"archiveFileName": "myboard-1.0.0.zip",
37+
"checksum": "SHA-256:ec3ff8a1dc96d3ba6f432b9b837a35fd4174a34b3d2927de1d51010e8b94f9f1",
38+
"size": "15005",
39+
"boards": [],
40+
"toolsDependencies": []
41+
}
42+
],
43+
"tools": []
44+
}
45+
]
46+
}

0 commit comments

Comments
 (0)