Browse Source

Add github dep

pull/4/head
Kegan Dougal 9 years ago
parent
commit
81818829c8
  1. 14
      vendor/manifest
  2. 67
      vendor/src/github.com/google/go-github/github/activity.go
  3. 287
      vendor/src/github.com/google/go-github/github/activity_events.go
  4. 305
      vendor/src/github.com/google/go-github/github/activity_events_test.go
  5. 222
      vendor/src/github.com/google/go-github/github/activity_notifications.go
  6. 203
      vendor/src/github.com/google/go-github/github/activity_notifications_test.go
  7. 132
      vendor/src/github.com/google/go-github/github/activity_star.go
  8. 171
      vendor/src/github.com/google/go-github/github/activity_star_test.go
  9. 128
      vendor/src/github.com/google/go-github/github/activity_test.go
  10. 136
      vendor/src/github.com/google/go-github/github/activity_watching.go
  11. 183
      vendor/src/github.com/google/go-github/github/activity_watching_test.go
  12. 436
      vendor/src/github.com/google/go-github/github/authorizations.go
  13. 343
      vendor/src/github.com/google/go-github/github/authorizations_test.go
  14. 145
      vendor/src/github.com/google/go-github/github/doc.go
  15. 467
      vendor/src/github.com/google/go-github/github/event_types.go
  16. 75
      vendor/src/github.com/google/go-github/github/examples_test.go
  17. 343
      vendor/src/github.com/google/go-github/github/gists.go
  18. 118
      vendor/src/github.com/google/go-github/github/gists_comments.go
  19. 153
      vendor/src/github.com/google/go-github/github/gists_comments_test.go
  20. 488
      vendor/src/github.com/google/go-github/github/gists_test.go
  21. 12
      vendor/src/github.com/google/go-github/github/git.go
  22. 47
      vendor/src/github.com/google/go-github/github/git_blobs.go
  23. 97
      vendor/src/github.com/google/go-github/github/git_blobs_test.go
  24. 127
      vendor/src/github.com/google/go-github/github/git_commits.go
  25. 83
      vendor/src/github.com/google/go-github/github/git_commits_test.go
  26. 162
      vendor/src/github.com/google/go-github/github/git_refs.go
  27. 280
      vendor/src/github.com/google/go-github/github/git_refs_test.go
  28. 77
      vendor/src/github.com/google/go-github/github/git_tags.go
  29. 68
      vendor/src/github.com/google/go-github/github/git_tags_test.go
  30. 89
      vendor/src/github.com/google/go-github/github/git_trees.go
  31. 189
      vendor/src/github.com/google/go-github/github/git_trees_test.go
  32. 807
      vendor/src/github.com/google/go-github/github/github.go
  33. 865
      vendor/src/github.com/google/go-github/github/github_test.go
  34. 61
      vendor/src/github.com/google/go-github/github/gitignore.go
  35. 58
      vendor/src/github.com/google/go-github/github/gitignore_test.go
  36. 299
      vendor/src/github.com/google/go-github/github/issues.go
  37. 82
      vendor/src/github.com/google/go-github/github/issues_assignees.go
  38. 157
      vendor/src/github.com/google/go-github/github/issues_assignees_test.go
  39. 147
      vendor/src/github.com/google/go-github/github/issues_comments.go
  40. 187
      vendor/src/github.com/google/go-github/github/issues_comments_test.go
  41. 149
      vendor/src/github.com/google/go-github/github/issues_events.go
  42. 83
      vendor/src/github.com/google/go-github/github/issues_events_test.go
  43. 222
      vendor/src/github.com/google/go-github/github/issues_labels.go
  44. 313
      vendor/src/github.com/google/go-github/github/issues_labels_test.go
  45. 146
      vendor/src/github.com/google/go-github/github/issues_milestones.go
  46. 158
      vendor/src/github.com/google/go-github/github/issues_milestones_test.go
  47. 276
      vendor/src/github.com/google/go-github/github/issues_test.go
  48. 148
      vendor/src/github.com/google/go-github/github/issues_timeline.go
  49. 39
      vendor/src/github.com/google/go-github/github/issues_timeline_test.go
  50. 79
      vendor/src/github.com/google/go-github/github/licenses.go
  51. 64
      vendor/src/github.com/google/go-github/github/licenses_test.go
  52. 119
      vendor/src/github.com/google/go-github/github/messages.go
  53. 81
      vendor/src/github.com/google/go-github/github/messages_test.go
  54. 223
      vendor/src/github.com/google/go-github/github/migrations.go
  55. 326
      vendor/src/github.com/google/go-github/github/migrations_source_import.go
  56. 225
      vendor/src/github.com/google/go-github/github/migrations_source_import_test.go
  57. 177
      vendor/src/github.com/google/go-github/github/migrations_test.go
  58. 197
      vendor/src/github.com/google/go-github/github/misc.go
  59. 170
      vendor/src/github.com/google/go-github/github/misc_test.go
  60. 170
      vendor/src/github.com/google/go-github/github/orgs.go
  61. 104
      vendor/src/github.com/google/go-github/github/orgs_hooks.go
  62. 134
      vendor/src/github.com/google/go-github/github/orgs_hooks_test.go
  63. 272
      vendor/src/github.com/google/go-github/github/orgs_members.go
  64. 355
      vendor/src/github.com/google/go-github/github/orgs_members_test.go
  65. 379
      vendor/src/github.com/google/go-github/github/orgs_teams.go
  66. 501
      vendor/src/github.com/google/go-github/github/orgs_teams_test.go
  67. 143
      vendor/src/github.com/google/go-github/github/orgs_test.go
  68. 285
      vendor/src/github.com/google/go-github/github/pulls.go
  69. 156
      vendor/src/github.com/google/go-github/github/pulls_comments.go
  70. 187
      vendor/src/github.com/google/go-github/github/pulls_comments_test.go
  71. 363
      vendor/src/github.com/google/go-github/github/pulls_test.go
  72. 270
      vendor/src/github.com/google/go-github/github/reactions.go
  73. 200
      vendor/src/github.com/google/go-github/github/reactions_test.go
  74. 597
      vendor/src/github.com/google/go-github/github/repos.go
  75. 92
      vendor/src/github.com/google/go-github/github/repos_collaborators.go
  76. 134
      vendor/src/github.com/google/go-github/github/repos_collaborators_test.go
  77. 160
      vendor/src/github.com/google/go-github/github/repos_comments.go
  78. 183
      vendor/src/github.com/google/go-github/github/repos_comments_test.go
  79. 198
      vendor/src/github.com/google/go-github/github/repos_commits.go
  80. 233
      vendor/src/github.com/google/go-github/github/repos_commits_test.go
  81. 275
      vendor/src/github.com/google/go-github/github/repos_contents.go
  82. 412
      vendor/src/github.com/google/go-github/github/repos_contents_test.go
  83. 179
      vendor/src/github.com/google/go-github/github/repos_deployments.go
  84. 118
      vendor/src/github.com/google/go-github/github/repos_deployments_test.go
  85. 73
      vendor/src/github.com/google/go-github/github/repos_forks.go
  86. 73
      vendor/src/github.com/google/go-github/github/repos_forks_test.go
  87. 196
      vendor/src/github.com/google/go-github/github/repos_hooks.go
  88. 187
      vendor/src/github.com/google/go-github/github/repos_hooks_test.go
  89. 91
      vendor/src/github.com/google/go-github/github/repos_invitations.go
  90. 73
      vendor/src/github.com/google/go-github/github/repos_invitations_test.go
  91. 108
      vendor/src/github.com/google/go-github/github/repos_keys.go
  92. 153
      vendor/src/github.com/google/go-github/github/repos_keys_test.go
  93. 37
      vendor/src/github.com/google/go-github/github/repos_merging.go
  94. 47
      vendor/src/github.com/google/go-github/github/repos_merging_test.go
  95. 116
      vendor/src/github.com/google/go-github/github/repos_pages.go
  96. 95
      vendor/src/github.com/google/go-github/github/repos_pages_test.go
  97. 325
      vendor/src/github.com/google/go-github/github/repos_releases.go
  98. 352
      vendor/src/github.com/google/go-github/github/repos_releases_test.go
  99. 214
      vendor/src/github.com/google/go-github/github/repos_stats.go
  100. 210
      vendor/src/github.com/google/go-github/github/repos_stats_test.go

14
vendor/manifest

@ -7,6 +7,20 @@
"revision": "a283a10442df8dc09befd873fab202bf8a253d6a",
"branch": "master"
},
{
"importpath": "github.com/google/go-github/github",
"repository": "https://github.com/google/go-github",
"revision": "b5e5babef39c18002f177a134fc49dc5013374ba",
"branch": "master",
"path": "/github"
},
{
"importpath": "github.com/google/go-querystring/query",
"repository": "https://github.com/google/go-querystring",
"revision": "9235644dd9e52eeae6fa48efd539fdc351a0af53",
"branch": "master",
"path": "/query"
},
{
"importpath": "github.com/mattn/go-shellwords",
"repository": "https://github.com/mattn/go-shellwords",

67
vendor/src/github.com/google/go-github/github/activity.go

@ -0,0 +1,67 @@
// Copyright 2013 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github
// ActivityService handles communication with the activity related
// methods of the GitHub API.
//
// GitHub API docs: http://developer.github.com/v3/activity/
type ActivityService service
// FeedLink represents a link to a related resource.
type FeedLink struct {
HRef *string `json:"href,omitempty"`
Type *string `json:"type,omitempty"`
}
// Feeds represents timeline resources in Atom format.
type Feeds struct {
TimelineURL *string `json:"timeline_url,omitempty"`
UserURL *string `json:"user_url,omitempty"`
CurrentUserPublicURL *string `json:"current_user_public_url,omitempty"`
CurrentUserURL *string `json:"current_user_url,omitempty"`
CurrentUserActorURL *string `json:"current_user_actor_url,omitempty"`
CurrentUserOrganizationURL *string `json:"current_user_organization_url,omitempty"`
CurrentUserOrganizationURLs []string `json:"current_user_organization_urls,omitempty"`
Links *struct {
Timeline *FeedLink `json:"timeline,omitempty"`
User *FeedLink `json:"user,omitempty"`
CurrentUserPublic *FeedLink `json:"current_user_public,omitempty"`
CurrentUser *FeedLink `json:"current_user,omitempty"`
CurrentUserActor *FeedLink `json:"current_user_actor,omitempty"`
CurrentUserOrganization *FeedLink `json:"current_user_organization,omitempty"`
CurrentUserOrganizations []FeedLink `json:"current_user_organizations,omitempty"`
} `json:"_links,omitempty"`
}
// ListFeeds lists all the feeds available to the authenticated user.
//
// GitHub provides several timeline resources in Atom format:
// Timeline: The GitHub global public timeline
// User: The public timeline for any user, using URI template
// Current user public: The public timeline for the authenticated user
// Current user: The private timeline for the authenticated user
// Current user actor: The private timeline for activity created by the
// authenticated user
// Current user organizations: The private timeline for the organizations
// the authenticated user is a member of.
//
// Note: Private feeds are only returned when authenticating via Basic Auth
// since current feed URIs use the older, non revocable auth tokens.
func (s *ActivityService) ListFeeds() (*Feeds, *Response, error) {
req, err := s.client.NewRequest("GET", "feeds", nil)
if err != nil {
return nil, nil, err
}
f := &Feeds{}
resp, err := s.client.Do(req, f)
if err != nil {
return nil, resp, err
}
return f, resp, nil
}

287
vendor/src/github.com/google/go-github/github/activity_events.go

@ -0,0 +1,287 @@
// Copyright 2013 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github
import (
"encoding/json"
"fmt"
"time"
)
// Event represents a GitHub event.
type Event struct {
Type *string `json:"type,omitempty"`
Public *bool `json:"public"`
RawPayload *json.RawMessage `json:"payload,omitempty"`
Repo *Repository `json:"repo,omitempty"`
Actor *User `json:"actor,omitempty"`
Org *Organization `json:"org,omitempty"`
CreatedAt *time.Time `json:"created_at,omitempty"`
ID *string `json:"id,omitempty"`
}
func (e Event) String() string {
return Stringify(e)
}
// Payload returns the parsed event payload. For recognized event types,
// a value of the corresponding struct type will be returned.
func (e *Event) Payload() (payload interface{}) {
switch *e.Type {
case "CommitCommentEvent":
payload = &CommitCommentEvent{}
case "CreateEvent":
payload = &CreateEvent{}
case "DeleteEvent":
payload = &DeleteEvent{}
case "DeploymentEvent":
payload = &DeploymentEvent{}
case "DeploymentStatusEvent":
payload = &DeploymentStatusEvent{}
case "ForkEvent":
payload = &ForkEvent{}
case "GollumEvent":
payload = &GollumEvent{}
case "IssueActivityEvent":
payload = &IssueActivityEvent{}
case "IssueCommentEvent":
payload = &IssueCommentEvent{}
case "IssuesEvent":
payload = &IssuesEvent{}
case "MemberEvent":
payload = &MemberEvent{}
case "MembershipEvent":
payload = &MembershipEvent{}
case "PageBuildEvent":
payload = &PageBuildEvent{}
case "PublicEvent":
payload = &PublicEvent{}
case "PullRequestEvent":
payload = &PullRequestEvent{}
case "PullRequestReviewCommentEvent":
payload = &PullRequestReviewCommentEvent{}
case "PushEvent":
payload = &PushEvent{}
case "ReleaseEvent":
payload = &ReleaseEvent{}
case "RepositoryEvent":
payload = &RepositoryEvent{}
case "StatusEvent":
payload = &StatusEvent{}
case "TeamAddEvent":
payload = &TeamAddEvent{}
case "WatchEvent":
payload = &WatchEvent{}
}
if err := json.Unmarshal(*e.RawPayload, &payload); err != nil {
panic(err.Error())
}
return payload
}
// ListEvents drinks from the firehose of all public events across GitHub.
//
// GitHub API docs: http://developer.github.com/v3/activity/events/#list-public-events
func (s *ActivityService) ListEvents(opt *ListOptions) ([]*Event, *Response, error) {
u, err := addOptions("events", opt)
if err != nil {
return nil, nil, err
}
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
events := new([]*Event)
resp, err := s.client.Do(req, events)
if err != nil {
return nil, resp, err
}
return *events, resp, err
}
// ListRepositoryEvents lists events for a repository.
//
// GitHub API docs: http://developer.github.com/v3/activity/events/#list-repository-events
func (s *ActivityService) ListRepositoryEvents(owner, repo string, opt *ListOptions) ([]*Event, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/events", owner, repo)
u, err := addOptions(u, opt)
if err != nil {
return nil, nil, err
}
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
events := new([]*Event)
resp, err := s.client.Do(req, events)
if err != nil {
return nil, resp, err
}
return *events, resp, err
}
// ListIssueEventsForRepository lists issue events for a repository.
//
// GitHub API docs: http://developer.github.com/v3/activity/events/#list-issue-events-for-a-repository
func (s *ActivityService) ListIssueEventsForRepository(owner, repo string, opt *ListOptions) ([]*Event, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/issues/events", owner, repo)
u, err := addOptions(u, opt)
if err != nil {
return nil, nil, err
}
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
events := new([]*Event)
resp, err := s.client.Do(req, events)
if err != nil {
return nil, resp, err
}
return *events, resp, err
}
// ListEventsForRepoNetwork lists public events for a network of repositories.
//
// GitHub API docs: http://developer.github.com/v3/activity/events/#list-public-events-for-a-network-of-repositories
func (s *ActivityService) ListEventsForRepoNetwork(owner, repo string, opt *ListOptions) ([]*Event, *Response, error) {
u := fmt.Sprintf("networks/%v/%v/events", owner, repo)
u, err := addOptions(u, opt)
if err != nil {
return nil, nil, err
}
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
events := new([]*Event)
resp, err := s.client.Do(req, events)
if err != nil {
return nil, resp, err
}
return *events, resp, err
}
// ListEventsForOrganization lists public events for an organization.
//
// GitHub API docs: http://developer.github.com/v3/activity/events/#list-public-events-for-an-organization
func (s *ActivityService) ListEventsForOrganization(org string, opt *ListOptions) ([]*Event, *Response, error) {
u := fmt.Sprintf("orgs/%v/events", org)
u, err := addOptions(u, opt)
if err != nil {
return nil, nil, err
}
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
events := new([]*Event)
resp, err := s.client.Do(req, events)
if err != nil {
return nil, resp, err
}
return *events, resp, err
}
// ListEventsPerformedByUser lists the events performed by a user. If publicOnly is
// true, only public events will be returned.
//
// GitHub API docs: http://developer.github.com/v3/activity/events/#list-events-performed-by-a-user
func (s *ActivityService) ListEventsPerformedByUser(user string, publicOnly bool, opt *ListOptions) ([]*Event, *Response, error) {
var u string
if publicOnly {
u = fmt.Sprintf("users/%v/events/public", user)
} else {
u = fmt.Sprintf("users/%v/events", user)
}
u, err := addOptions(u, opt)
if err != nil {
return nil, nil, err
}
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
events := new([]*Event)
resp, err := s.client.Do(req, events)
if err != nil {
return nil, resp, err
}
return *events, resp, err
}
// ListEventsReceivedByUser lists the events received by a user. If publicOnly is
// true, only public events will be returned.
//
// GitHub API docs: http://developer.github.com/v3/activity/events/#list-events-that-a-user-has-received
func (s *ActivityService) ListEventsReceivedByUser(user string, publicOnly bool, opt *ListOptions) ([]*Event, *Response, error) {
var u string
if publicOnly {
u = fmt.Sprintf("users/%v/received_events/public", user)
} else {
u = fmt.Sprintf("users/%v/received_events", user)
}
u, err := addOptions(u, opt)
if err != nil {
return nil, nil, err
}
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
events := new([]*Event)
resp, err := s.client.Do(req, events)
if err != nil {
return nil, resp, err
}
return *events, resp, err
}
// ListUserEventsForOrganization provides the user’s organization dashboard. You
// must be authenticated as the user to view this.
//
// GitHub API docs: http://developer.github.com/v3/activity/events/#list-events-for-an-organization
func (s *ActivityService) ListUserEventsForOrganization(org, user string, opt *ListOptions) ([]*Event, *Response, error) {
u := fmt.Sprintf("users/%v/events/orgs/%v", user, org)
u, err := addOptions(u, opt)
if err != nil {
return nil, nil, err
}
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
events := new([]*Event)
resp, err := s.client.Do(req, events)
if err != nil {
return nil, resp, err
}
return *events, resp, err
}

305
vendor/src/github.com/google/go-github/github/activity_events_test.go

@ -0,0 +1,305 @@
// Copyright 2013 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github
import (
"encoding/json"
"fmt"
"net/http"
"reflect"
"testing"
)
func TestActivityService_ListEvents(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/events", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testFormValues(t, r, values{
"page": "2",
})
fmt.Fprint(w, `[{"id":"1"},{"id":"2"}]`)
})
opt := &ListOptions{Page: 2}
events, _, err := client.Activity.ListEvents(opt)
if err != nil {
t.Errorf("Activities.ListEvents returned error: %v", err)
}
want := []*Event{{ID: String("1")}, {ID: String("2")}}
if !reflect.DeepEqual(events, want) {
t.Errorf("Activities.ListEvents returned %+v, want %+v", events, want)
}
}
func TestActivityService_ListRepositoryEvents(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/events", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testFormValues(t, r, values{
"page": "2",
})
fmt.Fprint(w, `[{"id":"1"},{"id":"2"}]`)
})
opt := &ListOptions{Page: 2}
events, _, err := client.Activity.ListRepositoryEvents("o", "r", opt)
if err != nil {
t.Errorf("Activities.ListRepositoryEvents returned error: %v", err)
}
want := []*Event{{ID: String("1")}, {ID: String("2")}}
if !reflect.DeepEqual(events, want) {
t.Errorf("Activities.ListRepositoryEvents returned %+v, want %+v", events, want)
}
}
func TestActivityService_ListRepositoryEvents_invalidOwner(t *testing.T) {
_, _, err := client.Activity.ListRepositoryEvents("%", "%", nil)
testURLParseError(t, err)
}
func TestActivityService_ListIssueEventsForRepository(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/issues/events", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testFormValues(t, r, values{
"page": "2",
})
fmt.Fprint(w, `[{"id":"1"},{"id":"2"}]`)
})
opt := &ListOptions{Page: 2}
events, _, err := client.Activity.ListIssueEventsForRepository("o", "r", opt)
if err != nil {
t.Errorf("Activities.ListIssueEventsForRepository returned error: %v", err)
}
want := []*Event{{ID: String("1")}, {ID: String("2")}}
if !reflect.DeepEqual(events, want) {
t.Errorf("Activities.ListIssueEventsForRepository returned %+v, want %+v", events, want)
}
}
func TestActivityService_ListIssueEventsForRepository_invalidOwner(t *testing.T) {
_, _, err := client.Activity.ListIssueEventsForRepository("%", "%", nil)
testURLParseError(t, err)
}
func TestActivityService_ListEventsForRepoNetwork(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/networks/o/r/events", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testFormValues(t, r, values{
"page": "2",
})
fmt.Fprint(w, `[{"id":"1"},{"id":"2"}]`)
})
opt := &ListOptions{Page: 2}
events, _, err := client.Activity.ListEventsForRepoNetwork("o", "r", opt)
if err != nil {
t.Errorf("Activities.ListEventsForRepoNetwork returned error: %v", err)
}
want := []*Event{{ID: String("1")}, {ID: String("2")}}
if !reflect.DeepEqual(events, want) {
t.Errorf("Activities.ListEventsForRepoNetwork returned %+v, want %+v", events, want)
}
}
func TestActivityService_ListEventsForRepoNetwork_invalidOwner(t *testing.T) {
_, _, err := client.Activity.ListEventsForRepoNetwork("%", "%", nil)
testURLParseError(t, err)
}
func TestActivityService_ListEventsForOrganization(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/orgs/o/events", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testFormValues(t, r, values{
"page": "2",
})
fmt.Fprint(w, `[{"id":"1"},{"id":"2"}]`)
})
opt := &ListOptions{Page: 2}
events, _, err := client.Activity.ListEventsForOrganization("o", opt)
if err != nil {
t.Errorf("Activities.ListEventsForOrganization returned error: %v", err)
}
want := []*Event{{ID: String("1")}, {ID: String("2")}}
if !reflect.DeepEqual(events, want) {
t.Errorf("Activities.ListEventsForOrganization returned %+v, want %+v", events, want)
}
}
func TestActivityService_ListEventsForOrganization_invalidOrg(t *testing.T) {
_, _, err := client.Activity.ListEventsForOrganization("%", nil)
testURLParseError(t, err)
}
func TestActivityService_ListEventsPerformedByUser_all(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/users/u/events", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testFormValues(t, r, values{
"page": "2",
})
fmt.Fprint(w, `[{"id":"1"},{"id":"2"}]`)
})
opt := &ListOptions{Page: 2}
events, _, err := client.Activity.ListEventsPerformedByUser("u", false, opt)
if err != nil {
t.Errorf("Events.ListPerformedByUser returned error: %v", err)
}
want := []*Event{{ID: String("1")}, {ID: String("2")}}
if !reflect.DeepEqual(events, want) {
t.Errorf("Events.ListPerformedByUser returned %+v, want %+v", events, want)
}
}
func TestActivityService_ListEventsPerformedByUser_publicOnly(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/users/u/events/public", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
fmt.Fprint(w, `[{"id":"1"},{"id":"2"}]`)
})
events, _, err := client.Activity.ListEventsPerformedByUser("u", true, nil)
if err != nil {
t.Errorf("Events.ListPerformedByUser returned error: %v", err)
}
want := []*Event{{ID: String("1")}, {ID: String("2")}}
if !reflect.DeepEqual(events, want) {
t.Errorf("Events.ListPerformedByUser returned %+v, want %+v", events, want)
}
}
func TestActivityService_ListEventsPerformedByUser_invalidUser(t *testing.T) {
_, _, err := client.Activity.ListEventsPerformedByUser("%", false, nil)
testURLParseError(t, err)
}
func TestActivityService_ListEventsReceivedByUser_all(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/users/u/received_events", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testFormValues(t, r, values{
"page": "2",
})
fmt.Fprint(w, `[{"id":"1"},{"id":"2"}]`)
})
opt := &ListOptions{Page: 2}
events, _, err := client.Activity.ListEventsReceivedByUser("u", false, opt)
if err != nil {
t.Errorf("Events.ListReceivedByUser returned error: %v", err)
}
want := []*Event{{ID: String("1")}, {ID: String("2")}}
if !reflect.DeepEqual(events, want) {
t.Errorf("Events.ListReceivedUser returned %+v, want %+v", events, want)
}
}
func TestActivityService_ListEventsReceivedByUser_publicOnly(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/users/u/received_events/public", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
fmt.Fprint(w, `[{"id":"1"},{"id":"2"}]`)
})
events, _, err := client.Activity.ListEventsReceivedByUser("u", true, nil)
if err != nil {
t.Errorf("Events.ListReceivedByUser returned error: %v", err)
}
want := []*Event{{ID: String("1")}, {ID: String("2")}}
if !reflect.DeepEqual(events, want) {
t.Errorf("Events.ListReceivedByUser returned %+v, want %+v", events, want)
}
}
func TestActivityService_ListEventsReceivedByUser_invalidUser(t *testing.T) {
_, _, err := client.Activity.ListEventsReceivedByUser("%", false, nil)
testURLParseError(t, err)
}
func TestActivityService_ListUserEventsForOrganization(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/users/u/events/orgs/o", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testFormValues(t, r, values{
"page": "2",
})
fmt.Fprint(w, `[{"id":"1"},{"id":"2"}]`)
})
opt := &ListOptions{Page: 2}
events, _, err := client.Activity.ListUserEventsForOrganization("o", "u", opt)
if err != nil {
t.Errorf("Activities.ListUserEventsForOrganization returned error: %v", err)
}
want := []*Event{{ID: String("1")}, {ID: String("2")}}
if !reflect.DeepEqual(events, want) {
t.Errorf("Activities.ListUserEventsForOrganization returned %+v, want %+v", events, want)
}
}
func TestActivity_EventPayload_typed(t *testing.T) {
raw := []byte(`{"type": "PushEvent","payload":{"push_id": 1}}`)
var event *Event
if err := json.Unmarshal(raw, &event); err != nil {
t.Fatalf("Unmarshal Event returned error: %v", err)
}
want := &PushEvent{PushID: Int(1)}
if !reflect.DeepEqual(event.Payload(), want) {
t.Errorf("Event Payload returned %+v, want %+v", event.Payload(), want)
}
}
// TestEvent_Payload_untyped checks that unrecognized events are parsed to an
// interface{} value (instead of being discarded or throwing an error), for
// forward compatibility with new event types.
func TestActivity_EventPayload_untyped(t *testing.T) {
raw := []byte(`{"type": "UnrecognizedEvent","payload":{"field": "val"}}`)
var event *Event
if err := json.Unmarshal(raw, &event); err != nil {
t.Fatalf("Unmarshal Event returned error: %v", err)
}
want := map[string]interface{}{"field": "val"}
if !reflect.DeepEqual(event.Payload(), want) {
t.Errorf("Event Payload returned %+v, want %+v", event.Payload(), want)
}
}

222
vendor/src/github.com/google/go-github/github/activity_notifications.go

@ -0,0 +1,222 @@
// Copyright 2014 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github
import (
"fmt"
"time"
)
// Notification identifies a GitHub notification for a user.
type Notification struct {
ID *string `json:"id,omitempty"`
Repository *Repository `json:"repository,omitempty"`
Subject *NotificationSubject `json:"subject,omitempty"`
// Reason identifies the event that triggered the notification.
//
// GitHub API Docs: https://developer.github.com/v3/activity/notifications/#notification-reasons
Reason *string `json:"reason,omitempty"`
Unread *bool `json:"unread,omitempty"`
UpdatedAt *time.Time `json:"updated_at,omitempty"`
LastReadAt *time.Time `json:"last_read_at,omitempty"`
URL *string `json:"url,omitempty"`
}
// NotificationSubject identifies the subject of a notification.
type NotificationSubject struct {
Title *string `json:"title,omitempty"`
URL *string `json:"url,omitempty"`
LatestCommentURL *string `json:"latest_comment_url,omitempty"`
Type *string `json:"type,omitempty"`
}
// NotificationListOptions specifies the optional parameters to the
// ActivityService.ListNotifications method.
type NotificationListOptions struct {
All bool `url:"all,omitempty"`
Participating bool `url:"participating,omitempty"`
Since time.Time `url:"since,omitempty"`
Before time.Time `url:"before,omitempty"`
ListOptions
}
// ListNotifications lists all notifications for the authenticated user.
//
// GitHub API Docs: https://developer.github.com/v3/activity/notifications/#list-your-notifications
func (s *ActivityService) ListNotifications(opt *NotificationListOptions) ([]*Notification, *Response, error) {
u := fmt.Sprintf("notifications")
u, err := addOptions(u, opt)
if err != nil {
return nil, nil, err
}
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
var notifications []*Notification
resp, err := s.client.Do(req, &notifications)
if err != nil {
return nil, resp, err
}
return notifications, resp, err
}
// ListRepositoryNotifications lists all notifications in a given repository
// for the authenticated user.
//
// GitHub API Docs: https://developer.github.com/v3/activity/notifications/#list-your-notifications-in-a-repository
func (s *ActivityService) ListRepositoryNotifications(owner, repo string, opt *NotificationListOptions) ([]*Notification, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/notifications", owner, repo)
u, err := addOptions(u, opt)
if err != nil {
return nil, nil, err
}
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
var notifications []*Notification
resp, err := s.client.Do(req, &notifications)
if err != nil {
return nil, resp, err
}
return notifications, resp, err
}
type markReadOptions struct {
LastReadAt time.Time `json:"last_read_at,omitempty"`
}
// MarkNotificationsRead marks all notifications up to lastRead as read.
//
// GitHub API Docs: https://developer.github.com/v3/activity/notifications/#mark-as-read
func (s *ActivityService) MarkNotificationsRead(lastRead time.Time) (*Response, error) {
opts := &markReadOptions{
LastReadAt: lastRead,
}
req, err := s.client.NewRequest("PUT", "notifications", opts)
if err != nil {
return nil, err
}
return s.client.Do(req, nil)
}
// MarkRepositoryNotificationsRead marks all notifications up to lastRead in
// the specified repository as read.
//
// GitHub API Docs: https://developer.github.com/v3/activity/notifications/#mark-notifications-as-read-in-a-repository
func (s *ActivityService) MarkRepositoryNotificationsRead(owner, repo string, lastRead time.Time) (*Response, error) {
opts := &markReadOptions{
LastReadAt: lastRead,
}
u := fmt.Sprintf("repos/%v/%v/notifications", owner, repo)
req, err := s.client.NewRequest("PUT", u, opts)
if err != nil {
return nil, err
}
return s.client.Do(req, nil)
}
// GetThread gets the specified notification thread.
//
// GitHub API Docs: https://developer.github.com/v3/activity/notifications/#view-a-single-thread
func (s *ActivityService) GetThread(id string) (*Notification, *Response, error) {
u := fmt.Sprintf("notifications/threads/%v", id)
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
notification := new(Notification)
resp, err := s.client.Do(req, notification)
if err != nil {
return nil, resp, err
}
return notification, resp, err
}
// MarkThreadRead marks the specified thread as read.
//
// GitHub API Docs: https://developer.github.com/v3/activity/notifications/#mark-a-thread-as-read
func (s *ActivityService) MarkThreadRead(id string) (*Response, error) {
u := fmt.Sprintf("notifications/threads/%v", id)
req, err := s.client.NewRequest("PATCH", u, nil)
if err != nil {
return nil, err
}
return s.client.Do(req, nil)
}
// GetThreadSubscription checks to see if the authenticated user is subscribed
// to a thread.
//
// GitHub API Docs: https://developer.github.com/v3/activity/notifications/#get-a-thread-subscription
func (s *ActivityService) GetThreadSubscription(id string) (*Subscription, *Response, error) {
u := fmt.Sprintf("notifications/threads/%v/subscription", id)
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
sub := new(Subscription)
resp, err := s.client.Do(req, sub)
if err != nil {
return nil, resp, err
}
return sub, resp, err
}
// SetThreadSubscription sets the subscription for the specified thread for the
// authenticated user.
//
// GitHub API Docs: https://developer.github.com/v3/activity/notifications/#set-a-thread-subscription
func (s *ActivityService) SetThreadSubscription(id string, subscription *Subscription) (*Subscription, *Response, error) {
u := fmt.Sprintf("notifications/threads/%v/subscription", id)
req, err := s.client.NewRequest("PUT", u, subscription)
if err != nil {
return nil, nil, err
}
sub := new(Subscription)
resp, err := s.client.Do(req, sub)
if err != nil {
return nil, resp, err
}
return sub, resp, err
}
// DeleteThreadSubscription deletes the subscription for the specified thread
// for the authenticated user.
//
// GitHub API Docs: https://developer.github.com/v3/activity/notifications/#delete-a-thread-subscription
func (s *ActivityService) DeleteThreadSubscription(id string) (*Response, error) {
u := fmt.Sprintf("notifications/threads/%v/subscription", id)
req, err := s.client.NewRequest("DELETE", u, nil)
if err != nil {
return nil, err
}
return s.client.Do(req, nil)
}

203
vendor/src/github.com/google/go-github/github/activity_notifications_test.go

@ -0,0 +1,203 @@
// Copyright 2014 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github
import (
"encoding/json"
"fmt"
"net/http"
"reflect"
"testing"
"time"
)
func TestActivityService_ListNotification(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/notifications", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testFormValues(t, r, values{
"all": "true",
"participating": "true",
"since": "2006-01-02T15:04:05Z",
"before": "2007-03-04T15:04:05Z",
})
fmt.Fprint(w, `[{"id":"1", "subject":{"title":"t"}}]`)
})
opt := &NotificationListOptions{
All: true,
Participating: true,
Since: time.Date(2006, 01, 02, 15, 04, 05, 0, time.UTC),
Before: time.Date(2007, 03, 04, 15, 04, 05, 0, time.UTC),
}
notifications, _, err := client.Activity.ListNotifications(opt)
if err != nil {
t.Errorf("Activity.ListNotifications returned error: %v", err)
}
want := []*Notification{{ID: String("1"), Subject: &NotificationSubject{Title: String("t")}}}
if !reflect.DeepEqual(notifications, want) {
t.Errorf("Activity.ListNotifications returned %+v, want %+v", notifications, want)
}
}
func TestActivityService_ListRepositoryNotification(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/notifications", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
fmt.Fprint(w, `[{"id":"1"}]`)
})
notifications, _, err := client.Activity.ListRepositoryNotifications("o", "r", nil)
if err != nil {
t.Errorf("Activity.ListRepositoryNotifications returned error: %v", err)
}
want := []*Notification{{ID: String("1")}}
if !reflect.DeepEqual(notifications, want) {
t.Errorf("Activity.ListRepositoryNotifications returned %+v, want %+v", notifications, want)
}
}
func TestActivityService_MarkNotificationsRead(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/notifications", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "PUT")
testHeader(t, r, "Content-Type", "application/json")
testBody(t, r, `{"last_read_at":"2006-01-02T15:04:05Z"}`+"\n")
w.WriteHeader(http.StatusResetContent)
})
_, err := client.Activity.MarkNotificationsRead(time.Date(2006, 01, 02, 15, 04, 05, 0, time.UTC))
if err != nil {
t.Errorf("Activity.MarkNotificationsRead returned error: %v", err)
}
}
func TestActivityService_MarkRepositoryNotificationsRead(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/notifications", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "PUT")
testHeader(t, r, "Content-Type", "application/json")
testBody(t, r, `{"last_read_at":"2006-01-02T15:04:05Z"}`+"\n")
w.WriteHeader(http.StatusResetContent)
})
_, err := client.Activity.MarkRepositoryNotificationsRead("o", "r", time.Date(2006, 01, 02, 15, 04, 05, 0, time.UTC))
if err != nil {
t.Errorf("Activity.MarkRepositoryNotificationsRead returned error: %v", err)
}
}
func TestActivityService_GetThread(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/notifications/threads/1", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
fmt.Fprint(w, `{"id":"1"}`)
})
notification, _, err := client.Activity.GetThread("1")
if err != nil {
t.Errorf("Activity.GetThread returned error: %v", err)
}
want := &Notification{ID: String("1")}
if !reflect.DeepEqual(notification, want) {
t.Errorf("Activity.GetThread returned %+v, want %+v", notification, want)
}
}
func TestActivityService_MarkThreadRead(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/notifications/threads/1", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "PATCH")
w.WriteHeader(http.StatusResetContent)
})
_, err := client.Activity.MarkThreadRead("1")
if err != nil {
t.Errorf("Activity.MarkThreadRead returned error: %v", err)
}
}
func TestActivityService_GetThreadSubscription(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/notifications/threads/1/subscription", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
fmt.Fprint(w, `{"subscribed":true}`)
})
sub, _, err := client.Activity.GetThreadSubscription("1")
if err != nil {
t.Errorf("Activity.GetThreadSubscription returned error: %v", err)
}
want := &Subscription{Subscribed: Bool(true)}
if !reflect.DeepEqual(sub, want) {
t.Errorf("Activity.GetThreadSubscription returned %+v, want %+v", sub, want)
}
}
func TestActivityService_SetThreadSubscription(t *testing.T) {
setup()
defer teardown()
input := &Subscription{Subscribed: Bool(true)}
mux.HandleFunc("/notifications/threads/1/subscription", func(w http.ResponseWriter, r *http.Request) {
v := new(Subscription)
json.NewDecoder(r.Body).Decode(v)
testMethod(t, r, "PUT")
if !reflect.DeepEqual(v, input) {
t.Errorf("Request body = %+v, want %+v", v, input)
}
fmt.Fprint(w, `{"ignored":true}`)
})
sub, _, err := client.Activity.SetThreadSubscription("1", input)
if err != nil {
t.Errorf("Activity.SetThreadSubscription returned error: %v", err)
}
want := &Subscription{Ignored: Bool(true)}
if !reflect.DeepEqual(sub, want) {
t.Errorf("Activity.SetThreadSubscription returned %+v, want %+v", sub, want)
}
}
func TestActivityService_DeleteThreadSubscription(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/notifications/threads/1/subscription", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "DELETE")
w.WriteHeader(http.StatusNoContent)
})
_, err := client.Activity.DeleteThreadSubscription("1")
if err != nil {
t.Errorf("Activity.DeleteThreadSubscription returned error: %v", err)
}
}

132
vendor/src/github.com/google/go-github/github/activity_star.go

@ -0,0 +1,132 @@
// Copyright 2013 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github
import "fmt"
// StarredRepository is returned by ListStarred.
type StarredRepository struct {
StarredAt *Timestamp `json:"starred_at,omitempty"`
Repository *Repository `json:"repo,omitempty"`
}
// Stargazer represents a user that has starred a repository.
type Stargazer struct {
StarredAt *Timestamp `json:"starred_at,omitempty"`
User *User `json:"user,omitempty"`
}
// ListStargazers lists people who have starred the specified repo.
//
// GitHub API Docs: https://developer.github.com/v3/activity/starring/#list-stargazers
func (s *ActivityService) ListStargazers(owner, repo string, opt *ListOptions) ([]*Stargazer, *Response, error) {
u := fmt.Sprintf("repos/%s/%s/stargazers", owner, repo)
u, err := addOptions(u, opt)
if err != nil {
return nil, nil, err
}
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
// TODO: remove custom Accept header when this API fully launches
req.Header.Set("Accept", mediaTypeStarringPreview)
stargazers := new([]*Stargazer)
resp, err := s.client.Do(req, stargazers)
if err != nil {
return nil, resp, err
}
return *stargazers, resp, err
}
// ActivityListStarredOptions specifies the optional parameters to the
// ActivityService.ListStarred method.
type ActivityListStarredOptions struct {
// How to sort the repository list. Possible values are: created, updated,
// pushed, full_name. Default is "full_name".
Sort string `url:"sort,omitempty"`
// Direction in which to sort repositories. Possible values are: asc, desc.
// Default is "asc" when sort is "full_name", otherwise default is "desc".
Direction string `url:"direction,omitempty"`
ListOptions
}
// ListStarred lists all the repos starred by a user. Passing the empty string
// will list the starred repositories for the authenticated user.
//
// GitHub API docs: http://developer.github.com/v3/activity/starring/#list-repositories-being-starred
func (s *ActivityService) ListStarred(user string, opt *ActivityListStarredOptions) ([]*StarredRepository, *Response, error) {
var u string
if user != "" {
u = fmt.Sprintf("users/%v/starred", user)
} else {
u = "user/starred"
}
u, err := addOptions(u, opt)
if err != nil {
return nil, nil, err
}
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
// TODO: remove custom Accept header when this API fully launches
req.Header.Set("Accept", mediaTypeStarringPreview)
repos := new([]*StarredRepository)
resp, err := s.client.Do(req, repos)
if err != nil {
return nil, resp, err
}
return *repos, resp, err
}
// IsStarred checks if a repository is starred by authenticated user.
//
// GitHub API docs: https://developer.github.com/v3/activity/starring/#check-if-you-are-starring-a-repository
func (s *ActivityService) IsStarred(owner, repo string) (bool, *Response, error) {
u := fmt.Sprintf("user/starred/%v/%v", owner, repo)
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return false, nil, err
}
resp, err := s.client.Do(req, nil)
starred, err := parseBoolResponse(err)
return starred, resp, err
}
// Star a repository as the authenticated user.
//
// GitHub API docs: https://developer.github.com/v3/activity/starring/#star-a-repository
func (s *ActivityService) Star(owner, repo string) (*Response, error) {
u := fmt.Sprintf("user/starred/%v/%v", owner, repo)
req, err := s.client.NewRequest("PUT", u, nil)
if err != nil {
return nil, err
}
return s.client.Do(req, nil)
}
// Unstar a repository as the authenticated user.
//
// GitHub API docs: https://developer.github.com/v3/activity/starring/#unstar-a-repository
func (s *ActivityService) Unstar(owner, repo string) (*Response, error) {
u := fmt.Sprintf("user/starred/%v/%v", owner, repo)
req, err := s.client.NewRequest("DELETE", u, nil)
if err != nil {
return nil, err
}
return s.client.Do(req, nil)
}

171
vendor/src/github.com/google/go-github/github/activity_star_test.go

@ -0,0 +1,171 @@
// Copyright 2013 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github
import (
"fmt"
"net/http"
"reflect"
"testing"
"time"
)
func TestActivityService_ListStargazers(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/stargazers", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testHeader(t, r, "Accept", mediaTypeStarringPreview)
testFormValues(t, r, values{
"page": "2",
})
fmt.Fprint(w, `[{"starred_at":"2002-02-10T15:30:00Z","user":{"id":1}}]`)
})
stargazers, _, err := client.Activity.ListStargazers("o", "r", &ListOptions{Page: 2})
if err != nil {
t.Errorf("Activity.ListStargazers returned error: %v", err)
}
want := []*Stargazer{{StarredAt: &Timestamp{time.Date(2002, time.February, 10, 15, 30, 0, 0, time.UTC)}, User: &User{ID: Int(1)}}}
if !reflect.DeepEqual(stargazers, want) {
t.Errorf("Activity.ListStargazers returned %+v, want %+v", stargazers, want)
}
}
func TestActivityService_ListStarred_authenticatedUser(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/user/starred", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testHeader(t, r, "Accept", mediaTypeStarringPreview)
fmt.Fprint(w, `[{"starred_at":"2002-02-10T15:30:00Z","repo":{"id":1}}]`)
})
repos, _, err := client.Activity.ListStarred("", nil)
if err != nil {
t.Errorf("Activity.ListStarred returned error: %v", err)
}
want := []*StarredRepository{{StarredAt: &Timestamp{time.Date(2002, time.February, 10, 15, 30, 0, 0, time.UTC)}, Repository: &Repository{ID: Int(1)}}}
if !reflect.DeepEqual(repos, want) {
t.Errorf("Activity.ListStarred returned %+v, want %+v", repos, want)
}
}
func TestActivityService_ListStarred_specifiedUser(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/users/u/starred", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testHeader(t, r, "Accept", mediaTypeStarringPreview)
testFormValues(t, r, values{
"sort": "created",
"direction": "asc",
"page": "2",
})
fmt.Fprint(w, `[{"starred_at":"2002-02-10T15:30:00Z","repo":{"id":2}}]`)
})
opt := &ActivityListStarredOptions{"created", "asc", ListOptions{Page: 2}}
repos, _, err := client.Activity.ListStarred("u", opt)
if err != nil {
t.Errorf("Activity.ListStarred returned error: %v", err)
}
want := []*StarredRepository{{StarredAt: &Timestamp{time.Date(2002, time.February, 10, 15, 30, 0, 0, time.UTC)}, Repository: &Repository{ID: Int(2)}}}
if !reflect.DeepEqual(repos, want) {
t.Errorf("Activity.ListStarred returned %+v, want %+v", repos, want)
}
}
func TestActivityService_ListStarred_invalidUser(t *testing.T) {
_, _, err := client.Activity.ListStarred("%", nil)
testURLParseError(t, err)
}
func TestActivityService_IsStarred_hasStar(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/user/starred/o/r", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
w.WriteHeader(http.StatusNoContent)
})
star, _, err := client.Activity.IsStarred("o", "r")
if err != nil {
t.Errorf("Activity.IsStarred returned error: %v", err)
}
if want := true; star != want {
t.Errorf("Activity.IsStarred returned %+v, want %+v", star, want)
}
}
func TestActivityService_IsStarred_noStar(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/user/starred/o/r", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
w.WriteHeader(http.StatusNotFound)
})
star, _, err := client.Activity.IsStarred("o", "r")
if err != nil {
t.Errorf("Activity.IsStarred returned error: %v", err)
}
if want := false; star != want {
t.Errorf("Activity.IsStarred returned %+v, want %+v", star, want)
}
}
func TestActivityService_IsStarred_invalidID(t *testing.T) {
_, _, err := client.Activity.IsStarred("%", "%")
testURLParseError(t, err)
}
func TestActivityService_Star(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/user/starred/o/r", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "PUT")
})
_, err := client.Activity.Star("o", "r")
if err != nil {
t.Errorf("Activity.Star returned error: %v", err)
}
}
func TestActivityService_Star_invalidID(t *testing.T) {
_, err := client.Activity.Star("%", "%")
testURLParseError(t, err)
}
func TestActivityService_Unstar(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/user/starred/o/r", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "DELETE")
})
_, err := client.Activity.Unstar("o", "r")
if err != nil {
t.Errorf("Activity.Unstar returned error: %v", err)
}
}
func TestActivityService_Unstar_invalidID(t *testing.T) {
_, err := client.Activity.Unstar("%", "%")
testURLParseError(t, err)
}

128
vendor/src/github.com/google/go-github/github/activity_test.go

@ -0,0 +1,128 @@
// Copyright 2016 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github
import (
"net/http"
"reflect"
"testing"
)
func TestActivityService_List(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/feeds", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
w.WriteHeader(http.StatusOK)
w.Write(feedsJSON)
})
got, _, err := client.Activity.ListFeeds()
if err != nil {
t.Errorf("Activity.ListFeeds returned error: %v", err)
}
if want := wantFeeds; !reflect.DeepEqual(got, want) {
t.Errorf("Activity.ListFeeds = %+v, want %+v", got, want)
}
}
var feedsJSON = []byte(`{
"timeline_url": "https://github.com/timeline",
"user_url": "https://github.com/{user}",
"current_user_public_url": "https://github.com/defunkt",
"current_user_url": "https://github.com/defunkt.private?token=abc123",
"current_user_actor_url": "https://github.com/defunkt.private.actor?token=abc123",
"current_user_organization_url": "",
"current_user_organization_urls": [
"https://github.com/organizations/github/defunkt.private.atom?token=abc123"
],
"_links": {
"timeline": {
"href": "https://github.com/timeline",
"type": "application/atom+xml"
},
"user": {
"href": "https://github.com/{user}",
"type": "application/atom+xml"
},
"current_user_public": {
"href": "https://github.com/defunkt",
"type": "application/atom+xml"
},
"current_user": {
"href": "https://github.com/defunkt.private?token=abc123",
"type": "application/atom+xml"
},
"current_user_actor": {
"href": "https://github.com/defunkt.private.actor?token=abc123",
"type": "application/atom+xml"
},
"current_user_organization": {
"href": "",
"type": ""
},
"current_user_organizations": [
{
"href": "https://github.com/organizations/github/defunkt.private.atom?token=abc123",
"type": "application/atom+xml"
}
]
}
}`)
var wantFeeds = &Feeds{
TimelineURL: String("https://github.com/timeline"),
UserURL: String("https://github.com/{user}"),
CurrentUserPublicURL: String("https://github.com/defunkt"),
CurrentUserURL: String("https://github.com/defunkt.private?token=abc123"),
CurrentUserActorURL: String("https://github.com/defunkt.private.actor?token=abc123"),
CurrentUserOrganizationURL: String(""),
CurrentUserOrganizationURLs: []string{
"https://github.com/organizations/github/defunkt.private.atom?token=abc123",
},
Links: &struct {
Timeline *FeedLink `json:"timeline,omitempty"`
User *FeedLink `json:"user,omitempty"`
CurrentUserPublic *FeedLink `json:"current_user_public,omitempty"`
CurrentUser *FeedLink `json:"current_user,omitempty"`
CurrentUserActor *FeedLink `json:"current_user_actor,omitempty"`
CurrentUserOrganization *FeedLink `json:"current_user_organization,omitempty"`
CurrentUserOrganizations []FeedLink `json:"current_user_organizations,omitempty"`
}{
Timeline: &FeedLink{
HRef: String("https://github.com/timeline"),
Type: String("application/atom+xml"),
},
User: &FeedLink{
HRef: String("https://github.com/{user}"),
Type: String("application/atom+xml"),
},
CurrentUserPublic: &FeedLink{
HRef: String("https://github.com/defunkt"),
Type: String("application/atom+xml"),
},
CurrentUser: &FeedLink{
HRef: String("https://github.com/defunkt.private?token=abc123"),
Type: String("application/atom+xml"),
},
CurrentUserActor: &FeedLink{
HRef: String("https://github.com/defunkt.private.actor?token=abc123"),
Type: String("application/atom+xml"),
},
CurrentUserOrganization: &FeedLink{
HRef: String(""),
Type: String(""),
},
CurrentUserOrganizations: []FeedLink{
{
HRef: String("https://github.com/organizations/github/defunkt.private.atom?token=abc123"),
Type: String("application/atom+xml"),
},
},
},
}

136
vendor/src/github.com/google/go-github/github/activity_watching.go

@ -0,0 +1,136 @@
// Copyright 2014 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github
import "fmt"
// Subscription identifies a repository or thread subscription.
type Subscription struct {
Subscribed *bool `json:"subscribed,omitempty"`
Ignored *bool `json:"ignored,omitempty"`
Reason *string `json:"reason,omitempty"`
CreatedAt *Timestamp `json:"created_at,omitempty"`
URL *string `json:"url,omitempty"`
// only populated for repository subscriptions
RepositoryURL *string `json:"repository_url,omitempty"`
// only populated for thread subscriptions
ThreadURL *string `json:"thread_url,omitempty"`
}
// ListWatchers lists watchers of a particular repo.
//
// GitHub API Docs: http://developer.github.com/v3/activity/watching/#list-watchers
func (s *ActivityService) ListWatchers(owner, repo string, opt *ListOptions) ([]*User, *Response, error) {
u := fmt.Sprintf("repos/%s/%s/subscribers", owner, repo)
u, err := addOptions(u, opt)
if err != nil {
return nil, nil, err
}
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
watchers := new([]*User)
resp, err := s.client.Do(req, watchers)
if err != nil {
return nil, resp, err
}
return *watchers, resp, err
}
// ListWatched lists the repositories the specified user is watching. Passing
// the empty string will fetch watched repos for the authenticated user.
//
// GitHub API Docs: https://developer.github.com/v3/activity/watching/#list-repositories-being-watched
func (s *ActivityService) ListWatched(user string, opt *ListOptions) ([]*Repository, *Response, error) {
var u string
if user != "" {
u = fmt.Sprintf("users/%v/subscriptions", user)
} else {
u = "user/subscriptions"
}
u, err := addOptions(u, opt)
if err != nil {
return nil, nil, err
}
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
watched := new([]*Repository)
resp, err := s.client.Do(req, watched)
if err != nil {
return nil, resp, err
}
return *watched, resp, err
}
// GetRepositorySubscription returns the subscription for the specified
// repository for the authenticated user. If the authenticated user is not
// watching the repository, a nil Subscription is returned.
//
// GitHub API Docs: https://developer.github.com/v3/activity/watching/#get-a-repository-subscription
func (s *ActivityService) GetRepositorySubscription(owner, repo string) (*Subscription, *Response, error) {
u := fmt.Sprintf("repos/%s/%s/subscription", owner, repo)
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
sub := new(Subscription)
resp, err := s.client.Do(req, sub)
if err != nil {
// if it's just a 404, don't return that as an error
_, err = parseBoolResponse(err)
return nil, resp, err
}
return sub, resp, err
}
// SetRepositorySubscription sets the subscription for the specified repository
// for the authenticated user.
//
// GitHub API Docs: https://developer.github.com/v3/activity/watching/#set-a-repository-subscription
func (s *ActivityService) SetRepositorySubscription(owner, repo string, subscription *Subscription) (*Subscription, *Response, error) {
u := fmt.Sprintf("repos/%s/%s/subscription", owner, repo)
req, err := s.client.NewRequest("PUT", u, subscription)
if err != nil {
return nil, nil, err
}
sub := new(Subscription)
resp, err := s.client.Do(req, sub)
if err != nil {
return nil, resp, err
}
return sub, resp, err
}
// DeleteRepositorySubscription deletes the subscription for the specified
// repository for the authenticated user.
//
// GitHub API Docs: https://developer.github.com/v3/activity/watching/#delete-a-repository-subscription
func (s *ActivityService) DeleteRepositorySubscription(owner, repo string) (*Response, error) {
u := fmt.Sprintf("repos/%s/%s/subscription", owner, repo)
req, err := s.client.NewRequest("DELETE", u, nil)
if err != nil {
return nil, err
}
return s.client.Do(req, nil)
}

183
vendor/src/github.com/google/go-github/github/activity_watching_test.go

@ -0,0 +1,183 @@
// Copyright 2014 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github
import (
"encoding/json"
"fmt"
"net/http"
"reflect"
"testing"
)
func TestActivityService_ListWatchers(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/subscribers", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testFormValues(t, r, values{
"page": "2",
})
fmt.Fprint(w, `[{"id":1}]`)
})
watchers, _, err := client.Activity.ListWatchers("o", "r", &ListOptions{Page: 2})
if err != nil {
t.Errorf("Activity.ListWatchers returned error: %v", err)
}
want := []*User{{ID: Int(1)}}
if !reflect.DeepEqual(watchers, want) {
t.Errorf("Activity.ListWatchers returned %+v, want %+v", watchers, want)
}
}
func TestActivityService_ListWatched_authenticatedUser(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/user/subscriptions", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testFormValues(t, r, values{
"page": "2",
})
fmt.Fprint(w, `[{"id":1}]`)
})
watched, _, err := client.Activity.ListWatched("", &ListOptions{Page: 2})
if err != nil {
t.Errorf("Activity.ListWatched returned error: %v", err)
}
want := []*Repository{{ID: Int(1)}}
if !reflect.DeepEqual(watched, want) {
t.Errorf("Activity.ListWatched returned %+v, want %+v", watched, want)
}
}
func TestActivityService_ListWatched_specifiedUser(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/users/u/subscriptions", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testFormValues(t, r, values{
"page": "2",
})
fmt.Fprint(w, `[{"id":1}]`)
})
watched, _, err := client.Activity.ListWatched("u", &ListOptions{Page: 2})
if err != nil {
t.Errorf("Activity.ListWatched returned error: %v", err)
}
want := []*Repository{{ID: Int(1)}}
if !reflect.DeepEqual(watched, want) {
t.Errorf("Activity.ListWatched returned %+v, want %+v", watched, want)
}
}
func TestActivityService_GetRepositorySubscription_true(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/subscription", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
fmt.Fprint(w, `{"subscribed":true}`)
})
sub, _, err := client.Activity.GetRepositorySubscription("o", "r")
if err != nil {
t.Errorf("Activity.GetRepositorySubscription returned error: %v", err)
}
want := &Subscription{Subscribed: Bool(true)}
if !reflect.DeepEqual(sub, want) {
t.Errorf("Activity.GetRepositorySubscription returned %+v, want %+v", sub, want)
}
}
func TestActivityService_GetRepositorySubscription_false(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/subscription", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
w.WriteHeader(http.StatusNotFound)
})
sub, _, err := client.Activity.GetRepositorySubscription("o", "r")
if err != nil {
t.Errorf("Activity.GetRepositorySubscription returned error: %v", err)
}
var want *Subscription
if !reflect.DeepEqual(sub, want) {
t.Errorf("Activity.GetRepositorySubscription returned %+v, want %+v", sub, want)
}
}
func TestActivityService_GetRepositorySubscription_error(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/subscription", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
w.WriteHeader(http.StatusBadRequest)
})
_, _, err := client.Activity.GetRepositorySubscription("o", "r")
if err == nil {
t.Errorf("Expected HTTP 400 response")
}
}
func TestActivityService_SetRepositorySubscription(t *testing.T) {
setup()
defer teardown()
input := &Subscription{Subscribed: Bool(true)}
mux.HandleFunc("/repos/o/r/subscription", func(w http.ResponseWriter, r *http.Request) {
v := new(Subscription)
json.NewDecoder(r.Body).Decode(v)
testMethod(t, r, "PUT")
if !reflect.DeepEqual(v, input) {
t.Errorf("Request body = %+v, want %+v", v, input)
}
fmt.Fprint(w, `{"ignored":true}`)
})
sub, _, err := client.Activity.SetRepositorySubscription("o", "r", input)
if err != nil {
t.Errorf("Activity.SetRepositorySubscription returned error: %v", err)
}
want := &Subscription{Ignored: Bool(true)}
if !reflect.DeepEqual(sub, want) {
t.Errorf("Activity.SetRepositorySubscription returned %+v, want %+v", sub, want)
}
}
func TestActivityService_DeleteRepositorySubscription(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/subscription", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "DELETE")
w.WriteHeader(http.StatusNoContent)
})
_, err := client.Activity.DeleteRepositorySubscription("o", "r")
if err != nil {
t.Errorf("Activity.DeleteRepositorySubscription returned error: %v", err)
}
}

436
vendor/src/github.com/google/go-github/github/authorizations.go

@ -0,0 +1,436 @@
// Copyright 2015 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github
import "fmt"
// Scope models a GitHub authorization scope.
//
// GitHub API docs:https://developer.github.com/v3/oauth/#scopes
type Scope string
// This is the set of scopes for GitHub API V3
const (
ScopeNone Scope = "(no scope)" // REVISIT: is this actually returned, or just a documentation artifact?
ScopeUser Scope = "user"
ScopeUserEmail Scope = "user:email"
ScopeUserFollow Scope = "user:follow"
ScopePublicRepo Scope = "public_repo"
ScopeRepo Scope = "repo"
ScopeRepoDeployment Scope = "repo_deployment"
ScopeRepoStatus Scope = "repo:status"
ScopeDeleteRepo Scope = "delete_repo"
ScopeNotifications Scope = "notifications"
ScopeGist Scope = "gist"
ScopeReadRepoHook Scope = "read:repo_hook"
ScopeWriteRepoHook Scope = "write:repo_hook"
ScopeAdminRepoHook Scope = "admin:repo_hook"
ScopeAdminOrgHook Scope = "admin:org_hook"
ScopeReadOrg Scope = "read:org"
ScopeWriteOrg Scope = "write:org"
ScopeAdminOrg Scope = "admin:org"
ScopeReadPublicKey Scope = "read:public_key"
ScopeWritePublicKey Scope = "write:public_key"
ScopeAdminPublicKey Scope = "admin:public_key"
ScopeReadGPGKey Scope = "read:gpg_key"
ScopeWriteGPGKey Scope = "write:gpg_key"
ScopeAdminGPGKey Scope = "admin:gpg_key"
)
// AuthorizationsService handles communication with the authorization related
// methods of the GitHub API.
//
// This service requires HTTP Basic Authentication; it cannot be accessed using
// an OAuth token.
//
// GitHub API docs: https://developer.github.com/v3/oauth_authorizations/
type AuthorizationsService service
// Authorization represents an individual GitHub authorization.
type Authorization struct {
ID *int `json:"id,omitempty"`
URL *string `json:"url,omitempty"`
Scopes []Scope `json:"scopes,omitempty"`
Token *string `json:"token,omitempty"`
TokenLastEight *string `json:"token_last_eight,omitempty"`
HashedToken *string `json:"hashed_token,omitempty"`
App *AuthorizationApp `json:"app,omitempty"`
Note *string `json:"note,omitempty"`
NoteURL *string `json:"note_url,omitempty"`
UpdateAt *Timestamp `json:"updated_at,omitempty"`
CreatedAt *Timestamp `json:"created_at,omitempty"`
Fingerprint *string `json:"fingerprint,omitempty"`
// User is only populated by the Check and Reset methods.
User *User `json:"user,omitempty"`
}
func (a Authorization) String() string {
return Stringify(a)
}
// AuthorizationApp represents an individual GitHub app (in the context of authorization).
type AuthorizationApp struct {
URL *string `json:"url,omitempty"`
Name *string `json:"name,omitempty"`
ClientID *string `json:"client_id,omitempty"`
}
func (a AuthorizationApp) String() string {
return Stringify(a)
}
// Grant represents an OAuth application that has been granted access to an account.
type Grant struct {
ID *int `json:"id,omitempty"`
URL *string `json:"url,omitempty"`
App *AuthorizationApp `json:"app,omitempty"`
CreatedAt *Timestamp `json:"created_at,omitempty"`
UpdatedAt *Timestamp `json:"updated_at,omitempty"`
Scopes []string `json:"scopes,omitempty"`
}
func (g Grant) String() string {
return Stringify(g)
}
// AuthorizationRequest represents a request to create an authorization.
type AuthorizationRequest struct {
Scopes []Scope `json:"scopes,omitempty"`
Note *string `json:"note,omitempty"`
NoteURL *string `json:"note_url,omitempty"`
ClientID *string `json:"client_id,omitempty"`
ClientSecret *string `json:"client_secret,omitempty"`
Fingerprint *string `json:"fingerprint,omitempty"`
}
func (a AuthorizationRequest) String() string {
return Stringify(a)
}
// AuthorizationUpdateRequest represents a request to update an authorization.
//
// Note that for any one update, you must only provide one of the "scopes"
// fields. That is, you may provide only one of "Scopes", or "AddScopes", or
// "RemoveScopes".
//
// GitHub API docs: https://developer.github.com/v3/oauth_authorizations/#update-an-existing-authorization
type AuthorizationUpdateRequest struct {
Scopes []string `json:"scopes,omitempty"`
AddScopes []string `json:"add_scopes,omitempty"`
RemoveScopes []string `json:"remove_scopes,omitempty"`
Note *string `json:"note,omitempty"`
NoteURL *string `json:"note_url,omitempty"`
Fingerprint *string `json:"fingerprint,omitempty"`
}
func (a AuthorizationUpdateRequest) String() string {
return Stringify(a)
}
// List the authorizations for the authenticated user.
//
// GitHub API docs: https://developer.github.com/v3/oauth_authorizations/#list-your-authorizations
func (s *AuthorizationsService) List(opt *ListOptions) ([]*Authorization, *Response, error) {
u := "authorizations"
u, err := addOptions(u, opt)
if err != nil {
return nil, nil, err
}
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
auths := new([]*Authorization)
resp, err := s.client.Do(req, auths)
if err != nil {
return nil, resp, err
}
return *auths, resp, err
}
// Get a single authorization.
//
// GitHub API docs: https://developer.github.com/v3/oauth_authorizations/#get-a-single-authorization
func (s *AuthorizationsService) Get(id int) (*Authorization, *Response, error) {
u := fmt.Sprintf("authorizations/%d", id)
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
a := new(Authorization)
resp, err := s.client.Do(req, a)
if err != nil {
return nil, resp, err
}
return a, resp, err
}
// Create a new authorization for the specified OAuth application.
//
// GitHub API docs: https://developer.github.com/v3/oauth_authorizations/#create-a-new-authorization
func (s *AuthorizationsService) Create(auth *AuthorizationRequest) (*Authorization, *Response, error) {
u := "authorizations"
req, err := s.client.NewRequest("POST", u, auth)
if err != nil {
return nil, nil, err
}
a := new(Authorization)
resp, err := s.client.Do(req, a)
if err != nil {
return nil, resp, err
}
return a, resp, err
}
// GetOrCreateForApp creates a new authorization for the specified OAuth
// application, only if an authorization for that application doesn’t already
// exist for the user.
//
// If a new token is created, the HTTP status code will be "201 Created", and
// the returned Authorization.Token field will be populated. If an existing
// token is returned, the status code will be "200 OK" and the
// Authorization.Token field will be empty.
//
// clientID is the OAuth Client ID with which to create the token.
//
// GitHub API docs:
// - https://developer.github.com/v3/oauth_authorizations/#get-or-create-an-authorization-for-a-specific-app
// - https://developer.github.com/v3/oauth_authorizations/#get-or-create-an-authorization-for-a-specific-app-and-fingerprint
func (s *AuthorizationsService) GetOrCreateForApp(clientID string, auth *AuthorizationRequest) (*Authorization, *Response, error) {
var u string
if auth.Fingerprint == nil || *auth.Fingerprint == "" {
u = fmt.Sprintf("authorizations/clients/%v", clientID)
} else {
u = fmt.Sprintf("authorizations/clients/%v/%v", clientID, *auth.Fingerprint)
}
req, err := s.client.NewRequest("PUT", u, auth)
if err != nil {
return nil, nil, err
}
a := new(Authorization)
resp, err := s.client.Do(req, a)
if err != nil {
return nil, resp, err
}
return a, resp, err
}
// Edit a single authorization.
//
// GitHub API docs: https://developer.github.com/v3/oauth_authorizations/#update-an-existing-authorization
func (s *AuthorizationsService) Edit(id int, auth *AuthorizationUpdateRequest) (*Authorization, *Response, error) {
u := fmt.Sprintf("authorizations/%d", id)
req, err := s.client.NewRequest("PATCH", u, auth)
if err != nil {
return nil, nil, err
}
a := new(Authorization)
resp, err := s.client.Do(req, a)
if err != nil {
return nil, resp, err
}
return a, resp, err
}
// Delete a single authorization.
//
// GitHub API docs: https://developer.github.com/v3/oauth_authorizations/#delete-an-authorization
func (s *AuthorizationsService) Delete(id int) (*Response, error) {
u := fmt.Sprintf("authorizations/%d", id)
req, err := s.client.NewRequest("DELETE", u, nil)
if err != nil {
return nil, err
}
return s.client.Do(req, nil)
}
// Check if an OAuth token is valid for a specific app.
//
// Note that this operation requires the use of BasicAuth, but where the
// username is the OAuth application clientID, and the password is its
// clientSecret. Invalid tokens will return a 404 Not Found.
//
// The returned Authorization.User field will be populated.
//
// GitHub API docs: https://developer.github.com/v3/oauth_authorizations/#check-an-authorization
func (s *AuthorizationsService) Check(clientID string, token string) (*Authorization, *Response, error) {
u := fmt.Sprintf("applications/%v/tokens/%v", clientID, token)
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
a := new(Authorization)
resp, err := s.client.Do(req, a)
if err != nil {
return nil, resp, err
}
return a, resp, err
}
// Reset is used to reset a valid OAuth token without end user involvement.
// Applications must save the "token" property in the response, because changes
// take effect immediately.
//
// Note that this operation requires the use of BasicAuth, but where the
// username is the OAuth application clientID, and the password is its
// clientSecret. Invalid tokens will return a 404 Not Found.
//
// The returned Authorization.User field will be populated.
//
// GitHub API docs: https://developer.github.com/v3/oauth_authorizations/#reset-an-authorization
func (s *AuthorizationsService) Reset(clientID string, token string) (*Authorization, *Response, error) {
u := fmt.Sprintf("applications/%v/tokens/%v", clientID, token)
req, err := s.client.NewRequest("POST", u, nil)
if err != nil {
return nil, nil, err
}
a := new(Authorization)
resp, err := s.client.Do(req, a)
if err != nil {
return nil, resp, err
}
return a, resp, err
}
// Revoke an authorization for an application.
//
// Note that this operation requires the use of BasicAuth, but where the
// username is the OAuth application clientID, and the password is its
// clientSecret. Invalid tokens will return a 404 Not Found.
//
// GitHub API docs: https://developer.github.com/v3/oauth_authorizations/#revoke-an-authorization-for-an-application
func (s *AuthorizationsService) Revoke(clientID string, token string) (*Response, error) {
u := fmt.Sprintf("applications/%v/tokens/%v", clientID, token)
req, err := s.client.NewRequest("DELETE", u, nil)
if err != nil {
return nil, err
}
return s.client.Do(req, nil)
}
// ListGrants lists the set of OAuth applications that have been granted
// access to a user's account. This will return one entry for each application
// that has been granted access to the account, regardless of the number of
// tokens an application has generated for the user.
//
// GitHub API docs: https://developer.github.com/v3/oauth_authorizations/#list-your-grants
func (s *AuthorizationsService) ListGrants() ([]*Grant, *Response, error) {
req, err := s.client.NewRequest("GET", "applications/grants", nil)
if err != nil {
return nil, nil, err
}
// TODO: remove custom Accept header when this API fully launches.
req.Header.Set("Accept", mediaTypeOAuthGrantAuthorizationsPreview)
grants := []*Grant{}
resp, err := s.client.Do(req, &grants)
if err != nil {
return nil, resp, err
}
return grants, resp, err
}
// GetGrant gets a single OAuth application grant.
//
// GitHub API docs: https://developer.github.com/v3/oauth_authorizations/#get-a-single-grant
func (s *AuthorizationsService) GetGrant(id int) (*Grant, *Response, error) {
u := fmt.Sprintf("applications/grants/%d", id)
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
// TODO: remove custom Accept header when this API fully launches.
req.Header.Set("Accept", mediaTypeOAuthGrantAuthorizationsPreview)
grant := new(Grant)
resp, err := s.client.Do(req, grant)
if err != nil {
return nil, resp, err
}
return grant, resp, err
}
// DeleteGrant deletes an OAuth application grant. Deleting an application's
// grant will also delete all OAuth tokens associated with the application for
// the user.
//
// GitHub API docs: https://developer.github.com/v3/oauth_authorizations/#delete-a-grant
func (s *AuthorizationsService) DeleteGrant(id int) (*Response, error) {
u := fmt.Sprintf("applications/grants/%d", id)
req, err := s.client.NewRequest("DELETE", u, nil)
if err != nil {
return nil, err
}
// TODO: remove custom Accept header when this API fully launches.
req.Header.Set("Accept", mediaTypeOAuthGrantAuthorizationsPreview)
return s.client.Do(req, nil)
}
// Create an impersonation OAuth token.
//
// This requires admin permissions. With the returned Authorization.Token
// you can e.g. create or delete a user's public SSH key. NOTE: creating a
// new token automatically revokes an existing one.
//
// GitHub API docs: https://developer.github.com/enterprise/2.5/v3/users/administration/#create-an-impersonation-oauth-token
func (s *AuthorizationsService) CreateImpersonation(username string, authReq *AuthorizationRequest) (*Authorization, *Response, error) {
u := fmt.Sprintf("admin/users/%v/authorizations", username)
req, err := s.client.NewRequest("POST", u, authReq)
if err != nil {
return nil, nil, err
}
a := new(Authorization)
resp, err := s.client.Do(req, a)
if err != nil {
return nil, resp, err
}
return a, resp, err
}
// Delete an impersonation OAuth token.
//
// NOTE: there can be only one at a time.
//
// GitHub API docs: https://developer.github.com/enterprise/2.5/v3/users/administration/#delete-an-impersonation-oauth-token
func (s *AuthorizationsService) DeleteImpersonation(username string) (*Response, error) {
u := fmt.Sprintf("admin/users/%v/authorizations", username)
req, err := s.client.NewRequest("DELETE", u, nil)
if err != nil {
return nil, err
}
return s.client.Do(req, nil)
}

343
vendor/src/github.com/google/go-github/github/authorizations_test.go

@ -0,0 +1,343 @@
// Copyright 2015 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github
import (
"encoding/json"
"fmt"
"net/http"
"reflect"
"testing"
)
func TestAuthorizationsService_List(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/authorizations", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testFormValues(t, r, values{"page": "1", "per_page": "2"})
fmt.Fprint(w, `[{"id":1}]`)
})
opt := &ListOptions{Page: 1, PerPage: 2}
got, _, err := client.Authorizations.List(opt)
if err != nil {
t.Errorf("Authorizations.List returned error: %v", err)
}
want := []*Authorization{{ID: Int(1)}}
if !reflect.DeepEqual(got, want) {
t.Errorf("Authorizations.List returned %+v, want %+v", *got[0].ID, *want[0].ID)
}
}
func TestAuthorizationsService_Get(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/authorizations/1", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
fmt.Fprint(w, `{"id":1}`)
})
got, _, err := client.Authorizations.Get(1)
if err != nil {
t.Errorf("Authorizations.Get returned error: %v", err)
}
want := &Authorization{ID: Int(1)}
if !reflect.DeepEqual(got, want) {
t.Errorf("Authorizations.Get returned auth %+v, want %+v", got, want)
}
}
func TestAuthorizationsService_Create(t *testing.T) {
setup()
defer teardown()
input := &AuthorizationRequest{
Note: String("test"),
}
mux.HandleFunc("/authorizations", func(w http.ResponseWriter, r *http.Request) {
v := new(AuthorizationRequest)
json.NewDecoder(r.Body).Decode(v)
testMethod(t, r, "POST")
if !reflect.DeepEqual(v, input) {
t.Errorf("Request body = %+v, want %+v", v, input)
}
fmt.Fprint(w, `{"ID":1}`)
})
got, _, err := client.Authorizations.Create(input)
if err != nil {
t.Errorf("Authorizations.Create returned error: %v", err)
}
want := &Authorization{ID: Int(1)}
if !reflect.DeepEqual(got, want) {
t.Errorf("Authorization.Create returned %+v, want %+v", got, want)
}
}
func TestAuthorizationsService_GetOrCreateForApp(t *testing.T) {
setup()
defer teardown()
input := &AuthorizationRequest{
Note: String("test"),
}
mux.HandleFunc("/authorizations/clients/id", func(w http.ResponseWriter, r *http.Request) {
v := new(AuthorizationRequest)
json.NewDecoder(r.Body).Decode(v)
testMethod(t, r, "PUT")
if !reflect.DeepEqual(v, input) {
t.Errorf("Request body = %+v, want %+v", v, input)
}
fmt.Fprint(w, `{"ID":1}`)
})
got, _, err := client.Authorizations.GetOrCreateForApp("id", input)
if err != nil {
t.Errorf("Authorizations.GetOrCreateForApp returned error: %v", err)
}
want := &Authorization{ID: Int(1)}
if !reflect.DeepEqual(got, want) {
t.Errorf("Authorization.GetOrCreateForApp returned %+v, want %+v", got, want)
}
}
func TestAuthorizationsService_GetOrCreateForApp_Fingerprint(t *testing.T) {
setup()
defer teardown()
input := &AuthorizationRequest{
Note: String("test"),
Fingerprint: String("fp"),
}
mux.HandleFunc("/authorizations/clients/id/fp", func(w http.ResponseWriter, r *http.Request) {
v := new(AuthorizationRequest)
json.NewDecoder(r.Body).Decode(v)
testMethod(t, r, "PUT")
if !reflect.DeepEqual(v, input) {
t.Errorf("Request body = %+v, want %+v", v, input)
}
fmt.Fprint(w, `{"ID":1}`)
})
got, _, err := client.Authorizations.GetOrCreateForApp("id", input)
if err != nil {
t.Errorf("Authorizations.GetOrCreateForApp returned error: %v", err)
}
want := &Authorization{ID: Int(1)}
if !reflect.DeepEqual(got, want) {
t.Errorf("Authorization.GetOrCreateForApp returned %+v, want %+v", got, want)
}
}
func TestAuthorizationsService_Edit(t *testing.T) {
setup()
defer teardown()
input := &AuthorizationUpdateRequest{
Note: String("test"),
}
mux.HandleFunc("/authorizations/1", func(w http.ResponseWriter, r *http.Request) {
v := new(AuthorizationUpdateRequest)
json.NewDecoder(r.Body).Decode(v)
testMethod(t, r, "PATCH")
if !reflect.DeepEqual(v, input) {
t.Errorf("Request body = %+v, want %+v", v, input)
}
fmt.Fprint(w, `{"ID":1}`)
})
got, _, err := client.Authorizations.Edit(1, input)
if err != nil {
t.Errorf("Authorizations.Edit returned error: %v", err)
}
want := &Authorization{ID: Int(1)}
if !reflect.DeepEqual(got, want) {
t.Errorf("Authorization.Update returned %+v, want %+v", got, want)
}
}
func TestAuthorizationsService_Delete(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/authorizations/1", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "DELETE")
w.WriteHeader(http.StatusNoContent)
})
_, err := client.Authorizations.Delete(1)
if err != nil {
t.Errorf("Authorizations.Delete returned error: %v", err)
}
}
func TestAuthorizationsService_Check(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/applications/id/tokens/t", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
fmt.Fprint(w, `{"id":1}`)
})
got, _, err := client.Authorizations.Check("id", "t")
if err != nil {
t.Errorf("Authorizations.Check returned error: %v", err)
}
want := &Authorization{ID: Int(1)}
if !reflect.DeepEqual(got, want) {
t.Errorf("Authorizations.Check returned auth %+v, want %+v", got, want)
}
}
func TestAuthorizationsService_Reset(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/applications/id/tokens/t", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "POST")
fmt.Fprint(w, `{"ID":1}`)
})
got, _, err := client.Authorizations.Reset("id", "t")
if err != nil {
t.Errorf("Authorizations.Reset returned error: %v", err)
}
want := &Authorization{ID: Int(1)}
if !reflect.DeepEqual(got, want) {
t.Errorf("Authorizations.Reset returned auth %+v, want %+v", got, want)
}
}
func TestAuthorizationsService_Revoke(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/applications/id/tokens/t", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "DELETE")
w.WriteHeader(http.StatusNoContent)
})
_, err := client.Authorizations.Revoke("id", "t")
if err != nil {
t.Errorf("Authorizations.Revoke returned error: %v", err)
}
}
func TestListGrants(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/applications/grants", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testHeader(t, r, "Accept", mediaTypeOAuthGrantAuthorizationsPreview)
fmt.Fprint(w, `[{"id": 1}]`)
})
got, _, err := client.Authorizations.ListGrants()
if err != nil {
t.Errorf("OAuthAuthorizations.ListGrants returned error: %v", err)
}
want := []*Grant{{ID: Int(1)}}
if !reflect.DeepEqual(got, want) {
t.Errorf("OAuthAuthorizations.ListGrants = %+v, want %+v", got, want)
}
}
func TestGetGrant(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/applications/grants/1", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testHeader(t, r, "Accept", mediaTypeOAuthGrantAuthorizationsPreview)
fmt.Fprint(w, `{"id": 1}`)
})
got, _, err := client.Authorizations.GetGrant(1)
if err != nil {
t.Errorf("OAuthAuthorizations.GetGrant returned error: %v", err)
}
want := &Grant{ID: Int(1)}
if !reflect.DeepEqual(got, want) {
t.Errorf("OAuthAuthorizations.GetGrant = %+v, want %+v", got, want)
}
}
func TestDeleteGrant(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/applications/grants/1", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "DELETE")
testHeader(t, r, "Accept", mediaTypeOAuthGrantAuthorizationsPreview)
})
_, err := client.Authorizations.DeleteGrant(1)
if err != nil {
t.Errorf("OAuthAuthorizations.DeleteGrant returned error: %v", err)
}
}
func TestAuthorizationsService_CreateImpersonation(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/admin/users/u/authorizations", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "POST")
fmt.Fprint(w, `{"id":1}`)
})
req := &AuthorizationRequest{Scopes: []Scope{ScopePublicRepo}}
got, _, err := client.Authorizations.CreateImpersonation("u", req)
if err != nil {
t.Errorf("Authorizations.CreateImpersonation returned error: %+v", err)
}
want := &Authorization{ID: Int(1)}
if !reflect.DeepEqual(got, want) {
t.Errorf("Authorizations.CreateImpersonation returned %+v, want %+v", *got.ID, *want.ID)
}
}
func TestAuthorizationsService_DeleteImpersonation(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/admin/users/u/authorizations", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "DELETE")
})
_, err := client.Authorizations.DeleteImpersonation("u")
if err != nil {
t.Errorf("Authorizations.DeleteImpersonation returned error: %+v", err)
}
}

145
vendor/src/github.com/google/go-github/github/doc.go

@ -0,0 +1,145 @@
// Copyright 2013 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
/*
Package github provides a client for using the GitHub API.
Usage:
import "github.com/google/go-github/github"
Construct a new GitHub client, then use the various services on the client to
access different parts of the GitHub API. For example:
client := github.NewClient(nil)
// list all organizations for user "willnorris"
orgs, _, err := client.Organizations.List("willnorris", nil)
Some API methods have optional parameters that can be passed. For example:
client := github.NewClient(nil)
// list recently updated repositories for org "github"
opt := &github.RepositoryListByOrgOptions{Sort: "updated"}
repos, _, err := client.Repositories.ListByOrg("github", opt)
The services of a client divide the API into logical chunks and correspond to
the structure of the GitHub API documentation at
http://developer.github.com/v3/.
Authentication
The go-github library does not directly handle authentication. Instead, when
creating a new client, pass an http.Client that can handle authentication for
you. The easiest and recommended way to do this is using the golang.org/x/oauth2
library, but you can always use any other library that provides an http.Client.
If you have an OAuth2 access token (for example, a personal API token), you can
use it with the oauth2 library using:
import "golang.org/x/oauth2"
func main() {
ts := oauth2.StaticTokenSource(
&oauth2.Token{AccessToken: "... your access token ..."},
)
tc := oauth2.NewClient(oauth2.NoContext, ts)
client := github.NewClient(tc)
// list all repositories for the authenticated user
repos, _, err := client.Repositories.List("", nil)
}
Note that when using an authenticated Client, all calls made by the client will
include the specified OAuth token. Therefore, authenticated clients should
almost never be shared between different users.
See the oauth2 docs for complete instructions on using that library.
For API methods that require HTTP Basic Authentication, use the
BasicAuthTransport.
Rate Limiting
GitHub imposes a rate limit on all API clients. Unauthenticated clients are
limited to 60 requests per hour, while authenticated clients can make up to
5,000 requests per hour. To receive the higher rate limit when making calls
that are not issued on behalf of a user, use the
UnauthenticatedRateLimitedTransport.
The Rate method on a client returns the rate limit information based on the most
recent API call. This is updated on every call, but may be out of date if it's
been some time since the last API call and other clients have made subsequent
requests since then. You can always call RateLimits() directly to get the most
up-to-date rate limit data for the client.
To detect an API rate limit error, you can check if its type is *github.RateLimitError:
repos, _, err := client.Repositories.List("", nil)
if _, ok := err.(*github.RateLimitError); ok {
log.Println("hit rate limit")
}
Learn more about GitHub rate limiting at
http://developer.github.com/v3/#rate-limiting.
Conditional Requests
The GitHub API has good support for conditional requests which will help
prevent you from burning through your rate limit, as well as help speed up your
application. go-github does not handle conditional requests directly, but is
instead designed to work with a caching http.Transport. We recommend using
https://github.com/gregjones/httpcache for that.
Learn more about GitHub conditional requests at
https://developer.github.com/v3/#conditional-requests.
Creating and Updating Resources
All structs for GitHub resources use pointer values for all non-repeated fields.
This allows distinguishing between unset fields and those set to a zero-value.
Helper functions have been provided to easily create these pointers for string,
bool, and int values. For example:
// create a new private repository named "foo"
repo := &github.Repository{
Name: github.String("foo"),
Private: github.Bool(true),
}
client.Repositories.Create("", repo)
Users who have worked with protocol buffers should find this pattern familiar.
Pagination
All requests for resource collections (repos, pull requests, issues, etc.)
support pagination. Pagination options are described in the
github.ListOptions struct and passed to the list methods directly or as an
embedded type of a more specific list options struct (for example
github.PullRequestListOptions). Pages information is available via the
github.Response struct.
client := github.NewClient(nil)
opt := &github.RepositoryListByOrgOptions{
ListOptions: github.ListOptions{PerPage: 10},
}
// get all pages of results
var allRepos []*github.Repository
for {
repos, resp, err := client.Repositories.ListByOrg("github", opt)
if err != nil {
return err
}
allRepos = append(allRepos, repos...)
if resp.NextPage == 0 {
break
}
opt.ListOptions.Page = resp.NextPage
}
*/
package github

467
vendor/src/github.com/google/go-github/github/event_types.go

@ -0,0 +1,467 @@
// Copyright 2016 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// These event types are shared between the Events API and used as Webhook payloads.
package github
// CommitCommentEvent is triggered when a commit comment is created.
// The Webhook event name is "commit_comment".
//
// GitHub docs: https://developer.github.com/v3/activity/events/types/#commitcommentevent
type CommitCommentEvent struct {
Comment *RepositoryComment `json:"comment,omitempty"`
// The following fields are only populated by Webhook events.
Action *string `json:"action,omitempty"`
Repo *Repository `json:"repository,omitempty"`
Sender *User `json:"sender,omitempty"`
}
// CreateEvent represents a created repository, branch, or tag.
// The Webhook event name is "create".
//
// Note: webhooks will not receive this event for created repositories.
// Additionally, webhooks will not receive this event for tags if more
// than three tags are pushed at once.
//
// GitHub docs: https://developer.github.com/v3/activity/events/types/#createevent
type CreateEvent struct {
Ref *string `json:"ref,omitempty"`
// RefType is the object that was created. Possible values are: "repository", "branch", "tag".
RefType *string `json:"ref_type,omitempty"`
MasterBranch *string `json:"master_branch,omitempty"`
Description *string `json:"description,omitempty"`
// The following fields are only populated by Webhook events.
PusherType *string `json:"pusher_type,omitempty"`
Repo *Repository `json:"repository,omitempty"`
Sender *User `json:"sender,omitempty"`
}
// DeleteEvent represents a deleted branch or tag.
// The Webhook event name is "delete".
//
// Note: webhooks will not receive this event for tags if more than three tags
// are deleted at once.
//
// GitHub docs: https://developer.github.com/v3/activity/events/types/#deleteevent
type DeleteEvent struct {
Ref *string `json:"ref,omitempty"`
// RefType is the object that was deleted. Possible values are: "branch", "tag".
RefType *string `json:"ref_type,omitempty"`
// The following fields are only populated by Webhook events.
PusherType *string `json:"pusher_type,omitempty"`
Repo *Repository `json:"repository,omitempty"`
Sender *User `json:"sender,omitempty"`
}
// DeploymentEvent represents a deployment.
// The Webhook event name is "deployment".
//
// Events of this type are not visible in timelines, they are only used to trigger hooks.
//
// GitHub docs: https://developer.github.com/v3/activity/events/types/#deploymentevent
type DeploymentEvent struct {
Deployment *Deployment `json:"deployment,omitempty"`
Repo *Repository `json:"repository,omitempty"`
// The following fields are only populated by Webhook events.
Sender *User `json:"sender,omitempty"`
}
// DeploymentStatusEvent represents a deployment status.
// The Webhook event name is "deployment_status".
//
// Events of this type are not visible in timelines, they are only used to trigger hooks.
//
// GitHub docs: https://developer.github.com/v3/activity/events/types/#deploymentstatusevent
type DeploymentStatusEvent struct {
Deployment *Deployment `json:"deployment,omitempty"`
DeploymentStatus *DeploymentStatus `json:"deployment_status,omitempty"`
Repo *Repository `json:"repository,omitempty"`
// The following fields are only populated by Webhook events.
Sender *User `json:"sender,omitempty"`
}
// ForkEvent is triggered when a user forks a repository.
// The Webhook event name is "fork".
//
// GitHub docs: https://developer.github.com/v3/activity/events/types/#forkevent
type ForkEvent struct {
// Forkee is the created repository.
Forkee *Repository `json:"forkee,omitempty"`
// The following fields are only populated by Webhook events.
Repo *Repository `json:"repository,omitempty"`
Sender *User `json:"sender,omitempty"`
}
// Page represents a single Wiki page.
type Page struct {
PageName *string `json:"page_name,omitempty"`
Title *string `json:"title,omitempty"`
Summary *string `json:"summary,omitempty"`
Action *string `json:"action,omitempty"`
SHA *string `json:"sha,omitempty"`
HTMLURL *string `json:"html_url,omitempty"`
}
// GollumEvent is triggered when a Wiki page is created or updated.
// The Webhook event name is "gollum".
//
// GitHub docs: https://developer.github.com/v3/activity/events/types/#gollumevent
type GollumEvent struct {
Pages []*Page `json:"pages,omitempty"`
// The following fields are only populated by Webhook events.
Repo *Repository `json:"repository,omitempty"`
Sender *User `json:"sender,omitempty"`
}
// DEPRECATED: IssueActivityEvent represents the payload delivered by Issue webhook
// Use IssuesEvent instead.
type IssueActivityEvent struct {
Action *string `json:"action,omitempty"`
Issue *Issue `json:"issue,omitempty"`
// The following fields are only populated by Webhook events.
Repo *Repository `json:"repository,omitempty"`
Sender *User `json:"sender,omitempty"`
}
// EditChange represents the changes when an issue, pull request, or comment has
// been edited.
type EditChange struct {
Title *struct {
From *string `json:"from,omitempty"`
} `json:"title,omitempty"`
Body *struct {
From *string `json:"from,omitempty"`
} `json:"body,omitempty"`
}
// IssueCommentEvent is triggered when an issue comment is created on an issue
// or pull request.
// The Webhook event name is "issue_comment".
//
// GitHub docs: https://developer.github.com/v3/activity/events/types/#issuecommentevent
type IssueCommentEvent struct {
// Action is the action that was performed on the comment.
// Possible values are: "created", "edited", "deleted".
Action *string `json:"action,omitempty"`
Issue *Issue `json:"issue,omitempty"`
Comment *IssueComment `json:"comment,omitempty"`
// The following fields are only populated by Webhook events.
Changes *EditChange `json:"changes,omitempty"`
Repo *Repository `json:"repository,omitempty"`
Sender *User `json:"sender,omitempty"`
}
// IssuesEvent is triggered when an issue is assigned, unassigned, labeled,
// unlabeled, opened, closed, or reopened.
// The Webhook event name is "issues".
//
// GitHub docs: https://developer.github.com/v3/activity/events/types/#issuesevent
type IssuesEvent struct {
// Action is the action that was performed. Possible values are: "assigned",
// "unassigned", "labeled", "unlabeled", "opened", "closed", "reopened", "edited".
Action *string `json:"action,omitempty"`
Issue *Issue `json:"issue,omitempty"`
Assignee *User `json:"assignee,omitempty"`
Label *Label `json:"label,omitempty"`
// The following fields are only populated by Webhook events.
Changes *EditChange `json:"changes,omitempty"`
Repo *Repository `json:"repository,omitempty"`
Sender *User `json:"sender,omitempty"`
}
// MemberEvent is triggered when a user is added as a collaborator to a repository.
// The Webhook event name is "member".
//
// GitHub docs: https://developer.github.com/v3/activity/events/types/#memberevent
type MemberEvent struct {
// Action is the action that was performed. Possible value is: "added".
Action *string `json:"action,omitempty"`
Member *User `json:"member,omitempty"`
// The following fields are only populated by Webhook events.
Repo *Repository `json:"repository,omitempty"`
Sender *User `json:"sender,omitempty"`
}
// MembershipEvent is triggered when a user is added or removed from a team.
// The Webhook event name is "membership".
//
// Events of this type are not visible in timelines, they are only used to
// trigger organization webhooks.
//
// GitHub docs: https://developer.github.com/v3/activity/events/types/#membershipevent
type MembershipEvent struct {
// Action is the action that was performed. Possible values are: "added", "removed".
Action *string `json:"action,omitempty"`
// Scope is the scope of the membership. Possible value is: "team".
Scope *string `json:"scope,omitempty"`
Member *User `json:"member,omitempty"`
Team *Team `json:"team,omitempty"`
// The following fields are only populated by Webhook events.
Org *Organization `json:"organization,omitempty"`
Sender *User `json:"sender,omitempty"`
}
// PageBuildEvent represents an attempted build of a GitHub Pages site, whether
// successful or not.
// The Webhook event name is "page_build".
//
// This event is triggered on push to a GitHub Pages enabled branch (gh-pages
// for project pages, master for user and organization pages).
//
// Events of this type are not visible in timelines, they are only used to trigger hooks.
//
// GitHub docs: https://developer.github.com/v3/activity/events/types/#pagebuildevent
type PageBuildEvent struct {
Build *PagesBuild `json:"build,omitempty"`
// The following fields are only populated by Webhook events.
ID *int `json:"id,omitempty"`
Repo *Repository `json:"repository,omitempty"`
Sender *User `json:"sender,omitempty"`
}
// PublicEvent is triggered when a private repository is open sourced.
// According to GitHub: "Without a doubt: the best GitHub event."
// The Webhook event name is "public".
//
// GitHub docs: https://developer.github.com/v3/activity/events/types/#publicevent
type PublicEvent struct {
// The following fields are only populated by Webhook events.
Repo *Repository `json:"repository,omitempty"`
Sender *User `json:"sender,omitempty"`
}
// PullRequestEvent is triggered when a pull request is assigned, unassigned,
// labeled, unlabeled, opened, closed, reopened, or synchronized.
// The Webhook event name is "pull_request".
//
// GitHub docs: https://developer.github.com/v3/activity/events/types/#pullrequestevent
type PullRequestEvent struct {
// Action is the action that was performed. Possible values are: "assigned",
// "unassigned", "labeled", "unlabeled", "opened", "closed", or "reopened",
// "synchronize", "edited". If the action is "closed" and the merged key is false,
// the pull request was closed with unmerged commits. If the action is "closed"
// and the merged key is true, the pull request was merged.
Action *string `json:"action,omitempty"`
Number *int `json:"number,omitempty"`
PullRequest *PullRequest `json:"pull_request,omitempty"`
// The following fields are only populated by Webhook events.
Changes *EditChange `json:"changes,omitempty"`
Repo *Repository `json:"repository,omitempty"`
Sender *User `json:"sender,omitempty"`
}
// PullRequestReviewCommentEvent is triggered when a comment is created on a
// portion of the unified diff of a pull request.
// The Webhook event name is "pull_request_review_comment".
//
// GitHub docs: https://developer.github.com/v3/activity/events/types/#pullrequestreviewcommentevent
type PullRequestReviewCommentEvent struct {
// Action is the action that was performed on the comment.
// Possible values are: "created", "edited", "deleted".
Action *string `json:"action,omitempty"`
PullRequest *PullRequest `json:"pull_request,omitempty"`
Comment *PullRequestComment `json:"comment,omitempty"`
// The following fields are only populated by Webhook events.
Changes *EditChange `json:"changes,omitempty"`
Repo *Repository `json:"repository,omitempty"`
Sender *User `json:"sender,omitempty"`
}
// PushEvent represents a git push to a GitHub repository.
//
// GitHub API docs: http://developer.github.com/v3/activity/events/types/#pushevent
type PushEvent struct {
PushID *int `json:"push_id,omitempty"`
Head *string `json:"head,omitempty"`
Ref *string `json:"ref,omitempty"`
Size *int `json:"size,omitempty"`
Commits []PushEventCommit `json:"commits,omitempty"`
Repo *PushEventRepository `json:"repository,omitempty"`
Before *string `json:"before,omitempty"`
DistinctSize *int `json:"distinct_size,omitempty"`
// The following fields are only populated by Webhook events.
After *string `json:"after,omitempty"`
Created *bool `json:"created,omitempty"`
Deleted *bool `json:"deleted,omitempty"`
Forced *bool `json:"forced,omitempty"`
BaseRef *string `json:"base_ref,omitempty"`
Compare *string `json:"compare,omitempty"`
HeadCommit *PushEventCommit `json:"head_commit,omitempty"`
Pusher *User `json:"pusher,omitempty"`
Sender *User `json:"sender,omitempty"`
}
func (p PushEvent) String() string {
return Stringify(p)
}
// PushEventCommit represents a git commit in a GitHub PushEvent.
type PushEventCommit struct {
Message *string `json:"message,omitempty"`
Author *CommitAuthor `json:"author,omitempty"`
URL *string `json:"url,omitempty"`
Distinct *bool `json:"distinct,omitempty"`
// The following fields are only populated by Events API.
SHA *string `json:"sha,omitempty"`
// The following fields are only populated by Webhook events.
ID *string `json:"id,omitempty"`
TreeID *string `json:"tree_id,omitempty"`
Timestamp *Timestamp `json:"timestamp,omitempty"`
Committer *CommitAuthor `json:"committer,omitempty"`
Added []string `json:"added,omitempty"`
Removed []string `json:"removed,omitempty"`
Modified []string `json:"modified,omitempty"`
}
func (p PushEventCommit) String() string {
return Stringify(p)
}
// PushEventRepository represents the repo object in a PushEvent payload
type PushEventRepository struct {
ID *int `json:"id,omitempty"`
Name *string `json:"name,omitempty"`
FullName *string `json:"full_name,omitempty"`
Owner *PushEventRepoOwner `json:"owner,omitempty"`
Private *bool `json:"private,omitempty"`
Description *string `json:"description,omitempty"`
Fork *bool `json:"fork,omitempty"`
CreatedAt *Timestamp `json:"created_at,omitempty"`
PushedAt *Timestamp `json:"pushed_at,omitempty"`
UpdatedAt *Timestamp `json:"updated_at,omitempty"`
Homepage *string `json:"homepage,omitempty"`
Size *int `json:"size,omitempty"`
StargazersCount *int `json:"stargazers_count,omitempty"`
WatchersCount *int `json:"watchers_count,omitempty"`
Language *string `json:"language,omitempty"`
HasIssues *bool `json:"has_issues,omitempty"`
HasDownloads *bool `json:"has_downloads,omitempty"`
HasWiki *bool `json:"has_wiki,omitempty"`
HasPages *bool `json:"has_pages,omitempty"`
ForksCount *int `json:"forks_count,omitempty"`
OpenIssuesCount *int `json:"open_issues_count,omitempty"`
DefaultBranch *string `json:"default_branch,omitempty"`
MasterBranch *string `json:"master_branch,omitempty"`
Organization *string `json:"organization,omitempty"`
// The following fields are only populated by Webhook events.
URL *string `json:"url,omitempty"`
HTMLURL *string `json:"html_url,omitempty"`
}
// PushEventRepoOwner is a basic reporesntation of user/org in a PushEvent payload
type PushEventRepoOwner struct {
Name *string `json:"name,omitempty"`
Email *string `json:"email,omitempty"`
}
// ReleaseEvent is triggered when a release is published.
// The Webhook event name is "release".
//
// GitHub docs: https://developer.github.com/v3/activity/events/types/#releaseevent
type ReleaseEvent struct {
// Action is the action that was performed. Possible value is: "published".
Action *string `json:"action,omitempty"`
Release *RepositoryRelease `json:"release,omitempty"`
// The following fields are only populated by Webhook events.
Repo *Repository `json:"repository,omitempty"`
Sender *User `json:"sender,omitempty"`
}
// RepositoryEvent is triggered when a repository is created.
// The Webhook event name is "repository".
//
// Events of this type are not visible in timelines, they are only used to
// trigger organization webhooks.
//
// GitHub docs: https://developer.github.com/v3/activity/events/types/#repositoryevent
type RepositoryEvent struct {
// Action is the action that was performed. Possible values are: "created", "deleted",
// "publicized", "privatized".
Action *string `json:"action,omitempty"`
Repo *Repository `json:"repository,omitempty"`
// The following fields are only populated by Webhook events.
Org *Organization `json:"organization,omitempty"`
Sender *User `json:"sender,omitempty"`
}
// StatusEvent is triggered when the status of a Git commit changes.
// The Webhook event name is "status".
//
// Events of this type are not visible in timelines, they are only used to
// trigger hooks.
//
// GitHub docs: https://developer.github.com/v3/activity/events/types/#statusevent
type StatusEvent struct {
SHA *string `json:"sha,omitempty"`
// State is the new state. Possible values are: "pending", "success", "failure", "error".
State *string `json:"state,omitempty"`
Description *string `json:"description,omitempty"`
TargetURL *string `json:"target_url,omitempty"`
Branches []*Branch `json:"branches,omitempty"`
// The following fields are only populated by Webhook events.
ID *int `json:"id,omitempty"`
Name *string `json:"name,omitempty"`
Context *string `json:"context,omitempty"`
Commit *PushEventCommit `json:"commit,omitempty"`
CreatedAt *Timestamp `json:"created_at,omitempty"`
UpdatedAt *Timestamp `json:"updated_at,omitempty"`
Repo *Repository `json:"repository,omitempty"`
Sender *User `json:"sender,omitempty"`
}
// TeamAddEvent is triggered when a repository is added to a team.
// The Webhook event name is "team_add".
//
// Events of this type are not visible in timelines. These events are only used
// to trigger hooks.
//
// GitHub docs: https://developer.github.com/v3/activity/events/types/#teamaddevent
type TeamAddEvent struct {
Team *Team `json:"team,omitempty"`
Repo *Repository `json:"repository,omitempty"`
// The following fields are only populated by Webhook events.
Org *Organization `json:"organization,omitempty"`
Sender *User `json:"sender,omitempty"`
}
// WatchEvent is related to starring a repository, not watching. See this API
// blog post for an explanation: https://developer.github.com/changes/2012-09-05-watcher-api/
//
// The event’s actor is the user who starred a repository, and the event’s
// repository is the repository that was starred.
//
// GitHub docs: https://developer.github.com/v3/activity/events/types/#watchevent
type WatchEvent struct {
// Action is the action that was performed. Possible value is: "started".
Action *string `json:"action,omitempty"`
// The following fields are only populated by Webhook events.
Repo *Repository `json:"repository,omitempty"`
Sender *User `json:"sender,omitempty"`
}

75
vendor/src/github.com/google/go-github/github/examples_test.go

@ -0,0 +1,75 @@
// Copyright 2016 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github_test
import (
"fmt"
"log"
"github.com/google/go-github/github"
)
func ExampleClient_Markdown() {
client := github.NewClient(nil)
input := "# heading #\n\nLink to issue #1"
opt := &github.MarkdownOptions{Mode: "gfm", Context: "google/go-github"}
output, _, err := client.Markdown(input, opt)
if err != nil {
fmt.Println(err)
}
fmt.Println(output)
}
func ExampleRepositoriesService_GetReadme() {
client := github.NewClient(nil)
readme, _, err := client.Repositories.GetReadme("google", "go-github", nil)
if err != nil {
fmt.Println(err)
return
}
content, err := readme.GetContent()
if err != nil {
fmt.Println(err)
return
}
fmt.Printf("google/go-github README:\n%v\n", content)
}
func ExampleRepositoriesService_List() {
client := github.NewClient(nil)
user := "willnorris"
opt := &github.RepositoryListOptions{Type: "owner", Sort: "updated", Direction: "desc"}
repos, _, err := client.Repositories.List(user, opt)
if err != nil {
fmt.Println(err)
}
fmt.Printf("Recently updated repositories by %q: %v", user, github.Stringify(repos))
}
func ExampleUsersService_ListAll() {
client := github.NewClient(nil)
opts := &github.UserListOptions{}
for {
users, _, err := client.Users.ListAll(opts)
if err != nil {
log.Fatalf("error listing users: %v", err)
}
if len(users) == 0 {
break
}
opts.Since = *users[len(users)-1].ID
// Process users...
}
}

343
vendor/src/github.com/google/go-github/github/gists.go

@ -0,0 +1,343 @@
// Copyright 2013 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by BSD-style
// license that can be found in the LICENSE file.
package github
import (
"fmt"
"time"
)
// GistsService handles communication with the Gist related
// methods of the GitHub API.
//
// GitHub API docs: http://developer.github.com/v3/gists/
type GistsService service
// Gist represents a GitHub's gist.
type Gist struct {
ID *string `json:"id,omitempty"`
Description *string `json:"description,omitempty"`
Public *bool `json:"public,omitempty"`
Owner *User `json:"owner,omitempty"`
Files map[GistFilename]GistFile `json:"files,omitempty"`
Comments *int `json:"comments,omitempty"`
HTMLURL *string `json:"html_url,omitempty"`
GitPullURL *string `json:"git_pull_url,omitempty"`
GitPushURL *string `json:"git_push_url,omitempty"`
CreatedAt *time.Time `json:"created_at,omitempty"`
UpdatedAt *time.Time `json:"updated_at,omitempty"`
}
func (g Gist) String() string {
return Stringify(g)
}
// GistFilename represents filename on a gist.
type GistFilename string
// GistFile represents a file on a gist.
type GistFile struct {
Size *int `json:"size,omitempty"`
Filename *string `json:"filename,omitempty"`
RawURL *string `json:"raw_url,omitempty"`
Content *string `json:"content,omitempty"`
}
func (g GistFile) String() string {
return Stringify(g)
}
// GistCommit represents a commit on a gist.
type GistCommit struct {
URL *string `json:"url,omitempty"`
Version *string `json:"version,omitempty"`
User *User `json:"user,omitempty"`
ChangeStatus *CommitStats `json:"change_status,omitempty"`
CommitedAt *Timestamp `json:"commited_at,omitempty"`
}
func (gc GistCommit) String() string {
return Stringify(gc)
}
// GistFork represents a fork of a gist.
type GistFork struct {
URL *string `json:"url,omitempty"`
User *User `json:"user,omitempty"`
ID *string `json:"id,omitempty"`
CreatedAt *Timestamp `json:"created_at,omitempty"`
UpdatedAt *Timestamp `json:"updated_at,omitempty"`
}
func (gf GistFork) String() string {
return Stringify(gf)
}
// GistListOptions specifies the optional parameters to the
// GistsService.List, GistsService.ListAll, and GistsService.ListStarred methods.
type GistListOptions struct {
// Since filters Gists by time.
Since time.Time `url:"since,omitempty"`
ListOptions
}
// List gists for a user. Passing the empty string will list
// all public gists if called anonymously. However, if the call
// is authenticated, it will returns all gists for the authenticated
// user.
//
// GitHub API docs: http://developer.github.com/v3/gists/#list-gists
func (s *GistsService) List(user string, opt *GistListOptions) ([]*Gist, *Response, error) {
var u string
if user != "" {
u = fmt.Sprintf("users/%v/gists", user)
} else {
u = "gists"
}
u, err := addOptions(u, opt)
if err != nil {
return nil, nil, err
}
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
gists := new([]*Gist)
resp, err := s.client.Do(req, gists)
if err != nil {
return nil, resp, err
}
return *gists, resp, err
}
// ListAll lists all public gists.
//
// GitHub API docs: http://developer.github.com/v3/gists/#list-gists
func (s *GistsService) ListAll(opt *GistListOptions) ([]*Gist, *Response, error) {
u, err := addOptions("gists/public", opt)
if err != nil {
return nil, nil, err
}
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
gists := new([]*Gist)
resp, err := s.client.Do(req, gists)
if err != nil {
return nil, resp, err
}
return *gists, resp, err
}
// ListStarred lists starred gists of authenticated user.
//
// GitHub API docs: http://developer.github.com/v3/gists/#list-gists
func (s *GistsService) ListStarred(opt *GistListOptions) ([]*Gist, *Response, error) {
u, err := addOptions("gists/starred", opt)
if err != nil {
return nil, nil, err
}
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
gists := new([]*Gist)
resp, err := s.client.Do(req, gists)
if err != nil {
return nil, resp, err
}
return *gists, resp, err
}
// Get a single gist.
//
// GitHub API docs: http://developer.github.com/v3/gists/#get-a-single-gist
func (s *GistsService) Get(id string) (*Gist, *Response, error) {
u := fmt.Sprintf("gists/%v", id)
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
gist := new(Gist)
resp, err := s.client.Do(req, gist)
if err != nil {
return nil, resp, err
}
return gist, resp, err
}
// GetRevision gets a specific revision of a gist.
//
// GitHub API docs: https://developer.github.com/v3/gists/#get-a-specific-revision-of-a-gist
func (s *GistsService) GetRevision(id, sha string) (*Gist, *Response, error) {
u := fmt.Sprintf("gists/%v/%v", id, sha)
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
gist := new(Gist)
resp, err := s.client.Do(req, gist)
if err != nil {
return nil, resp, err
}
return gist, resp, err
}
// Create a gist for authenticated user.
//
// GitHub API docs: http://developer.github.com/v3/gists/#create-a-gist
func (s *GistsService) Create(gist *Gist) (*Gist, *Response, error) {
u := "gists"
req, err := s.client.NewRequest("POST", u, gist)
if err != nil {
return nil, nil, err
}
g := new(Gist)
resp, err := s.client.Do(req, g)
if err != nil {
return nil, resp, err
}
return g, resp, err
}
// Edit a gist.
//
// GitHub API docs: http://developer.github.com/v3/gists/#edit-a-gist
func (s *GistsService) Edit(id string, gist *Gist) (*Gist, *Response, error) {
u := fmt.Sprintf("gists/%v", id)
req, err := s.client.NewRequest("PATCH", u, gist)
if err != nil {
return nil, nil, err
}
g := new(Gist)
resp, err := s.client.Do(req, g)
if err != nil {
return nil, resp, err
}
return g, resp, err
}
// ListCommits lists commits of a gist.
//
// Github API docs: https://developer.github.com/v3/gists/#list-gist-commits
func (s *GistsService) ListCommits(id string) ([]*GistCommit, *Response, error) {
u := fmt.Sprintf("gists/%v/commits", id)
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
gistCommits := new([]*GistCommit)
resp, err := s.client.Do(req, gistCommits)
if err != nil {
return nil, resp, err
}
return *gistCommits, resp, err
}
// Delete a gist.
//
// GitHub API docs: http://developer.github.com/v3/gists/#delete-a-gist
func (s *GistsService) Delete(id string) (*Response, error) {
u := fmt.Sprintf("gists/%v", id)
req, err := s.client.NewRequest("DELETE", u, nil)
if err != nil {
return nil, err
}
return s.client.Do(req, nil)
}
// Star a gist on behalf of authenticated user.
//
// GitHub API docs: http://developer.github.com/v3/gists/#star-a-gist
func (s *GistsService) Star(id string) (*Response, error) {
u := fmt.Sprintf("gists/%v/star", id)
req, err := s.client.NewRequest("PUT", u, nil)
if err != nil {
return nil, err
}
return s.client.Do(req, nil)
}
// Unstar a gist on a behalf of authenticated user.
//
// Github API docs: http://developer.github.com/v3/gists/#unstar-a-gist
func (s *GistsService) Unstar(id string) (*Response, error) {
u := fmt.Sprintf("gists/%v/star", id)
req, err := s.client.NewRequest("DELETE", u, nil)
if err != nil {
return nil, err
}
return s.client.Do(req, nil)
}
// IsStarred checks if a gist is starred by authenticated user.
//
// GitHub API docs: http://developer.github.com/v3/gists/#check-if-a-gist-is-starred
func (s *GistsService) IsStarred(id string) (bool, *Response, error) {
u := fmt.Sprintf("gists/%v/star", id)
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return false, nil, err
}
resp, err := s.client.Do(req, nil)
starred, err := parseBoolResponse(err)
return starred, resp, err
}
// Fork a gist.
//
// GitHub API docs: http://developer.github.com/v3/gists/#fork-a-gist
func (s *GistsService) Fork(id string) (*Gist, *Response, error) {
u := fmt.Sprintf("gists/%v/forks", id)
req, err := s.client.NewRequest("POST", u, nil)
if err != nil {
return nil, nil, err
}
g := new(Gist)
resp, err := s.client.Do(req, g)
if err != nil {
return nil, resp, err
}
return g, resp, err
}
// ListForks lists forks of a gist.
//
// Github API docs: https://developer.github.com/v3/gists/#list-gist-forks
func (s *GistsService) ListForks(id string) ([]*GistFork, *Response, error) {
u := fmt.Sprintf("gists/%v/forks", id)
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
gistForks := new([]*GistFork)
resp, err := s.client.Do(req, gistForks)
if err != nil {
return nil, resp, err
}
return *gistForks, resp, err
}

118
vendor/src/github.com/google/go-github/github/gists_comments.go

@ -0,0 +1,118 @@
// Copyright 2013 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github
import (
"fmt"
"time"
)
// GistComment represents a Gist comment.
type GistComment struct {
ID *int `json:"id,omitempty"`
URL *string `json:"url,omitempty"`
Body *string `json:"body,omitempty"`
User *User `json:"user,omitempty"`
CreatedAt *time.Time `json:"created_at,omitempty"`
}
func (g GistComment) String() string {
return Stringify(g)
}
// ListComments lists all comments for a gist.
//
// GitHub API docs: http://developer.github.com/v3/gists/comments/#list-comments-on-a-gist
func (s *GistsService) ListComments(gistID string, opt *ListOptions) ([]*GistComment, *Response, error) {
u := fmt.Sprintf("gists/%v/comments", gistID)
u, err := addOptions(u, opt)
if err != nil {
return nil, nil, err
}
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
comments := new([]*GistComment)
resp, err := s.client.Do(req, comments)
if err != nil {
return nil, resp, err
}
return *comments, resp, err
}
// GetComment retrieves a single comment from a gist.
//
// GitHub API docs: http://developer.github.com/v3/gists/comments/#get-a-single-comment
func (s *GistsService) GetComment(gistID string, commentID int) (*GistComment, *Response, error) {
u := fmt.Sprintf("gists/%v/comments/%v", gistID, commentID)
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
c := new(GistComment)
resp, err := s.client.Do(req, c)
if err != nil {
return nil, resp, err
}
return c, resp, err
}
// CreateComment creates a comment for a gist.
//
// GitHub API docs: http://developer.github.com/v3/gists/comments/#create-a-comment
func (s *GistsService) CreateComment(gistID string, comment *GistComment) (*GistComment, *Response, error) {
u := fmt.Sprintf("gists/%v/comments", gistID)
req, err := s.client.NewRequest("POST", u, comment)
if err != nil {
return nil, nil, err
}
c := new(GistComment)
resp, err := s.client.Do(req, c)
if err != nil {
return nil, resp, err
}
return c, resp, err
}
// EditComment edits an existing gist comment.
//
// GitHub API docs: http://developer.github.com/v3/gists/comments/#edit-a-comment
func (s *GistsService) EditComment(gistID string, commentID int, comment *GistComment) (*GistComment, *Response, error) {
u := fmt.Sprintf("gists/%v/comments/%v", gistID, commentID)
req, err := s.client.NewRequest("PATCH", u, comment)
if err != nil {
return nil, nil, err
}
c := new(GistComment)
resp, err := s.client.Do(req, c)
if err != nil {
return nil, resp, err
}
return c, resp, err
}
// DeleteComment deletes a gist comment.
//
// GitHub API docs: http://developer.github.com/v3/gists/comments/#delete-a-comment
func (s *GistsService) DeleteComment(gistID string, commentID int) (*Response, error) {
u := fmt.Sprintf("gists/%v/comments/%v", gistID, commentID)
req, err := s.client.NewRequest("DELETE", u, nil)
if err != nil {
return nil, err
}
return s.client.Do(req, nil)
}

153
vendor/src/github.com/google/go-github/github/gists_comments_test.go

@ -0,0 +1,153 @@
// Copyright 2013 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github
import (
"encoding/json"
"fmt"
"net/http"
"reflect"
"testing"
)
func TestGistsService_ListComments(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/gists/1/comments", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testFormValues(t, r, values{"page": "2"})
fmt.Fprint(w, `[{"id": 1}]`)
})
opt := &ListOptions{Page: 2}
comments, _, err := client.Gists.ListComments("1", opt)
if err != nil {
t.Errorf("Gists.Comments returned error: %v", err)
}
want := []*GistComment{{ID: Int(1)}}
if !reflect.DeepEqual(comments, want) {
t.Errorf("Gists.ListComments returned %+v, want %+v", comments, want)
}
}
func TestGistsService_ListComments_invalidID(t *testing.T) {
_, _, err := client.Gists.ListComments("%", nil)
testURLParseError(t, err)
}
func TestGistsService_GetComment(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/gists/1/comments/2", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
fmt.Fprint(w, `{"id": 1}`)
})
comment, _, err := client.Gists.GetComment("1", 2)
if err != nil {
t.Errorf("Gists.GetComment returned error: %v", err)
}
want := &GistComment{ID: Int(1)}
if !reflect.DeepEqual(comment, want) {
t.Errorf("Gists.GetComment returned %+v, want %+v", comment, want)
}
}
func TestGistsService_GetComment_invalidID(t *testing.T) {
_, _, err := client.Gists.GetComment("%", 1)
testURLParseError(t, err)
}
func TestGistsService_CreateComment(t *testing.T) {
setup()
defer teardown()
input := &GistComment{ID: Int(1), Body: String("b")}
mux.HandleFunc("/gists/1/comments", func(w http.ResponseWriter, r *http.Request) {
v := new(GistComment)
json.NewDecoder(r.Body).Decode(v)
testMethod(t, r, "POST")
if !reflect.DeepEqual(v, input) {
t.Errorf("Request body = %+v, want %+v", v, input)
}
fmt.Fprint(w, `{"id":1}`)
})
comment, _, err := client.Gists.CreateComment("1", input)
if err != nil {
t.Errorf("Gists.CreateComment returned error: %v", err)
}
want := &GistComment{ID: Int(1)}
if !reflect.DeepEqual(comment, want) {
t.Errorf("Gists.CreateComment returned %+v, want %+v", comment, want)
}
}
func TestGistsService_CreateComment_invalidID(t *testing.T) {
_, _, err := client.Gists.CreateComment("%", nil)
testURLParseError(t, err)
}
func TestGistsService_EditComment(t *testing.T) {
setup()
defer teardown()
input := &GistComment{ID: Int(1), Body: String("b")}
mux.HandleFunc("/gists/1/comments/2", func(w http.ResponseWriter, r *http.Request) {
v := new(GistComment)
json.NewDecoder(r.Body).Decode(v)
testMethod(t, r, "PATCH")
if !reflect.DeepEqual(v, input) {
t.Errorf("Request body = %+v, want %+v", v, input)
}
fmt.Fprint(w, `{"id":1}`)
})
comment, _, err := client.Gists.EditComment("1", 2, input)
if err != nil {
t.Errorf("Gists.EditComment returned error: %v", err)
}
want := &GistComment{ID: Int(1)}
if !reflect.DeepEqual(comment, want) {
t.Errorf("Gists.EditComment returned %+v, want %+v", comment, want)
}
}
func TestGistsService_EditComment_invalidID(t *testing.T) {
_, _, err := client.Gists.EditComment("%", 1, nil)
testURLParseError(t, err)
}
func TestGistsService_DeleteComment(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/gists/1/comments/2", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "DELETE")
})
_, err := client.Gists.DeleteComment("1", 2)
if err != nil {
t.Errorf("Gists.Delete returned error: %v", err)
}
}
func TestGistsService_DeleteComment_invalidID(t *testing.T) {
_, err := client.Gists.DeleteComment("%", 1)
testURLParseError(t, err)
}

488
vendor/src/github.com/google/go-github/github/gists_test.go

@ -0,0 +1,488 @@
// Copyright 2013 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github
import (
"encoding/json"
"fmt"
"net/http"
"reflect"
"testing"
"time"
)
func TestGistsService_List_specifiedUser(t *testing.T) {
setup()
defer teardown()
since := "2013-01-01T00:00:00Z"
mux.HandleFunc("/users/u/gists", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testFormValues(t, r, values{
"since": since,
})
fmt.Fprint(w, `[{"id": "1"}]`)
})
opt := &GistListOptions{Since: time.Date(2013, time.January, 1, 0, 0, 0, 0, time.UTC)}
gists, _, err := client.Gists.List("u", opt)
if err != nil {
t.Errorf("Gists.List returned error: %v", err)
}
want := []*Gist{{ID: String("1")}}
if !reflect.DeepEqual(gists, want) {
t.Errorf("Gists.List returned %+v, want %+v", gists, want)
}
}
func TestGistsService_List_authenticatedUser(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/gists", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
fmt.Fprint(w, `[{"id": "1"}]`)
})
gists, _, err := client.Gists.List("", nil)
if err != nil {
t.Errorf("Gists.List returned error: %v", err)
}
want := []*Gist{{ID: String("1")}}
if !reflect.DeepEqual(gists, want) {
t.Errorf("Gists.List returned %+v, want %+v", gists, want)
}
}
func TestGistsService_List_invalidUser(t *testing.T) {
_, _, err := client.Gists.List("%", nil)
testURLParseError(t, err)
}
func TestGistsService_ListAll(t *testing.T) {
setup()
defer teardown()
since := "2013-01-01T00:00:00Z"
mux.HandleFunc("/gists/public", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testFormValues(t, r, values{
"since": since,
})
fmt.Fprint(w, `[{"id": "1"}]`)
})
opt := &GistListOptions{Since: time.Date(2013, time.January, 1, 0, 0, 0, 0, time.UTC)}
gists, _, err := client.Gists.ListAll(opt)
if err != nil {
t.Errorf("Gists.ListAll returned error: %v", err)
}
want := []*Gist{{ID: String("1")}}
if !reflect.DeepEqual(gists, want) {
t.Errorf("Gists.ListAll returned %+v, want %+v", gists, want)
}
}
func TestGistsService_ListStarred(t *testing.T) {
setup()
defer teardown()
since := "2013-01-01T00:00:00Z"
mux.HandleFunc("/gists/starred", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testFormValues(t, r, values{
"since": since,
})
fmt.Fprint(w, `[{"id": "1"}]`)
})
opt := &GistListOptions{Since: time.Date(2013, time.January, 1, 0, 0, 0, 0, time.UTC)}
gists, _, err := client.Gists.ListStarred(opt)
if err != nil {
t.Errorf("Gists.ListStarred returned error: %v", err)
}
want := []*Gist{{ID: String("1")}}
if !reflect.DeepEqual(gists, want) {
t.Errorf("Gists.ListStarred returned %+v, want %+v", gists, want)
}
}
func TestGistsService_Get(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/gists/1", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
fmt.Fprint(w, `{"id": "1"}`)
})
gist, _, err := client.Gists.Get("1")
if err != nil {
t.Errorf("Gists.Get returned error: %v", err)
}
want := &Gist{ID: String("1")}
if !reflect.DeepEqual(gist, want) {
t.Errorf("Gists.Get returned %+v, want %+v", gist, want)
}
}
func TestGistsService_Get_invalidID(t *testing.T) {
_, _, err := client.Gists.Get("%")
testURLParseError(t, err)
}
func TestGistsService_GetRevision(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/gists/1/s", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
fmt.Fprint(w, `{"id": "1"}`)
})
gist, _, err := client.Gists.GetRevision("1", "s")
if err != nil {
t.Errorf("Gists.Get returned error: %v", err)
}
want := &Gist{ID: String("1")}
if !reflect.DeepEqual(gist, want) {
t.Errorf("Gists.Get returned %+v, want %+v", gist, want)
}
}
func TestGistsService_GetRevision_invalidID(t *testing.T) {
_, _, err := client.Gists.GetRevision("%", "%")
testURLParseError(t, err)
}
func TestGistsService_Create(t *testing.T) {
setup()
defer teardown()
input := &Gist{
Description: String("Gist description"),
Public: Bool(false),
Files: map[GistFilename]GistFile{
"test.txt": {Content: String("Gist file content")},
},
}
mux.HandleFunc("/gists", func(w http.ResponseWriter, r *http.Request) {
v := new(Gist)
json.NewDecoder(r.Body).Decode(v)
testMethod(t, r, "POST")
if !reflect.DeepEqual(v, input) {
t.Errorf("Request body = %+v, want %+v", v, input)
}
fmt.Fprint(w,
`
{
"id": "1",
"description": "Gist description",
"public": false,
"files": {
"test.txt": {
"filename": "test.txt"
}
}
}`)
})
gist, _, err := client.Gists.Create(input)
if err != nil {
t.Errorf("Gists.Create returned error: %v", err)
}
want := &Gist{
ID: String("1"),
Description: String("Gist description"),
Public: Bool(false),
Files: map[GistFilename]GistFile{
"test.txt": {Filename: String("test.txt")},
},
}
if !reflect.DeepEqual(gist, want) {
t.Errorf("Gists.Create returned %+v, want %+v", gist, want)
}
}
func TestGistsService_Edit(t *testing.T) {
setup()
defer teardown()
input := &Gist{
Description: String("New description"),
Files: map[GistFilename]GistFile{
"new.txt": {Content: String("new file content")},
},
}
mux.HandleFunc("/gists/1", func(w http.ResponseWriter, r *http.Request) {
v := new(Gist)
json.NewDecoder(r.Body).Decode(v)
testMethod(t, r, "PATCH")
if !reflect.DeepEqual(v, input) {
t.Errorf("Request body = %+v, want %+v", v, input)
}
fmt.Fprint(w,
`
{
"id": "1",
"description": "new description",
"public": false,
"files": {
"test.txt": {
"filename": "test.txt"
},
"new.txt": {
"filename": "new.txt"
}
}
}`)
})
gist, _, err := client.Gists.Edit("1", input)
if err != nil {
t.Errorf("Gists.Edit returned error: %v", err)
}
want := &Gist{
ID: String("1"),
Description: String("new description"),
Public: Bool(false),
Files: map[GistFilename]GistFile{
"test.txt": {Filename: String("test.txt")},
"new.txt": {Filename: String("new.txt")},
},
}
if !reflect.DeepEqual(gist, want) {
t.Errorf("Gists.Edit returned %+v, want %+v", gist, want)
}
}
func TestGistsService_Edit_invalidID(t *testing.T) {
_, _, err := client.Gists.Edit("%", nil)
testURLParseError(t, err)
}
func TestGistsService_ListCommits(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/gists/1/commits", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testFormValues(t, r, nil)
fmt.Fprint(w, `
[
{
"url": "https://api.github.com/gists/1/1",
"version": "1",
"user": {
"id": 1
},
"change_status": {
"deletions": 0,
"additions": 180,
"total": 180
},
"commited_at": "2010-01-01T00:00:00Z"
}
]
`)
})
gistCommits, _, err := client.Gists.ListCommits("1")
if err != nil {
t.Errorf("Gists.ListCommits returned error: %v", err)
}
want := []*GistCommit{{
URL: String("https://api.github.com/gists/1/1"),
Version: String("1"),
User: &User{ID: Int(1)},
CommitedAt: &Timestamp{time.Date(2010, 1, 1, 00, 00, 00, 0, time.UTC)},
ChangeStatus: &CommitStats{
Additions: Int(180),
Deletions: Int(0),
Total: Int(180),
}}}
if !reflect.DeepEqual(gistCommits, want) {
t.Errorf("Gists.ListCommits returned %+v, want %+v", gistCommits, want)
}
}
func TestGistsService_Delete(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/gists/1", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "DELETE")
})
_, err := client.Gists.Delete("1")
if err != nil {
t.Errorf("Gists.Delete returned error: %v", err)
}
}
func TestGistsService_Delete_invalidID(t *testing.T) {
_, err := client.Gists.Delete("%")
testURLParseError(t, err)
}
func TestGistsService_Star(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/gists/1/star", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "PUT")
})
_, err := client.Gists.Star("1")
if err != nil {
t.Errorf("Gists.Star returned error: %v", err)
}
}
func TestGistsService_Star_invalidID(t *testing.T) {
_, err := client.Gists.Star("%")
testURLParseError(t, err)
}
func TestGistsService_Unstar(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/gists/1/star", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "DELETE")
})
_, err := client.Gists.Unstar("1")
if err != nil {
t.Errorf("Gists.Unstar returned error: %v", err)
}
}
func TestGistsService_Unstar_invalidID(t *testing.T) {
_, err := client.Gists.Unstar("%")
testURLParseError(t, err)
}
func TestGistsService_IsStarred_hasStar(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/gists/1/star", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
w.WriteHeader(http.StatusNoContent)
})
star, _, err := client.Gists.IsStarred("1")
if err != nil {
t.Errorf("Gists.Starred returned error: %v", err)
}
if want := true; star != want {
t.Errorf("Gists.Starred returned %+v, want %+v", star, want)
}
}
func TestGistsService_IsStarred_noStar(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/gists/1/star", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
w.WriteHeader(http.StatusNotFound)
})
star, _, err := client.Gists.IsStarred("1")
if err != nil {
t.Errorf("Gists.Starred returned error: %v", err)
}
if want := false; star != want {
t.Errorf("Gists.Starred returned %+v, want %+v", star, want)
}
}
func TestGistsService_IsStarred_invalidID(t *testing.T) {
_, _, err := client.Gists.IsStarred("%")
testURLParseError(t, err)
}
func TestGistsService_Fork(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/gists/1/forks", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "POST")
fmt.Fprint(w, `{"id": "2"}`)
})
gist, _, err := client.Gists.Fork("1")
if err != nil {
t.Errorf("Gists.Fork returned error: %v", err)
}
want := &Gist{ID: String("2")}
if !reflect.DeepEqual(gist, want) {
t.Errorf("Gists.Fork returned %+v, want %+v", gist, want)
}
}
func TestGistsService_ListForks(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/gists/1/forks", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testFormValues(t, r, nil)
fmt.Fprint(w, `
[
{"url": "https://api.github.com/gists/1",
"user": {"id": 1},
"id": "1",
"created_at": "2010-01-01T00:00:00Z",
"updated_at": "2013-01-01T00:00:00Z"
}
]
`)
})
gistForks, _, err := client.Gists.ListForks("1")
if err != nil {
t.Errorf("Gists.ListForks returned error: %v", err)
}
want := []*GistFork{{
URL: String("https://api.github.com/gists/1"),
ID: String("1"),
User: &User{ID: Int(1)},
CreatedAt: &Timestamp{time.Date(2010, 1, 1, 00, 00, 00, 0, time.UTC)},
UpdatedAt: &Timestamp{time.Date(2013, 1, 1, 00, 00, 00, 0, time.UTC)}}}
if !reflect.DeepEqual(gistForks, want) {
t.Errorf("Gists.ListForks returned %+v, want %+v", gistForks, want)
}
}
func TestGistsService_Fork_invalidID(t *testing.T) {
_, _, err := client.Gists.Fork("%")
testURLParseError(t, err)
}

12
vendor/src/github.com/google/go-github/github/git.go

@ -0,0 +1,12 @@
// Copyright 2013 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github
// GitService handles communication with the git data related
// methods of the GitHub API.
//
// GitHub API docs: http://developer.github.com/v3/git/
type GitService service

47
vendor/src/github.com/google/go-github/github/git_blobs.go

@ -0,0 +1,47 @@
// Copyright 2013 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github
import "fmt"
// Blob represents a blob object.
type Blob struct {
Content *string `json:"content,omitempty"`
Encoding *string `json:"encoding,omitempty"`
SHA *string `json:"sha,omitempty"`
Size *int `json:"size,omitempty"`
URL *string `json:"url,omitempty"`
}
// GetBlob fetchs a blob from a repo given a SHA.
//
// GitHub API docs: http://developer.github.com/v3/git/blobs/#get-a-blob
func (s *GitService) GetBlob(owner string, repo string, sha string) (*Blob, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/git/blobs/%v", owner, repo, sha)
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
blob := new(Blob)
resp, err := s.client.Do(req, blob)
return blob, resp, err
}
// CreateBlob creates a blob object.
//
// GitHub API docs: https://developer.github.com/v3/git/blobs/#create-a-blob
func (s *GitService) CreateBlob(owner string, repo string, blob *Blob) (*Blob, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/git/blobs", owner, repo)
req, err := s.client.NewRequest("POST", u, blob)
if err != nil {
return nil, nil, err
}
t := new(Blob)
resp, err := s.client.Do(req, t)
return t, resp, err
}

97
vendor/src/github.com/google/go-github/github/git_blobs_test.go

@ -0,0 +1,97 @@
// Copyright 2014 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github
import (
"encoding/json"
"fmt"
"net/http"
"reflect"
"testing"
)
func TestGitService_GetBlob(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/git/blobs/s", func(w http.ResponseWriter, r *http.Request) {
if m := "GET"; m != r.Method {
t.Errorf("Request method = %v, want %v", r.Method, m)
}
fmt.Fprint(w, `{
"sha": "s",
"content": "blob content"
}`)
})
blob, _, err := client.Git.GetBlob("o", "r", "s")
if err != nil {
t.Errorf("Git.GetBlob returned error: %v", err)
}
want := Blob{
SHA: String("s"),
Content: String("blob content"),
}
if !reflect.DeepEqual(*blob, want) {
t.Errorf("Blob.Get returned %+v, want %+v", *blob, want)
}
}
func TestGitService_GetBlob_invalidOwner(t *testing.T) {
_, _, err := client.Git.GetBlob("%", "%", "%")
testURLParseError(t, err)
}
func TestGitService_CreateBlob(t *testing.T) {
setup()
defer teardown()
input := &Blob{
SHA: String("s"),
Content: String("blob content"),
Encoding: String("utf-8"),
Size: Int(12),
}
mux.HandleFunc("/repos/o/r/git/blobs", func(w http.ResponseWriter, r *http.Request) {
v := new(Blob)
json.NewDecoder(r.Body).Decode(v)
if m := "POST"; m != r.Method {
t.Errorf("Request method = %v, want %v", r.Method, m)
}
want := input
if !reflect.DeepEqual(v, want) {
t.Errorf("Git.CreateBlob request body: %+v, want %+v", v, want)
}
fmt.Fprint(w, `{
"sha": "s",
"content": "blob content",
"encoding": "utf-8",
"size": 12
}`)
})
blob, _, err := client.Git.CreateBlob("o", "r", input)
if err != nil {
t.Errorf("Git.CreateBlob returned error: %v", err)
}
want := input
if !reflect.DeepEqual(*blob, *want) {
t.Errorf("Git.CreateBlob returned %+v, want %+v", *blob, *want)
}
}
func TestGitService_CreateBlob_invalidOwner(t *testing.T) {
_, _, err := client.Git.CreateBlob("%", "%", &Blob{})
testURLParseError(t, err)
}

127
vendor/src/github.com/google/go-github/github/git_commits.go

@ -0,0 +1,127 @@
// Copyright 2013 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github
import (
"fmt"
"time"
)
// SignatureVerification represents GPG signature verification.
type SignatureVerification struct {
Verified *bool `json:"verified,omitempty"`
Reason *string `json:"reason,omitempty"`
Signature *string `json:"signature,omitempty"`
Payload *string `json:"payload,omitempty"`
}
// Commit represents a GitHub commit.
type Commit struct {
SHA *string `json:"sha,omitempty"`
Author *CommitAuthor `json:"author,omitempty"`
Committer *CommitAuthor `json:"committer,omitempty"`
Message *string `json:"message,omitempty"`
Tree *Tree `json:"tree,omitempty"`
Parents []Commit `json:"parents,omitempty"`
Stats *CommitStats `json:"stats,omitempty"`
URL *string `json:"url,omitempty"`
Verification *SignatureVerification `json:"verification,omitempty"`
// CommentCount is the number of GitHub comments on the commit. This
// is only populated for requests that fetch GitHub data like
// Pulls.ListCommits, Repositories.ListCommits, etc.
CommentCount *int `json:"comment_count,omitempty"`
}
func (c Commit) String() string {
return Stringify(c)
}
// CommitAuthor represents the author or committer of a commit. The commit
// author may not correspond to a GitHub User.
type CommitAuthor struct {
Date *time.Time `json:"date,omitempty"`
Name *string `json:"name,omitempty"`
Email *string `json:"email,omitempty"`
// The following fields are only populated by Webhook events.
Login *string `json:"username,omitempty"` // Renamed for go-github consistency.
}
func (c CommitAuthor) String() string {
return Stringify(c)
}
// GetCommit fetchs the Commit object for a given SHA.
//
// GitHub API docs: http://developer.github.com/v3/git/commits/#get-a-commit
func (s *GitService) GetCommit(owner string, repo string, sha string) (*Commit, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/git/commits/%v", owner, repo, sha)
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
// TODO: remove custom Accept header when this API fully launches.
req.Header.Set("Accept", mediaTypeGitSigningPreview)
c := new(Commit)
resp, err := s.client.Do(req, c)
if err != nil {
return nil, resp, err
}
return c, resp, err
}
// createCommit represents the body of a CreateCommit request.
type createCommit struct {
Author *CommitAuthor `json:"author,omitempty"`
Committer *CommitAuthor `json:"committer,omitempty"`
Message *string `json:"message,omitempty"`
Tree *string `json:"tree,omitempty"`
Parents []string `json:"parents,omitempty"`
}
// CreateCommit creates a new commit in a repository.
//
// The commit.Committer is optional and will be filled with the commit.Author
// data if omitted. If the commit.Author is omitted, it will be filled in with
// the authenticated user’s information and the current date.
//
// GitHub API docs: http://developer.github.com/v3/git/commits/#create-a-commit
func (s *GitService) CreateCommit(owner string, repo string, commit *Commit) (*Commit, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/git/commits", owner, repo)
body := &createCommit{}
if commit != nil {
parents := make([]string, len(commit.Parents))
for i, parent := range commit.Parents {
parents[i] = *parent.SHA
}
body = &createCommit{
Author: commit.Author,
Committer: commit.Committer,
Message: commit.Message,
Tree: commit.Tree.SHA,
Parents: parents,
}
}
req, err := s.client.NewRequest("POST", u, body)
if err != nil {
return nil, nil, err
}
c := new(Commit)
resp, err := s.client.Do(req, c)
if err != nil {
return nil, resp, err
}
return c, resp, err
}

83
vendor/src/github.com/google/go-github/github/git_commits_test.go

@ -0,0 +1,83 @@
// Copyright 2013 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github
import (
"encoding/json"
"fmt"
"net/http"
"reflect"
"testing"
)
func TestGitService_GetCommit(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/git/commits/s", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testHeader(t, r, "Accept", mediaTypeGitSigningPreview)
fmt.Fprint(w, `{"sha":"s","message":"m","author":{"name":"n"}}`)
})
commit, _, err := client.Git.GetCommit("o", "r", "s")
if err != nil {
t.Errorf("Git.GetCommit returned error: %v", err)
}
want := &Commit{SHA: String("s"), Message: String("m"), Author: &CommitAuthor{Name: String("n")}}
if !reflect.DeepEqual(commit, want) {
t.Errorf("Git.GetCommit returned %+v, want %+v", commit, want)
}
}
func TestGitService_GetCommit_invalidOwner(t *testing.T) {
_, _, err := client.Git.GetCommit("%", "%", "%")
testURLParseError(t, err)
}
func TestGitService_CreateCommit(t *testing.T) {
setup()
defer teardown()
input := &Commit{
Message: String("m"),
Tree: &Tree{SHA: String("t")},
Parents: []Commit{{SHA: String("p")}},
}
mux.HandleFunc("/repos/o/r/git/commits", func(w http.ResponseWriter, r *http.Request) {
v := new(createCommit)
json.NewDecoder(r.Body).Decode(v)
testMethod(t, r, "POST")
want := &createCommit{
Message: input.Message,
Tree: String("t"),
Parents: []string{"p"},
}
if !reflect.DeepEqual(v, want) {
t.Errorf("Request body = %+v, want %+v", v, want)
}
fmt.Fprint(w, `{"sha":"s"}`)
})
commit, _, err := client.Git.CreateCommit("o", "r", input)
if err != nil {
t.Errorf("Git.CreateCommit returned error: %v", err)
}
want := &Commit{SHA: String("s")}
if !reflect.DeepEqual(commit, want) {
t.Errorf("Git.CreateCommit returned %+v, want %+v", commit, want)
}
}
func TestGitService_CreateCommit_invalidOwner(t *testing.T) {
_, _, err := client.Git.CreateCommit("%", "%", nil)
testURLParseError(t, err)
}

162
vendor/src/github.com/google/go-github/github/git_refs.go

@ -0,0 +1,162 @@
// Copyright 2013 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github
import (
"fmt"
"strings"
)
// Reference represents a GitHub reference.
type Reference struct {
Ref *string `json:"ref"`
URL *string `json:"url"`
Object *GitObject `json:"object"`
}
func (r Reference) String() string {
return Stringify(r)
}
// GitObject represents a Git object.
type GitObject struct {
Type *string `json:"type"`
SHA *string `json:"sha"`
URL *string `json:"url"`
}
func (o GitObject) String() string {
return Stringify(o)
}
// createRefRequest represents the payload for creating a reference.
type createRefRequest struct {
Ref *string `json:"ref"`
SHA *string `json:"sha"`
}
// updateRefRequest represents the payload for updating a reference.
type updateRefRequest struct {
SHA *string `json:"sha"`
Force *bool `json:"force"`
}
// GetRef fetches the Reference object for a given Git ref.
//
// GitHub API docs: http://developer.github.com/v3/git/refs/#get-a-reference
func (s *GitService) GetRef(owner string, repo string, ref string) (*Reference, *Response, error) {
ref = strings.TrimPrefix(ref, "refs/")
u := fmt.Sprintf("repos/%v/%v/git/refs/%v", owner, repo, ref)
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
r := new(Reference)
resp, err := s.client.Do(req, r)
if err != nil {
return nil, resp, err
}
return r, resp, err
}
// ReferenceListOptions specifies optional parameters to the
// GitService.ListRefs method.
type ReferenceListOptions struct {
Type string `url:"-"`
ListOptions
}
// ListRefs lists all refs in a repository.
//
// GitHub API docs: http://developer.github.com/v3/git/refs/#get-all-references
func (s *GitService) ListRefs(owner, repo string, opt *ReferenceListOptions) ([]*Reference, *Response, error) {
var u string
if opt != nil && opt.Type != "" {
u = fmt.Sprintf("repos/%v/%v/git/refs/%v", owner, repo, opt.Type)
} else {
u = fmt.Sprintf("repos/%v/%v/git/refs", owner, repo)
}
u, err := addOptions(u, opt)
if err != nil {
return nil, nil, err
}
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
var rs []*Reference
resp, err := s.client.Do(req, &rs)
if err != nil {
return nil, resp, err
}
return rs, resp, err
}
// CreateRef creates a new ref in a repository.
//
// GitHub API docs: http://developer.github.com/v3/git/refs/#create-a-reference
func (s *GitService) CreateRef(owner string, repo string, ref *Reference) (*Reference, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/git/refs", owner, repo)
req, err := s.client.NewRequest("POST", u, &createRefRequest{
// back-compat with previous behavior that didn't require 'refs/' prefix
Ref: String("refs/" + strings.TrimPrefix(*ref.Ref, "refs/")),
SHA: ref.Object.SHA,
})
if err != nil {
return nil, nil, err
}
r := new(Reference)
resp, err := s.client.Do(req, r)
if err != nil {
return nil, resp, err
}
return r, resp, err
}
// UpdateRef updates an existing ref in a repository.
//
// GitHub API docs: http://developer.github.com/v3/git/refs/#update-a-reference
func (s *GitService) UpdateRef(owner string, repo string, ref *Reference, force bool) (*Reference, *Response, error) {
refPath := strings.TrimPrefix(*ref.Ref, "refs/")
u := fmt.Sprintf("repos/%v/%v/git/refs/%v", owner, repo, refPath)
req, err := s.client.NewRequest("PATCH", u, &updateRefRequest{
SHA: ref.Object.SHA,
Force: &force,
})
if err != nil {
return nil, nil, err
}
r := new(Reference)
resp, err := s.client.Do(req, r)
if err != nil {
return nil, resp, err
}
return r, resp, err
}
// DeleteRef deletes a ref from a repository.
//
// GitHub API docs: http://developer.github.com/v3/git/refs/#delete-a-reference
func (s *GitService) DeleteRef(owner string, repo string, ref string) (*Response, error) {
ref = strings.TrimPrefix(ref, "refs/")
u := fmt.Sprintf("repos/%v/%v/git/refs/%v", owner, repo, ref)
req, err := s.client.NewRequest("DELETE", u, nil)
if err != nil {
return nil, err
}
return s.client.Do(req, nil)
}

280
vendor/src/github.com/google/go-github/github/git_refs_test.go

@ -0,0 +1,280 @@
// Copyright 2013 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github
import (
"encoding/json"
"fmt"
"net/http"
"reflect"
"testing"
)
func TestGitService_GetRef(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/git/refs/heads/b", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
fmt.Fprint(w, `
{
"ref": "refs/heads/b",
"url": "https://api.github.com/repos/o/r/git/refs/heads/b",
"object": {
"type": "commit",
"sha": "aa218f56b14c9653891f9e74264a383fa43fefbd",
"url": "https://api.github.com/repos/o/r/git/commits/aa218f56b14c9653891f9e74264a383fa43fefbd"
}
}`)
})
ref, _, err := client.Git.GetRef("o", "r", "refs/heads/b")
if err != nil {
t.Errorf("Git.GetRef returned error: %v", err)
}
want := &Reference{
Ref: String("refs/heads/b"),
URL: String("https://api.github.com/repos/o/r/git/refs/heads/b"),
Object: &GitObject{
Type: String("commit"),
SHA: String("aa218f56b14c9653891f9e74264a383fa43fefbd"),
URL: String("https://api.github.com/repos/o/r/git/commits/aa218f56b14c9653891f9e74264a383fa43fefbd"),
},
}
if !reflect.DeepEqual(ref, want) {
t.Errorf("Git.GetRef returned %+v, want %+v", ref, want)
}
// without 'refs/' prefix
if _, _, err := client.Git.GetRef("o", "r", "heads/b"); err != nil {
t.Errorf("Git.GetRef returned error: %v", err)
}
}
func TestGitService_ListRefs(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/git/refs", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
fmt.Fprint(w, `
[
{
"ref": "refs/heads/branchA",
"url": "https://api.github.com/repos/o/r/git/refs/heads/branchA",
"object": {
"type": "commit",
"sha": "aa218f56b14c9653891f9e74264a383fa43fefbd",
"url": "https://api.github.com/repos/o/r/git/commits/aa218f56b14c9653891f9e74264a383fa43fefbd"
}
},
{
"ref": "refs/heads/branchB",
"url": "https://api.github.com/repos/o/r/git/refs/heads/branchB",
"object": {
"type": "commit",
"sha": "aa218f56b14c9653891f9e74264a383fa43fefbd",
"url": "https://api.github.com/repos/o/r/git/commits/aa218f56b14c9653891f9e74264a383fa43fefbd"
}
}
]`)
})
refs, _, err := client.Git.ListRefs("o", "r", nil)
if err != nil {
t.Errorf("Git.ListRefs returned error: %v", err)
}
want := []*Reference{
{
Ref: String("refs/heads/branchA"),
URL: String("https://api.github.com/repos/o/r/git/refs/heads/branchA"),
Object: &GitObject{
Type: String("commit"),
SHA: String("aa218f56b14c9653891f9e74264a383fa43fefbd"),
URL: String("https://api.github.com/repos/o/r/git/commits/aa218f56b14c9653891f9e74264a383fa43fefbd"),
},
},
{
Ref: String("refs/heads/branchB"),
URL: String("https://api.github.com/repos/o/r/git/refs/heads/branchB"),
Object: &GitObject{
Type: String("commit"),
SHA: String("aa218f56b14c9653891f9e74264a383fa43fefbd"),
URL: String("https://api.github.com/repos/o/r/git/commits/aa218f56b14c9653891f9e74264a383fa43fefbd"),
},
},
}
if !reflect.DeepEqual(refs, want) {
t.Errorf("Git.ListRefs returned %+v, want %+v", refs, want)
}
}
func TestGitService_ListRefs_options(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/git/refs/t", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testFormValues(t, r, values{"page": "2"})
fmt.Fprint(w, `[{"ref": "r"}]`)
})
opt := &ReferenceListOptions{Type: "t", ListOptions: ListOptions{Page: 2}}
refs, _, err := client.Git.ListRefs("o", "r", opt)
if err != nil {
t.Errorf("Git.ListRefs returned error: %v", err)
}
want := []*Reference{{Ref: String("r")}}
if !reflect.DeepEqual(refs, want) {
t.Errorf("Git.ListRefs returned %+v, want %+v", refs, want)
}
}
func TestGitService_CreateRef(t *testing.T) {
setup()
defer teardown()
args := &createRefRequest{
Ref: String("refs/heads/b"),
SHA: String("aa218f56b14c9653891f9e74264a383fa43fefbd"),
}
mux.HandleFunc("/repos/o/r/git/refs", func(w http.ResponseWriter, r *http.Request) {
v := new(createRefRequest)
json.NewDecoder(r.Body).Decode(v)
testMethod(t, r, "POST")
if !reflect.DeepEqual(v, args) {
t.Errorf("Request body = %+v, want %+v", v, args)
}
fmt.Fprint(w, `
{
"ref": "refs/heads/b",
"url": "https://api.github.com/repos/o/r/git/refs/heads/b",
"object": {
"type": "commit",
"sha": "aa218f56b14c9653891f9e74264a383fa43fefbd",
"url": "https://api.github.com/repos/o/r/git/commits/aa218f56b14c9653891f9e74264a383fa43fefbd"
}
}`)
})
ref, _, err := client.Git.CreateRef("o", "r", &Reference{
Ref: String("refs/heads/b"),
Object: &GitObject{
SHA: String("aa218f56b14c9653891f9e74264a383fa43fefbd"),
},
})
if err != nil {
t.Errorf("Git.CreateRef returned error: %v", err)
}
want := &Reference{
Ref: String("refs/heads/b"),
URL: String("https://api.github.com/repos/o/r/git/refs/heads/b"),
Object: &GitObject{
Type: String("commit"),
SHA: String("aa218f56b14c9653891f9e74264a383fa43fefbd"),
URL: String("https://api.github.com/repos/o/r/git/commits/aa218f56b14c9653891f9e74264a383fa43fefbd"),
},
}
if !reflect.DeepEqual(ref, want) {
t.Errorf("Git.CreateRef returned %+v, want %+v", ref, want)
}
// without 'refs/' prefix
_, _, err = client.Git.CreateRef("o", "r", &Reference{
Ref: String("heads/b"),
Object: &GitObject{
SHA: String("aa218f56b14c9653891f9e74264a383fa43fefbd"),
},
})
if err != nil {
t.Errorf("Git.CreateRef returned error: %v", err)
}
}
func TestGitService_UpdateRef(t *testing.T) {
setup()
defer teardown()
args := &updateRefRequest{
SHA: String("aa218f56b14c9653891f9e74264a383fa43fefbd"),
Force: Bool(true),
}
mux.HandleFunc("/repos/o/r/git/refs/heads/b", func(w http.ResponseWriter, r *http.Request) {
v := new(updateRefRequest)
json.NewDecoder(r.Body).Decode(v)
testMethod(t, r, "PATCH")
if !reflect.DeepEqual(v, args) {
t.Errorf("Request body = %+v, want %+v", v, args)
}
fmt.Fprint(w, `
{
"ref": "refs/heads/b",
"url": "https://api.github.com/repos/o/r/git/refs/heads/b",
"object": {
"type": "commit",
"sha": "aa218f56b14c9653891f9e74264a383fa43fefbd",
"url": "https://api.github.com/repos/o/r/git/commits/aa218f56b14c9653891f9e74264a383fa43fefbd"
}
}`)
})
ref, _, err := client.Git.UpdateRef("o", "r", &Reference{
Ref: String("refs/heads/b"),
Object: &GitObject{SHA: String("aa218f56b14c9653891f9e74264a383fa43fefbd")},
}, true)
if err != nil {
t.Errorf("Git.UpdateRef returned error: %v", err)
}
want := &Reference{
Ref: String("refs/heads/b"),
URL: String("https://api.github.com/repos/o/r/git/refs/heads/b"),
Object: &GitObject{
Type: String("commit"),
SHA: String("aa218f56b14c9653891f9e74264a383fa43fefbd"),
URL: String("https://api.github.com/repos/o/r/git/commits/aa218f56b14c9653891f9e74264a383fa43fefbd"),
},
}
if !reflect.DeepEqual(ref, want) {
t.Errorf("Git.UpdateRef returned %+v, want %+v", ref, want)
}
// without 'refs/' prefix
_, _, err = client.Git.UpdateRef("o", "r", &Reference{
Ref: String("heads/b"),
Object: &GitObject{SHA: String("aa218f56b14c9653891f9e74264a383fa43fefbd")},
}, true)
if err != nil {
t.Errorf("Git.UpdateRef returned error: %v", err)
}
}
func TestGitService_DeleteRef(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/git/refs/heads/b", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "DELETE")
})
_, err := client.Git.DeleteRef("o", "r", "refs/heads/b")
if err != nil {
t.Errorf("Git.DeleteRef returned error: %v", err)
}
// without 'refs/' prefix
if _, err := client.Git.DeleteRef("o", "r", "heads/b"); err != nil {
t.Errorf("Git.DeleteRef returned error: %v", err)
}
}

77
vendor/src/github.com/google/go-github/github/git_tags.go

@ -0,0 +1,77 @@
// Copyright 2013 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github
import (
"fmt"
)
// Tag represents a tag object.
type Tag struct {
Tag *string `json:"tag,omitempty"`
SHA *string `json:"sha,omitempty"`
URL *string `json:"url,omitempty"`
Message *string `json:"message,omitempty"`
Tagger *CommitAuthor `json:"tagger,omitempty"`
Object *GitObject `json:"object,omitempty"`
Verification *SignatureVerification `json:"verification,omitempty"`
}
// createTagRequest represents the body of a CreateTag request. This is mostly
// identical to Tag with the exception that the object SHA and Type are
// top-level fields, rather than being nested inside a JSON object.
type createTagRequest struct {
Tag *string `json:"tag,omitempty"`
Message *string `json:"message,omitempty"`
Object *string `json:"object,omitempty"`
Type *string `json:"type,omitempty"`
Tagger *CommitAuthor `json:"tagger,omitempty"`
}
// GetTag fetchs a tag from a repo given a SHA.
//
// GitHub API docs: http://developer.github.com/v3/git/tags/#get-a-tag
func (s *GitService) GetTag(owner string, repo string, sha string) (*Tag, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/git/tags/%v", owner, repo, sha)
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
// TODO: remove custom Accept header when this API fully launches.
req.Header.Set("Accept", mediaTypeGitSigningPreview)
tag := new(Tag)
resp, err := s.client.Do(req, tag)
return tag, resp, err
}
// CreateTag creates a tag object.
//
// GitHub API docs: http://developer.github.com/v3/git/tags/#create-a-tag-object
func (s *GitService) CreateTag(owner string, repo string, tag *Tag) (*Tag, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/git/tags", owner, repo)
// convert Tag into a createTagRequest
tagRequest := &createTagRequest{
Tag: tag.Tag,
Message: tag.Message,
Tagger: tag.Tagger,
}
if tag.Object != nil {
tagRequest.Object = tag.Object.SHA
tagRequest.Type = tag.Object.Type
}
req, err := s.client.NewRequest("POST", u, tagRequest)
if err != nil {
return nil, nil, err
}
t := new(Tag)
resp, err := s.client.Do(req, t)
return t, resp, err
}

68
vendor/src/github.com/google/go-github/github/git_tags_test.go

@ -0,0 +1,68 @@
// Copyright 2013 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github
import (
"encoding/json"
"fmt"
"net/http"
"reflect"
"testing"
)
func TestGitService_GetTag(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/git/tags/s", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testHeader(t, r, "Accept", mediaTypeGitSigningPreview)
fmt.Fprint(w, `{"tag": "t"}`)
})
tag, _, err := client.Git.GetTag("o", "r", "s")
if err != nil {
t.Errorf("Git.GetTag returned error: %v", err)
}
want := &Tag{Tag: String("t")}
if !reflect.DeepEqual(tag, want) {
t.Errorf("Git.GetTag returned %+v, want %+v", tag, want)
}
}
func TestGitService_CreateTag(t *testing.T) {
setup()
defer teardown()
input := &createTagRequest{Tag: String("t"), Object: String("s")}
mux.HandleFunc("/repos/o/r/git/tags", func(w http.ResponseWriter, r *http.Request) {
v := new(createTagRequest)
json.NewDecoder(r.Body).Decode(v)
testMethod(t, r, "POST")
if !reflect.DeepEqual(v, input) {
t.Errorf("Request body = %+v, want %+v", v, input)
}
fmt.Fprint(w, `{"tag": "t"}`)
})
tag, _, err := client.Git.CreateTag("o", "r", &Tag{
Tag: input.Tag,
Object: &GitObject{SHA: input.Object},
})
if err != nil {
t.Errorf("Git.CreateTag returned error: %v", err)
}
want := &Tag{Tag: String("t")}
if !reflect.DeepEqual(tag, want) {
t.Errorf("Git.GetTag returned %+v, want %+v", tag, want)
}
}

89
vendor/src/github.com/google/go-github/github/git_trees.go

@ -0,0 +1,89 @@
// Copyright 2013 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github
import "fmt"
// Tree represents a GitHub tree.
type Tree struct {
SHA *string `json:"sha,omitempty"`
Entries []TreeEntry `json:"tree,omitempty"`
}
func (t Tree) String() string {
return Stringify(t)
}
// TreeEntry represents the contents of a tree structure. TreeEntry can
// represent either a blob, a commit (in the case of a submodule), or another
// tree.
type TreeEntry struct {
SHA *string `json:"sha,omitempty"`
Path *string `json:"path,omitempty"`
Mode *string `json:"mode,omitempty"`
Type *string `json:"type,omitempty"`
Size *int `json:"size,omitempty"`
Content *string `json:"content,omitempty"`
}
func (t TreeEntry) String() string {
return Stringify(t)
}
// GetTree fetches the Tree object for a given sha hash from a repository.
//
// GitHub API docs: http://developer.github.com/v3/git/trees/#get-a-tree
func (s *GitService) GetTree(owner string, repo string, sha string, recursive bool) (*Tree, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/git/trees/%v", owner, repo, sha)
if recursive {
u += "?recursive=1"
}
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
t := new(Tree)
resp, err := s.client.Do(req, t)
if err != nil {
return nil, resp, err
}
return t, resp, err
}
// createTree represents the body of a CreateTree request.
type createTree struct {
BaseTree string `json:"base_tree,omitempty"`
Entries []TreeEntry `json:"tree"`
}
// CreateTree creates a new tree in a repository. If both a tree and a nested
// path modifying that tree are specified, it will overwrite the contents of
// that tree with the new path contents and write a new tree out.
//
// GitHub API docs: http://developer.github.com/v3/git/trees/#create-a-tree
func (s *GitService) CreateTree(owner string, repo string, baseTree string, entries []TreeEntry) (*Tree, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/git/trees", owner, repo)
body := &createTree{
BaseTree: baseTree,
Entries: entries,
}
req, err := s.client.NewRequest("POST", u, body)
if err != nil {
return nil, nil, err
}
t := new(Tree)
resp, err := s.client.Do(req, t)
if err != nil {
return nil, resp, err
}
return t, resp, err
}

189
vendor/src/github.com/google/go-github/github/git_trees_test.go

@ -0,0 +1,189 @@
// Copyright 2013 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github
import (
"encoding/json"
"fmt"
"net/http"
"reflect"
"testing"
)
func TestGitService_GetTree(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/git/trees/s", func(w http.ResponseWriter, r *http.Request) {
if m := "GET"; m != r.Method {
t.Errorf("Request method = %v, want %v", r.Method, m)
}
fmt.Fprint(w, `{
"sha": "s",
"tree": [ { "type": "blob" } ]
}`)
})
tree, _, err := client.Git.GetTree("o", "r", "s", true)
if err != nil {
t.Errorf("Git.GetTree returned error: %v", err)
}
want := Tree{
SHA: String("s"),
Entries: []TreeEntry{
{
Type: String("blob"),
},
},
}
if !reflect.DeepEqual(*tree, want) {
t.Errorf("Tree.Get returned %+v, want %+v", *tree, want)
}
}
func TestGitService_GetTree_invalidOwner(t *testing.T) {
_, _, err := client.Git.GetTree("%", "%", "%", false)
testURLParseError(t, err)
}
func TestGitService_CreateTree(t *testing.T) {
setup()
defer teardown()
input := []TreeEntry{
{
Path: String("file.rb"),
Mode: String("100644"),
Type: String("blob"),
SHA: String("7c258a9869f33c1e1e1f74fbb32f07c86cb5a75b"),
},
}
mux.HandleFunc("/repos/o/r/git/trees", func(w http.ResponseWriter, r *http.Request) {
v := new(createTree)
json.NewDecoder(r.Body).Decode(v)
if m := "POST"; m != r.Method {
t.Errorf("Request method = %v, want %v", r.Method, m)
}
want := &createTree{
BaseTree: "b",
Entries: input,
}
if !reflect.DeepEqual(v, want) {
t.Errorf("Git.CreateTree request body: %+v, want %+v", v, want)
}
fmt.Fprint(w, `{
"sha": "cd8274d15fa3ae2ab983129fb037999f264ba9a7",
"tree": [
{
"path": "file.rb",
"mode": "100644",
"type": "blob",
"size": 132,
"sha": "7c258a9869f33c1e1e1f74fbb32f07c86cb5a75b"
}
]
}`)
})
tree, _, err := client.Git.CreateTree("o", "r", "b", input)
if err != nil {
t.Errorf("Git.CreateTree returned error: %v", err)
}
want := Tree{
String("cd8274d15fa3ae2ab983129fb037999f264ba9a7"),
[]TreeEntry{
{
Path: String("file.rb"),
Mode: String("100644"),
Type: String("blob"),
Size: Int(132),
SHA: String("7c258a9869f33c1e1e1f74fbb32f07c86cb5a75b"),
},
},
}
if !reflect.DeepEqual(*tree, want) {
t.Errorf("Git.CreateTree returned %+v, want %+v", *tree, want)
}
}
func TestGitService_CreateTree_Content(t *testing.T) {
setup()
defer teardown()
input := []TreeEntry{
{
Path: String("content.md"),
Mode: String("100644"),
Content: String("file content"),
},
}
mux.HandleFunc("/repos/o/r/git/trees", func(w http.ResponseWriter, r *http.Request) {
v := new(createTree)
json.NewDecoder(r.Body).Decode(v)
if m := "POST"; m != r.Method {
t.Errorf("Request method = %v, want %v", r.Method, m)
}
want := &createTree{
BaseTree: "b",
Entries: input,
}
if !reflect.DeepEqual(v, want) {
t.Errorf("Git.CreateTree request body: %+v, want %+v", v, want)
}
fmt.Fprint(w, `{
"sha": "5c6780ad2c68743383b740fd1dab6f6a33202b11",
"url": "https://api.github.com/repos/o/r/git/trees/5c6780ad2c68743383b740fd1dab6f6a33202b11",
"tree": [
{
"mode": "100644",
"type": "blob",
"sha": "aad8feacf6f8063150476a7b2bd9770f2794c08b",
"path": "content.md",
"size": 12,
"url": "https://api.github.com/repos/o/r/git/blobs/aad8feacf6f8063150476a7b2bd9770f2794c08b"
}
]
}`)
})
tree, _, err := client.Git.CreateTree("o", "r", "b", input)
if err != nil {
t.Errorf("Git.CreateTree returned error: %v", err)
}
want := Tree{
String("5c6780ad2c68743383b740fd1dab6f6a33202b11"),
[]TreeEntry{
{
Path: String("content.md"),
Mode: String("100644"),
Type: String("blob"),
Size: Int(12),
SHA: String("aad8feacf6f8063150476a7b2bd9770f2794c08b"),
},
},
}
if !reflect.DeepEqual(*tree, want) {
t.Errorf("Git.CreateTree returned %+v, want %+v", *tree, want)
}
}
func TestGitService_CreateTree_invalidOwner(t *testing.T) {
_, _, err := client.Git.CreateTree("%", "%", "", nil)
testURLParseError(t, err)
}

807
vendor/src/github.com/google/go-github/github/github.go

@ -0,0 +1,807 @@
// Copyright 2013 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"io"
"io/ioutil"
"net/http"
"net/url"
"reflect"
"strconv"
"strings"
"sync"
"time"
"github.com/google/go-querystring/query"
)
const (
// StatusUnprocessableEntity is the status code returned when sending a request with invalid fields.
StatusUnprocessableEntity = 422
)
const (
libraryVersion = "2"
defaultBaseURL = "https://api.github.com/"
uploadBaseURL = "https://uploads.github.com/"
userAgent = "go-github/" + libraryVersion
headerRateLimit = "X-RateLimit-Limit"
headerRateRemaining = "X-RateLimit-Remaining"
headerRateReset = "X-RateLimit-Reset"
headerOTP = "X-GitHub-OTP"
mediaTypeV3 = "application/vnd.github.v3+json"
defaultMediaType = "application/octet-stream"
mediaTypeV3SHA = "application/vnd.github.v3.sha"
mediaTypeOrgPermissionRepo = "application/vnd.github.v3.repository+json"
// Media Type values to access preview APIs
// https://developer.github.com/changes/2015-03-09-licenses-api/
mediaTypeLicensesPreview = "application/vnd.github.drax-preview+json"
// https://developer.github.com/changes/2014-12-09-new-attributes-for-stars-api/
mediaTypeStarringPreview = "application/vnd.github.v3.star+json"
// https://developer.github.com/changes/2015-11-11-protected-branches-api/
mediaTypeProtectedBranchesPreview = "application/vnd.github.loki-preview+json"
// https://help.github.com/enterprise/2.4/admin/guides/migrations/exporting-the-github-com-organization-s-repositories/
mediaTypeMigrationsPreview = "application/vnd.github.wyandotte-preview+json"
// https://developer.github.com/changes/2016-04-06-deployment-and-deployment-status-enhancements/
mediaTypeDeploymentStatusPreview = "application/vnd.github.ant-man-preview+json"
// https://developer.github.com/changes/2016-02-19-source-import-preview-api/
mediaTypeImportPreview = "application/vnd.github.barred-rock-preview"
// https://developer.github.com/changes/2016-05-12-reactions-api-preview/
mediaTypeReactionsPreview = "application/vnd.github.squirrel-girl-preview"
// https://developer.github.com/changes/2016-04-01-squash-api-preview/
mediaTypeSquashPreview = "application/vnd.github.polaris-preview+json"
// https://developer.github.com/changes/2016-04-04-git-signing-api-preview/
mediaTypeGitSigningPreview = "application/vnd.github.cryptographer-preview+json"
// https://developer.github.com/changes/2016-05-23-timeline-preview-api/
mediaTypeTimelinePreview = "application/vnd.github.mockingbird-preview+json"
// https://developer.github.com/changes/2016-06-14-repository-invitations/
mediaTypeRepositoryInvitationsPreview = "application/vnd.github.swamp-thing-preview+json"
// https://developer.github.com/changes/2016-04-21-oauth-authorizations-grants-api-preview/
mediaTypeOAuthGrantAuthorizationsPreview = "application/vnd.github.damage-preview+json"
// https://developer.github.com/changes/2016-07-06-github-pages-preiew-api/
mediaTypePagesPreview = "application/vnd.github.mister-fantastic-preview+json"
)
// A Client manages communication with the GitHub API.
type Client struct {
clientMu sync.Mutex // clientMu protects the client during calls that modify the CheckRedirect func.
client *http.Client // HTTP client used to communicate with the API.
// Base URL for API requests. Defaults to the public GitHub API, but can be
// set to a domain endpoint to use with GitHub Enterprise. BaseURL should
// always be specified with a trailing slash.
BaseURL *url.URL
// Base URL for uploading files.
UploadURL *url.URL
// User agent used when communicating with the GitHub API.
UserAgent string
rateMu sync.Mutex
rateLimits [categories]Rate // Rate limits for the client as determined by the most recent API calls.
mostRecent rateLimitCategory
common service // Reuse a single struct instead of allocating one for each service on the heap.
// Services used for talking to different parts of the GitHub API.
Activity *ActivityService
Authorizations *AuthorizationsService
Gists *GistsService
Git *GitService
Gitignores *GitignoresService
Issues *IssuesService
Organizations *OrganizationsService
PullRequests *PullRequestsService
Repositories *RepositoriesService
Search *SearchService
Users *UsersService
Licenses *LicensesService
Migrations *MigrationService
Reactions *ReactionsService
}
type service struct {
client *Client
}
// ListOptions specifies the optional parameters to various List methods that
// support pagination.
type ListOptions struct {
// For paginated result sets, page of results to retrieve.
Page int `url:"page,omitempty"`
// For paginated result sets, the number of results to include per page.
PerPage int `url:"per_page,omitempty"`
}
// UploadOptions specifies the parameters to methods that support uploads.
type UploadOptions struct {
Name string `url:"name,omitempty"`
}
// addOptions adds the parameters in opt as URL query parameters to s. opt
// must be a struct whose fields may contain "url" tags.
func addOptions(s string, opt interface{}) (string, error) {
v := reflect.ValueOf(opt)
if v.Kind() == reflect.Ptr && v.IsNil() {
return s, nil
}
u, err := url.Parse(s)
if err != nil {
return s, err
}
qs, err := query.Values(opt)
if err != nil {
return s, err
}
u.RawQuery = qs.Encode()
return u.String(), nil
}
// NewClient returns a new GitHub API client. If a nil httpClient is
// provided, http.DefaultClient will be used. To use API methods which require
// authentication, provide an http.Client that will perform the authentication
// for you (such as that provided by the golang.org/x/oauth2 library).
func NewClient(httpClient *http.Client) *Client {
if httpClient == nil {
httpClient = http.DefaultClient
}
baseURL, _ := url.Parse(defaultBaseURL)
uploadURL, _ := url.Parse(uploadBaseURL)
c := &Client{client: httpClient, BaseURL: baseURL, UserAgent: userAgent, UploadURL: uploadURL}
c.common.client = c
c.Activity = (*ActivityService)(&c.common)
c.Authorizations = (*AuthorizationsService)(&c.common)
c.Gists = (*GistsService)(&c.common)
c.Git = (*GitService)(&c.common)
c.Gitignores = (*GitignoresService)(&c.common)
c.Issues = (*IssuesService)(&c.common)
c.Licenses = (*LicensesService)(&c.common)
c.Migrations = (*MigrationService)(&c.common)
c.Organizations = (*OrganizationsService)(&c.common)
c.PullRequests = (*PullRequestsService)(&c.common)
c.Reactions = (*ReactionsService)(&c.common)
c.Repositories = (*RepositoriesService)(&c.common)
c.Search = (*SearchService)(&c.common)
c.Users = (*UsersService)(&c.common)
return c
}
// NewRequest creates an API request. A relative URL can be provided in urlStr,
// in which case it is resolved relative to the BaseURL of the Client.
// Relative URLs should always be specified without a preceding slash. If
// specified, the value pointed to by body is JSON encoded and included as the
// request body.
func (c *Client) NewRequest(method, urlStr string, body interface{}) (*http.Request, error) {
rel, err := url.Parse(urlStr)
if err != nil {
return nil, err
}
u := c.BaseURL.ResolveReference(rel)
var buf io.ReadWriter
if body != nil {
buf = new(bytes.Buffer)
err := json.NewEncoder(buf).Encode(body)
if err != nil {
return nil, err
}
}
req, err := http.NewRequest(method, u.String(), buf)
if err != nil {
return nil, err
}
if body != nil {
req.Header.Set("Content-Type", "application/json")
}
req.Header.Set("Accept", mediaTypeV3)
if c.UserAgent != "" {
req.Header.Set("User-Agent", c.UserAgent)
}
return req, nil
}
// NewUploadRequest creates an upload request. A relative URL can be provided in
// urlStr, in which case it is resolved relative to the UploadURL of the Client.
// Relative URLs should always be specified without a preceding slash.
func (c *Client) NewUploadRequest(urlStr string, reader io.Reader, size int64, mediaType string) (*http.Request, error) {
rel, err := url.Parse(urlStr)
if err != nil {
return nil, err
}
u := c.UploadURL.ResolveReference(rel)
req, err := http.NewRequest("POST", u.String(), reader)
if err != nil {
return nil, err
}
req.ContentLength = size
if mediaType == "" {
mediaType = defaultMediaType
}
req.Header.Set("Content-Type", mediaType)
req.Header.Set("Accept", mediaTypeV3)
req.Header.Set("User-Agent", c.UserAgent)
return req, nil
}
// Response is a GitHub API response. This wraps the standard http.Response
// returned from GitHub and provides convenient access to things like
// pagination links.
type Response struct {
*http.Response
// These fields provide the page values for paginating through a set of
// results. Any or all of these may be set to the zero value for
// responses that are not part of a paginated set, or for which there
// are no additional pages.
NextPage int
PrevPage int
FirstPage int
LastPage int
Rate
}
// newResponse creates a new Response for the provided http.Response.
func newResponse(r *http.Response) *Response {
response := &Response{Response: r}
response.populatePageValues()
response.Rate = parseRate(r)
return response
}
// populatePageValues parses the HTTP Link response headers and populates the
// various pagination link values in the Response.
func (r *Response) populatePageValues() {
if links, ok := r.Response.Header["Link"]; ok && len(links) > 0 {
for _, link := range strings.Split(links[0], ",") {
segments := strings.Split(strings.TrimSpace(link), ";")
// link must at least have href and rel
if len(segments) < 2 {
continue
}
// ensure href is properly formatted
if !strings.HasPrefix(segments[0], "<") || !strings.HasSuffix(segments[0], ">") {
continue
}
// try to pull out page parameter
url, err := url.Parse(segments[0][1 : len(segments[0])-1])
if err != nil {
continue
}
page := url.Query().Get("page")
if page == "" {
continue
}
for _, segment := range segments[1:] {
switch strings.TrimSpace(segment) {
case `rel="next"`:
r.NextPage, _ = strconv.Atoi(page)
case `rel="prev"`:
r.PrevPage, _ = strconv.Atoi(page)
case `rel="first"`:
r.FirstPage, _ = strconv.Atoi(page)
case `rel="last"`:
r.LastPage, _ = strconv.Atoi(page)
}
}
}
}
}
// parseRate parses the rate related headers.
func parseRate(r *http.Response) Rate {
var rate Rate
if limit := r.Header.Get(headerRateLimit); limit != "" {
rate.Limit, _ = strconv.Atoi(limit)
}
if remaining := r.Header.Get(headerRateRemaining); remaining != "" {
rate.Remaining, _ = strconv.Atoi(remaining)
}
if reset := r.Header.Get(headerRateReset); reset != "" {
if v, _ := strconv.ParseInt(reset, 10, 64); v != 0 {
rate.Reset = Timestamp{time.Unix(v, 0)}
}
}
return rate
}
// Rate specifies the current rate limit for the client as determined by the
// most recent API call. If the client is used in a multi-user application,
// this rate may not always be up-to-date.
//
// Deprecated: Use the Response.Rate returned from most recent API call instead.
// Call RateLimits() to check the current rate.
func (c *Client) Rate() Rate {
c.rateMu.Lock()
rate := c.rateLimits[c.mostRecent]
c.rateMu.Unlock()
return rate
}
// Do sends an API request and returns the API response. The API response is
// JSON decoded and stored in the value pointed to by v, or returned as an
// error if an API error has occurred. If v implements the io.Writer
// interface, the raw response body will be written to v, without attempting to
// first decode it. If rate limit is exceeded and reset time is in the future,
// Do returns *RateLimitError immediately without making a network API call.
func (c *Client) Do(req *http.Request, v interface{}) (*Response, error) {
rateLimitCategory := category(req.URL.Path)
// If we've hit rate limit, don't make further requests before Reset time.
if err := c.checkRateLimitBeforeDo(req, rateLimitCategory); err != nil {
return nil, err
}
resp, err := c.client.Do(req)
if err != nil {
return nil, err
}
defer func() {
// Drain up to 512 bytes and close the body to let the Transport reuse the connection
io.CopyN(ioutil.Discard, resp.Body, 512)
resp.Body.Close()
}()
response := newResponse(resp)
c.rateMu.Lock()
c.rateLimits[rateLimitCategory] = response.Rate
c.mostRecent = rateLimitCategory
c.rateMu.Unlock()
err = CheckResponse(resp)
if err != nil {
// even though there was an error, we still return the response
// in case the caller wants to inspect it further
return response, err
}
if v != nil {
if w, ok := v.(io.Writer); ok {
io.Copy(w, resp.Body)
} else {
err = json.NewDecoder(resp.Body).Decode(v)
if err == io.EOF {
err = nil // ignore EOF errors caused by empty response body
}
}
}
return response, err
}
// checkRateLimitBeforeDo does not make any network calls, but uses existing knowledge from
// current client state in order to quickly check if *RateLimitError can be immediately returned
// from Client.Do, and if so, returns it so that Client.Do can skip making a network API call unneccessarily.
// Otherwise it returns nil, and Client.Do should proceed normally.
func (c *Client) checkRateLimitBeforeDo(req *http.Request, rateLimitCategory rateLimitCategory) error {
c.rateMu.Lock()
rate := c.rateLimits[rateLimitCategory]
c.rateMu.Unlock()
if !rate.Reset.Time.IsZero() && rate.Remaining == 0 && time.Now().Before(rate.Reset.Time) {
// Create a fake response.
resp := &http.Response{
Status: http.StatusText(http.StatusForbidden),
StatusCode: http.StatusForbidden,
Request: req,
Header: make(http.Header),
Body: ioutil.NopCloser(strings.NewReader("")),
}
return &RateLimitError{
Rate: rate,
Response: resp,
Message: fmt.Sprintf("API rate limit of %v still exceeded until %v, not making remote request.", rate.Limit, rate.Reset.Time),
}
}
return nil
}
/*
An ErrorResponse reports one or more errors caused by an API request.
GitHub API docs: http://developer.github.com/v3/#client-errors
*/
type ErrorResponse struct {
Response *http.Response // HTTP response that caused this error
Message string `json:"message"` // error message
Errors []Error `json:"errors"` // more detail on individual errors
// Block is only populated on certain types of errors such as code 451.
// See https://developer.github.com/changes/2016-03-17-the-451-status-code-is-now-supported/
// for more information.
Block *struct {
Reason string `json:"reason,omitempty"`
CreatedAt *Timestamp `json:"created_at,omitempty"`
} `json:"block,omitempty"`
// Most errors will also include a documentation_url field pointing
// to some content that might help you resolve the error, see
// https://developer.github.com/v3/#client-errors
DocumentationURL string `json:"documentation_url,omitempty"`
}
func (r *ErrorResponse) Error() string {
return fmt.Sprintf("%v %v: %d %v %+v",
r.Response.Request.Method, sanitizeURL(r.Response.Request.URL),
r.Response.StatusCode, r.Message, r.Errors)
}
// TwoFactorAuthError occurs when using HTTP Basic Authentication for a user
// that has two-factor authentication enabled. The request can be reattempted
// by providing a one-time password in the request.
type TwoFactorAuthError ErrorResponse
func (r *TwoFactorAuthError) Error() string { return (*ErrorResponse)(r).Error() }
// RateLimitError occurs when GitHub returns 403 Forbidden response with a rate limit
// remaining value of 0, and error message starts with "API rate limit exceeded for ".
type RateLimitError struct {
Rate Rate // Rate specifies last known rate limit for the client
Response *http.Response // HTTP response that caused this error
Message string `json:"message"` // error message
}
func (r *RateLimitError) Error() string {
return fmt.Sprintf("%v %v: %d %v; rate reset in %v",
r.Response.Request.Method, sanitizeURL(r.Response.Request.URL),
r.Response.StatusCode, r.Message, r.Rate.Reset.Time.Sub(time.Now()))
}
// sanitizeURL redacts the client_secret parameter from the URL which may be
// exposed to the user, specifically in the ErrorResponse error message.
func sanitizeURL(uri *url.URL) *url.URL {
if uri == nil {
return nil
}
params := uri.Query()
if len(params.Get("client_secret")) > 0 {
params.Set("client_secret", "REDACTED")
uri.RawQuery = params.Encode()
}
return uri
}
/*
An Error reports more details on an individual error in an ErrorResponse.
These are the possible validation error codes:
missing:
resource does not exist
missing_field:
a required field on a resource has not been set
invalid:
the formatting of a field is invalid
already_exists:
another resource has the same valid as this field
custom:
some resources return this (e.g. github.User.CreateKey()), additional
information is set in the Message field of the Error
GitHub API docs: http://developer.github.com/v3/#client-errors
*/
type Error struct {
Resource string `json:"resource"` // resource on which the error occurred
Field string `json:"field"` // field on which the error occurred
Code string `json:"code"` // validation error code
Message string `json:"message"` // Message describing the error. Errors with Code == "custom" will always have this set.
}
func (e *Error) Error() string {
return fmt.Sprintf("%v error caused by %v field on %v resource",
e.Code, e.Field, e.Resource)
}
// CheckResponse checks the API response for errors, and returns them if
// present. A response is considered an error if it has a status code outside
// the 200 range. API error responses are expected to have either no response
// body, or a JSON response body that maps to ErrorResponse. Any other
// response body will be silently ignored.
//
// The error type will be *RateLimitError for rate limit exceeded errors,
// and *TwoFactorAuthError for two-factor authentication errors.
func CheckResponse(r *http.Response) error {
if c := r.StatusCode; 200 <= c && c <= 299 {
return nil
}
errorResponse := &ErrorResponse{Response: r}
data, err := ioutil.ReadAll(r.Body)
if err == nil && data != nil {
json.Unmarshal(data, errorResponse)
}
switch {
case r.StatusCode == http.StatusUnauthorized && strings.HasPrefix(r.Header.Get(headerOTP), "required"):
return (*TwoFactorAuthError)(errorResponse)
case r.StatusCode == http.StatusForbidden && r.Header.Get(headerRateRemaining) == "0" && strings.HasPrefix(errorResponse.Message, "API rate limit exceeded for "):
return &RateLimitError{
Rate: parseRate(r),
Response: errorResponse.Response,
Message: errorResponse.Message,
}
default:
return errorResponse
}
}
// parseBoolResponse determines the boolean result from a GitHub API response.
// Several GitHub API methods return boolean responses indicated by the HTTP
// status code in the response (true indicated by a 204, false indicated by a
// 404). This helper function will determine that result and hide the 404
// error if present. Any other error will be returned through as-is.
func parseBoolResponse(err error) (bool, error) {
if err == nil {
return true, nil
}
if err, ok := err.(*ErrorResponse); ok && err.Response.StatusCode == http.StatusNotFound {
// Simply false. In this one case, we do not pass the error through.
return false, nil
}
// some other real error occurred
return false, err
}
// Rate represents the rate limit for the current client.
type Rate struct {
// The number of requests per hour the client is currently limited to.
Limit int `json:"limit"`
// The number of remaining requests the client can make this hour.
Remaining int `json:"remaining"`
// The time at which the current rate limit will reset.
Reset Timestamp `json:"reset"`
}
func (r Rate) String() string {
return Stringify(r)
}
// RateLimits represents the rate limits for the current client.
type RateLimits struct {
// The rate limit for non-search API requests. Unauthenticated
// requests are limited to 60 per hour. Authenticated requests are
// limited to 5,000 per hour.
//
// GitHub API docs: https://developer.github.com/v3/#rate-limiting
Core *Rate `json:"core"`
// The rate limit for search API requests. Unauthenticated requests
// are limited to 5 requests per minutes. Authenticated requests are
// limited to 20 per minute.
//
// GitHub API docs: https://developer.github.com/v3/search/#rate-limit
Search *Rate `json:"search"`
}
func (r RateLimits) String() string {
return Stringify(r)
}
type rateLimitCategory uint8
const (
coreCategory rateLimitCategory = iota
searchCategory
categories // An array of this length will be able to contain all rate limit categories.
)
// category returns the rate limit category of the endpoint, determined by Request.URL.Path.
func category(path string) rateLimitCategory {
switch {
default:
return coreCategory
case strings.HasPrefix(path, "/search/"):
return searchCategory
}
}
// Deprecated: RateLimit is deprecated, use RateLimits instead.
func (c *Client) RateLimit() (*Rate, *Response, error) {
limits, resp, err := c.RateLimits()
if limits == nil {
return nil, nil, err
}
return limits.Core, resp, err
}
// RateLimits returns the rate limits for the current client.
func (c *Client) RateLimits() (*RateLimits, *Response, error) {
req, err := c.NewRequest("GET", "rate_limit", nil)
if err != nil {
return nil, nil, err
}
response := new(struct {
Resources *RateLimits `json:"resources"`
})
resp, err := c.Do(req, response)
if err != nil {
return nil, nil, err
}
if response.Resources != nil {
c.rateMu.Lock()
if response.Resources.Core != nil {
c.rateLimits[coreCategory] = *response.Resources.Core
}
if response.Resources.Search != nil {
c.rateLimits[searchCategory] = *response.Resources.Search
}
c.rateMu.Unlock()
}
return response.Resources, resp, err
}
/*
UnauthenticatedRateLimitedTransport allows you to make unauthenticated calls
that need to use a higher rate limit associated with your OAuth application.
t := &github.UnauthenticatedRateLimitedTransport{
ClientID: "your app's client ID",
ClientSecret: "your app's client secret",
}
client := github.NewClient(t.Client())
This will append the querystring params client_id=xxx&client_secret=yyy to all
requests.
See http://developer.github.com/v3/#unauthenticated-rate-limited-requests for
more information.
*/
type UnauthenticatedRateLimitedTransport struct {
// ClientID is the GitHub OAuth client ID of the current application, which
// can be found by selecting its entry in the list at
// https://github.com/settings/applications.
ClientID string
// ClientSecret is the GitHub OAuth client secret of the current
// application.
ClientSecret string
// Transport is the underlying HTTP transport to use when making requests.
// It will default to http.DefaultTransport if nil.
Transport http.RoundTripper
}
// RoundTrip implements the RoundTripper interface.
func (t *UnauthenticatedRateLimitedTransport) RoundTrip(req *http.Request) (*http.Response, error) {
if t.ClientID == "" {
return nil, errors.New("t.ClientID is empty")
}
if t.ClientSecret == "" {
return nil, errors.New("t.ClientSecret is empty")
}
// To set extra querystring params, we must make a copy of the Request so
// that we don't modify the Request we were given. This is required by the
// specification of http.RoundTripper.
req = cloneRequest(req)
q := req.URL.Query()
q.Set("client_id", t.ClientID)
q.Set("client_secret", t.ClientSecret)
req.URL.RawQuery = q.Encode()
// Make the HTTP request.
return t.transport().RoundTrip(req)
}
// Client returns an *http.Client that makes requests which are subject to the
// rate limit of your OAuth application.
func (t *UnauthenticatedRateLimitedTransport) Client() *http.Client {
return &http.Client{Transport: t}
}
func (t *UnauthenticatedRateLimitedTransport) transport() http.RoundTripper {
if t.Transport != nil {
return t.Transport
}
return http.DefaultTransport
}
// BasicAuthTransport is an http.RoundTripper that authenticates all requests
// using HTTP Basic Authentication with the provided username and password. It
// additionally supports users who have two-factor authentication enabled on
// their GitHub account.
type BasicAuthTransport struct {
Username string // GitHub username
Password string // GitHub password
OTP string // one-time password for users with two-factor auth enabled
// Transport is the underlying HTTP transport to use when making requests.
// It will default to http.DefaultTransport if nil.
Transport http.RoundTripper
}
// RoundTrip implements the RoundTripper interface.
func (t *BasicAuthTransport) RoundTrip(req *http.Request) (*http.Response, error) {
req = cloneRequest(req) // per RoundTrip contract
req.SetBasicAuth(t.Username, t.Password)
if t.OTP != "" {
req.Header.Set(headerOTP, t.OTP)
}
return t.transport().RoundTrip(req)
}
// Client returns an *http.Client that makes requests that are authenticated
// using HTTP Basic Authentication.
func (t *BasicAuthTransport) Client() *http.Client {
return &http.Client{Transport: t}
}
func (t *BasicAuthTransport) transport() http.RoundTripper {
if t.Transport != nil {
return t.Transport
}
return http.DefaultTransport
}
// cloneRequest returns a clone of the provided *http.Request. The clone is a
// shallow copy of the struct and its Header map.
func cloneRequest(r *http.Request) *http.Request {
// shallow copy of the struct
r2 := new(http.Request)
*r2 = *r
// deep copy of the Header
r2.Header = make(http.Header, len(r.Header))
for k, s := range r.Header {
r2.Header[k] = append([]string(nil), s...)
}
return r2
}
// Bool is a helper routine that allocates a new bool value
// to store v and returns a pointer to it.
func Bool(v bool) *bool { return &v }
// Int is a helper routine that allocates a new int value
// to store v and returns a pointer to it.
func Int(v int) *int { return &v }
// String is a helper routine that allocates a new string value
// to store v and returns a pointer to it.
func String(v string) *string { return &v }

865
vendor/src/github.com/google/go-github/github/github_test.go

@ -0,0 +1,865 @@
// Copyright 2013 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github
import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"net/http/httptest"
"net/url"
"os"
"path"
"reflect"
"strings"
"testing"
"time"
)
var (
// mux is the HTTP request multiplexer used with the test server.
mux *http.ServeMux
// client is the GitHub client being tested.
client *Client
// server is a test HTTP server used to provide mock API responses.
server *httptest.Server
)
// setup sets up a test HTTP server along with a github.Client that is
// configured to talk to that test server. Tests should register handlers on
// mux which provide mock responses for the API method being tested.
func setup() {
// test server
mux = http.NewServeMux()
server = httptest.NewServer(mux)
// github client configured to use test server
client = NewClient(nil)
url, _ := url.Parse(server.URL)
client.BaseURL = url
client.UploadURL = url
}
// teardown closes the test HTTP server.
func teardown() {
server.Close()
}
// openTestFile creates a new file with the given name and content for testing.
// In order to ensure the exact file name, this function will create a new temp
// directory, and create the file in that directory. It is the caller's
// responsibility to remove the directory and its contents when no longer needed.
func openTestFile(name, content string) (file *os.File, dir string, err error) {
dir, err = ioutil.TempDir("", "go-github")
if err != nil {
return nil, dir, err
}
file, err = os.OpenFile(path.Join(dir, name), os.O_RDWR|os.O_CREATE|os.O_EXCL, 0600)
if err != nil {
return nil, dir, err
}
fmt.Fprint(file, content)
// close and re-open the file to keep file.Stat() happy
file.Close()
file, err = os.Open(file.Name())
if err != nil {
return nil, dir, err
}
return file, dir, err
}
func testMethod(t *testing.T, r *http.Request, want string) {
if got := r.Method; got != want {
t.Errorf("Request method: %v, want %v", got, want)
}
}
type values map[string]string
func testFormValues(t *testing.T, r *http.Request, values values) {
want := url.Values{}
for k, v := range values {
want.Add(k, v)
}
r.ParseForm()
if got := r.Form; !reflect.DeepEqual(got, want) {
t.Errorf("Request parameters: %v, want %v", got, want)
}
}
func testHeader(t *testing.T, r *http.Request, header string, want string) {
if got := r.Header.Get(header); got != want {
t.Errorf("Header.Get(%q) returned %q, want %q", header, got, want)
}
}
func testURLParseError(t *testing.T, err error) {
if err == nil {
t.Errorf("Expected error to be returned")
}
if err, ok := err.(*url.Error); !ok || err.Op != "parse" {
t.Errorf("Expected URL parse error, got %+v", err)
}
}
func testBody(t *testing.T, r *http.Request, want string) {
b, err := ioutil.ReadAll(r.Body)
if err != nil {
t.Errorf("Error reading request body: %v", err)
}
if got := string(b); got != want {
t.Errorf("request Body is %s, want %s", got, want)
}
}
// Helper function to test that a value is marshalled to JSON as expected.
func testJSONMarshal(t *testing.T, v interface{}, want string) {
j, err := json.Marshal(v)
if err != nil {
t.Errorf("Unable to marshal JSON for %v", v)
}
w := new(bytes.Buffer)
err = json.Compact(w, []byte(want))
if err != nil {
t.Errorf("String is not valid json: %s", want)
}
if w.String() != string(j) {
t.Errorf("json.Marshal(%q) returned %s, want %s", v, j, w)
}
// now go the other direction and make sure things unmarshal as expected
u := reflect.ValueOf(v).Interface()
if err := json.Unmarshal([]byte(want), u); err != nil {
t.Errorf("Unable to unmarshal JSON for %v", want)
}
if !reflect.DeepEqual(v, u) {
t.Errorf("json.Unmarshal(%q) returned %s, want %s", want, u, v)
}
}
func TestNewClient(t *testing.T) {
c := NewClient(nil)
if got, want := c.BaseURL.String(), defaultBaseURL; got != want {
t.Errorf("NewClient BaseURL is %v, want %v", got, want)
}
if got, want := c.UserAgent, userAgent; got != want {
t.Errorf("NewClient UserAgent is %v, want %v", got, want)
}
}
// Ensure that length of Client.rateLimits is the same as number of fields in RateLimits struct.
func TestClient_rateLimits(t *testing.T) {
if got, want := len(Client{}.rateLimits), reflect.TypeOf(RateLimits{}).NumField(); got != want {
t.Errorf("len(Client{}.rateLimits) is %v, want %v", got, want)
}
}
func TestNewRequest(t *testing.T) {
c := NewClient(nil)
inURL, outURL := "/foo", defaultBaseURL+"foo"
inBody, outBody := &User{Login: String("l")}, `{"login":"l"}`+"\n"
req, _ := c.NewRequest("GET", inURL, inBody)
// test that relative URL was expanded
if got, want := req.URL.String(), outURL; got != want {
t.Errorf("NewRequest(%q) URL is %v, want %v", inURL, got, want)
}
// test that body was JSON encoded
body, _ := ioutil.ReadAll(req.Body)
if got, want := string(body), outBody; got != want {
t.Errorf("NewRequest(%q) Body is %v, want %v", inBody, got, want)
}
// test that default user-agent is attached to the request
if got, want := req.Header.Get("User-Agent"), c.UserAgent; got != want {
t.Errorf("NewRequest() User-Agent is %v, want %v", got, want)
}
}
func TestNewRequest_invalidJSON(t *testing.T) {
c := NewClient(nil)
type T struct {
A map[interface{}]interface{}
}
_, err := c.NewRequest("GET", "/", &T{})
if err == nil {
t.Error("Expected error to be returned.")
}
if err, ok := err.(*json.UnsupportedTypeError); !ok {
t.Errorf("Expected a JSON error; got %#v.", err)
}
}
func TestNewRequest_badURL(t *testing.T) {
c := NewClient(nil)
_, err := c.NewRequest("GET", ":", nil)
testURLParseError(t, err)
}
// ensure that no User-Agent header is set if the client's UserAgent is empty.
// This caused a problem with Google's internal http client.
func TestNewRequest_emptyUserAgent(t *testing.T) {
c := NewClient(nil)
c.UserAgent = ""
req, err := c.NewRequest("GET", "/", nil)
if err != nil {
t.Fatalf("NewRequest returned unexpected error: %v", err)
}
if _, ok := req.Header["User-Agent"]; ok {
t.Fatal("constructed request contains unexpected User-Agent header")
}
}
// If a nil body is passed to github.NewRequest, make sure that nil is also
// passed to http.NewRequest. In most cases, passing an io.Reader that returns
// no content is fine, since there is no difference between an HTTP request
// body that is an empty string versus one that is not set at all. However in
// certain cases, intermediate systems may treat these differently resulting in
// subtle errors.
func TestNewRequest_emptyBody(t *testing.T) {
c := NewClient(nil)
req, err := c.NewRequest("GET", "/", nil)
if err != nil {
t.Fatalf("NewRequest returned unexpected error: %v", err)
}
if req.Body != nil {
t.Fatalf("constructed request contains a non-nil Body")
}
}
func TestResponse_populatePageValues(t *testing.T) {
r := http.Response{
Header: http.Header{
"Link": {`<https://api.github.com/?page=1>; rel="first",` +
` <https://api.github.com/?page=2>; rel="prev",` +
` <https://api.github.com/?page=4>; rel="next",` +
` <https://api.github.com/?page=5>; rel="last"`,
},
},
}
response := newResponse(&r)
if got, want := response.FirstPage, 1; got != want {
t.Errorf("response.FirstPage: %v, want %v", got, want)
}
if got, want := response.PrevPage, 2; want != got {
t.Errorf("response.PrevPage: %v, want %v", got, want)
}
if got, want := response.NextPage, 4; want != got {
t.Errorf("response.NextPage: %v, want %v", got, want)
}
if got, want := response.LastPage, 5; want != got {
t.Errorf("response.LastPage: %v, want %v", got, want)
}
}
func TestResponse_populatePageValues_invalid(t *testing.T) {
r := http.Response{
Header: http.Header{
"Link": {`<https://api.github.com/?page=1>,` +
`<https://api.github.com/?page=abc>; rel="first",` +
`https://api.github.com/?page=2; rel="prev",` +
`<https://api.github.com/>; rel="next",` +
`<https://api.github.com/?page=>; rel="last"`,
},
},
}
response := newResponse(&r)
if got, want := response.FirstPage, 0; got != want {
t.Errorf("response.FirstPage: %v, want %v", got, want)
}
if got, want := response.PrevPage, 0; got != want {
t.Errorf("response.PrevPage: %v, want %v", got, want)
}
if got, want := response.NextPage, 0; got != want {
t.Errorf("response.NextPage: %v, want %v", got, want)
}
if got, want := response.LastPage, 0; got != want {
t.Errorf("response.LastPage: %v, want %v", got, want)
}
// more invalid URLs
r = http.Response{
Header: http.Header{
"Link": {`<https://api.github.com/%?page=2>; rel="first"`},
},
}
response = newResponse(&r)
if got, want := response.FirstPage, 0; got != want {
t.Errorf("response.FirstPage: %v, want %v", got, want)
}
}
func TestDo(t *testing.T) {
setup()
defer teardown()
type foo struct {
A string
}
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
if m := "GET"; m != r.Method {
t.Errorf("Request method = %v, want %v", r.Method, m)
}
fmt.Fprint(w, `{"A":"a"}`)
})
req, _ := client.NewRequest("GET", "/", nil)
body := new(foo)
client.Do(req, body)
want := &foo{"a"}
if !reflect.DeepEqual(body, want) {
t.Errorf("Response body = %v, want %v", body, want)
}
}
func TestDo_httpError(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
http.Error(w, "Bad Request", 400)
})
req, _ := client.NewRequest("GET", "/", nil)
_, err := client.Do(req, nil)
if err == nil {
t.Error("Expected HTTP 400 error.")
}
}
// Test handling of an error caused by the internal http client's Do()
// function. A redirect loop is pretty unlikely to occur within the GitHub
// API, but does allow us to exercise the right code path.
func TestDo_redirectLoop(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
http.Redirect(w, r, "/", http.StatusFound)
})
req, _ := client.NewRequest("GET", "/", nil)
_, err := client.Do(req, nil)
if err == nil {
t.Error("Expected error to be returned.")
}
if err, ok := err.(*url.Error); !ok {
t.Errorf("Expected a URL error; got %#v.", err)
}
}
func TestDo_rateLimit(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
w.Header().Add(headerRateLimit, "60")
w.Header().Add(headerRateRemaining, "59")
w.Header().Add(headerRateReset, "1372700873")
})
if got, want := client.Rate().Limit, 0; got != want {
t.Errorf("Client rate limit = %v, want %v", got, want)
}
if got, want := client.Rate().Remaining, 0; got != want {
t.Errorf("Client rate remaining = %v, got %v", got, want)
}
if !client.Rate().Reset.IsZero() {
t.Errorf("Client rate reset not initialized to zero value")
}
req, _ := client.NewRequest("GET", "/", nil)
_, err := client.Do(req, nil)
if err != nil {
t.Errorf("Do returned unexpected error: %v", err)
}
if got, want := client.Rate().Limit, 60; got != want {
t.Errorf("Client rate limit = %v, want %v", got, want)
}
if got, want := client.Rate().Remaining, 59; got != want {
t.Errorf("Client rate remaining = %v, want %v", got, want)
}
reset := time.Date(2013, 7, 1, 17, 47, 53, 0, time.UTC)
if client.Rate().Reset.UTC() != reset {
t.Errorf("Client rate reset = %v, want %v", client.Rate().Reset, reset)
}
}
// ensure rate limit is still parsed, even for error responses
func TestDo_rateLimit_errorResponse(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
w.Header().Add(headerRateLimit, "60")
w.Header().Add(headerRateRemaining, "59")
w.Header().Add(headerRateReset, "1372700873")
http.Error(w, "Bad Request", 400)
})
req, _ := client.NewRequest("GET", "/", nil)
_, err := client.Do(req, nil)
if err == nil {
t.Error("Expected error to be returned.")
}
if _, ok := err.(*RateLimitError); ok {
t.Errorf("Did not expect a *RateLimitError error; got %#v.", err)
}
if got, want := client.Rate().Limit, 60; got != want {
t.Errorf("Client rate limit = %v, want %v", got, want)
}
if got, want := client.Rate().Remaining, 59; got != want {
t.Errorf("Client rate remaining = %v, want %v", got, want)
}
reset := time.Date(2013, 7, 1, 17, 47, 53, 0, time.UTC)
if client.Rate().Reset.UTC() != reset {
t.Errorf("Client rate reset = %v, want %v", client.Rate().Reset, reset)
}
}
// Ensure *RateLimitError is returned when API rate limit is exceeded.
func TestDo_rateLimit_rateLimitError(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
w.Header().Add(headerRateLimit, "60")
w.Header().Add(headerRateRemaining, "0")
w.Header().Add(headerRateReset, "1372700873")
w.Header().Set("Content-Type", "application/json; charset=utf-8")
w.WriteHeader(http.StatusForbidden)
fmt.Fprintln(w, `{
"message": "API rate limit exceeded for xxx.xxx.xxx.xxx. (But here's the good news: Authenticated requests get a higher rate limit. Check out the documentation for more details.)",
"documentation_url": "https://developer.github.com/v3/#rate-limiting"
}`)
})
req, _ := client.NewRequest("GET", "/", nil)
_, err := client.Do(req, nil)
if err == nil {
t.Error("Expected error to be returned.")
}
rateLimitErr, ok := err.(*RateLimitError)
if !ok {
t.Fatalf("Expected a *RateLimitError error; got %#v.", err)
}
if got, want := rateLimitErr.Rate.Limit, 60; got != want {
t.Errorf("rateLimitErr rate limit = %v, want %v", got, want)
}
if got, want := rateLimitErr.Rate.Remaining, 0; got != want {
t.Errorf("rateLimitErr rate remaining = %v, want %v", got, want)
}
reset := time.Date(2013, 7, 1, 17, 47, 53, 0, time.UTC)
if rateLimitErr.Rate.Reset.UTC() != reset {
t.Errorf("rateLimitErr rate reset = %v, want %v", rateLimitErr.Rate.Reset.UTC(), reset)
}
}
// Ensure a network call is not made when it's known that API rate limit is still exceeded.
func TestDo_rateLimit_noNetworkCall(t *testing.T) {
setup()
defer teardown()
reset := time.Now().UTC().Round(time.Second).Add(time.Minute) // Rate reset is a minute from now, with 1 second precision.
mux.HandleFunc("/first", func(w http.ResponseWriter, r *http.Request) {
w.Header().Add(headerRateLimit, "60")
w.Header().Add(headerRateRemaining, "0")
w.Header().Add(headerRateReset, fmt.Sprint(reset.Unix()))
w.Header().Set("Content-Type", "application/json; charset=utf-8")
w.WriteHeader(http.StatusForbidden)
fmt.Fprintln(w, `{
"message": "API rate limit exceeded for xxx.xxx.xxx.xxx. (But here's the good news: Authenticated requests get a higher rate limit. Check out the documentation for more details.)",
"documentation_url": "https://developer.github.com/v3/#rate-limiting"
}`)
})
madeNetworkCall := false
mux.HandleFunc("/second", func(w http.ResponseWriter, r *http.Request) {
madeNetworkCall = true
})
// First request is made, and it makes the client aware of rate reset time being in the future.
req, _ := client.NewRequest("GET", "/first", nil)
client.Do(req, nil)
// Second request should not cause a network call to be made, since client can predict a rate limit error.
req, _ = client.NewRequest("GET", "/second", nil)
_, err := client.Do(req, nil)
if madeNetworkCall {
t.Fatal("Network call was made, even though rate limit is known to still be exceeded.")
}
if err == nil {
t.Error("Expected error to be returned.")
}
rateLimitErr, ok := err.(*RateLimitError)
if !ok {
t.Fatalf("Expected a *RateLimitError error; got %#v.", err)
}
if got, want := rateLimitErr.Rate.Limit, 60; got != want {
t.Errorf("rateLimitErr rate limit = %v, want %v", got, want)
}
if got, want := rateLimitErr.Rate.Remaining, 0; got != want {
t.Errorf("rateLimitErr rate remaining = %v, want %v", got, want)
}
if rateLimitErr.Rate.Reset.UTC() != reset {
t.Errorf("rateLimitErr rate reset = %v, want %v", rateLimitErr.Rate.Reset.UTC(), reset)
}
}
func TestDo_noContent(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusNoContent)
})
var body json.RawMessage
req, _ := client.NewRequest("GET", "/", nil)
_, err := client.Do(req, &body)
if err != nil {
t.Fatalf("Do returned unexpected error: %v", err)
}
}
func TestSanitizeURL(t *testing.T) {
tests := []struct {
in, want string
}{
{"/?a=b", "/?a=b"},
{"/?a=b&client_secret=secret", "/?a=b&client_secret=REDACTED"},
{"/?a=b&client_id=id&client_secret=secret", "/?a=b&client_id=id&client_secret=REDACTED"},
}
for _, tt := range tests {
inURL, _ := url.Parse(tt.in)
want, _ := url.Parse(tt.want)
if got := sanitizeURL(inURL); !reflect.DeepEqual(got, want) {
t.Errorf("sanitizeURL(%v) returned %v, want %v", tt.in, got, want)
}
}
}
func TestCheckResponse(t *testing.T) {
res := &http.Response{
Request: &http.Request{},
StatusCode: http.StatusBadRequest,
Body: ioutil.NopCloser(strings.NewReader(`{"message":"m",
"errors": [{"resource": "r", "field": "f", "code": "c"}],
"block": {"reason": "dmca", "created_at": "2016-03-17T15:39:46Z"}}`)),
}
err := CheckResponse(res).(*ErrorResponse)
if err == nil {
t.Errorf("Expected error response.")
}
want := &ErrorResponse{
Response: res,
Message: "m",
Errors: []Error{{Resource: "r", Field: "f", Code: "c"}},
Block: &struct {
Reason string `json:"reason,omitempty"`
CreatedAt *Timestamp `json:"created_at,omitempty"`
}{
Reason: "dmca",
CreatedAt: &Timestamp{time.Date(2016, 3, 17, 15, 39, 46, 0, time.UTC)},
},
}
if !reflect.DeepEqual(err, want) {
t.Errorf("Error = %#v, want %#v", err, want)
}
}
// ensure that we properly handle API errors that do not contain a response body
func TestCheckResponse_noBody(t *testing.T) {
res := &http.Response{
Request: &http.Request{},
StatusCode: http.StatusBadRequest,
Body: ioutil.NopCloser(strings.NewReader("")),
}
err := CheckResponse(res).(*ErrorResponse)
if err == nil {
t.Errorf("Expected error response.")
}
want := &ErrorResponse{
Response: res,
}
if !reflect.DeepEqual(err, want) {
t.Errorf("Error = %#v, want %#v", err, want)
}
}
func TestParseBooleanResponse_true(t *testing.T) {
result, err := parseBoolResponse(nil)
if err != nil {
t.Errorf("parseBoolResponse returned error: %+v", err)
}
if want := true; result != want {
t.Errorf("parseBoolResponse returned %+v, want: %+v", result, want)
}
}
func TestParseBooleanResponse_false(t *testing.T) {
v := &ErrorResponse{Response: &http.Response{StatusCode: http.StatusNotFound}}
result, err := parseBoolResponse(v)
if err != nil {
t.Errorf("parseBoolResponse returned error: %+v", err)
}
if want := false; result != want {
t.Errorf("parseBoolResponse returned %+v, want: %+v", result, want)
}
}
func TestParseBooleanResponse_error(t *testing.T) {
v := &ErrorResponse{Response: &http.Response{StatusCode: http.StatusBadRequest}}
result, err := parseBoolResponse(v)
if err == nil {
t.Errorf("Expected error to be returned.")
}
if want := false; result != want {
t.Errorf("parseBoolResponse returned %+v, want: %+v", result, want)
}
}
func TestErrorResponse_Error(t *testing.T) {
res := &http.Response{Request: &http.Request{}}
err := ErrorResponse{Message: "m", Response: res}
if err.Error() == "" {
t.Errorf("Expected non-empty ErrorResponse.Error()")
}
}
func TestError_Error(t *testing.T) {
err := Error{}
if err.Error() == "" {
t.Errorf("Expected non-empty Error.Error()")
}
}
func TestRateLimit(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/rate_limit", func(w http.ResponseWriter, r *http.Request) {
if m := "GET"; m != r.Method {
t.Errorf("Request method = %v, want %v", r.Method, m)
}
fmt.Fprint(w, `{"resources":{
"core": {"limit":2,"remaining":1,"reset":1372700873},
"search": {"limit":3,"remaining":2,"reset":1372700874}
}}`)
})
rate, _, err := client.RateLimit()
if err != nil {
t.Errorf("Rate limit returned error: %v", err)
}
want := &Rate{
Limit: 2,
Remaining: 1,
Reset: Timestamp{time.Date(2013, 7, 1, 17, 47, 53, 0, time.UTC).Local()},
}
if !reflect.DeepEqual(rate, want) {
t.Errorf("RateLimit returned %+v, want %+v", rate, want)
}
}
func TestRateLimits(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/rate_limit", func(w http.ResponseWriter, r *http.Request) {
if m := "GET"; m != r.Method {
t.Errorf("Request method = %v, want %v", r.Method, m)
}
fmt.Fprint(w, `{"resources":{
"core": {"limit":2,"remaining":1,"reset":1372700873},
"search": {"limit":3,"remaining":2,"reset":1372700874}
}}`)
})
rate, _, err := client.RateLimits()
if err != nil {
t.Errorf("RateLimits returned error: %v", err)
}
want := &RateLimits{
Core: &Rate{
Limit: 2,
Remaining: 1,
Reset: Timestamp{time.Date(2013, 7, 1, 17, 47, 53, 0, time.UTC).Local()},
},
Search: &Rate{
Limit: 3,
Remaining: 2,
Reset: Timestamp{time.Date(2013, 7, 1, 17, 47, 54, 0, time.UTC).Local()},
},
}
if !reflect.DeepEqual(rate, want) {
t.Errorf("RateLimits returned %+v, want %+v", rate, want)
}
if got, want := client.rateLimits[coreCategory], *want.Core; got != want {
t.Errorf("client.rateLimits[coreCategory] is %+v, want %+v", got, want)
}
if got, want := client.rateLimits[searchCategory], *want.Search; got != want {
t.Errorf("client.rateLimits[searchCategory] is %+v, want %+v", got, want)
}
}
func TestUnauthenticatedRateLimitedTransport(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
var v, want string
q := r.URL.Query()
if v, want = q.Get("client_id"), "id"; v != want {
t.Errorf("OAuth Client ID = %v, want %v", v, want)
}
if v, want = q.Get("client_secret"), "secret"; v != want {
t.Errorf("OAuth Client Secret = %v, want %v", v, want)
}
})
tp := &UnauthenticatedRateLimitedTransport{
ClientID: "id",
ClientSecret: "secret",
}
unauthedClient := NewClient(tp.Client())
unauthedClient.BaseURL = client.BaseURL
req, _ := unauthedClient.NewRequest("GET", "/", nil)
unauthedClient.Do(req, nil)
}
func TestUnauthenticatedRateLimitedTransport_missingFields(t *testing.T) {
// missing ClientID
tp := &UnauthenticatedRateLimitedTransport{
ClientSecret: "secret",
}
_, err := tp.RoundTrip(nil)
if err == nil {
t.Errorf("Expected error to be returned")
}
// missing ClientSecret
tp = &UnauthenticatedRateLimitedTransport{
ClientID: "id",
}
_, err = tp.RoundTrip(nil)
if err == nil {
t.Errorf("Expected error to be returned")
}
}
func TestUnauthenticatedRateLimitedTransport_transport(t *testing.T) {
// default transport
tp := &UnauthenticatedRateLimitedTransport{
ClientID: "id",
ClientSecret: "secret",
}
if tp.transport() != http.DefaultTransport {
t.Errorf("Expected http.DefaultTransport to be used.")
}
// custom transport
tp = &UnauthenticatedRateLimitedTransport{
ClientID: "id",
ClientSecret: "secret",
Transport: &http.Transport{},
}
if tp.transport() == http.DefaultTransport {
t.Errorf("Expected custom transport to be used.")
}
}
func TestBasicAuthTransport(t *testing.T) {
setup()
defer teardown()
username, password, otp := "u", "p", "123456"
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
u, p, ok := r.BasicAuth()
if !ok {
t.Errorf("request does not contain basic auth credentials")
}
if u != username {
t.Errorf("request contained basic auth username %q, want %q", u, username)
}
if p != password {
t.Errorf("request contained basic auth password %q, want %q", p, password)
}
if got, want := r.Header.Get(headerOTP), otp; got != want {
t.Errorf("request contained OTP %q, want %q", got, want)
}
})
tp := &BasicAuthTransport{
Username: username,
Password: password,
OTP: otp,
}
basicAuthClient := NewClient(tp.Client())
basicAuthClient.BaseURL = client.BaseURL
req, _ := basicAuthClient.NewRequest("GET", "/", nil)
basicAuthClient.Do(req, nil)
}
func TestBasicAuthTransport_transport(t *testing.T) {
// default transport
tp := &BasicAuthTransport{}
if tp.transport() != http.DefaultTransport {
t.Errorf("Expected http.DefaultTransport to be used.")
}
// custom transport
tp = &BasicAuthTransport{
Transport: &http.Transport{},
}
if tp.transport() == http.DefaultTransport {
t.Errorf("Expected custom transport to be used.")
}
}

61
vendor/src/github.com/google/go-github/github/gitignore.go

@ -0,0 +1,61 @@
// Copyright 2013 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github
import "fmt"
// GitignoresService provides access to the gitignore related functions in the
// GitHub API.
//
// GitHub API docs: http://developer.github.com/v3/gitignore/
type GitignoresService service
// Gitignore represents a .gitignore file as returned by the GitHub API.
type Gitignore struct {
Name *string `json:"name,omitempty"`
Source *string `json:"source,omitempty"`
}
func (g Gitignore) String() string {
return Stringify(g)
}
// List all available Gitignore templates.
//
// http://developer.github.com/v3/gitignore/#listing-available-templates
func (s GitignoresService) List() ([]string, *Response, error) {
req, err := s.client.NewRequest("GET", "gitignore/templates", nil)
if err != nil {
return nil, nil, err
}
availableTemplates := new([]string)
resp, err := s.client.Do(req, availableTemplates)
if err != nil {
return nil, resp, err
}
return *availableTemplates, resp, err
}
// Get a Gitignore by name.
//
// http://developer.github.com/v3/gitignore/#get-a-single-template
func (s GitignoresService) Get(name string) (*Gitignore, *Response, error) {
u := fmt.Sprintf("gitignore/templates/%v", name)
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
gitignore := new(Gitignore)
resp, err := s.client.Do(req, gitignore)
if err != nil {
return nil, resp, err
}
return gitignore, resp, err
}

58
vendor/src/github.com/google/go-github/github/gitignore_test.go

@ -0,0 +1,58 @@
// Copyright 2013 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github
import (
"fmt"
"net/http"
"reflect"
"testing"
)
func TestGitignoresService_List(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/gitignore/templates", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
fmt.Fprint(w, `["C", "Go"]`)
})
available, _, err := client.Gitignores.List()
if err != nil {
t.Errorf("Gitignores.List returned error: %v", err)
}
want := []string{"C", "Go"}
if !reflect.DeepEqual(available, want) {
t.Errorf("Gitignores.List returned %+v, want %+v", available, want)
}
}
func TestGitignoresService_Get(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/gitignore/templates/name", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
fmt.Fprint(w, `{"name":"Name","source":"template source"}`)
})
gitignore, _, err := client.Gitignores.Get("name")
if err != nil {
t.Errorf("Gitignores.List returned error: %v", err)
}
want := &Gitignore{Name: String("Name"), Source: String("template source")}
if !reflect.DeepEqual(gitignore, want) {
t.Errorf("Gitignores.Get returned %+v, want %+v", gitignore, want)
}
}
func TestGitignoresService_Get_invalidTemplate(t *testing.T) {
_, _, err := client.Gitignores.Get("%")
testURLParseError(t, err)
}

299
vendor/src/github.com/google/go-github/github/issues.go

@ -0,0 +1,299 @@
// Copyright 2013 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github
import (
"fmt"
"time"
)
// IssuesService handles communication with the issue related
// methods of the GitHub API.
//
// GitHub API docs: http://developer.github.com/v3/issues/
type IssuesService service
// Issue represents a GitHub issue on a repository.
type Issue struct {
ID *int `json:"id,omitempty"`
Number *int `json:"number,omitempty"`
State *string `json:"state,omitempty"`
Title *string `json:"title,omitempty"`
Body *string `json:"body,omitempty"`
User *User `json:"user,omitempty"`
Labels []Label `json:"labels,omitempty"`
Assignee *User `json:"assignee,omitempty"`
Comments *int `json:"comments,omitempty"`
ClosedAt *time.Time `json:"closed_at,omitempty"`
CreatedAt *time.Time `json:"created_at,omitempty"`
UpdatedAt *time.Time `json:"updated_at,omitempty"`
URL *string `json:"url,omitempty"`
HTMLURL *string `json:"html_url,omitempty"`
Milestone *Milestone `json:"milestone,omitempty"`
PullRequestLinks *PullRequestLinks `json:"pull_request,omitempty"`
Repository *Repository `json:"repository,omitempty"`
Reactions *Reactions `json:"reactions,omitempty"`
Assignees []*User `json:"assignees,omitempty"`
// TextMatches is only populated from search results that request text matches
// See: search.go and https://developer.github.com/v3/search/#text-match-metadata
TextMatches []TextMatch `json:"text_matches,omitempty"`
}
func (i Issue) String() string {
return Stringify(i)
}
// IssueRequest represents a request to create/edit an issue.
// It is separate from Issue above because otherwise Labels
// and Assignee fail to serialize to the correct JSON.
type IssueRequest struct {
Title *string `json:"title,omitempty"`
Body *string `json:"body,omitempty"`
Labels *[]string `json:"labels,omitempty"`
Assignee *string `json:"assignee,omitempty"`
State *string `json:"state,omitempty"`
Milestone *int `json:"milestone,omitempty"`
Assignees *[]string `json:"assignees,omitempty"`
}
// IssueListOptions specifies the optional parameters to the IssuesService.List
// and IssuesService.ListByOrg methods.
type IssueListOptions struct {
// Filter specifies which issues to list. Possible values are: assigned,
// created, mentioned, subscribed, all. Default is "assigned".
Filter string `url:"filter,omitempty"`
// State filters issues based on their state. Possible values are: open,
// closed, all. Default is "open".
State string `url:"state,omitempty"`
// Labels filters issues based on their label.
Labels []string `url:"labels,comma,omitempty"`
// Sort specifies how to sort issues. Possible values are: created, updated,
// and comments. Default value is "created".
Sort string `url:"sort,omitempty"`
// Direction in which to sort issues. Possible values are: asc, desc.
// Default is "desc".
Direction string `url:"direction,omitempty"`
// Since filters issues by time.
Since time.Time `url:"since,omitempty"`
ListOptions
}
// PullRequestLinks object is added to the Issue object when it's an issue included
// in the IssueCommentEvent webhook payload, if the webhooks is fired by a comment on a PR
type PullRequestLinks struct {
URL *string `json:"url,omitempty"`
HTMLURL *string `json:"html_url,omitempty"`
DiffURL *string `json:"diff_url,omitempty"`
PatchURL *string `json:"patch_url,omitempty"`
}
// List the issues for the authenticated user. If all is true, list issues
// across all the user's visible repositories including owned, member, and
// organization repositories; if false, list only owned and member
// repositories.
//
// GitHub API docs: http://developer.github.com/v3/issues/#list-issues
func (s *IssuesService) List(all bool, opt *IssueListOptions) ([]*Issue, *Response, error) {
var u string
if all {
u = "issues"
} else {
u = "user/issues"
}
return s.listIssues(u, opt)
}
// ListByOrg fetches the issues in the specified organization for the
// authenticated user.
//
// GitHub API docs: http://developer.github.com/v3/issues/#list-issues
func (s *IssuesService) ListByOrg(org string, opt *IssueListOptions) ([]*Issue, *Response, error) {
u := fmt.Sprintf("orgs/%v/issues", org)
return s.listIssues(u, opt)
}
func (s *IssuesService) listIssues(u string, opt *IssueListOptions) ([]*Issue, *Response, error) {
u, err := addOptions(u, opt)
if err != nil {
return nil, nil, err
}
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
// TODO: remove custom Accept header when this API fully launches.
req.Header.Set("Accept", mediaTypeReactionsPreview)
issues := new([]*Issue)
resp, err := s.client.Do(req, issues)
if err != nil {
return nil, resp, err
}
return *issues, resp, err
}
// IssueListByRepoOptions specifies the optional parameters to the
// IssuesService.ListByRepo method.
type IssueListByRepoOptions struct {
// Milestone limits issues for the specified milestone. Possible values are
// a milestone number, "none" for issues with no milestone, "*" for issues
// with any milestone.
Milestone string `url:"milestone,omitempty"`
// State filters issues based on their state. Possible values are: open,
// closed, all. Default is "open".
State string `url:"state,omitempty"`
// Assignee filters issues based on their assignee. Possible values are a
// user name, "none" for issues that are not assigned, "*" for issues with
// any assigned user.
Assignee string `url:"assignee,omitempty"`
// Creator filters issues based on their creator.
Creator string `url:"creator,omitempty"`
// Mentioned filters issues to those mentioned a specific user.
Mentioned string `url:"mentioned,omitempty"`
// Labels filters issues based on their label.
Labels []string `url:"labels,omitempty,comma"`
// Sort specifies how to sort issues. Possible values are: created, updated,
// and comments. Default value is "created".
Sort string `url:"sort,omitempty"`
// Direction in which to sort issues. Possible values are: asc, desc.
// Default is "desc".
Direction string `url:"direction,omitempty"`
// Since filters issues by time.
Since time.Time `url:"since,omitempty"`
ListOptions
}
// ListByRepo lists the issues for the specified repository.
//
// GitHub API docs: http://developer.github.com/v3/issues/#list-issues-for-a-repository
func (s *IssuesService) ListByRepo(owner string, repo string, opt *IssueListByRepoOptions) ([]*Issue, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/issues", owner, repo)
u, err := addOptions(u, opt)
if err != nil {
return nil, nil, err
}
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
// TODO: remove custom Accept header when this API fully launches.
req.Header.Set("Accept", mediaTypeReactionsPreview)
issues := new([]*Issue)
resp, err := s.client.Do(req, issues)
if err != nil {
return nil, resp, err
}
return *issues, resp, err
}
// Get a single issue.
//
// GitHub API docs: http://developer.github.com/v3/issues/#get-a-single-issue
func (s *IssuesService) Get(owner string, repo string, number int) (*Issue, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/issues/%d", owner, repo, number)
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
// TODO: remove custom Accept header when this API fully launches.
req.Header.Set("Accept", mediaTypeReactionsPreview)
issue := new(Issue)
resp, err := s.client.Do(req, issue)
if err != nil {
return nil, resp, err
}
return issue, resp, err
}
// Create a new issue on the specified repository.
//
// GitHub API docs: http://developer.github.com/v3/issues/#create-an-issue
func (s *IssuesService) Create(owner string, repo string, issue *IssueRequest) (*Issue, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/issues", owner, repo)
req, err := s.client.NewRequest("POST", u, issue)
if err != nil {
return nil, nil, err
}
i := new(Issue)
resp, err := s.client.Do(req, i)
if err != nil {
return nil, resp, err
}
return i, resp, err
}
// Edit an issue.
//
// GitHub API docs: http://developer.github.com/v3/issues/#edit-an-issue
func (s *IssuesService) Edit(owner string, repo string, number int, issue *IssueRequest) (*Issue, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/issues/%d", owner, repo, number)
req, err := s.client.NewRequest("PATCH", u, issue)
if err != nil {
return nil, nil, err
}
i := new(Issue)
resp, err := s.client.Do(req, i)
if err != nil {
return nil, resp, err
}
return i, resp, err
}
// Lock an issue's conversation.
//
// GitHub API docs: https://developer.github.com/v3/issues/#lock-an-issue
func (s *IssuesService) Lock(owner string, repo string, number int) (*Response, error) {
u := fmt.Sprintf("repos/%v/%v/issues/%d/lock", owner, repo, number)
req, err := s.client.NewRequest("PUT", u, nil)
if err != nil {
return nil, err
}
return s.client.Do(req, nil)
}
// Unlock an issue's conversation.
//
// GitHub API docs: https://developer.github.com/v3/issues/#unlock-an-issue
func (s *IssuesService) Unlock(owner string, repo string, number int) (*Response, error) {
u := fmt.Sprintf("repos/%v/%v/issues/%d/lock", owner, repo, number)
req, err := s.client.NewRequest("DELETE", u, nil)
if err != nil {
return nil, err
}
return s.client.Do(req, nil)
}

82
vendor/src/github.com/google/go-github/github/issues_assignees.go

@ -0,0 +1,82 @@
// Copyright 2013 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github
import "fmt"
// ListAssignees fetches all available assignees (owners and collaborators) to
// which issues may be assigned.
//
// GitHub API docs: http://developer.github.com/v3/issues/assignees/#list-assignees
func (s *IssuesService) ListAssignees(owner, repo string, opt *ListOptions) ([]*User, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/assignees", owner, repo)
u, err := addOptions(u, opt)
if err != nil {
return nil, nil, err
}
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
assignees := new([]*User)
resp, err := s.client.Do(req, assignees)
if err != nil {
return nil, resp, err
}
return *assignees, resp, err
}
// IsAssignee checks if a user is an assignee for the specified repository.
//
// GitHub API docs: http://developer.github.com/v3/issues/assignees/#check-assignee
func (s *IssuesService) IsAssignee(owner, repo, user string) (bool, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/assignees/%v", owner, repo, user)
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return false, nil, err
}
resp, err := s.client.Do(req, nil)
assignee, err := parseBoolResponse(err)
return assignee, resp, err
}
// AddAssignees adds the provided GitHub users as assignees to the issue.
//
// GitHub API docs: https://developer.github.com/v3/issues/assignees/#add-assignees-to-an-issue
func (s *IssuesService) AddAssignees(owner, repo string, number int, assignees []string) (*Issue, *Response, error) {
users := &struct {
Assignees []string `json:"assignees,omitempty"`
}{Assignees: assignees}
u := fmt.Sprintf("repos/%v/%v/issues/%v/assignees", owner, repo, number)
req, err := s.client.NewRequest("POST", u, users)
if err != nil {
return nil, nil, err
}
issue := &Issue{}
resp, err := s.client.Do(req, issue)
return issue, resp, err
}
// RemoveAssignees removes the provided GitHub users as assignees from the issue.
//
// GitHub API docs: https://developer.github.com/v3/issues/assignees/#remove-assignees-from-an-issue
func (s *IssuesService) RemoveAssignees(owner, repo string, number int, assignees []string) (*Issue, *Response, error) {
users := &struct {
Assignees []string `json:"assignees,omitempty"`
}{Assignees: assignees}
u := fmt.Sprintf("repos/%v/%v/issues/%v/assignees", owner, repo, number)
req, err := s.client.NewRequest("DELETE", u, users)
if err != nil {
return nil, nil, err
}
issue := &Issue{}
resp, err := s.client.Do(req, issue)
return issue, resp, err
}

157
vendor/src/github.com/google/go-github/github/issues_assignees_test.go

@ -0,0 +1,157 @@
// Copyright 2013 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github
import (
"encoding/json"
"fmt"
"net/http"
"reflect"
"testing"
)
func TestIssuesService_ListAssignees(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/assignees", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testFormValues(t, r, values{"page": "2"})
fmt.Fprint(w, `[{"id":1}]`)
})
opt := &ListOptions{Page: 2}
assignees, _, err := client.Issues.ListAssignees("o", "r", opt)
if err != nil {
t.Errorf("Issues.ListAssignees returned error: %v", err)
}
want := []*User{{ID: Int(1)}}
if !reflect.DeepEqual(assignees, want) {
t.Errorf("Issues.ListAssignees returned %+v, want %+v", assignees, want)
}
}
func TestIssuesService_ListAssignees_invalidOwner(t *testing.T) {
_, _, err := client.Issues.ListAssignees("%", "r", nil)
testURLParseError(t, err)
}
func TestIssuesService_IsAssignee_true(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/assignees/u", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
})
assignee, _, err := client.Issues.IsAssignee("o", "r", "u")
if err != nil {
t.Errorf("Issues.IsAssignee returned error: %v", err)
}
if want := true; assignee != want {
t.Errorf("Issues.IsAssignee returned %+v, want %+v", assignee, want)
}
}
func TestIssuesService_IsAssignee_false(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/assignees/u", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
w.WriteHeader(http.StatusNotFound)
})
assignee, _, err := client.Issues.IsAssignee("o", "r", "u")
if err != nil {
t.Errorf("Issues.IsAssignee returned error: %v", err)
}
if want := false; assignee != want {
t.Errorf("Issues.IsAssignee returned %+v, want %+v", assignee, want)
}
}
func TestIssuesService_IsAssignee_error(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/assignees/u", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
http.Error(w, "BadRequest", http.StatusBadRequest)
})
assignee, _, err := client.Issues.IsAssignee("o", "r", "u")
if err == nil {
t.Errorf("Expected HTTP 400 response")
}
if want := false; assignee != want {
t.Errorf("Issues.IsAssignee returned %+v, want %+v", assignee, want)
}
}
func TestIssuesService_IsAssignee_invalidOwner(t *testing.T) {
_, _, err := client.Issues.IsAssignee("%", "r", "u")
testURLParseError(t, err)
}
func TestIssuesService_AddAssignees(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/issues/1/assignees", func(w http.ResponseWriter, r *http.Request) {
var assignees struct {
Assignees []string `json:"assignees,omitempty"`
}
json.NewDecoder(r.Body).Decode(&assignees)
testMethod(t, r, "POST")
want := []string{"user1", "user2"}
if !reflect.DeepEqual(assignees.Assignees, want) {
t.Errorf("assignees = %+v, want %+v", assignees, want)
}
fmt.Fprint(w, `{"number":1,"assignees":[{"login":"user1"},{"login":"user2"}]}`)
})
got, _, err := client.Issues.AddAssignees("o", "r", 1, []string{"user1", "user2"})
if err != nil {
t.Errorf("Issues.AddAssignees returned error: %v", err)
}
want := &Issue{Number: Int(1), Assignees: []*User{{Login: String("user1")}, {Login: String("user2")}}}
if !reflect.DeepEqual(got, want) {
t.Errorf("Issues.AddAssignees = %+v, want %+v", got, want)
}
}
func TestIssuesService_RemoveAssignees(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/issues/1/assignees", func(w http.ResponseWriter, r *http.Request) {
var assignees struct {
Assignees []string `json:"assignees,omitempty"`
}
json.NewDecoder(r.Body).Decode(&assignees)
testMethod(t, r, "DELETE")
want := []string{"user1", "user2"}
if !reflect.DeepEqual(assignees.Assignees, want) {
t.Errorf("assignees = %+v, want %+v", assignees, want)
}
fmt.Fprint(w, `{"number":1,"assignees":[]}`)
})
got, _, err := client.Issues.RemoveAssignees("o", "r", 1, []string{"user1", "user2"})
if err != nil {
t.Errorf("Issues.RemoveAssignees returned error: %v", err)
}
want := &Issue{Number: Int(1), Assignees: []*User{}}
if !reflect.DeepEqual(got, want) {
t.Errorf("Issues.RemoveAssignees = %+v, want %+v", got, want)
}
}

147
vendor/src/github.com/google/go-github/github/issues_comments.go

@ -0,0 +1,147 @@
// Copyright 2013 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github
import (
"fmt"
"time"
)
// IssueComment represents a comment left on an issue.
type IssueComment struct {
ID *int `json:"id,omitempty"`
Body *string `json:"body,omitempty"`
User *User `json:"user,omitempty"`
Reactions *Reactions `json:"reactions,omitempty"`
CreatedAt *time.Time `json:"created_at,omitempty"`
UpdatedAt *time.Time `json:"updated_at,omitempty"`
URL *string `json:"url,omitempty"`
HTMLURL *string `json:"html_url,omitempty"`
IssueURL *string `json:"issue_url,omitempty"`
}
func (i IssueComment) String() string {
return Stringify(i)
}
// IssueListCommentsOptions specifies the optional parameters to the
// IssuesService.ListComments method.
type IssueListCommentsOptions struct {
// Sort specifies how to sort comments. Possible values are: created, updated.
Sort string `url:"sort,omitempty"`
// Direction in which to sort comments. Possible values are: asc, desc.
Direction string `url:"direction,omitempty"`
// Since filters comments by time.
Since time.Time `url:"since,omitempty"`
ListOptions
}
// ListComments lists all comments on the specified issue. Specifying an issue
// number of 0 will return all comments on all issues for the repository.
//
// GitHub API docs: http://developer.github.com/v3/issues/comments/#list-comments-on-an-issue
func (s *IssuesService) ListComments(owner string, repo string, number int, opt *IssueListCommentsOptions) ([]*IssueComment, *Response, error) {
var u string
if number == 0 {
u = fmt.Sprintf("repos/%v/%v/issues/comments", owner, repo)
} else {
u = fmt.Sprintf("repos/%v/%v/issues/%d/comments", owner, repo, number)
}
u, err := addOptions(u, opt)
if err != nil {
return nil, nil, err
}
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
// TODO: remove custom Accept header when this API fully launches.
req.Header.Set("Accept", mediaTypeReactionsPreview)
comments := new([]*IssueComment)
resp, err := s.client.Do(req, comments)
if err != nil {
return nil, resp, err
}
return *comments, resp, err
}
// GetComment fetches the specified issue comment.
//
// GitHub API docs: http://developer.github.com/v3/issues/comments/#get-a-single-comment
func (s *IssuesService) GetComment(owner string, repo string, id int) (*IssueComment, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/issues/comments/%d", owner, repo, id)
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
// TODO: remove custom Accept header when this API fully launches.
req.Header.Set("Accept", mediaTypeReactionsPreview)
comment := new(IssueComment)
resp, err := s.client.Do(req, comment)
if err != nil {
return nil, resp, err
}
return comment, resp, err
}
// CreateComment creates a new comment on the specified issue.
//
// GitHub API docs: http://developer.github.com/v3/issues/comments/#create-a-comment
func (s *IssuesService) CreateComment(owner string, repo string, number int, comment *IssueComment) (*IssueComment, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/issues/%d/comments", owner, repo, number)
req, err := s.client.NewRequest("POST", u, comment)
if err != nil {
return nil, nil, err
}
c := new(IssueComment)
resp, err := s.client.Do(req, c)
if err != nil {
return nil, resp, err
}
return c, resp, err
}
// EditComment updates an issue comment.
//
// GitHub API docs: http://developer.github.com/v3/issues/comments/#edit-a-comment
func (s *IssuesService) EditComment(owner string, repo string, id int, comment *IssueComment) (*IssueComment, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/issues/comments/%d", owner, repo, id)
req, err := s.client.NewRequest("PATCH", u, comment)
if err != nil {
return nil, nil, err
}
c := new(IssueComment)
resp, err := s.client.Do(req, c)
if err != nil {
return nil, resp, err
}
return c, resp, err
}
// DeleteComment deletes an issue comment.
//
// GitHub API docs: http://developer.github.com/v3/issues/comments/#delete-a-comment
func (s *IssuesService) DeleteComment(owner string, repo string, id int) (*Response, error) {
u := fmt.Sprintf("repos/%v/%v/issues/comments/%d", owner, repo, id)
req, err := s.client.NewRequest("DELETE", u, nil)
if err != nil {
return nil, err
}
return s.client.Do(req, nil)
}

187
vendor/src/github.com/google/go-github/github/issues_comments_test.go

@ -0,0 +1,187 @@
// Copyright 2013 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github
import (
"encoding/json"
"fmt"
"net/http"
"reflect"
"testing"
"time"
)
func TestIssuesService_ListComments_allIssues(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/issues/comments", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testHeader(t, r, "Accept", mediaTypeReactionsPreview)
testFormValues(t, r, values{
"sort": "updated",
"direction": "desc",
"since": "2002-02-10T15:30:00Z",
"page": "2",
})
fmt.Fprint(w, `[{"id":1}]`)
})
opt := &IssueListCommentsOptions{
Sort: "updated",
Direction: "desc",
Since: time.Date(2002, time.February, 10, 15, 30, 0, 0, time.UTC),
ListOptions: ListOptions{Page: 2},
}
comments, _, err := client.Issues.ListComments("o", "r", 0, opt)
if err != nil {
t.Errorf("Issues.ListComments returned error: %v", err)
}
want := []*IssueComment{{ID: Int(1)}}
if !reflect.DeepEqual(comments, want) {
t.Errorf("Issues.ListComments returned %+v, want %+v", comments, want)
}
}
func TestIssuesService_ListComments_specificIssue(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/issues/1/comments", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testHeader(t, r, "Accept", mediaTypeReactionsPreview)
fmt.Fprint(w, `[{"id":1}]`)
})
comments, _, err := client.Issues.ListComments("o", "r", 1, nil)
if err != nil {
t.Errorf("Issues.ListComments returned error: %v", err)
}
want := []*IssueComment{{ID: Int(1)}}
if !reflect.DeepEqual(comments, want) {
t.Errorf("Issues.ListComments returned %+v, want %+v", comments, want)
}
}
func TestIssuesService_ListComments_invalidOwner(t *testing.T) {
_, _, err := client.Issues.ListComments("%", "r", 1, nil)
testURLParseError(t, err)
}
func TestIssuesService_GetComment(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/issues/comments/1", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testHeader(t, r, "Accept", mediaTypeReactionsPreview)
fmt.Fprint(w, `{"id":1}`)
})
comment, _, err := client.Issues.GetComment("o", "r", 1)
if err != nil {
t.Errorf("Issues.GetComment returned error: %v", err)
}
want := &IssueComment{ID: Int(1)}
if !reflect.DeepEqual(comment, want) {
t.Errorf("Issues.GetComment returned %+v, want %+v", comment, want)
}
}
func TestIssuesService_GetComment_invalidOrg(t *testing.T) {
_, _, err := client.Issues.GetComment("%", "r", 1)
testURLParseError(t, err)
}
func TestIssuesService_CreateComment(t *testing.T) {
setup()
defer teardown()
input := &IssueComment{Body: String("b")}
mux.HandleFunc("/repos/o/r/issues/1/comments", func(w http.ResponseWriter, r *http.Request) {
v := new(IssueComment)
json.NewDecoder(r.Body).Decode(v)
testMethod(t, r, "POST")
if !reflect.DeepEqual(v, input) {
t.Errorf("Request body = %+v, want %+v", v, input)
}
fmt.Fprint(w, `{"id":1}`)
})
comment, _, err := client.Issues.CreateComment("o", "r", 1, input)
if err != nil {
t.Errorf("Issues.CreateComment returned error: %v", err)
}
want := &IssueComment{ID: Int(1)}
if !reflect.DeepEqual(comment, want) {
t.Errorf("Issues.CreateComment returned %+v, want %+v", comment, want)
}
}
func TestIssuesService_CreateComment_invalidOrg(t *testing.T) {
_, _, err := client.Issues.CreateComment("%", "r", 1, nil)
testURLParseError(t, err)
}
func TestIssuesService_EditComment(t *testing.T) {
setup()
defer teardown()
input := &IssueComment{Body: String("b")}
mux.HandleFunc("/repos/o/r/issues/comments/1", func(w http.ResponseWriter, r *http.Request) {
v := new(IssueComment)
json.NewDecoder(r.Body).Decode(v)
testMethod(t, r, "PATCH")
if !reflect.DeepEqual(v, input) {
t.Errorf("Request body = %+v, want %+v", v, input)
}
fmt.Fprint(w, `{"id":1}`)
})
comment, _, err := client.Issues.EditComment("o", "r", 1, input)
if err != nil {
t.Errorf("Issues.EditComment returned error: %v", err)
}
want := &IssueComment{ID: Int(1)}
if !reflect.DeepEqual(comment, want) {
t.Errorf("Issues.EditComment returned %+v, want %+v", comment, want)
}
}
func TestIssuesService_EditComment_invalidOwner(t *testing.T) {
_, _, err := client.Issues.EditComment("%", "r", 1, nil)
testURLParseError(t, err)
}
func TestIssuesService_DeleteComment(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/issues/comments/1", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "DELETE")
})
_, err := client.Issues.DeleteComment("o", "r", 1)
if err != nil {
t.Errorf("Issues.DeleteComments returned error: %v", err)
}
}
func TestIssuesService_DeleteComment_invalidOwner(t *testing.T) {
_, err := client.Issues.DeleteComment("%", "r", 1)
testURLParseError(t, err)
}

149
vendor/src/github.com/google/go-github/github/issues_events.go

@ -0,0 +1,149 @@
// Copyright 2014 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github
import (
"fmt"
"time"
)
// IssueEvent represents an event that occurred around an Issue or Pull Request.
type IssueEvent struct {
ID *int `json:"id,omitempty"`
URL *string `json:"url,omitempty"`
// The User that generated this event.
Actor *User `json:"actor,omitempty"`
// Event identifies the actual type of Event that occurred. Possible
// values are:
//
// closed
// The Actor closed the issue.
// If the issue was closed by commit message, CommitID holds the SHA1 hash of the commit.
//
// merged
// The Actor merged into master a branch containing a commit mentioning the issue.
// CommitID holds the SHA1 of the merge commit.
//
// referenced
// The Actor committed to master a commit mentioning the issue in its commit message.
// CommitID holds the SHA1 of the commit.
//
// reopened, locked, unlocked
// The Actor did that to the issue.
//
// renamed
// The Actor changed the issue title from Rename.From to Rename.To.
//
// mentioned
// Someone unspecified @mentioned the Actor [sic] in an issue comment body.
//
// assigned, unassigned
// The Actor assigned the issue to or removed the assignment from the Assignee.
//
// labeled, unlabeled
// The Actor added or removed the Label from the issue.
//
// milestoned, demilestoned
// The Actor added or removed the issue from the Milestone.
//
// subscribed, unsubscribed
// The Actor subscribed to or unsubscribed from notifications for an issue.
//
// head_ref_deleted, head_ref_restored
// The pull request’s branch was deleted or restored.
//
Event *string `json:"event,omitempty"`
CreatedAt *time.Time `json:"created_at,omitempty"`
Issue *Issue `json:"issue,omitempty"`
// Only present on certain events; see above.
Assignee *User `json:"assignee,omitempty"`
CommitID *string `json:"commit_id,omitempty"`
Milestone *Milestone `json:"milestone,omitempty"`
Label *Label `json:"label,omitempty"`
Rename *Rename `json:"rename,omitempty"`
}
// ListIssueEvents lists events for the specified issue.
//
// GitHub API docs: https://developer.github.com/v3/issues/events/#list-events-for-an-issue
func (s *IssuesService) ListIssueEvents(owner, repo string, number int, opt *ListOptions) ([]*IssueEvent, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/issues/%v/events", owner, repo, number)
u, err := addOptions(u, opt)
if err != nil {
return nil, nil, err
}
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
var events []*IssueEvent
resp, err := s.client.Do(req, &events)
if err != nil {
return nil, resp, err
}
return events, resp, err
}
// ListRepositoryEvents lists events for the specified repository.
//
// GitHub API docs: https://developer.github.com/v3/issues/events/#list-events-for-a-repository
func (s *IssuesService) ListRepositoryEvents(owner, repo string, opt *ListOptions) ([]*IssueEvent, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/issues/events", owner, repo)
u, err := addOptions(u, opt)
if err != nil {
return nil, nil, err
}
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
var events []*IssueEvent
resp, err := s.client.Do(req, &events)
if err != nil {
return nil, resp, err
}
return events, resp, err
}
// GetEvent returns the specified issue event.
//
// GitHub API docs: https://developer.github.com/v3/issues/events/#get-a-single-event
func (s *IssuesService) GetEvent(owner, repo string, id int) (*IssueEvent, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/issues/events/%v", owner, repo, id)
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
event := new(IssueEvent)
resp, err := s.client.Do(req, event)
if err != nil {
return nil, resp, err
}
return event, resp, err
}
// Rename contains details for 'renamed' events.
type Rename struct {
From *string `json:"from,omitempty"`
To *string `json:"to,omitempty"`
}
func (r Rename) String() string {
return Stringify(r)
}

83
vendor/src/github.com/google/go-github/github/issues_events_test.go

@ -0,0 +1,83 @@
// Copyright 2014 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github
import (
"fmt"
"net/http"
"reflect"
"testing"
)
func TestIssuesService_ListIssueEvents(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/issues/1/events", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testFormValues(t, r, values{
"page": "1",
"per_page": "2",
})
fmt.Fprint(w, `[{"id":1}]`)
})
opt := &ListOptions{Page: 1, PerPage: 2}
events, _, err := client.Issues.ListIssueEvents("o", "r", 1, opt)
if err != nil {
t.Errorf("Issues.ListIssueEvents returned error: %v", err)
}
want := []*IssueEvent{{ID: Int(1)}}
if !reflect.DeepEqual(events, want) {
t.Errorf("Issues.ListIssueEvents returned %+v, want %+v", events, want)
}
}
func TestIssuesService_ListRepositoryEvents(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/issues/events", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testFormValues(t, r, values{
"page": "1",
"per_page": "2",
})
fmt.Fprint(w, `[{"id":1}]`)
})
opt := &ListOptions{Page: 1, PerPage: 2}
events, _, err := client.Issues.ListRepositoryEvents("o", "r", opt)
if err != nil {
t.Errorf("Issues.ListRepositoryEvents returned error: %v", err)
}
want := []*IssueEvent{{ID: Int(1)}}
if !reflect.DeepEqual(events, want) {
t.Errorf("Issues.ListRepositoryEvents returned %+v, want %+v", events, want)
}
}
func TestIssuesService_GetEvent(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/issues/events/1", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
fmt.Fprint(w, `{"id":1}`)
})
event, _, err := client.Issues.GetEvent("o", "r", 1)
if err != nil {
t.Errorf("Issues.GetEvent returned error: %v", err)
}
want := &IssueEvent{ID: Int(1)}
if !reflect.DeepEqual(event, want) {
t.Errorf("Issues.GetEvent returned %+v, want %+v", event, want)
}
}

222
vendor/src/github.com/google/go-github/github/issues_labels.go

@ -0,0 +1,222 @@
// Copyright 2013 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github
import "fmt"
// Label represents a GitHub label on an Issue
type Label struct {
URL *string `json:"url,omitempty"`
Name *string `json:"name,omitempty"`
Color *string `json:"color,omitempty"`
}
func (l Label) String() string {
return fmt.Sprint(*l.Name)
}
// ListLabels lists all labels for a repository.
//
// GitHub API docs: http://developer.github.com/v3/issues/labels/#list-all-labels-for-this-repository
func (s *IssuesService) ListLabels(owner string, repo string, opt *ListOptions) ([]*Label, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/labels", owner, repo)
u, err := addOptions(u, opt)
if err != nil {
return nil, nil, err
}
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
labels := new([]*Label)
resp, err := s.client.Do(req, labels)
if err != nil {
return nil, resp, err
}
return *labels, resp, err
}
// GetLabel gets a single label.
//
// GitHub API docs: http://developer.github.com/v3/issues/labels/#get-a-single-label
func (s *IssuesService) GetLabel(owner string, repo string, name string) (*Label, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/labels/%v", owner, repo, name)
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
label := new(Label)
resp, err := s.client.Do(req, label)
if err != nil {
return nil, resp, err
}
return label, resp, err
}
// CreateLabel creates a new label on the specified repository.
//
// GitHub API docs: http://developer.github.com/v3/issues/labels/#create-a-label
func (s *IssuesService) CreateLabel(owner string, repo string, label *Label) (*Label, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/labels", owner, repo)
req, err := s.client.NewRequest("POST", u, label)
if err != nil {
return nil, nil, err
}
l := new(Label)
resp, err := s.client.Do(req, l)
if err != nil {
return nil, resp, err
}
return l, resp, err
}
// EditLabel edits a label.
//
// GitHub API docs: http://developer.github.com/v3/issues/labels/#update-a-label
func (s *IssuesService) EditLabel(owner string, repo string, name string, label *Label) (*Label, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/labels/%v", owner, repo, name)
req, err := s.client.NewRequest("PATCH", u, label)
if err != nil {
return nil, nil, err
}
l := new(Label)
resp, err := s.client.Do(req, l)
if err != nil {
return nil, resp, err
}
return l, resp, err
}
// DeleteLabel deletes a label.
//
// GitHub API docs: http://developer.github.com/v3/issues/labels/#delete-a-label
func (s *IssuesService) DeleteLabel(owner string, repo string, name string) (*Response, error) {
u := fmt.Sprintf("repos/%v/%v/labels/%v", owner, repo, name)
req, err := s.client.NewRequest("DELETE", u, nil)
if err != nil {
return nil, err
}
return s.client.Do(req, nil)
}
// ListLabelsByIssue lists all labels for an issue.
//
// GitHub API docs: http://developer.github.com/v3/issues/labels/#list-all-labels-for-this-repository
func (s *IssuesService) ListLabelsByIssue(owner string, repo string, number int, opt *ListOptions) ([]*Label, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/issues/%d/labels", owner, repo, number)
u, err := addOptions(u, opt)
if err != nil {
return nil, nil, err
}
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
labels := new([]*Label)
resp, err := s.client.Do(req, labels)
if err != nil {
return nil, resp, err
}
return *labels, resp, err
}
// AddLabelsToIssue adds labels to an issue.
//
// GitHub API docs: http://developer.github.com/v3/issues/labels/#list-all-labels-for-this-repository
func (s *IssuesService) AddLabelsToIssue(owner string, repo string, number int, labels []string) ([]*Label, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/issues/%d/labels", owner, repo, number)
req, err := s.client.NewRequest("POST", u, labels)
if err != nil {
return nil, nil, err
}
l := new([]*Label)
resp, err := s.client.Do(req, l)
if err != nil {
return nil, resp, err
}
return *l, resp, err
}
// RemoveLabelForIssue removes a label for an issue.
//
// GitHub API docs: http://developer.github.com/v3/issues/labels/#remove-a-label-from-an-issue
func (s *IssuesService) RemoveLabelForIssue(owner string, repo string, number int, label string) (*Response, error) {
u := fmt.Sprintf("repos/%v/%v/issues/%d/labels/%v", owner, repo, number, label)
req, err := s.client.NewRequest("DELETE", u, nil)
if err != nil {
return nil, err
}
return s.client.Do(req, nil)
}
// ReplaceLabelsForIssue replaces all labels for an issue.
//
// GitHub API docs: http://developer.github.com/v3/issues/labels/#replace-all-labels-for-an-issue
func (s *IssuesService) ReplaceLabelsForIssue(owner string, repo string, number int, labels []string) ([]*Label, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/issues/%d/labels", owner, repo, number)
req, err := s.client.NewRequest("PUT", u, labels)
if err != nil {
return nil, nil, err
}
l := new([]*Label)
resp, err := s.client.Do(req, l)
if err != nil {
return nil, resp, err
}
return *l, resp, err
}
// RemoveLabelsForIssue removes all labels for an issue.
//
// GitHub API docs: http://developer.github.com/v3/issues/labels/#remove-all-labels-from-an-issue
func (s *IssuesService) RemoveLabelsForIssue(owner string, repo string, number int) (*Response, error) {
u := fmt.Sprintf("repos/%v/%v/issues/%d/labels", owner, repo, number)
req, err := s.client.NewRequest("DELETE", u, nil)
if err != nil {
return nil, err
}
return s.client.Do(req, nil)
}
// ListLabelsForMilestone lists labels for every issue in a milestone.
//
// GitHub API docs: http://developer.github.com/v3/issues/labels/#get-labels-for-every-issue-in-a-milestone
func (s *IssuesService) ListLabelsForMilestone(owner string, repo string, number int, opt *ListOptions) ([]*Label, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/milestones/%d/labels", owner, repo, number)
u, err := addOptions(u, opt)
if err != nil {
return nil, nil, err
}
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
labels := new([]*Label)
resp, err := s.client.Do(req, labels)
if err != nil {
return nil, resp, err
}
return *labels, resp, err
}

313
vendor/src/github.com/google/go-github/github/issues_labels_test.go

@ -0,0 +1,313 @@
// Copyright 2013 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github
import (
"encoding/json"
"fmt"
"net/http"
"reflect"
"testing"
)
func TestIssuesService_ListLabels(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/labels", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testFormValues(t, r, values{"page": "2"})
fmt.Fprint(w, `[{"name": "a"},{"name": "b"}]`)
})
opt := &ListOptions{Page: 2}
labels, _, err := client.Issues.ListLabels("o", "r", opt)
if err != nil {
t.Errorf("Issues.ListLabels returned error: %v", err)
}
want := []*Label{{Name: String("a")}, {Name: String("b")}}
if !reflect.DeepEqual(labels, want) {
t.Errorf("Issues.ListLabels returned %+v, want %+v", labels, want)
}
}
func TestIssuesService_ListLabels_invalidOwner(t *testing.T) {
_, _, err := client.Issues.ListLabels("%", "%", nil)
testURLParseError(t, err)
}
func TestIssuesService_GetLabel(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/labels/n", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
fmt.Fprint(w, `{"url":"u", "name": "n", "color": "c"}`)
})
label, _, err := client.Issues.GetLabel("o", "r", "n")
if err != nil {
t.Errorf("Issues.GetLabel returned error: %v", err)
}
want := &Label{URL: String("u"), Name: String("n"), Color: String("c")}
if !reflect.DeepEqual(label, want) {
t.Errorf("Issues.GetLabel returned %+v, want %+v", label, want)
}
}
func TestIssuesService_GetLabel_invalidOwner(t *testing.T) {
_, _, err := client.Issues.GetLabel("%", "%", "%")
testURLParseError(t, err)
}
func TestIssuesService_CreateLabel(t *testing.T) {
setup()
defer teardown()
input := &Label{Name: String("n")}
mux.HandleFunc("/repos/o/r/labels", func(w http.ResponseWriter, r *http.Request) {
v := new(Label)
json.NewDecoder(r.Body).Decode(v)
testMethod(t, r, "POST")
if !reflect.DeepEqual(v, input) {
t.Errorf("Request body = %+v, want %+v", v, input)
}
fmt.Fprint(w, `{"url":"u"}`)
})
label, _, err := client.Issues.CreateLabel("o", "r", input)
if err != nil {
t.Errorf("Issues.CreateLabel returned error: %v", err)
}
want := &Label{URL: String("u")}
if !reflect.DeepEqual(label, want) {
t.Errorf("Issues.CreateLabel returned %+v, want %+v", label, want)
}
}
func TestIssuesService_CreateLabel_invalidOwner(t *testing.T) {
_, _, err := client.Issues.CreateLabel("%", "%", nil)
testURLParseError(t, err)
}
func TestIssuesService_EditLabel(t *testing.T) {
setup()
defer teardown()
input := &Label{Name: String("z")}
mux.HandleFunc("/repos/o/r/labels/n", func(w http.ResponseWriter, r *http.Request) {
v := new(Label)
json.NewDecoder(r.Body).Decode(v)
testMethod(t, r, "PATCH")
if !reflect.DeepEqual(v, input) {
t.Errorf("Request body = %+v, want %+v", v, input)
}
fmt.Fprint(w, `{"url":"u"}`)
})
label, _, err := client.Issues.EditLabel("o", "r", "n", input)
if err != nil {
t.Errorf("Issues.EditLabel returned error: %v", err)
}
want := &Label{URL: String("u")}
if !reflect.DeepEqual(label, want) {
t.Errorf("Issues.EditLabel returned %+v, want %+v", label, want)
}
}
func TestIssuesService_EditLabel_invalidOwner(t *testing.T) {
_, _, err := client.Issues.EditLabel("%", "%", "%", nil)
testURLParseError(t, err)
}
func TestIssuesService_DeleteLabel(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/labels/n", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "DELETE")
})
_, err := client.Issues.DeleteLabel("o", "r", "n")
if err != nil {
t.Errorf("Issues.DeleteLabel returned error: %v", err)
}
}
func TestIssuesService_DeleteLabel_invalidOwner(t *testing.T) {
_, err := client.Issues.DeleteLabel("%", "%", "%")
testURLParseError(t, err)
}
func TestIssuesService_ListLabelsByIssue(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/issues/1/labels", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testFormValues(t, r, values{"page": "2"})
fmt.Fprint(w, `[{"name": "a"},{"name": "b"}]`)
})
opt := &ListOptions{Page: 2}
labels, _, err := client.Issues.ListLabelsByIssue("o", "r", 1, opt)
if err != nil {
t.Errorf("Issues.ListLabelsByIssue returned error: %v", err)
}
want := []*Label{{Name: String("a")}, {Name: String("b")}}
if !reflect.DeepEqual(labels, want) {
t.Errorf("Issues.ListLabelsByIssue returned %+v, want %+v", labels, want)
}
}
func TestIssuesService_ListLabelsByIssue_invalidOwner(t *testing.T) {
_, _, err := client.Issues.ListLabelsByIssue("%", "%", 1, nil)
testURLParseError(t, err)
}
func TestIssuesService_AddLabelsToIssue(t *testing.T) {
setup()
defer teardown()
input := []string{"a", "b"}
mux.HandleFunc("/repos/o/r/issues/1/labels", func(w http.ResponseWriter, r *http.Request) {
v := new([]string)
json.NewDecoder(r.Body).Decode(v)
testMethod(t, r, "POST")
if !reflect.DeepEqual(*v, input) {
t.Errorf("Request body = %+v, want %+v", v, input)
}
fmt.Fprint(w, `[{"url":"u"}]`)
})
labels, _, err := client.Issues.AddLabelsToIssue("o", "r", 1, input)
if err != nil {
t.Errorf("Issues.AddLabelsToIssue returned error: %v", err)
}
want := []*Label{{URL: String("u")}}
if !reflect.DeepEqual(labels, want) {
t.Errorf("Issues.AddLabelsToIssue returned %+v, want %+v", labels, want)
}
}
func TestIssuesService_AddLabelsToIssue_invalidOwner(t *testing.T) {
_, _, err := client.Issues.AddLabelsToIssue("%", "%", 1, nil)
testURLParseError(t, err)
}
func TestIssuesService_RemoveLabelForIssue(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/issues/1/labels/l", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "DELETE")
})
_, err := client.Issues.RemoveLabelForIssue("o", "r", 1, "l")
if err != nil {
t.Errorf("Issues.RemoveLabelForIssue returned error: %v", err)
}
}
func TestIssuesService_RemoveLabelForIssue_invalidOwner(t *testing.T) {
_, err := client.Issues.RemoveLabelForIssue("%", "%", 1, "%")
testURLParseError(t, err)
}
func TestIssuesService_ReplaceLabelsForIssue(t *testing.T) {
setup()
defer teardown()
input := []string{"a", "b"}
mux.HandleFunc("/repos/o/r/issues/1/labels", func(w http.ResponseWriter, r *http.Request) {
v := new([]string)
json.NewDecoder(r.Body).Decode(v)
testMethod(t, r, "PUT")
if !reflect.DeepEqual(*v, input) {
t.Errorf("Request body = %+v, want %+v", v, input)
}
fmt.Fprint(w, `[{"url":"u"}]`)
})
labels, _, err := client.Issues.ReplaceLabelsForIssue("o", "r", 1, input)
if err != nil {
t.Errorf("Issues.ReplaceLabelsForIssue returned error: %v", err)
}
want := []*Label{{URL: String("u")}}
if !reflect.DeepEqual(labels, want) {
t.Errorf("Issues.ReplaceLabelsForIssue returned %+v, want %+v", labels, want)
}
}
func TestIssuesService_ReplaceLabelsForIssue_invalidOwner(t *testing.T) {
_, _, err := client.Issues.ReplaceLabelsForIssue("%", "%", 1, nil)
testURLParseError(t, err)
}
func TestIssuesService_RemoveLabelsForIssue(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/issues/1/labels", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "DELETE")
})
_, err := client.Issues.RemoveLabelsForIssue("o", "r", 1)
if err != nil {
t.Errorf("Issues.RemoveLabelsForIssue returned error: %v", err)
}
}
func TestIssuesService_RemoveLabelsForIssue_invalidOwner(t *testing.T) {
_, err := client.Issues.RemoveLabelsForIssue("%", "%", 1)
testURLParseError(t, err)
}
func TestIssuesService_ListLabelsForMilestone(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/milestones/1/labels", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testFormValues(t, r, values{"page": "2"})
fmt.Fprint(w, `[{"name": "a"},{"name": "b"}]`)
})
opt := &ListOptions{Page: 2}
labels, _, err := client.Issues.ListLabelsForMilestone("o", "r", 1, opt)
if err != nil {
t.Errorf("Issues.ListLabelsForMilestone returned error: %v", err)
}
want := []*Label{{Name: String("a")}, {Name: String("b")}}
if !reflect.DeepEqual(labels, want) {
t.Errorf("Issues.ListLabelsForMilestone returned %+v, want %+v", labels, want)
}
}
func TestIssuesService_ListLabelsForMilestone_invalidOwner(t *testing.T) {
_, _, err := client.Issues.ListLabelsForMilestone("%", "%", 1, nil)
testURLParseError(t, err)
}

146
vendor/src/github.com/google/go-github/github/issues_milestones.go

@ -0,0 +1,146 @@
// Copyright 2014 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github
import (
"fmt"
"time"
)
// Milestone represents a Github repository milestone.
type Milestone struct {
URL *string `json:"url,omitempty"`
HTMLURL *string `json:"html_url,omitempty"`
LabelsURL *string `json:"labels_url,omitempty"`
ID *int `json:"id,omitempty"`
Number *int `json:"number,omitempty"`
State *string `json:"state,omitempty"`
Title *string `json:"title,omitempty"`
Description *string `json:"description,omitempty"`
Creator *User `json:"creator,omitempty"`
OpenIssues *int `json:"open_issues,omitempty"`
ClosedIssues *int `json:"closed_issues,omitempty"`
CreatedAt *time.Time `json:"created_at,omitempty"`
UpdatedAt *time.Time `json:"updated_at,omitempty"`
ClosedAt *time.Time `json:"closed_at,omitempty"`
DueOn *time.Time `json:"due_on,omitempty"`
}
func (m Milestone) String() string {
return Stringify(m)
}
// MilestoneListOptions specifies the optional parameters to the
// IssuesService.ListMilestones method.
type MilestoneListOptions struct {
// State filters milestones based on their state. Possible values are:
// open, closed. Default is "open".
State string `url:"state,omitempty"`
// Sort specifies how to sort milestones. Possible values are: due_date, completeness.
// Default value is "due_date".
Sort string `url:"sort,omitempty"`
// Direction in which to sort milestones. Possible values are: asc, desc.
// Default is "asc".
Direction string `url:"direction,omitempty"`
ListOptions
}
// ListMilestones lists all milestones for a repository.
//
// GitHub API docs: https://developer.github.com/v3/issues/milestones/#list-milestones-for-a-repository
func (s *IssuesService) ListMilestones(owner string, repo string, opt *MilestoneListOptions) ([]*Milestone, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/milestones", owner, repo)
u, err := addOptions(u, opt)
if err != nil {
return nil, nil, err
}
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
milestones := new([]*Milestone)
resp, err := s.client.Do(req, milestones)
if err != nil {
return nil, resp, err
}
return *milestones, resp, err
}
// GetMilestone gets a single milestone.
//
// GitHub API docs: https://developer.github.com/v3/issues/milestones/#get-a-single-milestone
func (s *IssuesService) GetMilestone(owner string, repo string, number int) (*Milestone, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/milestones/%d", owner, repo, number)
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
milestone := new(Milestone)
resp, err := s.client.Do(req, milestone)
if err != nil {
return nil, resp, err
}
return milestone, resp, err
}
// CreateMilestone creates a new milestone on the specified repository.
//
// GitHub API docs: https://developer.github.com/v3/issues/milestones/#create-a-milestone
func (s *IssuesService) CreateMilestone(owner string, repo string, milestone *Milestone) (*Milestone, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/milestones", owner, repo)
req, err := s.client.NewRequest("POST", u, milestone)
if err != nil {
return nil, nil, err
}
m := new(Milestone)
resp, err := s.client.Do(req, m)
if err != nil {
return nil, resp, err
}
return m, resp, err
}
// EditMilestone edits a milestone.
//
// GitHub API docs: https://developer.github.com/v3/issues/milestones/#update-a-milestone
func (s *IssuesService) EditMilestone(owner string, repo string, number int, milestone *Milestone) (*Milestone, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/milestones/%d", owner, repo, number)
req, err := s.client.NewRequest("PATCH", u, milestone)
if err != nil {
return nil, nil, err
}
m := new(Milestone)
resp, err := s.client.Do(req, m)
if err != nil {
return nil, resp, err
}
return m, resp, err
}
// DeleteMilestone deletes a milestone.
//
// GitHub API docs: https://developer.github.com/v3/issues/milestones/#delete-a-milestone
func (s *IssuesService) DeleteMilestone(owner string, repo string, number int) (*Response, error) {
u := fmt.Sprintf("repos/%v/%v/milestones/%d", owner, repo, number)
req, err := s.client.NewRequest("DELETE", u, nil)
if err != nil {
return nil, err
}
return s.client.Do(req, nil)
}

158
vendor/src/github.com/google/go-github/github/issues_milestones_test.go

@ -0,0 +1,158 @@
// Copyright 2014 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github
import (
"encoding/json"
"fmt"
"net/http"
"reflect"
"testing"
)
func TestIssuesService_ListMilestones(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/milestones", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testFormValues(t, r, values{
"state": "closed",
"sort": "due_date",
"direction": "asc",
"page": "2",
})
fmt.Fprint(w, `[{"number":1}]`)
})
opt := &MilestoneListOptions{"closed", "due_date", "asc", ListOptions{Page: 2}}
milestones, _, err := client.Issues.ListMilestones("o", "r", opt)
if err != nil {
t.Errorf("IssuesService.ListMilestones returned error: %v", err)
}
want := []*Milestone{{Number: Int(1)}}
if !reflect.DeepEqual(milestones, want) {
t.Errorf("IssuesService.ListMilestones returned %+v, want %+v", milestones, want)
}
}
func TestIssuesService_ListMilestones_invalidOwner(t *testing.T) {
_, _, err := client.Issues.ListMilestones("%", "r", nil)
testURLParseError(t, err)
}
func TestIssuesService_GetMilestone(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/milestones/1", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
fmt.Fprint(w, `{"number":1}`)
})
milestone, _, err := client.Issues.GetMilestone("o", "r", 1)
if err != nil {
t.Errorf("IssuesService.GetMilestone returned error: %v", err)
}
want := &Milestone{Number: Int(1)}
if !reflect.DeepEqual(milestone, want) {
t.Errorf("IssuesService.GetMilestone returned %+v, want %+v", milestone, want)
}
}
func TestIssuesService_GetMilestone_invalidOwner(t *testing.T) {
_, _, err := client.Issues.GetMilestone("%", "r", 1)
testURLParseError(t, err)
}
func TestIssuesService_CreateMilestone(t *testing.T) {
setup()
defer teardown()
input := &Milestone{Title: String("t")}
mux.HandleFunc("/repos/o/r/milestones", func(w http.ResponseWriter, r *http.Request) {
v := new(Milestone)
json.NewDecoder(r.Body).Decode(v)
testMethod(t, r, "POST")
if !reflect.DeepEqual(v, input) {
t.Errorf("Request body = %+v, want %+v", v, input)
}
fmt.Fprint(w, `{"number":1}`)
})
milestone, _, err := client.Issues.CreateMilestone("o", "r", input)
if err != nil {
t.Errorf("IssuesService.CreateMilestone returned error: %v", err)
}
want := &Milestone{Number: Int(1)}
if !reflect.DeepEqual(milestone, want) {
t.Errorf("IssuesService.CreateMilestone returned %+v, want %+v", milestone, want)
}
}
func TestIssuesService_CreateMilestone_invalidOwner(t *testing.T) {
_, _, err := client.Issues.CreateMilestone("%", "r", nil)
testURLParseError(t, err)
}
func TestIssuesService_EditMilestone(t *testing.T) {
setup()
defer teardown()
input := &Milestone{Title: String("t")}
mux.HandleFunc("/repos/o/r/milestones/1", func(w http.ResponseWriter, r *http.Request) {
v := new(Milestone)
json.NewDecoder(r.Body).Decode(v)
testMethod(t, r, "PATCH")
if !reflect.DeepEqual(v, input) {
t.Errorf("Request body = %+v, want %+v", v, input)
}
fmt.Fprint(w, `{"number":1}`)
})
milestone, _, err := client.Issues.EditMilestone("o", "r", 1, input)
if err != nil {
t.Errorf("IssuesService.EditMilestone returned error: %v", err)
}
want := &Milestone{Number: Int(1)}
if !reflect.DeepEqual(milestone, want) {
t.Errorf("IssuesService.EditMilestone returned %+v, want %+v", milestone, want)
}
}
func TestIssuesService_EditMilestone_invalidOwner(t *testing.T) {
_, _, err := client.Issues.EditMilestone("%", "r", 1, nil)
testURLParseError(t, err)
}
func TestIssuesService_DeleteMilestone(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/milestones/1", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "DELETE")
})
_, err := client.Issues.DeleteMilestone("o", "r", 1)
if err != nil {
t.Errorf("IssuesService.DeleteMilestone returned error: %v", err)
}
}
func TestIssuesService_DeleteMilestone_invalidOwner(t *testing.T) {
_, err := client.Issues.DeleteMilestone("%", "r", 1)
testURLParseError(t, err)
}

276
vendor/src/github.com/google/go-github/github/issues_test.go

@ -0,0 +1,276 @@
// Copyright 2013 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github
import (
"encoding/json"
"fmt"
"net/http"
"reflect"
"testing"
"time"
)
func TestIssuesService_List_all(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/issues", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testHeader(t, r, "Accept", mediaTypeReactionsPreview)
testFormValues(t, r, values{
"filter": "all",
"state": "closed",
"labels": "a,b",
"sort": "updated",
"direction": "asc",
"since": "2002-02-10T15:30:00Z",
"page": "1",
"per_page": "2",
})
fmt.Fprint(w, `[{"number":1}]`)
})
opt := &IssueListOptions{
"all", "closed", []string{"a", "b"}, "updated", "asc",
time.Date(2002, time.February, 10, 15, 30, 0, 0, time.UTC),
ListOptions{Page: 1, PerPage: 2},
}
issues, _, err := client.Issues.List(true, opt)
if err != nil {
t.Errorf("Issues.List returned error: %v", err)
}
want := []*Issue{{Number: Int(1)}}
if !reflect.DeepEqual(issues, want) {
t.Errorf("Issues.List returned %+v, want %+v", issues, want)
}
}
func TestIssuesService_List_owned(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/user/issues", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testHeader(t, r, "Accept", mediaTypeReactionsPreview)
fmt.Fprint(w, `[{"number":1}]`)
})
issues, _, err := client.Issues.List(false, nil)
if err != nil {
t.Errorf("Issues.List returned error: %v", err)
}
want := []*Issue{{Number: Int(1)}}
if !reflect.DeepEqual(issues, want) {
t.Errorf("Issues.List returned %+v, want %+v", issues, want)
}
}
func TestIssuesService_ListByOrg(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/orgs/o/issues", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testHeader(t, r, "Accept", mediaTypeReactionsPreview)
fmt.Fprint(w, `[{"number":1}]`)
})
issues, _, err := client.Issues.ListByOrg("o", nil)
if err != nil {
t.Errorf("Issues.ListByOrg returned error: %v", err)
}
want := []*Issue{{Number: Int(1)}}
if !reflect.DeepEqual(issues, want) {
t.Errorf("Issues.List returned %+v, want %+v", issues, want)
}
}
func TestIssuesService_ListByOrg_invalidOrg(t *testing.T) {
_, _, err := client.Issues.ListByOrg("%", nil)
testURLParseError(t, err)
}
func TestIssuesService_ListByRepo(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/issues", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testHeader(t, r, "Accept", mediaTypeReactionsPreview)
testFormValues(t, r, values{
"milestone": "*",
"state": "closed",
"assignee": "a",
"creator": "c",
"mentioned": "m",
"labels": "a,b",
"sort": "updated",
"direction": "asc",
"since": "2002-02-10T15:30:00Z",
})
fmt.Fprint(w, `[{"number":1}]`)
})
opt := &IssueListByRepoOptions{
"*", "closed", "a", "c", "m", []string{"a", "b"}, "updated", "asc",
time.Date(2002, time.February, 10, 15, 30, 0, 0, time.UTC),
ListOptions{0, 0},
}
issues, _, err := client.Issues.ListByRepo("o", "r", opt)
if err != nil {
t.Errorf("Issues.ListByOrg returned error: %v", err)
}
want := []*Issue{{Number: Int(1)}}
if !reflect.DeepEqual(issues, want) {
t.Errorf("Issues.List returned %+v, want %+v", issues, want)
}
}
func TestIssuesService_ListByRepo_invalidOwner(t *testing.T) {
_, _, err := client.Issues.ListByRepo("%", "r", nil)
testURLParseError(t, err)
}
func TestIssuesService_Get(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/issues/1", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testHeader(t, r, "Accept", mediaTypeReactionsPreview)
fmt.Fprint(w, `{"number":1, "labels": [{"url": "u", "name": "n", "color": "c"}]}`)
})
issue, _, err := client.Issues.Get("o", "r", 1)
if err != nil {
t.Errorf("Issues.Get returned error: %v", err)
}
want := &Issue{
Number: Int(1),
Labels: []Label{{
URL: String("u"),
Name: String("n"),
Color: String("c"),
}},
}
if !reflect.DeepEqual(issue, want) {
t.Errorf("Issues.Get returned %+v, want %+v", issue, want)
}
}
func TestIssuesService_Get_invalidOwner(t *testing.T) {
_, _, err := client.Issues.Get("%", "r", 1)
testURLParseError(t, err)
}
func TestIssuesService_Create(t *testing.T) {
setup()
defer teardown()
input := &IssueRequest{
Title: String("t"),
Body: String("b"),
Assignee: String("a"),
Labels: &[]string{"l1", "l2"},
}
mux.HandleFunc("/repos/o/r/issues", func(w http.ResponseWriter, r *http.Request) {
v := new(IssueRequest)
json.NewDecoder(r.Body).Decode(v)
testMethod(t, r, "POST")
if !reflect.DeepEqual(v, input) {
t.Errorf("Request body = %+v, want %+v", v, input)
}
fmt.Fprint(w, `{"number":1}`)
})
issue, _, err := client.Issues.Create("o", "r", input)
if err != nil {
t.Errorf("Issues.Create returned error: %v", err)
}
want := &Issue{Number: Int(1)}
if !reflect.DeepEqual(issue, want) {
t.Errorf("Issues.Create returned %+v, want %+v", issue, want)
}
}
func TestIssuesService_Create_invalidOwner(t *testing.T) {
_, _, err := client.Issues.Create("%", "r", nil)
testURLParseError(t, err)
}
func TestIssuesService_Edit(t *testing.T) {
setup()
defer teardown()
input := &IssueRequest{Title: String("t")}
mux.HandleFunc("/repos/o/r/issues/1", func(w http.ResponseWriter, r *http.Request) {
v := new(IssueRequest)
json.NewDecoder(r.Body).Decode(v)
testMethod(t, r, "PATCH")
if !reflect.DeepEqual(v, input) {
t.Errorf("Request body = %+v, want %+v", v, input)
}
fmt.Fprint(w, `{"number":1}`)
})
issue, _, err := client.Issues.Edit("o", "r", 1, input)
if err != nil {
t.Errorf("Issues.Edit returned error: %v", err)
}
want := &Issue{Number: Int(1)}
if !reflect.DeepEqual(issue, want) {
t.Errorf("Issues.Edit returned %+v, want %+v", issue, want)
}
}
func TestIssuesService_Edit_invalidOwner(t *testing.T) {
_, _, err := client.Issues.Edit("%", "r", 1, nil)
testURLParseError(t, err)
}
func TestIssuesService_Lock(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/issues/1/lock", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "PUT")
w.WriteHeader(http.StatusNoContent)
})
if _, err := client.Issues.Lock("o", "r", 1); err != nil {
t.Errorf("Issues.Lock returned error: %v", err)
}
}
func TestIssuesService_Unlock(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/issues/1/lock", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "DELETE")
w.WriteHeader(http.StatusNoContent)
})
if _, err := client.Issues.Unlock("o", "r", 1); err != nil {
t.Errorf("Issues.Unlock returned error: %v", err)
}
}

148
vendor/src/github.com/google/go-github/github/issues_timeline.go

@ -0,0 +1,148 @@
// Copyright 2016 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github
import (
"fmt"
"time"
)
// Timeline represents an event that occurred around an Issue or Pull Request.
//
// It is similar to an IssueEvent but may contain more information.
// GitHub API docs: https://developer.github.com/v3/issues/timeline/
type Timeline struct {
ID *int `json:"id,omitempty"`
URL *string `json:"url,omitempty"`
CommitURL *string `json:"commit_url,omitempty"`
// The User object that generated the event.
Actor *User `json:"actor,omitempty"`
// Event identifies the actual type of Event that occurred. Possible values
// are:
//
// assigned
// The issue was assigned to the assignee.
//
// closed
// The issue was closed by the actor. When the commit_id is present, it
// identifies the commit that closed the issue using "closes / fixes #NN"
// syntax.
//
// commented
// A comment was added to the issue.
//
// committed
// A commit was added to the pull request's 'HEAD' branch. Only provided
// for pull requests.
//
// cross-referenced
// The issue was referenced from another issue. The 'source' attribute
// contains the 'id', 'actor', and 'url' of the reference's source.
//
// demilestoned
// The issue was removed from a milestone.
//
// head_ref_deleted
// The pull request's branch was deleted.
//
// head_ref_restored
// The pull request's branch was restored.
//
// labeled
// A label was added to the issue.
//
// locked
// The issue was locked by the actor.
//
// mentioned
// The actor was @mentioned in an issue body.
//
// merged
// The issue was merged by the actor. The 'commit_id' attribute is the
// SHA1 of the HEAD commit that was merged.
//
// milestoned
// The issue was added to a milestone.
//
// referenced
// The issue was referenced from a commit message. The 'commit_id'
// attribute is the commit SHA1 of where that happened.
//
// renamed
// The issue title was changed.
//
// reopened
// The issue was reopened by the actor.
//
// subscribed
// The actor subscribed to receive notifications for an issue.
//
// unassigned
// The assignee was unassigned from the issue.
//
// unlabeled
// A label was removed from the issue.
//
// unlocked
// The issue was unlocked by the actor.
//
// unsubscribed
// The actor unsubscribed to stop receiving notifications for an issue.
//
Event *string `json:"event,omitempty"`
// The string SHA of a commit that referenced this Issue or Pull Request.
CommitID *string `json:"commit_id,omitempty"`
// The timestamp indicating when the event occurred.
CreatedAt *time.Time `json:"created_at,omitempty"`
// The Label object including `name` and `color` attributes. Only provided for
// 'labeled' and 'unlabeled' events.
Label *Label `json:"label,omitempty"`
// The User object which was assigned to (or unassigned from) this Issue or
// Pull Request. Only provided for 'assigned' and 'unassigned' events.
Assignee *User `json:"assignee,omitempty"`
// The Milestone object including a 'title' attribute.
// Only provided for 'milestoned' and 'demilestoned' events.
Milestone *Milestone `json:"milestone,omitempty"`
// The 'id', 'actor', and 'url' for the source of a reference from another issue.
// Only provided for 'cross-referenced' events.
Source *Source `json:"source,omitempty"`
// An object containing rename details including 'from' and 'to' attributes.
// Only provided for 'renamed' events.
Rename *Rename `json:"rename,omitempty"`
}
// Source represents a reference's source.
type Source struct {
ID *int `json:"id,omitempty"`
URL *string `json:"url,omitempty"`
Actor *User `json:"actor,omitempty"`
}
// ListIssueTimeline lists events for the specified issue.
//
// GitHub API docs: https://developer.github.com/v3/issues/timeline/#list-events-for-an-issue
func (s *IssuesService) ListIssueTimeline(owner, repo string, number int, opt *ListOptions) ([]*Timeline, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/issues/%v/timeline", owner, repo, number)
u, err := addOptions(u, opt)
if err != nil {
return nil, nil, err
}
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
// TODO: remove custom Accept header when this API fully launches.
req.Header.Set("Accept", mediaTypeTimelinePreview)
var events []*Timeline
resp, err := s.client.Do(req, &events)
return events, resp, err
}

39
vendor/src/github.com/google/go-github/github/issues_timeline_test.go

@ -0,0 +1,39 @@
// Copyright 2016 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github
import (
"fmt"
"net/http"
"reflect"
"testing"
)
func TestIssuesService_ListIssueTimeline(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/issues/1/timeline", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testHeader(t, r, "Accept", mediaTypeTimelinePreview)
testFormValues(t, r, values{
"page": "1",
"per_page": "2",
})
fmt.Fprint(w, `[{"id":1}]`)
})
opt := &ListOptions{Page: 1, PerPage: 2}
events, _, err := client.Issues.ListIssueTimeline("o", "r", 1, opt)
if err != nil {
t.Errorf("Issues.ListIssueTimeline returned error: %v", err)
}
want := []*Timeline{{ID: Int(1)}}
if !reflect.DeepEqual(events, want) {
t.Errorf("Issues.ListIssueTimeline = %+v, want %+v", events, want)
}
}

79
vendor/src/github.com/google/go-github/github/licenses.go

@ -0,0 +1,79 @@
// Copyright 2013 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github
import "fmt"
// LicensesService handles communication with the license related
// methods of the GitHub API.
//
// GitHub API docs: http://developer.github.com/v3/pulls/
type LicensesService service
// License represents an open source license.
type License struct {
Key *string `json:"key,omitempty"`
Name *string `json:"name,omitempty"`
URL *string `json:"url,omitempty"`
HTMLURL *string `json:"html_url,omitempty"`
Featured *bool `json:"featured,omitempty"`
Description *string `json:"description,omitempty"`
Category *string `json:"category,omitempty"`
Implementation *string `json:"implementation,omitempty"`
Required *[]string `json:"required,omitempty"`
Permitted *[]string `json:"permitted,omitempty"`
Forbidden *[]string `json:"forbidden,omitempty"`
Body *string `json:"body,omitempty"`
}
func (l License) String() string {
return Stringify(l)
}
// List popular open source licenses.
//
// GitHub API docs: https://developer.github.com/v3/licenses/#list-all-licenses
func (s *LicensesService) List() ([]*License, *Response, error) {
req, err := s.client.NewRequest("GET", "licenses", nil)
if err != nil {
return nil, nil, err
}
// TODO: remove custom Accept header when this API fully launches
req.Header.Set("Accept", mediaTypeLicensesPreview)
licenses := new([]*License)
resp, err := s.client.Do(req, licenses)
if err != nil {
return nil, resp, err
}
return *licenses, resp, err
}
// Get extended metadata for one license.
//
// GitHub API docs: https://developer.github.com/v3/licenses/#get-an-individual-license
func (s *LicensesService) Get(licenseName string) (*License, *Response, error) {
u := fmt.Sprintf("licenses/%s", licenseName)
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
// TODO: remove custom Accept header when this API fully launches
req.Header.Set("Accept", mediaTypeLicensesPreview)
license := new(License)
resp, err := s.client.Do(req, license)
if err != nil {
return nil, resp, err
}
return license, resp, err
}

64
vendor/src/github.com/google/go-github/github/licenses_test.go

@ -0,0 +1,64 @@
// Copyright 2013 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github
import (
"fmt"
"net/http"
"reflect"
"testing"
)
func TestLicensesService_List(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/licenses", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testHeader(t, r, "Accept", mediaTypeLicensesPreview)
fmt.Fprint(w, `[{"key":"mit","name":"MIT","url":"https://api.github.com/licenses/mit"}]`)
})
licenses, _, err := client.Licenses.List()
if err != nil {
t.Errorf("Licenses.List returned error: %v", err)
}
want := []*License{{
Key: String("mit"),
Name: String("MIT"),
URL: String("https://api.github.com/licenses/mit"),
}}
if !reflect.DeepEqual(licenses, want) {
t.Errorf("Licenses.List returned %+v, want %+v", licenses, want)
}
}
func TestLicensesService_Get(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/licenses/mit", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testHeader(t, r, "Accept", mediaTypeLicensesPreview)
fmt.Fprint(w, `{"key":"mit","name":"MIT"}`)
})
license, _, err := client.Licenses.Get("mit")
if err != nil {
t.Errorf("Licenses.Get returned error: %v", err)
}
want := &License{Key: String("mit"), Name: String("MIT")}
if !reflect.DeepEqual(license, want) {
t.Errorf("Licenses.Get returned %+v, want %+v", license, want)
}
}
func TestLicensesService_Get_invalidTemplate(t *testing.T) {
_, _, err := client.Licenses.Get("%")
testURLParseError(t, err)
}

119
vendor/src/github.com/google/go-github/github/messages.go

@ -0,0 +1,119 @@
// Copyright 2016 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// This file provides functions for validating payloads from GitHub Webhooks.
// GitHub docs: https://developer.github.com/webhooks/securing/#validating-payloads-from-github
package github
import (
"crypto/hmac"
"crypto/sha1"
"crypto/sha256"
"crypto/sha512"
"encoding/hex"
"errors"
"fmt"
"hash"
"io/ioutil"
"net/http"
"strings"
)
const (
// sha1Prefix is the prefix used by GitHub before the HMAC hexdigest.
sha1Prefix = "sha1"
// sha256Prefix and sha512Prefix are provided for future compatibility.
sha256Prefix = "sha256"
sha512Prefix = "sha512"
// signatureHeader is the GitHub header key used to pass the HMAC hexdigest.
signatureHeader = "X-Hub-Signature"
)
// genMAC generates the HMAC signature for a message provided the secret key
// and hashFunc.
func genMAC(message, key []byte, hashFunc func() hash.Hash) []byte {
mac := hmac.New(hashFunc, key)
mac.Write(message)
return mac.Sum(nil)
}
// checkMAC reports whether messageMAC is a valid HMAC tag for message.
func checkMAC(message, messageMAC, key []byte, hashFunc func() hash.Hash) bool {
expectedMAC := genMAC(message, key, hashFunc)
return hmac.Equal(messageMAC, expectedMAC)
}
// messageMAC returns the hex-decoded HMAC tag from the signature and its
// corresponding hash function.
func messageMAC(signature string) ([]byte, func() hash.Hash, error) {
if signature == "" {
return nil, nil, errors.New("missing signature")
}
sigParts := strings.SplitN(signature, "=", 2)
if len(sigParts) != 2 {
return nil, nil, fmt.Errorf("error parsing signature %q", signature)
}
var hashFunc func() hash.Hash
switch sigParts[0] {
case sha1Prefix:
hashFunc = sha1.New
case sha256Prefix:
hashFunc = sha256.New
case sha512Prefix:
hashFunc = sha512.New
default:
return nil, nil, fmt.Errorf("unknown hash type prefix: %q", sigParts[0])
}
buf, err := hex.DecodeString(sigParts[1])
if err != nil {
return nil, nil, fmt.Errorf("error decoding signature %q: %v", signature, err)
}
return buf, hashFunc, nil
}
// ValidatePayload validates an incoming GitHub Webhook event request
// and returns the (JSON) payload.
// secretKey is the GitHub Webhook secret message.
//
// Example usage:
//
// func (s *GitHubEventMonitor) ServeHTTP(w http.ResponseWriter, r *http.Request) {
// payload, err := github.ValidatePayload(r, s.webhookSecretKey)
// if err != nil { ... }
// // Process payload...
// }
//
func ValidatePayload(r *http.Request, secretKey []byte) (payload []byte, err error) {
payload, err = ioutil.ReadAll(r.Body)
if err != nil {
return nil, err
}
sig := r.Header.Get(signatureHeader)
if err := validateSignature(sig, payload, secretKey); err != nil {
return nil, err
}
return payload, nil
}
// validateSignature validates the signature for the given payload.
// signature is the GitHub hash signature delivered in the X-Hub-Signature header.
// payload is the JSON payload sent by GitHub Webhooks.
// secretKey is the GitHub Webhook secret message.
//
// GitHub docs: https://developer.github.com/webhooks/securing/#validating-payloads-from-github
func validateSignature(signature string, payload, secretKey []byte) error {
messageMAC, hashFunc, err := messageMAC(signature)
if err != nil {
return err
}
if !checkMAC(payload, messageMAC, secretKey, hashFunc) {
return errors.New("payload signature check failed")
}
return nil
}

81
vendor/src/github.com/google/go-github/github/messages_test.go

@ -0,0 +1,81 @@
// Copyright 2016 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github
import (
"bytes"
"net/http"
"testing"
)
func TestValidatePayload(t *testing.T) {
const defaultBody = `{"yo":true}` // All tests below use the default request body and signature.
const defaultSignature = "sha1=126f2c800419c60137ce748d7672e77b65cf16d6"
secretKey := []byte("0123456789abcdef")
tests := []struct {
signature string
eventID string
event string
wantEventID string
wantEvent string
wantPayload string
}{
// The following tests generate expected errors:
{}, // Missing signature
{signature: "yo"}, // Missing signature prefix
{signature: "sha1=yo"}, // Signature not hex string
{signature: "sha1=012345"}, // Invalid signature
// The following tests expect err=nil:
{
signature: defaultSignature,
eventID: "dead-beef",
event: "ping",
wantEventID: "dead-beef",
wantEvent: "ping",
wantPayload: defaultBody,
},
{
signature: defaultSignature,
event: "ping",
wantEvent: "ping",
wantPayload: defaultBody,
},
{
signature: "sha256=b1f8020f5b4cd42042f807dd939015c4a418bc1ff7f604dd55b0a19b5d953d9b",
event: "ping",
wantEvent: "ping",
wantPayload: defaultBody,
},
{
signature: "sha512=8456767023c1195682e182a23b3f5d19150ecea598fde8cb85918f7281b16079471b1329f92b912c4d8bd7455cb159777db8f29608b20c7c87323ba65ae62e1f",
event: "ping",
wantEvent: "ping",
wantPayload: defaultBody,
},
}
for _, test := range tests {
buf := bytes.NewBufferString(defaultBody)
req, err := http.NewRequest("GET", "http://localhost/event", buf)
if err != nil {
t.Fatalf("NewRequest: %v", err)
}
if test.signature != "" {
req.Header.Set(signatureHeader, test.signature)
}
got, err := ValidatePayload(req, secretKey)
if err != nil {
if test.wantPayload != "" {
t.Errorf("ValidatePayload(%#v): err = %v, want nil", test, err)
}
continue
}
if string(got) != test.wantPayload {
t.Errorf("ValidatePayload = %q, want %q", got, test.wantPayload)
}
}
}

223
vendor/src/github.com/google/go-github/github/migrations.go

@ -0,0 +1,223 @@
// Copyright 2016 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github
import (
"errors"
"fmt"
"net/http"
"strings"
)
// MigrationService provides access to the migration related functions
// in the GitHub API.
//
// GitHub API docs: https://developer.github.com/v3/migration/
type MigrationService service
// Migration represents a GitHub migration (archival).
type Migration struct {
ID *int `json:"id,omitempty"`
GUID *string `json:"guid,omitempty"`
// State is the current state of a migration.
// Possible values are:
// "pending" which means the migration hasn't started yet,
// "exporting" which means the migration is in progress,
// "exported" which means the migration finished successfully, or
// "failed" which means the migration failed.
State *string `json:"state,omitempty"`
// LockRepositories indicates whether repositories are locked (to prevent
// manipulation) while migrating data.
LockRepositories *bool `json:"lock_repositories,omitempty"`
// ExcludeAttachments indicates whether attachments should be excluded from
// the migration (to reduce migration archive file size).
ExcludeAttachments *bool `json:"exclude_attachments,omitempty"`
URL *string `json:"url,omitempty"`
CreatedAt *string `json:"created_at,omitempty"`
UpdatedAt *string `json:"updated_at,omitempty"`
Repositories []*Repository `json:"repositories,omitempty"`
}
func (m Migration) String() string {
return Stringify(m)
}
// MigrationOptions specifies the optional parameters to Migration methods.
type MigrationOptions struct {
// LockRepositories indicates whether repositories should be locked (to prevent
// manipulation) while migrating data.
LockRepositories bool
// ExcludeAttachments indicates whether attachments should be excluded from
// the migration (to reduce migration archive file size).
ExcludeAttachments bool
}
// startMigration represents the body of a StartMigration request.
type startMigration struct {
// Repositories is a slice of repository names to migrate.
Repositories []string `json:"repositories,omitempty"`
// LockRepositories indicates whether repositories should be locked (to prevent
// manipulation) while migrating data.
LockRepositories *bool `json:"lock_repositories,omitempty"`
// ExcludeAttachments indicates whether attachments should be excluded from
// the migration (to reduce migration archive file size).
ExcludeAttachments *bool `json:"exclude_attachments,omitempty"`
}
// StartMigration starts the generation of a migration archive.
// repos is a slice of repository names to migrate.
//
// GitHub API docs: https://developer.github.com/v3/migration/migrations/#start-a-migration
func (s *MigrationService) StartMigration(org string, repos []string, opt *MigrationOptions) (*Migration, *Response, error) {
u := fmt.Sprintf("orgs/%v/migrations", org)
body := &startMigration{Repositories: repos}
if opt != nil {
body.LockRepositories = Bool(opt.LockRepositories)
body.ExcludeAttachments = Bool(opt.ExcludeAttachments)
}
req, err := s.client.NewRequest("POST", u, body)
if err != nil {
return nil, nil, err
}
// TODO: remove custom Accept header when this API fully launches.
req.Header.Set("Accept", mediaTypeMigrationsPreview)
m := &Migration{}
resp, err := s.client.Do(req, m)
if err != nil {
return nil, resp, err
}
return m, resp, nil
}
// ListMigrations lists the most recent migrations.
//
// GitHub API docs: https://developer.github.com/v3/migration/migrations/#get-a-list-of-migrations
func (s *MigrationService) ListMigrations(org string) ([]*Migration, *Response, error) {
u := fmt.Sprintf("orgs/%v/migrations", org)
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
// TODO: remove custom Accept header when this API fully launches.
req.Header.Set("Accept", mediaTypeMigrationsPreview)
var m []*Migration
resp, err := s.client.Do(req, &m)
if err != nil {
return nil, resp, err
}
return m, resp, nil
}
// MigrationStatus gets the status of a specific migration archive.
// id is the migration ID.
//
// GitHub API docs: https://developer.github.com/v3/migration/migrations/#get-the-status-of-a-migration
func (s *MigrationService) MigrationStatus(org string, id int) (*Migration, *Response, error) {
u := fmt.Sprintf("orgs/%v/migrations/%v", org, id)
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
// TODO: remove custom Accept header when this API fully launches.
req.Header.Set("Accept", mediaTypeMigrationsPreview)
m := &Migration{}
resp, err := s.client.Do(req, m)
if err != nil {
return nil, resp, err
}
return m, resp, nil
}
// MigrationArchiveURL fetches a migration archive URL.
// id is the migration ID.
//
// GitHub API docs: https://developer.github.com/v3/migration/migrations/#download-a-migration-archive
func (s *MigrationService) MigrationArchiveURL(org string, id int) (url string, err error) {
u := fmt.Sprintf("orgs/%v/migrations/%v/archive", org, id)
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return "", err
}
// TODO: remove custom Accept header when this API fully launches.
req.Header.Set("Accept", mediaTypeMigrationsPreview)
s.client.clientMu.Lock()
defer s.client.clientMu.Unlock()
// Disable the redirect mechanism because AWS fails if the GitHub auth token is provided.
var loc string
saveRedirect := s.client.client.CheckRedirect
s.client.client.CheckRedirect = func(req *http.Request, via []*http.Request) error {
loc = req.URL.String()
return errors.New("disable redirect")
}
defer func() { s.client.client.CheckRedirect = saveRedirect }()
_, err = s.client.Do(req, nil) // expect error from disable redirect
if err == nil {
return "", errors.New("expected redirect, none provided")
}
if !strings.Contains(err.Error(), "disable redirect") {
return "", err
}
return loc, nil
}
// DeleteMigration deletes a previous migration archive.
// id is the migration ID.
//
// GitHub API docs: https://developer.github.com/v3/migration/migrations/#delete-a-migration-archive
func (s *MigrationService) DeleteMigration(org string, id int) (*Response, error) {
u := fmt.Sprintf("orgs/%v/migrations/%v/archive", org, id)
req, err := s.client.NewRequest("DELETE", u, nil)
if err != nil {
return nil, err
}
// TODO: remove custom Accept header when this API fully launches.
req.Header.Set("Accept", mediaTypeMigrationsPreview)
return s.client.Do(req, nil)
}
// UnlockRepo unlocks a repository that was locked for migration.
// id is the migration ID.
// You should unlock each migrated repository and delete them when the migration
// is complete and you no longer need the source data.
//
// GitHub API docs: https://developer.github.com/v3/migration/migrations/#unlock-a-repository
func (s *MigrationService) UnlockRepo(org string, id int, repo string) (*Response, error) {
u := fmt.Sprintf("orgs/%v/migrations/%v/repos/%v/lock", org, id, repo)
req, err := s.client.NewRequest("DELETE", u, nil)
if err != nil {
return nil, err
}
// TODO: remove custom Accept header when this API fully launches.
req.Header.Set("Accept", mediaTypeMigrationsPreview)
return s.client.Do(req, nil)
}

326
vendor/src/github.com/google/go-github/github/migrations_source_import.go

@ -0,0 +1,326 @@
// Copyright 2016 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github
import "fmt"
// Import represents a repository import request.
type Import struct {
// The URL of the originating repository.
VCSURL *string `json:"vcs_url,omitempty"`
// The originating VCS type. Can be one of 'subversion', 'git',
// 'mercurial', or 'tfvc'. Without this parameter, the import job will
// take additional time to detect the VCS type before beginning the
// import. This detection step will be reflected in the response.
VCS *string `json:"vcs,omitempty"`
// VCSUsername and VCSPassword are only used for StartImport calls that
// are importing a password-protected repository.
VCSUsername *string `json:"vcs_username,omitempty"`
VCSPassword *string `json:"vcs_password,omitempty"`
// For a tfvc import, the name of the project that is being imported.
TFVCProject *string `json:"tfvc_project,omitempty"`
// LFS related fields that may be preset in the Import Progress response
// Describes whether the import has been opted in or out of using Git
// LFS. The value can be 'opt_in', 'opt_out', or 'undecided' if no
// action has been taken.
UseLFS *string `json:"use_lfs,omitempty"`
// Describes whether files larger than 100MB were found during the
// importing step.
HasLargeFiles *bool `json:"has_large_files,omitempty"`
// The total size in gigabytes of files larger than 100MB found in the
// originating repository.
LargeFilesSize *int `json:"large_files_size,omitempty"`
// The total number of files larger than 100MB found in the originating
// repository. To see a list of these files, call LargeFiles.
LargeFilesCount *int `json:"large_files_count,omitempty"`
// Identifies the current status of an import. An import that does not
// have errors will progress through these steps:
//
// detecting - the "detection" step of the import is in progress
// because the request did not include a VCS parameter. The
// import is identifying the type of source control present at
// the URL.
// importing - the "raw" step of the import is in progress. This is
// where commit data is fetched from the original repository.
// The import progress response will include CommitCount (the
// total number of raw commits that will be imported) and
// Percent (0 - 100, the current progress through the import).
// mapping - the "rewrite" step of the import is in progress. This
// is where SVN branches are converted to Git branches, and
// where author updates are applied. The import progress
// response does not include progress information.
// pushing - the "push" step of the import is in progress. This is
// where the importer updates the repository on GitHub. The
// import progress response will include PushPercent, which is
// the percent value reported by git push when it is "Writing
// objects".
// complete - the import is complete, and the repository is ready
// on GitHub.
//
// If there are problems, you will see one of these in the status field:
//
// auth_failed - the import requires authentication in order to
// connect to the original repository. Make an UpdateImport
// request, and include VCSUsername and VCSPassword.
// error - the import encountered an error. The import progress
// response will include the FailedStep and an error message.
// Contact GitHub support for more information.
// detection_needs_auth - the importer requires authentication for
// the originating repository to continue detection. Make an
// UpdatImport request, and include VCSUsername and
// VCSPassword.
// detection_found_nothing - the importer didn't recognize any
// source control at the URL.
// detection_found_multiple - the importer found several projects
// or repositories at the provided URL. When this is the case,
// the Import Progress response will also include a
// ProjectChoices field with the possible project choices as
// values. Make an UpdateImport request, and include VCS and
// (if applicable) TFVCProject.
Status *string `json:"status,omitempty"`
CommitCount *int `json:"commit_count,omitempty"`
StatusText *string `json:"status_text,omitempty"`
AuthorsCount *int `json:"authors_count,omitempty"`
Percent *int `json:"percent,omitempty"`
PushPercent *int `json:"push_percent,omitempty"`
URL *string `json:"url,omitempty"`
HTMLURL *string `json:"html_url,omitempty"`
AuthorsURL *string `json:"authors_url,omitempty"`
RepositoryURL *string `json:"repository_url,omitempty"`
Message *string `json:"message,omitempty"`
FailedStep *string `json:"failed_step,omitempty"`
// Human readable display name, provided when the Import appears as
// part of ProjectChoices.
HumanName *string `json:"human_name,omitempty"`
// When the importer finds several projects or repositories at the
// provided URLs, this will identify the available choices. Call
// UpdateImport with the selected Import value.
ProjectChoices []Import `json:"project_choices,omitempty"`
}
func (i Import) String() string {
return Stringify(i)
}
// SourceImportAuthor identifies an author imported from a source repository.
//
// GitHub API docs: https://developer.github.com/v3/migration/source_imports/#get-commit-authors
type SourceImportAuthor struct {
ID *int `json:"id,omitempty"`
RemoteID *string `json:"remote_id,omitempty"`
RemoteName *string `json:"remote_name,omitempty"`
Email *string `json:"email,omitempty"`
Name *string `json:"name,omitempty"`
URL *string `json:"url,omitempty"`
ImportURL *string `json:"import_url,omitempty"`
}
func (a SourceImportAuthor) String() string {
return Stringify(a)
}
// LargeFile identifies a file larger than 100MB found during a repository import.
//
// GitHub API docs: https://developer.github.com/v3/migration/source_imports/#get-large-files
type LargeFile struct {
RefName *string `json:"ref_name,omitempty"`
Path *string `json:"path,omitempty"`
OID *string `json:"oid,omitempty"`
Size *int `json:"size,omitempty"`
}
func (f LargeFile) String() string {
return Stringify(f)
}
// StartImport initiates a repository import.
//
// GitHub API docs: https://developer.github.com/v3/migration/source_imports/#start-an-import
func (s *MigrationService) StartImport(owner, repo string, in *Import) (*Import, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/import", owner, repo)
req, err := s.client.NewRequest("PUT", u, in)
if err != nil {
return nil, nil, err
}
// TODO: remove custom Accept header when this API fully launches
req.Header.Set("Accept", mediaTypeImportPreview)
out := new(Import)
resp, err := s.client.Do(req, out)
if err != nil {
return nil, resp, err
}
return out, resp, err
}
// QueryImport queries for the status and progress of an ongoing repository import.
//
// GitHub API docs: https://developer.github.com/v3/migration/source_imports/#get-import-progress
func (s *MigrationService) ImportProgress(owner, repo string) (*Import, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/import", owner, repo)
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
// TODO: remove custom Accept header when this API fully launches
req.Header.Set("Accept", mediaTypeImportPreview)
out := new(Import)
resp, err := s.client.Do(req, out)
if err != nil {
return nil, resp, err
}
return out, resp, err
}
// UpdateImport initiates a repository import.
//
// GitHub API docs: https://developer.github.com/v3/migration/source_imports/#update-existing-import
func (s *MigrationService) UpdateImport(owner, repo string, in *Import) (*Import, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/import", owner, repo)
req, err := s.client.NewRequest("PATCH", u, in)
if err != nil {
return nil, nil, err
}
// TODO: remove custom Accept header when this API fully launches
req.Header.Set("Accept", mediaTypeImportPreview)
out := new(Import)
resp, err := s.client.Do(req, out)
if err != nil {
return nil, resp, err
}
return out, resp, err
}
// CommitAuthors gets the authors mapped from the original repository.
//
// Each type of source control system represents authors in a different way.
// For example, a Git commit author has a display name and an email address,
// but a Subversion commit author just has a username. The GitHub Importer will
// make the author information valid, but the author might not be correct. For
// example, it will change the bare Subversion username "hubot" into something
// like "hubot <hubot@12341234-abab-fefe-8787-fedcba987654>".
//
// This method and MapCommitAuthor allow you to provide correct Git author
// information.
//
// GitHub API docs: https://developer.github.com/v3/migration/source_imports/#get-commit-authors
func (s *MigrationService) CommitAuthors(owner, repo string) ([]*SourceImportAuthor, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/import/authors", owner, repo)
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
// TODO: remove custom Accept header when this API fully launches
req.Header.Set("Accept", mediaTypeImportPreview)
authors := new([]*SourceImportAuthor)
resp, err := s.client.Do(req, authors)
if err != nil {
return nil, resp, err
}
return *authors, resp, err
}
// MapCommitAuthor updates an author's identity for the import. Your
// application can continue updating authors any time before you push new
// commits to the repository.
//
// GitHub API docs: https://developer.github.com/v3/migration/source_imports/#map-a-commit-author
func (s *MigrationService) MapCommitAuthor(owner, repo string, id int, author *SourceImportAuthor) (*SourceImportAuthor, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/import/authors/%v", owner, repo, id)
req, err := s.client.NewRequest("PATCH", u, author)
if err != nil {
return nil, nil, err
}
// TODO: remove custom Accept header when this API fully launches
req.Header.Set("Accept", mediaTypeImportPreview)
out := new(SourceImportAuthor)
resp, err := s.client.Do(req, out)
if err != nil {
return nil, resp, err
}
return out, resp, err
}
// SetLFSPreference sets whether imported repositories should use Git LFS for
// files larger than 100MB. Only the UseLFS field on the provided Import is
// used.
//
// GitHub API docs: https://developer.github.com/v3/migration/source_imports/#set-git-lfs-preference
func (s *MigrationService) SetLFSPreference(owner, repo string, in *Import) (*Import, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/import/lfs", owner, repo)
req, err := s.client.NewRequest("PATCH", u, in)
if err != nil {
return nil, nil, err
}
// TODO: remove custom Accept header when this API fully launches
req.Header.Set("Accept", mediaTypeImportPreview)
out := new(Import)
resp, err := s.client.Do(req, out)
if err != nil {
return nil, resp, err
}
return out, resp, err
}
// LargeFiles lists files larger than 100MB found during the import.
//
// GitHub API docs: https://developer.github.com/v3/migration/source_imports/#get-large-files
func (s *MigrationService) LargeFiles(owner, repo string) ([]*LargeFile, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/import/large_files", owner, repo)
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
// TODO: remove custom Accept header when this API fully launches
req.Header.Set("Accept", mediaTypeImportPreview)
files := new([]*LargeFile)
resp, err := s.client.Do(req, files)
if err != nil {
return nil, resp, err
}
return *files, resp, err
}
// CancelImport stops an import for a repository.
//
// GitHub API docs: https://developer.github.com/v3/migration/source_imports/#cancel-an-import
func (s *MigrationService) CancelImport(owner, repo string) (*Response, error) {
u := fmt.Sprintf("repos/%v/%v/import", owner, repo)
req, err := s.client.NewRequest("DELETE", u, nil)
if err != nil {
return nil, err
}
// TODO: remove custom Accept header when this API fully launches
req.Header.Set("Accept", mediaTypeImportPreview)
return s.client.Do(req, nil)
}

225
vendor/src/github.com/google/go-github/github/migrations_source_import_test.go

@ -0,0 +1,225 @@
// Copyright 2016 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github
import (
"encoding/json"
"fmt"
"net/http"
"reflect"
"testing"
)
func TestMigrationService_StartImport(t *testing.T) {
setup()
defer teardown()
input := &Import{
VCS: String("git"),
VCSURL: String("url"),
VCSUsername: String("u"),
VCSPassword: String("p"),
}
mux.HandleFunc("/repos/o/r/import", func(w http.ResponseWriter, r *http.Request) {
v := new(Import)
json.NewDecoder(r.Body).Decode(v)
testMethod(t, r, "PUT")
testHeader(t, r, "Accept", mediaTypeImportPreview)
if !reflect.DeepEqual(v, input) {
t.Errorf("Request body = %+v, want %+v", v, input)
}
w.WriteHeader(http.StatusCreated)
fmt.Fprint(w, `{"status":"importing"}`)
})
got, _, err := client.Migrations.StartImport("o", "r", input)
if err != nil {
t.Errorf("StartImport returned error: %v", err)
}
want := &Import{Status: String("importing")}
if !reflect.DeepEqual(got, want) {
t.Errorf("StartImport = %+v, want %+v", got, want)
}
}
func TestMigrationService_ImportProgress(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/import", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testHeader(t, r, "Accept", mediaTypeImportPreview)
fmt.Fprint(w, `{"status":"complete"}`)
})
got, _, err := client.Migrations.ImportProgress("o", "r")
if err != nil {
t.Errorf("ImportProgress returned error: %v", err)
}
want := &Import{Status: String("complete")}
if !reflect.DeepEqual(got, want) {
t.Errorf("ImportProgress = %+v, want %+v", got, want)
}
}
func TestMigrationService_UpdateImport(t *testing.T) {
setup()
defer teardown()
input := &Import{
VCS: String("git"),
VCSURL: String("url"),
VCSUsername: String("u"),
VCSPassword: String("p"),
}
mux.HandleFunc("/repos/o/r/import", func(w http.ResponseWriter, r *http.Request) {
v := new(Import)
json.NewDecoder(r.Body).Decode(v)
testMethod(t, r, "PATCH")
testHeader(t, r, "Accept", mediaTypeImportPreview)
if !reflect.DeepEqual(v, input) {
t.Errorf("Request body = %+v, want %+v", v, input)
}
w.WriteHeader(http.StatusCreated)
fmt.Fprint(w, `{"status":"importing"}`)
})
got, _, err := client.Migrations.UpdateImport("o", "r", input)
if err != nil {
t.Errorf("UpdateImport returned error: %v", err)
}
want := &Import{Status: String("importing")}
if !reflect.DeepEqual(got, want) {
t.Errorf("UpdateImport = %+v, want %+v", got, want)
}
}
func TestMigrationService_CommitAuthors(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/import/authors", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testHeader(t, r, "Accept", mediaTypeImportPreview)
fmt.Fprint(w, `[{"id":1,"name":"a"},{"id":2,"name":"b"}]`)
})
got, _, err := client.Migrations.CommitAuthors("o", "r")
if err != nil {
t.Errorf("CommitAuthors returned error: %v", err)
}
want := []*SourceImportAuthor{
{ID: Int(1), Name: String("a")},
{ID: Int(2), Name: String("b")},
}
if !reflect.DeepEqual(got, want) {
t.Errorf("CommitAuthors = %+v, want %+v", got, want)
}
}
func TestMigrationService_MapCommitAuthor(t *testing.T) {
setup()
defer teardown()
input := &SourceImportAuthor{Name: String("n"), Email: String("e")}
mux.HandleFunc("/repos/o/r/import/authors/1", func(w http.ResponseWriter, r *http.Request) {
v := new(SourceImportAuthor)
json.NewDecoder(r.Body).Decode(v)
testMethod(t, r, "PATCH")
testHeader(t, r, "Accept", mediaTypeImportPreview)
if !reflect.DeepEqual(v, input) {
t.Errorf("Request body = %+v, want %+v", v, input)
}
fmt.Fprint(w, `{"id": 1}`)
})
got, _, err := client.Migrations.MapCommitAuthor("o", "r", 1, input)
if err != nil {
t.Errorf("MapCommitAuthor returned error: %v", err)
}
want := &SourceImportAuthor{ID: Int(1)}
if !reflect.DeepEqual(got, want) {
t.Errorf("MapCommitAuthor = %+v, want %+v", got, want)
}
}
func TestMigrationService_SetLFSPreference(t *testing.T) {
setup()
defer teardown()
input := &Import{UseLFS: String("opt_in")}
mux.HandleFunc("/repos/o/r/import/lfs", func(w http.ResponseWriter, r *http.Request) {
v := new(Import)
json.NewDecoder(r.Body).Decode(v)
testMethod(t, r, "PATCH")
testHeader(t, r, "Accept", mediaTypeImportPreview)
if !reflect.DeepEqual(v, input) {
t.Errorf("Request body = %+v, want %+v", v, input)
}
w.WriteHeader(http.StatusCreated)
fmt.Fprint(w, `{"status":"importing"}`)
})
got, _, err := client.Migrations.SetLFSPreference("o", "r", input)
if err != nil {
t.Errorf("SetLFSPreference returned error: %v", err)
}
want := &Import{Status: String("importing")}
if !reflect.DeepEqual(got, want) {
t.Errorf("SetLFSPreference = %+v, want %+v", got, want)
}
}
func TestMigrationService_LargeFiles(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/import/large_files", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testHeader(t, r, "Accept", mediaTypeImportPreview)
fmt.Fprint(w, `[{"oid":"a"},{"oid":"b"}]`)
})
got, _, err := client.Migrations.LargeFiles("o", "r")
if err != nil {
t.Errorf("LargeFiles returned error: %v", err)
}
want := []*LargeFile{
{OID: String("a")},
{OID: String("b")},
}
if !reflect.DeepEqual(got, want) {
t.Errorf("LargeFiles = %+v, want %+v", got, want)
}
}
func TestMigrationService_CancelImport(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/import", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "DELETE")
testHeader(t, r, "Accept", mediaTypeImportPreview)
w.WriteHeader(http.StatusNoContent)
})
_, err := client.Migrations.CancelImport("o", "r")
if err != nil {
t.Errorf("CancelImport returned error: %v", err)
}
}

177
vendor/src/github.com/google/go-github/github/migrations_test.go

@ -0,0 +1,177 @@
// Copyright 2016 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github
import (
"fmt"
"net/http"
"reflect"
"strings"
"testing"
)
func TestMigrationService_StartMigration(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/orgs/o/migrations", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "POST")
testHeader(t, r, "Accept", mediaTypeMigrationsPreview)
w.WriteHeader(http.StatusCreated)
w.Write(migrationJSON)
})
opt := &MigrationOptions{
LockRepositories: true,
ExcludeAttachments: false,
}
got, _, err := client.Migrations.StartMigration("o", []string{"r"}, opt)
if err != nil {
t.Errorf("StartMigration returned error: %v", err)
}
if want := wantMigration; !reflect.DeepEqual(got, want) {
t.Errorf("StartMigration = %+v, want %+v", got, want)
}
}
func TestMigrationService_ListMigrations(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/orgs/o/migrations", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testHeader(t, r, "Accept", mediaTypeMigrationsPreview)
w.WriteHeader(http.StatusOK)
w.Write([]byte(fmt.Sprintf("[%s]", migrationJSON)))
})
got, _, err := client.Migrations.ListMigrations("o")
if err != nil {
t.Errorf("ListMigrations returned error: %v", err)
}
if want := []*Migration{wantMigration}; !reflect.DeepEqual(got, want) {
t.Errorf("ListMigrations = %+v, want %+v", got, want)
}
}
func TestMigrationService_MigrationStatus(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/orgs/o/migrations/1", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testHeader(t, r, "Accept", mediaTypeMigrationsPreview)
w.WriteHeader(http.StatusOK)
w.Write(migrationJSON)
})
got, _, err := client.Migrations.MigrationStatus("o", 1)
if err != nil {
t.Errorf("MigrationStatus returned error: %v", err)
}
if want := wantMigration; !reflect.DeepEqual(got, want) {
t.Errorf("MigrationStatus = %+v, want %+v", got, want)
}
}
func TestMigrationService_MigrationArchiveURL(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/orgs/o/migrations/1/archive", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testHeader(t, r, "Accept", mediaTypeMigrationsPreview)
http.Redirect(w, r, "/yo", http.StatusFound)
})
mux.HandleFunc("/yo", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
w.WriteHeader(http.StatusOK)
w.Write([]byte("0123456789abcdef"))
})
got, err := client.Migrations.MigrationArchiveURL("o", 1)
if err != nil {
t.Errorf("MigrationStatus returned error: %v", err)
}
if want := "/yo"; !strings.HasSuffix(got, want) {
t.Errorf("MigrationArchiveURL = %+v, want %+v", got, want)
}
}
func TestMigrationService_DeleteMigration(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/orgs/o/migrations/1/archive", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "DELETE")
testHeader(t, r, "Accept", mediaTypeMigrationsPreview)
w.WriteHeader(http.StatusNoContent)
})
if _, err := client.Migrations.DeleteMigration("o", 1); err != nil {
t.Errorf("DeleteMigration returned error: %v", err)
}
}
func TestMigrationService_UnlockRepo(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/orgs/o/migrations/1/repos/r/lock", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "DELETE")
testHeader(t, r, "Accept", mediaTypeMigrationsPreview)
w.WriteHeader(http.StatusNoContent)
})
if _, err := client.Migrations.UnlockRepo("o", 1, "r"); err != nil {
t.Errorf("UnlockRepo returned error: %v", err)
}
}
var migrationJSON = []byte(`{
"id": 79,
"guid": "0b989ba4-242f-11e5-81e1-c7b6966d2516",
"state": "pending",
"lock_repositories": true,
"exclude_attachments": false,
"url": "https://api.github.com/orgs/octo-org/migrations/79",
"created_at": "2015-07-06T15:33:38-07:00",
"updated_at": "2015-07-06T15:33:38-07:00",
"repositories": [
{
"id": 1296269,
"name": "Hello-World",
"full_name": "octocat/Hello-World",
"description": "This your first repo!"
}
]
}`)
var wantMigration = &Migration{
ID: Int(79),
GUID: String("0b989ba4-242f-11e5-81e1-c7b6966d2516"),
State: String("pending"),
LockRepositories: Bool(true),
ExcludeAttachments: Bool(false),
URL: String("https://api.github.com/orgs/octo-org/migrations/79"),
CreatedAt: String("2015-07-06T15:33:38-07:00"),
UpdatedAt: String("2015-07-06T15:33:38-07:00"),
Repositories: []*Repository{
{
ID: Int(1296269),
Name: String("Hello-World"),
FullName: String("octocat/Hello-World"),
Description: String("This your first repo!"),
},
},
}

197
vendor/src/github.com/google/go-github/github/misc.go

@ -0,0 +1,197 @@
// Copyright 2014 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github
import (
"bytes"
"fmt"
"net/url"
)
// MarkdownOptions specifies optional parameters to the Markdown method.
type MarkdownOptions struct {
// Mode identifies the rendering mode. Possible values are:
// markdown - render a document as plain Markdown, just like
// README files are rendered.
//
// gfm - to render a document as user-content, e.g. like user
// comments or issues are rendered. In GFM mode, hard line breaks are
// always taken into account, and issue and user mentions are linked
// accordingly.
//
// Default is "markdown".
Mode string
// Context identifies the repository context. Only taken into account
// when rendering as "gfm".
Context string
}
type markdownRequest struct {
Text *string `json:"text,omitempty"`
Mode *string `json:"mode,omitempty"`
Context *string `json:"context,omitempty"`
}
// Markdown renders an arbitrary Markdown document.
//
// GitHub API docs: https://developer.github.com/v3/markdown/
func (c *Client) Markdown(text string, opt *MarkdownOptions) (string, *Response, error) {
request := &markdownRequest{Text: String(text)}
if opt != nil {
if opt.Mode != "" {
request.Mode = String(opt.Mode)
}
if opt.Context != "" {
request.Context = String(opt.Context)
}
}
req, err := c.NewRequest("POST", "markdown", request)
if err != nil {
return "", nil, err
}
buf := new(bytes.Buffer)
resp, err := c.Do(req, buf)
if err != nil {
return "", resp, err
}
return buf.String(), resp, nil
}
// ListEmojis returns the emojis available to use on GitHub.
//
// GitHub API docs: https://developer.github.com/v3/emojis/
func (c *Client) ListEmojis() (map[string]string, *Response, error) {
req, err := c.NewRequest("GET", "emojis", nil)
if err != nil {
return nil, nil, err
}
var emoji map[string]string
resp, err := c.Do(req, &emoji)
if err != nil {
return nil, resp, err
}
return emoji, resp, nil
}
// APIMeta represents metadata about the GitHub API.
type APIMeta struct {
// An Array of IP addresses in CIDR format specifying the addresses
// that incoming service hooks will originate from on GitHub.com.
Hooks []string `json:"hooks,omitempty"`
// An Array of IP addresses in CIDR format specifying the Git servers
// for GitHub.com.
Git []string `json:"git,omitempty"`
// Whether authentication with username and password is supported.
// (GitHub Enterprise instances using CAS or OAuth for authentication
// will return false. Features like Basic Authentication with a
// username and password, sudo mode, and two-factor authentication are
// not supported on these servers.)
VerifiablePasswordAuthentication *bool `json:"verifiable_password_authentication,omitempty"`
// An array of IP addresses in CIDR format specifying the addresses
// which serve GitHub Pages websites.
Pages []string `json:"pages,omitempty"`
}
// APIMeta returns information about GitHub.com, the service. Or, if you access
// this endpoint on your organization’s GitHub Enterprise installation, this
// endpoint provides information about that installation.
//
// GitHub API docs: https://developer.github.com/v3/meta/
func (c *Client) APIMeta() (*APIMeta, *Response, error) {
req, err := c.NewRequest("GET", "meta", nil)
if err != nil {
return nil, nil, err
}
meta := new(APIMeta)
resp, err := c.Do(req, meta)
if err != nil {
return nil, resp, err
}
return meta, resp, nil
}
// Octocat returns an ASCII art octocat with the specified message in a speech
// bubble. If message is empty, a random zen phrase is used.
func (c *Client) Octocat(message string) (string, *Response, error) {
u := "octocat"
if message != "" {
u = fmt.Sprintf("%s?s=%s", u, url.QueryEscape(message))
}
req, err := c.NewRequest("GET", u, nil)
if err != nil {
return "", nil, err
}
buf := new(bytes.Buffer)
resp, err := c.Do(req, buf)
if err != nil {
return "", resp, err
}
return buf.String(), resp, nil
}
// Zen returns a random line from The Zen of GitHub.
//
// see also: http://warpspire.com/posts/taste/
func (c *Client) Zen() (string, *Response, error) {
req, err := c.NewRequest("GET", "zen", nil)
if err != nil {
return "", nil, err
}
buf := new(bytes.Buffer)
resp, err := c.Do(req, buf)
if err != nil {
return "", resp, err
}
return buf.String(), resp, nil
}
// ServiceHook represents a hook that has configuration settings, a list of
// available events, and default events.
type ServiceHook struct {
Name *string `json:"name,omitempty"`
Events []string `json:"events,omitempty"`
SupportedEvents []string `json:"supported_events,omitempty"`
Schema [][]string `json:"schema,omitempty"`
}
func (s *ServiceHook) String() string {
return Stringify(s)
}
// ListServiceHooks lists all of the available service hooks.
//
// GitHub API docs: https://developer.github.com/webhooks/#services
func (c *Client) ListServiceHooks() ([]*ServiceHook, *Response, error) {
u := "hooks"
req, err := c.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
hooks := new([]*ServiceHook)
resp, err := c.Do(req, hooks)
if err != nil {
return nil, resp, err
}
return *hooks, resp, err
}

170
vendor/src/github.com/google/go-github/github/misc_test.go

@ -0,0 +1,170 @@
// Copyright 2014 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github
import (
"encoding/json"
"fmt"
"net/http"
"reflect"
"testing"
)
func TestMarkdown(t *testing.T) {
setup()
defer teardown()
input := &markdownRequest{
Text: String("# text #"),
Mode: String("gfm"),
Context: String("google/go-github"),
}
mux.HandleFunc("/markdown", func(w http.ResponseWriter, r *http.Request) {
v := new(markdownRequest)
json.NewDecoder(r.Body).Decode(v)
testMethod(t, r, "POST")
if !reflect.DeepEqual(v, input) {
t.Errorf("Request body = %+v, want %+v", v, input)
}
fmt.Fprint(w, `<h1>text</h1>`)
})
md, _, err := client.Markdown("# text #", &MarkdownOptions{
Mode: "gfm",
Context: "google/go-github",
})
if err != nil {
t.Errorf("Markdown returned error: %v", err)
}
if want := "<h1>text</h1>"; want != md {
t.Errorf("Markdown returned %+v, want %+v", md, want)
}
}
func TestListEmojis(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/emojis", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
fmt.Fprint(w, `{"+1": "+1.png"}`)
})
emoji, _, err := client.ListEmojis()
if err != nil {
t.Errorf("ListEmojis returned error: %v", err)
}
want := map[string]string{"+1": "+1.png"}
if !reflect.DeepEqual(want, emoji) {
t.Errorf("ListEmojis returned %+v, want %+v", emoji, want)
}
}
func TestAPIMeta(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/meta", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
fmt.Fprint(w, `{"hooks":["h"], "git":["g"], "pages":["p"], "verifiable_password_authentication": true}`)
})
meta, _, err := client.APIMeta()
if err != nil {
t.Errorf("APIMeta returned error: %v", err)
}
want := &APIMeta{
Hooks: []string{"h"},
Git: []string{"g"},
Pages: []string{"p"},
VerifiablePasswordAuthentication: Bool(true),
}
if !reflect.DeepEqual(want, meta) {
t.Errorf("APIMeta returned %+v, want %+v", meta, want)
}
}
func TestOctocat(t *testing.T) {
setup()
defer teardown()
input := "input"
output := "sample text"
mux.HandleFunc("/octocat", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testFormValues(t, r, values{"s": input})
w.Header().Set("Content-Type", "application/octocat-stream")
fmt.Fprint(w, output)
})
got, _, err := client.Octocat(input)
if err != nil {
t.Errorf("Octocat returned error: %v", err)
}
if want := output; got != want {
t.Errorf("Octocat returned %+v, want %+v", got, want)
}
}
func TestZen(t *testing.T) {
setup()
defer teardown()
output := "sample text"
mux.HandleFunc("/zen", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
w.Header().Set("Content-Type", "text/plain;charset=utf-8")
fmt.Fprint(w, output)
})
got, _, err := client.Zen()
if err != nil {
t.Errorf("Zen returned error: %v", err)
}
if want := output; got != want {
t.Errorf("Zen returned %+v, want %+v", got, want)
}
}
func TestRepositoriesService_ListServiceHooks(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/hooks", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
fmt.Fprint(w, `[{
"name":"n",
"events":["e"],
"supported_events":["s"],
"schema":[
["a", "b"]
]
}]`)
})
hooks, _, err := client.Repositories.ListServiceHooks()
if err != nil {
t.Errorf("Repositories.ListHooks returned error: %v", err)
}
want := []*ServiceHook{{
Name: String("n"),
Events: []string{"e"},
SupportedEvents: []string{"s"},
Schema: [][]string{{"a", "b"}},
}}
if !reflect.DeepEqual(hooks, want) {
t.Errorf("Repositories.ListServiceHooks returned %+v, want %+v", hooks, want)
}
}

170
vendor/src/github.com/google/go-github/github/orgs.go

@ -0,0 +1,170 @@
// Copyright 2013 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github
import (
"fmt"
"time"
)
// OrganizationsService provides access to the organization related functions
// in the GitHub API.
//
// GitHub API docs: http://developer.github.com/v3/orgs/
type OrganizationsService service
// Organization represents a GitHub organization account.
type Organization struct {
Login *string `json:"login,omitempty"`
ID *int `json:"id,omitempty"`
AvatarURL *string `json:"avatar_url,omitempty"`
HTMLURL *string `json:"html_url,omitempty"`
Name *string `json:"name,omitempty"`
Company *string `json:"company,omitempty"`
Blog *string `json:"blog,omitempty"`
Location *string `json:"location,omitempty"`
Email *string `json:"email,omitempty"`
PublicRepos *int `json:"public_repos,omitempty"`
PublicGists *int `json:"public_gists,omitempty"`
Followers *int `json:"followers,omitempty"`
Following *int `json:"following,omitempty"`
CreatedAt *time.Time `json:"created_at,omitempty"`
UpdatedAt *time.Time `json:"updated_at,omitempty"`
TotalPrivateRepos *int `json:"total_private_repos,omitempty"`
OwnedPrivateRepos *int `json:"owned_private_repos,omitempty"`
PrivateGists *int `json:"private_gists,omitempty"`
DiskUsage *int `json:"disk_usage,omitempty"`
Collaborators *int `json:"collaborators,omitempty"`
BillingEmail *string `json:"billing_email,omitempty"`
Type *string `json:"type,omitempty"`
Plan *Plan `json:"plan,omitempty"`
// API URLs
URL *string `json:"url,omitempty"`
EventsURL *string `json:"events_url,omitempty"`
MembersURL *string `json:"members_url,omitempty"`
PublicMembersURL *string `json:"public_members_url,omitempty"`
ReposURL *string `json:"repos_url,omitempty"`
}
func (o Organization) String() string {
return Stringify(o)
}
// Plan represents the payment plan for an account. See plans at https://github.com/plans.
type Plan struct {
Name *string `json:"name,omitempty"`
Space *int `json:"space,omitempty"`
Collaborators *int `json:"collaborators,omitempty"`
PrivateRepos *int `json:"private_repos,omitempty"`
}
func (p Plan) String() string {
return Stringify(p)
}
// OrganizationsListOptions specifies the optional parameters to the
// OrganizationsService.ListAll method.
type OrganizationsListOptions struct {
// Since filters Organizations by ID.
Since int `url:"since,omitempty"`
ListOptions
}
// ListAll lists all organizations, in the order that they were created on GitHub.
//
// Note: Pagination is powered exclusively by the since parameter. To continue
// listing the next set of organizations, use the ID of the last-returned organization
// as the opts.Since parameter for the next call.
//
// GitHub API docs: https://developer.github.com/v3/orgs/#list-all-organizations
func (s *OrganizationsService) ListAll(opt *OrganizationsListOptions) ([]*Organization, *Response, error) {
u, err := addOptions("organizations", opt)
if err != nil {
return nil, nil, err
}
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
orgs := []*Organization{}
resp, err := s.client.Do(req, &orgs)
if err != nil {
return nil, resp, err
}
return orgs, resp, err
}
// List the organizations for a user. Passing the empty string will list
// organizations for the authenticated user.
//
// GitHub API docs: http://developer.github.com/v3/orgs/#list-user-organizations
func (s *OrganizationsService) List(user string, opt *ListOptions) ([]*Organization, *Response, error) {
var u string
if user != "" {
u = fmt.Sprintf("users/%v/orgs", user)
} else {
u = "user/orgs"
}
u, err := addOptions(u, opt)
if err != nil {
return nil, nil, err
}
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
orgs := new([]*Organization)
resp, err := s.client.Do(req, orgs)
if err != nil {
return nil, resp, err
}
return *orgs, resp, err
}
// Get fetches an organization by name.
//
// GitHub API docs: http://developer.github.com/v3/orgs/#get-an-organization
func (s *OrganizationsService) Get(org string) (*Organization, *Response, error) {
u := fmt.Sprintf("orgs/%v", org)
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
organization := new(Organization)
resp, err := s.client.Do(req, organization)
if err != nil {
return nil, resp, err
}
return organization, resp, err
}
// Edit an organization.
//
// GitHub API docs: http://developer.github.com/v3/orgs/#edit-an-organization
func (s *OrganizationsService) Edit(name string, org *Organization) (*Organization, *Response, error) {
u := fmt.Sprintf("orgs/%v", name)
req, err := s.client.NewRequest("PATCH", u, org)
if err != nil {
return nil, nil, err
}
o := new(Organization)
resp, err := s.client.Do(req, o)
if err != nil {
return nil, resp, err
}
return o, resp, err
}

104
vendor/src/github.com/google/go-github/github/orgs_hooks.go

@ -0,0 +1,104 @@
// Copyright 2015 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github
import "fmt"
// ListHooks lists all Hooks for the specified organization.
//
// GitHub API docs: https://developer.github.com/v3/orgs/hooks/#list-hooks
func (s *OrganizationsService) ListHooks(org string, opt *ListOptions) ([]*Hook, *Response, error) {
u := fmt.Sprintf("orgs/%v/hooks", org)
u, err := addOptions(u, opt)
if err != nil {
return nil, nil, err
}
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
hooks := new([]*Hook)
resp, err := s.client.Do(req, hooks)
if err != nil {
return nil, resp, err
}
return *hooks, resp, err
}
// GetHook returns a single specified Hook.
//
// GitHub API docs: https://developer.github.com/v3/orgs/hooks/#get-single-hook
func (s *OrganizationsService) GetHook(org string, id int) (*Hook, *Response, error) {
u := fmt.Sprintf("orgs/%v/hooks/%d", org, id)
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
hook := new(Hook)
resp, err := s.client.Do(req, hook)
return hook, resp, err
}
// CreateHook creates a Hook for the specified org.
// Name and Config are required fields.
//
// GitHub API docs: https://developer.github.com/v3/orgs/hooks/#create-a-hook
func (s *OrganizationsService) CreateHook(org string, hook *Hook) (*Hook, *Response, error) {
u := fmt.Sprintf("orgs/%v/hooks", org)
req, err := s.client.NewRequest("POST", u, hook)
if err != nil {
return nil, nil, err
}
h := new(Hook)
resp, err := s.client.Do(req, h)
if err != nil {
return nil, resp, err
}
return h, resp, err
}
// EditHook updates a specified Hook.
//
// GitHub API docs: https://developer.github.com/v3/orgs/hooks/#edit-a-hook
func (s *OrganizationsService) EditHook(org string, id int, hook *Hook) (*Hook, *Response, error) {
u := fmt.Sprintf("orgs/%v/hooks/%d", org, id)
req, err := s.client.NewRequest("PATCH", u, hook)
if err != nil {
return nil, nil, err
}
h := new(Hook)
resp, err := s.client.Do(req, h)
return h, resp, err
}
// PingHook triggers a 'ping' event to be sent to the Hook.
//
// GitHub API docs: https://developer.github.com/v3/orgs/hooks/#ping-a-hook
func (s *OrganizationsService) PingHook(org string, id int) (*Response, error) {
u := fmt.Sprintf("orgs/%v/hooks/%d/pings", org, id)
req, err := s.client.NewRequest("POST", u, nil)
if err != nil {
return nil, err
}
return s.client.Do(req, nil)
}
// DeleteHook deletes a specified Hook.
//
// GitHub API docs: https://developer.github.com/v3/orgs/hooks/#delete-a-hook
func (s *OrganizationsService) DeleteHook(org string, id int) (*Response, error) {
u := fmt.Sprintf("orgs/%v/hooks/%d", org, id)
req, err := s.client.NewRequest("DELETE", u, nil)
if err != nil {
return nil, err
}
return s.client.Do(req, nil)
}

134
vendor/src/github.com/google/go-github/github/orgs_hooks_test.go

@ -0,0 +1,134 @@
// Copyright 2015 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github
import (
"encoding/json"
"fmt"
"net/http"
"reflect"
"testing"
)
func TestOrganizationsService_ListHooks(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/orgs/o/hooks", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testFormValues(t, r, values{"page": "2"})
fmt.Fprint(w, `[{"id":1}, {"id":2}]`)
})
opt := &ListOptions{Page: 2}
hooks, _, err := client.Organizations.ListHooks("o", opt)
if err != nil {
t.Errorf("Organizations.ListHooks returned error: %v", err)
}
want := []*Hook{{ID: Int(1)}, {ID: Int(2)}}
if !reflect.DeepEqual(hooks, want) {
t.Errorf("Organizations.ListHooks returned %+v, want %+v", hooks, want)
}
}
func TestOrganizationsService_ListHooks_invalidOrg(t *testing.T) {
_, _, err := client.Organizations.ListHooks("%", nil)
testURLParseError(t, err)
}
func TestOrganizationsService_GetHook(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/orgs/o/hooks/1", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
fmt.Fprint(w, `{"id":1}`)
})
hook, _, err := client.Organizations.GetHook("o", 1)
if err != nil {
t.Errorf("Organizations.GetHook returned error: %v", err)
}
want := &Hook{ID: Int(1)}
if !reflect.DeepEqual(hook, want) {
t.Errorf("Organizations.GetHook returned %+v, want %+v", hook, want)
}
}
func TestOrganizationsService_GetHook_invalidOrg(t *testing.T) {
_, _, err := client.Organizations.GetHook("%", 1)
testURLParseError(t, err)
}
func TestOrganizationsService_EditHook(t *testing.T) {
setup()
defer teardown()
input := &Hook{Name: String("t")}
mux.HandleFunc("/orgs/o/hooks/1", func(w http.ResponseWriter, r *http.Request) {
v := new(Hook)
json.NewDecoder(r.Body).Decode(v)
testMethod(t, r, "PATCH")
if !reflect.DeepEqual(v, input) {
t.Errorf("Request body = %+v, want %+v", v, input)
}
fmt.Fprint(w, `{"id":1}`)
})
hook, _, err := client.Organizations.EditHook("o", 1, input)
if err != nil {
t.Errorf("Organizations.EditHook returned error: %v", err)
}
want := &Hook{ID: Int(1)}
if !reflect.DeepEqual(hook, want) {
t.Errorf("Organizations.EditHook returned %+v, want %+v", hook, want)
}
}
func TestOrganizationsService_EditHook_invalidOrg(t *testing.T) {
_, _, err := client.Organizations.EditHook("%", 1, nil)
testURLParseError(t, err)
}
func TestOrganizationsService_PingHook(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/orgs/o/hooks/1/pings", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "POST")
})
_, err := client.Organizations.PingHook("o", 1)
if err != nil {
t.Errorf("Organizations.PingHook returned error: %v", err)
}
}
func TestOrganizationsService_DeleteHook(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/orgs/o/hooks/1", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "DELETE")
})
_, err := client.Organizations.DeleteHook("o", 1)
if err != nil {
t.Errorf("Organizations.DeleteHook returned error: %v", err)
}
}
func TestOrganizationsService_DeleteHook_invalidOrg(t *testing.T) {
_, err := client.Organizations.DeleteHook("%", 1)
testURLParseError(t, err)
}

272
vendor/src/github.com/google/go-github/github/orgs_members.go

@ -0,0 +1,272 @@
// Copyright 2013 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github
import "fmt"
// Membership represents the status of a user's membership in an organization or team.
type Membership struct {
URL *string `json:"url,omitempty"`
// State is the user's status within the organization or team.
// Possible values are: "active", "pending"
State *string `json:"state,omitempty"`
// Role identifies the user's role within the organization or team.
// Possible values for organization membership:
// member - non-owner organization member
// admin - organization owner
//
// Possible values for team membership are:
// member - a normal member of the team
// maintainer - a team maintainer. Able to add/remove other team
// members, promote other team members to team
// maintainer, and edit the team’s name and description
Role *string `json:"role,omitempty"`
// For organization membership, the API URL of the organization.
OrganizationURL *string `json:"organization_url,omitempty"`
// For organization membership, the organization the membership is for.
Organization *Organization `json:"organization,omitempty"`
// For organization membership, the user the membership is for.
User *User `json:"user,omitempty"`
}
func (m Membership) String() string {
return Stringify(m)
}
// ListMembersOptions specifies optional parameters to the
// OrganizationsService.ListMembers method.
type ListMembersOptions struct {
// If true (or if the authenticated user is not an owner of the
// organization), list only publicly visible members.
PublicOnly bool `url:"-"`
// Filter members returned in the list. Possible values are:
// 2fa_disabled, all. Default is "all".
Filter string `url:"filter,omitempty"`
// Role filters members returned by their role in the organization.
// Possible values are:
// all - all members of the organization, regardless of role
// admin - organization owners
// member - non-organization members
//
// Default is "all".
Role string `url:"role,omitempty"`
ListOptions
}
// ListMembers lists the members for an organization. If the authenticated
// user is an owner of the organization, this will return both concealed and
// public members, otherwise it will only return public members.
//
// GitHub API docs: http://developer.github.com/v3/orgs/members/#members-list
func (s *OrganizationsService) ListMembers(org string, opt *ListMembersOptions) ([]*User, *Response, error) {
var u string
if opt != nil && opt.PublicOnly {
u = fmt.Sprintf("orgs/%v/public_members", org)
} else {
u = fmt.Sprintf("orgs/%v/members", org)
}
u, err := addOptions(u, opt)
if err != nil {
return nil, nil, err
}
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
members := new([]*User)
resp, err := s.client.Do(req, members)
if err != nil {
return nil, resp, err
}
return *members, resp, err
}
// IsMember checks if a user is a member of an organization.
//
// GitHub API docs: http://developer.github.com/v3/orgs/members/#check-membership
func (s *OrganizationsService) IsMember(org, user string) (bool, *Response, error) {
u := fmt.Sprintf("orgs/%v/members/%v", org, user)
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return false, nil, err
}
resp, err := s.client.Do(req, nil)
member, err := parseBoolResponse(err)
return member, resp, err
}
// IsPublicMember checks if a user is a public member of an organization.
//
// GitHub API docs: http://developer.github.com/v3/orgs/members/#check-public-membership
func (s *OrganizationsService) IsPublicMember(org, user string) (bool, *Response, error) {
u := fmt.Sprintf("orgs/%v/public_members/%v", org, user)
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return false, nil, err
}
resp, err := s.client.Do(req, nil)
member, err := parseBoolResponse(err)
return member, resp, err
}
// RemoveMember removes a user from all teams of an organization.
//
// GitHub API docs: http://developer.github.com/v3/orgs/members/#remove-a-member
func (s *OrganizationsService) RemoveMember(org, user string) (*Response, error) {
u := fmt.Sprintf("orgs/%v/members/%v", org, user)
req, err := s.client.NewRequest("DELETE", u, nil)
if err != nil {
return nil, err
}
return s.client.Do(req, nil)
}
// PublicizeMembership publicizes a user's membership in an organization. (A
// user cannot publicize the membership for another user.)
//
// GitHub API docs: http://developer.github.com/v3/orgs/members/#publicize-a-users-membership
func (s *OrganizationsService) PublicizeMembership(org, user string) (*Response, error) {
u := fmt.Sprintf("orgs/%v/public_members/%v", org, user)
req, err := s.client.NewRequest("PUT", u, nil)
if err != nil {
return nil, err
}
return s.client.Do(req, nil)
}
// ConcealMembership conceals a user's membership in an organization.
//
// GitHub API docs: http://developer.github.com/v3/orgs/members/#conceal-a-users-membership
func (s *OrganizationsService) ConcealMembership(org, user string) (*Response, error) {
u := fmt.Sprintf("orgs/%v/public_members/%v", org, user)
req, err := s.client.NewRequest("DELETE", u, nil)
if err != nil {
return nil, err
}
return s.client.Do(req, nil)
}
// ListOrgMembershipsOptions specifies optional parameters to the
// OrganizationsService.ListOrgMemberships method.
type ListOrgMembershipsOptions struct {
// Filter memberships to include only those with the specified state.
// Possible values are: "active", "pending".
State string `url:"state,omitempty"`
ListOptions
}
// ListOrgMemberships lists the organization memberships for the authenticated user.
//
// GitHub API docs: https://developer.github.com/v3/orgs/members/#list-your-organization-memberships
func (s *OrganizationsService) ListOrgMemberships(opt *ListOrgMembershipsOptions) ([]*Membership, *Response, error) {
u := "user/memberships/orgs"
u, err := addOptions(u, opt)
if err != nil {
return nil, nil, err
}
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
var memberships []*Membership
resp, err := s.client.Do(req, &memberships)
if err != nil {
return nil, resp, err
}
return memberships, resp, err
}
// GetOrgMembership gets the membership for a user in a specified organization.
// Passing an empty string for user will get the membership for the
// authenticated user.
//
// GitHub API docs: https://developer.github.com/v3/orgs/members/#get-organization-membership
// GitHub API docs: https://developer.github.com/v3/orgs/members/#get-your-organization-membership
func (s *OrganizationsService) GetOrgMembership(user, org string) (*Membership, *Response, error) {
var u string
if user != "" {
u = fmt.Sprintf("orgs/%v/memberships/%v", org, user)
} else {
u = fmt.Sprintf("user/memberships/orgs/%v", org)
}
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
membership := new(Membership)
resp, err := s.client.Do(req, membership)
if err != nil {
return nil, resp, err
}
return membership, resp, err
}
// EditOrgMembership edits the membership for user in specified organization.
// Passing an empty string for user will edit the membership for the
// authenticated user.
//
// GitHub API docs: https://developer.github.com/v3/orgs/members/#add-or-update-organization-membership
// GitHub API docs: https://developer.github.com/v3/orgs/members/#edit-your-organization-membership
func (s *OrganizationsService) EditOrgMembership(user, org string, membership *Membership) (*Membership, *Response, error) {
var u, method string
if user != "" {
u = fmt.Sprintf("orgs/%v/memberships/%v", org, user)
method = "PUT"
} else {
u = fmt.Sprintf("user/memberships/orgs/%v", org)
method = "PATCH"
}
req, err := s.client.NewRequest(method, u, membership)
if err != nil {
return nil, nil, err
}
m := new(Membership)
resp, err := s.client.Do(req, m)
if err != nil {
return nil, resp, err
}
return m, resp, err
}
// RemoveOrgMembership removes user from the specified organization. If the
// user has been invited to the organization, this will cancel their invitation.
//
// GitHub API docs: https://developer.github.com/v3/orgs/members/#remove-organization-membership
func (s *OrganizationsService) RemoveOrgMembership(user, org string) (*Response, error) {
u := fmt.Sprintf("orgs/%v/memberships/%v", org, user)
req, err := s.client.NewRequest("DELETE", u, nil)
if err != nil {
return nil, err
}
return s.client.Do(req, nil)
}

355
vendor/src/github.com/google/go-github/github/orgs_members_test.go

@ -0,0 +1,355 @@
// Copyright 2013 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github
import (
"encoding/json"
"fmt"
"net/http"
"reflect"
"testing"
)
func TestOrganizationsService_ListMembers(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/orgs/o/members", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testFormValues(t, r, values{
"filter": "2fa_disabled",
"role": "admin",
"page": "2",
})
fmt.Fprint(w, `[{"id":1}]`)
})
opt := &ListMembersOptions{
PublicOnly: false,
Filter: "2fa_disabled",
Role: "admin",
ListOptions: ListOptions{Page: 2},
}
members, _, err := client.Organizations.ListMembers("o", opt)
if err != nil {
t.Errorf("Organizations.ListMembers returned error: %v", err)
}
want := []*User{{ID: Int(1)}}
if !reflect.DeepEqual(members, want) {
t.Errorf("Organizations.ListMembers returned %+v, want %+v", members, want)
}
}
func TestOrganizationsService_ListMembers_invalidOrg(t *testing.T) {
_, _, err := client.Organizations.ListMembers("%", nil)
testURLParseError(t, err)
}
func TestOrganizationsService_ListMembers_public(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/orgs/o/public_members", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
fmt.Fprint(w, `[{"id":1}]`)
})
opt := &ListMembersOptions{PublicOnly: true}
members, _, err := client.Organizations.ListMembers("o", opt)
if err != nil {
t.Errorf("Organizations.ListMembers returned error: %v", err)
}
want := []*User{{ID: Int(1)}}
if !reflect.DeepEqual(members, want) {
t.Errorf("Organizations.ListMembers returned %+v, want %+v", members, want)
}
}
func TestOrganizationsService_IsMember(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/orgs/o/members/u", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
w.WriteHeader(http.StatusNoContent)
})
member, _, err := client.Organizations.IsMember("o", "u")
if err != nil {
t.Errorf("Organizations.IsMember returned error: %v", err)
}
if want := true; member != want {
t.Errorf("Organizations.IsMember returned %+v, want %+v", member, want)
}
}
// ensure that a 404 response is interpreted as "false" and not an error
func TestOrganizationsService_IsMember_notMember(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/orgs/o/members/u", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
w.WriteHeader(http.StatusNotFound)
})
member, _, err := client.Organizations.IsMember("o", "u")
if err != nil {
t.Errorf("Organizations.IsMember returned error: %+v", err)
}
if want := false; member != want {
t.Errorf("Organizations.IsMember returned %+v, want %+v", member, want)
}
}
// ensure that a 400 response is interpreted as an actual error, and not simply
// as "false" like the above case of a 404
func TestOrganizationsService_IsMember_error(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/orgs/o/members/u", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
http.Error(w, "BadRequest", http.StatusBadRequest)
})
member, _, err := client.Organizations.IsMember("o", "u")
if err == nil {
t.Errorf("Expected HTTP 400 response")
}
if want := false; member != want {
t.Errorf("Organizations.IsMember returned %+v, want %+v", member, want)
}
}
func TestOrganizationsService_IsMember_invalidOrg(t *testing.T) {
_, _, err := client.Organizations.IsMember("%", "u")
testURLParseError(t, err)
}
func TestOrganizationsService_IsPublicMember(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/orgs/o/public_members/u", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
w.WriteHeader(http.StatusNoContent)
})
member, _, err := client.Organizations.IsPublicMember("o", "u")
if err != nil {
t.Errorf("Organizations.IsPublicMember returned error: %v", err)
}
if want := true; member != want {
t.Errorf("Organizations.IsPublicMember returned %+v, want %+v", member, want)
}
}
// ensure that a 404 response is interpreted as "false" and not an error
func TestOrganizationsService_IsPublicMember_notMember(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/orgs/o/public_members/u", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
w.WriteHeader(http.StatusNotFound)
})
member, _, err := client.Organizations.IsPublicMember("o", "u")
if err != nil {
t.Errorf("Organizations.IsPublicMember returned error: %v", err)
}
if want := false; member != want {
t.Errorf("Organizations.IsPublicMember returned %+v, want %+v", member, want)
}
}
// ensure that a 400 response is interpreted as an actual error, and not simply
// as "false" like the above case of a 404
func TestOrganizationsService_IsPublicMember_error(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/orgs/o/public_members/u", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
http.Error(w, "BadRequest", http.StatusBadRequest)
})
member, _, err := client.Organizations.IsPublicMember("o", "u")
if err == nil {
t.Errorf("Expected HTTP 400 response")
}
if want := false; member != want {
t.Errorf("Organizations.IsPublicMember returned %+v, want %+v", member, want)
}
}
func TestOrganizationsService_IsPublicMember_invalidOrg(t *testing.T) {
_, _, err := client.Organizations.IsPublicMember("%", "u")
testURLParseError(t, err)
}
func TestOrganizationsService_RemoveMember(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/orgs/o/members/u", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "DELETE")
})
_, err := client.Organizations.RemoveMember("o", "u")
if err != nil {
t.Errorf("Organizations.RemoveMember returned error: %v", err)
}
}
func TestOrganizationsService_RemoveMember_invalidOrg(t *testing.T) {
_, err := client.Organizations.RemoveMember("%", "u")
testURLParseError(t, err)
}
func TestOrganizationsService_ListOrgMemberships(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/user/memberships/orgs", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testFormValues(t, r, values{
"state": "active",
"page": "2",
})
fmt.Fprint(w, `[{"url":"u"}]`)
})
opt := &ListOrgMembershipsOptions{
State: "active",
ListOptions: ListOptions{Page: 2},
}
memberships, _, err := client.Organizations.ListOrgMemberships(opt)
if err != nil {
t.Errorf("Organizations.ListOrgMemberships returned error: %v", err)
}
want := []*Membership{{URL: String("u")}}
if !reflect.DeepEqual(memberships, want) {
t.Errorf("Organizations.ListOrgMemberships returned %+v, want %+v", memberships, want)
}
}
func TestOrganizationsService_GetOrgMembership_AuthenticatedUser(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/user/memberships/orgs/o", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
fmt.Fprint(w, `{"url":"u"}`)
})
membership, _, err := client.Organizations.GetOrgMembership("", "o")
if err != nil {
t.Errorf("Organizations.GetOrgMembership returned error: %v", err)
}
want := &Membership{URL: String("u")}
if !reflect.DeepEqual(membership, want) {
t.Errorf("Organizations.GetOrgMembership returned %+v, want %+v", membership, want)
}
}
func TestOrganizationsService_GetOrgMembership_SpecifiedUser(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/orgs/o/memberships/u", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
fmt.Fprint(w, `{"url":"u"}`)
})
membership, _, err := client.Organizations.GetOrgMembership("u", "o")
if err != nil {
t.Errorf("Organizations.GetOrgMembership returned error: %v", err)
}
want := &Membership{URL: String("u")}
if !reflect.DeepEqual(membership, want) {
t.Errorf("Organizations.GetOrgMembership returned %+v, want %+v", membership, want)
}
}
func TestOrganizationsService_EditOrgMembership_AuthenticatedUser(t *testing.T) {
setup()
defer teardown()
input := &Membership{State: String("active")}
mux.HandleFunc("/user/memberships/orgs/o", func(w http.ResponseWriter, r *http.Request) {
v := new(Membership)
json.NewDecoder(r.Body).Decode(v)
testMethod(t, r, "PATCH")
if !reflect.DeepEqual(v, input) {
t.Errorf("Request body = %+v, want %+v", v, input)
}
fmt.Fprint(w, `{"url":"u"}`)
})
membership, _, err := client.Organizations.EditOrgMembership("", "o", input)
if err != nil {
t.Errorf("Organizations.EditOrgMembership returned error: %v", err)
}
want := &Membership{URL: String("u")}
if !reflect.DeepEqual(membership, want) {
t.Errorf("Organizations.EditOrgMembership returned %+v, want %+v", membership, want)
}
}
func TestOrganizationsService_EditOrgMembership_SpecifiedUser(t *testing.T) {
setup()
defer teardown()
input := &Membership{State: String("active")}
mux.HandleFunc("/orgs/o/memberships/u", func(w http.ResponseWriter, r *http.Request) {
v := new(Membership)
json.NewDecoder(r.Body).Decode(v)
testMethod(t, r, "PUT")
if !reflect.DeepEqual(v, input) {
t.Errorf("Request body = %+v, want %+v", v, input)
}
fmt.Fprint(w, `{"url":"u"}`)
})
membership, _, err := client.Organizations.EditOrgMembership("u", "o", input)
if err != nil {
t.Errorf("Organizations.EditOrgMembership returned error: %v", err)
}
want := &Membership{URL: String("u")}
if !reflect.DeepEqual(membership, want) {
t.Errorf("Organizations.EditOrgMembership returned %+v, want %+v", membership, want)
}
}
func TestOrganizationsService_RemoveOrgMembership(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/orgs/o/memberships/u", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "DELETE")
w.WriteHeader(http.StatusNoContent)
})
_, err := client.Organizations.RemoveOrgMembership("u", "o")
if err != nil {
t.Errorf("Organizations.RemoveOrgMembership returned error: %v", err)
}
}

379
vendor/src/github.com/google/go-github/github/orgs_teams.go

@ -0,0 +1,379 @@
// Copyright 2013 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github
import "fmt"
// Team represents a team within a GitHub organization. Teams are used to
// manage access to an organization's repositories.
type Team struct {
ID *int `json:"id,omitempty"`
Name *string `json:"name,omitempty"`
Description *string `json:"description,omitempty"`
URL *string `json:"url,omitempty"`
Slug *string `json:"slug,omitempty"`
// Permission is deprecated when creating or editing a team in an org
// using the new GitHub permission model. It no longer identifies the
// permission a team has on its repos, but only specifies the default
// permission a repo is initially added with. Avoid confusion by
// specifying a permission value when calling AddTeamRepo.
Permission *string `json:"permission,omitempty"`
// Privacy identifies the level of privacy this team should have.
// Possible values are:
// secret - only visible to organization owners and members of this team
// closed - visible to all members of this organization
// Default is "secret".
Privacy *string `json:"privacy,omitempty"`
MembersCount *int `json:"members_count,omitempty"`
ReposCount *int `json:"repos_count,omitempty"`
Organization *Organization `json:"organization,omitempty"`
MembersURL *string `json:"members_url,omitempty"`
RepositoriesURL *string `json:"repositories_url,omitempty"`
}
func (t Team) String() string {
return Stringify(t)
}
// ListTeams lists all of the teams for an organization.
//
// GitHub API docs: http://developer.github.com/v3/orgs/teams/#list-teams
func (s *OrganizationsService) ListTeams(org string, opt *ListOptions) ([]*Team, *Response, error) {
u := fmt.Sprintf("orgs/%v/teams", org)
u, err := addOptions(u, opt)
if err != nil {
return nil, nil, err
}
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
teams := new([]*Team)
resp, err := s.client.Do(req, teams)
if err != nil {
return nil, resp, err
}
return *teams, resp, err
}
// GetTeam fetches a team by ID.
//
// GitHub API docs: http://developer.github.com/v3/orgs/teams/#get-team
func (s *OrganizationsService) GetTeam(team int) (*Team, *Response, error) {
u := fmt.Sprintf("teams/%v", team)
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
t := new(Team)
resp, err := s.client.Do(req, t)
if err != nil {
return nil, resp, err
}
return t, resp, err
}
// CreateTeam creates a new team within an organization.
//
// GitHub API docs: http://developer.github.com/v3/orgs/teams/#create-team
func (s *OrganizationsService) CreateTeam(org string, team *Team) (*Team, *Response, error) {
u := fmt.Sprintf("orgs/%v/teams", org)
req, err := s.client.NewRequest("POST", u, team)
if err != nil {
return nil, nil, err
}
t := new(Team)
resp, err := s.client.Do(req, t)
if err != nil {
return nil, resp, err
}
return t, resp, err
}
// EditTeam edits a team.
//
// GitHub API docs: http://developer.github.com/v3/orgs/teams/#edit-team
func (s *OrganizationsService) EditTeam(id int, team *Team) (*Team, *Response, error) {
u := fmt.Sprintf("teams/%v", id)
req, err := s.client.NewRequest("PATCH", u, team)
if err != nil {
return nil, nil, err
}
t := new(Team)
resp, err := s.client.Do(req, t)
if err != nil {
return nil, resp, err
}
return t, resp, err
}
// DeleteTeam deletes a team.
//
// GitHub API docs: http://developer.github.com/v3/orgs/teams/#delete-team
func (s *OrganizationsService) DeleteTeam(team int) (*Response, error) {
u := fmt.Sprintf("teams/%v", team)
req, err := s.client.NewRequest("DELETE", u, nil)
if err != nil {
return nil, err
}
return s.client.Do(req, nil)
}
// OrganizationListTeamMembersOptions specifies the optional parameters to the
// OrganizationsService.ListTeamMembers method.
type OrganizationListTeamMembersOptions struct {
// Role filters members returned by their role in the team. Possible
// values are "all", "member", "maintainer". Default is "all".
Role string `url:"role,omitempty"`
ListOptions
}
// ListTeamMembers lists all of the users who are members of the specified
// team.
//
// GitHub API docs: http://developer.github.com/v3/orgs/teams/#list-team-members
func (s *OrganizationsService) ListTeamMembers(team int, opt *OrganizationListTeamMembersOptions) ([]*User, *Response, error) {
u := fmt.Sprintf("teams/%v/members", team)
u, err := addOptions(u, opt)
if err != nil {
return nil, nil, err
}
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
members := new([]*User)
resp, err := s.client.Do(req, members)
if err != nil {
return nil, resp, err
}
return *members, resp, err
}
// IsTeamMember checks if a user is a member of the specified team.
//
// GitHub API docs: http://developer.github.com/v3/orgs/teams/#get-team-member
func (s *OrganizationsService) IsTeamMember(team int, user string) (bool, *Response, error) {
u := fmt.Sprintf("teams/%v/members/%v", team, user)
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return false, nil, err
}
resp, err := s.client.Do(req, nil)
member, err := parseBoolResponse(err)
return member, resp, err
}
// ListTeamRepos lists the repositories that the specified team has access to.
//
// GitHub API docs: http://developer.github.com/v3/orgs/teams/#list-team-repos
func (s *OrganizationsService) ListTeamRepos(team int, opt *ListOptions) ([]*Repository, *Response, error) {
u := fmt.Sprintf("teams/%v/repos", team)
u, err := addOptions(u, opt)
if err != nil {
return nil, nil, err
}
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
repos := new([]*Repository)
resp, err := s.client.Do(req, repos)
if err != nil {
return nil, resp, err
}
return *repos, resp, err
}
// IsTeamRepo checks if a team manages the specified repository. If the
// repository is managed by team, a Repository is returned which includes the
// permissions team has for that repo.
//
// GitHub API docs: https://developer.github.com/v3/orgs/teams/#check-if-a-team-manages-a-repository
func (s *OrganizationsService) IsTeamRepo(team int, owner string, repo string) (*Repository, *Response, error) {
u := fmt.Sprintf("teams/%v/repos/%v/%v", team, owner, repo)
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
req.Header.Set("Accept", mediaTypeOrgPermissionRepo)
repository := new(Repository)
resp, err := s.client.Do(req, repository)
if err != nil {
return nil, resp, err
}
return repository, resp, err
}
// OrganizationAddTeamRepoOptions specifies the optional parameters to the
// OrganizationsService.AddTeamRepo method.
type OrganizationAddTeamRepoOptions struct {
// Permission specifies the permission to grant the team on this repository.
// Possible values are:
// pull - team members can pull, but not push to or administer this repository
// push - team members can pull and push, but not administer this repository
// admin - team members can pull, push and administer this repository
//
// If not specified, the team's permission attribute will be used.
Permission string `json:"permission,omitempty"`
}
// AddTeamRepo adds a repository to be managed by the specified team. The
// specified repository must be owned by the organization to which the team
// belongs, or a direct fork of a repository owned by the organization.
//
// GitHub API docs: http://developer.github.com/v3/orgs/teams/#add-team-repo
func (s *OrganizationsService) AddTeamRepo(team int, owner string, repo string, opt *OrganizationAddTeamRepoOptions) (*Response, error) {
u := fmt.Sprintf("teams/%v/repos/%v/%v", team, owner, repo)
req, err := s.client.NewRequest("PUT", u, opt)
if err != nil {
return nil, err
}
return s.client.Do(req, nil)
}
// RemoveTeamRepo removes a repository from being managed by the specified
// team. Note that this does not delete the repository, it just removes it
// from the team.
//
// GitHub API docs: http://developer.github.com/v3/orgs/teams/#remove-team-repo
func (s *OrganizationsService) RemoveTeamRepo(team int, owner string, repo string) (*Response, error) {
u := fmt.Sprintf("teams/%v/repos/%v/%v", team, owner, repo)
req, err := s.client.NewRequest("DELETE", u, nil)
if err != nil {
return nil, err
}
return s.client.Do(req, nil)
}
// ListUserTeams lists a user's teams
// GitHub API docs: https://developer.github.com/v3/orgs/teams/#list-user-teams
func (s *OrganizationsService) ListUserTeams(opt *ListOptions) ([]*Team, *Response, error) {
u := "user/teams"
u, err := addOptions(u, opt)
if err != nil {
return nil, nil, err
}
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
teams := new([]*Team)
resp, err := s.client.Do(req, teams)
if err != nil {
return nil, resp, err
}
return *teams, resp, err
}
// GetTeamMembership returns the membership status for a user in a team.
//
// GitHub API docs: https://developer.github.com/v3/orgs/teams/#get-team-membership
func (s *OrganizationsService) GetTeamMembership(team int, user string) (*Membership, *Response, error) {
u := fmt.Sprintf("teams/%v/memberships/%v", team, user)
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
t := new(Membership)
resp, err := s.client.Do(req, t)
if err != nil {
return nil, resp, err
}
return t, resp, err
}
// OrganizationAddTeamMembershipOptions does stuff specifies the optional
// parameters to the OrganizationsService.AddTeamMembership method.
type OrganizationAddTeamMembershipOptions struct {
// Role specifies the role the user should have in the team. Possible
// values are:
// member - a normal member of the team
// maintainer - a team maintainer. Able to add/remove other team
// members, promote other team members to team
// maintainer, and edit the team’s name and description
//
// Default value is "member".
Role string `json:"role,omitempty"`
}
// AddTeamMembership adds or invites a user to a team.
//
// In order to add a membership between a user and a team, the authenticated
// user must have 'admin' permissions to the team or be an owner of the
// organization that the team is associated with.
//
// If the user is already a part of the team's organization (meaning they're on
// at least one other team in the organization), this endpoint will add the
// user to the team.
//
// If the user is completely unaffiliated with the team's organization (meaning
// they're on none of the organization's teams), this endpoint will send an
// invitation to the user via email. This newly-created membership will be in
// the "pending" state until the user accepts the invitation, at which point
// the membership will transition to the "active" state and the user will be
// added as a member of the team.
//
// GitHub API docs: https://developer.github.com/v3/orgs/teams/#add-team-membership
func (s *OrganizationsService) AddTeamMembership(team int, user string, opt *OrganizationAddTeamMembershipOptions) (*Membership, *Response, error) {
u := fmt.Sprintf("teams/%v/memberships/%v", team, user)
req, err := s.client.NewRequest("PUT", u, opt)
if err != nil {
return nil, nil, err
}
t := new(Membership)
resp, err := s.client.Do(req, t)
if err != nil {
return nil, resp, err
}
return t, resp, err
}
// RemoveTeamMembership removes a user from a team.
//
// GitHub API docs: https://developer.github.com/v3/orgs/teams/#remove-team-membership
func (s *OrganizationsService) RemoveTeamMembership(team int, user string) (*Response, error) {
u := fmt.Sprintf("teams/%v/memberships/%v", team, user)
req, err := s.client.NewRequest("DELETE", u, nil)
if err != nil {
return nil, err
}
return s.client.Do(req, nil)
}

501
vendor/src/github.com/google/go-github/github/orgs_teams_test.go

@ -0,0 +1,501 @@
// Copyright 2013 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github
import (
"encoding/json"
"fmt"
"net/http"
"reflect"
"testing"
)
func TestOrganizationsService_ListTeams(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/orgs/o/teams", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testFormValues(t, r, values{"page": "2"})
fmt.Fprint(w, `[{"id":1}]`)
})
opt := &ListOptions{Page: 2}
teams, _, err := client.Organizations.ListTeams("o", opt)
if err != nil {
t.Errorf("Organizations.ListTeams returned error: %v", err)
}
want := []*Team{{ID: Int(1)}}
if !reflect.DeepEqual(teams, want) {
t.Errorf("Organizations.ListTeams returned %+v, want %+v", teams, want)
}
}
func TestOrganizationsService_ListTeams_invalidOrg(t *testing.T) {
_, _, err := client.Organizations.ListTeams("%", nil)
testURLParseError(t, err)
}
func TestOrganizationsService_GetTeam(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/teams/1", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
fmt.Fprint(w, `{"id":1, "name":"n", "description": "d", "url":"u", "slug": "s", "permission":"p"}`)
})
team, _, err := client.Organizations.GetTeam(1)
if err != nil {
t.Errorf("Organizations.GetTeam returned error: %v", err)
}
want := &Team{ID: Int(1), Name: String("n"), Description: String("d"), URL: String("u"), Slug: String("s"), Permission: String("p")}
if !reflect.DeepEqual(team, want) {
t.Errorf("Organizations.GetTeam returned %+v, want %+v", team, want)
}
}
func TestOrganizationsService_CreateTeam(t *testing.T) {
setup()
defer teardown()
input := &Team{Name: String("n"), Privacy: String("closed")}
mux.HandleFunc("/orgs/o/teams", func(w http.ResponseWriter, r *http.Request) {
v := new(Team)
json.NewDecoder(r.Body).Decode(v)
testMethod(t, r, "POST")
if !reflect.DeepEqual(v, input) {
t.Errorf("Request body = %+v, want %+v", v, input)
}
fmt.Fprint(w, `{"id":1}`)
})
team, _, err := client.Organizations.CreateTeam("o", input)
if err != nil {
t.Errorf("Organizations.CreateTeam returned error: %v", err)
}
want := &Team{ID: Int(1)}
if !reflect.DeepEqual(team, want) {
t.Errorf("Organizations.CreateTeam returned %+v, want %+v", team, want)
}
}
func TestOrganizationsService_CreateTeam_invalidOrg(t *testing.T) {
_, _, err := client.Organizations.CreateTeam("%", nil)
testURLParseError(t, err)
}
func TestOrganizationsService_EditTeam(t *testing.T) {
setup()
defer teardown()
input := &Team{Name: String("n"), Privacy: String("closed")}
mux.HandleFunc("/teams/1", func(w http.ResponseWriter, r *http.Request) {
v := new(Team)
json.NewDecoder(r.Body).Decode(v)
testMethod(t, r, "PATCH")
if !reflect.DeepEqual(v, input) {
t.Errorf("Request body = %+v, want %+v", v, input)
}
fmt.Fprint(w, `{"id":1}`)
})
team, _, err := client.Organizations.EditTeam(1, input)
if err != nil {
t.Errorf("Organizations.EditTeam returned error: %v", err)
}
want := &Team{ID: Int(1)}
if !reflect.DeepEqual(team, want) {
t.Errorf("Organizations.EditTeam returned %+v, want %+v", team, want)
}
}
func TestOrganizationsService_DeleteTeam(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/teams/1", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "DELETE")
})
_, err := client.Organizations.DeleteTeam(1)
if err != nil {
t.Errorf("Organizations.DeleteTeam returned error: %v", err)
}
}
func TestOrganizationsService_ListTeamMembers(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/teams/1/members", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testFormValues(t, r, values{"role": "member", "page": "2"})
fmt.Fprint(w, `[{"id":1}]`)
})
opt := &OrganizationListTeamMembersOptions{Role: "member", ListOptions: ListOptions{Page: 2}}
members, _, err := client.Organizations.ListTeamMembers(1, opt)
if err != nil {
t.Errorf("Organizations.ListTeamMembers returned error: %v", err)
}
want := []*User{{ID: Int(1)}}
if !reflect.DeepEqual(members, want) {
t.Errorf("Organizations.ListTeamMembers returned %+v, want %+v", members, want)
}
}
func TestOrganizationsService_IsTeamMember_true(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/teams/1/members/u", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
})
member, _, err := client.Organizations.IsTeamMember(1, "u")
if err != nil {
t.Errorf("Organizations.IsTeamMember returned error: %v", err)
}
if want := true; member != want {
t.Errorf("Organizations.IsTeamMember returned %+v, want %+v", member, want)
}
}
// ensure that a 404 response is interpreted as "false" and not an error
func TestOrganizationsService_IsTeamMember_false(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/teams/1/members/u", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
w.WriteHeader(http.StatusNotFound)
})
member, _, err := client.Organizations.IsTeamMember(1, "u")
if err != nil {
t.Errorf("Organizations.IsTeamMember returned error: %+v", err)
}
if want := false; member != want {
t.Errorf("Organizations.IsTeamMember returned %+v, want %+v", member, want)
}
}
// ensure that a 400 response is interpreted as an actual error, and not simply
// as "false" like the above case of a 404
func TestOrganizationsService_IsTeamMember_error(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/teams/1/members/u", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
http.Error(w, "BadRequest", http.StatusBadRequest)
})
member, _, err := client.Organizations.IsTeamMember(1, "u")
if err == nil {
t.Errorf("Expected HTTP 400 response")
}
if want := false; member != want {
t.Errorf("Organizations.IsTeamMember returned %+v, want %+v", member, want)
}
}
func TestOrganizationsService_IsTeamMember_invalidUser(t *testing.T) {
_, _, err := client.Organizations.IsTeamMember(1, "%")
testURLParseError(t, err)
}
func TestOrganizationsService_PublicizeMembership(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/orgs/o/public_members/u", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "PUT")
w.WriteHeader(http.StatusNoContent)
})
_, err := client.Organizations.PublicizeMembership("o", "u")
if err != nil {
t.Errorf("Organizations.PublicizeMembership returned error: %v", err)
}
}
func TestOrganizationsService_PublicizeMembership_invalidOrg(t *testing.T) {
_, err := client.Organizations.PublicizeMembership("%", "u")
testURLParseError(t, err)
}
func TestOrganizationsService_ConcealMembership(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/orgs/o/public_members/u", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "DELETE")
w.WriteHeader(http.StatusNoContent)
})
_, err := client.Organizations.ConcealMembership("o", "u")
if err != nil {
t.Errorf("Organizations.ConcealMembership returned error: %v", err)
}
}
func TestOrganizationsService_ConcealMembership_invalidOrg(t *testing.T) {
_, err := client.Organizations.ConcealMembership("%", "u")
testURLParseError(t, err)
}
func TestOrganizationsService_ListTeamRepos(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/teams/1/repos", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testFormValues(t, r, values{"page": "2"})
fmt.Fprint(w, `[{"id":1}]`)
})
opt := &ListOptions{Page: 2}
members, _, err := client.Organizations.ListTeamRepos(1, opt)
if err != nil {
t.Errorf("Organizations.ListTeamRepos returned error: %v", err)
}
want := []*Repository{{ID: Int(1)}}
if !reflect.DeepEqual(members, want) {
t.Errorf("Organizations.ListTeamRepos returned %+v, want %+v", members, want)
}
}
func TestOrganizationsService_IsTeamRepo_true(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/teams/1/repos/o/r", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testHeader(t, r, "Accept", mediaTypeOrgPermissionRepo)
fmt.Fprint(w, `{"id":1}`)
})
repo, _, err := client.Organizations.IsTeamRepo(1, "o", "r")
if err != nil {
t.Errorf("Organizations.IsTeamRepo returned error: %v", err)
}
want := &Repository{ID: Int(1)}
if !reflect.DeepEqual(repo, want) {
t.Errorf("Organizations.IsTeamRepo returned %+v, want %+v", repo, want)
}
}
func TestOrganizationsService_IsTeamRepo_false(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/teams/1/repos/o/r", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
w.WriteHeader(http.StatusNotFound)
})
repo, resp, err := client.Organizations.IsTeamRepo(1, "o", "r")
if err == nil {
t.Errorf("Expected HTTP 404 response")
}
if got, want := resp.Response.StatusCode, http.StatusNotFound; got != want {
t.Errorf("Organizations.IsTeamRepo returned status %d, want %d", got, want)
}
if repo != nil {
t.Errorf("Organizations.IsTeamRepo returned %+v, want nil", repo)
}
}
func TestOrganizationsService_IsTeamRepo_error(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/teams/1/repos/o/r", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
http.Error(w, "BadRequest", http.StatusBadRequest)
})
repo, resp, err := client.Organizations.IsTeamRepo(1, "o", "r")
if err == nil {
t.Errorf("Expected HTTP 400 response")
}
if got, want := resp.Response.StatusCode, http.StatusBadRequest; got != want {
t.Errorf("Organizations.IsTeamRepo returned status %d, want %d", got, want)
}
if repo != nil {
t.Errorf("Organizations.IsTeamRepo returned %+v, want nil", repo)
}
}
func TestOrganizationsService_IsTeamRepo_invalidOwner(t *testing.T) {
_, _, err := client.Organizations.IsTeamRepo(1, "%", "r")
testURLParseError(t, err)
}
func TestOrganizationsService_AddTeamRepo(t *testing.T) {
setup()
defer teardown()
opt := &OrganizationAddTeamRepoOptions{Permission: "admin"}
mux.HandleFunc("/teams/1/repos/o/r", func(w http.ResponseWriter, r *http.Request) {
v := new(OrganizationAddTeamRepoOptions)
json.NewDecoder(r.Body).Decode(v)
testMethod(t, r, "PUT")
if !reflect.DeepEqual(v, opt) {
t.Errorf("Request body = %+v, want %+v", v, opt)
}
w.WriteHeader(http.StatusNoContent)
})
_, err := client.Organizations.AddTeamRepo(1, "o", "r", opt)
if err != nil {
t.Errorf("Organizations.AddTeamRepo returned error: %v", err)
}
}
func TestOrganizationsService_AddTeamRepo_noAccess(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/teams/1/repos/o/r", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "PUT")
w.WriteHeader(StatusUnprocessableEntity)
})
_, err := client.Organizations.AddTeamRepo(1, "o", "r", nil)
if err == nil {
t.Errorf("Expcted error to be returned")
}
}
func TestOrganizationsService_AddTeamRepo_invalidOwner(t *testing.T) {
_, err := client.Organizations.AddTeamRepo(1, "%", "r", nil)
testURLParseError(t, err)
}
func TestOrganizationsService_RemoveTeamRepo(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/teams/1/repos/o/r", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "DELETE")
w.WriteHeader(http.StatusNoContent)
})
_, err := client.Organizations.RemoveTeamRepo(1, "o", "r")
if err != nil {
t.Errorf("Organizations.RemoveTeamRepo returned error: %v", err)
}
}
func TestOrganizationsService_RemoveTeamRepo_invalidOwner(t *testing.T) {
_, err := client.Organizations.RemoveTeamRepo(1, "%", "r")
testURLParseError(t, err)
}
func TestOrganizationsService_GetTeamMembership(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/teams/1/memberships/u", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
fmt.Fprint(w, `{"url":"u", "state":"active"}`)
})
membership, _, err := client.Organizations.GetTeamMembership(1, "u")
if err != nil {
t.Errorf("Organizations.GetTeamMembership returned error: %v", err)
}
want := &Membership{URL: String("u"), State: String("active")}
if !reflect.DeepEqual(membership, want) {
t.Errorf("Organizations.GetTeamMembership returned %+v, want %+v", membership, want)
}
}
func TestOrganizationsService_AddTeamMembership(t *testing.T) {
setup()
defer teardown()
opt := &OrganizationAddTeamMembershipOptions{Role: "maintainer"}
mux.HandleFunc("/teams/1/memberships/u", func(w http.ResponseWriter, r *http.Request) {
v := new(OrganizationAddTeamMembershipOptions)
json.NewDecoder(r.Body).Decode(v)
testMethod(t, r, "PUT")
if !reflect.DeepEqual(v, opt) {
t.Errorf("Request body = %+v, want %+v", v, opt)
}
fmt.Fprint(w, `{"url":"u", "state":"pending"}`)
})
membership, _, err := client.Organizations.AddTeamMembership(1, "u", opt)
if err != nil {
t.Errorf("Organizations.AddTeamMembership returned error: %v", err)
}
want := &Membership{URL: String("u"), State: String("pending")}
if !reflect.DeepEqual(membership, want) {
t.Errorf("Organizations.AddTeamMembership returned %+v, want %+v", membership, want)
}
}
func TestOrganizationsService_RemoveTeamMembership(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/teams/1/memberships/u", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "DELETE")
w.WriteHeader(http.StatusNoContent)
})
_, err := client.Organizations.RemoveTeamMembership(1, "u")
if err != nil {
t.Errorf("Organizations.RemoveTeamMembership returned error: %v", err)
}
}
func TestOrganizationsService_ListUserTeams(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/user/teams", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testFormValues(t, r, values{"page": "1"})
fmt.Fprint(w, `[{"id":1}]`)
})
opt := &ListOptions{Page: 1}
teams, _, err := client.Organizations.ListUserTeams(opt)
if err != nil {
t.Errorf("Organizations.ListUserTeams returned error: %v", err)
}
want := []*Team{{ID: Int(1)}}
if !reflect.DeepEqual(teams, want) {
t.Errorf("Organizations.ListUserTeams returned %+v, want %+v", teams, want)
}
}

143
vendor/src/github.com/google/go-github/github/orgs_test.go

@ -0,0 +1,143 @@
// Copyright 2013 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github
import (
"encoding/json"
"fmt"
"net/http"
"reflect"
"testing"
)
func TestOrganizationsService_ListAll(t *testing.T) {
setup()
defer teardown()
since := 1342004
mux.HandleFunc("/organizations", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testFormValues(t, r, values{"since": "1342004"})
fmt.Fprint(w, `[{"id":4314092}]`)
})
opt := &OrganizationsListOptions{Since: since}
orgs, _, err := client.Organizations.ListAll(opt)
if err != nil {
t.Errorf("Organizations.ListAll returned error: %v", err)
}
want := []*Organization{{ID: Int(4314092)}}
if !reflect.DeepEqual(orgs, want) {
t.Errorf("Organizations.ListAll returned %+v, want %+v", orgs, want)
}
}
func TestOrganizationsService_List_authenticatedUser(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/user/orgs", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
fmt.Fprint(w, `[{"id":1},{"id":2}]`)
})
orgs, _, err := client.Organizations.List("", nil)
if err != nil {
t.Errorf("Organizations.List returned error: %v", err)
}
want := []*Organization{{ID: Int(1)}, {ID: Int(2)}}
if !reflect.DeepEqual(orgs, want) {
t.Errorf("Organizations.List returned %+v, want %+v", orgs, want)
}
}
func TestOrganizationsService_List_specifiedUser(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/users/u/orgs", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testFormValues(t, r, values{"page": "2"})
fmt.Fprint(w, `[{"id":1},{"id":2}]`)
})
opt := &ListOptions{Page: 2}
orgs, _, err := client.Organizations.List("u", opt)
if err != nil {
t.Errorf("Organizations.List returned error: %v", err)
}
want := []*Organization{{ID: Int(1)}, {ID: Int(2)}}
if !reflect.DeepEqual(orgs, want) {
t.Errorf("Organizations.List returned %+v, want %+v", orgs, want)
}
}
func TestOrganizationsService_List_invalidUser(t *testing.T) {
_, _, err := client.Organizations.List("%", nil)
testURLParseError(t, err)
}
func TestOrganizationsService_Get(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/orgs/o", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
fmt.Fprint(w, `{"id":1, "login":"l", "url":"u", "avatar_url": "a", "location":"l"}`)
})
org, _, err := client.Organizations.Get("o")
if err != nil {
t.Errorf("Organizations.Get returned error: %v", err)
}
want := &Organization{ID: Int(1), Login: String("l"), URL: String("u"), AvatarURL: String("a"), Location: String("l")}
if !reflect.DeepEqual(org, want) {
t.Errorf("Organizations.Get returned %+v, want %+v", org, want)
}
}
func TestOrganizationsService_Get_invalidOrg(t *testing.T) {
_, _, err := client.Organizations.Get("%")
testURLParseError(t, err)
}
func TestOrganizationsService_Edit(t *testing.T) {
setup()
defer teardown()
input := &Organization{Login: String("l")}
mux.HandleFunc("/orgs/o", func(w http.ResponseWriter, r *http.Request) {
v := new(Organization)
json.NewDecoder(r.Body).Decode(v)
testMethod(t, r, "PATCH")
if !reflect.DeepEqual(v, input) {
t.Errorf("Request body = %+v, want %+v", v, input)
}
fmt.Fprint(w, `{"id":1}`)
})
org, _, err := client.Organizations.Edit("o", input)
if err != nil {
t.Errorf("Organizations.Edit returned error: %v", err)
}
want := &Organization{ID: Int(1)}
if !reflect.DeepEqual(org, want) {
t.Errorf("Organizations.Edit returned %+v, want %+v", org, want)
}
}
func TestOrganizationsService_Edit_invalidOrg(t *testing.T) {
_, _, err := client.Organizations.Edit("%", nil)
testURLParseError(t, err)
}

285
vendor/src/github.com/google/go-github/github/pulls.go

@ -0,0 +1,285 @@
// Copyright 2013 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github
import (
"fmt"
"time"
)
// PullRequestsService handles communication with the pull request related
// methods of the GitHub API.
//
// GitHub API docs: http://developer.github.com/v3/pulls/
type PullRequestsService service
// PullRequest represents a GitHub pull request on a repository.
type PullRequest struct {
ID *int `json:"id,omitempty"`
Number *int `json:"number,omitempty"`
State *string `json:"state,omitempty"`
Title *string `json:"title,omitempty"`
Body *string `json:"body,omitempty"`
CreatedAt *time.Time `json:"created_at,omitempty"`
UpdatedAt *time.Time `json:"updated_at,omitempty"`
ClosedAt *time.Time `json:"closed_at,omitempty"`
MergedAt *time.Time `json:"merged_at,omitempty"`
User *User `json:"user,omitempty"`
Merged *bool `json:"merged,omitempty"`
Mergeable *bool `json:"mergeable,omitempty"`
MergedBy *User `json:"merged_by,omitempty"`
Comments *int `json:"comments,omitempty"`
Commits *int `json:"commits,omitempty"`
Additions *int `json:"additions,omitempty"`
Deletions *int `json:"deletions,omitempty"`
ChangedFiles *int `json:"changed_files,omitempty"`
URL *string `json:"url,omitempty"`
HTMLURL *string `json:"html_url,omitempty"`
IssueURL *string `json:"issue_url,omitempty"`
StatusesURL *string `json:"statuses_url,omitempty"`
DiffURL *string `json:"diff_url,omitempty"`
PatchURL *string `json:"patch_url,omitempty"`
Assignee *User `json:"assignee,omitempty"` // probably only in webhooks
Head *PullRequestBranch `json:"head,omitempty"`
Base *PullRequestBranch `json:"base,omitempty"`
}
func (p PullRequest) String() string {
return Stringify(p)
}
// PullRequestBranch represents a base or head branch in a GitHub pull request.
type PullRequestBranch struct {
Label *string `json:"label,omitempty"`
Ref *string `json:"ref,omitempty"`
SHA *string `json:"sha,omitempty"`
Repo *Repository `json:"repo,omitempty"`
User *User `json:"user,omitempty"`
}
// PullRequestListOptions specifies the optional parameters to the
// PullRequestsService.List method.
type PullRequestListOptions struct {
// State filters pull requests based on their state. Possible values are:
// open, closed. Default is "open".
State string `url:"state,omitempty"`
// Head filters pull requests by head user and branch name in the format of:
// "user:ref-name".
Head string `url:"head,omitempty"`
// Base filters pull requests by base branch name.
Base string `url:"base,omitempty"`
// Sort specifies how to sort pull requests. Possible values are: created,
// updated, popularity, long-running. Default is "created".
Sort string `url:"sort,omitempty"`
// Direction in which to sort pull requests. Possible values are: asc, desc.
// If Sort is "created" or not specified, Default is "desc", otherwise Default
// is "asc"
Direction string `url:"direction,omitempty"`
ListOptions
}
// List the pull requests for the specified repository.
//
// GitHub API docs: http://developer.github.com/v3/pulls/#list-pull-requests
func (s *PullRequestsService) List(owner string, repo string, opt *PullRequestListOptions) ([]*PullRequest, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/pulls", owner, repo)
u, err := addOptions(u, opt)
if err != nil {
return nil, nil, err
}
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
pulls := new([]*PullRequest)
resp, err := s.client.Do(req, pulls)
if err != nil {
return nil, resp, err
}
return *pulls, resp, err
}
// Get a single pull request.
//
// GitHub API docs: https://developer.github.com/v3/pulls/#get-a-single-pull-request
func (s *PullRequestsService) Get(owner string, repo string, number int) (*PullRequest, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/pulls/%d", owner, repo, number)
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
pull := new(PullRequest)
resp, err := s.client.Do(req, pull)
if err != nil {
return nil, resp, err
}
return pull, resp, err
}
// NewPullRequest represents a new pull request to be created.
type NewPullRequest struct {
Title *string `json:"title,omitempty"`
Head *string `json:"head,omitempty"`
Base *string `json:"base,omitempty"`
Body *string `json:"body,omitempty"`
Issue *int `json:"issue,omitempty"`
}
// Create a new pull request on the specified repository.
//
// GitHub API docs: https://developer.github.com/v3/pulls/#create-a-pull-request
func (s *PullRequestsService) Create(owner string, repo string, pull *NewPullRequest) (*PullRequest, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/pulls", owner, repo)
req, err := s.client.NewRequest("POST", u, pull)
if err != nil {
return nil, nil, err
}
p := new(PullRequest)
resp, err := s.client.Do(req, p)
if err != nil {
return nil, resp, err
}
return p, resp, err
}
// Edit a pull request.
//
// GitHub API docs: https://developer.github.com/v3/pulls/#update-a-pull-request
func (s *PullRequestsService) Edit(owner string, repo string, number int, pull *PullRequest) (*PullRequest, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/pulls/%d", owner, repo, number)
req, err := s.client.NewRequest("PATCH", u, pull)
if err != nil {
return nil, nil, err
}
p := new(PullRequest)
resp, err := s.client.Do(req, p)
if err != nil {
return nil, resp, err
}
return p, resp, err
}
// ListCommits lists the commits in a pull request.
//
// GitHub API docs: https://developer.github.com/v3/pulls/#list-commits-on-a-pull-request
func (s *PullRequestsService) ListCommits(owner string, repo string, number int, opt *ListOptions) ([]*RepositoryCommit, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/pulls/%d/commits", owner, repo, number)
u, err := addOptions(u, opt)
if err != nil {
return nil, nil, err
}
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
commits := new([]*RepositoryCommit)
resp, err := s.client.Do(req, commits)
if err != nil {
return nil, resp, err
}
return *commits, resp, err
}
// ListFiles lists the files in a pull request.
//
// GitHub API docs: https://developer.github.com/v3/pulls/#list-pull-requests-files
func (s *PullRequestsService) ListFiles(owner string, repo string, number int, opt *ListOptions) ([]*CommitFile, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/pulls/%d/files", owner, repo, number)
u, err := addOptions(u, opt)
if err != nil {
return nil, nil, err
}
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
commitFiles := new([]*CommitFile)
resp, err := s.client.Do(req, commitFiles)
if err != nil {
return nil, resp, err
}
return *commitFiles, resp, err
}
// IsMerged checks if a pull request has been merged.
//
// GitHub API docs: https://developer.github.com/v3/pulls/#get-if-a-pull-request-has-been-merged
func (s *PullRequestsService) IsMerged(owner string, repo string, number int) (bool, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/pulls/%d/merge", owner, repo, number)
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return false, nil, err
}
resp, err := s.client.Do(req, nil)
merged, err := parseBoolResponse(err)
return merged, resp, err
}
// PullRequestMergeResult represents the result of merging a pull request.
type PullRequestMergeResult struct {
SHA *string `json:"sha,omitempty"`
Merged *bool `json:"merged,omitempty"`
Message *string `json:"message,omitempty"`
}
// PullRequestOptions lets you define how a pull request will be merged.
type PullRequestOptions struct {
Squash bool
}
type pullRequestMergeRequest struct {
CommitMessage *string `json:"commit_message"`
Squash *bool `json:"squash,omitempty"`
}
// Merge a pull request (Merge Button™).
//
// GitHub API docs: https://developer.github.com/v3/pulls/#merge-a-pull-request-merge-buttontrade
func (s *PullRequestsService) Merge(owner string, repo string, number int, commitMessage string, options *PullRequestOptions) (*PullRequestMergeResult, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/pulls/%d/merge", owner, repo, number)
pullRequestBody := &pullRequestMergeRequest{CommitMessage: &commitMessage}
if options != nil {
pullRequestBody.Squash = &options.Squash
}
req, err := s.client.NewRequest("PUT", u, pullRequestBody)
// TODO: This header will be unnecessary when the API is no longer in preview.
req.Header.Set("Accept", mediaTypeSquashPreview)
if err != nil {
return nil, nil, err
}
mergeResult := new(PullRequestMergeResult)
resp, err := s.client.Do(req, mergeResult)
if err != nil {
return nil, resp, err
}
return mergeResult, resp, err
}

156
vendor/src/github.com/google/go-github/github/pulls_comments.go

@ -0,0 +1,156 @@
// Copyright 2013 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github
import (
"fmt"
"time"
)
// PullRequestComment represents a comment left on a pull request.
type PullRequestComment struct {
ID *int `json:"id,omitempty"`
InReplyTo *int `json:"in_reply_to,omitempty"`
Body *string `json:"body,omitempty"`
Path *string `json:"path,omitempty"`
DiffHunk *string `json:"diff_hunk,omitempty"`
Position *int `json:"position,omitempty"`
OriginalPosition *int `json:"original_position,omitempty"`
CommitID *string `json:"commit_id,omitempty"`
OriginalCommitID *string `json:"original_commit_id,omitempty"`
User *User `json:"user,omitempty"`
Reactions *Reactions `json:"reactions,omitempty"`
CreatedAt *time.Time `json:"created_at,omitempty"`
UpdatedAt *time.Time `json:"updated_at,omitempty"`
URL *string `json:"url,omitempty"`
HTMLURL *string `json:"html_url,omitempty"`
PullRequestURL *string `json:"pull_request_url,omitempty"`
}
func (p PullRequestComment) String() string {
return Stringify(p)
}
// PullRequestListCommentsOptions specifies the optional parameters to the
// PullRequestsService.ListComments method.
type PullRequestListCommentsOptions struct {
// Sort specifies how to sort comments. Possible values are: created, updated.
Sort string `url:"sort,omitempty"`
// Direction in which to sort comments. Possible values are: asc, desc.
Direction string `url:"direction,omitempty"`
// Since filters comments by time.
Since time.Time `url:"since,omitempty"`
ListOptions
}
// ListComments lists all comments on the specified pull request. Specifying a
// pull request number of 0 will return all comments on all pull requests for
// the repository.
//
// GitHub API docs: https://developer.github.com/v3/pulls/comments/#list-comments-on-a-pull-request
func (s *PullRequestsService) ListComments(owner string, repo string, number int, opt *PullRequestListCommentsOptions) ([]*PullRequestComment, *Response, error) {
var u string
if number == 0 {
u = fmt.Sprintf("repos/%v/%v/pulls/comments", owner, repo)
} else {
u = fmt.Sprintf("repos/%v/%v/pulls/%d/comments", owner, repo, number)
}
u, err := addOptions(u, opt)
if err != nil {
return nil, nil, err
}
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
// TODO: remove custom Accept header when this API fully launches.
req.Header.Set("Accept", mediaTypeReactionsPreview)
comments := new([]*PullRequestComment)
resp, err := s.client.Do(req, comments)
if err != nil {
return nil, resp, err
}
return *comments, resp, err
}
// GetComment fetches the specified pull request comment.
//
// GitHub API docs: https://developer.github.com/v3/pulls/comments/#get-a-single-comment
func (s *PullRequestsService) GetComment(owner string, repo string, number int) (*PullRequestComment, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/pulls/comments/%d", owner, repo, number)
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
// TODO: remove custom Accept header when this API fully launches.
req.Header.Set("Accept", mediaTypeReactionsPreview)
comment := new(PullRequestComment)
resp, err := s.client.Do(req, comment)
if err != nil {
return nil, resp, err
}
return comment, resp, err
}
// CreateComment creates a new comment on the specified pull request.
//
// GitHub API docs: https://developer.github.com/v3/pulls/comments/#create-a-comment
func (s *PullRequestsService) CreateComment(owner string, repo string, number int, comment *PullRequestComment) (*PullRequestComment, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/pulls/%d/comments", owner, repo, number)
req, err := s.client.NewRequest("POST", u, comment)
if err != nil {
return nil, nil, err
}
c := new(PullRequestComment)
resp, err := s.client.Do(req, c)
if err != nil {
return nil, resp, err
}
return c, resp, err
}
// EditComment updates a pull request comment.
//
// GitHub API docs: https://developer.github.com/v3/pulls/comments/#edit-a-comment
func (s *PullRequestsService) EditComment(owner string, repo string, number int, comment *PullRequestComment) (*PullRequestComment, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/pulls/comments/%d", owner, repo, number)
req, err := s.client.NewRequest("PATCH", u, comment)
if err != nil {
return nil, nil, err
}
c := new(PullRequestComment)
resp, err := s.client.Do(req, c)
if err != nil {
return nil, resp, err
}
return c, resp, err
}
// DeleteComment deletes a pull request comment.
//
// GitHub API docs: https://developer.github.com/v3/pulls/comments/#delete-a-comment
func (s *PullRequestsService) DeleteComment(owner string, repo string, number int) (*Response, error) {
u := fmt.Sprintf("repos/%v/%v/pulls/comments/%d", owner, repo, number)
req, err := s.client.NewRequest("DELETE", u, nil)
if err != nil {
return nil, err
}
return s.client.Do(req, nil)
}

187
vendor/src/github.com/google/go-github/github/pulls_comments_test.go

@ -0,0 +1,187 @@
// Copyright 2013 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github
import (
"encoding/json"
"fmt"
"net/http"
"reflect"
"testing"
"time"
)
func TestPullRequestsService_ListComments_allPulls(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/pulls/comments", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testHeader(t, r, "Accept", mediaTypeReactionsPreview)
testFormValues(t, r, values{
"sort": "updated",
"direction": "desc",
"since": "2002-02-10T15:30:00Z",
"page": "2",
})
fmt.Fprint(w, `[{"id":1}]`)
})
opt := &PullRequestListCommentsOptions{
Sort: "updated",
Direction: "desc",
Since: time.Date(2002, time.February, 10, 15, 30, 0, 0, time.UTC),
ListOptions: ListOptions{Page: 2},
}
pulls, _, err := client.PullRequests.ListComments("o", "r", 0, opt)
if err != nil {
t.Errorf("PullRequests.ListComments returned error: %v", err)
}
want := []*PullRequestComment{{ID: Int(1)}}
if !reflect.DeepEqual(pulls, want) {
t.Errorf("PullRequests.ListComments returned %+v, want %+v", pulls, want)
}
}
func TestPullRequestsService_ListComments_specificPull(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/pulls/1/comments", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testHeader(t, r, "Accept", mediaTypeReactionsPreview)
fmt.Fprint(w, `[{"id":1}]`)
})
pulls, _, err := client.PullRequests.ListComments("o", "r", 1, nil)
if err != nil {
t.Errorf("PullRequests.ListComments returned error: %v", err)
}
want := []*PullRequestComment{{ID: Int(1)}}
if !reflect.DeepEqual(pulls, want) {
t.Errorf("PullRequests.ListComments returned %+v, want %+v", pulls, want)
}
}
func TestPullRequestsService_ListComments_invalidOwner(t *testing.T) {
_, _, err := client.PullRequests.ListComments("%", "r", 1, nil)
testURLParseError(t, err)
}
func TestPullRequestsService_GetComment(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/pulls/comments/1", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testHeader(t, r, "Accept", mediaTypeReactionsPreview)
fmt.Fprint(w, `{"id":1}`)
})
comment, _, err := client.PullRequests.GetComment("o", "r", 1)
if err != nil {
t.Errorf("PullRequests.GetComment returned error: %v", err)
}
want := &PullRequestComment{ID: Int(1)}
if !reflect.DeepEqual(comment, want) {
t.Errorf("PullRequests.GetComment returned %+v, want %+v", comment, want)
}
}
func TestPullRequestsService_GetComment_invalidOwner(t *testing.T) {
_, _, err := client.PullRequests.GetComment("%", "r", 1)
testURLParseError(t, err)
}
func TestPullRequestsService_CreateComment(t *testing.T) {
setup()
defer teardown()
input := &PullRequestComment{Body: String("b")}
mux.HandleFunc("/repos/o/r/pulls/1/comments", func(w http.ResponseWriter, r *http.Request) {
v := new(PullRequestComment)
json.NewDecoder(r.Body).Decode(v)
testMethod(t, r, "POST")
if !reflect.DeepEqual(v, input) {
t.Errorf("Request body = %+v, want %+v", v, input)
}
fmt.Fprint(w, `{"id":1}`)
})
comment, _, err := client.PullRequests.CreateComment("o", "r", 1, input)
if err != nil {
t.Errorf("PullRequests.CreateComment returned error: %v", err)
}
want := &PullRequestComment{ID: Int(1)}
if !reflect.DeepEqual(comment, want) {
t.Errorf("PullRequests.CreateComment returned %+v, want %+v", comment, want)
}
}
func TestPullRequestsService_CreateComment_invalidOwner(t *testing.T) {
_, _, err := client.PullRequests.CreateComment("%", "r", 1, nil)
testURLParseError(t, err)
}
func TestPullRequestsService_EditComment(t *testing.T) {
setup()
defer teardown()
input := &PullRequestComment{Body: String("b")}
mux.HandleFunc("/repos/o/r/pulls/comments/1", func(w http.ResponseWriter, r *http.Request) {
v := new(PullRequestComment)
json.NewDecoder(r.Body).Decode(v)
testMethod(t, r, "PATCH")
if !reflect.DeepEqual(v, input) {
t.Errorf("Request body = %+v, want %+v", v, input)
}
fmt.Fprint(w, `{"id":1}`)
})
comment, _, err := client.PullRequests.EditComment("o", "r", 1, input)
if err != nil {
t.Errorf("PullRequests.EditComment returned error: %v", err)
}
want := &PullRequestComment{ID: Int(1)}
if !reflect.DeepEqual(comment, want) {
t.Errorf("PullRequests.EditComment returned %+v, want %+v", comment, want)
}
}
func TestPullRequestsService_EditComment_invalidOwner(t *testing.T) {
_, _, err := client.PullRequests.EditComment("%", "r", 1, nil)
testURLParseError(t, err)
}
func TestPullRequestsService_DeleteComment(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/pulls/comments/1", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "DELETE")
})
_, err := client.PullRequests.DeleteComment("o", "r", 1)
if err != nil {
t.Errorf("PullRequests.DeleteComment returned error: %v", err)
}
}
func TestPullRequestsService_DeleteComment_invalidOwner(t *testing.T) {
_, err := client.PullRequests.DeleteComment("%", "r", 1)
testURLParseError(t, err)
}

363
vendor/src/github.com/google/go-github/github/pulls_test.go

@ -0,0 +1,363 @@
// Copyright 2013 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github
import (
"encoding/json"
"fmt"
"net/http"
"reflect"
"testing"
)
func TestPullRequestsService_List(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/pulls", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testFormValues(t, r, values{
"state": "closed",
"head": "h",
"base": "b",
"sort": "created",
"direction": "desc",
"page": "2",
})
fmt.Fprint(w, `[{"number":1}]`)
})
opt := &PullRequestListOptions{"closed", "h", "b", "created", "desc", ListOptions{Page: 2}}
pulls, _, err := client.PullRequests.List("o", "r", opt)
if err != nil {
t.Errorf("PullRequests.List returned error: %v", err)
}
want := []*PullRequest{{Number: Int(1)}}
if !reflect.DeepEqual(pulls, want) {
t.Errorf("PullRequests.List returned %+v, want %+v", pulls, want)
}
}
func TestPullRequestsService_List_invalidOwner(t *testing.T) {
_, _, err := client.PullRequests.List("%", "r", nil)
testURLParseError(t, err)
}
func TestPullRequestsService_Get(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/pulls/1", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
fmt.Fprint(w, `{"number":1}`)
})
pull, _, err := client.PullRequests.Get("o", "r", 1)
if err != nil {
t.Errorf("PullRequests.Get returned error: %v", err)
}
want := &PullRequest{Number: Int(1)}
if !reflect.DeepEqual(pull, want) {
t.Errorf("PullRequests.Get returned %+v, want %+v", pull, want)
}
}
func TestPullRequestsService_Get_headAndBase(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/pulls/1", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
fmt.Fprint(w, `{"number":1,"head":{"ref":"r2","repo":{"id":2}},"base":{"ref":"r1","repo":{"id":1}}}`)
})
pull, _, err := client.PullRequests.Get("o", "r", 1)
if err != nil {
t.Errorf("PullRequests.Get returned error: %v", err)
}
want := &PullRequest{
Number: Int(1),
Head: &PullRequestBranch{
Ref: String("r2"),
Repo: &Repository{ID: Int(2)},
},
Base: &PullRequestBranch{
Ref: String("r1"),
Repo: &Repository{ID: Int(1)},
},
}
if !reflect.DeepEqual(pull, want) {
t.Errorf("PullRequests.Get returned %+v, want %+v", pull, want)
}
}
func TestPullRequestService_Get_DiffURLAndPatchURL(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/pulls/1", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
fmt.Fprint(w, `{"number":1,
"diff_url": "https://github.com/octocat/Hello-World/pull/1347.diff",
"patch_url": "https://github.com/octocat/Hello-World/pull/1347.patch"}`)
})
pull, _, err := client.PullRequests.Get("o", "r", 1)
if err != nil {
t.Errorf("PullRequests.Get returned error: %v", err)
}
want := &PullRequest{Number: Int(1), DiffURL: String("https://github.com/octocat/Hello-World/pull/1347.diff"), PatchURL: String("https://github.com/octocat/Hello-World/pull/1347.patch")}
if !reflect.DeepEqual(pull, want) {
t.Errorf("PullRequests.Get returned %+v, want %+v", pull, want)
}
}
func TestPullRequestsService_Get_invalidOwner(t *testing.T) {
_, _, err := client.PullRequests.Get("%", "r", 1)
testURLParseError(t, err)
}
func TestPullRequestsService_Create(t *testing.T) {
setup()
defer teardown()
input := &NewPullRequest{Title: String("t")}
mux.HandleFunc("/repos/o/r/pulls", func(w http.ResponseWriter, r *http.Request) {
v := new(NewPullRequest)
json.NewDecoder(r.Body).Decode(v)
testMethod(t, r, "POST")
if !reflect.DeepEqual(v, input) {
t.Errorf("Request body = %+v, want %+v", v, input)
}
fmt.Fprint(w, `{"number":1}`)
})
pull, _, err := client.PullRequests.Create("o", "r", input)
if err != nil {
t.Errorf("PullRequests.Create returned error: %v", err)
}
want := &PullRequest{Number: Int(1)}
if !reflect.DeepEqual(pull, want) {
t.Errorf("PullRequests.Create returned %+v, want %+v", pull, want)
}
}
func TestPullRequestsService_Create_invalidOwner(t *testing.T) {
_, _, err := client.PullRequests.Create("%", "r", nil)
testURLParseError(t, err)
}
func TestPullRequestsService_Edit(t *testing.T) {
setup()
defer teardown()
input := &PullRequest{Title: String("t")}
mux.HandleFunc("/repos/o/r/pulls/1", func(w http.ResponseWriter, r *http.Request) {
v := new(PullRequest)
json.NewDecoder(r.Body).Decode(v)
testMethod(t, r, "PATCH")
if !reflect.DeepEqual(v, input) {
t.Errorf("Request body = %+v, want %+v", v, input)
}
fmt.Fprint(w, `{"number":1}`)
})
pull, _, err := client.PullRequests.Edit("o", "r", 1, input)
if err != nil {
t.Errorf("PullRequests.Edit returned error: %v", err)
}
want := &PullRequest{Number: Int(1)}
if !reflect.DeepEqual(pull, want) {
t.Errorf("PullRequests.Edit returned %+v, want %+v", pull, want)
}
}
func TestPullRequestsService_Edit_invalidOwner(t *testing.T) {
_, _, err := client.PullRequests.Edit("%", "r", 1, nil)
testURLParseError(t, err)
}
func TestPullRequestsService_ListCommits(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/pulls/1/commits", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testFormValues(t, r, values{"page": "2"})
fmt.Fprint(w, `
[
{
"sha": "3",
"parents": [
{
"sha": "2"
}
]
},
{
"sha": "2",
"parents": [
{
"sha": "1"
}
]
}
]`)
})
opt := &ListOptions{Page: 2}
commits, _, err := client.PullRequests.ListCommits("o", "r", 1, opt)
if err != nil {
t.Errorf("PullRequests.ListCommits returned error: %v", err)
}
want := []*RepositoryCommit{
{
SHA: String("3"),
Parents: []Commit{
{
SHA: String("2"),
},
},
},
{
SHA: String("2"),
Parents: []Commit{
{
SHA: String("1"),
},
},
},
}
if !reflect.DeepEqual(commits, want) {
t.Errorf("PullRequests.ListCommits returned %+v, want %+v", commits, want)
}
}
func TestPullRequestsService_ListFiles(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/pulls/1/files", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testFormValues(t, r, values{"page": "2"})
fmt.Fprint(w, `
[
{
"sha": "6dcb09b5b57875f334f61aebed695e2e4193db5e",
"filename": "file1.txt",
"status": "added",
"additions": 103,
"deletions": 21,
"changes": 124,
"patch": "@@ -132,7 +132,7 @@ module Test @@ -1000,7 +1000,7 @@ module Test"
},
{
"sha": "f61aebed695e2e4193db5e6dcb09b5b57875f334",
"filename": "file2.txt",
"status": "modified",
"additions": 5,
"deletions": 3,
"changes": 103,
"patch": "@@ -132,7 +132,7 @@ module Test @@ -1000,7 +1000,7 @@ module Test"
}
]`)
})
opt := &ListOptions{Page: 2}
commitFiles, _, err := client.PullRequests.ListFiles("o", "r", 1, opt)
if err != nil {
t.Errorf("PullRequests.ListFiles returned error: %v", err)
}
want := []*CommitFile{
{
SHA: String("6dcb09b5b57875f334f61aebed695e2e4193db5e"),
Filename: String("file1.txt"),
Additions: Int(103),
Deletions: Int(21),
Changes: Int(124),
Status: String("added"),
Patch: String("@@ -132,7 +132,7 @@ module Test @@ -1000,7 +1000,7 @@ module Test"),
},
{
SHA: String("f61aebed695e2e4193db5e6dcb09b5b57875f334"),
Filename: String("file2.txt"),
Additions: Int(5),
Deletions: Int(3),
Changes: Int(103),
Status: String("modified"),
Patch: String("@@ -132,7 +132,7 @@ module Test @@ -1000,7 +1000,7 @@ module Test"),
},
}
if !reflect.DeepEqual(commitFiles, want) {
t.Errorf("PullRequests.ListFiles returned %+v, want %+v", commitFiles, want)
}
}
func TestPullRequestsService_IsMerged(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/pulls/1/merge", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
w.WriteHeader(http.StatusNoContent)
})
isMerged, _, err := client.PullRequests.IsMerged("o", "r", 1)
if err != nil {
t.Errorf("PullRequests.IsMerged returned error: %v", err)
}
want := true
if !reflect.DeepEqual(isMerged, want) {
t.Errorf("PullRequests.IsMerged returned %+v, want %+v", isMerged, want)
}
}
func TestPullRequestsService_Merge(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/pulls/1/merge", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "PUT")
testHeader(t, r, "Accept", mediaTypeSquashPreview)
fmt.Fprint(w, `
{
"sha": "6dcb09b5b57875f334f61aebed695e2e4193db5e",
"merged": true,
"message": "Pull Request successfully merged"
}`)
})
options := &PullRequestOptions{Squash: true}
merge, _, err := client.PullRequests.Merge("o", "r", 1, "merging pull request", options)
if err != nil {
t.Errorf("PullRequests.Merge returned error: %v", err)
}
want := &PullRequestMergeResult{
SHA: String("6dcb09b5b57875f334f61aebed695e2e4193db5e"),
Merged: Bool(true),
Message: String("Pull Request successfully merged"),
}
if !reflect.DeepEqual(merge, want) {
t.Errorf("PullRequests.Merge returned %+v, want %+v", merge, want)
}
}

270
vendor/src/github.com/google/go-github/github/reactions.go

@ -0,0 +1,270 @@
// Copyright 2016 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github
import "fmt"
// ReactionsService provides access to the reactions-related functions in the
// GitHub API.
//
// GitHub API docs: https://developer.github.com/v3/reactions/
type ReactionsService service
// Reaction represents a GitHub reaction.
type Reaction struct {
// ID is the Reaction ID.
ID *int `json:"id,omitempty"`
User *User `json:"user,omitempty"`
// Content is the type of reaction.
// Possible values are:
// "+1", "-1", "laugh", "confused", "heart", "hooray".
Content *string `json:"content,omitempty"`
}
// Reactions represents a summary of GitHub reactions.
type Reactions struct {
TotalCount *int `json:"total_count,omitempty"`
PlusOne *int `json:"+1,omitempty"`
MinusOne *int `json:"-1,omitempty"`
Laugh *int `json:"laugh,omitempty"`
Confused *int `json:"confused,omitempty"`
Heart *int `json:"heart,omitempty"`
Hooray *int `json:"hooray,omitempty"`
URL *string `json:"url,omitempty"`
}
func (r Reaction) String() string {
return Stringify(r)
}
// ListCommentReactions lists the reactions for a commit comment.
//
// GitHub API docs: https://developer.github.com/v3/reactions/#list-reactions-for-a-commit-comment
func (s *ReactionsService) ListCommentReactions(owner, repo string, id int, opt *ListOptions) ([]*Reaction, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/comments/%v/reactions", owner, repo, id)
u, err := addOptions(u, opt)
if err != nil {
return nil, nil, err
}
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
// TODO: remove custom Accept header when this API fully launches.
req.Header.Set("Accept", mediaTypeReactionsPreview)
var m []*Reaction
resp, err := s.client.Do(req, &m)
if err != nil {
return nil, resp, err
}
return m, resp, nil
}
// CreateCommentReaction creates a reaction for a commit comment.
// Note that if you have already created a reaction of type content, the
// previously created reaction will be returned with Status: 200 OK.
//
// GitHub API docs: https://developer.github.com/v3/reactions/#create-reaction-for-a-commit-comment
func (s ReactionsService) CreateCommentReaction(owner, repo string, id int, content string) (*Reaction, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/comments/%v/reactions", owner, repo, id)
body := &Reaction{Content: String(content)}
req, err := s.client.NewRequest("POST", u, body)
if err != nil {
return nil, nil, err
}
// TODO: remove custom Accept header when this API fully launches.
req.Header.Set("Accept", mediaTypeReactionsPreview)
m := &Reaction{}
resp, err := s.client.Do(req, m)
if err != nil {
return nil, resp, err
}
return m, resp, nil
}
// ListIssueReactions lists the reactions for an issue.
//
// GitHub API docs: https://developer.github.com/v3/reactions/#list-reactions-for-an-issue
func (s *ReactionsService) ListIssueReactions(owner, repo string, number int, opt *ListOptions) ([]*Reaction, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/issues/%v/reactions", owner, repo, number)
u, err := addOptions(u, opt)
if err != nil {
return nil, nil, err
}
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
// TODO: remove custom Accept header when this API fully launches.
req.Header.Set("Accept", mediaTypeReactionsPreview)
var m []*Reaction
resp, err := s.client.Do(req, &m)
if err != nil {
return nil, resp, err
}
return m, resp, nil
}
// CreateIssueReaction creates a reaction for an issue.
// Note that if you have already created a reaction of type content, the
// previously created reaction will be returned with Status: 200 OK.
//
// GitHub API docs: https://developer.github.com/v3/reactions/#create-reaction-for-an-issue
func (s ReactionsService) CreateIssueReaction(owner, repo string, number int, content string) (*Reaction, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/issues/%v/reactions", owner, repo, number)
body := &Reaction{Content: String(content)}
req, err := s.client.NewRequest("POST", u, body)
if err != nil {
return nil, nil, err
}
// TODO: remove custom Accept header when this API fully launches.
req.Header.Set("Accept", mediaTypeReactionsPreview)
m := &Reaction{}
resp, err := s.client.Do(req, m)
if err != nil {
return nil, resp, err
}
return m, resp, nil
}
// ListIssueCommentReactions lists the reactions for an issue comment.
//
// GitHub API docs: https://developer.github.com/v3/reactions/#list-reactions-for-an-issue-comment
func (s *ReactionsService) ListIssueCommentReactions(owner, repo string, id int, opt *ListOptions) ([]*Reaction, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/issues/comments/%v/reactions", owner, repo, id)
u, err := addOptions(u, opt)
if err != nil {
return nil, nil, err
}
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
// TODO: remove custom Accept header when this API fully launches.
req.Header.Set("Accept", mediaTypeReactionsPreview)
var m []*Reaction
resp, err := s.client.Do(req, &m)
if err != nil {
return nil, resp, err
}
return m, resp, nil
}
// CreateIssueCommentReaction creates a reaction for an issue comment.
// Note that if you have already created a reaction of type content, the
// previously created reaction will be returned with Status: 200 OK.
//
// GitHub API docs: https://developer.github.com/v3/reactions/#create-reaction-for-an-issue-comment
func (s ReactionsService) CreateIssueCommentReaction(owner, repo string, id int, content string) (*Reaction, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/issues/comments/%v/reactions", owner, repo, id)
body := &Reaction{Content: String(content)}
req, err := s.client.NewRequest("POST", u, body)
if err != nil {
return nil, nil, err
}
// TODO: remove custom Accept header when this API fully launches.
req.Header.Set("Accept", mediaTypeReactionsPreview)
m := &Reaction{}
resp, err := s.client.Do(req, m)
if err != nil {
return nil, resp, err
}
return m, resp, nil
}
// ListPullRequestCommentReactions lists the reactions for a pull request review comment.
//
// GitHub API docs: https://developer.github.com/v3/reactions/#list-reactions-for-an-issue-comment
func (s *ReactionsService) ListPullRequestCommentReactions(owner, repo string, id int, opt *ListOptions) ([]*Reaction, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/pulls/comments/%v/reactions", owner, repo, id)
u, err := addOptions(u, opt)
if err != nil {
return nil, nil, err
}
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
// TODO: remove custom Accept header when this API fully launches.
req.Header.Set("Accept", mediaTypeReactionsPreview)
var m []*Reaction
resp, err := s.client.Do(req, &m)
if err != nil {
return nil, resp, err
}
return m, resp, nil
}
// CreatePullRequestCommentReaction creates a reaction for a pull request review comment.
// Note that if you have already created a reaction of type content, the
// previously created reaction will be returned with Status: 200 OK.
//
// GitHub API docs: https://developer.github.com/v3/reactions/#create-reaction-for-an-issue-comment
func (s ReactionsService) CreatePullRequestCommentReaction(owner, repo string, id int, content string) (*Reaction, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/pulls/comments/%v/reactions", owner, repo, id)
body := &Reaction{Content: String(content)}
req, err := s.client.NewRequest("POST", u, body)
if err != nil {
return nil, nil, err
}
// TODO: remove custom Accept header when this API fully launches.
req.Header.Set("Accept", mediaTypeReactionsPreview)
m := &Reaction{}
resp, err := s.client.Do(req, m)
if err != nil {
return nil, resp, err
}
return m, resp, nil
}
// DeleteReaction deletes a reaction.
//
// GitHub API docs: https://developer.github.com/v3/reaction/reactions/#delete-a-reaction-archive
func (s *ReactionsService) DeleteReaction(id int) (*Response, error) {
u := fmt.Sprintf("reactions/%v", id)
req, err := s.client.NewRequest("DELETE", u, nil)
if err != nil {
return nil, err
}
// TODO: remove custom Accept header when this API fully launches.
req.Header.Set("Accept", mediaTypeReactionsPreview)
return s.client.Do(req, nil)
}

200
vendor/src/github.com/google/go-github/github/reactions_test.go

@ -0,0 +1,200 @@
// Copyright 2016 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github
import (
"net/http"
"reflect"
"testing"
)
func TestReactionsService_ListCommentReactions(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/comments/1/reactions", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testHeader(t, r, "Accept", mediaTypeReactionsPreview)
w.WriteHeader(http.StatusOK)
w.Write([]byte(`[{"id":1,"user":{"login":"l","id":2},"content":"+1"}]`))
})
got, _, err := client.Reactions.ListCommentReactions("o", "r", 1, nil)
if err != nil {
t.Errorf("ListCommentReactions returned error: %v", err)
}
if want := []*Reaction{{ID: Int(1), User: &User{Login: String("l"), ID: Int(2)}, Content: String("+1")}}; !reflect.DeepEqual(got, want) {
t.Errorf("ListCommentReactions = %+v, want %+v", got, want)
}
}
func TestReactionsService_CreateCommentReaction(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/comments/1/reactions", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "POST")
testHeader(t, r, "Accept", mediaTypeReactionsPreview)
w.WriteHeader(http.StatusCreated)
w.Write([]byte(`{"id":1,"user":{"login":"l","id":2},"content":"+1"}`))
})
got, _, err := client.Reactions.CreateCommentReaction("o", "r", 1, "+1")
if err != nil {
t.Errorf("CreateCommentReaction returned error: %v", err)
}
want := &Reaction{ID: Int(1), User: &User{Login: String("l"), ID: Int(2)}, Content: String("+1")}
if !reflect.DeepEqual(got, want) {
t.Errorf("CreateCommentReaction = %+v, want %+v", got, want)
}
}
func TestReactionsService_ListIssueReactions(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/issues/1/reactions", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testHeader(t, r, "Accept", mediaTypeReactionsPreview)
w.WriteHeader(http.StatusOK)
w.Write([]byte(`[{"id":1,"user":{"login":"l","id":2},"content":"+1"}]`))
})
got, _, err := client.Reactions.ListIssueReactions("o", "r", 1, nil)
if err != nil {
t.Errorf("ListIssueReactions returned error: %v", err)
}
if want := []*Reaction{{ID: Int(1), User: &User{Login: String("l"), ID: Int(2)}, Content: String("+1")}}; !reflect.DeepEqual(got, want) {
t.Errorf("ListIssueReactions = %+v, want %+v", got, want)
}
}
func TestReactionsService_CreateIssueReaction(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/issues/1/reactions", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "POST")
testHeader(t, r, "Accept", mediaTypeReactionsPreview)
w.WriteHeader(http.StatusCreated)
w.Write([]byte(`{"id":1,"user":{"login":"l","id":2},"content":"+1"}`))
})
got, _, err := client.Reactions.CreateIssueReaction("o", "r", 1, "+1")
if err != nil {
t.Errorf("CreateIssueReaction returned error: %v", err)
}
want := &Reaction{ID: Int(1), User: &User{Login: String("l"), ID: Int(2)}, Content: String("+1")}
if !reflect.DeepEqual(got, want) {
t.Errorf("CreateIssueReaction = %+v, want %+v", got, want)
}
}
func TestReactionsService_ListIssueCommentReactions(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/issues/comments/1/reactions", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testHeader(t, r, "Accept", mediaTypeReactionsPreview)
w.WriteHeader(http.StatusOK)
w.Write([]byte(`[{"id":1,"user":{"login":"l","id":2},"content":"+1"}]`))
})
got, _, err := client.Reactions.ListIssueCommentReactions("o", "r", 1, nil)
if err != nil {
t.Errorf("ListIssueCommentReactions returned error: %v", err)
}
if want := []*Reaction{{ID: Int(1), User: &User{Login: String("l"), ID: Int(2)}, Content: String("+1")}}; !reflect.DeepEqual(got, want) {
t.Errorf("ListIssueCommentReactions = %+v, want %+v", got, want)
}
}
func TestReactionsService_CreateIssueCommentReaction(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/issues/comments/1/reactions", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "POST")
testHeader(t, r, "Accept", mediaTypeReactionsPreview)
w.WriteHeader(http.StatusCreated)
w.Write([]byte(`{"id":1,"user":{"login":"l","id":2},"content":"+1"}`))
})
got, _, err := client.Reactions.CreateIssueCommentReaction("o", "r", 1, "+1")
if err != nil {
t.Errorf("CreateIssueCommentReaction returned error: %v", err)
}
want := &Reaction{ID: Int(1), User: &User{Login: String("l"), ID: Int(2)}, Content: String("+1")}
if !reflect.DeepEqual(got, want) {
t.Errorf("CreateIssueCommentReaction = %+v, want %+v", got, want)
}
}
func TestReactionsService_ListPullRequestCommentReactions(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/pulls/comments/1/reactions", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testHeader(t, r, "Accept", mediaTypeReactionsPreview)
w.WriteHeader(http.StatusOK)
w.Write([]byte(`[{"id":1,"user":{"login":"l","id":2},"content":"+1"}]`))
})
got, _, err := client.Reactions.ListPullRequestCommentReactions("o", "r", 1, nil)
if err != nil {
t.Errorf("ListPullRequestCommentReactions returned error: %v", err)
}
if want := []*Reaction{{ID: Int(1), User: &User{Login: String("l"), ID: Int(2)}, Content: String("+1")}}; !reflect.DeepEqual(got, want) {
t.Errorf("ListPullRequestCommentReactions = %+v, want %+v", got, want)
}
}
func TestReactionsService_CreatePullRequestCommentReaction(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/pulls/comments/1/reactions", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "POST")
testHeader(t, r, "Accept", mediaTypeReactionsPreview)
w.WriteHeader(http.StatusCreated)
w.Write([]byte(`{"id":1,"user":{"login":"l","id":2},"content":"+1"}`))
})
got, _, err := client.Reactions.CreatePullRequestCommentReaction("o", "r", 1, "+1")
if err != nil {
t.Errorf("CreatePullRequestCommentReaction returned error: %v", err)
}
want := &Reaction{ID: Int(1), User: &User{Login: String("l"), ID: Int(2)}, Content: String("+1")}
if !reflect.DeepEqual(got, want) {
t.Errorf("CreatePullRequestCommentReaction = %+v, want %+v", got, want)
}
}
func TestReactionsService_DeleteReaction(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/reactions/1", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "DELETE")
testHeader(t, r, "Accept", mediaTypeReactionsPreview)
w.WriteHeader(http.StatusNoContent)
})
if _, err := client.Reactions.DeleteReaction(1); err != nil {
t.Errorf("DeleteReaction returned error: %v", err)
}
}

597
vendor/src/github.com/google/go-github/github/repos.go

@ -0,0 +1,597 @@
// Copyright 2013 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github
import "fmt"
// RepositoriesService handles communication with the repository related
// methods of the GitHub API.
//
// GitHub API docs: http://developer.github.com/v3/repos/
type RepositoriesService service
// Repository represents a GitHub repository.
type Repository struct {
ID *int `json:"id,omitempty"`
Owner *User `json:"owner,omitempty"`
Name *string `json:"name,omitempty"`
FullName *string `json:"full_name,omitempty"`
Description *string `json:"description,omitempty"`
Homepage *string `json:"homepage,omitempty"`
DefaultBranch *string `json:"default_branch,omitempty"`
MasterBranch *string `json:"master_branch,omitempty"`
CreatedAt *Timestamp `json:"created_at,omitempty"`
PushedAt *Timestamp `json:"pushed_at,omitempty"`
UpdatedAt *Timestamp `json:"updated_at,omitempty"`
HTMLURL *string `json:"html_url,omitempty"`
CloneURL *string `json:"clone_url,omitempty"`
GitURL *string `json:"git_url,omitempty"`
MirrorURL *string `json:"mirror_url,omitempty"`
SSHURL *string `json:"ssh_url,omitempty"`
SVNURL *string `json:"svn_url,omitempty"`
Language *string `json:"language,omitempty"`
Fork *bool `json:"fork"`
ForksCount *int `json:"forks_count,omitempty"`
NetworkCount *int `json:"network_count,omitempty"`
OpenIssuesCount *int `json:"open_issues_count,omitempty"`
StargazersCount *int `json:"stargazers_count,omitempty"`
SubscribersCount *int `json:"subscribers_count,omitempty"`
WatchersCount *int `json:"watchers_count,omitempty"`
Size *int `json:"size,omitempty"`
AutoInit *bool `json:"auto_init,omitempty"`
Parent *Repository `json:"parent,omitempty"`
Source *Repository `json:"source,omitempty"`
Organization *Organization `json:"organization,omitempty"`
Permissions *map[string]bool `json:"permissions,omitempty"`
// Only provided when using RepositoriesService.Get while in preview
License *License `json:"license,omitempty"`
// Additional mutable fields when creating and editing a repository
Private *bool `json:"private"`
HasIssues *bool `json:"has_issues"`
HasWiki *bool `json:"has_wiki"`
HasDownloads *bool `json:"has_downloads"`
// Creating an organization repository. Required for non-owners.
TeamID *int `json:"team_id"`
// API URLs
URL *string `json:"url,omitempty"`
ArchiveURL *string `json:"archive_url,omitempty"`
AssigneesURL *string `json:"assignees_url,omitempty"`
BlobsURL *string `json:"blobs_url,omitempty"`
BranchesURL *string `json:"branches_url,omitempty"`
CollaboratorsURL *string `json:"collaborators_url,omitempty"`
CommentsURL *string `json:"comments_url,omitempty"`
CommitsURL *string `json:"commits_url,omitempty"`
CompareURL *string `json:"compare_url,omitempty"`
ContentsURL *string `json:"contents_url,omitempty"`
ContributorsURL *string `json:"contributors_url,omitempty"`
DownloadsURL *string `json:"downloads_url,omitempty"`
EventsURL *string `json:"events_url,omitempty"`
ForksURL *string `json:"forks_url,omitempty"`
GitCommitsURL *string `json:"git_commits_url,omitempty"`
GitRefsURL *string `json:"git_refs_url,omitempty"`
GitTagsURL *string `json:"git_tags_url,omitempty"`
HooksURL *string `json:"hooks_url,omitempty"`
IssueCommentURL *string `json:"issue_comment_url,omitempty"`
IssueEventsURL *string `json:"issue_events_url,omitempty"`
IssuesURL *string `json:"issues_url,omitempty"`
KeysURL *string `json:"keys_url,omitempty"`
LabelsURL *string `json:"labels_url,omitempty"`
LanguagesURL *string `json:"languages_url,omitempty"`
MergesURL *string `json:"merges_url,omitempty"`
MilestonesURL *string `json:"milestones_url,omitempty"`
NotificationsURL *string `json:"notifications_url,omitempty"`
PullsURL *string `json:"pulls_url,omitempty"`
ReleasesURL *string `json:"releases_url,omitempty"`
StargazersURL *string `json:"stargazers_url,omitempty"`
StatusesURL *string `json:"statuses_url,omitempty"`
SubscribersURL *string `json:"subscribers_url,omitempty"`
SubscriptionURL *string `json:"subscription_url,omitempty"`
TagsURL *string `json:"tags_url,omitempty"`
TreesURL *string `json:"trees_url,omitempty"`
TeamsURL *string `json:"teams_url,omitempty"`
// TextMatches is only populated from search results that request text matches
// See: search.go and https://developer.github.com/v3/search/#text-match-metadata
TextMatches []TextMatch `json:"text_matches,omitempty"`
}
func (r Repository) String() string {
return Stringify(r)
}
// RepositoryListOptions specifies the optional parameters to the
// RepositoriesService.List method.
type RepositoryListOptions struct {
// Visibility of repositories to list. Can be one of all, public, or private.
// Default: all
Visibility string `url:"visibility,omitempty"`
// List repos of given affiliation[s].
// Comma-separated list of values. Can include:
// * owner: Repositories that are owned by the authenticated user.
// * collaborator: Repositories that the user has been added to as a
// collaborator.
// * organization_member: Repositories that the user has access to through
// being a member of an organization. This includes every repository on
// every team that the user is on.
// Default: owner,collaborator,organization_member
Affiliation string `url:"affiliation,omitempty"`
// Type of repositories to list.
// Can be one of all, owner, public, private, member. Default: all
// Will cause a 422 error if used in the same request as visibility or
// affiliation.
Type string `url:"type,omitempty"`
// How to sort the repository list. Can be one of created, updated, pushed,
// full_name. Default: full_name
Sort string `url:"sort,omitempty"`
// Direction in which to sort repositories. Can be one of asc or desc.
// Default: when using full_name: asc; otherwise desc
Direction string `url:"direction,omitempty"`
ListOptions
}
// List the repositories for a user. Passing the empty string will list
// repositories for the authenticated user.
//
// GitHub API docs: http://developer.github.com/v3/repos/#list-user-repositories
func (s *RepositoriesService) List(user string, opt *RepositoryListOptions) ([]*Repository, *Response, error) {
var u string
if user != "" {
u = fmt.Sprintf("users/%v/repos", user)
} else {
u = "user/repos"
}
u, err := addOptions(u, opt)
if err != nil {
return nil, nil, err
}
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
// TODO: remove custom Accept header when license support fully launches
req.Header.Set("Accept", mediaTypeLicensesPreview)
repos := new([]*Repository)
resp, err := s.client.Do(req, repos)
if err != nil {
return nil, resp, err
}
return *repos, resp, err
}
// RepositoryListByOrgOptions specifies the optional parameters to the
// RepositoriesService.ListByOrg method.
type RepositoryListByOrgOptions struct {
// Type of repositories to list. Possible values are: all, public, private,
// forks, sources, member. Default is "all".
Type string `url:"type,omitempty"`
ListOptions
}
// ListByOrg lists the repositories for an organization.
//
// GitHub API docs: http://developer.github.com/v3/repos/#list-organization-repositories
func (s *RepositoriesService) ListByOrg(org string, opt *RepositoryListByOrgOptions) ([]*Repository, *Response, error) {
u := fmt.Sprintf("orgs/%v/repos", org)
u, err := addOptions(u, opt)
if err != nil {
return nil, nil, err
}
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
// TODO: remove custom Accept header when license support fully launches
req.Header.Set("Accept", mediaTypeLicensesPreview)
repos := new([]*Repository)
resp, err := s.client.Do(req, repos)
if err != nil {
return nil, resp, err
}
return *repos, resp, err
}
// RepositoryListAllOptions specifies the optional parameters to the
// RepositoriesService.ListAll method.
type RepositoryListAllOptions struct {
// ID of the last repository seen
Since int `url:"since,omitempty"`
ListOptions
}
// ListAll lists all GitHub repositories in the order that they were created.
//
// GitHub API docs: http://developer.github.com/v3/repos/#list-all-public-repositories
func (s *RepositoriesService) ListAll(opt *RepositoryListAllOptions) ([]*Repository, *Response, error) {
u, err := addOptions("repositories", opt)
if err != nil {
return nil, nil, err
}
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
repos := new([]*Repository)
resp, err := s.client.Do(req, repos)
if err != nil {
return nil, resp, err
}
return *repos, resp, err
}
// Create a new repository. If an organization is specified, the new
// repository will be created under that org. If the empty string is
// specified, it will be created for the authenticated user.
//
// GitHub API docs: http://developer.github.com/v3/repos/#create
func (s *RepositoriesService) Create(org string, repo *Repository) (*Repository, *Response, error) {
var u string
if org != "" {
u = fmt.Sprintf("orgs/%v/repos", org)
} else {
u = "user/repos"
}
req, err := s.client.NewRequest("POST", u, repo)
if err != nil {
return nil, nil, err
}
r := new(Repository)
resp, err := s.client.Do(req, r)
if err != nil {
return nil, resp, err
}
return r, resp, err
}
// Get fetches a repository.
//
// GitHub API docs: http://developer.github.com/v3/repos/#get
func (s *RepositoriesService) Get(owner, repo string) (*Repository, *Response, error) {
u := fmt.Sprintf("repos/%v/%v", owner, repo)
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
// TODO: remove custom Accept header when the license support fully launches
// https://developer.github.com/v3/licenses/#get-a-repositorys-license
req.Header.Set("Accept", mediaTypeLicensesPreview)
repository := new(Repository)
resp, err := s.client.Do(req, repository)
if err != nil {
return nil, resp, err
}
return repository, resp, err
}
// GetByID fetches a repository.
//
// Note: GetByID uses the undocumented GitHub API endpoint /repositories/:id.
func (s *RepositoriesService) GetByID(id int) (*Repository, *Response, error) {
u := fmt.Sprintf("repositories/%d", id)
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
// TODO: remove custom Accept header when the license support fully launches
// https://developer.github.com/v3/licenses/#get-a-repositorys-license
req.Header.Set("Accept", mediaTypeLicensesPreview)
repository := new(Repository)
resp, err := s.client.Do(req, repository)
if err != nil {
return nil, resp, err
}
return repository, resp, err
}
// Edit updates a repository.
//
// GitHub API docs: http://developer.github.com/v3/repos/#edit
func (s *RepositoriesService) Edit(owner, repo string, repository *Repository) (*Repository, *Response, error) {
u := fmt.Sprintf("repos/%v/%v", owner, repo)
req, err := s.client.NewRequest("PATCH", u, repository)
if err != nil {
return nil, nil, err
}
r := new(Repository)
resp, err := s.client.Do(req, r)
if err != nil {
return nil, resp, err
}
return r, resp, err
}
// Delete a repository.
//
// GitHub API docs: https://developer.github.com/v3/repos/#delete-a-repository
func (s *RepositoriesService) Delete(owner, repo string) (*Response, error) {
u := fmt.Sprintf("repos/%v/%v", owner, repo)
req, err := s.client.NewRequest("DELETE", u, nil)
if err != nil {
return nil, err
}
return s.client.Do(req, nil)
}
// Contributor represents a repository contributor
type Contributor struct {
Login *string `json:"login,omitempty"`
ID *int `json:"id,omitempty"`
AvatarURL *string `json:"avatar_url,omitempty"`
GravatarID *string `json:"gravatar_id,omitempty"`
URL *string `json:"url,omitempty"`
HTMLURL *string `json:"html_url,omitempty"`
FollowersURL *string `json:"followers_url,omitempty"`
FollowingURL *string `json:"following_url,omitempty"`
GistsURL *string `json:"gists_url,omitempty"`
StarredURL *string `json:"starred_url,omitempty"`
SubscriptionsURL *string `json:"subscriptions_url,omitempty"`
OrganizationsURL *string `json:"organizations_url,omitempty"`
ReposURL *string `json:"repos_url,omitempty"`
EventsURL *string `json:"events_url,omitempty"`
ReceivedEventsURL *string `json:"received_events_url,omitempty"`
Type *string `json:"type,omitempty"`
SiteAdmin *bool `json:"site_admin"`
Contributions *int `json:"contributions,omitempty"`
}
// ListContributorsOptions specifies the optional parameters to the
// RepositoriesService.ListContributors method.
type ListContributorsOptions struct {
// Include anonymous contributors in results or not
Anon string `url:"anon,omitempty"`
ListOptions
}
// ListContributors lists contributors for a repository.
//
// GitHub API docs: http://developer.github.com/v3/repos/#list-contributors
func (s *RepositoriesService) ListContributors(owner string, repository string, opt *ListContributorsOptions) ([]*Contributor, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/contributors", owner, repository)
u, err := addOptions(u, opt)
if err != nil {
return nil, nil, err
}
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
contributor := new([]*Contributor)
resp, err := s.client.Do(req, contributor)
if err != nil {
return nil, nil, err
}
return *contributor, resp, err
}
// ListLanguages lists languages for the specified repository. The returned map
// specifies the languages and the number of bytes of code written in that
// language. For example:
//
// {
// "C": 78769,
// "Python": 7769
// }
//
// GitHub API Docs: http://developer.github.com/v3/repos/#list-languages
func (s *RepositoriesService) ListLanguages(owner string, repo string) (map[string]int, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/languages", owner, repo)
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
languages := make(map[string]int)
resp, err := s.client.Do(req, &languages)
if err != nil {
return nil, resp, err
}
return languages, resp, err
}
// ListTeams lists the teams for the specified repository.
//
// GitHub API docs: https://developer.github.com/v3/repos/#list-teams
func (s *RepositoriesService) ListTeams(owner string, repo string, opt *ListOptions) ([]*Team, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/teams", owner, repo)
u, err := addOptions(u, opt)
if err != nil {
return nil, nil, err
}
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
teams := new([]*Team)
resp, err := s.client.Do(req, teams)
if err != nil {
return nil, resp, err
}
return *teams, resp, err
}
// RepositoryTag represents a repository tag.
type RepositoryTag struct {
Name *string `json:"name,omitempty"`
Commit *Commit `json:"commit,omitempty"`
ZipballURL *string `json:"zipball_url,omitempty"`
TarballURL *string `json:"tarball_url,omitempty"`
}
// ListTags lists tags for the specified repository.
//
// GitHub API docs: https://developer.github.com/v3/repos/#list-tags
func (s *RepositoriesService) ListTags(owner string, repo string, opt *ListOptions) ([]*RepositoryTag, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/tags", owner, repo)
u, err := addOptions(u, opt)
if err != nil {
return nil, nil, err
}
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
tags := new([]*RepositoryTag)
resp, err := s.client.Do(req, tags)
if err != nil {
return nil, resp, err
}
return *tags, resp, err
}
// Branch represents a repository branch
type Branch struct {
Name *string `json:"name,omitempty"`
Commit *Commit `json:"commit,omitempty"`
Protection *Protection `json:"protection,omitempty"`
}
// Protection represents a repository branch's protection
type Protection struct {
Enabled *bool `json:"enabled,omitempty"`
RequiredStatusChecks *RequiredStatusChecks `json:"required_status_checks,omitempty"`
}
// RequiredStatusChecks represents the protection status of a individual branch
type RequiredStatusChecks struct {
// Who required status checks apply to.
// Possible values are:
// off
// non_admins
// everyone
EnforcementLevel *string `json:"enforcement_level,omitempty"`
// The list of status checks which are required
Contexts *[]string `json:"contexts,omitempty"`
}
// ListBranches lists branches for the specified repository.
//
// GitHub API docs: http://developer.github.com/v3/repos/#list-branches
func (s *RepositoriesService) ListBranches(owner string, repo string, opt *ListOptions) ([]*Branch, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/branches", owner, repo)
u, err := addOptions(u, opt)
if err != nil {
return nil, nil, err
}
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
req.Header.Set("Accept", mediaTypeProtectedBranchesPreview)
branches := new([]*Branch)
resp, err := s.client.Do(req, branches)
if err != nil {
return nil, resp, err
}
return *branches, resp, err
}
// GetBranch gets the specified branch for a repository.
//
// GitHub API docs: https://developer.github.com/v3/repos/#get-branch
func (s *RepositoriesService) GetBranch(owner, repo, branch string) (*Branch, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/branches/%v", owner, repo, branch)
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
req.Header.Set("Accept", mediaTypeProtectedBranchesPreview)
b := new(Branch)
resp, err := s.client.Do(req, b)
if err != nil {
return nil, resp, err
}
return b, resp, err
}
// EditBranch edits the branch (currently only Branch Protection)
//
// GitHub API docs: https://developer.github.com/v3/repos/#enabling-and-disabling-branch-protection
func (s *RepositoriesService) EditBranch(owner, repo, branchName string, branch *Branch) (*Branch, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/branches/%v", owner, repo, branchName)
req, err := s.client.NewRequest("PATCH", u, branch)
if err != nil {
return nil, nil, err
}
req.Header.Set("Accept", mediaTypeProtectedBranchesPreview)
b := new(Branch)
resp, err := s.client.Do(req, b)
if err != nil {
return nil, resp, err
}
return b, resp, err
}
// License gets the contents of a repository's license if one is detected.
//
// GitHub API docs: https://developer.github.com/v3/licenses/#get-the-contents-of-a-repositorys-license
func (s *RepositoriesService) License(owner, repo string) (*License, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/license", owner, repo)
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
r := &Repository{}
resp, err := s.client.Do(req, r)
if err != nil {
return nil, resp, err
}
return r.License, resp, err
}

92
vendor/src/github.com/google/go-github/github/repos_collaborators.go

@ -0,0 +1,92 @@
// Copyright 2013 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github
import "fmt"
// ListCollaborators lists the Github users that have access to the repository.
//
// GitHub API docs: http://developer.github.com/v3/repos/collaborators/#list
func (s *RepositoriesService) ListCollaborators(owner, repo string, opt *ListOptions) ([]*User, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/collaborators", owner, repo)
u, err := addOptions(u, opt)
if err != nil {
return nil, nil, err
}
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
users := new([]*User)
resp, err := s.client.Do(req, users)
if err != nil {
return nil, resp, err
}
return *users, resp, err
}
// IsCollaborator checks whether the specified Github user has collaborator
// access to the given repo.
// Note: This will return false if the user is not a collaborator OR the user
// is not a GitHub user.
//
// GitHub API docs: http://developer.github.com/v3/repos/collaborators/#get
func (s *RepositoriesService) IsCollaborator(owner, repo, user string) (bool, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/collaborators/%v", owner, repo, user)
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return false, nil, err
}
resp, err := s.client.Do(req, nil)
isCollab, err := parseBoolResponse(err)
return isCollab, resp, err
}
// RepositoryAddCollaboratorOptions specifies the optional parameters to the
// RepositoriesService.AddCollaborator method.
type RepositoryAddCollaboratorOptions struct {
// Permission specifies the permission to grant the user on this repository.
// Possible values are:
// pull - team members can pull, but not push to or administer this repository
// push - team members can pull and push, but not administer this repository
// admin - team members can pull, push and administer this repository
//
// Default value is "push". This option is only valid for organization-owned repositories.
Permission string `json:"permission,omitempty"`
}
// AddCollaborator adds the specified Github user as collaborator to the given repo.
//
// GitHub API docs: https://developer.github.com/v3/repos/collaborators/#add-user-as-a-collaborator
func (s *RepositoriesService) AddCollaborator(owner, repo, user string, opt *RepositoryAddCollaboratorOptions) (*Response, error) {
u := fmt.Sprintf("repos/%v/%v/collaborators/%v", owner, repo, user)
req, err := s.client.NewRequest("PUT", u, opt)
if err != nil {
return nil, err
}
// TODO: remove custom Accept header when this API fully launches.
req.Header.Set("Accept", mediaTypeRepositoryInvitationsPreview)
return s.client.Do(req, nil)
}
// RemoveCollaborator removes the specified Github user as collaborator from the given repo.
// Note: Does not return error if a valid user that is not a collaborator is removed.
//
// GitHub API docs: http://developer.github.com/v3/repos/collaborators/#remove-collaborator
func (s *RepositoriesService) RemoveCollaborator(owner, repo, user string) (*Response, error) {
u := fmt.Sprintf("repos/%v/%v/collaborators/%v", owner, repo, user)
req, err := s.client.NewRequest("DELETE", u, nil)
if err != nil {
return nil, err
}
return s.client.Do(req, nil)
}

134
vendor/src/github.com/google/go-github/github/repos_collaborators_test.go

@ -0,0 +1,134 @@
// Copyright 2013 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github
import (
"encoding/json"
"fmt"
"net/http"
"reflect"
"testing"
)
func TestRepositoriesService_ListCollaborators(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/collaborators", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testFormValues(t, r, values{"page": "2"})
fmt.Fprintf(w, `[{"id":1}, {"id":2}]`)
})
opt := &ListOptions{Page: 2}
users, _, err := client.Repositories.ListCollaborators("o", "r", opt)
if err != nil {
t.Errorf("Repositories.ListCollaborators returned error: %v", err)
}
want := []*User{{ID: Int(1)}, {ID: Int(2)}}
if !reflect.DeepEqual(users, want) {
t.Errorf("Repositories.ListCollaborators returned %+v, want %+v", users, want)
}
}
func TestRepositoriesService_ListCollaborators_invalidOwner(t *testing.T) {
_, _, err := client.Repositories.ListCollaborators("%", "%", nil)
testURLParseError(t, err)
}
func TestRepositoriesService_IsCollaborator_True(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/collaborators/u", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
w.WriteHeader(http.StatusNoContent)
})
isCollab, _, err := client.Repositories.IsCollaborator("o", "r", "u")
if err != nil {
t.Errorf("Repositories.IsCollaborator returned error: %v", err)
}
if !isCollab {
t.Errorf("Repositories.IsCollaborator returned false, want true")
}
}
func TestRepositoriesService_IsCollaborator_False(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/collaborators/u", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
w.WriteHeader(http.StatusNotFound)
})
isCollab, _, err := client.Repositories.IsCollaborator("o", "r", "u")
if err != nil {
t.Errorf("Repositories.IsCollaborator returned error: %v", err)
}
if isCollab {
t.Errorf("Repositories.IsCollaborator returned true, want false")
}
}
func TestRepositoriesService_IsCollaborator_invalidUser(t *testing.T) {
_, _, err := client.Repositories.IsCollaborator("%", "%", "%")
testURLParseError(t, err)
}
func TestRepositoriesService_AddCollaborator(t *testing.T) {
setup()
defer teardown()
opt := &RepositoryAddCollaboratorOptions{Permission: "admin"}
mux.HandleFunc("/repos/o/r/collaborators/u", func(w http.ResponseWriter, r *http.Request) {
v := new(RepositoryAddCollaboratorOptions)
json.NewDecoder(r.Body).Decode(v)
testMethod(t, r, "PUT")
testHeader(t, r, "Accept", mediaTypeRepositoryInvitationsPreview)
if !reflect.DeepEqual(v, opt) {
t.Errorf("Request body = %+v, want %+v", v, opt)
}
w.WriteHeader(http.StatusNoContent)
})
_, err := client.Repositories.AddCollaborator("o", "r", "u", opt)
if err != nil {
t.Errorf("Repositories.AddCollaborator returned error: %v", err)
}
}
func TestRepositoriesService_AddCollaborator_invalidUser(t *testing.T) {
_, err := client.Repositories.AddCollaborator("%", "%", "%", nil)
testURLParseError(t, err)
}
func TestRepositoriesService_RemoveCollaborator(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/collaborators/u", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "DELETE")
w.WriteHeader(http.StatusNoContent)
})
_, err := client.Repositories.RemoveCollaborator("o", "r", "u")
if err != nil {
t.Errorf("Repositories.RemoveCollaborator returned error: %v", err)
}
}
func TestRepositoriesService_RemoveCollaborator_invalidUser(t *testing.T) {
_, err := client.Repositories.RemoveCollaborator("%", "%", "%")
testURLParseError(t, err)
}

160
vendor/src/github.com/google/go-github/github/repos_comments.go

@ -0,0 +1,160 @@
// Copyright 2013 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github
import (
"fmt"
"time"
)
// RepositoryComment represents a comment for a commit, file, or line in a repository.
type RepositoryComment struct {
HTMLURL *string `json:"html_url,omitempty"`
URL *string `json:"url,omitempty"`
ID *int `json:"id,omitempty"`
CommitID *string `json:"commit_id,omitempty"`
User *User `json:"user,omitempty"`
Reactions *Reactions `json:"reactions,omitempty"`
CreatedAt *time.Time `json:"created_at,omitempty"`
UpdatedAt *time.Time `json:"updated_at,omitempty"`
// User-mutable fields
Body *string `json:"body"`
// User-initialized fields
Path *string `json:"path,omitempty"`
Position *int `json:"position,omitempty"`
}
func (r RepositoryComment) String() string {
return Stringify(r)
}
// ListComments lists all the comments for the repository.
//
// GitHub API docs: http://developer.github.com/v3/repos/comments/#list-commit-comments-for-a-repository
func (s *RepositoriesService) ListComments(owner, repo string, opt *ListOptions) ([]*RepositoryComment, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/comments", owner, repo)
u, err := addOptions(u, opt)
if err != nil {
return nil, nil, err
}
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
// TODO: remove custom Accept header when this API fully launches.
req.Header.Set("Accept", mediaTypeReactionsPreview)
comments := new([]*RepositoryComment)
resp, err := s.client.Do(req, comments)
if err != nil {
return nil, resp, err
}
return *comments, resp, err
}
// ListCommitComments lists all the comments for a given commit SHA.
//
// GitHub API docs: http://developer.github.com/v3/repos/comments/#list-comments-for-a-single-commit
func (s *RepositoriesService) ListCommitComments(owner, repo, sha string, opt *ListOptions) ([]*RepositoryComment, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/commits/%v/comments", owner, repo, sha)
u, err := addOptions(u, opt)
if err != nil {
return nil, nil, err
}
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
// TODO: remove custom Accept header when this API fully launches.
req.Header.Set("Accept", mediaTypeReactionsPreview)
comments := new([]*RepositoryComment)
resp, err := s.client.Do(req, comments)
if err != nil {
return nil, resp, err
}
return *comments, resp, err
}
// CreateComment creates a comment for the given commit.
// Note: GitHub allows for comments to be created for non-existing files and positions.
//
// GitHub API docs: http://developer.github.com/v3/repos/comments/#create-a-commit-comment
func (s *RepositoriesService) CreateComment(owner, repo, sha string, comment *RepositoryComment) (*RepositoryComment, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/commits/%v/comments", owner, repo, sha)
req, err := s.client.NewRequest("POST", u, comment)
if err != nil {
return nil, nil, err
}
c := new(RepositoryComment)
resp, err := s.client.Do(req, c)
if err != nil {
return nil, resp, err
}
return c, resp, err
}
// GetComment gets a single comment from a repository.
//
// GitHub API docs: http://developer.github.com/v3/repos/comments/#get-a-single-commit-comment
func (s *RepositoriesService) GetComment(owner, repo string, id int) (*RepositoryComment, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/comments/%v", owner, repo, id)
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
// TODO: remove custom Accept header when this API fully launches.
req.Header.Set("Accept", mediaTypeReactionsPreview)
c := new(RepositoryComment)
resp, err := s.client.Do(req, c)
if err != nil {
return nil, resp, err
}
return c, resp, err
}
// UpdateComment updates the body of a single comment.
//
// GitHub API docs: http://developer.github.com/v3/repos/comments/#update-a-commit-comment
func (s *RepositoriesService) UpdateComment(owner, repo string, id int, comment *RepositoryComment) (*RepositoryComment, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/comments/%v", owner, repo, id)
req, err := s.client.NewRequest("PATCH", u, comment)
if err != nil {
return nil, nil, err
}
c := new(RepositoryComment)
resp, err := s.client.Do(req, c)
if err != nil {
return nil, resp, err
}
return c, resp, err
}
// DeleteComment deletes a single comment from a repository.
//
// GitHub API docs: http://developer.github.com/v3/repos/comments/#delete-a-commit-comment
func (s *RepositoriesService) DeleteComment(owner, repo string, id int) (*Response, error) {
u := fmt.Sprintf("repos/%v/%v/comments/%v", owner, repo, id)
req, err := s.client.NewRequest("DELETE", u, nil)
if err != nil {
return nil, err
}
return s.client.Do(req, nil)
}

183
vendor/src/github.com/google/go-github/github/repos_comments_test.go

@ -0,0 +1,183 @@
// Copyright 2013 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github
import (
"encoding/json"
"fmt"
"net/http"
"reflect"
"testing"
)
func TestRepositoriesService_ListComments(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/comments", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testHeader(t, r, "Accept", mediaTypeReactionsPreview)
testFormValues(t, r, values{"page": "2"})
fmt.Fprint(w, `[{"id":1}, {"id":2}]`)
})
opt := &ListOptions{Page: 2}
comments, _, err := client.Repositories.ListComments("o", "r", opt)
if err != nil {
t.Errorf("Repositories.ListComments returned error: %v", err)
}
want := []*RepositoryComment{{ID: Int(1)}, {ID: Int(2)}}
if !reflect.DeepEqual(comments, want) {
t.Errorf("Repositories.ListComments returned %+v, want %+v", comments, want)
}
}
func TestRepositoriesService_ListComments_invalidOwner(t *testing.T) {
_, _, err := client.Repositories.ListComments("%", "%", nil)
testURLParseError(t, err)
}
func TestRepositoriesService_ListCommitComments(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/commits/s/comments", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testHeader(t, r, "Accept", mediaTypeReactionsPreview)
testFormValues(t, r, values{"page": "2"})
fmt.Fprint(w, `[{"id":1}, {"id":2}]`)
})
opt := &ListOptions{Page: 2}
comments, _, err := client.Repositories.ListCommitComments("o", "r", "s", opt)
if err != nil {
t.Errorf("Repositories.ListCommitComments returned error: %v", err)
}
want := []*RepositoryComment{{ID: Int(1)}, {ID: Int(2)}}
if !reflect.DeepEqual(comments, want) {
t.Errorf("Repositories.ListCommitComments returned %+v, want %+v", comments, want)
}
}
func TestRepositoriesService_ListCommitComments_invalidOwner(t *testing.T) {
_, _, err := client.Repositories.ListCommitComments("%", "%", "%", nil)
testURLParseError(t, err)
}
func TestRepositoriesService_CreateComment(t *testing.T) {
setup()
defer teardown()
input := &RepositoryComment{Body: String("b")}
mux.HandleFunc("/repos/o/r/commits/s/comments", func(w http.ResponseWriter, r *http.Request) {
v := new(RepositoryComment)
json.NewDecoder(r.Body).Decode(v)
testMethod(t, r, "POST")
if !reflect.DeepEqual(v, input) {
t.Errorf("Request body = %+v, want %+v", v, input)
}
fmt.Fprint(w, `{"id":1}`)
})
comment, _, err := client.Repositories.CreateComment("o", "r", "s", input)
if err != nil {
t.Errorf("Repositories.CreateComment returned error: %v", err)
}
want := &RepositoryComment{ID: Int(1)}
if !reflect.DeepEqual(comment, want) {
t.Errorf("Repositories.CreateComment returned %+v, want %+v", comment, want)
}
}
func TestRepositoriesService_CreateComment_invalidOwner(t *testing.T) {
_, _, err := client.Repositories.CreateComment("%", "%", "%", nil)
testURLParseError(t, err)
}
func TestRepositoriesService_GetComment(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/comments/1", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testHeader(t, r, "Accept", mediaTypeReactionsPreview)
fmt.Fprint(w, `{"id":1}`)
})
comment, _, err := client.Repositories.GetComment("o", "r", 1)
if err != nil {
t.Errorf("Repositories.GetComment returned error: %v", err)
}
want := &RepositoryComment{ID: Int(1)}
if !reflect.DeepEqual(comment, want) {
t.Errorf("Repositories.GetComment returned %+v, want %+v", comment, want)
}
}
func TestRepositoriesService_GetComment_invalidOwner(t *testing.T) {
_, _, err := client.Repositories.GetComment("%", "%", 1)
testURLParseError(t, err)
}
func TestRepositoriesService_UpdateComment(t *testing.T) {
setup()
defer teardown()
input := &RepositoryComment{Body: String("b")}
mux.HandleFunc("/repos/o/r/comments/1", func(w http.ResponseWriter, r *http.Request) {
v := new(RepositoryComment)
json.NewDecoder(r.Body).Decode(v)
testMethod(t, r, "PATCH")
if !reflect.DeepEqual(v, input) {
t.Errorf("Request body = %+v, want %+v", v, input)
}
fmt.Fprint(w, `{"id":1}`)
})
comment, _, err := client.Repositories.UpdateComment("o", "r", 1, input)
if err != nil {
t.Errorf("Repositories.UpdateComment returned error: %v", err)
}
want := &RepositoryComment{ID: Int(1)}
if !reflect.DeepEqual(comment, want) {
t.Errorf("Repositories.UpdateComment returned %+v, want %+v", comment, want)
}
}
func TestRepositoriesService_UpdateComment_invalidOwner(t *testing.T) {
_, _, err := client.Repositories.UpdateComment("%", "%", 1, nil)
testURLParseError(t, err)
}
func TestRepositoriesService_DeleteComment(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/comments/1", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "DELETE")
})
_, err := client.Repositories.DeleteComment("o", "r", 1)
if err != nil {
t.Errorf("Repositories.DeleteComment returned error: %v", err)
}
}
func TestRepositoriesService_DeleteComment_invalidOwner(t *testing.T) {
_, err := client.Repositories.DeleteComment("%", "%", 1)
testURLParseError(t, err)
}

198
vendor/src/github.com/google/go-github/github/repos_commits.go

@ -0,0 +1,198 @@
// Copyright 2013 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github
import (
"bytes"
"fmt"
"time"
)
// RepositoryCommit represents a commit in a repo.
// Note that it's wrapping a Commit, so author/committer information is in two places,
// but contain different details about them: in RepositoryCommit "github details", in Commit - "git details".
type RepositoryCommit struct {
SHA *string `json:"sha,omitempty"`
Commit *Commit `json:"commit,omitempty"`
Author *User `json:"author,omitempty"`
Committer *User `json:"committer,omitempty"`
Parents []Commit `json:"parents,omitempty"`
Message *string `json:"message,omitempty"`
HTMLURL *string `json:"html_url,omitempty"`
// Details about how many changes were made in this commit. Only filled in during GetCommit!
Stats *CommitStats `json:"stats,omitempty"`
// Details about which files, and how this commit touched. Only filled in during GetCommit!
Files []CommitFile `json:"files,omitempty"`
}
func (r RepositoryCommit) String() string {
return Stringify(r)
}
// CommitStats represents the number of additions / deletions from a file in a given RepositoryCommit or GistCommit.
type CommitStats struct {
Additions *int `json:"additions,omitempty"`
Deletions *int `json:"deletions,omitempty"`
Total *int `json:"total,omitempty"`
}
func (c CommitStats) String() string {
return Stringify(c)
}
// CommitFile represents a file modified in a commit.
type CommitFile struct {
SHA *string `json:"sha,omitempty"`
Filename *string `json:"filename,omitempty"`
Additions *int `json:"additions,omitempty"`
Deletions *int `json:"deletions,omitempty"`
Changes *int `json:"changes,omitempty"`
Status *string `json:"status,omitempty"`
Patch *string `json:"patch,omitempty"`
}
func (c CommitFile) String() string {
return Stringify(c)
}
// CommitsComparison is the result of comparing two commits.
// See CompareCommits() for details.
type CommitsComparison struct {
BaseCommit *RepositoryCommit `json:"base_commit,omitempty"`
MergeBaseCommit *RepositoryCommit `json:"merge_base_commit,omitempty"`
// Head can be 'behind' or 'ahead'
Status *string `json:"status,omitempty"`
AheadBy *int `json:"ahead_by,omitempty"`
BehindBy *int `json:"behind_by,omitempty"`
TotalCommits *int `json:"total_commits,omitempty"`
Commits []RepositoryCommit `json:"commits,omitempty"`
Files []CommitFile `json:"files,omitempty"`
}
func (c CommitsComparison) String() string {
return Stringify(c)
}
// CommitsListOptions specifies the optional parameters to the
// RepositoriesService.ListCommits method.
type CommitsListOptions struct {
// SHA or branch to start listing Commits from.
SHA string `url:"sha,omitempty"`
// Path that should be touched by the returned Commits.
Path string `url:"path,omitempty"`
// Author of by which to filter Commits.
Author string `url:"author,omitempty"`
// Since when should Commits be included in the response.
Since time.Time `url:"since,omitempty"`
// Until when should Commits be included in the response.
Until time.Time `url:"until,omitempty"`
ListOptions
}
// ListCommits lists the commits of a repository.
//
// GitHub API docs: http://developer.github.com/v3/repos/commits/#list
func (s *RepositoriesService) ListCommits(owner, repo string, opt *CommitsListOptions) ([]*RepositoryCommit, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/commits", owner, repo)
u, err := addOptions(u, opt)
if err != nil {
return nil, nil, err
}
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
commits := new([]*RepositoryCommit)
resp, err := s.client.Do(req, commits)
if err != nil {
return nil, resp, err
}
return *commits, resp, err
}
// GetCommit fetches the specified commit, including all details about it.
// todo: support media formats - https://github.com/google/go-github/issues/6
//
// GitHub API docs: http://developer.github.com/v3/repos/commits/#get-a-single-commit
// See also: http://developer.github.com//v3/git/commits/#get-a-single-commit provides the same functionality
func (s *RepositoriesService) GetCommit(owner, repo, sha string) (*RepositoryCommit, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/commits/%v", owner, repo, sha)
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
// TODO: remove custom Accept header when this API fully launches.
req.Header.Set("Accept", mediaTypeGitSigningPreview)
commit := new(RepositoryCommit)
resp, err := s.client.Do(req, commit)
if err != nil {
return nil, resp, err
}
return commit, resp, err
}
// GetCommitSHA1 gets the SHA-1 of a commit reference. If a last-known SHA1 is
// supplied and no new commits have occurred, a 304 Unmodified response is returned.
//
// GitHub API docs: https://developer.github.com/v3/repos/commits/#get-the-sha-1-of-a-commit-reference
func (s *RepositoriesService) GetCommitSHA1(owner, repo, ref, lastSHA string) (string, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/commits/%v", owner, repo, ref)
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return "", nil, err
}
if lastSHA != "" {
req.Header.Set("If-None-Match", `"`+lastSHA+`"`)
}
req.Header.Set("Accept", mediaTypeV3SHA)
var buf bytes.Buffer
resp, err := s.client.Do(req, &buf)
if err != nil {
return "", resp, err
}
return buf.String(), resp, err
}
// CompareCommits compares a range of commits with each other.
// todo: support media formats - https://github.com/google/go-github/issues/6
//
// GitHub API docs: http://developer.github.com/v3/repos/commits/index.html#compare-two-commits
func (s *RepositoriesService) CompareCommits(owner, repo string, base, head string) (*CommitsComparison, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/compare/%v...%v", owner, repo, base, head)
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
comp := new(CommitsComparison)
resp, err := s.client.Do(req, comp)
if err != nil {
return nil, resp, err
}
return comp, resp, err
}

233
vendor/src/github.com/google/go-github/github/repos_commits_test.go

@ -0,0 +1,233 @@
// Copyright 2013 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github
import (
"fmt"
"net/http"
"reflect"
"testing"
"time"
)
func TestRepositoriesService_ListCommits(t *testing.T) {
setup()
defer teardown()
// given
mux.HandleFunc("/repos/o/r/commits", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testFormValues(t, r,
values{
"sha": "s",
"path": "p",
"author": "a",
"since": "2013-08-01T00:00:00Z",
"until": "2013-09-03T00:00:00Z",
})
fmt.Fprintf(w, `[{"sha": "s"}]`)
})
opt := &CommitsListOptions{
SHA: "s",
Path: "p",
Author: "a",
Since: time.Date(2013, time.August, 1, 0, 0, 0, 0, time.UTC),
Until: time.Date(2013, time.September, 3, 0, 0, 0, 0, time.UTC),
}
commits, _, err := client.Repositories.ListCommits("o", "r", opt)
if err != nil {
t.Errorf("Repositories.ListCommits returned error: %v", err)
}
want := []*RepositoryCommit{{SHA: String("s")}}
if !reflect.DeepEqual(commits, want) {
t.Errorf("Repositories.ListCommits returned %+v, want %+v", commits, want)
}
}
func TestRepositoriesService_GetCommit(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/commits/s", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testHeader(t, r, "Accept", mediaTypeGitSigningPreview)
fmt.Fprintf(w, `{
"sha": "s",
"commit": { "message": "m" },
"author": { "login": "l" },
"committer": { "login": "l" },
"parents": [ { "sha": "s" } ],
"stats": { "additions": 104, "deletions": 4, "total": 108 },
"files": [
{
"filename": "f",
"additions": 10,
"deletions": 2,
"changes": 12,
"status": "s",
"raw_url": "r",
"blob_url": "b",
"patch": "p"
}
]
}`)
})
commit, _, err := client.Repositories.GetCommit("o", "r", "s")
if err != nil {
t.Errorf("Repositories.GetCommit returned error: %v", err)
}
want := &RepositoryCommit{
SHA: String("s"),
Commit: &Commit{
Message: String("m"),
},
Author: &User{
Login: String("l"),
},
Committer: &User{
Login: String("l"),
},
Parents: []Commit{
{
SHA: String("s"),
},
},
Stats: &CommitStats{
Additions: Int(104),
Deletions: Int(4),
Total: Int(108),
},
Files: []CommitFile{
{
Filename: String("f"),
Additions: Int(10),
Deletions: Int(2),
Changes: Int(12),
Status: String("s"),
Patch: String("p"),
},
},
}
if !reflect.DeepEqual(commit, want) {
t.Errorf("Repositories.GetCommit returned \n%+v, want \n%+v", commit, want)
}
}
func TestRepositoriesService_GetCommitSHA1(t *testing.T) {
setup()
defer teardown()
const sha1 = "01234abcde"
mux.HandleFunc("/repos/o/r/commits/master", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testHeader(t, r, "Accept", mediaTypeV3SHA)
fmt.Fprintf(w, sha1)
})
got, _, err := client.Repositories.GetCommitSHA1("o", "r", "master", "")
if err != nil {
t.Errorf("Repositories.GetCommitSHA1 returned error: %v", err)
}
want := sha1
if got != want {
t.Errorf("Repositories.GetCommitSHA1 = %v, want %v", got, want)
}
mux.HandleFunc("/repos/o/r/commits/tag", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testHeader(t, r, "Accept", mediaTypeV3SHA)
testHeader(t, r, "If-None-Match", `"`+sha1+`"`)
w.WriteHeader(http.StatusNotModified)
})
got, _, err = client.Repositories.GetCommitSHA1("o", "r", "tag", sha1)
if err == nil {
t.Errorf("Expected HTTP 304 response")
}
want = ""
if got != want {
t.Errorf("Repositories.GetCommitSHA1 = %v, want %v", got, want)
}
}
func TestRepositoriesService_CompareCommits(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/compare/b...h", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
fmt.Fprintf(w, `{
"base_commit": {
"sha": "s",
"commit": {
"author": { "name": "n" },
"committer": { "name": "n" },
"message": "m",
"tree": { "sha": "t" }
},
"author": { "login": "n" },
"committer": { "login": "l" },
"parents": [ { "sha": "s" } ]
},
"status": "s",
"ahead_by": 1,
"behind_by": 2,
"total_commits": 1,
"commits": [
{
"sha": "s",
"commit": { "author": { "name": "n" } },
"author": { "login": "l" },
"committer": { "login": "l" },
"parents": [ { "sha": "s" } ]
}
],
"files": [ { "filename": "f" } ]
}`)
})
got, _, err := client.Repositories.CompareCommits("o", "r", "b", "h")
if err != nil {
t.Errorf("Repositories.CompareCommits returned error: %v", err)
}
want := &CommitsComparison{
Status: String("s"),
AheadBy: Int(1),
BehindBy: Int(2),
TotalCommits: Int(1),
BaseCommit: &RepositoryCommit{
Commit: &Commit{
Author: &CommitAuthor{Name: String("n")},
},
Author: &User{Login: String("l")},
Committer: &User{Login: String("l")},
Message: String("m"),
},
Commits: []RepositoryCommit{
{
SHA: String("s"),
},
},
Files: []CommitFile{
{
Filename: String("f"),
},
},
}
if reflect.DeepEqual(got, want) {
t.Errorf("Repositories.CompareCommits returned \n%+v, want \n%+v", got, want)
}
}

275
vendor/src/github.com/google/go-github/github/repos_contents.go

@ -0,0 +1,275 @@
// Copyright 2013 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Repository contents API methods.
// http://developer.github.com/v3/repos/contents/
package github
import (
"encoding/base64"
"encoding/json"
"errors"
"fmt"
"io"
"net/http"
"net/url"
"path"
)
// RepositoryContent represents a file or directory in a github repository.
type RepositoryContent struct {
Type *string `json:"type,omitempty"`
Encoding *string `json:"encoding,omitempty"`
Size *int `json:"size,omitempty"`
Name *string `json:"name,omitempty"`
Path *string `json:"path,omitempty"`
// Content contains the actual file content, which may be encoded.
// Callers should call GetContent which will decode the content if
// necessary.
Content *string `json:"content,omitempty"`
SHA *string `json:"sha,omitempty"`
URL *string `json:"url,omitempty"`
GitURL *string `json:"git_url,omitempty"`
HTMLURL *string `json:"html_url,omitempty"`
DownloadURL *string `json:"download_url,omitempty"`
}
// RepositoryContentResponse holds the parsed response from CreateFile, UpdateFile, and DeleteFile.
type RepositoryContentResponse struct {
Content *RepositoryContent `json:"content,omitempty"`
Commit `json:"commit,omitempty"`
}
// RepositoryContentFileOptions specifies optional parameters for CreateFile, UpdateFile, and DeleteFile.
type RepositoryContentFileOptions struct {
Message *string `json:"message,omitempty"`
Content []byte `json:"content,omitempty"` // unencoded
SHA *string `json:"sha,omitempty"`
Branch *string `json:"branch,omitempty"`
Author *CommitAuthor `json:"author,omitempty"`
Committer *CommitAuthor `json:"committer,omitempty"`
}
// RepositoryContentGetOptions represents an optional ref parameter, which can be a SHA,
// branch, or tag
type RepositoryContentGetOptions struct {
Ref string `url:"ref,omitempty"`
}
// String converts RepositoryContent to a string. It's primarily for testing.
func (r RepositoryContent) String() string {
return Stringify(r)
}
// Decode decodes the file content if it is base64 encoded.
//
// Deprecated: Use GetContent instead.
func (r *RepositoryContent) Decode() ([]byte, error) {
if *r.Encoding != "base64" {
return nil, errors.New("cannot decode non-base64")
}
o, err := base64.StdEncoding.DecodeString(*r.Content)
if err != nil {
return nil, err
}
return o, nil
}
// GetContent returns the content of r, decoding it if necessary.
func (r *RepositoryContent) GetContent() (string, error) {
var encoding string
if r.Encoding != nil {
encoding = *r.Encoding
}
switch encoding {
case "base64":
c, err := base64.StdEncoding.DecodeString(*r.Content)
return string(c), err
case "":
if r.Content == nil {
return "", nil
}
return *r.Content, nil
default:
return "", fmt.Errorf("unsupported content encoding: %v", encoding)
}
}
// GetReadme gets the Readme file for the repository.
//
// GitHub API docs: http://developer.github.com/v3/repos/contents/#get-the-readme
func (s *RepositoriesService) GetReadme(owner, repo string, opt *RepositoryContentGetOptions) (*RepositoryContent, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/readme", owner, repo)
u, err := addOptions(u, opt)
if err != nil {
return nil, nil, err
}
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
readme := new(RepositoryContent)
resp, err := s.client.Do(req, readme)
if err != nil {
return nil, resp, err
}
return readme, resp, err
}
// DownloadContents returns an io.ReadCloser that reads the contents of the
// specified file. This function will work with files of any size, as opposed
// to GetContents which is limited to 1 Mb files. It is the caller's
// responsibility to close the ReadCloser.
func (s *RepositoriesService) DownloadContents(owner, repo, filepath string, opt *RepositoryContentGetOptions) (io.ReadCloser, error) {
dir := path.Dir(filepath)
filename := path.Base(filepath)
_, dirContents, _, err := s.GetContents(owner, repo, dir, opt)
if err != nil {
return nil, err
}
for _, contents := range dirContents {
if *contents.Name == filename {
if contents.DownloadURL == nil || *contents.DownloadURL == "" {
return nil, fmt.Errorf("No download link found for %s", filepath)
}
resp, err := s.client.client.Get(*contents.DownloadURL)
if err != nil {
return nil, err
}
return resp.Body, nil
}
}
return nil, fmt.Errorf("No file named %s found in %s", filename, dir)
}
// GetContents can return either the metadata and content of a single file
// (when path references a file) or the metadata of all the files and/or
// subdirectories of a directory (when path references a directory). To make it
// easy to distinguish between both result types and to mimic the API as much
// as possible, both result types will be returned but only one will contain a
// value and the other will be nil.
//
// GitHub API docs: http://developer.github.com/v3/repos/contents/#get-contents
func (s *RepositoriesService) GetContents(owner, repo, path string, opt *RepositoryContentGetOptions) (fileContent *RepositoryContent, directoryContent []*RepositoryContent, resp *Response, err error) {
escapedPath := (&url.URL{Path: path}).String()
u := fmt.Sprintf("repos/%s/%s/contents/%s", owner, repo, escapedPath)
u, err = addOptions(u, opt)
if err != nil {
return nil, nil, nil, err
}
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, nil, err
}
var rawJSON json.RawMessage
resp, err = s.client.Do(req, &rawJSON)
if err != nil {
return nil, nil, resp, err
}
fileUnmarshalError := json.Unmarshal(rawJSON, &fileContent)
if fileUnmarshalError == nil {
return fileContent, nil, resp, fileUnmarshalError
}
directoryUnmarshalError := json.Unmarshal(rawJSON, &directoryContent)
if directoryUnmarshalError == nil {
return nil, directoryContent, resp, directoryUnmarshalError
}
return nil, nil, resp, fmt.Errorf("unmarshalling failed for both file and directory content: %s and %s ", fileUnmarshalError, directoryUnmarshalError)
}
// CreateFile creates a new file in a repository at the given path and returns
// the commit and file metadata.
//
// GitHub API docs: http://developer.github.com/v3/repos/contents/#create-a-file
func (s *RepositoriesService) CreateFile(owner, repo, path string, opt *RepositoryContentFileOptions) (*RepositoryContentResponse, *Response, error) {
u := fmt.Sprintf("repos/%s/%s/contents/%s", owner, repo, path)
req, err := s.client.NewRequest("PUT", u, opt)
if err != nil {
return nil, nil, err
}
createResponse := new(RepositoryContentResponse)
resp, err := s.client.Do(req, createResponse)
if err != nil {
return nil, resp, err
}
return createResponse, resp, err
}
// UpdateFile updates a file in a repository at the given path and returns the
// commit and file metadata. Requires the blob SHA of the file being updated.
//
// GitHub API docs: http://developer.github.com/v3/repos/contents/#update-a-file
func (s *RepositoriesService) UpdateFile(owner, repo, path string, opt *RepositoryContentFileOptions) (*RepositoryContentResponse, *Response, error) {
u := fmt.Sprintf("repos/%s/%s/contents/%s", owner, repo, path)
req, err := s.client.NewRequest("PUT", u, opt)
if err != nil {
return nil, nil, err
}
updateResponse := new(RepositoryContentResponse)
resp, err := s.client.Do(req, updateResponse)
if err != nil {
return nil, resp, err
}
return updateResponse, resp, err
}
// DeleteFile deletes a file from a repository and returns the commit.
// Requires the blob SHA of the file to be deleted.
//
// GitHub API docs: http://developer.github.com/v3/repos/contents/#delete-a-file
func (s *RepositoriesService) DeleteFile(owner, repo, path string, opt *RepositoryContentFileOptions) (*RepositoryContentResponse, *Response, error) {
u := fmt.Sprintf("repos/%s/%s/contents/%s", owner, repo, path)
req, err := s.client.NewRequest("DELETE", u, opt)
if err != nil {
return nil, nil, err
}
deleteResponse := new(RepositoryContentResponse)
resp, err := s.client.Do(req, deleteResponse)
if err != nil {
return nil, resp, err
}
return deleteResponse, resp, err
}
// archiveFormat is used to define the archive type when calling GetArchiveLink.
type archiveFormat string
const (
// Tarball specifies an archive in gzipped tar format.
Tarball archiveFormat = "tarball"
// Zipball specifies an archive in zip format.
Zipball archiveFormat = "zipball"
)
// GetArchiveLink returns an URL to download a tarball or zipball archive for a
// repository. The archiveFormat can be specified by either the github.Tarball
// or github.Zipball constant.
//
// GitHub API docs: http://developer.github.com/v3/repos/contents/#get-archive-link
func (s *RepositoriesService) GetArchiveLink(owner, repo string, archiveformat archiveFormat, opt *RepositoryContentGetOptions) (*url.URL, *Response, error) {
u := fmt.Sprintf("repos/%s/%s/%s", owner, repo, archiveformat)
if opt != nil && opt.Ref != "" {
u += fmt.Sprintf("/%s", opt.Ref)
}
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
var resp *http.Response
// Use http.DefaultTransport if no custom Transport is configured
if s.client.client.Transport == nil {
resp, err = http.DefaultTransport.RoundTrip(req)
} else {
resp, err = s.client.client.Transport.RoundTrip(req)
}
if err != nil || resp.StatusCode != http.StatusFound {
return nil, newResponse(resp), err
}
parsedURL, err := url.Parse(resp.Header.Get("Location"))
return parsedURL, newResponse(resp), err
}

412
vendor/src/github.com/google/go-github/github/repos_contents_test.go

@ -0,0 +1,412 @@
// Copyright 2014 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github
import (
"fmt"
"io/ioutil"
"net/http"
"reflect"
"testing"
)
func TestRepositoryContent_Decode(t *testing.T) {
tests := []struct {
encoding, content *string // input encoding and content
want string // desired output
wantErr bool // whether an error is expected
}{
{
encoding: String("base64"),
content: String("aGVsbG8="),
want: "hello",
wantErr: false,
},
{
encoding: String("bad"),
content: String("aGVsbG8="),
want: "",
wantErr: true,
},
}
for _, tt := range tests {
r := RepositoryContent{Encoding: tt.encoding, Content: tt.content}
o, err := r.Decode()
if err != nil && !tt.wantErr {
t.Errorf("RepositoryContent(%q, %q) returned unexpected error: %v", tt.encoding, tt.content, err)
}
if err == nil && tt.wantErr {
t.Errorf("RepositoryContent(%q, %q) did not return unexpected error", tt.encoding, tt.content)
}
if got, want := string(o), tt.want; got != want {
t.Errorf("RepositoryContent.Decode returned %+v, want %+v", got, want)
}
}
}
func TestRepositoryContent_GetContent(t *testing.T) {
tests := []struct {
encoding, content *string // input encoding and content
want string // desired output
wantErr bool // whether an error is expected
}{
{
encoding: String(""),
content: String("hello"),
want: "hello",
wantErr: false,
},
{
encoding: nil,
content: String("hello"),
want: "hello",
wantErr: false,
},
{
encoding: nil,
content: nil,
want: "",
wantErr: false,
},
{
encoding: String("base64"),
content: String("aGVsbG8="),
want: "hello",
wantErr: false,
},
{
encoding: String("bad"),
content: String("aGVsbG8="),
want: "",
wantErr: true,
},
}
for _, tt := range tests {
r := RepositoryContent{Encoding: tt.encoding, Content: tt.content}
got, err := r.GetContent()
if err != nil && !tt.wantErr {
t.Errorf("RepositoryContent(%q, %q) returned unexpected error: %v", tt.encoding, tt.content, err)
}
if err == nil && tt.wantErr {
t.Errorf("RepositoryContent(%q, %q) did not return unexpected error", tt.encoding, tt.content)
}
if want := tt.want; got != want {
t.Errorf("RepositoryContent.GetContent returned %+v, want %+v", got, want)
}
}
}
func TestRepositoriesService_GetReadme(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/readme", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
fmt.Fprint(w, `{
"type": "file",
"encoding": "base64",
"size": 5362,
"name": "README.md",
"path": "README.md"
}`)
})
readme, _, err := client.Repositories.GetReadme("o", "r", &RepositoryContentGetOptions{})
if err != nil {
t.Errorf("Repositories.GetReadme returned error: %v", err)
}
want := &RepositoryContent{Type: String("file"), Name: String("README.md"), Size: Int(5362), Encoding: String("base64"), Path: String("README.md")}
if !reflect.DeepEqual(readme, want) {
t.Errorf("Repositories.GetReadme returned %+v, want %+v", readme, want)
}
}
func TestRepositoriesService_DownloadContents_Success(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/contents/d", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
fmt.Fprint(w, `[{
"type": "file",
"name": "f",
"download_url": "`+server.URL+`/download/f"
}]`)
})
mux.HandleFunc("/download/f", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
fmt.Fprint(w, "foo")
})
r, err := client.Repositories.DownloadContents("o", "r", "d/f", nil)
if err != nil {
t.Errorf("Repositories.DownloadContents returned error: %v", err)
}
bytes, err := ioutil.ReadAll(r)
if err != nil {
t.Errorf("Error reading response body: %v", err)
}
r.Close()
if got, want := string(bytes), "foo"; got != want {
t.Errorf("Repositories.DownloadContents returned %v, want %v", got, want)
}
}
func TestRepositoriesService_DownloadContents_NoDownloadURL(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/contents/d", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
fmt.Fprint(w, `[{
"type": "file",
"name": "f",
}]`)
})
_, err := client.Repositories.DownloadContents("o", "r", "d/f", nil)
if err == nil {
t.Errorf("Repositories.DownloadContents did not return expected error")
}
}
func TestRepositoriesService_DownloadContents_NoFile(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/contents/d", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
fmt.Fprint(w, `[]`)
})
_, err := client.Repositories.DownloadContents("o", "r", "d/f", nil)
if err == nil {
t.Errorf("Repositories.DownloadContents did not return expected error")
}
}
func TestRepositoriesService_GetContents_File(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/contents/p", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
fmt.Fprint(w, `{
"type": "file",
"encoding": "base64",
"size": 20678,
"name": "LICENSE",
"path": "LICENSE"
}`)
})
fileContents, _, _, err := client.Repositories.GetContents("o", "r", "p", &RepositoryContentGetOptions{})
if err != nil {
t.Errorf("Repositories.GetContents returned error: %v", err)
}
want := &RepositoryContent{Type: String("file"), Name: String("LICENSE"), Size: Int(20678), Encoding: String("base64"), Path: String("LICENSE")}
if !reflect.DeepEqual(fileContents, want) {
t.Errorf("Repositories.GetContents returned %+v, want %+v", fileContents, want)
}
}
func TestRepositoriesService_GetContents_FilenameNeedsEscape(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/contents/p#?%/中.go", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
fmt.Fprint(w, `{}`)
})
_, _, _, err := client.Repositories.GetContents("o", "r", "p#?%/中.go", &RepositoryContentGetOptions{})
if err != nil {
t.Fatalf("Repositories.GetContents returned error: %v", err)
}
}
func TestRepositoriesService_GetContents_DirectoryWithSpaces(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/contents/some directory/file.go", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
fmt.Fprint(w, `{}`)
})
_, _, _, err := client.Repositories.GetContents("o", "r", "some directory/file.go", &RepositoryContentGetOptions{})
if err != nil {
t.Fatalf("Repositories.GetContents returned error: %v", err)
}
}
func TestRepositoriesService_GetContents_DirectoryWithPlusChars(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/contents/some directory+name/file.go", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
fmt.Fprint(w, `{}`)
})
_, _, _, err := client.Repositories.GetContents("o", "r", "some directory+name/file.go", &RepositoryContentGetOptions{})
if err != nil {
t.Fatalf("Repositories.GetContents returned error: %v", err)
}
}
func TestRepositoriesService_GetContents_Directory(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/contents/p", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
fmt.Fprint(w, `[{
"type": "dir",
"name": "lib",
"path": "lib"
},
{
"type": "file",
"size": 20678,
"name": "LICENSE",
"path": "LICENSE"
}]`)
})
_, directoryContents, _, err := client.Repositories.GetContents("o", "r", "p", &RepositoryContentGetOptions{})
if err != nil {
t.Errorf("Repositories.GetContents returned error: %v", err)
}
want := []*RepositoryContent{{Type: String("dir"), Name: String("lib"), Path: String("lib")},
{Type: String("file"), Name: String("LICENSE"), Size: Int(20678), Path: String("LICENSE")}}
if !reflect.DeepEqual(directoryContents, want) {
t.Errorf("Repositories.GetContents_Directory returned %+v, want %+v", directoryContents, want)
}
}
func TestRepositoriesService_CreateFile(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/contents/p", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "PUT")
fmt.Fprint(w, `{
"content":{
"name":"p"
},
"commit":{
"message":"m",
"sha":"f5f369044773ff9c6383c087466d12adb6fa0828"
}
}`)
})
message := "m"
content := []byte("c")
repositoryContentsOptions := &RepositoryContentFileOptions{
Message: &message,
Content: content,
Committer: &CommitAuthor{Name: String("n"), Email: String("e")},
}
createResponse, _, err := client.Repositories.CreateFile("o", "r", "p", repositoryContentsOptions)
if err != nil {
t.Errorf("Repositories.CreateFile returned error: %v", err)
}
want := &RepositoryContentResponse{
Content: &RepositoryContent{Name: String("p")},
Commit: Commit{
Message: String("m"),
SHA: String("f5f369044773ff9c6383c087466d12adb6fa0828"),
},
}
if !reflect.DeepEqual(createResponse, want) {
t.Errorf("Repositories.CreateFile returned %+v, want %+v", createResponse, want)
}
}
func TestRepositoriesService_UpdateFile(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/contents/p", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "PUT")
fmt.Fprint(w, `{
"content":{
"name":"p"
},
"commit":{
"message":"m",
"sha":"f5f369044773ff9c6383c087466d12adb6fa0828"
}
}`)
})
message := "m"
content := []byte("c")
sha := "f5f369044773ff9c6383c087466d12adb6fa0828"
repositoryContentsOptions := &RepositoryContentFileOptions{
Message: &message,
Content: content,
SHA: &sha,
Committer: &CommitAuthor{Name: String("n"), Email: String("e")},
}
updateResponse, _, err := client.Repositories.UpdateFile("o", "r", "p", repositoryContentsOptions)
if err != nil {
t.Errorf("Repositories.UpdateFile returned error: %v", err)
}
want := &RepositoryContentResponse{
Content: &RepositoryContent{Name: String("p")},
Commit: Commit{
Message: String("m"),
SHA: String("f5f369044773ff9c6383c087466d12adb6fa0828"),
},
}
if !reflect.DeepEqual(updateResponse, want) {
t.Errorf("Repositories.UpdateFile returned %+v, want %+v", updateResponse, want)
}
}
func TestRepositoriesService_DeleteFile(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/contents/p", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "DELETE")
fmt.Fprint(w, `{
"content": null,
"commit":{
"message":"m",
"sha":"f5f369044773ff9c6383c087466d12adb6fa0828"
}
}`)
})
message := "m"
sha := "f5f369044773ff9c6383c087466d12adb6fa0828"
repositoryContentsOptions := &RepositoryContentFileOptions{
Message: &message,
SHA: &sha,
Committer: &CommitAuthor{Name: String("n"), Email: String("e")},
}
deleteResponse, _, err := client.Repositories.DeleteFile("o", "r", "p", repositoryContentsOptions)
if err != nil {
t.Errorf("Repositories.DeleteFile returned error: %v", err)
}
want := &RepositoryContentResponse{
Content: nil,
Commit: Commit{
Message: String("m"),
SHA: String("f5f369044773ff9c6383c087466d12adb6fa0828"),
},
}
if !reflect.DeepEqual(deleteResponse, want) {
t.Errorf("Repositories.DeleteFile returned %+v, want %+v", deleteResponse, want)
}
}
func TestRepositoriesService_GetArchiveLink(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/tarball", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
http.Redirect(w, r, "http://github.com/a", http.StatusFound)
})
url, resp, err := client.Repositories.GetArchiveLink("o", "r", Tarball, &RepositoryContentGetOptions{})
if err != nil {
t.Errorf("Repositories.GetArchiveLink returned error: %v", err)
}
if resp.StatusCode != http.StatusFound {
t.Errorf("Repositories.GetArchiveLink returned status: %d, want %d", resp.StatusCode, http.StatusFound)
}
want := "http://github.com/a"
if url.String() != want {
t.Errorf("Repositories.GetArchiveLink returned %+v, want %+v", url.String(), want)
}
}

179
vendor/src/github.com/google/go-github/github/repos_deployments.go

@ -0,0 +1,179 @@
// Copyright 2014 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github
import (
"encoding/json"
"fmt"
)
// Deployment represents a deployment in a repo
type Deployment struct {
URL *string `json:"url,omitempty"`
ID *int `json:"id,omitempty"`
SHA *string `json:"sha,omitempty"`
Ref *string `json:"ref,omitempty"`
Task *string `json:"task,omitempty"`
Payload json.RawMessage `json:"payload,omitempty"`
Environment *string `json:"environment,omitempty"`
Description *string `json:"description,omitempty"`
Creator *User `json:"creator,omitempty"`
CreatedAt *Timestamp `json:"created_at,omitempty"`
UpdatedAt *Timestamp `json:"pushed_at,omitempty"`
StatusesURL *string `json:"statuses_url,omitempty"`
RepositoryURL *string `json:"repository_url,omitempty"`
}
// DeploymentRequest represents a deployment request
type DeploymentRequest struct {
Ref *string `json:"ref,omitempty"`
Task *string `json:"task,omitempty"`
AutoMerge *bool `json:"auto_merge,omitempty"`
RequiredContexts *[]string `json:"required_contexts,omitempty"`
Payload *string `json:"payload,omitempty"`
Environment *string `json:"environment,omitempty"`
Description *string `json:"description,omitempty"`
TransientEnvironment *bool `json:"transient_environment,omitempty"`
ProductionEnvironment *bool `json:"production_environment,omitempty"`
}
// DeploymentsListOptions specifies the optional parameters to the
// RepositoriesService.ListDeployments method.
type DeploymentsListOptions struct {
// SHA of the Deployment.
SHA string `url:"sha,omitempty"`
// List deployments for a given ref.
Ref string `url:"ref,omitempty"`
// List deployments for a given task.
Task string `url:"task,omitempty"`
// List deployments for a given environment.
Environment string `url:"environment,omitempty"`
ListOptions
}
// ListDeployments lists the deployments of a repository.
//
// GitHub API docs: https://developer.github.com/v3/repos/deployments/#list-deployments
func (s *RepositoriesService) ListDeployments(owner, repo string, opt *DeploymentsListOptions) ([]*Deployment, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/deployments", owner, repo)
u, err := addOptions(u, opt)
if err != nil {
return nil, nil, err
}
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
deployments := new([]*Deployment)
resp, err := s.client.Do(req, deployments)
if err != nil {
return nil, resp, err
}
return *deployments, resp, err
}
// CreateDeployment creates a new deployment for a repository.
//
// GitHub API docs: https://developer.github.com/v3/repos/deployments/#create-a-deployment
func (s *RepositoriesService) CreateDeployment(owner, repo string, request *DeploymentRequest) (*Deployment, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/deployments", owner, repo)
req, err := s.client.NewRequest("POST", u, request)
if err != nil {
return nil, nil, err
}
// TODO: remove custom Accept header when deployment support fully launches
req.Header.Set("Accept", mediaTypeDeploymentStatusPreview)
d := new(Deployment)
resp, err := s.client.Do(req, d)
if err != nil {
return nil, resp, err
}
return d, resp, err
}
// DeploymentStatus represents the status of a
// particular deployment.
type DeploymentStatus struct {
ID *int `json:"id,omitempty"`
// State is the deployment state.
// Possible values are: "pending", "success", "failure", "error", "inactive".
State *string `json:"state,omitempty"`
Creator *User `json:"creator,omitempty"`
Description *string `json:"description,omitempty"`
TargetURL *string `json:"target_url,omitempty"`
CreatedAt *Timestamp `json:"created_at,omitempty"`
UpdatedAt *Timestamp `json:"pushed_at,omitempty"`
DeploymentURL *string `json:"deployment_url,omitempty"`
RepositoryURL *string `json:"repository_url,omitempty"`
}
// DeploymentStatusRequest represents a deployment request
type DeploymentStatusRequest struct {
State *string `json:"state,omitempty"`
TargetURL *string `json:"target_url,omitempty"` // Deprecated. Use LogURL instead.
LogURL *string `json:"log_url,omitempty"`
Description *string `json:"description,omitempty"`
EnvironmentURL *string `json:"environment_url,omitempty"`
AutoInactive *bool `json:"auto_inactive,omitempty"`
}
// ListDeploymentStatuses lists the statuses of a given deployment of a repository.
//
// GitHub API docs: https://developer.github.com/v3/repos/deployments/#list-deployment-statuses
func (s *RepositoriesService) ListDeploymentStatuses(owner, repo string, deployment int, opt *ListOptions) ([]*DeploymentStatus, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/deployments/%v/statuses", owner, repo, deployment)
u, err := addOptions(u, opt)
if err != nil {
return nil, nil, err
}
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
statuses := new([]*DeploymentStatus)
resp, err := s.client.Do(req, statuses)
if err != nil {
return nil, resp, err
}
return *statuses, resp, err
}
// CreateDeploymentStatus creates a new status for a deployment.
//
// GitHub API docs: https://developer.github.com/v3/repos/deployments/#create-a-deployment-status
func (s *RepositoriesService) CreateDeploymentStatus(owner, repo string, deployment int, request *DeploymentStatusRequest) (*DeploymentStatus, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/deployments/%v/statuses", owner, repo, deployment)
req, err := s.client.NewRequest("POST", u, request)
if err != nil {
return nil, nil, err
}
// TODO: remove custom Accept header when deployment support fully launches
req.Header.Set("Accept", mediaTypeDeploymentStatusPreview)
d := new(DeploymentStatus)
resp, err := s.client.Do(req, d)
if err != nil {
return nil, resp, err
}
return d, resp, err
}

118
vendor/src/github.com/google/go-github/github/repos_deployments_test.go

@ -0,0 +1,118 @@
// Copyright 2014 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github
import (
"encoding/json"
"fmt"
"net/http"
"reflect"
"testing"
)
func TestRepositoriesService_ListDeployments(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/deployments", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testFormValues(t, r, values{"environment": "test"})
fmt.Fprint(w, `[{"id":1}, {"id":2}]`)
})
opt := &DeploymentsListOptions{Environment: "test"}
deployments, _, err := client.Repositories.ListDeployments("o", "r", opt)
if err != nil {
t.Errorf("Repositories.ListDeployments returned error: %v", err)
}
want := []*Deployment{{ID: Int(1)}, {ID: Int(2)}}
if !reflect.DeepEqual(deployments, want) {
t.Errorf("Repositories.ListDeployments returned %+v, want %+v", deployments, want)
}
}
func TestRepositoriesService_CreateDeployment(t *testing.T) {
setup()
defer teardown()
input := &DeploymentRequest{Ref: String("1111"), Task: String("deploy"), TransientEnvironment: Bool(true)}
mux.HandleFunc("/repos/o/r/deployments", func(w http.ResponseWriter, r *http.Request) {
v := new(DeploymentRequest)
json.NewDecoder(r.Body).Decode(v)
testMethod(t, r, "POST")
testHeader(t, r, "Accept", mediaTypeDeploymentStatusPreview)
if !reflect.DeepEqual(v, input) {
t.Errorf("Request body = %+v, want %+v", v, input)
}
fmt.Fprint(w, `{"ref": "1111", "task": "deploy"}`)
})
deployment, _, err := client.Repositories.CreateDeployment("o", "r", input)
if err != nil {
t.Errorf("Repositories.CreateDeployment returned error: %v", err)
}
want := &Deployment{Ref: String("1111"), Task: String("deploy")}
if !reflect.DeepEqual(deployment, want) {
t.Errorf("Repositories.CreateDeployment returned %+v, want %+v", deployment, want)
}
}
func TestRepositoriesService_ListDeploymentStatuses(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/deployments/1/statuses", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testFormValues(t, r, values{"page": "2"})
fmt.Fprint(w, `[{"id":1}, {"id":2}]`)
})
opt := &ListOptions{Page: 2}
statutses, _, err := client.Repositories.ListDeploymentStatuses("o", "r", 1, opt)
if err != nil {
t.Errorf("Repositories.ListDeploymentStatuses returned error: %v", err)
}
want := []*DeploymentStatus{{ID: Int(1)}, {ID: Int(2)}}
if !reflect.DeepEqual(statutses, want) {
t.Errorf("Repositories.ListDeploymentStatuses returned %+v, want %+v", statutses, want)
}
}
func TestRepositoriesService_CreateDeploymentStatus(t *testing.T) {
setup()
defer teardown()
input := &DeploymentStatusRequest{State: String("inactive"), Description: String("deploy"), AutoInactive: Bool(false)}
mux.HandleFunc("/repos/o/r/deployments/1/statuses", func(w http.ResponseWriter, r *http.Request) {
v := new(DeploymentStatusRequest)
json.NewDecoder(r.Body).Decode(v)
testMethod(t, r, "POST")
testHeader(t, r, "Accept", mediaTypeDeploymentStatusPreview)
if !reflect.DeepEqual(v, input) {
t.Errorf("Request body = %+v, want %+v", v, input)
}
fmt.Fprint(w, `{"state": "inactive", "description": "deploy"}`)
})
deploymentStatus, _, err := client.Repositories.CreateDeploymentStatus("o", "r", 1, input)
if err != nil {
t.Errorf("Repositories.CreateDeploymentStatus returned error: %v", err)
}
want := &DeploymentStatus{State: String("inactive"), Description: String("deploy")}
if !reflect.DeepEqual(deploymentStatus, want) {
t.Errorf("Repositories.CreateDeploymentStatus returned %+v, want %+v", deploymentStatus, want)
}
}

73
vendor/src/github.com/google/go-github/github/repos_forks.go

@ -0,0 +1,73 @@
// Copyright 2013 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github
import "fmt"
// RepositoryListForksOptions specifies the optional parameters to the
// RepositoriesService.ListForks method.
type RepositoryListForksOptions struct {
// How to sort the forks list. Possible values are: newest, oldest,
// watchers. Default is "newest".
Sort string `url:"sort,omitempty"`
ListOptions
}
// ListForks lists the forks of the specified repository.
//
// GitHub API docs: http://developer.github.com/v3/repos/forks/#list-forks
func (s *RepositoriesService) ListForks(owner, repo string, opt *RepositoryListForksOptions) ([]*Repository, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/forks", owner, repo)
u, err := addOptions(u, opt)
if err != nil {
return nil, nil, err
}
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
repos := new([]*Repository)
resp, err := s.client.Do(req, repos)
if err != nil {
return nil, resp, err
}
return *repos, resp, err
}
// RepositoryCreateForkOptions specifies the optional parameters to the
// RepositoriesService.CreateFork method.
type RepositoryCreateForkOptions struct {
// The organization to fork the repository into.
Organization string `url:"organization,omitempty"`
}
// CreateFork creates a fork of the specified repository.
//
// GitHub API docs: http://developer.github.com/v3/repos/forks/#list-forks
func (s *RepositoriesService) CreateFork(owner, repo string, opt *RepositoryCreateForkOptions) (*Repository, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/forks", owner, repo)
u, err := addOptions(u, opt)
if err != nil {
return nil, nil, err
}
req, err := s.client.NewRequest("POST", u, nil)
if err != nil {
return nil, nil, err
}
fork := new(Repository)
resp, err := s.client.Do(req, fork)
if err != nil {
return nil, resp, err
}
return fork, resp, err
}

73
vendor/src/github.com/google/go-github/github/repos_forks_test.go

@ -0,0 +1,73 @@
// Copyright 2013 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github
import (
"fmt"
"net/http"
"reflect"
"testing"
)
func TestRepositoriesService_ListForks(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/forks", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testFormValues(t, r, values{
"sort": "newest",
"page": "3",
})
fmt.Fprint(w, `[{"id":1},{"id":2}]`)
})
opt := &RepositoryListForksOptions{
Sort: "newest",
ListOptions: ListOptions{Page: 3},
}
repos, _, err := client.Repositories.ListForks("o", "r", opt)
if err != nil {
t.Errorf("Repositories.ListForks returned error: %v", err)
}
want := []*Repository{{ID: Int(1)}, {ID: Int(2)}}
if !reflect.DeepEqual(repos, want) {
t.Errorf("Repositories.ListForks returned %+v, want %+v", repos, want)
}
}
func TestRepositoriesService_ListForks_invalidOwner(t *testing.T) {
_, _, err := client.Repositories.ListForks("%", "r", nil)
testURLParseError(t, err)
}
func TestRepositoriesService_CreateFork(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/forks", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "POST")
testFormValues(t, r, values{"organization": "o"})
fmt.Fprint(w, `{"id":1}`)
})
opt := &RepositoryCreateForkOptions{Organization: "o"}
repo, _, err := client.Repositories.CreateFork("o", "r", opt)
if err != nil {
t.Errorf("Repositories.CreateFork returned error: %v", err)
}
want := &Repository{ID: Int(1)}
if !reflect.DeepEqual(repo, want) {
t.Errorf("Repositories.CreateFork returned %+v, want %+v", repo, want)
}
}
func TestRepositoriesService_CreateFork_invalidOwner(t *testing.T) {
_, _, err := client.Repositories.CreateFork("%", "r", nil)
testURLParseError(t, err)
}

196
vendor/src/github.com/google/go-github/github/repos_hooks.go

@ -0,0 +1,196 @@
// Copyright 2013 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github
import (
"fmt"
"time"
)
// WebHookPayload represents the data that is received from GitHub when a push
// event hook is triggered. The format of these payloads pre-date most of the
// GitHub v3 API, so there are lots of minor incompatibilities with the types
// defined in the rest of the API. Therefore, several types are duplicated
// here to account for these differences.
//
// GitHub API docs: https://help.github.com/articles/post-receive-hooks
type WebHookPayload struct {
After *string `json:"after,omitempty"`
Before *string `json:"before,omitempty"`
Commits []WebHookCommit `json:"commits,omitempty"`
Compare *string `json:"compare,omitempty"`
Created *bool `json:"created,omitempty"`
Deleted *bool `json:"deleted,omitempty"`
Forced *bool `json:"forced,omitempty"`
HeadCommit *WebHookCommit `json:"head_commit,omitempty"`
Pusher *User `json:"pusher,omitempty"`
Ref *string `json:"ref,omitempty"`
Repo *Repository `json:"repository,omitempty"`
Sender *User `json:"sender,omitempty"`
}
func (w WebHookPayload) String() string {
return Stringify(w)
}
// WebHookCommit represents the commit variant we receive from GitHub in a
// WebHookPayload.
type WebHookCommit struct {
Added []string `json:"added,omitempty"`
Author *WebHookAuthor `json:"author,omitempty"`
Committer *WebHookAuthor `json:"committer,omitempty"`
Distinct *bool `json:"distinct,omitempty"`
ID *string `json:"id,omitempty"`
Message *string `json:"message,omitempty"`
Modified []string `json:"modified,omitempty"`
Removed []string `json:"removed,omitempty"`
Timestamp *time.Time `json:"timestamp,omitempty"`
}
func (w WebHookCommit) String() string {
return Stringify(w)
}
// WebHookAuthor represents the author or committer of a commit, as specified
// in a WebHookCommit. The commit author may not correspond to a GitHub User.
type WebHookAuthor struct {
Email *string `json:"email,omitempty"`
Name *string `json:"name,omitempty"`
Username *string `json:"username,omitempty"`
}
func (w WebHookAuthor) String() string {
return Stringify(w)
}
// Hook represents a GitHub (web and service) hook for a repository.
type Hook struct {
CreatedAt *time.Time `json:"created_at,omitempty"`
UpdatedAt *time.Time `json:"updated_at,omitempty"`
Name *string `json:"name,omitempty"`
URL *string `json:"url,omitempty"`
Events []string `json:"events,omitempty"`
Active *bool `json:"active,omitempty"`
Config map[string]interface{} `json:"config,omitempty"`
ID *int `json:"id,omitempty"`
}
func (h Hook) String() string {
return Stringify(h)
}
// CreateHook creates a Hook for the specified repository.
// Name and Config are required fields.
//
// GitHub API docs: http://developer.github.com/v3/repos/hooks/#create-a-hook
func (s *RepositoriesService) CreateHook(owner, repo string, hook *Hook) (*Hook, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/hooks", owner, repo)
req, err := s.client.NewRequest("POST", u, hook)
if err != nil {
return nil, nil, err
}
h := new(Hook)
resp, err := s.client.Do(req, h)
if err != nil {
return nil, resp, err
}
return h, resp, err
}
// ListHooks lists all Hooks for the specified repository.
//
// GitHub API docs: http://developer.github.com/v3/repos/hooks/#list
func (s *RepositoriesService) ListHooks(owner, repo string, opt *ListOptions) ([]*Hook, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/hooks", owner, repo)
u, err := addOptions(u, opt)
if err != nil {
return nil, nil, err
}
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
hooks := new([]*Hook)
resp, err := s.client.Do(req, hooks)
if err != nil {
return nil, resp, err
}
return *hooks, resp, err
}
// GetHook returns a single specified Hook.
//
// GitHub API docs: http://developer.github.com/v3/repos/hooks/#get-single-hook
func (s *RepositoriesService) GetHook(owner, repo string, id int) (*Hook, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/hooks/%d", owner, repo, id)
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
hook := new(Hook)
resp, err := s.client.Do(req, hook)
return hook, resp, err
}
// EditHook updates a specified Hook.
//
// GitHub API docs: http://developer.github.com/v3/repos/hooks/#edit-a-hook
func (s *RepositoriesService) EditHook(owner, repo string, id int, hook *Hook) (*Hook, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/hooks/%d", owner, repo, id)
req, err := s.client.NewRequest("PATCH", u, hook)
if err != nil {
return nil, nil, err
}
h := new(Hook)
resp, err := s.client.Do(req, h)
return h, resp, err
}
// DeleteHook deletes a specified Hook.
//
// GitHub API docs: http://developer.github.com/v3/repos/hooks/#delete-a-hook
func (s *RepositoriesService) DeleteHook(owner, repo string, id int) (*Response, error) {
u := fmt.Sprintf("repos/%v/%v/hooks/%d", owner, repo, id)
req, err := s.client.NewRequest("DELETE", u, nil)
if err != nil {
return nil, err
}
return s.client.Do(req, nil)
}
// PingHook triggers a 'ping' event to be sent to the Hook.
//
// GitHub API docs: https://developer.github.com/v3/repos/hooks/#ping-a-hook
func (s *RepositoriesService) PingHook(owner, repo string, id int) (*Response, error) {
u := fmt.Sprintf("repos/%v/%v/hooks/%d/pings", owner, repo, id)
req, err := s.client.NewRequest("POST", u, nil)
if err != nil {
return nil, err
}
return s.client.Do(req, nil)
}
// TestHook triggers a test Hook by github.
//
// GitHub API docs: http://developer.github.com/v3/repos/hooks/#test-a-push-hook
func (s *RepositoriesService) TestHook(owner, repo string, id int) (*Response, error) {
u := fmt.Sprintf("repos/%v/%v/hooks/%d/tests", owner, repo, id)
req, err := s.client.NewRequest("POST", u, nil)
if err != nil {
return nil, err
}
return s.client.Do(req, nil)
}
// ListServiceHooks is deprecated. Use Client.ListServiceHooks instead.
func (s *RepositoriesService) ListServiceHooks() ([]*ServiceHook, *Response, error) {
return s.client.ListServiceHooks()
}

187
vendor/src/github.com/google/go-github/github/repos_hooks_test.go

@ -0,0 +1,187 @@
// Copyright 2013 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github
import (
"encoding/json"
"fmt"
"net/http"
"reflect"
"testing"
)
func TestRepositoriesService_CreateHook(t *testing.T) {
setup()
defer teardown()
input := &Hook{Name: String("t")}
mux.HandleFunc("/repos/o/r/hooks", func(w http.ResponseWriter, r *http.Request) {
v := new(Hook)
json.NewDecoder(r.Body).Decode(v)
testMethod(t, r, "POST")
if !reflect.DeepEqual(v, input) {
t.Errorf("Request body = %+v, want %+v", v, input)
}
fmt.Fprint(w, `{"id":1}`)
})
hook, _, err := client.Repositories.CreateHook("o", "r", input)
if err != nil {
t.Errorf("Repositories.CreateHook returned error: %v", err)
}
want := &Hook{ID: Int(1)}
if !reflect.DeepEqual(hook, want) {
t.Errorf("Repositories.CreateHook returned %+v, want %+v", hook, want)
}
}
func TestRepositoriesService_CreateHook_invalidOwner(t *testing.T) {
_, _, err := client.Repositories.CreateHook("%", "%", nil)
testURLParseError(t, err)
}
func TestRepositoriesService_ListHooks(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/hooks", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testFormValues(t, r, values{"page": "2"})
fmt.Fprint(w, `[{"id":1}, {"id":2}]`)
})
opt := &ListOptions{Page: 2}
hooks, _, err := client.Repositories.ListHooks("o", "r", opt)
if err != nil {
t.Errorf("Repositories.ListHooks returned error: %v", err)
}
want := []*Hook{{ID: Int(1)}, {ID: Int(2)}}
if !reflect.DeepEqual(hooks, want) {
t.Errorf("Repositories.ListHooks returned %+v, want %+v", hooks, want)
}
}
func TestRepositoriesService_ListHooks_invalidOwner(t *testing.T) {
_, _, err := client.Repositories.ListHooks("%", "%", nil)
testURLParseError(t, err)
}
func TestRepositoriesService_GetHook(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/hooks/1", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
fmt.Fprint(w, `{"id":1}`)
})
hook, _, err := client.Repositories.GetHook("o", "r", 1)
if err != nil {
t.Errorf("Repositories.GetHook returned error: %v", err)
}
want := &Hook{ID: Int(1)}
if !reflect.DeepEqual(hook, want) {
t.Errorf("Repositories.GetHook returned %+v, want %+v", hook, want)
}
}
func TestRepositoriesService_GetHook_invalidOwner(t *testing.T) {
_, _, err := client.Repositories.GetHook("%", "%", 1)
testURLParseError(t, err)
}
func TestRepositoriesService_EditHook(t *testing.T) {
setup()
defer teardown()
input := &Hook{Name: String("t")}
mux.HandleFunc("/repos/o/r/hooks/1", func(w http.ResponseWriter, r *http.Request) {
v := new(Hook)
json.NewDecoder(r.Body).Decode(v)
testMethod(t, r, "PATCH")
if !reflect.DeepEqual(v, input) {
t.Errorf("Request body = %+v, want %+v", v, input)
}
fmt.Fprint(w, `{"id":1}`)
})
hook, _, err := client.Repositories.EditHook("o", "r", 1, input)
if err != nil {
t.Errorf("Repositories.EditHook returned error: %v", err)
}
want := &Hook{ID: Int(1)}
if !reflect.DeepEqual(hook, want) {
t.Errorf("Repositories.EditHook returned %+v, want %+v", hook, want)
}
}
func TestRepositoriesService_EditHook_invalidOwner(t *testing.T) {
_, _, err := client.Repositories.EditHook("%", "%", 1, nil)
testURLParseError(t, err)
}
func TestRepositoriesService_DeleteHook(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/hooks/1", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "DELETE")
})
_, err := client.Repositories.DeleteHook("o", "r", 1)
if err != nil {
t.Errorf("Repositories.DeleteHook returned error: %v", err)
}
}
func TestRepositoriesService_DeleteHook_invalidOwner(t *testing.T) {
_, err := client.Repositories.DeleteHook("%", "%", 1)
testURLParseError(t, err)
}
func TestRepositoriesService_PingHook(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/hooks/1/pings", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "POST")
})
_, err := client.Repositories.PingHook("o", "r", 1)
if err != nil {
t.Errorf("Repositories.PingHook returned error: %v", err)
}
}
func TestRepositoriesService_TestHook(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/hooks/1/tests", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "POST")
})
_, err := client.Repositories.TestHook("o", "r", 1)
if err != nil {
t.Errorf("Repositories.TestHook returned error: %v", err)
}
}
func TestRepositoriesService_TestHook_invalidOwner(t *testing.T) {
_, err := client.Repositories.TestHook("%", "%", 1)
testURLParseError(t, err)
}

91
vendor/src/github.com/google/go-github/github/repos_invitations.go

@ -0,0 +1,91 @@
// Copyright 2016 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github
import "fmt"
// RepositoryInvitation represents an invitation to collaborate on a repo.
type RepositoryInvitation struct {
ID *int `json:"id,omitempty"`
Repo *Repository `json:"repository,omitempty"`
Invitee *User `json:"invitee,omitempty"`
Inviter *User `json:"inviter,omitempty"`
// Permissions represents the permissions that the associated user will have
// on the repository. Possible values are: "read", "write", "admin".
Permissions *string `json:"permissions,omitempty"`
CreatedAt *Timestamp `json:"created_at,omitempty"`
URL *string `json:"url,omitempty"`
HTMLURL *string `json:"html_url,omitempty"`
}
// ListInvitations lists all currently-open repository invitations.
//
// GitHub API docs: https://developer.github.com/v3/repos/invitations/#list-invitations-for-a-repository
func (s *RepositoriesService) ListInvitations(repoID int, opt *ListOptions) ([]*RepositoryInvitation, *Response, error) {
u := fmt.Sprintf("repositories/%v/invitations", repoID)
u, err := addOptions(u, opt)
if err != nil {
return nil, nil, err
}
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
// TODO: remove custom Accept header when this API fully launches.
req.Header.Set("Accept", mediaTypeRepositoryInvitationsPreview)
invites := []*RepositoryInvitation{}
resp, err := s.client.Do(req, &invites)
if err != nil {
return nil, resp, err
}
return invites, resp, err
}
// DeleteInvitation deletes a repository invitation.
//
// GitHub API docs: https://developer.github.com/v3/repos/invitations/#delete-a-repository-invitation
func (s *RepositoriesService) DeleteInvitation(repoID, invitationID int) (*Response, error) {
u := fmt.Sprintf("repositories/%v/invitations/%v", repoID, invitationID)
req, err := s.client.NewRequest("DELETE", u, nil)
if err != nil {
return nil, err
}
// TODO: remove custom Accept header when this API fully launches.
req.Header.Set("Accept", mediaTypeRepositoryInvitationsPreview)
return s.client.Do(req, nil)
}
// UpdateInvitation updates the permissions associated with a repository
// invitation.
//
// permissions represents the permissions that the associated user will have
// on the repository. Possible values are: "read", "write", "admin".
//
// GitHub API docs: https://developer.github.com/v3/repos/invitations/#update-a-repository-invitation
func (s *RepositoriesService) UpdateInvitation(repoID, invitationID int, permissions string) (*RepositoryInvitation, *Response, error) {
opts := &struct {
Permissions string `json:"permissions"`
}{Permissions: permissions}
u := fmt.Sprintf("repositories/%v/invitations/%v", repoID, invitationID)
req, err := s.client.NewRequest("PATCH", u, opts)
if err != nil {
return nil, nil, err
}
// TODO: remove custom Accept header when this API fully launches.
req.Header.Set("Accept", mediaTypeRepositoryInvitationsPreview)
invite := &RepositoryInvitation{}
resp, err := s.client.Do(req, invite)
return invite, resp, err
}

73
vendor/src/github.com/google/go-github/github/repos_invitations_test.go

@ -0,0 +1,73 @@
// Copyright 2016 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github
import (
"fmt"
"net/http"
"reflect"
"testing"
)
func TestRepositoriesService_ListInvitations(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repositories/1/invitations", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testHeader(t, r, "Accept", mediaTypeRepositoryInvitationsPreview)
testFormValues(t, r, values{"page": "2"})
fmt.Fprintf(w, `[{"id":1}, {"id":2}]`)
})
opt := &ListOptions{Page: 2}
got, _, err := client.Repositories.ListInvitations(1, opt)
if err != nil {
t.Errorf("Repositories.ListInvitations returned error: %v", err)
}
want := []*RepositoryInvitation{{ID: Int(1)}, {ID: Int(2)}}
if !reflect.DeepEqual(got, want) {
t.Errorf("Repositories.ListInvitations = %+v, want %+v", got, want)
}
}
func TestRepositoriesService_DeleteInvitation(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repositories/1/invitations/2", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "DELETE")
testHeader(t, r, "Accept", mediaTypeRepositoryInvitationsPreview)
w.WriteHeader(http.StatusNoContent)
})
_, err := client.Repositories.DeleteInvitation(1, 2)
if err != nil {
t.Errorf("Repositories.DeleteInvitation returned error: %v", err)
}
}
func TestRepositoriesService_UpdateInvitation(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repositories/1/invitations/2", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "PATCH")
testHeader(t, r, "Accept", mediaTypeRepositoryInvitationsPreview)
fmt.Fprintf(w, `{"id":1}`)
})
got, _, err := client.Repositories.UpdateInvitation(1, 2, "write")
if err != nil {
t.Errorf("Repositories.UpdateInvitation returned error: %v", err)
}
want := &RepositoryInvitation{ID: Int(1)}
if !reflect.DeepEqual(got, want) {
t.Errorf("Repositories.UpdateInvitation = %+v, want %+v", got, want)
}
}

108
vendor/src/github.com/google/go-github/github/repos_keys.go

@ -0,0 +1,108 @@
// Copyright 2013 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github
import "fmt"
// The Key type is defined in users_keys.go
// ListKeys lists the deploy keys for a repository.
//
// GitHub API docs: http://developer.github.com/v3/repos/keys/#list
func (s *RepositoriesService) ListKeys(owner string, repo string, opt *ListOptions) ([]*Key, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/keys", owner, repo)
u, err := addOptions(u, opt)
if err != nil {
return nil, nil, err
}
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
keys := new([]*Key)
resp, err := s.client.Do(req, keys)
if err != nil {
return nil, resp, err
}
return *keys, resp, err
}
// GetKey fetches a single deploy key.
//
// GitHub API docs: http://developer.github.com/v3/repos/keys/#get
func (s *RepositoriesService) GetKey(owner string, repo string, id int) (*Key, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/keys/%v", owner, repo, id)
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
key := new(Key)
resp, err := s.client.Do(req, key)
if err != nil {
return nil, resp, err
}
return key, resp, err
}
// CreateKey adds a deploy key for a repository.
//
// GitHub API docs: http://developer.github.com/v3/repos/keys/#create
func (s *RepositoriesService) CreateKey(owner string, repo string, key *Key) (*Key, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/keys", owner, repo)
req, err := s.client.NewRequest("POST", u, key)
if err != nil {
return nil, nil, err
}
k := new(Key)
resp, err := s.client.Do(req, k)
if err != nil {
return nil, resp, err
}
return k, resp, err
}
// EditKey edits a deploy key.
//
// GitHub API docs: http://developer.github.com/v3/repos/keys/#edit
func (s *RepositoriesService) EditKey(owner string, repo string, id int, key *Key) (*Key, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/keys/%v", owner, repo, id)
req, err := s.client.NewRequest("PATCH", u, key)
if err != nil {
return nil, nil, err
}
k := new(Key)
resp, err := s.client.Do(req, k)
if err != nil {
return nil, resp, err
}
return k, resp, err
}
// DeleteKey deletes a deploy key.
//
// GitHub API docs: http://developer.github.com/v3/repos/keys/#delete
func (s *RepositoriesService) DeleteKey(owner string, repo string, id int) (*Response, error) {
u := fmt.Sprintf("repos/%v/%v/keys/%v", owner, repo, id)
req, err := s.client.NewRequest("DELETE", u, nil)
if err != nil {
return nil, err
}
return s.client.Do(req, nil)
}

153
vendor/src/github.com/google/go-github/github/repos_keys_test.go

@ -0,0 +1,153 @@
// Copyright 2013 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github
import (
"encoding/json"
"fmt"
"net/http"
"reflect"
"testing"
)
func TestRepositoriesService_ListKeys(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/keys", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testFormValues(t, r, values{"page": "2"})
fmt.Fprint(w, `[{"id":1}]`)
})
opt := &ListOptions{Page: 2}
keys, _, err := client.Repositories.ListKeys("o", "r", opt)
if err != nil {
t.Errorf("Repositories.ListKeys returned error: %v", err)
}
want := []*Key{{ID: Int(1)}}
if !reflect.DeepEqual(keys, want) {
t.Errorf("Repositories.ListKeys returned %+v, want %+v", keys, want)
}
}
func TestRepositoriesService_ListKeys_invalidOwner(t *testing.T) {
_, _, err := client.Repositories.ListKeys("%", "%", nil)
testURLParseError(t, err)
}
func TestRepositoriesService_GetKey(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/keys/1", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
fmt.Fprint(w, `{"id":1}`)
})
key, _, err := client.Repositories.GetKey("o", "r", 1)
if err != nil {
t.Errorf("Repositories.GetKey returned error: %v", err)
}
want := &Key{ID: Int(1)}
if !reflect.DeepEqual(key, want) {
t.Errorf("Repositories.GetKey returned %+v, want %+v", key, want)
}
}
func TestRepositoriesService_GetKey_invalidOwner(t *testing.T) {
_, _, err := client.Repositories.GetKey("%", "%", 1)
testURLParseError(t, err)
}
func TestRepositoriesService_CreateKey(t *testing.T) {
setup()
defer teardown()
input := &Key{Key: String("k"), Title: String("t")}
mux.HandleFunc("/repos/o/r/keys", func(w http.ResponseWriter, r *http.Request) {
v := new(Key)
json.NewDecoder(r.Body).Decode(v)
testMethod(t, r, "POST")
if !reflect.DeepEqual(v, input) {
t.Errorf("Request body = %+v, want %+v", v, input)
}
fmt.Fprint(w, `{"id":1}`)
})
key, _, err := client.Repositories.CreateKey("o", "r", input)
if err != nil {
t.Errorf("Repositories.GetKey returned error: %v", err)
}
want := &Key{ID: Int(1)}
if !reflect.DeepEqual(key, want) {
t.Errorf("Repositories.GetKey returned %+v, want %+v", key, want)
}
}
func TestRepositoriesService_CreateKey_invalidOwner(t *testing.T) {
_, _, err := client.Repositories.CreateKey("%", "%", nil)
testURLParseError(t, err)
}
func TestRepositoriesService_EditKey(t *testing.T) {
setup()
defer teardown()
input := &Key{Key: String("k"), Title: String("t")}
mux.HandleFunc("/repos/o/r/keys/1", func(w http.ResponseWriter, r *http.Request) {
v := new(Key)
json.NewDecoder(r.Body).Decode(v)
testMethod(t, r, "PATCH")
if !reflect.DeepEqual(v, input) {
t.Errorf("Request body = %+v, want %+v", v, input)
}
fmt.Fprint(w, `{"id":1}`)
})
key, _, err := client.Repositories.EditKey("o", "r", 1, input)
if err != nil {
t.Errorf("Repositories.EditKey returned error: %v", err)
}
want := &Key{ID: Int(1)}
if !reflect.DeepEqual(key, want) {
t.Errorf("Repositories.EditKey returned %+v, want %+v", key, want)
}
}
func TestRepositoriesService_EditKey_invalidOwner(t *testing.T) {
_, _, err := client.Repositories.EditKey("%", "%", 1, nil)
testURLParseError(t, err)
}
func TestRepositoriesService_DeleteKey(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/keys/1", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "DELETE")
})
_, err := client.Repositories.DeleteKey("o", "r", 1)
if err != nil {
t.Errorf("Repositories.DeleteKey returned error: %v", err)
}
}
func TestRepositoriesService_DeleteKey_invalidOwner(t *testing.T) {
_, err := client.Repositories.DeleteKey("%", "%", 1)
testURLParseError(t, err)
}

37
vendor/src/github.com/google/go-github/github/repos_merging.go

@ -0,0 +1,37 @@
// Copyright 2014 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github
import (
"fmt"
)
// RepositoryMergeRequest represents a request to merge a branch in a
// repository.
type RepositoryMergeRequest struct {
Base *string `json:"base,omitempty"`
Head *string `json:"head,omitempty"`
CommitMessage *string `json:"commit_message,omitempty"`
}
// Merge a branch in the specified repository.
//
// GitHub API docs: https://developer.github.com/v3/repos/merging/#perform-a-merge
func (s *RepositoriesService) Merge(owner, repo string, request *RepositoryMergeRequest) (*RepositoryCommit, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/merges", owner, repo)
req, err := s.client.NewRequest("POST", u, request)
if err != nil {
return nil, nil, err
}
commit := new(RepositoryCommit)
resp, err := s.client.Do(req, commit)
if err != nil {
return nil, resp, err
}
return commit, resp, err
}

47
vendor/src/github.com/google/go-github/github/repos_merging_test.go

@ -0,0 +1,47 @@
// Copyright 2014 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github
import (
"encoding/json"
"fmt"
"net/http"
"reflect"
"testing"
)
func TestRepositoriesService_Merge(t *testing.T) {
setup()
defer teardown()
input := &RepositoryMergeRequest{
Base: String("b"),
Head: String("h"),
CommitMessage: String("c"),
}
mux.HandleFunc("/repos/o/r/merges", func(w http.ResponseWriter, r *http.Request) {
v := new(RepositoryMergeRequest)
json.NewDecoder(r.Body).Decode(v)
testMethod(t, r, "POST")
if !reflect.DeepEqual(v, input) {
t.Errorf("Request body = %+v, want %+v", v, input)
}
fmt.Fprint(w, `{"sha":"s"}`)
})
commit, _, err := client.Repositories.Merge("o", "r", input)
if err != nil {
t.Errorf("Repositories.Merge returned error: %v", err)
}
want := &RepositoryCommit{SHA: String("s")}
if !reflect.DeepEqual(commit, want) {
t.Errorf("Repositories.Merge returned %+v, want %+v", commit, want)
}
}

116
vendor/src/github.com/google/go-github/github/repos_pages.go

@ -0,0 +1,116 @@
// Copyright 2014 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github
import "fmt"
// Pages represents a GitHub Pages site configuration.
type Pages struct {
URL *string `json:"url,omitempty"`
Status *string `json:"status,omitempty"`
CNAME *string `json:"cname,omitempty"`
Custom404 *bool `json:"custom_404,omitempty"`
HTMLURL *string `json:"html_url,omitempty"`
}
// PagesError represents a build error for a GitHub Pages site.
type PagesError struct {
Message *string `json:"message,omitempty"`
}
// PagesBuild represents the build information for a GitHub Pages site.
type PagesBuild struct {
URL *string `json:"url,omitempty"`
Status *string `json:"status,omitempty"`
Error *PagesError `json:"error,omitempty"`
Pusher *User `json:"pusher,omitempty"`
Commit *string `json:"commit,omitempty"`
Duration *int `json:"duration,omitempty"`
CreatedAt *Timestamp `json:"created_at,omitempty"`
UpdatedAt *Timestamp `json:"created_at,omitempty"`
}
// GetPagesInfo fetches information about a GitHub Pages site.
//
// GitHub API docs: https://developer.github.com/v3/repos/pages/#get-information-about-a-pages-site
func (s *RepositoriesService) GetPagesInfo(owner string, repo string) (*Pages, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/pages", owner, repo)
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
// TODO: remove custom Accept header when this API fully launches.
req.Header.Set("Accept", mediaTypePagesPreview)
site := new(Pages)
resp, err := s.client.Do(req, site)
if err != nil {
return nil, resp, err
}
return site, resp, err
}
// ListPagesBuilds lists the builds for a GitHub Pages site.
//
// GitHub API docs: https://developer.github.com/v3/repos/pages/#list-pages-builds
func (s *RepositoriesService) ListPagesBuilds(owner string, repo string) ([]*PagesBuild, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/pages/builds", owner, repo)
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
var pages []*PagesBuild
resp, err := s.client.Do(req, &pages)
if err != nil {
return nil, resp, err
}
return pages, resp, err
}
// GetLatestPagesBuild fetches the latest build information for a GitHub pages site.
//
// GitHub API docs: https://developer.github.com/v3/repos/pages/#list-latest-pages-build
func (s *RepositoriesService) GetLatestPagesBuild(owner string, repo string) (*PagesBuild, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/pages/builds/latest", owner, repo)
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
build := new(PagesBuild)
resp, err := s.client.Do(req, build)
if err != nil {
return nil, resp, err
}
return build, resp, err
}
// RequestPageBuild requests a build of a GitHub Pages site without needing to push new commit.
//
// GitHub API docs: https://developer.github.com/v3/repos/pages/#request-a-page-build
func (s *RepositoriesService) RequestPageBuild(owner string, repo string) (*PagesBuild, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/pages/builds", owner, repo)
req, err := s.client.NewRequest("POST", u, nil)
if err != nil {
return nil, nil, err
}
// TODO: remove custom Accept header when this API fully launches.
req.Header.Set("Accept", mediaTypePagesPreview)
build := new(PagesBuild)
resp, err := s.client.Do(req, build)
if err != nil {
return nil, resp, err
}
return build, resp, err
}

95
vendor/src/github.com/google/go-github/github/repos_pages_test.go

@ -0,0 +1,95 @@
// Copyright 2014 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github
import (
"fmt"
"net/http"
"reflect"
"testing"
)
func TestRepositoriesService_GetPagesInfo(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/pages", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testHeader(t, r, "Accept", mediaTypePagesPreview)
fmt.Fprint(w, `{"url":"u","status":"s","cname":"c","custom_404":false,"html_url":"h"}`)
})
page, _, err := client.Repositories.GetPagesInfo("o", "r")
if err != nil {
t.Errorf("Repositories.GetPagesInfo returned error: %v", err)
}
want := &Pages{URL: String("u"), Status: String("s"), CNAME: String("c"), Custom404: Bool(false), HTMLURL: String("h")}
if !reflect.DeepEqual(page, want) {
t.Errorf("Repositories.GetPagesInfo returned %+v, want %+v", page, want)
}
}
func TestRepositoriesService_ListPagesBuilds(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/pages/builds", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
fmt.Fprint(w, `[{"url":"u","status":"s","commit":"c"}]`)
})
pages, _, err := client.Repositories.ListPagesBuilds("o", "r")
if err != nil {
t.Errorf("Repositories.ListPagesBuilds returned error: %v", err)
}
want := []*PagesBuild{{URL: String("u"), Status: String("s"), Commit: String("c")}}
if !reflect.DeepEqual(pages, want) {
t.Errorf("Repositories.ListPagesBuilds returned %+v, want %+v", pages, want)
}
}
func TestRepositoriesService_GetLatestPagesBuild(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/pages/builds/latest", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
fmt.Fprint(w, `{"url":"u","status":"s","commit":"c"}`)
})
build, _, err := client.Repositories.GetLatestPagesBuild("o", "r")
if err != nil {
t.Errorf("Repositories.GetLatestPagesBuild returned error: %v", err)
}
want := &PagesBuild{URL: String("u"), Status: String("s"), Commit: String("c")}
if !reflect.DeepEqual(build, want) {
t.Errorf("Repositories.GetLatestPagesBuild returned %+v, want %+v", build, want)
}
}
func TestRepositoriesService_RequestPageBuild(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/pages/builds", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "POST")
testHeader(t, r, "Accept", mediaTypePagesPreview)
fmt.Fprint(w, `{"url":"u","status":"s"}`)
})
build, _, err := client.Repositories.RequestPageBuild("o", "r")
if err != nil {
t.Errorf("Repositories.RequestPageBuild returned error: %v", err)
}
want := &PagesBuild{URL: String("u"), Status: String("s")}
if !reflect.DeepEqual(build, want) {
t.Errorf("Repositories.RequestPageBuild returned %+v, want %+v", build, want)
}
}

325
vendor/src/github.com/google/go-github/github/repos_releases.go

@ -0,0 +1,325 @@
// Copyright 2013 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github
import (
"errors"
"fmt"
"io"
"mime"
"net/http"
"os"
"path/filepath"
"strings"
)
// RepositoryRelease represents a GitHub release in a repository.
type RepositoryRelease struct {
ID *int `json:"id,omitempty"`
TagName *string `json:"tag_name,omitempty"`
TargetCommitish *string `json:"target_commitish,omitempty"`
Name *string `json:"name,omitempty"`
Body *string `json:"body,omitempty"`
Draft *bool `json:"draft,omitempty"`
Prerelease *bool `json:"prerelease,omitempty"`
CreatedAt *Timestamp `json:"created_at,omitempty"`
PublishedAt *Timestamp `json:"published_at,omitempty"`
URL *string `json:"url,omitempty"`
HTMLURL *string `json:"html_url,omitempty"`
AssetsURL *string `json:"assets_url,omitempty"`
Assets []ReleaseAsset `json:"assets,omitempty"`
UploadURL *string `json:"upload_url,omitempty"`
ZipballURL *string `json:"zipball_url,omitempty"`
TarballURL *string `json:"tarball_url,omitempty"`
Author *CommitAuthor `json:"author,omitempty"`
}
func (r RepositoryRelease) String() string {
return Stringify(r)
}
// ReleaseAsset represents a Github release asset in a repository.
type ReleaseAsset struct {
ID *int `json:"id,omitempty"`
URL *string `json:"url,omitempty"`
Name *string `json:"name,omitempty"`
Label *string `json:"label,omitempty"`
State *string `json:"state,omitempty"`
ContentType *string `json:"content_type,omitempty"`
Size *int `json:"size,omitempty"`
DownloadCount *int `json:"download_count,omitempty"`
CreatedAt *Timestamp `json:"created_at,omitempty"`
UpdatedAt *Timestamp `json:"updated_at,omitempty"`
BrowserDownloadURL *string `json:"browser_download_url,omitempty"`
Uploader *User `json:"uploader,omitempty"`
}
func (r ReleaseAsset) String() string {
return Stringify(r)
}
// ListReleases lists the releases for a repository.
//
// GitHub API docs: http://developer.github.com/v3/repos/releases/#list-releases-for-a-repository
func (s *RepositoriesService) ListReleases(owner, repo string, opt *ListOptions) ([]*RepositoryRelease, *Response, error) {
u := fmt.Sprintf("repos/%s/%s/releases", owner, repo)
u, err := addOptions(u, opt)
if err != nil {
return nil, nil, err
}
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
releases := new([]*RepositoryRelease)
resp, err := s.client.Do(req, releases)
if err != nil {
return nil, resp, err
}
return *releases, resp, err
}
// GetRelease fetches a single release.
//
// GitHub API docs: http://developer.github.com/v3/repos/releases/#get-a-single-release
func (s *RepositoriesService) GetRelease(owner, repo string, id int) (*RepositoryRelease, *Response, error) {
u := fmt.Sprintf("repos/%s/%s/releases/%d", owner, repo, id)
return s.getSingleRelease(u)
}
// GetLatestRelease fetches the latest published release for the repository.
//
// GitHub API docs: https://developer.github.com/v3/repos/releases/#get-the-latest-release
func (s *RepositoriesService) GetLatestRelease(owner, repo string) (*RepositoryRelease, *Response, error) {
u := fmt.Sprintf("repos/%s/%s/releases/latest", owner, repo)
return s.getSingleRelease(u)
}
// GetReleaseByTag fetches a release with the specified tag.
//
// GitHub API docs: https://developer.github.com/v3/repos/releases/#get-a-release-by-tag-name
func (s *RepositoriesService) GetReleaseByTag(owner, repo, tag string) (*RepositoryRelease, *Response, error) {
u := fmt.Sprintf("repos/%s/%s/releases/tags/%s", owner, repo, tag)
return s.getSingleRelease(u)
}
func (s *RepositoriesService) getSingleRelease(url string) (*RepositoryRelease, *Response, error) {
req, err := s.client.NewRequest("GET", url, nil)
if err != nil {
return nil, nil, err
}
release := new(RepositoryRelease)
resp, err := s.client.Do(req, release)
if err != nil {
return nil, resp, err
}
return release, resp, err
}
// CreateRelease adds a new release for a repository.
//
// GitHub API docs : http://developer.github.com/v3/repos/releases/#create-a-release
func (s *RepositoriesService) CreateRelease(owner, repo string, release *RepositoryRelease) (*RepositoryRelease, *Response, error) {
u := fmt.Sprintf("repos/%s/%s/releases", owner, repo)
req, err := s.client.NewRequest("POST", u, release)
if err != nil {
return nil, nil, err
}
r := new(RepositoryRelease)
resp, err := s.client.Do(req, r)
if err != nil {
return nil, resp, err
}
return r, resp, err
}
// EditRelease edits a repository release.
//
// GitHub API docs : http://developer.github.com/v3/repos/releases/#edit-a-release
func (s *RepositoriesService) EditRelease(owner, repo string, id int, release *RepositoryRelease) (*RepositoryRelease, *Response, error) {
u := fmt.Sprintf("repos/%s/%s/releases/%d", owner, repo, id)
req, err := s.client.NewRequest("PATCH", u, release)
if err != nil {
return nil, nil, err
}
r := new(RepositoryRelease)
resp, err := s.client.Do(req, r)
if err != nil {
return nil, resp, err
}
return r, resp, err
}
// DeleteRelease delete a single release from a repository.
//
// GitHub API docs : http://developer.github.com/v3/repos/releases/#delete-a-release
func (s *RepositoriesService) DeleteRelease(owner, repo string, id int) (*Response, error) {
u := fmt.Sprintf("repos/%s/%s/releases/%d", owner, repo, id)
req, err := s.client.NewRequest("DELETE", u, nil)
if err != nil {
return nil, err
}
return s.client.Do(req, nil)
}
// ListReleaseAssets lists the release's assets.
//
// GitHub API docs : http://developer.github.com/v3/repos/releases/#list-assets-for-a-release
func (s *RepositoriesService) ListReleaseAssets(owner, repo string, id int, opt *ListOptions) ([]*ReleaseAsset, *Response, error) {
u := fmt.Sprintf("repos/%s/%s/releases/%d/assets", owner, repo, id)
u, err := addOptions(u, opt)
if err != nil {
return nil, nil, err
}
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
assets := new([]*ReleaseAsset)
resp, err := s.client.Do(req, assets)
if err != nil {
return nil, resp, nil
}
return *assets, resp, err
}
// GetReleaseAsset fetches a single release asset.
//
// GitHub API docs : http://developer.github.com/v3/repos/releases/#get-a-single-release-asset
func (s *RepositoriesService) GetReleaseAsset(owner, repo string, id int) (*ReleaseAsset, *Response, error) {
u := fmt.Sprintf("repos/%s/%s/releases/assets/%d", owner, repo, id)
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
asset := new(ReleaseAsset)
resp, err := s.client.Do(req, asset)
if err != nil {
return nil, resp, nil
}
return asset, resp, err
}
// DownloadReleaseAsset downloads a release asset or returns a redirect URL.
//
// DownloadReleaseAsset returns an io.ReadCloser that reads the contents of the
// specified release asset. It is the caller's responsibility to close the ReadCloser.
// If a redirect is returned, the redirect URL will be returned as a string instead
// of the io.ReadCloser. Exactly one of rc and redirectURL will be zero.
//
// GitHub API docs : http://developer.github.com/v3/repos/releases/#get-a-single-release-asset
func (s *RepositoriesService) DownloadReleaseAsset(owner, repo string, id int) (rc io.ReadCloser, redirectURL string, err error) {
u := fmt.Sprintf("repos/%s/%s/releases/assets/%d", owner, repo, id)
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, "", err
}
req.Header.Set("Accept", defaultMediaType)
s.client.clientMu.Lock()
defer s.client.clientMu.Unlock()
var loc string
saveRedirect := s.client.client.CheckRedirect
s.client.client.CheckRedirect = func(req *http.Request, via []*http.Request) error {
loc = req.URL.String()
return errors.New("disable redirect")
}
defer func() { s.client.client.CheckRedirect = saveRedirect }()
resp, err := s.client.client.Do(req)
if err != nil {
if !strings.Contains(err.Error(), "disable redirect") {
return nil, "", err
}
return nil, loc, nil
}
if err := CheckResponse(resp); err != nil {
resp.Body.Close()
return nil, "", err
}
return resp.Body, "", nil
}
// EditReleaseAsset edits a repository release asset.
//
// GitHub API docs : http://developer.github.com/v3/repos/releases/#edit-a-release-asset
func (s *RepositoriesService) EditReleaseAsset(owner, repo string, id int, release *ReleaseAsset) (*ReleaseAsset, *Response, error) {
u := fmt.Sprintf("repos/%s/%s/releases/assets/%d", owner, repo, id)
req, err := s.client.NewRequest("PATCH", u, release)
if err != nil {
return nil, nil, err
}
asset := new(ReleaseAsset)
resp, err := s.client.Do(req, asset)
if err != nil {
return nil, resp, err
}
return asset, resp, err
}
// DeleteReleaseAsset delete a single release asset from a repository.
//
// GitHub API docs : http://developer.github.com/v3/repos/releases/#delete-a-release-asset
func (s *RepositoriesService) DeleteReleaseAsset(owner, repo string, id int) (*Response, error) {
u := fmt.Sprintf("repos/%s/%s/releases/assets/%d", owner, repo, id)
req, err := s.client.NewRequest("DELETE", u, nil)
if err != nil {
return nil, err
}
return s.client.Do(req, nil)
}
// UploadReleaseAsset creates an asset by uploading a file into a release repository.
// To upload assets that cannot be represented by an os.File, call NewUploadRequest directly.
//
// GitHub API docs : http://developer.github.com/v3/repos/releases/#upload-a-release-asset
func (s *RepositoriesService) UploadReleaseAsset(owner, repo string, id int, opt *UploadOptions, file *os.File) (*ReleaseAsset, *Response, error) {
u := fmt.Sprintf("repos/%s/%s/releases/%d/assets", owner, repo, id)
u, err := addOptions(u, opt)
if err != nil {
return nil, nil, err
}
stat, err := file.Stat()
if err != nil {
return nil, nil, err
}
if stat.IsDir() {
return nil, nil, errors.New("the asset to upload can't be a directory")
}
mediaType := mime.TypeByExtension(filepath.Ext(file.Name()))
req, err := s.client.NewUploadRequest(u, file, stat.Size(), mediaType)
if err != nil {
return nil, nil, err
}
asset := new(ReleaseAsset)
resp, err := s.client.Do(req, asset)
if err != nil {
return nil, resp, err
}
return asset, resp, err
}

352
vendor/src/github.com/google/go-github/github/repos_releases_test.go

@ -0,0 +1,352 @@
// Copyright 2013 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github
import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"os"
"reflect"
"strings"
"testing"
)
func TestRepositoriesService_ListReleases(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/releases", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testFormValues(t, r, values{"page": "2"})
fmt.Fprint(w, `[{"id":1}]`)
})
opt := &ListOptions{Page: 2}
releases, _, err := client.Repositories.ListReleases("o", "r", opt)
if err != nil {
t.Errorf("Repositories.ListReleases returned error: %v", err)
}
want := []*RepositoryRelease{{ID: Int(1)}}
if !reflect.DeepEqual(releases, want) {
t.Errorf("Repositories.ListReleases returned %+v, want %+v", releases, want)
}
}
func TestRepositoriesService_GetRelease(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/releases/1", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
fmt.Fprint(w, `{"id":1}`)
})
release, resp, err := client.Repositories.GetRelease("o", "r", 1)
if err != nil {
t.Errorf("Repositories.GetRelease returned error: %v\n%v", err, resp.Body)
}
want := &RepositoryRelease{ID: Int(1)}
if !reflect.DeepEqual(release, want) {
t.Errorf("Repositories.GetRelease returned %+v, want %+v", release, want)
}
}
func TestRepositoriesService_GetLatestRelease(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/releases/latest", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
fmt.Fprint(w, `{"id":3}`)
})
release, resp, err := client.Repositories.GetLatestRelease("o", "r")
if err != nil {
t.Errorf("Repositories.GetLatestRelease returned error: %v\n%v", err, resp.Body)
}
want := &RepositoryRelease{ID: Int(3)}
if !reflect.DeepEqual(release, want) {
t.Errorf("Repositories.GetLatestRelease returned %+v, want %+v", release, want)
}
}
func TestRepositoriesService_GetReleaseByTag(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/releases/tags/foo", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
fmt.Fprint(w, `{"id":13}`)
})
release, resp, err := client.Repositories.GetReleaseByTag("o", "r", "foo")
if err != nil {
t.Errorf("Repositories.GetReleaseByTag returned error: %v\n%v", err, resp.Body)
}
want := &RepositoryRelease{ID: Int(13)}
if !reflect.DeepEqual(release, want) {
t.Errorf("Repositories.GetReleaseByTag returned %+v, want %+v", release, want)
}
}
func TestRepositoriesService_CreateRelease(t *testing.T) {
setup()
defer teardown()
input := &RepositoryRelease{Name: String("v1.0")}
mux.HandleFunc("/repos/o/r/releases", func(w http.ResponseWriter, r *http.Request) {
v := new(RepositoryRelease)
json.NewDecoder(r.Body).Decode(v)
testMethod(t, r, "POST")
if !reflect.DeepEqual(v, input) {
t.Errorf("Request body = %+v, want %+v", v, input)
}
fmt.Fprint(w, `{"id":1}`)
})
release, _, err := client.Repositories.CreateRelease("o", "r", input)
if err != nil {
t.Errorf("Repositories.CreateRelease returned error: %v", err)
}
want := &RepositoryRelease{ID: Int(1)}
if !reflect.DeepEqual(release, want) {
t.Errorf("Repositories.CreateRelease returned %+v, want %+v", release, want)
}
}
func TestRepositoriesService_EditRelease(t *testing.T) {
setup()
defer teardown()
input := &RepositoryRelease{Name: String("n")}
mux.HandleFunc("/repos/o/r/releases/1", func(w http.ResponseWriter, r *http.Request) {
v := new(RepositoryRelease)
json.NewDecoder(r.Body).Decode(v)
testMethod(t, r, "PATCH")
if !reflect.DeepEqual(v, input) {
t.Errorf("Request body = %+v, want %+v", v, input)
}
fmt.Fprint(w, `{"id":1}`)
})
release, _, err := client.Repositories.EditRelease("o", "r", 1, input)
if err != nil {
t.Errorf("Repositories.EditRelease returned error: %v", err)
}
want := &RepositoryRelease{ID: Int(1)}
if !reflect.DeepEqual(release, want) {
t.Errorf("Repositories.EditRelease returned = %+v, want %+v", release, want)
}
}
func TestRepositoriesService_DeleteRelease(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/releases/1", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "DELETE")
})
_, err := client.Repositories.DeleteRelease("o", "r", 1)
if err != nil {
t.Errorf("Repositories.DeleteRelease returned error: %v", err)
}
}
func TestRepositoriesService_ListReleaseAssets(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/releases/1/assets", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testFormValues(t, r, values{"page": "2"})
fmt.Fprint(w, `[{"id":1}]`)
})
opt := &ListOptions{Page: 2}
assets, _, err := client.Repositories.ListReleaseAssets("o", "r", 1, opt)
if err != nil {
t.Errorf("Repositories.ListReleaseAssets returned error: %v", err)
}
want := []*ReleaseAsset{{ID: Int(1)}}
if !reflect.DeepEqual(assets, want) {
t.Errorf("Repositories.ListReleaseAssets returned %+v, want %+v", assets, want)
}
}
func TestRepositoriesService_GetReleaseAsset(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/releases/assets/1", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
fmt.Fprint(w, `{"id":1}`)
})
asset, _, err := client.Repositories.GetReleaseAsset("o", "r", 1)
if err != nil {
t.Errorf("Repositories.GetReleaseAsset returned error: %v", err)
}
want := &ReleaseAsset{ID: Int(1)}
if !reflect.DeepEqual(asset, want) {
t.Errorf("Repositories.GetReleaseAsset returned %+v, want %+v", asset, want)
}
}
func TestRepositoriesService_DownloadReleaseAsset_Stream(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/releases/assets/1", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testHeader(t, r, "Accept", defaultMediaType)
w.Header().Set("Content-Type", "application/octet-stream")
w.Header().Set("Content-Disposition", "attachment; filename=hello-world.txt")
fmt.Fprint(w, "Hello World")
})
reader, _, err := client.Repositories.DownloadReleaseAsset("o", "r", 1)
if err != nil {
t.Errorf("Repositories.DownloadReleaseAsset returned error: %v", err)
}
want := []byte("Hello World")
content, err := ioutil.ReadAll(reader)
if err != nil {
t.Errorf("Repositories.DownloadReleaseAsset returned bad reader: %v", err)
}
if !bytes.Equal(want, content) {
t.Errorf("Repositories.DownloadReleaseAsset returned %+v, want %+v", content, want)
}
}
func TestRepositoriesService_DownloadReleaseAsset_Redirect(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/releases/assets/1", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testHeader(t, r, "Accept", defaultMediaType)
http.Redirect(w, r, "/yo", http.StatusFound)
})
_, got, err := client.Repositories.DownloadReleaseAsset("o", "r", 1)
if err != nil {
t.Errorf("Repositories.DownloadReleaseAsset returned error: %v", err)
}
want := "/yo"
if !strings.HasSuffix(got, want) {
t.Errorf("Repositories.DownloadReleaseAsset returned %+v, want %+v", got, want)
}
}
func TestRepositoriesService_DownloadReleaseAsset_APIError(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/releases/assets/1", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
testHeader(t, r, "Accept", defaultMediaType)
w.WriteHeader(http.StatusNotFound)
fmt.Fprint(w, `{"message":"Not Found","documentation_url":"https://developer.github.com/v3"}`)
})
resp, loc, err := client.Repositories.DownloadReleaseAsset("o", "r", 1)
if err == nil {
t.Error("Repositories.DownloadReleaseAsset did not return an error")
}
if resp != nil {
resp.Close()
t.Error("Repositories.DownloadReleaseAsset returned stream, want nil")
}
if loc != "" {
t.Errorf(`Repositories.DownloadReleaseAsset returned "%s", want empty ""`, loc)
}
}
func TestRepositoriesService_EditReleaseAsset(t *testing.T) {
setup()
defer teardown()
input := &ReleaseAsset{Name: String("n")}
mux.HandleFunc("/repos/o/r/releases/assets/1", func(w http.ResponseWriter, r *http.Request) {
v := new(ReleaseAsset)
json.NewDecoder(r.Body).Decode(v)
testMethod(t, r, "PATCH")
if !reflect.DeepEqual(v, input) {
t.Errorf("Request body = %+v, want %+v", v, input)
}
fmt.Fprint(w, `{"id":1}`)
})
asset, _, err := client.Repositories.EditReleaseAsset("o", "r", 1, input)
if err != nil {
t.Errorf("Repositories.EditReleaseAsset returned error: %v", err)
}
want := &ReleaseAsset{ID: Int(1)}
if !reflect.DeepEqual(asset, want) {
t.Errorf("Repositories.EditReleaseAsset returned = %+v, want %+v", asset, want)
}
}
func TestRepositoriesService_DeleteReleaseAsset(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/releases/assets/1", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "DELETE")
})
_, err := client.Repositories.DeleteReleaseAsset("o", "r", 1)
if err != nil {
t.Errorf("Repositories.DeleteReleaseAsset returned error: %v", err)
}
}
func TestRepositoriesService_UploadReleaseAsset(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/releases/1/assets", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "POST")
testHeader(t, r, "Content-Type", "text/plain; charset=utf-8")
testHeader(t, r, "Content-Length", "12")
testFormValues(t, r, values{"name": "n"})
testBody(t, r, "Upload me !\n")
fmt.Fprintf(w, `{"id":1}`)
})
file, dir, err := openTestFile("upload.txt", "Upload me !\n")
if err != nil {
t.Fatalf("Unable to create temp file: %v", err)
}
defer os.RemoveAll(dir)
opt := &UploadOptions{Name: "n"}
asset, _, err := client.Repositories.UploadReleaseAsset("o", "r", 1, opt, file)
if err != nil {
t.Errorf("Repositories.UploadReleaseAssert returned error: %v", err)
}
want := &ReleaseAsset{ID: Int(1)}
if !reflect.DeepEqual(asset, want) {
t.Errorf("Repositories.UploadReleaseAssert returned %+v, want %+v", asset, want)
}
}

214
vendor/src/github.com/google/go-github/github/repos_stats.go

@ -0,0 +1,214 @@
// Copyright 2014 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github
import (
"fmt"
"time"
)
// ContributorStats represents a contributor to a repository and their
// weekly contributions to a given repo.
type ContributorStats struct {
Author *Contributor `json:"author,omitempty"`
Total *int `json:"total,omitempty"`
Weeks []WeeklyStats `json:"weeks,omitempty"`
}
func (c ContributorStats) String() string {
return Stringify(c)
}
// WeeklyStats represents the number of additions, deletions and commits
// a Contributor made in a given week.
type WeeklyStats struct {
Week *Timestamp `json:"w,omitempty"`
Additions *int `json:"a,omitempty"`
Deletions *int `json:"d,omitempty"`
Commits *int `json:"c,omitempty"`
}
func (w WeeklyStats) String() string {
return Stringify(w)
}
// ListContributorsStats gets a repo's contributor list with additions,
// deletions and commit counts.
//
// If this is the first time these statistics are requested for the given
// repository, this method will return a non-nil error and a status code of
// 202. This is because this is the status that github returns to signify that
// it is now computing the requested statistics. A follow up request, after a
// delay of a second or so, should result in a successful request.
//
// GitHub API Docs: https://developer.github.com/v3/repos/statistics/#contributors
func (s *RepositoriesService) ListContributorsStats(owner, repo string) ([]*ContributorStats, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/stats/contributors", owner, repo)
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
var contributorStats []*ContributorStats
resp, err := s.client.Do(req, &contributorStats)
if err != nil {
return nil, resp, err
}
return contributorStats, resp, err
}
// WeeklyCommitActivity represents the weekly commit activity for a repository.
// The days array is a group of commits per day, starting on Sunday.
type WeeklyCommitActivity struct {
Days []int `json:"days,omitempty"`
Total *int `json:"total,omitempty"`
Week *Timestamp `json:"week,omitempty"`
}
func (w WeeklyCommitActivity) String() string {
return Stringify(w)
}
// ListCommitActivity returns the last year of commit activity
// grouped by week. The days array is a group of commits per day,
// starting on Sunday.
//
// If this is the first time these statistics are requested for the given
// repository, this method will return a non-nil error and a status code of
// 202. This is because this is the status that github returns to signify that
// it is now computing the requested statistics. A follow up request, after a
// delay of a second or so, should result in a successful request.
//
// GitHub API Docs: https://developer.github.com/v3/repos/statistics/#commit-activity
func (s *RepositoriesService) ListCommitActivity(owner, repo string) ([]*WeeklyCommitActivity, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/stats/commit_activity", owner, repo)
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
var weeklyCommitActivity []*WeeklyCommitActivity
resp, err := s.client.Do(req, &weeklyCommitActivity)
if err != nil {
return nil, resp, err
}
return weeklyCommitActivity, resp, err
}
// ListCodeFrequency returns a weekly aggregate of the number of additions and
// deletions pushed to a repository. Returned WeeklyStats will contain
// additions and deletions, but not total commits.
//
// GitHub API Docs: https://developer.github.com/v3/repos/statistics/#code-frequency
func (s *RepositoriesService) ListCodeFrequency(owner, repo string) ([]*WeeklyStats, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/stats/code_frequency", owner, repo)
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
var weeks [][]int
resp, err := s.client.Do(req, &weeks)
// convert int slices into WeeklyStats
var stats []*WeeklyStats
for _, week := range weeks {
if len(week) != 3 {
continue
}
stat := &WeeklyStats{
Week: &Timestamp{time.Unix(int64(week[0]), 0)},
Additions: Int(week[1]),
Deletions: Int(week[2]),
}
stats = append(stats, stat)
}
return stats, resp, err
}
// RepositoryParticipation is the number of commits by everyone
// who has contributed to the repository (including the owner)
// as well as the number of commits by the owner themself.
type RepositoryParticipation struct {
All []int `json:"all,omitempty"`
Owner []int `json:"owner,omitempty"`
}
func (r RepositoryParticipation) String() string {
return Stringify(r)
}
// ListParticipation returns the total commit counts for the 'owner'
// and total commit counts in 'all'. 'all' is everyone combined,
// including the 'owner' in the last 52 weeks. If you’d like to get
// the commit counts for non-owners, you can subtract 'all' from 'owner'.
//
// The array order is oldest week (index 0) to most recent week.
//
// If this is the first time these statistics are requested for the given
// repository, this method will return a non-nil error and a status code
// of 202. This is because this is the status that github returns to
// signify that it is now computing the requested statistics. A follow
// up request, after a delay of a second or so, should result in a
// successful request.
//
// GitHub API Docs: https://developer.github.com/v3/repos/statistics/#participation
func (s *RepositoriesService) ListParticipation(owner, repo string) (*RepositoryParticipation, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/stats/participation", owner, repo)
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
participation := new(RepositoryParticipation)
resp, err := s.client.Do(req, participation)
if err != nil {
return nil, resp, err
}
return participation, resp, err
}
// PunchCard represents the number of commits made during a given hour of a
// day of thew eek.
type PunchCard struct {
Day *int // Day of the week (0-6: =Sunday - Saturday).
Hour *int // Hour of day (0-23).
Commits *int // Number of commits.
}
// ListPunchCard returns the number of commits per hour in each day.
//
// GitHub API Docs: https://developer.github.com/v3/repos/statistics/#punch-card
func (s *RepositoriesService) ListPunchCard(owner, repo string) ([]*PunchCard, *Response, error) {
u := fmt.Sprintf("repos/%v/%v/stats/punch_card", owner, repo)
req, err := s.client.NewRequest("GET", u, nil)
if err != nil {
return nil, nil, err
}
var results [][]int
resp, err := s.client.Do(req, &results)
// convert int slices into Punchcards
var cards []*PunchCard
for _, result := range results {
if len(result) != 3 {
continue
}
card := &PunchCard{
Day: Int(result[0]),
Hour: Int(result[1]),
Commits: Int(result[2]),
}
cards = append(cards, card)
}
return cards, resp, err
}

210
vendor/src/github.com/google/go-github/github/repos_stats_test.go

@ -0,0 +1,210 @@
// Copyright 2014 The go-github AUTHORS. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package github
import (
"fmt"
"net/http"
"reflect"
"testing"
"time"
)
func TestRepositoriesService_ListContributorsStats(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/stats/contributors", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
fmt.Fprint(w, `
[
{
"author": {
"id": 1
},
"total": 135,
"weeks": [
{
"w": 1367712000,
"a": 6898,
"d": 77,
"c": 10
}
]
}
]
`)
})
stats, _, err := client.Repositories.ListContributorsStats("o", "r")
if err != nil {
t.Errorf("RepositoriesService.ListContributorsStats returned error: %v", err)
}
want := []*ContributorStats{
{
Author: &Contributor{
ID: Int(1),
},
Total: Int(135),
Weeks: []WeeklyStats{
{
Week: &Timestamp{time.Date(2013, 05, 05, 00, 00, 00, 0, time.UTC).Local()},
Additions: Int(6898),
Deletions: Int(77),
Commits: Int(10),
},
},
},
}
if !reflect.DeepEqual(stats, want) {
t.Errorf("RepositoriesService.ListContributorsStats returned %+v, want %+v", stats, want)
}
}
func TestRepositoriesService_ListCommitActivity(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/stats/commit_activity", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
fmt.Fprint(w, `
[
{
"days": [0, 3, 26, 20, 39, 1, 0],
"total": 89,
"week": 1336280400
}
]
`)
})
activity, _, err := client.Repositories.ListCommitActivity("o", "r")
if err != nil {
t.Errorf("RepositoriesService.ListCommitActivity returned error: %v", err)
}
want := []*WeeklyCommitActivity{
{
Days: []int{0, 3, 26, 20, 39, 1, 0},
Total: Int(89),
Week: &Timestamp{time.Date(2012, 05, 06, 05, 00, 00, 0, time.UTC).Local()},
},
}
if !reflect.DeepEqual(activity, want) {
t.Errorf("RepositoriesService.ListCommitActivity returned %+v, want %+v", activity, want)
}
}
func TestRepositoriesService_ListCodeFrequency(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/stats/code_frequency", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
fmt.Fprint(w, `[[1302998400, 1124, -435]]`)
})
code, _, err := client.Repositories.ListCodeFrequency("o", "r")
if err != nil {
t.Errorf("RepositoriesService.ListCodeFrequency returned error: %v", err)
}
want := []*WeeklyStats{{
Week: &Timestamp{time.Date(2011, 04, 17, 00, 00, 00, 0, time.UTC).Local()},
Additions: Int(1124),
Deletions: Int(-435),
}}
if !reflect.DeepEqual(code, want) {
t.Errorf("RepositoriesService.ListCodeFrequency returned %+v, want %+v", code, want)
}
}
func TestRepositoriesService_Participation(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/stats/participation", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
fmt.Fprint(w, `
{
"all": [
11,21,15,2,8,1,8,23,17,21,11,10,33,
91,38,34,22,23,32,3,43,87,71,18,13,5,
13,16,66,27,12,45,110,117,13,8,18,9,19,
26,39,12,20,31,46,91,45,10,24,9,29,7
],
"owner": [
3,2,3,0,2,0,5,14,7,9,1,5,0,
48,19,2,0,1,10,2,23,40,35,8,8,2,
10,6,30,0,2,9,53,104,3,3,10,4,7,
11,21,4,4,22,26,63,11,2,14,1,10,3
]
}
`)
})
participation, _, err := client.Repositories.ListParticipation("o", "r")
if err != nil {
t.Errorf("RepositoriesService.ListParticipation returned error: %v", err)
}
want := &RepositoryParticipation{
All: []int{
11, 21, 15, 2, 8, 1, 8, 23, 17, 21, 11, 10, 33,
91, 38, 34, 22, 23, 32, 3, 43, 87, 71, 18, 13, 5,
13, 16, 66, 27, 12, 45, 110, 117, 13, 8, 18, 9, 19,
26, 39, 12, 20, 31, 46, 91, 45, 10, 24, 9, 29, 7,
},
Owner: []int{
3, 2, 3, 0, 2, 0, 5, 14, 7, 9, 1, 5, 0,
48, 19, 2, 0, 1, 10, 2, 23, 40, 35, 8, 8, 2,
10, 6, 30, 0, 2, 9, 53, 104, 3, 3, 10, 4, 7,
11, 21, 4, 4, 22, 26, 63, 11, 2, 14, 1, 10, 3,
},
}
if !reflect.DeepEqual(participation, want) {
t.Errorf("RepositoriesService.ListParticipation returned %+v, want %+v", participation, want)
}
}
func TestRepositoriesService_ListPunchCard(t *testing.T) {
setup()
defer teardown()
mux.HandleFunc("/repos/o/r/stats/punch_card", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "GET")
fmt.Fprint(w, `[
[0, 0, 5],
[0, 1, 43],
[0, 2, 21]
]`)
})
card, _, err := client.Repositories.ListPunchCard("o", "r")
if err != nil {
t.Errorf("RepositoriesService.ListPunchCard returned error: %v", err)
}
want := []*PunchCard{
{Day: Int(0), Hour: Int(0), Commits: Int(5)},
{Day: Int(0), Hour: Int(1), Commits: Int(43)},
{Day: Int(0), Hour: Int(2), Commits: Int(21)},
}
if !reflect.DeepEqual(card, want) {
t.Errorf("RepositoriesService.ListPunchCard returned %+v, want %+v", card, want)
}
}

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save