From b24f9e2e9ba5c43b600af905e74fb70c8cf42967 Mon Sep 17 00:00:00 2001 From: per1234 Date: Sun, 6 Jun 2021 14:22:59 -0700 Subject: [PATCH] Add rules for checking package index filename The package index filename must follow a specific format. Package indexes which are not compliant are ignored by the Arduino development software. Only the official package index may be named package_index.json. --- .../ruleconfiguration/ruleconfiguration.go | 32 ++++++++++++ internal/rule/rulefunction/packageindex.go | 27 ++++++++++ .../rule/rulefunction/packageindex_test.go | 22 ++++++++ .../package_3rd-party_index.json | 51 +++++++++++++++++++ .../invalid-filename/invalid-filename.json | 51 +++++++++++++++++++ .../official-filename/package_index.json | 51 +++++++++++++++++++ 6 files changed, 234 insertions(+) create mode 100644 internal/rule/rulefunction/testdata/packageindexes/3rd-party-filename/package_3rd-party_index.json create mode 100644 internal/rule/rulefunction/testdata/packageindexes/invalid-filename/invalid-filename.json create mode 100644 internal/rule/rulefunction/testdata/packageindexes/official-filename/package_index.json diff --git a/internal/rule/ruleconfiguration/ruleconfiguration.go b/internal/rule/ruleconfiguration/ruleconfiguration.go index 208aa9f9..c8a95daf 100644 --- a/internal/rule/ruleconfiguration/ruleconfiguration.go +++ b/internal/rule/ruleconfiguration/ruleconfiguration.go @@ -2857,6 +2857,38 @@ var configurations = []Type{ ErrorModes: []rulemode.Type{rulemode.Default}, RuleFunction: rulefunction.PackageIndexMissing, }, + { + ProjectType: projecttype.PackageIndex, + SuperprojectType: projecttype.All, + Category: "data", + Subcategory: "general", + ID: "IS002", + Brief: "invalid filename", + Description: "", + MessageTemplate: "Invalid package index filename {{.}}. See: https://arduino.github.io/arduino-cli/latest/package_index_json-specification/", + DisableModes: []rulemode.Type{rulemode.Official}, + EnableModes: []rulemode.Type{rulemode.Default}, + InfoModes: nil, + WarningModes: nil, + ErrorModes: []rulemode.Type{rulemode.Default}, + RuleFunction: rulefunction.PackageIndexFilenameInvalid, + }, + { + ProjectType: projecttype.PackageIndex, + SuperprojectType: projecttype.All, + Category: "data", + Subcategory: "general", + ID: "IS003", + Brief: "invalid official filename", + Description: "", + MessageTemplate: "Invalid official package index filename {{.}}. See: https://arduino.github.io/arduino-cli/latest/package_index_json-specification/", + DisableModes: []rulemode.Type{rulemode.Default}, + EnableModes: []rulemode.Type{rulemode.Official}, + InfoModes: nil, + WarningModes: nil, + ErrorModes: []rulemode.Type{rulemode.Default}, + RuleFunction: rulefunction.PackageIndexOfficialFilenameInvalid, + }, { ProjectType: projecttype.PackageIndex, SuperprojectType: projecttype.All, diff --git a/internal/rule/rulefunction/packageindex.go b/internal/rule/rulefunction/packageindex.go index 13fe707c..a112c012 100644 --- a/internal/rule/rulefunction/packageindex.go +++ b/internal/rule/rulefunction/packageindex.go @@ -16,6 +16,7 @@ package rulefunction import ( + "github.com/arduino/arduino-lint/internal/project/packageindex" "github.com/arduino/arduino-lint/internal/project/projectdata" "github.com/arduino/arduino-lint/internal/rule/ruleresult" ) @@ -31,6 +32,32 @@ func PackageIndexMissing() (result ruleresult.Type, output string) { return ruleresult.Pass, "" } +// PackageIndexFilenameInvalid checks whether the package index's filename is valid for 3rd party projects. +func PackageIndexFilenameInvalid() (result ruleresult.Type, output string) { + if projectdata.ProjectPath() == nil { + return ruleresult.NotRun, "Package index not found" + } + + if packageindex.HasValidFilename(projectdata.ProjectPath(), false) { + return ruleresult.Pass, "" + } + + return ruleresult.Fail, projectdata.ProjectPath().Base() +} + +// PackageIndexOfficialFilenameInvalid checks whether the package index's filename is valid for official projects. +func PackageIndexOfficialFilenameInvalid() (result ruleresult.Type, output string) { + if projectdata.ProjectPath() == nil { + return ruleresult.NotRun, "Package index not found" + } + + if packageindex.HasValidFilename(projectdata.ProjectPath(), true) { + return ruleresult.Pass, "" + } + + return ruleresult.Fail, projectdata.ProjectPath().Base() +} + // PackageIndexJSONFormat checks whether the package index file is a valid JSON document. func PackageIndexJSONFormat() (result ruleresult.Type, output string) { if projectdata.ProjectPath() == nil { diff --git a/internal/rule/rulefunction/packageindex_test.go b/internal/rule/rulefunction/packageindex_test.go index 74868de6..e2f17022 100644 --- a/internal/rule/rulefunction/packageindex_test.go +++ b/internal/rule/rulefunction/packageindex_test.go @@ -69,6 +69,28 @@ func TestPackageIndexMissing(t *testing.T) { checkPackageIndexRuleFunction(PackageIndexMissing, testTables, t) } +func TestPackageIndexFilenameInvalid(t *testing.T) { + testTables := []packageIndexRuleFunctionTestTable{ + {"Missing", "missing", ruleresult.NotRun, ""}, + {"Valid 3rd party", "3rd-party-filename", ruleresult.Pass, ""}, + {"Valid official", "official-filename", ruleresult.Fail, "^package_index.json$"}, + {"Invalid", "invalid-filename", ruleresult.Fail, "^invalid-filename.json$"}, + } + + checkPackageIndexRuleFunction(PackageIndexFilenameInvalid, testTables, t) +} + +func TestPackageIndexOfficialFilenameInvalid(t *testing.T) { + testTables := []packageIndexRuleFunctionTestTable{ + {"Missing", "missing", ruleresult.NotRun, ""}, + {"Valid 3rd party", "3rd-party-filename", ruleresult.Pass, ""}, + {"Valid official", "official-filename", ruleresult.Pass, ""}, + {"Invalid", "invalid-filename", ruleresult.Fail, "^invalid-filename.json$"}, + } + + checkPackageIndexRuleFunction(PackageIndexOfficialFilenameInvalid, testTables, t) +} + func TestPackageIndexJSONFormat(t *testing.T) { testTables := []packageIndexRuleFunctionTestTable{ {"Invalid JSON", "invalid-JSON", ruleresult.Fail, ""}, diff --git a/internal/rule/rulefunction/testdata/packageindexes/3rd-party-filename/package_3rd-party_index.json b/internal/rule/rulefunction/testdata/packageindexes/3rd-party-filename/package_3rd-party_index.json new file mode 100644 index 00000000..7938a2aa --- /dev/null +++ b/internal/rule/rulefunction/testdata/packageindexes/3rd-party-filename/package_3rd-party_index.json @@ -0,0 +1,51 @@ +{ + "packages": [ + { + "name": "notarduino", + "maintainer": "NotArduino", + "websiteURL": "http://www.arduino.cc/", + "email": "packages@arduino.cc", + "help": { + "online": "http://www.arduino.cc/en/Reference/HomePage" + }, + "platforms": [ + { + "name": "Arduino AVR Boards", + "architecture": "avr", + "version": "1.8.3", + "category": "Contributed", + "help": { + "online": "http://www.arduino.cc/en/Reference/HomePage" + }, + "url": "http://downloads.arduino.cc/cores/avr-1.8.3.tar.bz2", + "archiveFileName": "avr-1.8.3.tar.bz2", + "checksum": "SHA-256:de8a9b982477762d3d3e52fc2b682cdd8ff194dc3f1d46f4debdea6a01b33c14", + "size": "4941548", + "boards": [{ "name": "Arduino Uno" }], + "toolsDependencies": [ + { + "packager": "arduino", + "name": "avr-gcc", + "version": "7.3.0-atmel3.6.1-arduino7" + } + ] + } + ], + "tools": [ + { + "name": "avr-gcc", + "version": "7.3.0-atmel3.6.1-arduino7", + "systems": [ + { + "size": "34683056", + "checksum": "SHA-256:3903553d035da59e33cff9941b857c3cb379cb0638105dfdf69c97f0acc8e7b5", + "host": "arm-linux-gnueabihf", + "archiveFileName": "avr-gcc-7.3.0-atmel3.6.1-arduino7-arm-linux-gnueabihf.tar.bz2", + "url": "http://downloads.arduino.cc/tools/avr-gcc-7.3.0-atmel3.6.1-arduino7-arm-linux-gnueabihf.tar.bz2" + } + ] + } + ] + } + ] +} diff --git a/internal/rule/rulefunction/testdata/packageindexes/invalid-filename/invalid-filename.json b/internal/rule/rulefunction/testdata/packageindexes/invalid-filename/invalid-filename.json new file mode 100644 index 00000000..7938a2aa --- /dev/null +++ b/internal/rule/rulefunction/testdata/packageindexes/invalid-filename/invalid-filename.json @@ -0,0 +1,51 @@ +{ + "packages": [ + { + "name": "notarduino", + "maintainer": "NotArduino", + "websiteURL": "http://www.arduino.cc/", + "email": "packages@arduino.cc", + "help": { + "online": "http://www.arduino.cc/en/Reference/HomePage" + }, + "platforms": [ + { + "name": "Arduino AVR Boards", + "architecture": "avr", + "version": "1.8.3", + "category": "Contributed", + "help": { + "online": "http://www.arduino.cc/en/Reference/HomePage" + }, + "url": "http://downloads.arduino.cc/cores/avr-1.8.3.tar.bz2", + "archiveFileName": "avr-1.8.3.tar.bz2", + "checksum": "SHA-256:de8a9b982477762d3d3e52fc2b682cdd8ff194dc3f1d46f4debdea6a01b33c14", + "size": "4941548", + "boards": [{ "name": "Arduino Uno" }], + "toolsDependencies": [ + { + "packager": "arduino", + "name": "avr-gcc", + "version": "7.3.0-atmel3.6.1-arduino7" + } + ] + } + ], + "tools": [ + { + "name": "avr-gcc", + "version": "7.3.0-atmel3.6.1-arduino7", + "systems": [ + { + "size": "34683056", + "checksum": "SHA-256:3903553d035da59e33cff9941b857c3cb379cb0638105dfdf69c97f0acc8e7b5", + "host": "arm-linux-gnueabihf", + "archiveFileName": "avr-gcc-7.3.0-atmel3.6.1-arduino7-arm-linux-gnueabihf.tar.bz2", + "url": "http://downloads.arduino.cc/tools/avr-gcc-7.3.0-atmel3.6.1-arduino7-arm-linux-gnueabihf.tar.bz2" + } + ] + } + ] + } + ] +} diff --git a/internal/rule/rulefunction/testdata/packageindexes/official-filename/package_index.json b/internal/rule/rulefunction/testdata/packageindexes/official-filename/package_index.json new file mode 100644 index 00000000..b8a62038 --- /dev/null +++ b/internal/rule/rulefunction/testdata/packageindexes/official-filename/package_index.json @@ -0,0 +1,51 @@ +{ + "packages": [ + { + "name": "arduino", + "maintainer": "Arduino", + "websiteURL": "http://www.arduino.cc/", + "email": "packages@arduino.cc", + "help": { + "online": "http://www.arduino.cc/en/Reference/HomePage" + }, + "platforms": [ + { + "name": "Arduino AVR Boards", + "architecture": "avr", + "version": "1.8.3", + "category": "Arduino", + "help": { + "online": "http://www.arduino.cc/en/Reference/HomePage" + }, + "url": "http://downloads.arduino.cc/cores/avr-1.8.3.tar.bz2", + "archiveFileName": "avr-1.8.3.tar.bz2", + "checksum": "SHA-256:de8a9b982477762d3d3e52fc2b682cdd8ff194dc3f1d46f4debdea6a01b33c14", + "size": "4941548", + "boards": [{ "name": "Arduino Uno" }], + "toolsDependencies": [ + { + "packager": "arduino", + "name": "avr-gcc", + "version": "7.3.0-atmel3.6.1-arduino7" + } + ] + } + ], + "tools": [ + { + "name": "avr-gcc", + "version": "7.3.0-atmel3.6.1-arduino7", + "systems": [ + { + "size": "34683056", + "checksum": "SHA-256:3903553d035da59e33cff9941b857c3cb379cb0638105dfdf69c97f0acc8e7b5", + "host": "arm-linux-gnueabihf", + "archiveFileName": "avr-gcc-7.3.0-atmel3.6.1-arduino7-arm-linux-gnueabihf.tar.bz2", + "url": "http://downloads.arduino.cc/tools/avr-gcc-7.3.0-atmel3.6.1-arduino7-arm-linux-gnueabihf.tar.bz2" + } + ] + } + ] + } + ] +}