Skip to content

Commit 3f2ea5c

Browse files
authored
Accept empty emails in ParsePatchIdentity (#42)
Git is actually more lenient here than I thought. As long as the identity contains the "<>" delimiters, Git will allow an empty email, so we should accept the same thing. I also discovered that an identity with only an email set will use the email as the name, so I've implemented that behavior as well.
1 parent 13e8639 commit 3f2ea5c

File tree

2 files changed

+34
-9
lines changed

2 files changed

+34
-9
lines changed

gitdiff/patch_header.go

+14-7
Original file line numberDiff line numberDiff line change
@@ -82,12 +82,15 @@ func (i PatchIdentity) String() string {
8282
return fmt.Sprintf("%s <%s>", name, i.Email)
8383
}
8484

85-
// ParsePatchIdentity parses a patch identity string. A valid string contains a
86-
// non-empty name followed by an email address in angle brackets. Like Git,
87-
// ParsePatchIdentity does not require that the email address is valid or
88-
// properly formatted, only that it is non-empty. The name must not contain a
89-
// left angle bracket, '<', and the email address must not contain a right
90-
// angle bracket, '>'.
85+
// ParsePatchIdentity parses a patch identity string. A valid string contains
86+
// an optional name followed by an email address in angle brackets. The angle
87+
// brackets must always exist, but may enclose an empty address. At least one
88+
// of the name or the email address must be non-empty. If the string only
89+
// contains an email address, that value is also used as the name.
90+
//
91+
// The name must not contain a left angle bracket, '<', and the email address
92+
// must not contain a right angle bracket, '>'. Otherwise, there are no
93+
// restrictions on the format of either field.
9194
func ParsePatchIdentity(s string) (PatchIdentity, error) {
9295
var emailStart, emailEnd int
9396
for i, c := range s {
@@ -110,7 +113,11 @@ func ParsePatchIdentity(s string) (PatchIdentity, error) {
110113
if emailStart > 0 && emailEnd > 0 {
111114
email = strings.TrimSpace(s[emailStart:emailEnd])
112115
}
113-
if name == "" || email == "" {
116+
if name == "" && email != "" {
117+
name = email
118+
}
119+
120+
if name == "" && email == "" {
114121
return PatchIdentity{}, fmt.Errorf("invalid identity string: %s", s)
115122
}
116123

gitdiff/patch_header_test.go

+20-2
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,32 @@ func TestParsePatchIdentity(t *testing.T) {
3232
3333
},
3434
},
35-
"missingName": {
35+
"onlyEmail": {
3636
Input: "<[email protected]>",
37-
Err: "invalid identity",
37+
Output: PatchIdentity{
38+
39+
40+
},
41+
},
42+
"emptyEmail": {
43+
Input: "Morton Haypenny <>",
44+
Output: PatchIdentity{
45+
Name: "Morton Haypenny",
46+
Email: "",
47+
},
3848
},
3949
"missingEmail": {
4050
Input: "Morton Haypenny",
4151
Err: "invalid identity",
4252
},
53+
"missingNameAndEmptyEmail": {
54+
Input: "<>",
55+
Err: "invalid identity",
56+
},
57+
"empty": {
58+
Input: "",
59+
Err: "invalid identity",
60+
},
4361
"unclosedEmail": {
4462
Input: "Morton Haypenny <[email protected]",
4563
Err: "unclosed email",

0 commit comments

Comments
 (0)