Skip to content

Commit

Permalink
GitHub Subscribe Organization (#52)
Browse files Browse the repository at this point in the history
* Adding in logic for allowing subscribing to all of an organizations repos in one command.  Specifically /github subscribe org [orgname]

* Support for full github URL path to organization in addition to just organization name.  I.e /github subscribe org https://github.com/mattermost will now work

* Change name of method from SubscribeAll to SubscribeOrg

* Removing 'org' requirement and factoring github owner / repo check in command to see if it is an org or just a repo

* Updated COMMAND_HELP with info about subscribe org command

* Adding test cases for parseOwnerAndRepo method

* Organization typo fix

* Accidently committed server/main
  • Loading branch information
benschuster788 authored and levb committed Mar 1, 2019
1 parent e3f9a62 commit 0697d61
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 9 deletions.
15 changes: 12 additions & 3 deletions server/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ const COMMAND_HELP = `* |/github connect| - Connect your Mattermost account to y
* |/github disconnect| - Disconnect your Mattermost account from your GitHub account
* |/github todo| - Get a list of unread messages and pull requests awaiting your review
* |/github subscribe list| - Will list the current channel subscriptions
* |/github subscribe owner [features]| - Subscribe the current channel to all available repositories within an organization and receive notifications about opened pull requests and issues
* |/github subscribe owner/repo [features]| - Subscribe the current channel to receive notifications about opened pull requests and issues for a repository
* |features| is a comma-delimited list of one or more the following:
* issues - includes new and closed issues
Expand Down Expand Up @@ -96,8 +97,10 @@ func (p *Plugin) ExecuteCommand(c *plugin.Context, args *model.CommandArgs) (*mo

switch action {
case "subscribe":
config := p.getConfiguration()
features := "pulls,issues,creates,deletes"

txt := ""
if len(parameters) == 0 {
return getCommandResponse(model.COMMAND_RESPONSE_TYPE_EPHEMERAL, "Please specify a repository or 'list' command."), nil
} else if len(parameters) == 1 && parameters[0] == "list" {
Expand All @@ -106,7 +109,6 @@ func (p *Plugin) ExecuteCommand(c *plugin.Context, args *model.CommandArgs) (*mo
return getCommandResponse(model.COMMAND_RESPONSE_TYPE_EPHEMERAL, err.Error()), nil
}

txt := ""
if len(subs) == 0 {
txt = "Currently there are no subscriptions in this channel"
} else {
Expand All @@ -120,9 +122,16 @@ func (p *Plugin) ExecuteCommand(c *plugin.Context, args *model.CommandArgs) (*mo
features = strings.Join(parameters[1:], " ")
}

repo := parameters[0]
_, owner, repo := parseOwnerAndRepo(parameters[0], config.EnterpriseBaseURL)
if repo == "" {
if err := p.SubscribeOrg(context.Background(), githubClient, args.UserId, owner, args.ChannelId, features); err != nil {
return getCommandResponse(model.COMMAND_RESPONSE_TYPE_EPHEMERAL, err.Error()), nil
}

return getCommandResponse(model.COMMAND_RESPONSE_TYPE_EPHEMERAL, fmt.Sprintf("Successfully subscribed to organization %s.", owner)), nil
}

if err := p.Subscribe(context.Background(), githubClient, args.UserId, repo, args.ChannelId, features); err != nil {
if err := p.Subscribe(context.Background(), githubClient, args.UserId, owner, repo, args.ChannelId, features); err != nil {
return getCommandResponse(model.COMMAND_RESPONSE_TYPE_EPHEMERAL, err.Error()), nil
}

Expand Down
41 changes: 36 additions & 5 deletions server/subscriptions.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,7 @@ func (s *Subscription) Label() string {
return labelSplit[1]
}

func (p *Plugin) Subscribe(ctx context.Context, githubClient *github.Client, userId, ownerAndRepo, channelID, features string) error {
config := p.getConfiguration()

_, owner, repo := parseOwnerAndRepo(ownerAndRepo, config.EnterpriseBaseURL)

func (p *Plugin) Subscribe(ctx context.Context, githubClient *github.Client, userId, owner, repo, channelID, features string) error {
if owner == "" {
return fmt.Errorf("Invalid repository")
}
Expand Down Expand Up @@ -102,6 +98,41 @@ func (p *Plugin) Subscribe(ctx context.Context, githubClient *github.Client, use
return nil
}

func (p *Plugin) SubscribeOrg(ctx context.Context, githubClient *github.Client, userId, org, channelID, features string) error {
if org == "" {
return fmt.Errorf("Invalid organization")
}
if err := p.checkOrg(org); err != nil {
return err
}

listOrgOptions := github.RepositoryListByOrgOptions{
Type: "all",
}
repos, _, err := githubClient.Repositories.ListByOrg(ctx, org, &listOrgOptions)
if repos == nil || err != nil {
if err != nil {
mlog.Error(err.Error())
}
return fmt.Errorf("Unknown organization %s", org)
}

for _, repo := range repos {
sub := &Subscription{
ChannelID: channelID,
CreatorID: userId,
Features: features,
Repository: fmt.Sprintf("%s/%s", org, repo.GetFullName()),
}

if err := p.AddSubscription(fmt.Sprintf("%s/%s", org, repo), sub); err != nil {
continue
}
}

return nil
}

func (p *Plugin) GetSubscriptionsByChannel(channelID string) ([]*Subscription, error) {
var filteredSubs []*Subscription
subs, err := p.GetSubscriptions()
Expand Down
6 changes: 5 additions & 1 deletion server/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,11 @@ func parseOwnerAndRepo(full, baseURL string) (string, string, string) {
}
full = strings.TrimSuffix(strings.TrimSpace(strings.Replace(full, baseURL, "", 1)), "/")
splitStr := strings.Split(full, "/")
if len(splitStr) != 2 {

if len(splitStr) == 1 {
owner := splitStr[0]
return fmt.Sprintf("%s", owner), owner, ""
} else if len(splitStr) != 2 {
return "", "", ""
}
owner := splitStr[0]
Expand Down
28 changes: 28 additions & 0 deletions server/utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,31 @@ func TestFixGithubNotificationSubjectURL(t *testing.T) {
assert.Equal(t, tc.Expected, fixGithubNotificationSubjectURL(tc.Text))
}
}

func TestParseOwnerAndRepo(t *testing.T) {
tcs := []struct {
Full string
BaseURL string
ExpectedOwner string
ExpectedRepo string
}{
{Full: "mattermost", BaseURL: "", ExpectedOwner: "mattermost", ExpectedRepo: ""},
{Full: "mattermost", BaseURL: "https://github.com/", ExpectedOwner: "mattermost", ExpectedRepo: ""},
{Full: "https://github.com/mattermost", BaseURL: "", ExpectedOwner: "mattermost", ExpectedRepo: ""},
{Full: "https://github.com/mattermost", BaseURL: "https://github.com/", ExpectedOwner: "mattermost", ExpectedRepo: ""},
{Full: "mattermost/mattermost-server", BaseURL: "", ExpectedOwner: "mattermost", ExpectedRepo: "mattermost-server"},
{Full: "mattermost/mattermost-server", BaseURL: "https://github.com/", ExpectedOwner: "mattermost", ExpectedRepo: "mattermost-server"},
{Full: "https://github.com/mattermost/mattermost-server", BaseURL: "", ExpectedOwner: "mattermost", ExpectedRepo: "mattermost-server"},
{Full: "https://github.com/mattermost/mattermost-server", BaseURL: "https://github.com/", ExpectedOwner: "mattermost", ExpectedRepo: "mattermost-server"},
{Full: "", BaseURL: "", ExpectedOwner: "", ExpectedRepo: ""},
{Full: "mattermost/mattermost/invalid_repo_url", BaseURL: "", ExpectedOwner: "", ExpectedRepo: ""},
{Full: "https://github.com/mattermost/mattermost/invalid_repo_url", BaseURL: "", ExpectedOwner: "", ExpectedRepo: ""},
}

for _, tc := range tcs {
_, owner, repo := parseOwnerAndRepo(tc.Full, tc.BaseURL)

assert.Equal(t, owner, tc.ExpectedOwner)
assert.Equal(t, repo, tc.ExpectedRepo)
}
}

0 comments on commit 0697d61

Please sign in to comment.