Skip to content

Commit fc2fc0a

Browse files
authored
Add parse line (#18)
1 parent 54479a1 commit fc2fc0a

4 files changed

Lines changed: 88 additions & 11 deletions

File tree

codeowners.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,30 @@
11
// Package codeowners provides funcionality to evaluate CODEOWNERS file.
22
package codeowners // import "github.com/fmenezes/codeowners"
33

4+
import (
5+
"strings"
6+
"unicode"
7+
)
8+
49
// DefaultLocations provides default locations for the CODEOWNERS file
510
var DefaultLocations = [...]string{"CODEOWNERS", "docs/CODEOWNERS", ".github/CODEOWNERS"}
11+
12+
// ParseLine parses a CODEOWNERS line into file pattern and owners
13+
func ParseLine(line string) (string, []string) {
14+
line = sanitiseLine(line)
15+
16+
var previousRune rune
17+
data := strings.FieldsFunc(line, func(r rune) bool {
18+
result := unicode.IsSpace(r) && previousRune != '\\'
19+
previousRune = r
20+
return result
21+
})
22+
23+
if len(data) > 1 {
24+
return data[0], data[1:]
25+
} else if len(data) == 1 {
26+
return data[0], nil
27+
} else {
28+
return "", nil
29+
}
30+
}

codeowners_test.go

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
package codeowners_test
2+
3+
import (
4+
"reflect"
5+
"testing"
6+
7+
"github.com/fmenezes/codeowners"
8+
)
9+
10+
func TestParseLine(t *testing.T) {
11+
testCases := []struct {
12+
input string
13+
wantPattern string
14+
wantOwners []string
15+
}{
16+
{
17+
input: "* test@example.org",
18+
wantPattern: "*",
19+
wantOwners: []string{"test@example.org"},
20+
},
21+
{
22+
input: "filepattern test@example.org @owner @company/team",
23+
wantPattern: "filepattern",
24+
wantOwners: []string{"test@example.org", "@owner", "@company/team"},
25+
},
26+
{
27+
input: "file\\ with\\ spaces @owner",
28+
wantPattern: "file\\ with\\ spaces",
29+
wantOwners: []string{"@owner"},
30+
},
31+
{
32+
input: " filepattern ",
33+
wantPattern: "filepattern",
34+
wantOwners: nil,
35+
},
36+
{
37+
input: "filepattern @owner # comments",
38+
wantPattern: "filepattern",
39+
wantOwners: []string{"@owner"},
40+
},
41+
{
42+
input: "",
43+
wantPattern: "",
44+
wantOwners: nil,
45+
},
46+
{
47+
input: "# only comments on the line",
48+
wantPattern: "",
49+
wantOwners: nil,
50+
},
51+
}
52+
53+
for _, testCase := range testCases {
54+
gotPattern, gotOwners := codeowners.ParseLine(testCase.input)
55+
if gotPattern != testCase.wantPattern || !reflect.DeepEqual(gotOwners, testCase.wantOwners) {
56+
t.Errorf("Input: %s, Want: %s, %v, Got: %s, %v", testCase.input, testCase.wantPattern, testCase.wantOwners, gotPattern, gotOwners)
57+
}
58+
}
59+
}

decoder.go

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -59,18 +59,11 @@ func (d *Decoder) More() bool {
5959
// If More was never called it will return an empty token.
6060
// After end of file Token will always return the last line.
6161
func (d *Decoder) Token() (Token, int) {
62-
line := sanitiseLine(d.line)
63-
line = strings.ReplaceAll(line, "\\ ", "\\s")
64-
65-
data := strings.Split(line, " ")
66-
67-
for i := range data {
68-
data[i] = strings.ReplaceAll(data[i], "\\s", " ")
69-
}
62+
pattern, owners := ParseLine(d.line)
7063

7164
return Token{
72-
path: data[0],
73-
owners: data[1:],
65+
path: pattern,
66+
owners: owners,
7467
}, d.lineNo
7568
}
7669

decoder_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ func TestMultipleOwners(t *testing.T) {
4646

4747
func TestFilesWithSpaces(t *testing.T) {
4848
assert(t, `file\ with\ spaces @owner`, [][]string{
49-
{"1", "file with spaces", "@owner"},
49+
{"1", "file\\ with\\ spaces", "@owner"},
5050
})
5151
}
5252

0 commit comments

Comments
 (0)