Skip to content

Commit 9fa16fa

Browse files
committed
feat: support WITH in SPDX license expressions
Use https://github.com/github/go-spdx to validate SPDX license expressions: it's more maintained and supports WITH exceptions. Also, make it a function for go-playground/validator. Fix italia#189.
1 parent 986aedb commit 9fa16fa

File tree

9 files changed

+119
-18
lines changed

9 files changed

+119
-18
lines changed

fields.go

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import (
66

77
"github.com/alranel/go-vcsurl/v2"
88
urlutil "github.com/italia/publiccode-parser-go/v4/internal"
9-
spdxValidator "github.com/kyoh86/go-spdx/spdx"
109
)
1110

1211
type validateFn func(publiccode PublicCode, parser Parser, network bool) error
@@ -18,7 +17,6 @@ func validateFieldsV0(publiccode PublicCode, parser Parser, network bool) error
1817
publiccodev0 := publiccode.(PublicCodeV0)
1918

2019
var vr ValidationResults
21-
var err error
2220

2321
if publiccodev0.URL != nil && network {
2422
if reachable, err := parser.isReachable(*(*url.URL)(publiccodev0.URL), network); !reachable {
@@ -70,16 +68,6 @@ func validateFieldsV0(publiccode PublicCode, parser Parser, network bool) error
7068
}
7169
}
7270

73-
if publiccodev0.Legal.License != "" {
74-
_, err = spdxValidator.Parse(publiccodev0.Legal.License)
75-
if err != nil {
76-
vr = append(vr, newValidationError(
77-
"legal.license",
78-
"invalid license '%s'", publiccodev0.Legal.License,
79-
))
80-
}
81-
}
82-
8371
if len(publiccodev0.InputTypes) > 0 {
8472
vr = append(vr, ValidationWarning{"inputTypes", "This key is DEPRECATED and will be removed in the future", 0, 0})
8573
}

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@ module github.com/italia/publiccode-parser-go/v4
33
require (
44
github.com/alranel/go-vcsurl/v2 v2.0.2
55
github.com/dyatlov/go-oembed v0.0.0-20191103150536-a57c85b3b37c
6+
github.com/github/go-spdx/v2 v2.3.3
67
github.com/go-playground/locales v0.14.1
78
github.com/go-playground/universal-translator v0.18.1
89
github.com/go-playground/validator/v10 v10.18.0
910
github.com/italia/httpclient-lib-go v0.0.2
10-
github.com/kyoh86/go-spdx v0.0.5-0.20220518012447-4d195d3a5da1
1111
github.com/rivo/uniseg v0.4.2
1212
gopkg.in/yaml.v3 v3.0.1
1313
)

go.sum

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ github.com/dyatlov/go-oembed v0.0.0-20191103150536-a57c85b3b37c h1:MEV1LrQtCBGac
99
github.com/dyatlov/go-oembed v0.0.0-20191103150536-a57c85b3b37c/go.mod h1:DjlDZiZGRRKbiJZmiEiiXozsBQAQzHmxwHKFeXifL2g=
1010
github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0=
1111
github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk=
12+
github.com/github/go-spdx/v2 v2.3.3 h1:QI7evnHWEfWkT54eJwkoV/f3a0xD3gLlnVmT5wQG6LE=
13+
github.com/github/go-spdx/v2 v2.3.3/go.mod h1:2ZxKsOhvBp+OYBDlsGnUMcchLeo2mrpEBn2L1C+U3IQ=
1214
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
1315
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
1416
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
@@ -24,8 +26,6 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN
2426
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
2527
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
2628
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
27-
github.com/kyoh86/go-spdx v0.0.5-0.20220518012447-4d195d3a5da1 h1:V9VECvxFpeRc1dQGZyB2rOsUOAcDKi+t2sV64UK8xE4=
28-
github.com/kyoh86/go-spdx v0.0.5-0.20220518012447-4d195d3a5da1/go.mod h1:PLyaOnItOIGepc7kUKJbp2YSsaZf94luSUcUgb2MQ+4=
2929
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
3030
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
3131
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
@@ -37,7 +37,6 @@ github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0
3737
github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
3838
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
3939
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
40-
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
4140
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
4241
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
4342
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=

parser_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -438,7 +438,7 @@ func TestInvalidTestcasesV0(t *testing.T) {
438438
},
439439
"legal_license_missing.yml": ValidationResults{ValidationError{"legal.license", "license is a required field", 41, 3}},
440440
"legal_license_invalid.yml": ValidationResults{ValidationError{
441-
"legal.license", "invalid license 'Invalid License'", 42, 3,
441+
"legal.license", "license must be a valid license (see https://spdx.org/licenses)", 42, 3,
442442
}},
443443
"legal_authorsFile_missing_file.yml": ValidationResults{
444444
ValidationWarning{
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
publiccodeYmlVersion: "0.4"
2+
3+
name: Medusa
4+
url: "https://github.com/italia/developers.italia.it.git"
5+
6+
platforms:
7+
- web
8+
9+
categories:
10+
- cloud-management
11+
12+
developmentStatus: development
13+
14+
softwareType: "standalone/other"
15+
16+
description:
17+
en_GB:
18+
localisedName: Medusa
19+
shortDescription: >
20+
A rather short description which
21+
is probably useless
22+
longDescription: >
23+
Very long description of this software, also split
24+
on multiple rows. You should note what the software
25+
is and why one should need it. This is 158 characters.
26+
Very long description of this software, also split
27+
on multiple rows. You should note what the software
28+
is and why one should need it. This is 316 characters.
29+
Very long description of this software, also split
30+
on multiple rows. You should note what the software
31+
is and why one should need it. This is 474 characters.
32+
Very long description of this software, also split
33+
on multiple rows. You should note what the software
34+
is and why one should need it. This is 632 characters.
35+
features:
36+
- Just one feature
37+
38+
legal:
39+
# OR operator in SPDX expression
40+
license: MIT OR Apache-2.0
41+
42+
maintenance:
43+
type: "community"
44+
45+
contacts:
46+
- name: Francesco Rossi
47+
48+
localisation:
49+
localisationReady: true
50+
availableLanguages:
51+
- en
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
publiccodeYmlVersion: "0.4"
2+
3+
name: Medusa
4+
url: "https://github.com/italia/developers.italia.it.git"
5+
6+
platforms:
7+
- web
8+
9+
categories:
10+
- cloud-management
11+
12+
developmentStatus: development
13+
14+
softwareType: "standalone/other"
15+
16+
description:
17+
en_GB:
18+
localisedName: Medusa
19+
shortDescription: >
20+
A rather short description which
21+
is probably useless
22+
longDescription: >
23+
Very long description of this software, also split
24+
on multiple rows. You should note what the software
25+
is and why one should need it. This is 158 characters.
26+
Very long description of this software, also split
27+
on multiple rows. You should note what the software
28+
is and why one should need it. This is 316 characters.
29+
Very long description of this software, also split
30+
on multiple rows. You should note what the software
31+
is and why one should need it. This is 474 characters.
32+
Very long description of this software, also split
33+
on multiple rows. You should note what the software
34+
is and why one should need it. This is 632 characters.
35+
features:
36+
- Just one feature
37+
38+
legal:
39+
# WITH exception in SPDX expression
40+
license: MIT WITH Bison-exception-2.2
41+
42+
maintenance:
43+
type: "community"
44+
45+
contacts:
46+
- name: Francesco Rossi
47+
48+
localisation:
49+
localisationReady: true
50+
availableLanguages:
51+
- en

v0.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ type PublicCodeV0 struct {
4444
Description map[string]DescV0 `yaml:"description" validate:"gt=0,bcp47_keys,dive"`
4545

4646
Legal struct {
47-
License string `yaml:"license" validate:"required"`
47+
License string `yaml:"license" validate:"required,is_spdx_expression"`
4848
MainCopyrightOwner *string `yaml:"mainCopyrightOwner,omitempty"`
4949
RepoOwner *string `yaml:"repoOwner,omitempty"`
5050
AuthorsFile *string `yaml:"authorsFile,omitempty"`

validators/common.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"strings"
88
"time"
99

10+
"github.com/github/go-spdx/v2/spdxexp"
1011
"github.com/go-playground/validator/v10"
1112
"github.com/rivo/uniseg"
1213
)
@@ -88,3 +89,9 @@ func bcp47_keys(fl validator.FieldLevel) bool {
8889

8990
return true
9091
}
92+
93+
func isSPDXExpression(fl validator.FieldLevel) bool {
94+
valid, _ := spdxexp.ValidateLicenses([]string{fl.Field().String()})
95+
96+
return valid
97+
}

validators/validator.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ func New() *validator.Validate {
1818
_ = validate.RegisterValidation("umin", uMin)
1919
_ = validate.RegisterValidation("url_http_url", isHTTPURL)
2020
_ = validate.RegisterValidation("url_url", isURL)
21+
_ = validate.RegisterValidation("is_spdx_expression", isSPDXExpression)
2122

2223
_ = validate.RegisterValidation("is_category_v0", isCategoryV0)
2324
_ = validate.RegisterValidation("is_scope_v0", isScopeV0)
@@ -125,6 +126,10 @@ func RegisterLocalErrorMessages(v *validator.Validate, trans ut.Translator) erro
125126
tag: "url_url",
126127
translation: "{0} must be a valid URL",
127128
},
129+
{
130+
tag: "is_spdx_expression",
131+
translation: "{0} must be a valid license (see https://spdx.org/licenses)",
132+
},
128133
{
129134
tag: "is_category_v0",
130135
translation: "{0} must be a valid category (see https://github.com/publiccodeyml/publiccode.yml/blob/main/docs/standard/categories-list.rst)",

0 commit comments

Comments
 (0)