Skip to content

Commit e7cedb7

Browse files
authored
Merge pull request #24 from infosiftr/maintainer-struct
Add explicit Manifest2822Maintainer struct
2 parents 00e281f + 8c7ed36 commit e7cedb7

File tree

3 files changed

+56
-6
lines changed

3 files changed

+56
-6
lines changed

manifest/line-based.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,11 @@ func ParseLineBased(readerIn io.Reader) (*Manifest2822, error) {
5757
maintainerLine := strings.TrimPrefix(line, "# maintainer: ")
5858
if line != maintainerLine {
5959
// if the prefix was removed, it must be a maintainer line!
60-
manifest.Global.Maintainers = append(manifest.Global.Maintainers, maintainerLine)
60+
maintainer := Manifest2822Maintainer{}
61+
if err := maintainer.UnmarshalControl(maintainerLine); err != nil {
62+
return nil, err
63+
}
64+
manifest.Global.Maintainers = append(manifest.Global.Maintainers, maintainer)
6165
}
6266
} else {
6367
entry, parseErr := ParseLineBasedLine(line, manifest.Global)

manifest/parse_test.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,24 @@ func TestParseError(t *testing.T) {
1313
man, err := manifest.Parse(strings.NewReader(invalidManifest))
1414
if err == nil {
1515
t.Errorf("Expected error, got valid manifest instead:\n%s", man)
16+
return
1617
}
1718
if !strings.HasPrefix(err.Error(), "Bad line:") {
1819
t.Errorf("Unexpected error: %v", err)
20+
return
21+
}
22+
}
23+
24+
func TestInvalidMaintainer(t *testing.T) {
25+
testManifest := `Maintainers: Valid Name (@valid-handle), Valid Name <valid-email> (@valid-handle), Invalid Maintainer (invalid-handle)`
26+
27+
man, err := manifest.Parse(strings.NewReader(testManifest))
28+
if err == nil {
29+
t.Errorf("Expected error, got valid manifest instead:\n%s", man)
30+
return
31+
}
32+
if !strings.HasPrefix(err.Error(), "invalid Maintainers:") {
33+
t.Errorf("Unexpected error: %v", err)
34+
return
1935
}
2036
}

manifest/rfc2822.go

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ type Manifest2822 struct {
3131
type Manifest2822Entry struct {
3232
control.Paragraph
3333

34-
Maintainers []string `delim:"," strip:"\n\r\t "`
34+
Maintainers []Manifest2822Maintainer `delim:"," strip:"\n\r\t "`
3535

3636
Tags []string `delim:"," strip:"\n\r\t "`
3737
SharedTags []string `delim:"," strip:"\n\r\t "`
@@ -53,6 +53,12 @@ type Manifest2822Entry struct {
5353
Constraints []string `delim:"," strip:"\n\r\t "`
5454
}
5555

56+
type Manifest2822Maintainer struct {
57+
Name string
58+
Email string
59+
Handle string
60+
}
61+
5662
var (
5763
DefaultArchitecture = "amd64"
5864

@@ -75,7 +81,7 @@ func deepCopyStringsMap(a map[string]string) map[string]string {
7581

7682
func (entry Manifest2822Entry) Clone() Manifest2822Entry {
7783
// SLICES! grr
78-
entry.Maintainers = append([]string{}, entry.Maintainers...)
84+
entry.Maintainers = append([]Manifest2822Maintainer{}, entry.Maintainers...)
7985
entry.Tags = append([]string{}, entry.Tags...)
8086
entry.SharedTags = append([]string{}, entry.SharedTags...)
8187
entry.Architectures = append([]string{}, entry.Architectures...)
@@ -104,7 +110,11 @@ func (entry *Manifest2822Entry) CleanDirectoryValues() {
104110
const StringSeparator2822 = ", "
105111

106112
func (entry Manifest2822Entry) MaintainersString() string {
107-
return strings.Join(entry.Maintainers, StringSeparator2822)
113+
maintainers := []string{}
114+
for _, maint := range entry.Maintainers {
115+
maintainers = append(maintainers, maint.String())
116+
}
117+
return strings.Join(maintainers, StringSeparator2822)
108118
}
109119

110120
func (entry Manifest2822Entry) TagsString() string {
@@ -454,11 +464,31 @@ var (
454464
MaintainersRegex = regexp.MustCompile(`^(` + MaintainersNameRegex + `)(?:\s+<(` + MaintainersEmailRegex + `)>)?\s+[(]@(` + MaintainersGitHubRegex + `)[)]$`)
455465
)
456466

467+
func (maint Manifest2822Maintainer) String() string {
468+
ret := []string{maint.Name}
469+
if maint.Email != "" {
470+
ret = append(ret, "<"+maint.Email+">")
471+
}
472+
ret = append(ret, "(@"+maint.Handle+")")
473+
return strings.Join(ret, " ")
474+
}
475+
476+
func (maint *Manifest2822Maintainer) UnmarshalControl(data string) error {
477+
if matches := MaintainersRegex.FindStringSubmatch(data); len(matches) > 0 {
478+
maint.Name = matches[1]
479+
maint.Email = matches[2]
480+
maint.Handle = matches[3]
481+
return nil
482+
}
483+
return fmt.Errorf("invalid Maintainers: %q (expected format %q)", data, MaintainersFormat)
484+
}
485+
457486
func (entry Manifest2822Entry) InvalidMaintainers() []string {
458487
invalid := []string{}
459488
for _, maintainer := range entry.Maintainers {
460-
if !MaintainersRegex.MatchString(maintainer) {
461-
invalid = append(invalid, maintainer)
489+
// 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
490+
if maintainer.Name == "" || maintainer.Handle == "" {
491+
invalid = append(invalid, maintainer.String())
462492
}
463493
}
464494
return invalid

0 commit comments

Comments
 (0)