@ -9,6 +9,7 @@ import (
"bytes"
"bytes"
"encoding/json"
"encoding/json"
"fmt"
"fmt"
"io"
"net/url"
"net/url"
"strings"
"strings"
"time"
"time"
@ -21,42 +22,77 @@ type Permission struct {
Pull bool ` json:"pull" `
Pull bool ` json:"pull" `
}
}
// InternalTracker represents settings for internal tracker
type InternalTracker struct {
// Enable time tracking (Built-in issue tracker)
EnableTimeTracker bool ` json:"enable_time_tracker" `
// Let only contributors track time (Built-in issue tracker)
AllowOnlyContributorsToTrackTime bool ` json:"allow_only_contributors_to_track_time" `
// Enable dependencies for issues and pull requests (Built-in issue tracker)
EnableIssueDependencies bool ` json:"enable_issue_dependencies" `
}
// ExternalTracker represents settings for external tracker
type ExternalTracker struct {
// URL of external issue tracker.
ExternalTrackerURL string ` json:"external_tracker_url" `
// External Issue Tracker URL Format. Use the placeholders {user}, {repo} and {index} for the username, repository name and issue index.
ExternalTrackerFormat string ` json:"external_tracker_format" `
// External Issue Tracker Number Format, either `numeric` or `alphanumeric`
ExternalTrackerStyle string ` json:"external_tracker_style" `
}
// ExternalWiki represents setting for external wiki
type ExternalWiki struct {
// URL of external wiki.
ExternalWikiURL string ` json:"external_wiki_url" `
}
// Repository represents a repository
// Repository represents a repository
type Repository struct {
type Repository struct {
ID int64 ` json:"id" `
ID int64 ` json:"id" `
Owner * User ` json:"owner" `
Owner * User ` json:"owner" `
Name string ` json:"name" `
Name string ` json:"name" `
FullName string ` json:"full_name" `
FullName string ` json:"full_name" `
Description string ` json:"description" `
Description string ` json:"description" `
Empty bool ` json:"empty" `
Empty bool ` json:"empty" `
Private bool ` json:"private" `
Private bool ` json:"private" `
Fork bool ` json:"fork" `
Fork bool ` json:"fork" `
Parent * Repository ` json:"parent" `
Template bool ` json:"template" `
Mirror bool ` json:"mirror" `
Parent * Repository ` json:"parent" `
Size int ` json:"size" `
Mirror bool ` json:"mirror" `
HTMLURL string ` json:"html_url" `
Size int ` json:"size" `
SSHURL string ` json:"ssh_url" `
HTMLURL string ` json:"html_url" `
CloneURL string ` json:"clone_url" `
SSHURL string ` json:"ssh_url" `
OriginalURL string ` json:"original_url" `
CloneURL string ` json:"clone_url" `
Website string ` json:"website" `
OriginalURL string ` json:"original_url" `
Stars int ` json:"stars_count" `
Website string ` json:"website" `
Forks int ` json:"forks_count" `
Stars int ` json:"stars_count" `
Watchers int ` json:"watchers_count" `
Forks int ` json:"forks_count" `
OpenIssues int ` json:"open_issues_count" `
Watchers int ` json:"watchers_count" `
DefaultBranch string ` json:"default_branch" `
OpenIssues int ` json:"open_issues_count" `
Archived bool ` json:"archived" `
OpenPulls int ` json:"open_pr_counter" `
Created time . Time ` json:"created_at" `
Releases int ` json:"release_counter" `
Updated time . Time ` json:"updated_at" `
DefaultBranch string ` json:"default_branch" `
Permissions * Permission ` json:"permissions,omitempty" `
Archived bool ` json:"archived" `
HasIssues bool ` json:"has_issues" `
Created time . Time ` json:"created_at" `
HasWiki bool ` json:"has_wiki" `
Updated time . Time ` json:"updated_at" `
HasPullRequests bool ` json:"has_pull_requests" `
Permissions * Permission ` json:"permissions,omitempty" `
IgnoreWhitespaceConflicts bool ` json:"ignore_whitespace_conflicts" `
HasIssues bool ` json:"has_issues" `
AllowMerge bool ` json:"allow_merge_commits" `
InternalTracker * InternalTracker ` json:"internal_tracker,omitempty" `
AllowRebase bool ` json:"allow_rebase" `
ExternalTracker * ExternalTracker ` json:"external_tracker,omitempty" `
AllowRebaseMerge bool ` json:"allow_rebase_explicit" `
HasWiki bool ` json:"has_wiki" `
AllowSquash bool ` json:"allow_squash_merge" `
ExternalWiki * ExternalWiki ` json:"external_wiki,omitempty" `
AvatarURL string ` json:"avatar_url" `
HasPullRequests bool ` json:"has_pull_requests" `
HasProjects bool ` json:"has_projects" `
IgnoreWhitespaceConflicts bool ` json:"ignore_whitespace_conflicts" `
AllowMerge bool ` json:"allow_merge_commits" `
AllowRebase bool ` json:"allow_rebase" `
AllowRebaseMerge bool ` json:"allow_rebase_explicit" `
AllowSquash bool ` json:"allow_squash_merge" `
AvatarURL string ` json:"avatar_url" `
Internal bool ` json:"internal" `
MirrorInterval string ` json:"mirror_interval" `
}
}
// RepoType represent repo type
// RepoType represent repo type
@ -102,6 +138,9 @@ func (c *Client) ListMyRepos(opt ListReposOptions) ([]*Repository, *Response, er
// ListUserRepos list all repositories of one user by user's name
// ListUserRepos list all repositories of one user by user's name
func ( c * Client ) ListUserRepos ( user string , opt ListReposOptions ) ( [ ] * Repository , * Response , error ) {
func ( c * Client ) ListUserRepos ( user string , opt ListReposOptions ) ( [ ] * Repository , * Response , error ) {
if err := escapeValidatePathSegments ( & user ) ; err != nil {
return nil , nil , err
}
opt . setDefaults ( )
opt . setDefaults ( )
repos := make ( [ ] * Repository , 0 , opt . PageSize )
repos := make ( [ ] * Repository , 0 , opt . PageSize )
resp , err := c . getParsedResponse ( "GET" , fmt . Sprintf ( "/users/%s/repos?%s" , user , opt . getURLQuery ( ) . Encode ( ) ) , nil , nil , & repos )
resp , err := c . getParsedResponse ( "GET" , fmt . Sprintf ( "/users/%s/repos?%s" , user , opt . getURLQuery ( ) . Encode ( ) ) , nil , nil , & repos )
@ -115,6 +154,9 @@ type ListOrgReposOptions struct {
// ListOrgRepos list all repositories of one organization by organization's name
// ListOrgRepos list all repositories of one organization by organization's name
func ( c * Client ) ListOrgRepos ( org string , opt ListOrgReposOptions ) ( [ ] * Repository , * Response , error ) {
func ( c * Client ) ListOrgRepos ( org string , opt ListOrgReposOptions ) ( [ ] * Repository , * Response , error ) {
if err := escapeValidatePathSegments ( & org ) ; err != nil {
return nil , nil , err
}
opt . setDefaults ( )
opt . setDefaults ( )
repos := make ( [ ] * Repository , 0 , opt . PageSize )
repos := make ( [ ] * Repository , 0 , opt . PageSize )
resp , err := c . getParsedResponse ( "GET" , fmt . Sprintf ( "/orgs/%s/repos?%s" , org , opt . getURLQuery ( ) . Encode ( ) ) , nil , nil , & repos )
resp , err := c . getParsedResponse ( "GET" , fmt . Sprintf ( "/orgs/%s/repos?%s" , org , opt . getURLQuery ( ) . Encode ( ) ) , nil , nil , & repos )
@ -315,6 +357,9 @@ func (c *Client) CreateRepo(opt CreateRepoOption) (*Repository, *Response, error
// CreateOrgRepo creates an organization repository for authenticated user.
// CreateOrgRepo creates an organization repository for authenticated user.
func ( c * Client ) CreateOrgRepo ( org string , opt CreateRepoOption ) ( * Repository , * Response , error ) {
func ( c * Client ) CreateOrgRepo ( org string , opt CreateRepoOption ) ( * Repository , * Response , error ) {
if err := escapeValidatePathSegments ( & org ) ; err != nil {
return nil , nil , err
}
if err := opt . Validate ( c ) ; err != nil {
if err := opt . Validate ( c ) ; err != nil {
return nil , nil , err
return nil , nil , err
}
}
@ -329,6 +374,9 @@ func (c *Client) CreateOrgRepo(org string, opt CreateRepoOption) (*Repository, *
// GetRepo returns information of a repository of given owner.
// GetRepo returns information of a repository of given owner.
func ( c * Client ) GetRepo ( owner , reponame string ) ( * Repository , * Response , error ) {
func ( c * Client ) GetRepo ( owner , reponame string ) ( * Repository , * Response , error ) {
if err := escapeValidatePathSegments ( & owner , & reponame ) ; err != nil {
return nil , nil , err
}
repo := new ( Repository )
repo := new ( Repository )
resp , err := c . getParsedResponse ( "GET" , fmt . Sprintf ( "/repos/%s/%s" , owner , reponame ) , nil , nil , repo )
resp , err := c . getParsedResponse ( "GET" , fmt . Sprintf ( "/repos/%s/%s" , owner , reponame ) , nil , nil , repo )
return repo , resp , err
return repo , resp , err
@ -346,14 +394,24 @@ type EditRepoOption struct {
// Note: you will get a 422 error if the organization restricts changing repository visibility to organization
// Note: you will get a 422 error if the organization restricts changing repository visibility to organization
// owners and a non-owner tries to change the value of private.
// owners and a non-owner tries to change the value of private.
Private * bool ` json:"private,omitempty" `
Private * bool ` json:"private,omitempty" `
// either `true` to make this repository a template or `false` to make it a normal repository
Template * bool ` json:"template,omitempty" `
// either `true` to enable issues for this repository or `false` to disable them.
// either `true` to enable issues for this repository or `false` to disable them.
HasIssues * bool ` json:"has_issues,omitempty" `
HasIssues * bool ` json:"has_issues,omitempty" `
// set this structure to configure internal issue tracker (requires has_issues)
InternalTracker * InternalTracker ` json:"internal_tracker,omitempty" `
// set this structure to use external issue tracker (requires has_issues)
ExternalTracker * ExternalTracker ` json:"external_tracker,omitempty" `
// either `true` to enable the wiki for this repository or `false` to disable it.
// either `true` to enable the wiki for this repository or `false` to disable it.
HasWiki * bool ` json:"has_wiki,omitempty" `
HasWiki * bool ` json:"has_wiki,omitempty" `
// set this structure to use external wiki instead of internal (requires has_wiki)
ExternalWiki * ExternalWiki ` json:"external_wiki,omitempty" `
// sets the default branch for this repository.
// sets the default branch for this repository.
DefaultBranch * string ` json:"default_branch,omitempty" `
DefaultBranch * string ` json:"default_branch,omitempty" `
// either `true` to allow pull requests, or `false` to prevent pull request.
// either `true` to allow pull requests, or `false` to prevent pull request.
HasPullRequests * bool ` json:"has_pull_requests,omitempty" `
HasPullRequests * bool ` json:"has_pull_requests,omitempty" `
// either `true` to enable project unit, or `false` to disable them.
HasProjects * bool ` json:"has_projects,omitempty" `
// either `true` to ignore whitespace for conflicts, or `false` to not ignore whitespace. `has_pull_requests` must be `true`.
// either `true` to ignore whitespace for conflicts, or `false` to not ignore whitespace. `has_pull_requests` must be `true`.
IgnoreWhitespaceConflicts * bool ` json:"ignore_whitespace_conflicts,omitempty" `
IgnoreWhitespaceConflicts * bool ` json:"ignore_whitespace_conflicts,omitempty" `
// either `true` to allow merging pull requests with a merge commit, or `false` to prevent merging pull requests with merge commits. `has_pull_requests` must be `true`.
// either `true` to allow merging pull requests with a merge commit, or `false` to prevent merging pull requests with merge commits. `has_pull_requests` must be `true`.
@ -366,10 +424,15 @@ type EditRepoOption struct {
AllowSquash * bool ` json:"allow_squash_merge,omitempty" `
AllowSquash * bool ` json:"allow_squash_merge,omitempty" `
// set to `true` to archive this repository.
// set to `true` to archive this repository.
Archived * bool ` json:"archived,omitempty" `
Archived * bool ` json:"archived,omitempty" `
// set to a string like `8h30m0s` to set the mirror interval time
MirrorInterval * string ` json:"mirror_interval,omitempty" `
}
}
// EditRepo edit the properties of a repository
// EditRepo edit the properties of a repository
func ( c * Client ) EditRepo ( owner , reponame string , opt EditRepoOption ) ( * Repository , * Response , error ) {
func ( c * Client ) EditRepo ( owner , reponame string , opt EditRepoOption ) ( * Repository , * Response , error ) {
if err := escapeValidatePathSegments ( & owner , & reponame ) ; err != nil {
return nil , nil , err
}
body , err := json . Marshal ( & opt )
body , err := json . Marshal ( & opt )
if err != nil {
if err != nil {
return nil , nil , err
return nil , nil , err
@ -381,18 +444,27 @@ func (c *Client) EditRepo(owner, reponame string, opt EditRepoOption) (*Reposito
// DeleteRepo deletes a repository of user or organization.
// DeleteRepo deletes a repository of user or organization.
func ( c * Client ) DeleteRepo ( owner , repo string ) ( * Response , error ) {
func ( c * Client ) DeleteRepo ( owner , repo string ) ( * Response , error ) {
if err := escapeValidatePathSegments ( & owner , & repo ) ; err != nil {
return nil , err
}
_ , resp , err := c . getResponse ( "DELETE" , fmt . Sprintf ( "/repos/%s/%s" , owner , repo ) , nil , nil )
_ , resp , err := c . getResponse ( "DELETE" , fmt . Sprintf ( "/repos/%s/%s" , owner , repo ) , nil , nil )
return resp , err
return resp , err
}
}
// MirrorSync adds a mirrored repository to the mirror sync queue.
// MirrorSync adds a mirrored repository to the mirror sync queue.
func ( c * Client ) MirrorSync ( owner , repo string ) ( * Response , error ) {
func ( c * Client ) MirrorSync ( owner , repo string ) ( * Response , error ) {
if err := escapeValidatePathSegments ( & owner , & repo ) ; err != nil {
return nil , err
}
_ , resp , err := c . getResponse ( "POST" , fmt . Sprintf ( "/repos/%s/%s/mirror-sync" , owner , repo ) , nil , nil )
_ , resp , err := c . getResponse ( "POST" , fmt . Sprintf ( "/repos/%s/%s/mirror-sync" , owner , repo ) , nil , nil )
return resp , err
return resp , err
}
}
// GetRepoLanguages return language stats of a repo
// GetRepoLanguages return language stats of a repo
func ( c * Client ) GetRepoLanguages ( owner , repo string ) ( map [ string ] int64 , * Response , error ) {
func ( c * Client ) GetRepoLanguages ( owner , repo string ) ( map [ string ] int64 , * Response , error ) {
if err := escapeValidatePathSegments ( & owner , & repo ) ; err != nil {
return nil , nil , err
}
langMap := make ( map [ string ] int64 )
langMap := make ( map [ string ] int64 )
data , resp , err := c . getResponse ( "GET" , fmt . Sprintf ( "/repos/%s/%s/languages" , owner , repo ) , jsonHeader , nil )
data , resp , err := c . getResponse ( "GET" , fmt . Sprintf ( "/repos/%s/%s/languages" , owner , repo ) , jsonHeader , nil )
@ -418,5 +490,30 @@ const (
// GetArchive get an archive of a repository by git reference
// GetArchive get an archive of a repository by git reference
// e.g.: ref -> master, 70b7c74b33, v1.2.1, ...
// e.g.: ref -> master, 70b7c74b33, v1.2.1, ...
func ( c * Client ) GetArchive ( owner , repo , ref string , ext ArchiveType ) ( [ ] byte , * Response , error ) {
func ( c * Client ) GetArchive ( owner , repo , ref string , ext ArchiveType ) ( [ ] byte , * Response , error ) {
return c . getResponse ( "GET" , fmt . Sprintf ( "/repos/%s/%s/archive/%s%s" , owner , repo , url . PathEscape ( ref ) , ext ) , nil , nil )
if err := escapeValidatePathSegments ( & owner , & repo ) ; err != nil {
return nil , nil , err
}
ref = pathEscapeSegments ( ref )
return c . getResponse ( "GET" , fmt . Sprintf ( "/repos/%s/%s/archive/%s%s" , owner , repo , ref , ext ) , nil , nil )
}
// GetArchiveReader gets a `git archive` for a particular tree-ish git reference
// such as a branch name (`master`), a commit hash (`70b7c74b33`), a tag
// (`v1.2.1`). The archive is returned as a byte stream in a ReadCloser. It is
// the responsibility of the client to close the reader.
func ( c * Client ) GetArchiveReader ( owner , repo , ref string , ext ArchiveType ) ( io . ReadCloser , * Response , error ) {
if err := escapeValidatePathSegments ( & owner , & repo ) ; err != nil {
return nil , nil , err
}
ref = pathEscapeSegments ( ref )
resp , err := c . doRequest ( "GET" , fmt . Sprintf ( "/repos/%s/%s/archive/%s%s" , owner , repo , ref , ext ) , nil , nil )
if err != nil {
return nil , resp , err
}
if _ , err := statusCodeToErr ( resp ) ; err != nil {
return nil , resp , err
}
return resp . Body , resp , nil
}
}