Browse Source

Linkify/Expand commits

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
pull/221/head
Michael Telatynski 7 years ago
parent
commit
a31aaab46e
  1. 104
      src/github.com/matrix-org/go-neb/services/github/github.go

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

@ -26,10 +26,18 @@ import (
// ServiceType of the Github service // ServiceType of the Github service
const ServiceType = "github" const ServiceType = "github"
// Optionally matches alphanumeric then a /, then more alphanumeric
// Used as a base for the expansion regexes below.
var ownerRepoBaseRegex = `(?:(?:([A-z0-9-_.]+)/([A-z0-9-_.]+))|\B)`
// Matches alphanumeric then a /, then more alphanumeric then a #, then a number. // Matches alphanumeric then a /, then more alphanumeric then a #, then a number.
// E.g. owner/repo#11 (issue/PR numbers) - Captured groups for owner/repo/number // E.g. owner/repo#11 (issue/PR numbers) - Captured groups for owner/repo/number
// Does not match things like #3dprinting and testing#1234 (incomplete owner/repo format) // Does not match things like #3dprinting and testing#1234 (incomplete owner/repo format)
var ownerRepoIssueRegex = regexp.MustCompile(`(?:(?:([A-z0-9-_.]+)/([A-z0-9-_.]+))|\B)#([0-9]+)\b`)
var ownerRepoIssueRegex = regexp.MustCompile(ownerRepoBaseRegex + `#([0-9]+)\b`)
// Matches alphanumeric then a /, then more alphanumeric then a @, then a hex string.
// E.g. owner/repo@deadbeef1234 (commit hash) - Captured groups for owner/repo/hash
var ownerRepoCommitRegex = regexp.MustCompile(ownerRepoBaseRegex + `@([0-9a-fA-F]+)\b`)
// Matches like above, but anchored to start and end of the string respectively. // Matches like above, but anchored to start and end of the string respectively.
var ownerRepoIssueRegexAnchored = regexp.MustCompile(`^(([A-z0-9-_.]+)/([A-z0-9-_.]+))?#([0-9]+)$`) var ownerRepoIssueRegexAnchored = regexp.MustCompile(`^(([A-z0-9-_.]+)/([A-z0-9-_.]+))?#([0-9]+)$`)
@ -81,7 +89,7 @@ func (s *Service) requireGithubClientFor(userID string) (cli *gogithub.Client, r
} }
const numberGithubSearchSummaries = 3 const numberGithubSearchSummaries = 3
const cmdGithubSearchUsage = `!github create owner/repo "search query"`
const cmdGithubSearchUsage = `!github search "search query"`
func (s *Service) cmdGithubSearch(roomID, userID string, args []string) (interface{}, error) { func (s *Service) cmdGithubSearch(roomID, userID string, args []string) (interface{}, error) {
cli := s.githubClientFor(userID, true) cli := s.githubClientFor(userID, true)
@ -89,7 +97,7 @@ func (s *Service) cmdGithubSearch(roomID, userID string, args []string) (interfa
return &gomatrix.TextMessage{"m.notice", "Usage: " + cmdGithubSearchUsage}, nil return &gomatrix.TextMessage{"m.notice", "Usage: " + cmdGithubSearchUsage}, nil
} }
query := fmt.Sprintf("repo:%s %s", args[0], strings.Join(args[1:], " "))
query := strings.Join(args, " ")
searchResult, res, err := cli.Search.Issues(query, nil) searchResult, res, err := cli.Search.Issues(query, nil)
if err != nil { if err != nil {
@ -426,6 +434,58 @@ func (s *Service) expandIssue(roomID, userID, owner, repo string, issueNum int)
} }
} }
func (s *Service) expandCommit(roomID, userID, owner, repo, sha string) interface{} {
cli := s.githubClientFor(userID, true)
c, _, err := cli.Repositories.GetCommit(owner, repo, sha)
if err != nil {
log.WithError(err).WithFields(log.Fields{
"owner": owner,
"repo": repo,
"sha": sha,
}).Print("Failed to fetch commit")
return nil
}
commit := c.Commit
var htmlBuffer bytes.Buffer
var plainBuffer bytes.Buffer
shortUrl := strings.TrimSuffix(*c.HTMLURL, *c.SHA) + sha
htmlBuffer.WriteString(fmt.Sprintf("<a href=\"%s\">%s</a><br />", *c.HTMLURL, shortUrl))
plainBuffer.WriteString(fmt.Sprintf("%s\n", shortUrl))
if c.Stats != nil {
htmlBuffer.WriteString(fmt.Sprintf("[<strong><font color='#1cc3ed'>~%d</font>, <font color='#30bf2b'>+%d</font>, <font color='#fc3a25'>-%d</font></strong>] ", len(c.Files), *c.Stats.Additions, *c.Stats.Deletions))
plainBuffer.WriteString(fmt.Sprintf("[~%d, +%d, -%d] ", len(c.Files), *c.Stats.Additions, *c.Stats.Deletions))
}
if commit.Author != nil {
authorName := ""
if commit.Author.Name != nil {
authorName = *commit.Author.Name
} else if commit.Author.Login != nil {
authorName = *commit.Author.Login
}
htmlBuffer.WriteString(fmt.Sprintf("%s: ", authorName))
plainBuffer.WriteString(fmt.Sprintf("%s: ", authorName))
}
if commit.Message != nil {
segs := strings.SplitN(*commit.Message, "\n", 2)
htmlBuffer.WriteString(segs[0])
plainBuffer.WriteString(segs[0])
}
return &gomatrix.HTMLMessage{
Body: plainBuffer.String(),
MsgType: "m.notice",
Format: "org.matrix.custom.html",
FormattedBody: htmlBuffer.String(),
}
}
// Commands supported: // Commands supported:
// !github create owner/repo "issue title" "optional issue description" // !github create owner/repo "issue title" "optional issue description"
// Responds with the outcome of the issue creation request. This command requires // Responds with the outcome of the issue creation request. This command requires
@ -541,6 +601,44 @@ func (s *Service) Expansions(cli *gomatrix.Client) []types.Expansion {
return s.expandIssue(roomID, userID, matchingGroups[1], matchingGroups[2], num) return s.expandIssue(roomID, userID, matchingGroups[1], matchingGroups[2], num)
}, },
}, },
types.Expansion{
Regexp: ownerRepoCommitRegex,
Expand: func(roomID, userID string, matchingGroups []string) interface{} {
// There's an optional group in the regex so matchingGroups can look like:
// [foo/bar@a123 foo bar a123]
// [@a123 a123]
if len(matchingGroups) != 4 {
log.WithField("groups", matchingGroups).WithField("len", len(matchingGroups)).Print(
"Unexpected number of groups",
)
return nil
}
if matchingGroups[1] == "" && matchingGroups[2] == "" {
// issue only match, this only works if there is a default repo
defaultRepo := s.defaultRepo(roomID)
if defaultRepo == "" {
return nil
}
segs := strings.Split(defaultRepo, "/")
if len(segs) != 2 {
log.WithFields(log.Fields{
"room_id": roomID,
"default_repo": defaultRepo,
}).Error("Default repo is malformed")
return nil
}
// Fill in the missing fields in matching groups and fall through into ["foo/bar@a123", "foo", "bar", "a123"]
matchingGroups = []string{
defaultRepo + matchingGroups[0],
segs[0],
segs[1],
matchingGroups[3],
}
}
return s.expandCommit(roomID, userID, matchingGroups[1], matchingGroups[2], matchingGroups[3])
},
},
} }
} }

Loading…
Cancel
Save