diff --git a/parser_test.go b/parser_test.go index e0a0da1e..7e6feab4 100644 --- a/parser_test.go +++ b/parser_test.go @@ -497,6 +497,15 @@ func TestInvalidTestcasesV0(t *testing.T) { "maintenance_contractors_website_invalid.yml": ValidationResults{ ValidationError{"maintenance.contractors[0].website", "website must be an HTTP URL", 0, 0}, // TODO: line number }, + "maintenance_contractors_when_type_is_community.yml": ValidationResults{ + ValidationError{"maintenance.contractors", "contractors must not be present unless \"type\" is \"contract\"", 46, 3}, + }, + "maintenance_contractors_when_type_is_internal.yml": ValidationResults{ + ValidationError{"maintenance.contractors", "contractors must not be present unless \"type\" is \"contract\"", 46, 3}, + }, + "maintenance_contractors_when_type_is_none.yml": ValidationResults{ + ValidationError{"maintenance.contractors", "contractors must not be present unless \"type\" is \"contract\"", 46, 3}, + }, // localisation "localisation_availableLanguages_missing.yml": ValidationResults{ diff --git a/testdata/v0/invalid/maintenance_contractors_when_type_is_community.yml b/testdata/v0/invalid/maintenance_contractors_when_type_is_community.yml new file mode 100644 index 00000000..9e6088e9 --- /dev/null +++ b/testdata/v0/invalid/maintenance_contractors_when_type_is_community.yml @@ -0,0 +1,58 @@ +publiccodeYmlVersion: "0.4" + +name: Medusa +url: "https://github.com/italia/developers.italia.it.git" +softwareVersion: "dev" +releaseDate: "2017-04-15" + +platforms: + - web + +categories: + - cloud-management + +developmentStatus: development + +softwareType: "standalone/other" + +description: + en: + localisedName: Medusa + shortDescription: > + A rather short description which + is probably useless + longDescription: > + Very long description of this software, also split + on multiple rows. You should note what the software + is and why one should need it. This is 158 characters. + Very long description of this software, also split + on multiple rows. You should note what the software + is and why one should need it. This is 316 characters. + Very long description of this software, also split + on multiple rows. You should note what the software + is and why one should need it. This is 474 characters. + Very long description of this software, also split + on multiple rows. You should note what the software + is and why one should need it. This is 632 characters. + features: + - Just one feature + +legal: + license: AGPL-3.0-or-later + +maintenance: + type: "community" + + contractors: + # This should NOT be accepted NOR validated (the "until" is missing), + # because type is "community" + - name: "Contractor" + website: "https://example.org" + + contacts: + - name: John Smith + +localisation: + localisationReady: true + availableLanguages: + - en diff --git a/testdata/v0/invalid/maintenance_contractors_when_type_is_internal.yml b/testdata/v0/invalid/maintenance_contractors_when_type_is_internal.yml new file mode 100644 index 00000000..00e51de6 --- /dev/null +++ b/testdata/v0/invalid/maintenance_contractors_when_type_is_internal.yml @@ -0,0 +1,58 @@ +publiccodeYmlVersion: "0.4" + +name: Medusa +url: "https://github.com/italia/developers.italia.it.git" +softwareVersion: "dev" +releaseDate: "2017-04-15" + +platforms: + - web + +categories: + - cloud-management + +developmentStatus: development + +softwareType: "standalone/other" + +description: + en: + localisedName: Medusa + shortDescription: > + A rather short description which + is probably useless + longDescription: > + Very long description of this software, also split + on multiple rows. You should note what the software + is and why one should need it. This is 158 characters. + Very long description of this software, also split + on multiple rows. You should note what the software + is and why one should need it. This is 316 characters. + Very long description of this software, also split + on multiple rows. You should note what the software + is and why one should need it. This is 474 characters. + Very long description of this software, also split + on multiple rows. You should note what the software + is and why one should need it. This is 632 characters. + features: + - Just one feature + +legal: + license: AGPL-3.0-or-later + +maintenance: + type: "internal" + + contractors: + # This should NOT be accepted NOR validated (the "until" is missing), + # because type is "internal" + - name: "Contractor" + website: "https://example.org" + + contacts: + - name: John Smith + +localisation: + localisationReady: true + availableLanguages: + - en diff --git a/testdata/v0/invalid/maintenance_contractors_when_type_is_none.yml b/testdata/v0/invalid/maintenance_contractors_when_type_is_none.yml new file mode 100644 index 00000000..404f708f --- /dev/null +++ b/testdata/v0/invalid/maintenance_contractors_when_type_is_none.yml @@ -0,0 +1,55 @@ +publiccodeYmlVersion: "0.4" + +name: Medusa +url: "https://github.com/italia/developers.italia.it.git" +softwareVersion: "dev" +releaseDate: "2017-04-15" + +platforms: + - web + +categories: + - cloud-management + +developmentStatus: development + +softwareType: "standalone/other" + +description: + en: + localisedName: Medusa + shortDescription: > + A rather short description which + is probably useless + longDescription: > + Very long description of this software, also split + on multiple rows. You should note what the software + is and why one should need it. This is 158 characters. + Very long description of this software, also split + on multiple rows. You should note what the software + is and why one should need it. This is 316 characters. + Very long description of this software, also split + on multiple rows. You should note what the software + is and why one should need it. This is 474 characters. + Very long description of this software, also split + on multiple rows. You should note what the software + is and why one should need it. This is 632 characters. + features: + - Just one feature + +legal: + license: AGPL-3.0-or-later + +maintenance: + type: "none" + + contractors: + # This should NOT be accepted NOR validated (the "until" is missing), + # because type is "none" + - name: "Contractor" + website: "https://example.org" + +localisation: + localisationReady: true + availableLanguages: + - en diff --git a/testdata/v0/valid/maintenance_contacts_when_type_is_contract.yml b/testdata/v0/valid/maintenance_contacts_when_type_is_contract.yml new file mode 100644 index 00000000..c1b44ff8 --- /dev/null +++ b/testdata/v0/valid/maintenance_contacts_when_type_is_contract.yml @@ -0,0 +1,56 @@ +publiccodeYmlVersion: "0.4" + +name: Medusa +url: "https://github.com/italia/developers.italia.it.git" + +platforms: + - web + +categories: + - cloud-management + +developmentStatus: development + +softwareType: "standalone/other" + +description: + en_GB: + localisedName: Medusa + shortDescription: > + A rather short description which + is probably useless + longDescription: > + Very long description of this software, also split + on multiple rows. You should note what the software + is and why one should need it. This is 158 characters. + Very long description of this software, also split + on multiple rows. You should note what the software + is and why one should need it. This is 316 characters. + Very long description of this software, also split + on multiple rows. You should note what the software + is and why one should need it. This is 474 characters. + Very long description of this software, also split + on multiple rows. You should note what the software + is and why one should need it. This is 632 characters. + features: + - Just one feature + +legal: + license: AGPL-3.0-or-later + +maintenance: + type: "contract" + + contractors: + - name: "Contractor" + website: "https://example.org" + until: 2040-01-01 + + # `contacts` is allowed when type is "contract" as well + contacts: + - name: John Smith + +localisation: + localisationReady: true + availableLanguages: + - en diff --git a/testdata/v0/valid/maintenance_contacts_when_type_is_internal.yml b/testdata/v0/valid/maintenance_contacts_when_type_is_internal.yml new file mode 100644 index 00000000..258369d2 --- /dev/null +++ b/testdata/v0/valid/maintenance_contacts_when_type_is_internal.yml @@ -0,0 +1,51 @@ +publiccodeYmlVersion: "0.4" + +name: Medusa +url: "https://github.com/italia/developers.italia.it.git" + +platforms: + - web + +categories: + - cloud-management + +developmentStatus: development + +softwareType: "standalone/other" + +description: + en_GB: + localisedName: Medusa + shortDescription: > + A rather short description which + is probably useless + longDescription: > + Very long description of this software, also split + on multiple rows. You should note what the software + is and why one should need it. This is 158 characters. + Very long description of this software, also split + on multiple rows. You should note what the software + is and why one should need it. This is 316 characters. + Very long description of this software, also split + on multiple rows. You should note what the software + is and why one should need it. This is 474 characters. + Very long description of this software, also split + on multiple rows. You should note what the software + is and why one should need it. This is 632 characters. + features: + - Just one feature + +legal: + license: AGPL-3.0-or-later + +maintenance: + type: "internal" + + # `contacts` is allowed when type is "internal" as well + contacts: + - name: John Smith + +localisation: + localisationReady: true + availableLanguages: + - en diff --git a/testdata/v0/valid/maintenance_contacts_when_type_is_none.yml b/testdata/v0/valid/maintenance_contacts_when_type_is_none.yml new file mode 100644 index 00000000..5f9b1a4d --- /dev/null +++ b/testdata/v0/valid/maintenance_contacts_when_type_is_none.yml @@ -0,0 +1,51 @@ +publiccodeYmlVersion: "0.4" + +name: Medusa +url: "https://github.com/italia/developers.italia.it.git" + +platforms: + - web + +categories: + - cloud-management + +developmentStatus: development + +softwareType: "standalone/other" + +description: + en_GB: + localisedName: Medusa + shortDescription: > + A rather short description which + is probably useless + longDescription: > + Very long description of this software, also split + on multiple rows. You should note what the software + is and why one should need it. This is 158 characters. + Very long description of this software, also split + on multiple rows. You should note what the software + is and why one should need it. This is 316 characters. + Very long description of this software, also split + on multiple rows. You should note what the software + is and why one should need it. This is 474 characters. + Very long description of this software, also split + on multiple rows. You should note what the software + is and why one should need it. This is 632 characters. + features: + - Just one feature + +legal: + license: AGPL-3.0-or-later + +maintenance: + type: "none" + + # `contacts` is allowed when type is "none" as well + contacts: + - name: John Smith + +localisation: + localisationReady: true + availableLanguages: + - en diff --git a/v0.go b/v0.go index 53a89762..6cbf8d2d 100644 --- a/v0.go +++ b/v0.go @@ -51,9 +51,9 @@ type PublicCodeV0 struct { } `yaml:"legal"` Maintenance struct { - Type string `validate:"required,oneof=internal contract community none" yaml:"type"` - Contractors []ContractorV0 `validate:"required_if=Type contract,dive" yaml:"contractors,omitempty"` - Contacts []ContactV0 `validate:"required_if=Type community,required_if=Type internal,dive" yaml:"contacts,omitempty"` + Type string `validate:"required,oneof=internal contract community none" yaml:"type"` + Contractors []ContractorV0 `validate:"required_if=Type contract,excluded_unless=Type contract,dive" yaml:"contractors,omitempty"` + Contacts []ContactV0 `validate:"required_if=Type community,required_if=Type internal,dive" yaml:"contacts,omitempty"` } `yaml:"maintenance"` Localisation struct { diff --git a/validators/validator.go b/validators/validator.go index 5fcb125f..f2192f25 100644 --- a/validators/validator.go +++ b/validators/validator.go @@ -102,6 +102,26 @@ func RegisterLocalErrorMessages(v *validator.Validate, trans ut.Translator) erro tag: "is_mime_type", translation: "{0} is not a valid MIME type", }, + { + // Override the default error with a more user friendly one + // + // original: + // foo is an excluded field + // overridden: + // foo is not permitted when "bar" is "foobar" + tag: "excluded_unless", + customRegisFunc: func(ut ut.Translator) error { + return ut.Add("excluded_unless", "{0} must not be present unless {1}", true) + }, + customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { + parts := strings.Fields(fe.Param()) + + t, _ := ut.T("excluded_unless", fe.Field(), fmt.Sprintf("\"%s\" is \"%s\"", strings.ToLower(parts[0]), parts[1])) + + return t + }, + override: true, + }, { tag: "umax", customRegisFunc: func(ut ut.Translator) error {