@@ -3,111 +3,112 @@ package publiccode
3
3
import (
4
4
"fmt"
5
5
"net/url"
6
- "slices"
7
6
8
7
spdxValidator "github.com/kyoh86/go-spdx/spdx"
9
8
"github.com/alranel/go-vcsurl/v2"
10
9
11
- urlutil "github.com/italia/publiccode-parser-go/v3 /internal"
10
+ urlutil "github.com/italia/publiccode-parser-go/v4 /internal"
12
11
)
13
12
13
+ type validateFn func (publiccode PublicCode , parser Parser , network bool ) error
14
+
14
15
// validateFields validates publiccode with additional rules not validatable
15
16
// with a simple YAML schema.
16
17
// It returns any error encountered as ValidationResults.
17
- func (p * Parser ) validateFields () error {
18
+ func validateFieldsV0 (publiccode PublicCode , parser Parser , network bool ) error {
19
+ publiccodev0 := publiccode .(PublicCodeV0 )
20
+
18
21
var vr ValidationResults
19
22
var err error
20
23
21
- if (p . PublicCode . URL != nil ) {
22
- if reachable , err := p .isReachable (* (* url .URL )(p . PublicCode . URL )); ! reachable {
23
- vr = append (vr , newValidationError ("url" , "'%s' not reachable: %s" , p . PublicCode .URL , err .Error ()))
24
+ if (publiccodev0 . URL != nil && network ) {
25
+ if reachable , err := parser .isReachable (* (* url .URL )(publiccodev0 . URL ), network ); ! reachable {
26
+ vr = append (vr , newValidationError ("url" , "'%s' not reachable: %s" , publiccodev0 .URL , err .Error ()))
24
27
}
25
- if ! vcsurl .IsRepo ((* url .URL )(p . PublicCode .URL )) {
28
+ if ! vcsurl .IsRepo ((* url .URL )(publiccodev0 .URL )) {
26
29
vr = append (vr , newValidationError ("url" , "is not a valid code repository" ))
27
30
}
28
31
}
29
32
30
- if p . PublicCode .LandingURL != nil {
31
- if reachable , err := p .isReachable (* (* url .URL )(p . PublicCode . LandingURL )); ! reachable {
33
+ if publiccodev0 .LandingURL != nil {
34
+ if reachable , err := parser .isReachable (* (* url .URL )(publiccodev0 . LandingURL ), network ); ! reachable {
32
35
vr = append (vr , newValidationError (
33
36
"landingURL" ,
34
- "'%s' not reachable: %s" , p . PublicCode .LandingURL , err .Error (),
37
+ "'%s' not reachable: %s" , publiccodev0 .LandingURL , err .Error (),
35
38
))
36
39
}
37
40
}
38
41
39
- if p . PublicCode .Roadmap != nil {
40
- if reachable , err := p .isReachable (* (* url .URL )(p . PublicCode . Roadmap )); ! reachable {
42
+ if publiccodev0 .Roadmap != nil {
43
+ if reachable , err := parser .isReachable (* (* url .URL )(publiccodev0 . Roadmap ), network ); ! reachable {
41
44
vr = append (vr , newValidationError (
42
45
"roadmap" ,
43
- "'%s' not reachable: %s" , p . PublicCode .Roadmap , err .Error (),
46
+ "'%s' not reachable: %s" , publiccodev0 .Roadmap , err .Error (),
44
47
))
45
48
}
46
49
}
47
50
48
- if (p . PublicCode .Logo != "" ) {
49
- if validLogo , err := p .validLogo (p . toURL ( p . PublicCode . Logo ) ); ! validLogo {
51
+ if (publiccodev0 .Logo != "" ) {
52
+ if validLogo , err := parser .validLogo (toCodeHostingURL ( publiccodev0 . Logo , parser . baseURL ), parser , network ); ! validLogo {
50
53
vr = append (vr , newValidationError ("logo" , err .Error ()))
51
54
}
52
55
}
53
- if (p . PublicCode .MonochromeLogo != "" ) {
56
+ if (publiccodev0 .MonochromeLogo != "" ) {
54
57
vr = append (vr , ValidationWarning {"monochromeLogo" , "This key is DEPRECATED and will be removed in the future" , 0 , 0 })
55
58
56
- if validLogo , err := p .validLogo (p . toURL ( p . PublicCode . MonochromeLogo ) ); ! validLogo {
59
+ if validLogo , err := parser .validLogo (toCodeHostingURL ( publiccodev0 . MonochromeLogo , parser . baseURL ), parser , network ); ! validLogo {
57
60
vr = append (vr , newValidationError ("monochromeLogo" , err .Error ()))
58
61
}
59
62
}
60
63
61
- if p . PublicCode . Legal .AuthorsFile != nil && ! p .fileExists (p . toURL ( * p . PublicCode . Legal .AuthorsFile ) ) {
62
- u := p . toURL ( * p . PublicCode . Legal .AuthorsFile )
64
+ if publiccodev0 . Legal .AuthorsFile != nil && ! parser .fileExists (toCodeHostingURL ( * publiccodev0 . Legal .AuthorsFile , parser . baseURL ), network ) {
65
+ u := toCodeHostingURL ( * publiccodev0 . Legal .AuthorsFile , parser . baseURL )
63
66
64
67
vr = append (vr , newValidationError ("legal.authorsFile" , "'%s' does not exist" , urlutil .DisplayURL (& u )))
65
68
}
66
69
67
- if p . PublicCode .Legal .License != "" {
68
- _ , err = spdxValidator .Parse (p . PublicCode .Legal .License )
70
+ if publiccodev0 .Legal .License != "" {
71
+ _ , err = spdxValidator .Parse (publiccodev0 .Legal .License )
69
72
if err != nil {
70
73
vr = append (vr , newValidationError (
71
74
"legal.license" ,
72
- "invalid license '%s'" , p . PublicCode .Legal .License ,
75
+ "invalid license '%s'" , publiccodev0 .Legal .License ,
73
76
))
74
77
}
75
78
}
76
79
77
- if p .PublicCode .It .CountryExtensionVersion != "" &&
78
- ! slices .Contains (ExtensionITSupportedVersions , p .PublicCode .It .CountryExtensionVersion ) {
79
-
80
+ if publiccodev0 .It .CountryExtensionVersion != "" && publiccodev0 .It .CountryExtensionVersion != "0.2" {
80
81
vr = append (vr , newValidationError (
81
82
"it.countryExtensionVersion" ,
82
- "version %s not supported for 'it' extension " , p . PublicCode .It .CountryExtensionVersion ,
83
+ "version %s not supported for country-specific section 'it'" , publiccodev0 .It .CountryExtensionVersion ,
83
84
))
84
85
}
85
86
86
- if len (p . PublicCode .InputTypes ) > 0 {
87
+ if len (publiccodev0 .InputTypes ) > 0 {
87
88
vr = append (vr , ValidationWarning {"inputTypes" , "This key is DEPRECATED and will be removed in the future" , 0 , 0 })
88
89
}
89
- for i , mimeType := range p . PublicCode .InputTypes {
90
- if ! p . isMIME (mimeType ) {
90
+ for i , mimeType := range publiccodev0 .InputTypes {
91
+ if ! isMIME (mimeType ) {
91
92
vr = append (vr , newValidationError (
92
93
fmt .Sprintf ("inputTypes[%d]" , i ), "'%s' is not a MIME type" , mimeType ,
93
94
))
94
95
}
95
96
}
96
97
97
- if len (p . PublicCode .OutputTypes ) > 0 {
98
+ if len (publiccodev0 .OutputTypes ) > 0 {
98
99
vr = append (vr , ValidationWarning {"outputTypes" , "This key is DEPRECATED and will be removed in the future" , 0 , 0 })
99
100
}
100
- for i , mimeType := range p . PublicCode .OutputTypes {
101
- if ! p . isMIME (mimeType ) {
101
+ for i , mimeType := range publiccodev0 .OutputTypes {
102
+ if ! isMIME (mimeType ) {
102
103
vr = append (vr , newValidationError (
103
104
fmt .Sprintf ("outputTypes[%d]" , i ), "'%s' is not a MIME type" , mimeType ,
104
105
))
105
106
}
106
107
}
107
108
108
- for lang , desc := range p . PublicCode .Description {
109
- if p . PublicCode .Description == nil {
110
- p . PublicCode . Description = make (map [string ]Desc )
109
+ for lang , desc := range publiccodev0 .Description {
110
+ if publiccodev0 .Description == nil {
111
+ publiccodev0 . Description = make (map [string ]DescV0 )
111
112
}
112
113
113
114
if len (desc .GenericName ) > 0 {
@@ -117,16 +118,16 @@ func (p *Parser) validateFields() error {
117
118
})
118
119
}
119
120
120
- if ( desc .Documentation != nil ) {
121
- if reachable , err := p .isReachable (* (* url .URL )(desc .Documentation )); ! reachable {
121
+ if network && desc .Documentation != nil {
122
+ if reachable , err := parser .isReachable (* (* url .URL )(desc .Documentation ), network ); ! reachable {
122
123
vr = append (vr , newValidationError (
123
124
fmt .Sprintf ("description.%s.documentation" , lang ),
124
125
"'%s' not reachable: %s" , desc .Documentation , err .Error (),
125
126
))
126
127
}
127
128
}
128
- if desc .APIDocumentation != nil {
129
- if reachable , err := p .isReachable (* (* url .URL )(desc .APIDocumentation )); ! reachable {
129
+ if network && desc .APIDocumentation != nil {
130
+ if reachable , err := parser .isReachable (* (* url .URL )(desc .APIDocumentation ), network ); ! reachable {
130
131
vr = append (vr , newValidationError (
131
132
fmt .Sprintf ("description.%s.apiDocumentation" , lang ),
132
133
"'%s' not reachable: %s" , desc .APIDocumentation , err .Error (),
@@ -135,15 +136,15 @@ func (p *Parser) validateFields() error {
135
136
}
136
137
137
138
for i , v := range desc .Screenshots {
138
- if isImage , err := p .isImageFile (p . toURL ( v ) ); ! isImage {
139
+ if isImage , err := parser .isImageFile (toCodeHostingURL ( v , parser . baseURL ), network ); ! isImage {
139
140
vr = append (vr , newValidationError (
140
141
fmt .Sprintf ("description.%s.screenshots[%d]" , lang , i ),
141
142
"'%s' is not an image: %s" , v , err .Error (),
142
143
))
143
144
}
144
145
}
145
146
for i , v := range desc .Videos {
146
- _ , err := p .isOEmbedURL ((* url .URL )(v ))
147
+ _ , err := parser .isOEmbedURL ((* url .URL )(v ))
147
148
if err != nil {
148
149
vr = append (vr , newValidationError (
149
150
fmt .Sprintf ("description.%s.videos[%d]" , lang , i ),
@@ -159,3 +160,7 @@ func (p *Parser) validateFields() error {
159
160
160
161
return vr
161
162
}
163
+
164
+ func validateFieldsV1 (_ PublicCode , _ Parser , _ bool ) error {
165
+ return nil
166
+ }
0 commit comments