Merge pull request #24 from infosiftr/maintainer-struct

Add explicit Manifest2822Maintainer struct
This commit is contained in:
yosifkit 2021-02-01 16:29:58 -08:00 committed by GitHub
commit e7cedb7a54
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 56 additions and 6 deletions

View File

@ -57,7 +57,11 @@ func ParseLineBased(readerIn io.Reader) (*Manifest2822, error) {
maintainerLine := strings.TrimPrefix(line, "# maintainer: ") maintainerLine := strings.TrimPrefix(line, "# maintainer: ")
if line != maintainerLine { if line != maintainerLine {
// if the prefix was removed, it must be a maintainer line! // if the prefix was removed, it must be a maintainer line!
manifest.Global.Maintainers = append(manifest.Global.Maintainers, maintainerLine) maintainer := Manifest2822Maintainer{}
if err := maintainer.UnmarshalControl(maintainerLine); err != nil {
return nil, err
}
manifest.Global.Maintainers = append(manifest.Global.Maintainers, maintainer)
} }
} else { } else {
entry, parseErr := ParseLineBasedLine(line, manifest.Global) entry, parseErr := ParseLineBasedLine(line, manifest.Global)

View File

@ -13,8 +13,24 @@ func TestParseError(t *testing.T) {
man, err := manifest.Parse(strings.NewReader(invalidManifest)) man, err := manifest.Parse(strings.NewReader(invalidManifest))
if err == nil { if err == nil {
t.Errorf("Expected error, got valid manifest instead:\n%s", man) t.Errorf("Expected error, got valid manifest instead:\n%s", man)
return
} }
if !strings.HasPrefix(err.Error(), "Bad line:") { if !strings.HasPrefix(err.Error(), "Bad line:") {
t.Errorf("Unexpected error: %v", err) t.Errorf("Unexpected error: %v", err)
return
}
}
func TestInvalidMaintainer(t *testing.T) {
testManifest := `Maintainers: Valid Name (@valid-handle), Valid Name <valid-email> (@valid-handle), Invalid Maintainer (invalid-handle)`
man, err := manifest.Parse(strings.NewReader(testManifest))
if err == nil {
t.Errorf("Expected error, got valid manifest instead:\n%s", man)
return
}
if !strings.HasPrefix(err.Error(), "invalid Maintainers:") {
t.Errorf("Unexpected error: %v", err)
return
} }
} }

View File

@ -31,7 +31,7 @@ type Manifest2822 struct {
type Manifest2822Entry struct { type Manifest2822Entry struct {
control.Paragraph control.Paragraph
Maintainers []string `delim:"," strip:"\n\r\t "` Maintainers []Manifest2822Maintainer `delim:"," strip:"\n\r\t "`
Tags []string `delim:"," strip:"\n\r\t "` Tags []string `delim:"," strip:"\n\r\t "`
SharedTags []string `delim:"," strip:"\n\r\t "` SharedTags []string `delim:"," strip:"\n\r\t "`
@ -53,6 +53,12 @@ type Manifest2822Entry struct {
Constraints []string `delim:"," strip:"\n\r\t "` Constraints []string `delim:"," strip:"\n\r\t "`
} }
type Manifest2822Maintainer struct {
Name string
Email string
Handle string
}
var ( var (
DefaultArchitecture = "amd64" DefaultArchitecture = "amd64"
@ -75,7 +81,7 @@ func deepCopyStringsMap(a map[string]string) map[string]string {
func (entry Manifest2822Entry) Clone() Manifest2822Entry { func (entry Manifest2822Entry) Clone() Manifest2822Entry {
// SLICES! grr // SLICES! grr
entry.Maintainers = append([]string{}, entry.Maintainers...) entry.Maintainers = append([]Manifest2822Maintainer{}, entry.Maintainers...)
entry.Tags = append([]string{}, entry.Tags...) entry.Tags = append([]string{}, entry.Tags...)
entry.SharedTags = append([]string{}, entry.SharedTags...) entry.SharedTags = append([]string{}, entry.SharedTags...)
entry.Architectures = append([]string{}, entry.Architectures...) entry.Architectures = append([]string{}, entry.Architectures...)
@ -104,7 +110,11 @@ func (entry *Manifest2822Entry) CleanDirectoryValues() {
const StringSeparator2822 = ", " const StringSeparator2822 = ", "
func (entry Manifest2822Entry) MaintainersString() string { func (entry Manifest2822Entry) MaintainersString() string {
return strings.Join(entry.Maintainers, StringSeparator2822) maintainers := []string{}
for _, maint := range entry.Maintainers {
maintainers = append(maintainers, maint.String())
}
return strings.Join(maintainers, StringSeparator2822)
} }
func (entry Manifest2822Entry) TagsString() string { func (entry Manifest2822Entry) TagsString() string {
@ -454,11 +464,31 @@ var (
MaintainersRegex = regexp.MustCompile(`^(` + MaintainersNameRegex + `)(?:\s+<(` + MaintainersEmailRegex + `)>)?\s+[(]@(` + MaintainersGitHubRegex + `)[)]$`) MaintainersRegex = regexp.MustCompile(`^(` + MaintainersNameRegex + `)(?:\s+<(` + MaintainersEmailRegex + `)>)?\s+[(]@(` + MaintainersGitHubRegex + `)[)]$`)
) )
func (maint Manifest2822Maintainer) String() string {
ret := []string{maint.Name}
if maint.Email != "" {
ret = append(ret, "<"+maint.Email+">")
}
ret = append(ret, "(@"+maint.Handle+")")
return strings.Join(ret, " ")
}
func (maint *Manifest2822Maintainer) UnmarshalControl(data string) error {
if matches := MaintainersRegex.FindStringSubmatch(data); len(matches) > 0 {
maint.Name = matches[1]
maint.Email = matches[2]
maint.Handle = matches[3]
return nil
}
return fmt.Errorf("invalid Maintainers: %q (expected format %q)", data, MaintainersFormat)
}
func (entry Manifest2822Entry) InvalidMaintainers() []string { func (entry Manifest2822Entry) InvalidMaintainers() []string {
invalid := []string{} invalid := []string{}
for _, maintainer := range entry.Maintainers { for _, maintainer := range entry.Maintainers {
if !MaintainersRegex.MatchString(maintainer) { // normally these would already be caught by the parsing regex, but just in case someone made an invalid object by hand or something, let's re-validate
invalid = append(invalid, maintainer) if maintainer.Name == "" || maintainer.Handle == "" {
invalid = append(invalid, maintainer.String())
} }
} }
return invalid return invalid