From 40976a08dff1d2ef277617c2579bf8878ae67283 Mon Sep 17 00:00:00 2001 From: per1234 Date: Wed, 2 Dec 2020 14:21:17 -0800 Subject: [PATCH 1/8] Correct check configurations Some of the checks were incorrectly configured. --- check/checkconfigurations/checkconfigurations.go | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/check/checkconfigurations/checkconfigurations.go b/check/checkconfigurations/checkconfigurations.go index 6a00e3b9..5c2d1e6e 100644 --- a/check/checkconfigurations/checkconfigurations.go +++ b/check/checkconfigurations/checkconfigurations.go @@ -97,8 +97,8 @@ var configurations = []Type{ DisableModes: nil, EnableModes: []checkmode.Type{checkmode.Default}, InfoModes: nil, - WarningModes: []checkmode.Type{checkmode.Permissive}, - ErrorModes: []checkmode.Type{checkmode.Default}, + WarningModes: []checkmode.Type{checkmode.Default}, + ErrorModes: []checkmode.Type{checkmode.Strict}, CheckFunction: checkfunctions.MisspelledLibraryPropertiesFileName, }, { @@ -232,8 +232,8 @@ var configurations = []Type{ DisableModes: []checkmode.Type{checkmode.Official}, EnableModes: []checkmode.Type{checkmode.Default}, InfoModes: nil, - WarningModes: []checkmode.Type{checkmode.Permissive}, - ErrorModes: []checkmode.Type{checkmode.Default}, + WarningModes: []checkmode.Type{checkmode.Default}, + ErrorModes: []checkmode.Type{checkmode.LibraryManagerSubmission, checkmode.Strict}, CheckFunction: checkfunctions.LibraryPropertiesNameFieldStartsWithArduino, }, { @@ -247,8 +247,8 @@ var configurations = []Type{ DisableModes: []checkmode.Type{checkmode.Default}, EnableModes: []checkmode.Type{checkmode.Official}, InfoModes: nil, - WarningModes: nil, - ErrorModes: []checkmode.Type{checkmode.Official}, + WarningModes: []checkmode.Type{checkmode.Default}, + ErrorModes: []checkmode.Type{checkmode.Strict}, CheckFunction: checkfunctions.LibraryPropertiesNameFieldMissingOfficialPrefix, }, { @@ -1102,8 +1102,8 @@ var configurations = []Type{ DisableModes: nil, EnableModes: []checkmode.Type{checkmode.Default}, InfoModes: nil, - WarningModes: []checkmode.Type{checkmode.Default}, - ErrorModes: []checkmode.Type{checkmode.Strict}, + WarningModes: []checkmode.Type{checkmode.Permissive}, + ErrorModes: []checkmode.Type{checkmode.Default}, CheckFunction: checkfunctions.IncorrectSketchSrcFolderNameCase, }, { From ea3639b0de3e7f7a983ea9c9576f498c7029408b Mon Sep 17 00:00:00 2001 From: per1234 Date: Thu, 3 Dec 2020 04:09:17 -0800 Subject: [PATCH 2/8] Show value in message of name's disallowed characters check This will make it more clear to the user which think the error message is referring to. --- check/checkconfigurations/checkconfigurations.go | 2 +- check/checkfunctions/library.go | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/check/checkconfigurations/checkconfigurations.go b/check/checkconfigurations/checkconfigurations.go index 5c2d1e6e..e10ca900 100644 --- a/check/checkconfigurations/checkconfigurations.go +++ b/check/checkconfigurations/checkconfigurations.go @@ -198,7 +198,7 @@ var configurations = []Type{ ID: "LP003", Brief: "disallowed characters", Description: "", - MessageTemplate: "disallowed characters in library.properties name field. See: https://arduino.github.io/arduino-cli/latest/library-specification/#libraryproperties-file-format", + MessageTemplate: "disallowed characters in library.properties name value: {{.}}. See: https://arduino.github.io/arduino-cli/latest/library-specification/#libraryproperties-file-format", DisableModes: nil, EnableModes: []checkmode.Type{checkmode.Default}, InfoModes: nil, diff --git a/check/checkfunctions/library.go b/check/checkfunctions/library.go index 1b91d315..c6dac6c8 100644 --- a/check/checkfunctions/library.go +++ b/check/checkfunctions/library.go @@ -175,8 +175,13 @@ func LibraryPropertiesNameFieldDisallowedCharacters() (result checkresult.Type, return checkresult.NotRun, "" } + name, ok := checkdata.LibraryProperties().GetOk("name") + if !ok { + return checkresult.NotRun, "name not defined" + } + if schema.PropertyPatternMismatch("name", checkdata.LibraryPropertiesSchemaValidationResult()[compliancelevel.Specification], configuration.SchemasPath()) { - return checkresult.Fail, "" + return checkresult.Fail, name } return checkresult.Pass, "" From 3b8f69a0adc98c7a8b0db1b481be5eb2e826baed Mon Sep 17 00:00:00 2001 From: per1234 Date: Thu, 3 Dec 2020 04:17:55 -0800 Subject: [PATCH 3/8] Add missing templates to src subfolder name case checks The check functions already return this information, but the template was omitted from the error messages. Displaying the actual file name in the error message may help the user to understand the cause of the check failure. --- check/checkconfigurations/checkconfigurations.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/check/checkconfigurations/checkconfigurations.go b/check/checkconfigurations/checkconfigurations.go index e10ca900..06d5ad89 100644 --- a/check/checkconfigurations/checkconfigurations.go +++ b/check/checkconfigurations/checkconfigurations.go @@ -1008,7 +1008,7 @@ var configurations = []Type{ ID: "", Brief: "incorrect src folder case", Description: "", - MessageTemplate: "Incorrect src folder case. This will cause the library to not be recognized on case-sensitive operating systems. See: https://arduino.github.io/arduino-cli/latest/library-specification/#library-root-folder", + MessageTemplate: "Incorrect src folder case: {{.}}. This will cause the library to not be recognized on case-sensitive operating systems. See: https://arduino.github.io/arduino-cli/latest/library-specification/#library-root-folder", DisableModes: nil, EnableModes: []checkmode.Type{checkmode.Default}, InfoModes: nil, @@ -1098,7 +1098,7 @@ var configurations = []Type{ ID: "", Brief: "incorrect src folder case", Description: "", - MessageTemplate: "Incorrect src folder case. This will cause the source files under it to not be compiled on case-sensitive operating systems. See: https://arduino.github.io/arduino-cli/latest/sketch-specification/#src-subfolder", + MessageTemplate: "Incorrect src folder case: {{.}}. This will cause the source files under it to not be compiled on case-sensitive operating systems. See: https://arduino.github.io/arduino-cli/latest/sketch-specification/#src-subfolder", DisableModes: nil, EnableModes: []checkmode.Type{checkmode.Default}, InfoModes: nil, From 8a8c63130491262040c40be42e76ac49e1aeac4a Mon Sep 17 00:00:00 2001 From: per1234 Date: Thu, 3 Dec 2020 09:36:38 -0800 Subject: [PATCH 4/8] Provide reason for not running checks Return an explanatory message when it is impossible to run a check due to the required information being unavailable. Previously, the infrastructure was in place to display this output to the user, but there was no output to display, so you just got a confusing "notice:" output with no notice to follow. --- check/checkfunctions/library.go | 186 +++++++++++++++++--------------- 1 file changed, 97 insertions(+), 89 deletions(-) diff --git a/check/checkfunctions/library.go b/check/checkfunctions/library.go index c6dac6c8..3fece099 100644 --- a/check/checkfunctions/library.go +++ b/check/checkfunctions/library.go @@ -39,7 +39,7 @@ import ( // LibraryPropertiesFormat checks for invalid library.properties format. func LibraryPropertiesFormat() (result checkresult.Type, output string) { if checkdata.LoadedLibrary() != nil && checkdata.LoadedLibrary().IsLegacy { - return checkresult.NotRun, "" + return checkresult.NotRun, "Library has no library.properties" } if checkdata.LibraryPropertiesLoadError() != nil { @@ -52,7 +52,7 @@ func LibraryPropertiesFormat() (result checkresult.Type, output string) { // LibraryPropertiesMissing checks for presence of library.properties. func LibraryPropertiesMissing() (result checkresult.Type, output string) { if checkdata.LoadedLibrary() == nil { - return checkresult.NotRun, "" + return checkresult.NotRun, "Couldn't load library." } if checkdata.LoadedLibrary().IsLegacy { @@ -107,7 +107,7 @@ func RedundantLibraryProperties() (result checkresult.Type, output string) { // LibraryPropertiesNameFieldMissing checks for missing library.properties "name" field. func LibraryPropertiesNameFieldMissing() (result checkresult.Type, output string) { if checkdata.LibraryPropertiesLoadError() != nil { - return checkresult.NotRun, "" + return checkresult.NotRun, "Couldn't load library.properties" } if schema.RequiredPropertyMissing("name", checkdata.LibraryPropertiesSchemaValidationResult()[compliancelevel.Specification], configuration.SchemasPath()) { @@ -119,11 +119,11 @@ func LibraryPropertiesNameFieldMissing() (result checkresult.Type, output string // LibraryPropertiesNameFieldLTMinLength checks if the library.properties "name" value is less than the minimum length. func LibraryPropertiesNameFieldLTMinLength() (result checkresult.Type, output string) { if checkdata.LibraryPropertiesLoadError() != nil { - return checkresult.NotRun, "" + return checkresult.NotRun, "Couldn't load library.properties" } if !checkdata.LibraryProperties().ContainsKey("name") { - return checkresult.NotRun, "" + return checkresult.NotRun, "Field not present" } if schema.PropertyLessThanMinLength("name", checkdata.LibraryPropertiesSchemaValidationResult()[compliancelevel.Specification], configuration.SchemasPath()) { @@ -136,12 +136,12 @@ func LibraryPropertiesNameFieldLTMinLength() (result checkresult.Type, output st // LibraryPropertiesNameFieldGTMaxLength checks if the library.properties "name" value is greater than the maximum length. func LibraryPropertiesNameFieldGTMaxLength() (result checkresult.Type, output string) { if checkdata.LibraryPropertiesLoadError() != nil { - return checkresult.NotRun, "" + return checkresult.NotRun, "Couldn't load library.properties" } name, ok := checkdata.LibraryProperties().GetOk("name") if !ok { - return checkresult.NotRun, "" + return checkresult.NotRun, "Field not present" } if schema.PropertyGreaterThanMaxLength("name", checkdata.LibraryPropertiesSchemaValidationResult()[compliancelevel.Specification], configuration.SchemasPath()) { @@ -154,12 +154,12 @@ func LibraryPropertiesNameFieldGTMaxLength() (result checkresult.Type, output st // LibraryPropertiesNameFieldGTRecommendedLength checks if the library.properties "name" value is greater than the recommended length. func LibraryPropertiesNameFieldGTRecommendedLength() (result checkresult.Type, output string) { if checkdata.LibraryPropertiesLoadError() != nil { - return checkresult.NotRun, "" + return checkresult.NotRun, "Couldn't load library.properties" } name, ok := checkdata.LibraryProperties().GetOk("name") if !ok { - return checkresult.NotRun, "" + return checkresult.NotRun, "Field not present" } if schema.PropertyGreaterThanMaxLength("name", checkdata.LibraryPropertiesSchemaValidationResult()[compliancelevel.Strict], configuration.SchemasPath()) { @@ -172,12 +172,12 @@ func LibraryPropertiesNameFieldGTRecommendedLength() (result checkresult.Type, o // LibraryPropertiesNameFieldDisallowedCharacters checks for disallowed characters in the library.properties "name" field. func LibraryPropertiesNameFieldDisallowedCharacters() (result checkresult.Type, output string) { if checkdata.LibraryPropertiesLoadError() != nil { - return checkresult.NotRun, "" + return checkresult.NotRun, "Couldn't load library.properties" } name, ok := checkdata.LibraryProperties().GetOk("name") if !ok { - return checkresult.NotRun, "name not defined" + return checkresult.NotRun, "Field not present" } if schema.PropertyPatternMismatch("name", checkdata.LibraryPropertiesSchemaValidationResult()[compliancelevel.Specification], configuration.SchemasPath()) { @@ -190,12 +190,12 @@ func LibraryPropertiesNameFieldDisallowedCharacters() (result checkresult.Type, // LibraryPropertiesNameFieldHasSpaces checks if the library.properties "name" value contains spaces. func LibraryPropertiesNameFieldHasSpaces() (result checkresult.Type, output string) { if checkdata.LibraryPropertiesLoadError() != nil { - return checkresult.NotRun, "" + return checkresult.NotRun, "Couldn't load library.properties" } name, ok := checkdata.LibraryProperties().GetOk("name") if !ok { - return checkresult.NotRun, "" + return checkresult.NotRun, "Field not present" } if schema.ValidationErrorMatch("^#/name$", "/patternObjects/notContainsSpaces", "", "", checkdata.LibraryPropertiesSchemaValidationResult()[compliancelevel.Strict], configuration.SchemasPath()) { @@ -208,12 +208,12 @@ func LibraryPropertiesNameFieldHasSpaces() (result checkresult.Type, output stri // LibraryPropertiesNameFieldStartsWithArduino checks if the library.properties "name" value starts with "Arduino". func LibraryPropertiesNameFieldStartsWithArduino() (result checkresult.Type, output string) { if checkdata.LibraryPropertiesLoadError() != nil { - return checkresult.NotRun, "" + return checkresult.NotRun, "Couldn't load library.properties" } name, ok := checkdata.LibraryProperties().GetOk("name") if !ok { - return checkresult.NotRun, "" + return checkresult.NotRun, "Field not present" } if schema.ValidationErrorMatch("^#/name$", "/patternObjects/notStartsWithArduino", "", "", checkdata.LibraryPropertiesSchemaValidationResult()[compliancelevel.Specification], configuration.SchemasPath()) { @@ -226,12 +226,12 @@ func LibraryPropertiesNameFieldStartsWithArduino() (result checkresult.Type, out // LibraryPropertiesNameFieldMissingOfficialPrefix checks whether the library.properties `name` value uses the prefix required of all new official Arduino libraries. func LibraryPropertiesNameFieldMissingOfficialPrefix() (result checkresult.Type, output string) { if checkdata.LibraryPropertiesLoadError() != nil { - return checkresult.NotRun, "" + return checkresult.NotRun, "Couldn't load library.properties" } name, ok := checkdata.LibraryProperties().GetOk("name") if !ok { - return checkresult.NotRun, "" + return checkresult.NotRun, "Field not present" } if strings.HasPrefix(name, "Arduino_") { @@ -243,12 +243,12 @@ func LibraryPropertiesNameFieldMissingOfficialPrefix() (result checkresult.Type, // LibraryPropertiesNameFieldContainsArduino checks if the library.properties "name" value contains "Arduino". func LibraryPropertiesNameFieldContainsArduino() (result checkresult.Type, output string) { if checkdata.LibraryPropertiesLoadError() != nil { - return checkresult.NotRun, "" + return checkresult.NotRun, "Couldn't load library.properties" } name, ok := checkdata.LibraryProperties().GetOk("name") if !ok { - return checkresult.NotRun, "" + return checkresult.NotRun, "Field not present" } if schema.ValidationErrorMatch("^#/name$", "/patternObjects/notContainsArduino", "", "", checkdata.LibraryPropertiesSchemaValidationResult()[compliancelevel.Strict], configuration.SchemasPath()) { @@ -261,12 +261,12 @@ func LibraryPropertiesNameFieldContainsArduino() (result checkresult.Type, outpu // LibraryPropertiesNameFieldContainsLibrary checks if the library.properties "name" value contains "library". func LibraryPropertiesNameFieldContainsLibrary() (result checkresult.Type, output string) { if checkdata.LibraryPropertiesLoadError() != nil { - return checkresult.NotRun, "" + return checkresult.NotRun, "Couldn't load library.properties" } name, ok := checkdata.LibraryProperties().GetOk("name") if !ok { - return checkresult.NotRun, "" + return checkresult.NotRun, "Field not present" } if schema.ValidationErrorMatch("^#/name$", "/patternObjects/notContainsSuperfluousTerms", "", "", checkdata.LibraryPropertiesSchemaValidationResult()[compliancelevel.Strict], configuration.SchemasPath()) { @@ -279,12 +279,12 @@ func LibraryPropertiesNameFieldContainsLibrary() (result checkresult.Type, outpu // LibraryPropertiesNameFieldDuplicate checks whether there is an existing entry in the Library Manager index using the the library.properties `name` value. func LibraryPropertiesNameFieldDuplicate() (result checkresult.Type, output string) { if checkdata.LibraryPropertiesLoadError() != nil { - return checkresult.NotRun, "" + return checkresult.NotRun, "Couldn't load library.properties" } name, hasName := checkdata.LibraryProperties().GetOk("name") if !hasName { - return checkresult.NotRun, "" + return checkresult.NotRun, "Field not present" } if nameInLibraryManagerIndex(name) { @@ -297,12 +297,12 @@ func LibraryPropertiesNameFieldDuplicate() (result checkresult.Type, output stri // LibraryPropertiesNameFieldNotInIndex checks whether there is no existing entry in the Library Manager index using the the library.properties `name` value. func LibraryPropertiesNameFieldNotInIndex() (result checkresult.Type, output string) { if checkdata.LibraryPropertiesLoadError() != nil { - return checkresult.NotRun, "" + return checkresult.NotRun, "Couldn't load library.properties" } name, hasName := checkdata.LibraryProperties().GetOk("name") if !hasName { - return checkresult.NotRun, "" + return checkresult.NotRun, "Field not present" } if nameInLibraryManagerIndex(name) { @@ -315,12 +315,12 @@ func LibraryPropertiesNameFieldNotInIndex() (result checkresult.Type, output str // LibraryPropertiesNameFieldHeaderMismatch checks whether the filename of one of the library's header files matches the Library Manager installation folder name. func LibraryPropertiesNameFieldHeaderMismatch() (result checkresult.Type, output string) { if checkdata.LibraryPropertiesLoadError() != nil { - return checkresult.NotRun, "" + return checkresult.NotRun, "Couldn't load library.properties" } name, ok := checkdata.LibraryProperties().GetOk("name") if !ok { - return checkresult.NotRun, "" + return checkresult.NotRun, "Field not present" } sanitizedName := utils.SanitizeName(name) @@ -336,7 +336,7 @@ func LibraryPropertiesNameFieldHeaderMismatch() (result checkresult.Type, output // LibraryPropertiesVersionFieldMissing checks for missing library.properties "version" field. func LibraryPropertiesVersionFieldMissing() (result checkresult.Type, output string) { if checkdata.LibraryPropertiesLoadError() != nil { - return checkresult.NotRun, "" + return checkresult.NotRun, "Couldn't load library.properties" } if schema.RequiredPropertyMissing("version", checkdata.LibraryPropertiesSchemaValidationResult()[compliancelevel.Specification], configuration.SchemasPath()) { @@ -348,12 +348,12 @@ func LibraryPropertiesVersionFieldMissing() (result checkresult.Type, output str // LibraryPropertiesVersionFieldNonRelaxedSemver checks whether the library.properties "version" value is "relaxed semver" compliant. func LibraryPropertiesVersionFieldNonRelaxedSemver() (result checkresult.Type, output string) { if checkdata.LibraryPropertiesLoadError() != nil { - return checkresult.NotRun, "" + return checkresult.NotRun, "Couldn't load library.properties" } version, ok := checkdata.LibraryProperties().GetOk("version") if !ok { - return checkresult.NotRun, "" + return checkresult.NotRun, "Field not present" } if schema.PropertyPatternMismatch("version", checkdata.LibraryPropertiesSchemaValidationResult()[compliancelevel.Specification], configuration.SchemasPath()) { @@ -366,12 +366,12 @@ func LibraryPropertiesVersionFieldNonRelaxedSemver() (result checkresult.Type, o // LibraryPropertiesVersionFieldNonSemver checks whether the library.properties "version" value is semver compliant. func LibraryPropertiesVersionFieldNonSemver() (result checkresult.Type, output string) { if checkdata.LibraryPropertiesLoadError() != nil { - return checkresult.NotRun, "" + return checkresult.NotRun, "Couldn't load library.properties" } version, ok := checkdata.LibraryProperties().GetOk("version") if !ok { - return checkresult.NotRun, "" + return checkresult.NotRun, "Field not present" } if schema.PropertyPatternMismatch("version", checkdata.LibraryPropertiesSchemaValidationResult()[compliancelevel.Strict], configuration.SchemasPath()) { @@ -384,7 +384,7 @@ func LibraryPropertiesVersionFieldNonSemver() (result checkresult.Type, output s // LibraryPropertiesAuthorFieldMissing checks for missing library.properties "author" field. func LibraryPropertiesAuthorFieldMissing() (result checkresult.Type, output string) { if checkdata.LibraryPropertiesLoadError() != nil { - return checkresult.NotRun, "" + return checkresult.NotRun, "Couldn't load library.properties" } if schema.RequiredPropertyMissing("author", checkdata.LibraryPropertiesSchemaValidationResult()[compliancelevel.Specification], configuration.SchemasPath()) { @@ -396,11 +396,11 @@ func LibraryPropertiesAuthorFieldMissing() (result checkresult.Type, output stri // LibraryPropertiesAuthorFieldLTMinLength checks if the library.properties "author" value is less than the minimum length. func LibraryPropertiesAuthorFieldLTMinLength() (result checkresult.Type, output string) { if checkdata.LibraryPropertiesLoadError() != nil { - return checkresult.NotRun, "" + return checkresult.NotRun, "Couldn't load library.properties" } if !checkdata.LibraryProperties().ContainsKey("author") { - return checkresult.NotRun, "" + return checkresult.NotRun, "Field not present" } if schema.PropertyLessThanMinLength("author", checkdata.LibraryPropertiesSchemaValidationResult()[compliancelevel.Specification], configuration.SchemasPath()) { @@ -413,7 +413,7 @@ func LibraryPropertiesAuthorFieldLTMinLength() (result checkresult.Type, output // LibraryPropertiesMaintainerFieldMissing checks for missing library.properties "maintainer" field. func LibraryPropertiesMaintainerFieldMissing() (result checkresult.Type, output string) { if checkdata.LibraryPropertiesLoadError() != nil { - return checkresult.NotRun, "" + return checkresult.NotRun, "Couldn't load library.properties" } if schema.RequiredPropertyMissing("maintainer", checkdata.LibraryPropertiesSchemaValidationResult()[compliancelevel.Specification], configuration.SchemasPath()) { @@ -425,11 +425,11 @@ func LibraryPropertiesMaintainerFieldMissing() (result checkresult.Type, output // LibraryPropertiesMaintainerFieldLTMinLength checks if the library.properties "maintainer" value is less than the minimum length. func LibraryPropertiesMaintainerFieldLTMinLength() (result checkresult.Type, output string) { if checkdata.LibraryPropertiesLoadError() != nil { - return checkresult.NotRun, "" + return checkresult.NotRun, "Couldn't load library.properties" } if !checkdata.LibraryProperties().ContainsKey("maintainer") { - return checkresult.NotRun, "" + return checkresult.NotRun, "Field not present" } if schema.PropertyLessThanMinLength("maintainer", checkdata.LibraryPropertiesSchemaValidationResult()[compliancelevel.Specification], configuration.SchemasPath()) { @@ -442,12 +442,12 @@ func LibraryPropertiesMaintainerFieldLTMinLength() (result checkresult.Type, out // LibraryPropertiesMaintainerFieldStartsWithArduino checks if the library.properties "maintainer" value starts with "Arduino". func LibraryPropertiesMaintainerFieldStartsWithArduino() (result checkresult.Type, output string) { if checkdata.LibraryPropertiesLoadError() != nil { - return checkresult.NotRun, "" + return checkresult.NotRun, "Couldn't load library.properties" } maintainer, ok := checkdata.LibraryProperties().GetOk("maintainer") if !ok { - return checkresult.NotRun, "" + return checkresult.NotRun, "Field not present" } if schema.ValidationErrorMatch("^#/maintainer$", "/patternObjects/notStartsWithArduino", "", "", checkdata.LibraryPropertiesSchemaValidationResult()[compliancelevel.Specification], configuration.SchemasPath()) { @@ -460,11 +460,11 @@ func LibraryPropertiesMaintainerFieldStartsWithArduino() (result checkresult.Typ // LibraryPropertiesEmailFieldAsMaintainerAlias checks whether the library.properties "email" field is being used as an alias for the "maintainer" field. func LibraryPropertiesEmailFieldAsMaintainerAlias() (result checkresult.Type, output string) { if checkdata.LibraryPropertiesLoadError() != nil { - return checkresult.NotRun, "" + return checkresult.NotRun, "Couldn't load library.properties" } if !checkdata.LibraryProperties().ContainsKey("email") { - return checkresult.NotRun, "" + return checkresult.NotRun, "Field not present" } if !checkdata.LibraryProperties().ContainsKey("maintainer") { @@ -477,11 +477,11 @@ func LibraryPropertiesEmailFieldAsMaintainerAlias() (result checkresult.Type, ou // LibraryPropertiesEmailFieldLTMinLength checks if the library.properties "email" value is less than the minimum length. func LibraryPropertiesEmailFieldLTMinLength() (result checkresult.Type, output string) { if checkdata.LibraryPropertiesLoadError() != nil { - return checkresult.NotRun, "" + return checkresult.NotRun, "Couldn't load library.properties" } if checkdata.LibraryProperties().ContainsKey("maintainer") || !checkdata.LibraryProperties().ContainsKey("email") { - return checkresult.NotRun, "" + return checkresult.NotRun, "Field not present" } if schema.PropertyLessThanMinLength("email", checkdata.LibraryPropertiesSchemaValidationResult()[compliancelevel.Specification], configuration.SchemasPath()) { @@ -494,16 +494,16 @@ func LibraryPropertiesEmailFieldLTMinLength() (result checkresult.Type, output s // LibraryPropertiesEmailFieldStartsWithArduino checks if the library.properties "email" value starts with "Arduino". func LibraryPropertiesEmailFieldStartsWithArduino() (result checkresult.Type, output string) { if checkdata.LibraryPropertiesLoadError() != nil { - return checkresult.NotRun, "" + return checkresult.NotRun, "Couldn't load library.properties" } if checkdata.LibraryProperties().ContainsKey("maintainer") { - return checkresult.NotRun, "" + return checkresult.NotRun, "Field not present" } email, ok := checkdata.LibraryProperties().GetOk("email") if !ok { - return checkresult.NotRun, "" + return checkresult.NotRun, "Field not present" } if schema.ValidationErrorMatch("^#/email$", "/patternObjects/notStartsWithArduino", "", "", checkdata.LibraryPropertiesSchemaValidationResult()[compliancelevel.Specification], configuration.SchemasPath()) { @@ -516,7 +516,7 @@ func LibraryPropertiesEmailFieldStartsWithArduino() (result checkresult.Type, ou // LibraryPropertiesSentenceFieldMissing checks for missing library.properties "sentence" field. func LibraryPropertiesSentenceFieldMissing() (result checkresult.Type, output string) { if checkdata.LibraryPropertiesLoadError() != nil { - return checkresult.NotRun, "" + return checkresult.NotRun, "Couldn't load library.properties" } if schema.RequiredPropertyMissing("sentence", checkdata.LibraryPropertiesSchemaValidationResult()[compliancelevel.Specification], configuration.SchemasPath()) { @@ -528,11 +528,11 @@ func LibraryPropertiesSentenceFieldMissing() (result checkresult.Type, output st // LibraryPropertiesSentenceFieldLTMinLength checks if the library.properties "sentence" value is less than the minimum length. func LibraryPropertiesSentenceFieldLTMinLength() (result checkresult.Type, output string) { if checkdata.LibraryPropertiesLoadError() != nil { - return checkresult.NotRun, "" + return checkresult.NotRun, "Couldn't load library.properties" } if !checkdata.LibraryProperties().ContainsKey("sentence") { - return checkresult.NotRun, "" + return checkresult.NotRun, "Field not present" } if schema.PropertyLessThanMinLength("sentence", checkdata.LibraryPropertiesSchemaValidationResult()[compliancelevel.Specification], configuration.SchemasPath()) { @@ -550,7 +550,7 @@ func LibraryPropertiesSentenceFieldSpellCheck() (result checkresult.Type, output // LibraryPropertiesParagraphFieldMissing checks for missing library.properties "paragraph" field. func LibraryPropertiesParagraphFieldMissing() (result checkresult.Type, output string) { if checkdata.LibraryPropertiesLoadError() != nil { - return checkresult.NotRun, "" + return checkresult.NotRun, "Couldn't load library.properties" } if schema.RequiredPropertyMissing("paragraph", checkdata.LibraryPropertiesSchemaValidationResult()[compliancelevel.Specification], configuration.SchemasPath()) { @@ -567,14 +567,14 @@ func LibraryPropertiesParagraphFieldSpellCheck() (result checkresult.Type, outpu // LibraryPropertiesParagraphFieldRepeatsSentence checks whether the library.properties `paragraph` value repeats the `sentence` value. func LibraryPropertiesParagraphFieldRepeatsSentence() (result checkresult.Type, output string) { if checkdata.LibraryPropertiesLoadError() != nil { - return checkresult.NotRun, "" + return checkresult.NotRun, "Couldn't load library.properties" } sentence, hasSentence := checkdata.LibraryProperties().GetOk("sentence") paragraph, hasParagraph := checkdata.LibraryProperties().GetOk("paragraph") if !hasSentence || !hasParagraph { - return checkresult.NotRun, "" + return checkresult.NotRun, "Field not present" } if strings.HasPrefix(paragraph, sentence) { @@ -586,7 +586,7 @@ func LibraryPropertiesParagraphFieldRepeatsSentence() (result checkresult.Type, // LibraryPropertiesCategoryFieldMissing checks for missing library.properties "category" field. func LibraryPropertiesCategoryFieldMissing() (result checkresult.Type, output string) { if checkdata.LibraryPropertiesLoadError() != nil { - return checkresult.NotRun, "" + return checkresult.NotRun, "Couldn't load library.properties" } if schema.RequiredPropertyMissing("category", checkdata.LibraryPropertiesSchemaValidationResult()[compliancelevel.Specification], configuration.SchemasPath()) { @@ -598,12 +598,12 @@ func LibraryPropertiesCategoryFieldMissing() (result checkresult.Type, output st // LibraryPropertiesCategoryFieldInvalid checks for invalid category in the library.properties "category" field. func LibraryPropertiesCategoryFieldInvalid() (result checkresult.Type, output string) { if checkdata.LibraryPropertiesLoadError() != nil { - return checkresult.NotRun, "" + return checkresult.NotRun, "Couldn't load library.properties" } category, ok := checkdata.LibraryProperties().GetOk("category") if !ok { - return checkresult.NotRun, "" + return checkresult.NotRun, "Field not present" } if schema.PropertyEnumMismatch("category", checkdata.LibraryPropertiesSchemaValidationResult()[compliancelevel.Specification], configuration.SchemasPath()) { @@ -616,12 +616,12 @@ func LibraryPropertiesCategoryFieldInvalid() (result checkresult.Type, output st // LibraryPropertiesCategoryFieldUncategorized checks whether the library.properties "category" value is "Uncategorized". func LibraryPropertiesCategoryFieldUncategorized() (result checkresult.Type, output string) { if checkdata.LibraryPropertiesLoadError() != nil { - return checkresult.NotRun, "" + return checkresult.NotRun, "Couldn't load library.properties" } category, ok := checkdata.LibraryProperties().GetOk("category") if !ok { - return checkresult.NotRun, "" + return checkresult.NotRun, "Field not present" } if category == "Uncategorized" { @@ -634,7 +634,7 @@ func LibraryPropertiesCategoryFieldUncategorized() (result checkresult.Type, out // LibraryPropertiesUrlFieldMissing checks for missing library.properties "url" field. func LibraryPropertiesUrlFieldMissing() (result checkresult.Type, output string) { if checkdata.LibraryPropertiesLoadError() != nil { - return checkresult.NotRun, "" + return checkresult.NotRun, "Couldn't load library.properties" } if schema.RequiredPropertyMissing("url", checkdata.LibraryPropertiesSchemaValidationResult()[compliancelevel.Specification], configuration.SchemasPath()) { @@ -646,12 +646,12 @@ func LibraryPropertiesUrlFieldMissing() (result checkresult.Type, output string) // LibraryPropertiesUrlFieldInvalid checks whether the library.properties "url" value has a valid URL format. func LibraryPropertiesUrlFieldInvalid() (result checkresult.Type, output string) { if checkdata.LibraryPropertiesLoadError() != nil { - return checkresult.NotRun, "" + return checkresult.NotRun, "Couldn't load library.properties" } url, ok := checkdata.LibraryProperties().GetOk("url") if !ok { - return checkresult.NotRun, "" + return checkresult.NotRun, "Field not present" } if schema.ValidationErrorMatch("^#/url$", "/format$", "", "", checkdata.LibraryPropertiesSchemaValidationResult()[compliancelevel.Specification], configuration.SchemasPath()) { @@ -664,12 +664,12 @@ func LibraryPropertiesUrlFieldInvalid() (result checkresult.Type, output string) // LibraryPropertiesUrlFieldDeadLink checks whether the URL in the library.properties `url` field can be loaded. func LibraryPropertiesUrlFieldDeadLink() (result checkresult.Type, output string) { if checkdata.LibraryPropertiesLoadError() != nil { - return checkresult.NotRun, "" + return checkresult.NotRun, "Couldn't load library.properties" } url, ok := checkdata.LibraryProperties().GetOk("url") if !ok { - return checkresult.NotRun, "" + return checkresult.NotRun, "Field not present" } logrus.Tracef("Checking URL: %s", url) @@ -688,7 +688,7 @@ func LibraryPropertiesUrlFieldDeadLink() (result checkresult.Type, output string // LibraryPropertiesArchitecturesFieldMissing checks for missing library.properties "architectures" field. func LibraryPropertiesArchitecturesFieldMissing() (result checkresult.Type, output string) { if checkdata.LibraryPropertiesLoadError() != nil { - return checkresult.NotRun, "" + return checkresult.NotRun, "Couldn't load library.properties" } if schema.RequiredPropertyMissing("architectures", checkdata.LibraryPropertiesSchemaValidationResult()[compliancelevel.Specification], configuration.SchemasPath()) { @@ -700,11 +700,11 @@ func LibraryPropertiesArchitecturesFieldMissing() (result checkresult.Type, outp // LibraryPropertiesArchitecturesFieldLTMinLength checks if the library.properties "architectures" value is less than the minimum length. func LibraryPropertiesArchitecturesFieldLTMinLength() (result checkresult.Type, output string) { if checkdata.LibraryPropertiesLoadError() != nil { - return checkresult.NotRun, "" + return checkresult.NotRun, "Couldn't load library.properties" } if !checkdata.LibraryProperties().ContainsKey("architectures") { - return checkresult.NotRun, "" + return checkresult.NotRun, "Field not present" } if schema.PropertyLessThanMinLength("architectures", checkdata.LibraryPropertiesSchemaValidationResult()[compliancelevel.Specification], configuration.SchemasPath()) { @@ -717,12 +717,12 @@ func LibraryPropertiesArchitecturesFieldLTMinLength() (result checkresult.Type, // LibraryPropertiesDependsFieldDisallowedCharacters checks for disallowed characters in the library.properties "depends" field. func LibraryPropertiesDependsFieldDisallowedCharacters() (result checkresult.Type, output string) { if checkdata.LibraryPropertiesLoadError() != nil { - return checkresult.NotRun, "" + return checkresult.NotRun, "Couldn't load library.properties" } depends, ok := checkdata.LibraryProperties().GetOk("depends") if !ok { - return checkresult.NotRun, "" + return checkresult.NotRun, "Field not present" } if schema.PropertyPatternMismatch("depends", checkdata.LibraryPropertiesSchemaValidationResult()[compliancelevel.Specification], configuration.SchemasPath()) { @@ -735,12 +735,12 @@ func LibraryPropertiesDependsFieldDisallowedCharacters() (result checkresult.Typ // LibraryPropertiesDependsFieldNotInIndex checks whether the libraries listed in the library.properties `depends` field are in the Library Manager index. func LibraryPropertiesDependsFieldNotInIndex() (result checkresult.Type, output string) { if checkdata.LibraryPropertiesLoadError() != nil { - return checkresult.NotRun, "" + return checkresult.NotRun, "Couldn't load library.properties" } depends, hasDepends := checkdata.LibraryProperties().GetOk("depends") if !hasDepends { - return checkresult.NotRun, "" + return checkresult.NotRun, "Field not present" } dependencies, err := properties.SplitQuotedString(depends, "", false) @@ -765,12 +765,12 @@ func LibraryPropertiesDependsFieldNotInIndex() (result checkresult.Type, output // LibraryPropertiesDotALinkageFieldInvalid checks for invalid value in the library.properties "dot_a_linkage" field. func LibraryPropertiesDotALinkageFieldInvalid() (result checkresult.Type, output string) { if checkdata.LibraryPropertiesLoadError() != nil { - return checkresult.NotRun, "" + return checkresult.NotRun, "Couldn't load library.properties" } dotALinkage, ok := checkdata.LibraryProperties().GetOk("dot_a_linkage") if !ok { - return checkresult.NotRun, "" + return checkresult.NotRun, "Field not present" } if schema.PropertyEnumMismatch("dot_a_linkage", checkdata.LibraryPropertiesSchemaValidationResult()[compliancelevel.Specification], configuration.SchemasPath()) { @@ -782,8 +782,12 @@ func LibraryPropertiesDotALinkageFieldInvalid() (result checkresult.Type, output // LibraryPropertiesDotALinkageFieldTrueWithFlatLayout checks whether a library using the "dot_a_linkage" feature has the required recursive layout type. func LibraryPropertiesDotALinkageFieldTrueWithFlatLayout() (result checkresult.Type, output string) { - if checkdata.LoadedLibrary() == nil || !checkdata.LibraryProperties().ContainsKey("dot_a_linkage") { - return checkresult.NotRun, "" + if checkdata.LoadedLibrary() == nil { + return checkresult.NotRun, "Library not loaded" + } + + if !checkdata.LibraryProperties().ContainsKey("dot_a_linkage") { + return checkresult.NotRun, "Field not present" } if checkdata.LoadedLibrary().DotALinkage && checkdata.LoadedLibrary().Layout == libraries.FlatLayout { @@ -796,11 +800,11 @@ func LibraryPropertiesDotALinkageFieldTrueWithFlatLayout() (result checkresult.T // LibraryPropertiesIncludesFieldLTMinLength checks if the library.properties "includes" value is less than the minimum length. func LibraryPropertiesIncludesFieldLTMinLength() (result checkresult.Type, output string) { if checkdata.LibraryPropertiesLoadError() != nil { - return checkresult.NotRun, "" + return checkresult.NotRun, "Library not loaded" } if !checkdata.LibraryProperties().ContainsKey("includes") { - return checkresult.NotRun, "" + return checkresult.NotRun, "Field not present" } if schema.PropertyLessThanMinLength("includes", checkdata.LibraryPropertiesSchemaValidationResult()[compliancelevel.Specification], configuration.SchemasPath()) { @@ -813,12 +817,12 @@ func LibraryPropertiesIncludesFieldLTMinLength() (result checkresult.Type, outpu // LibraryPropertiesIncludesFieldItemNotFound checks whether the header files specified in the library.properties `includes` field are in the library. func LibraryPropertiesIncludesFieldItemNotFound() (result checkresult.Type, output string) { if checkdata.LibraryPropertiesLoadError() != nil { - return checkresult.NotRun, "" + return checkresult.NotRun, "Library not loaded" } includes, ok := checkdata.LibraryProperties().GetOk("includes") if !ok { - return checkresult.NotRun, "" + return checkresult.NotRun, "Field not present" } includesList, err := properties.SplitQuotedString(includes, "", false) @@ -854,12 +858,12 @@ func LibraryPropertiesIncludesFieldItemNotFound() (result checkresult.Type, outp // LibraryPropertiesPrecompiledFieldInvalid checks for invalid value in the library.properties "precompiled" field. func LibraryPropertiesPrecompiledFieldInvalid() (result checkresult.Type, output string) { if checkdata.LibraryPropertiesLoadError() != nil { - return checkresult.NotRun, "" + return checkresult.NotRun, "Library not loaded" } precompiled, ok := checkdata.LibraryProperties().GetOk("precompiled") if !ok { - return checkresult.NotRun, "" + return checkresult.NotRun, "Field not present" } if schema.PropertyEnumMismatch("precompiled", checkdata.LibraryPropertiesSchemaValidationResult()[compliancelevel.Specification], configuration.SchemasPath()) { @@ -872,12 +876,12 @@ func LibraryPropertiesPrecompiledFieldInvalid() (result checkresult.Type, output // LibraryPropertiesPrecompiledFieldEnabledWithFlatLayout checks whether a precompiled library has the required recursive layout type. func LibraryPropertiesPrecompiledFieldEnabledWithFlatLayout() (result checkresult.Type, output string) { if checkdata.LoadedLibrary() == nil || checkdata.LibraryPropertiesLoadError() != nil { - return checkresult.NotRun, "" + return checkresult.NotRun, "Library not loaded" } precompiled, ok := checkdata.LibraryProperties().GetOk("precompiled") if !ok { - return checkresult.NotRun, "" + return checkresult.NotRun, "Field not present" } if checkdata.LoadedLibrary().Precompiled && checkdata.LoadedLibrary().Layout == libraries.FlatLayout { @@ -890,7 +894,7 @@ func LibraryPropertiesPrecompiledFieldEnabledWithFlatLayout() (result checkresul // LibraryPropertiesLdflagsFieldLTMinLength checks if the library.properties "ldflags" value is less than the minimum length. func LibraryPropertiesLdflagsFieldLTMinLength() (result checkresult.Type, output string) { if checkdata.LibraryPropertiesLoadError() != nil { - return checkresult.NotRun, "" + return checkresult.NotRun, "Library not loaded" } if schema.PropertyLessThanMinLength("ldflags", checkdata.LibraryPropertiesSchemaValidationResult()[compliancelevel.Specification], configuration.SchemasPath()) { @@ -903,7 +907,7 @@ func LibraryPropertiesLdflagsFieldLTMinLength() (result checkresult.Type, output // LibraryPropertiesMisspelledOptionalField checks if library.properties contains common misspellings of optional fields. func LibraryPropertiesMisspelledOptionalField() (result checkresult.Type, output string) { if checkdata.LibraryPropertiesLoadError() != nil { - return checkresult.NotRun, "" + return checkresult.NotRun, "Library not loaded" } if schema.MisspelledOptionalPropertyFound(checkdata.LibraryPropertiesSchemaValidationResult()[compliancelevel.Specification], configuration.SchemasPath()) { @@ -1062,7 +1066,7 @@ func LibraryFolderNameGTMaxLength() (result checkresult.Type, output string) { func IncorrectLibrarySrcFolderNameCase() (result checkresult.Type, output string) { if library.ContainsMetadataFile(checkdata.ProjectPath()) && library.ContainsHeaderFile(checkdata.ProjectPath()) { // Flat layout, so no special treatment of src subfolder. - return checkresult.NotRun, "" + return checkresult.NotRun, "Not applicable due to layout type" } // The library is intended to have the recursive layout. @@ -1130,8 +1134,12 @@ func MisspelledExtrasFolderName() (result checkresult.Type, output string) { // RecursiveLibraryWithUtilityFolder checks for presence of a `utility` subfolder in a recursive layout library. func RecursiveLibraryWithUtilityFolder() (result checkresult.Type, output string) { - if checkdata.LoadedLibrary() == nil || checkdata.LoadedLibrary().Layout == libraries.FlatLayout { - return checkresult.NotRun, "" + if checkdata.LoadedLibrary() == nil { + return checkresult.NotRun, "Library not loaded" + } + + if checkdata.LoadedLibrary().Layout == libraries.FlatLayout { + return checkresult.NotRun, "Not applicable due to layout type" } if checkdata.ProjectPath().Join("utility").Exist() { @@ -1144,12 +1152,12 @@ func RecursiveLibraryWithUtilityFolder() (result checkresult.Type, output string // spellCheckLibraryPropertiesFieldValue returns the value of the provided library.properties field with commonly misspelled words corrected. func spellCheckLibraryPropertiesFieldValue(fieldName string) (result checkresult.Type, output string) { if checkdata.LibraryPropertiesLoadError() != nil { - return checkresult.NotRun, "" + return checkresult.NotRun, "Library not loaded" } fieldValue, ok := checkdata.LibraryProperties().GetOk(fieldName) if !ok { - return checkresult.NotRun, "" + return checkresult.NotRun, "Field not present" } replaced, diff := checkdata.MisspelledWordsReplacer().Replace(fieldValue) From c042ba4b009293c58ffb2841803a3cb9ff64475f Mon Sep 17 00:00:00 2001 From: per1234 Date: Thu, 3 Dec 2020 19:18:14 -0800 Subject: [PATCH 5/8] Correct regular expression for readme filename --- check/checkfunctions/checkfunctions.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/check/checkfunctions/checkfunctions.go b/check/checkfunctions/checkfunctions.go index 1406ebbe..58faa43e 100644 --- a/check/checkfunctions/checkfunctions.go +++ b/check/checkfunctions/checkfunctions.go @@ -70,7 +70,7 @@ func containsIncorrectPathBaseCase(pathList paths.PathList, correctBaseName stri // MissingReadme checks if the project has a readme that will be recognized by GitHub. func MissingReadme() (result checkresult.Type, output string) { // https://github.com/github/markup/blob/master/README.md - readmeRegexp := regexp.MustCompile(`(?i)^readme\.(markdown)|(mdown)|(mkdn)|(md)|(textile)|(rdoc)|(org)|(creole)|(mediawiki)|(wiki)|(rst)|(asciidoc)|(adoc)|(asc)|(pod)|(txt)`) + readmeRegexp := regexp.MustCompile(`(?i)^readme\.(markdown)|(mdown)|(mkdn)|(md)|(textile)|(rdoc)|(org)|(creole)|(mediawiki)|(wiki)|(rst)|(asciidoc)|(adoc)|(asc)|(pod)|(txt)$`) // https://docs.github.com/en/free-pro-team@latest/github/creating-cloning-and-archiving-repositories/about-readmes#about-readmes if pathContainsReadme(checkdata.ProjectPath(), readmeRegexp) || From 259ae3f8fbc1878d41084d145abf8ea1289f2ce7 Mon Sep 17 00:00:00 2001 From: per1234 Date: Thu, 3 Dec 2020 19:37:23 -0800 Subject: [PATCH 6/8] Add dedicated file for tests of the functions in check/checkfunctions/checkfunctions.go check/checkfunctions/checkfunctions.go will contain check functions that aren't specific to a single project type. There are a large, ever increasing, number of tests for check functions, and each group of check function types may have different testing requirements, so it's helpful to split them up a bit. --- check/checkfunctions/checkfunctions_test.go | 72 +++++++++++++++++++ check/checkfunctions/library_test.go | 19 ++--- .../NoReadme.h => general/no-readme/.gitkeep} | 0 .../Readme => general/readme}/README.md | 0 .../libraries/NoReadme/library.properties | 9 --- .../libraries/Readme/library.properties | 9 --- .../testdata/libraries/Readme/src/Readme.h | 0 7 files changed, 77 insertions(+), 32 deletions(-) create mode 100644 check/checkfunctions/checkfunctions_test.go rename check/checkfunctions/testdata/{libraries/NoReadme/src/NoReadme.h => general/no-readme/.gitkeep} (100%) rename check/checkfunctions/testdata/{libraries/Readme => general/readme}/README.md (100%) delete mode 100644 check/checkfunctions/testdata/libraries/NoReadme/library.properties delete mode 100644 check/checkfunctions/testdata/libraries/Readme/library.properties delete mode 100644 check/checkfunctions/testdata/libraries/Readme/src/Readme.h diff --git a/check/checkfunctions/checkfunctions_test.go b/check/checkfunctions/checkfunctions_test.go new file mode 100644 index 00000000..4405bca3 --- /dev/null +++ b/check/checkfunctions/checkfunctions_test.go @@ -0,0 +1,72 @@ +// This file is part of arduino-check. +// +// Copyright 2020 ARDUINO SA (http://www.arduino.cc/) +// +// This software is released under the GNU General Public License version 3, +// which covers the main part of arduino-check. +// The terms of this license can be found at: +// https://www.gnu.org/licenses/gpl-3.0.en.html +// +// You can be released from the requirements of the above licenses by purchasing +// a commercial license. Buying such a license is mandatory if you want to +// modify or otherwise use the software for commercial activities involving the +// Arduino software without disclosing the source code of your own applications. +// To purchase a commercial license, send an email to license@arduino.cc. + +package checkfunctions + +import ( + "os" + "regexp" + "testing" + + "github.com/arduino/arduino-check/check/checkdata" + "github.com/arduino/arduino-check/check/checkresult" + "github.com/arduino/arduino-check/project" + "github.com/arduino/arduino-check/project/projecttype" + "github.com/arduino/go-paths-helper" + "github.com/stretchr/testify/assert" +) + +var testDataPath *paths.Path + +func init() { + workingDirectory, _ := os.Getwd() + testDataPath = paths.New(workingDirectory, "testdata", "general") +} + +type checkFunctionTestTable struct { + testName string + projectFolderName string + projectType projecttype.Type + superProjectType projecttype.Type + expectedCheckResult checkresult.Type + expectedOutputQuery string +} + +func checkCheckFunction(checkFunction Type, testTables []checkFunctionTestTable, t *testing.T) { + for _, testTable := range testTables { + expectedOutputRegexp := regexp.MustCompile(testTable.expectedOutputQuery) + + testProject := project.Type{ + Path: testDataPath.Join(testTable.projectFolderName), + ProjectType: testTable.projectType, + SuperprojectType: testTable.superProjectType, + } + + checkdata.Initialize(testProject, schemasPath) + + result, output := checkFunction() + assert.Equal(t, testTable.expectedCheckResult, result, testTable.testName) + assert.True(t, expectedOutputRegexp.MatchString(output), testTable.testName) + } +} + +func TestMissingReadme(t *testing.T) { + testTables := []checkFunctionTestTable{ + {"Readme", "readme", projecttype.Sketch, projecttype.Sketch, checkresult.Pass, ""}, + {"No readme", "no-readme", projecttype.Sketch, projecttype.Sketch, checkresult.Fail, ""}, + } + + checkCheckFunction(MissingReadme, testTables, t) +} diff --git a/check/checkfunctions/library_test.go b/check/checkfunctions/library_test.go index 26913734..09936413 100644 --- a/check/checkfunctions/library_test.go +++ b/check/checkfunctions/library_test.go @@ -29,12 +29,12 @@ import ( "github.com/stretchr/testify/require" ) -var testDataPath *paths.Path +var librariesTestDataPath *paths.Path var schemasPath *paths.Path func init() { workingDirectory, _ := os.Getwd() - testDataPath = paths.New(workingDirectory, "testdata", "libraries") + librariesTestDataPath = paths.New(workingDirectory, "testdata", "libraries") schemasPath = paths.New(workingDirectory, "..", "..", "etc", "schemas") } @@ -50,7 +50,7 @@ func checkLibraryCheckFunction(checkFunction Type, testTables []libraryCheckFunc expectedOutputRegexp := regexp.MustCompile(testTable.expectedOutputQuery) testProject := project.Type{ - Path: testDataPath.Join(testTable.libraryFolderName), + Path: librariesTestDataPath.Join(testTable.libraryFolderName), ProjectType: projecttype.Library, SuperprojectType: projecttype.Library, } @@ -263,9 +263,9 @@ func TestLibraryHasSubmodule(t *testing.T) { func TestLibraryContainsSymlinks(t *testing.T) { testLibrary := "Recursive" - symlinkPath := testDataPath.Join(testLibrary, "test-symlink") + symlinkPath := librariesTestDataPath.Join(testLibrary, "test-symlink") // It's probably most friendly to developers using Windows to create the symlink needed for the test on demand. - err := os.Symlink(testDataPath.Join(testLibrary, "library.properties").String(), symlinkPath.String()) + err := os.Symlink(librariesTestDataPath.Join(testLibrary, "library.properties").String(), symlinkPath.String()) require.Nil(t, err, "This test must be run as administrator on Windows to have symlink creation privilege.") defer symlinkPath.RemoveAll() // clean up @@ -392,12 +392,3 @@ func TestRecursiveLibraryWithUtilityFolder(t *testing.T) { checkLibraryCheckFunction(RecursiveLibraryWithUtilityFolder, testTables, t) } - -func TestMissingReadme(t *testing.T) { - testTables := []libraryCheckFunctionTestTable{ - {"Readme", "Readme", checkresult.Pass, ""}, - {"No readme", "NoReadme", checkresult.Fail, ""}, - } - - checkLibraryCheckFunction(MissingReadme, testTables, t) -} diff --git a/check/checkfunctions/testdata/libraries/NoReadme/src/NoReadme.h b/check/checkfunctions/testdata/general/no-readme/.gitkeep similarity index 100% rename from check/checkfunctions/testdata/libraries/NoReadme/src/NoReadme.h rename to check/checkfunctions/testdata/general/no-readme/.gitkeep diff --git a/check/checkfunctions/testdata/libraries/Readme/README.md b/check/checkfunctions/testdata/general/readme/README.md similarity index 100% rename from check/checkfunctions/testdata/libraries/Readme/README.md rename to check/checkfunctions/testdata/general/readme/README.md diff --git a/check/checkfunctions/testdata/libraries/NoReadme/library.properties b/check/checkfunctions/testdata/libraries/NoReadme/library.properties deleted file mode 100644 index fd65bca7..00000000 --- a/check/checkfunctions/testdata/libraries/NoReadme/library.properties +++ /dev/null @@ -1,9 +0,0 @@ -name=NoReadme -version=1.0.0 -author=Cristian Maglie , Pippo Pluto -maintainer=Cristian Maglie -sentence=A library that makes coding a web server a breeze. -paragraph=Supports HTTP1.1 and you can do GET and POST. -category=Communication -url=http://example.com/ -architectures=avr diff --git a/check/checkfunctions/testdata/libraries/Readme/library.properties b/check/checkfunctions/testdata/libraries/Readme/library.properties deleted file mode 100644 index f3d92915..00000000 --- a/check/checkfunctions/testdata/libraries/Readme/library.properties +++ /dev/null @@ -1,9 +0,0 @@ -name=Readme -version=1.0.0 -author=Cristian Maglie , Pippo Pluto -maintainer=Cristian Maglie -sentence=A library that makes coding a web server a breeze. -paragraph=Supports HTTP1.1 and you can do GET and POST. -category=Communication -url=http://example.com/ -architectures=avr diff --git a/check/checkfunctions/testdata/libraries/Readme/src/Readme.h b/check/checkfunctions/testdata/libraries/Readme/src/Readme.h deleted file mode 100644 index e69de29b..00000000 From 1e6f98854dad9e5c3abc18bceb74fb327e8a23b4 Mon Sep 17 00:00:00 2001 From: per1234 Date: Thu, 3 Dec 2020 04:01:23 -0800 Subject: [PATCH 7/8] Add checkdata.SuperProjectType() This makes the superproject type accessible to the check functions. This allows the check to determine whether the project is a subproject, which may require different handling. --- check/checkdata/checkdata.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/check/checkdata/checkdata.go b/check/checkdata/checkdata.go index 4dc25bc2..4626aaa2 100644 --- a/check/checkdata/checkdata.go +++ b/check/checkdata/checkdata.go @@ -28,6 +28,7 @@ import ( // Initialize gathers the check data for the specified project. func Initialize(project project.Type, schemasPath *paths.Path) { + superprojectType = project.SuperprojectType projectType = project.ProjectType projectPath = project.Path switch project.ProjectType { @@ -48,6 +49,13 @@ func Initialize(project project.Type, schemasPath *paths.Path) { } } +var superprojectType projecttype.Type + +// SuperProjectType returns the type of the project being checked. +func SuperProjectType() projecttype.Type { + return superprojectType +} + var projectType projecttype.Type // ProjectType returns the type of the project being checked. From 12170ff877b5636b2de65fd6b496256b1416a7a0 Mon Sep 17 00:00:00 2001 From: per1234 Date: Thu, 3 Dec 2020 04:02:36 -0800 Subject: [PATCH 8/8] Don't run the readme check for subprojects The superproject should have a readme, but it's not necessarily essential for the subproject to have one as well. --- check/checkfunctions/checkfunctions.go | 4 ++++ check/checkfunctions/checkfunctions_test.go | 1 + 2 files changed, 5 insertions(+) diff --git a/check/checkfunctions/checkfunctions.go b/check/checkfunctions/checkfunctions.go index 58faa43e..33764079 100644 --- a/check/checkfunctions/checkfunctions.go +++ b/check/checkfunctions/checkfunctions.go @@ -69,6 +69,10 @@ func containsIncorrectPathBaseCase(pathList paths.PathList, correctBaseName stri // MissingReadme checks if the project has a readme that will be recognized by GitHub. func MissingReadme() (result checkresult.Type, output string) { + if checkdata.ProjectType() != checkdata.SuperProjectType() { + return checkresult.NotRun, "Readme not required for subprojects" + } + // https://github.com/github/markup/blob/master/README.md readmeRegexp := regexp.MustCompile(`(?i)^readme\.(markdown)|(mdown)|(mkdn)|(md)|(textile)|(rdoc)|(org)|(creole)|(mediawiki)|(wiki)|(rst)|(asciidoc)|(adoc)|(asc)|(pod)|(txt)$`) diff --git a/check/checkfunctions/checkfunctions_test.go b/check/checkfunctions/checkfunctions_test.go index 4405bca3..2c2501c1 100644 --- a/check/checkfunctions/checkfunctions_test.go +++ b/check/checkfunctions/checkfunctions_test.go @@ -64,6 +64,7 @@ func checkCheckFunction(checkFunction Type, testTables []checkFunctionTestTable, func TestMissingReadme(t *testing.T) { testTables := []checkFunctionTestTable{ + {"Subproject", "readme", projecttype.Sketch, projecttype.Library, checkresult.NotRun, ""}, {"Readme", "readme", projecttype.Sketch, projecttype.Sketch, checkresult.Pass, ""}, {"No readme", "no-readme", projecttype.Sketch, projecttype.Sketch, checkresult.Fail, ""}, }