Browse Source

Change Expansion.Expand to include matching groups rather than just the match

kegan/expand-with-groups
Kegan Dougal 8 years ago
parent
commit
928a243ad2
  1. 7
      src/github.com/matrix-org/go-neb/plugin/plugin.go
  2. 14
      src/github.com/matrix-org/go-neb/plugin/plugin_test.go
  3. 36
      src/github.com/matrix-org/go-neb/services/github/github.go
  4. 20
      src/github.com/matrix-org/go-neb/services/jira/jira.go

7
src/github.com/matrix-org/go-neb/plugin/plugin.go

@ -31,7 +31,7 @@ type Command struct {
// the appropriate RFC. // the appropriate RFC.
type Expansion struct { type Expansion struct {
Regexp *regexp.Regexp Regexp *regexp.Regexp
Expand func(roomID, userID, matchingText string) interface{}
Expand func(roomID, userID string, matchingGroups []string) interface{}
} }
// matches if the arguments start with the path of the command. // matches if the arguments start with the path of the command.
@ -94,13 +94,14 @@ func runExpansionsForPlugin(plugin Plugin, event *matrix.Event, body string) []i
for _, expansion := range plugin.Expansions { for _, expansion := range plugin.Expansions {
matches := map[string]bool{} matches := map[string]bool{}
for _, matchingText := range expansion.Regexp.FindAllString(body, -1) {
for _, matchingGroups := range expansion.Regexp.FindAllStringSubmatch(body, -1) {
matchingText := matchingGroups[0] // first element is always the complete match
if matches[matchingText] { if matches[matchingText] {
// Only expand the first occurance of a matching string // Only expand the first occurance of a matching string
continue continue
} }
matches[matchingText] = true matches[matchingText] = true
if response := expansion.Expand(event.RoomID, event.Sender, matchingText); response != nil {
if response := expansion.Expand(event.RoomID, event.Sender, matchingGroups); response != nil {
responses = append(responses, response) responses = append(responses, response)
} }
} }

14
src/github.com/matrix-org/go-neb/plugin/plugin_test.go

@ -36,11 +36,11 @@ func makeTestResponse(roomID, sender string, arguments []string) interface{} {
type testExpansion struct { type testExpansion struct {
RoomID string RoomID string
UserID string UserID string
MatchingText string
MatchingGroups []string
} }
func makeTestExpansion(roomID, userID, matchingText string) interface{} {
return testExpansion{roomID, userID, matchingText}
func makeTestExpansion(roomID, userID string, matchingGroups []string) interface{} {
return testExpansion{roomID, userID, matchingGroups}
} }
func makeTestPlugin(paths [][]string, regexps []*regexp.Regexp) Plugin { func makeTestPlugin(paths [][]string, regexps []*regexp.Regexp) Plugin {
@ -133,9 +133,9 @@ func TestExpansion(t *testing.T) {
event := makeTestEvent("m.text", "test banana for scale") event := makeTestEvent("m.text", "test banana for scale")
got := runCommands(plugins, event) got := runCommands(plugins, event)
want := []interface{}{ want := []interface{}{
makeTestExpansion(myRoomID, mySender, "anana"),
makeTestExpansion(myRoomID, mySender, "ale"),
makeTestExpansion(myRoomID, mySender, "ban"),
makeTestExpansion(myRoomID, mySender, []string{"anana"}),
makeTestExpansion(myRoomID, mySender, []string{"ale"}),
makeTestExpansion(myRoomID, mySender, []string{"ban"}),
} }
if !reflect.DeepEqual(got, want) { if !reflect.DeepEqual(got, want) {
t.Errorf("runCommands(\nplugins=%+v\nevent=%+v\n)\n%+v\nwanted: %+v", plugins, event, got, want) t.Errorf("runCommands(\nplugins=%+v\nevent=%+v\n)\n%+v\nwanted: %+v", plugins, event, got, want)
@ -151,7 +151,7 @@ func TestExpansionDuplicateMatches(t *testing.T) {
event := makeTestEvent("m.text", "badger badger badger") event := makeTestEvent("m.text", "badger badger badger")
got := runCommands(plugins, event) got := runCommands(plugins, event)
want := []interface{}{ want := []interface{}{
makeTestExpansion(myRoomID, mySender, "badger"),
makeTestExpansion(myRoomID, mySender, []string{"badger"}),
} }
if !reflect.DeepEqual(got, want) { if !reflect.DeepEqual(got, want) {
t.Errorf("runCommands(\nplugins=%+v\nevent=%+v\n)\n%+v\nwanted: %+v", plugins, event, got, want) t.Errorf("runCommands(\nplugins=%+v\nevent=%+v\n)\n%+v\nwanted: %+v", plugins, event, got, want)

36
src/github.com/matrix-org/go-neb/services/github/github.go

@ -102,14 +102,21 @@ func (s *githubService) cmdGithubCreate(roomID, userID string, args []string) (i
return matrix.TextMessage{"m.notice", fmt.Sprintf("Created issue: %s", *issue.HTMLURL)}, nil return matrix.TextMessage{"m.notice", fmt.Sprintf("Created issue: %s", *issue.HTMLURL)}, nil
} }
func (s *githubService) expandIssue(roomID, userID, matchingText string) interface{} {
cli := s.githubClientFor(userID, true)
owner, repo, num, err := ownerRepoNumberFromText(matchingText)
func (s *githubService) expandIssue(roomID, userID string, matchingGroups []string) interface{} {
// matchingGroups => ["foo/bar#11", "foo", "bar", "11"]
if len(matchingGroups) != 4 {
log.WithField("groups", matchingGroups).Print("Unexpected number of groups")
return nil
}
num, err := strconv.Atoi(matchingGroups[3])
if err != nil { if err != nil {
log.WithError(err).WithField("text", matchingText).Print(
"Failed to extract owner,repo,number from matched string")
log.WithField("issue_number", matchingGroups[3]).Print("Bad issue number")
return nil return nil
} }
owner := matchingGroups[1]
repo := matchingGroups[2]
cli := s.githubClientFor(userID, true)
i, _, err := cli.Issues.Get(owner, repo, num) i, _, err := cli.Issues.Get(owner, repo, num)
if err != nil { if err != nil {
@ -140,8 +147,8 @@ func (s *githubService) Plugin(roomID string) plugin.Plugin {
Expansions: []plugin.Expansion{ Expansions: []plugin.Expansion{
plugin.Expansion{ plugin.Expansion{
Regexp: ownerRepoIssueRegex, Regexp: ownerRepoIssueRegex,
Expand: func(roomID, userID, matchingText string) interface{} {
return s.expandIssue(roomID, userID, matchingText)
Expand: func(roomID, userID string, matchingGroups []string) interface{} {
return s.expandIssue(roomID, userID, matchingGroups)
}, },
}, },
}, },
@ -322,21 +329,6 @@ func getTokenForUser(realmID, userID string) (string, error) {
return ghSession.AccessToken, nil return ghSession.AccessToken, nil
} }
// ownerRepoNumberFromText parses a GH issue string that looks like 'owner/repo#11'
// into its constituient parts. Returns: owner, repo, issue#.
func ownerRepoNumberFromText(ownerRepoNumberText string) (string, string, int, error) {
// [full_string, owner, repo, issue_number]
groups := ownerRepoIssueRegex.FindStringSubmatch(ownerRepoNumberText)
if len(groups) != 4 {
return "", "", 0, fmt.Errorf("No match found for '%s'", ownerRepoNumberText)
}
num, err := strconv.Atoi(groups[3])
if err != nil {
return "", "", 0, err
}
return groups[1], groups[2], num, nil
}
func removeHook(logger *log.Entry, cli *github.Client, owner, repo, webhookEndpointURL string) { func removeHook(logger *log.Entry, cli *github.Client, owner, repo, webhookEndpointURL string) {
// Get a list of webhooks for this owner/repo and find the one which has the // Get a list of webhooks for this owner/repo and find the one which has the
// same endpoint URL which is what github uses to determine equivalence. // same endpoint URL which is what github uses to determine equivalence.

20
src/github.com/matrix-org/go-neb/services/jira/jira.go

@ -148,17 +148,15 @@ func (s *jiraService) cmdJiraCreate(roomID, userID string, args []string) (inter
}, nil }, nil
} }
func (s *jiraService) expandIssue(roomID, userID, issueKey string) interface{} {
issueKey = strings.ToUpper(issueKey)
logger := log.WithField("issue_key", issueKey)
// [ISSU-123, ISSU, 123]
groups := issueKeyRegex.FindStringSubmatch(issueKey)
if len(groups) != 3 {
logger.Print("Failed to find issue key")
func (s *jiraService) expandIssue(roomID, userID string, issueKeyGroups []string) interface{} {
// issueKeyGroups => ["SYN-123", "SYN", "123"]
if len(issueKeyGroups) != 3 {
log.WithField("groups", issueKeyGroups).Error("Bad number of groups")
return nil return nil
} }
projectKey := groups[1]
issueKey := strings.ToUpper(issueKeyGroups[0])
logger := log.WithField("issue_key", issueKey)
projectKey := strings.ToUpper(issueKeyGroups[1])
realmID := s.realmIDForProject(roomID, projectKey) realmID := s.realmIDForProject(roomID, projectKey)
if realmID == "" { if realmID == "" {
@ -223,8 +221,8 @@ func (s *jiraService) Plugin(roomID string) plugin.Plugin {
Expansions: []plugin.Expansion{ Expansions: []plugin.Expansion{
plugin.Expansion{ plugin.Expansion{
Regexp: issueKeyRegex, Regexp: issueKeyRegex,
Expand: func(roomID, userID, issueKey string) interface{} {
return s.expandIssue(roomID, userID, issueKey)
Expand: func(roomID, userID string, issueKeyGroups []string) interface{} {
return s.expandIssue(roomID, userID, issueKeyGroups)
}, },
}, },
}, },

Loading…
Cancel
Save