11package main
22
33import (
4- "errors"
5- "fmt"
64 "log"
75 "net/url"
86 "os"
97 "path"
108 "slices"
119 "strings"
1210
11+ "golang.org/x/xerrors"
1312 "gopkg.in/yaml.v3"
1413)
1514
@@ -35,7 +34,7 @@ type contributorProfileReadme struct {
3534
3635func validateContributorDisplayName (displayName string ) error {
3736 if displayName == "" {
38- return fmt . Errorf ("missing display_name" )
37+ return xerrors . New ("missing display_name" )
3938 }
4039
4140 return nil
@@ -47,7 +46,7 @@ func validateContributorLinkedinURL(linkedinURL *string) error {
4746 }
4847
4948 if _ , err := url .ParseRequestURI (* linkedinURL ); err != nil {
50- return fmt .Errorf ("linkedIn URL %q is not valid: %v" , * linkedinURL , err )
49+ return xerrors .Errorf ("linkedIn URL %q is not valid: %v" , * linkedinURL , err )
5150 }
5251
5352 return nil
@@ -66,28 +65,28 @@ func validateContributorSupportEmail(email *string) []error {
6665 // pipeline. Best we can do is verify the general structure
6766 username , server , ok := strings .Cut (* email , "@" )
6867 if ! ok {
69- errs = append (errs , fmt .Errorf ("email address %q is missing @ symbol" , * email ))
68+ errs = append (errs , xerrors .Errorf ("email address %q is missing @ symbol" , * email ))
7069 return errs
7170 }
7271
7372 if username == "" {
74- errs = append (errs , fmt .Errorf ("email address %q is missing username" , * email ))
73+ errs = append (errs , xerrors .Errorf ("email address %q is missing username" , * email ))
7574 }
7675
7776 domain , tld , ok := strings .Cut (server , "." )
7877 if ! ok {
79- errs = append (errs , fmt .Errorf ("email address %q is missing period for server segment" , * email ))
78+ errs = append (errs , xerrors .Errorf ("email address %q is missing period for server segment" , * email ))
8079 return errs
8180 }
8281
8382 if domain == "" {
84- errs = append (errs , fmt .Errorf ("email address %q is missing domain" , * email ))
83+ errs = append (errs , xerrors .Errorf ("email address %q is missing domain" , * email ))
8584 }
8685 if tld == "" {
87- errs = append (errs , fmt .Errorf ("email address %q is missing top-level domain" , * email ))
86+ errs = append (errs , xerrors .Errorf ("email address %q is missing top-level domain" , * email ))
8887 }
8988 if strings .Contains (* email , "?" ) {
90- errs = append (errs , errors .New ("email is not allowed to contain query parameters" ))
89+ errs = append (errs , xerrors .New ("email is not allowed to contain query parameters" ))
9190 }
9291
9392 return errs
@@ -99,40 +98,40 @@ func validateContributorWebsite(websiteURL *string) error {
9998 }
10099
101100 if _ , err := url .ParseRequestURI (* websiteURL ); err != nil {
102- return fmt .Errorf ("linkedIn URL %q is not valid: %v" , * websiteURL , err )
101+ return xerrors .Errorf ("linkedIn URL %q is not valid: %v" , * websiteURL , err )
103102 }
104103
105104 return nil
106105}
107106
108107func validateContributorStatus (status string ) error {
109108 if ! slices .Contains (validContributorStatuses , status ) {
110- return fmt .Errorf ("contributor status %q is not valid" , status )
109+ return xerrors .Errorf ("contributor status %q is not valid" , status )
111110 }
112111
113112 return nil
114113}
115114
116115// Can't validate the image actually leads to a valid resource in a pure
117- // function, but can at least catch obvious problems
116+ // function, but can at least catch obvious problems.
118117func validateContributorAvatarURL (avatarURL * string ) []error {
119118 if avatarURL == nil {
120119 return nil
121120 }
122121
123122 errs := []error {}
124123 if * avatarURL == "" {
125- errs = append (errs , errors .New ("avatar URL must be omitted or non-empty string" ))
124+ errs = append (errs , xerrors .New ("avatar URL must be omitted or non-empty string" ))
126125 return errs
127126 }
128127
129128 // Have to use .Parse instead of .ParseRequestURI because this is the
130129 // one field that's allowed to be a relative URL
131130 if _ , err := url .Parse (* avatarURL ); err != nil {
132- errs = append (errs , fmt .Errorf ("URL %q is not a valid relative or absolute URL" , * avatarURL ))
131+ errs = append (errs , xerrors .Errorf ("URL %q is not a valid relative or absolute URL" , * avatarURL ))
133132 }
134133 if strings .Contains (* avatarURL , "?" ) {
135- errs = append (errs , errors .New ("avatar URL is not allowed to contain search parameters" ))
134+ errs = append (errs , xerrors .New ("avatar URL is not allowed to contain search parameters" ))
136135 }
137136
138137 matched := false
@@ -145,7 +144,7 @@ func validateContributorAvatarURL(avatarURL *string) []error {
145144 if ! matched {
146145 segments := strings .Split (* avatarURL , "." )
147146 fileExtension := segments [len (segments )- 1 ]
148- errs = append (errs , fmt .Errorf ("avatar URL '.%s' does not end in a supported file format: [%s]" , fileExtension , strings .Join (supportedAvatarFileFormats , ", " )))
147+ errs = append (errs , xerrors .Errorf ("avatar URL '.%s' does not end in a supported file format: [%s]" , fileExtension , strings .Join (supportedAvatarFileFormats , ", " )))
149148 }
150149
151150 return errs
@@ -180,12 +179,12 @@ func validateContributorReadme(rm contributorProfileReadme) []error {
180179func parseContributorProfile (rm readme ) (contributorProfileReadme , error ) {
181180 fm , _ , err := separateFrontmatter (rm .rawText )
182181 if err != nil {
183- return contributorProfileReadme {}, fmt .Errorf ("%q: failed to parse frontmatter: %v" , rm .filePath , err )
182+ return contributorProfileReadme {}, xerrors .Errorf ("%q: failed to parse frontmatter: %v" , rm .filePath , err )
184183 }
185184
186185 yml := contributorProfileFrontmatter {}
187186 if err := yaml .Unmarshal ([]byte (fm ), & yml ); err != nil {
188- return contributorProfileReadme {}, fmt .Errorf ("%q: failed to parse: %v" , rm .filePath , err )
187+ return contributorProfileReadme {}, xerrors .Errorf ("%q: failed to parse: %v" , rm .filePath , err )
189188 }
190189
191190 return contributorProfileReadme {
@@ -206,7 +205,7 @@ func parseContributorFiles(readmeEntries []readme) (map[string]contributorProfil
206205 }
207206
208207 if prev , alreadyExists := profilesByNamespace [p .namespace ]; alreadyExists {
209- yamlParsingErrors = append (yamlParsingErrors , fmt .Errorf ("%q: namespace %q conflicts with namespace from %q" , p .filePath , p .namespace , prev .filePath ))
208+ yamlParsingErrors = append (yamlParsingErrors , xerrors .Errorf ("%q: namespace %q conflicts with namespace from %q" , p .filePath , p .namespace , prev .filePath ))
210209 continue
211210 }
212211 profilesByNamespace [p .namespace ] = p
@@ -291,15 +290,15 @@ func validateContributorRelativeUrls(contributors map[string]contributorProfileR
291290 }
292291
293292 if strings .HasPrefix (* con .frontmatter .AvatarURL , ".." ) {
294- errs = append (errs , fmt .Errorf ("%q: relative avatar URLs cannot be placed outside a user's namespaced directory" , con .filePath ))
293+ errs = append (errs , xerrors .Errorf ("%q: relative avatar URLs cannot be placed outside a user's namespaced directory" , con .filePath ))
295294 continue
296295 }
297296
298297 absolutePath := strings .TrimSuffix (con .filePath , "README.md" ) +
299298 * con .frontmatter .AvatarURL
300299 _ , err := os .ReadFile (absolutePath )
301300 if err != nil {
302- errs = append (errs , fmt .Errorf ("%q: relative avatar path %q does not point to image in file system" , con .filePath , * con .frontmatter .AvatarURL ))
301+ errs = append (errs , xerrors .Errorf ("%q: relative avatar path %q does not point to image in file system" , con .filePath , * con .frontmatter .AvatarURL ))
303302 }
304303 }
305304
0 commit comments