Skip to content

Commit 4c7b9a7

Browse files
committed
feat: require ISO 3166-1 country codes in v1
v1 country codes must be strict ISO 3166-1 alpha-2, uppercase only.
1 parent 92c2312 commit 4c7b9a7

6 files changed

Lines changed: 16 additions & 66 deletions

File tree

fields.go

Lines changed: 0 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -318,35 +318,6 @@ func validateFieldsV1(publiccode PublicCode, parser *Parser, network bool, baseU
318318
}
319319
}
320320

321-
if publiccodev1.IntendedAudience != nil {
322-
// This is not ideal, but we need to revalidate the countries
323-
// here, because otherwise we could get a warning and the advice
324-
// to use uppercase on an invalid country.
325-
if publiccodev1.IntendedAudience.Countries != nil {
326-
for i, c := range *publiccodev1.IntendedAudience.Countries {
327-
if sharedValidate.Var(c, "iso3166_1_alpha2_lower_or_upper") == nil && c == strings.ToLower(c) {
328-
vr = append(vr, ValidationWarning{
329-
fmt.Sprintf("intendedAudience.countries[%d]", i),
330-
fmt.Sprintf("Lowercase country codes are DEPRECATED. Use uppercase instead ('%s')", strings.ToUpper(c)),
331-
0, 0,
332-
})
333-
}
334-
}
335-
}
336-
337-
if publiccodev1.IntendedAudience.UnsupportedCountries != nil {
338-
for i, c := range *publiccodev1.IntendedAudience.UnsupportedCountries {
339-
if sharedValidate.Var(c, "iso3166_1_alpha2_lower_or_upper") == nil && c == strings.ToLower(c) {
340-
vr = append(vr, ValidationWarning{
341-
fmt.Sprintf("intendedAudience.unsupportedCountries[%d]", i),
342-
fmt.Sprintf("Lowercase country codes are DEPRECATED. Use uppercase instead ('%s')", strings.ToUpper(c)),
343-
0, 0,
344-
})
345-
}
346-
}
347-
}
348-
}
349-
350321
for lang, desc := range publiccodev1.Description {
351322
if checksNetwork && desc.Documentation != nil {
352323
if reachable, err := parser.isReachable(*(*url.URL)(desc.Documentation)); !reachable {

fields_v1_test.go

Lines changed: 0 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -261,37 +261,6 @@ func TestValidateFieldsV1WithAPIDocNetworkCheck(t *testing.T) {
261261
}
262262
}
263263

264-
func TestValidateFieldsV1WithCountriesDeprecated(t *testing.T) {
265-
p, _ := NewParser(ParserConfig{DisableNetwork: true, DisableExternalChecks: true})
266-
base := &url.URL{Scheme: "file", Path: "/tmp"}
267-
268-
countries := []string{"it"} // lowercase - deprecated
269-
unsupported := []string{"de"} // lowercase - deprecated
270-
locReady := true
271-
v1 := &PublicCodeV1{
272-
IntendedAudience: &struct {
273-
Scope *[]string `json:"scope,omitempty" validate:"omitempty,dive,is_scope_v1" yaml:"scope,omitempty"`
274-
Countries *[]string `json:"countries,omitempty" validate:"omitempty,dive,iso3166_1_alpha2_lower_or_upper" yaml:"countries,omitempty"`
275-
UnsupportedCountries *[]string `json:"unsupportedCountries,omitempty" validate:"omitempty,dive,iso3166_1_alpha2_lower_or_upper" yaml:"unsupportedCountries,omitempty"`
276-
}{
277-
Countries: &countries,
278-
UnsupportedCountries: &unsupported,
279-
},
280-
Localisation: struct {
281-
LocalisationReady *bool `json:"localisationReady" validate:"required" yaml:"localisationReady"`
282-
AvailableLanguages []string `json:"availableLanguages" validate:"required,gt=0,dive,bcp47_strict_language_tag" yaml:"availableLanguages"`
283-
}{
284-
LocalisationReady: &locReady,
285-
AvailableLanguages: []string{"en"},
286-
},
287-
}
288-
289-
err := validateFieldsV1(v1, p, false, base)
290-
if err == nil {
291-
t.Error("expected deprecation warnings for lowercase countries")
292-
}
293-
}
294-
295264
func TestValidateFieldsV0MonochromeLogoAbsPath(t *testing.T) {
296265
p, _ := NewParser(ParserConfig{DisableNetwork: true, DisableExternalChecks: false})
297266
base := &url.URL{Scheme: "file", Path: "/tmp"}

testdata/v1/invalid_valid_with_warnings_in_v0/valid_with_lowercase_countries.yml renamed to testdata/v1/invalid/lowercase_countries.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,15 +80,15 @@ maintenance:
8080
- name: Francesco Rossi
8181
email: "francesco.rossi@comune.reggioemilia.it"
8282
affiliation: Comune di Reggio Emilia
83-
phone: +39 231 13215112
83+
phone: +3923113215112
8484
- name: Dario Bianchi
8585
email: "dario.bianchi@fornitore.it"
8686
affiliation: Fornitore Privato S.P.A.
87-
phone: +39 16 24231322
87+
phone: +391624231322
8888
- name: Giancarlo Verdi
8989
email: "dario.bianchi@fornitore.it"
9090
affiliation: Fornitore Privato S.P.A.
91-
phone: +39 16 24231322
91+
phone: +391624231322
9292

9393
localisation:
9494
localisationReady: true

v1.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,9 @@ type PublicCodeV1 struct {
3838
SoftwareType string `json:"softwareType" validate:"required,oneof=standalone/mobile standalone/iot standalone/desktop standalone/web standalone/backend standalone/other addon library configurationFiles" yaml:"softwareType"`
3939

4040
IntendedAudience *struct {
41-
Scope *[]string `json:"scope,omitempty" validate:"omitempty,dive,is_scope_v1" yaml:"scope,omitempty"`
42-
Countries *[]string `json:"countries,omitempty" validate:"omitempty,dive,iso3166_1_alpha2_lower_or_upper" yaml:"countries,omitempty"`
43-
UnsupportedCountries *[]string `json:"unsupportedCountries,omitempty" validate:"omitempty,dive,iso3166_1_alpha2_lower_or_upper" yaml:"unsupportedCountries,omitempty"`
41+
Scope *[]string `json:"scope,omitempty" validate:"omitempty,dive,is_scope_v1" yaml:"scope,omitempty"`
42+
Countries *[]string `json:"countries,omitempty" validate:"omitempty,dive,iso3166_1_alpha2" yaml:"countries,omitempty"`
43+
UnsupportedCountries *[]string `json:"unsupportedCountries,omitempty" validate:"omitempty,dive,iso3166_1_alpha2" yaml:"unsupportedCountries,omitempty"`
4444
} `json:"intendedAudience,omitempty" yaml:"intendedAudience,omitempty"`
4545

4646
Description map[string]DescV1 `json:"description" validate:"gt=0,bcp47_keys,dive" yaml:"description"`

v1_test.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,11 @@ func TestInvalidTestcasesV1(t *testing.T) {
147147
"intendedAudience_countries_invalid_iso_3166_1_alpha_2.yml": ValidationResults{
148148
ValidationError{"intendedAudience.countries[2]", "countries[2] must be a valid ISO 3166-1 alpha-2 two-letter country code", 22, 7},
149149
},
150+
"lowercase_countries.yml": ValidationResults{
151+
ValidationError{"intendedAudience.countries[0]", "countries[0] must be a valid ISO 3166-1 alpha-2 two-letter country code", 31, 7},
152+
ValidationError{"intendedAudience.countries[1]", "countries[1] must be a valid ISO 3166-1 alpha-2 two-letter country code", 32, 7},
153+
ValidationError{"intendedAudience.unsupportedCountries[0]", "unsupportedCountries[0] must be a valid ISO 3166-1 alpha-2 two-letter country code", 34, 7},
154+
},
150155
"intendedAudience_countries_wrong_type.yml": ValidationResults{
151156
ValidationError{"intendedAudience.countries", "wrong type for this field", 19, 1},
152157
},

validators/validator.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,11 @@ func RegisterLocalErrorMessages(v *validator.Validate, trans ut.Translator) erro
211211
tag: "iso3166_1_alpha2_lower_or_upper",
212212
translation: "{0} must be a valid ISO 3166-1 alpha-2 two-letter country code",
213213
},
214+
{
215+
tag: "iso3166_1_alpha2",
216+
override: true,
217+
translation: "{0} must be a valid ISO 3166-1 alpha-2 two-letter country code",
218+
},
214219
{
215220
tag: "bcp47_strict_language_tag",
216221
override: true,

0 commit comments

Comments
 (0)