all: decouple API types from go-gogs-client SDK (#8171)

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
ᴊᴏᴇ ᴄʜᴇɴ
2026-02-10 10:56:17 -05:00
committed by GitHub
parent 317e28b908
commit a1fa62b270
64 changed files with 1634 additions and 963 deletions

1
go.mod
View File

@@ -22,7 +22,6 @@ require (
github.com/gogs/chardet v0.0.0-20150115103509-2404f7772561
github.com/gogs/cron v0.0.0-20171120032916-9f6c956d3e14
github.com/gogs/git-module v1.8.6
github.com/gogs/go-gogs-client v0.0.0-20200128182646-c69cb7680fd4
github.com/gogs/go-libravatar v0.0.0-20191106065024-33a75213d0a0
github.com/gogs/minwinsvc v0.0.0-20170301035411-95be6356811a
github.com/google/go-github v17.0.0+incompatible

2
go.sum
View File

@@ -153,8 +153,6 @@ github.com/gogs/cron v0.0.0-20171120032916-9f6c956d3e14 h1:yXtpJr/LV6PFu4nTLgfjQ
github.com/gogs/cron v0.0.0-20171120032916-9f6c956d3e14/go.mod h1:jPoNZLWDAqA5N3G5amEoiNbhVrmM+ZQEcnQvNQ2KaZk=
github.com/gogs/git-module v1.8.6 h1:4Io9vWZYQyIjdIPxfKgeYZXnDKNgydc6OZTxII5xCH4=
github.com/gogs/git-module v1.8.6/go.mod h1:IiMSJqi8XH62Kjqjt5Rw8IawSo+DHfM2dDjkSzWLjhs=
github.com/gogs/go-gogs-client v0.0.0-20200128182646-c69cb7680fd4 h1:C7NryI/RQhsIWwC2bHN601P1wJKeuQ6U/UCOYTn3Cic=
github.com/gogs/go-gogs-client v0.0.0-20200128182646-c69cb7680fd4/go.mod h1:fR6z1Ie6rtF7kl/vBYMfgD5/G5B1blui7z426/sj2DU=
github.com/gogs/go-libravatar v0.0.0-20191106065024-33a75213d0a0 h1:K02vod+sn3M1OOkdqi2tPxN2+xESK4qyITVQ3JkGEv4=
github.com/gogs/go-libravatar v0.0.0-20191106065024-33a75213d0a0/go.mod h1:Zas3BtO88pk1cwUfEYlvnl/CRwh0ybDxRWSwRjG8I3w=
github.com/gogs/minwinsvc v0.0.0-20170301035411-95be6356811a h1:8DZwxETOVWIinYxDK+i6L+rMb7eGATGaakD6ZucfHVk=

View File

@@ -12,13 +12,13 @@ import (
"github.com/cockroachdb/errors"
"github.com/gogs/git-module"
api "github.com/gogs/go-gogs-client"
"gorm.io/gorm"
log "unknwon.dev/clog/v2"
"gogs.io/gogs/internal/conf"
"gogs.io/gogs/internal/lazyregexp"
"gogs.io/gogs/internal/repoutil"
apiv1types "gogs.io/gogs/internal/route/api/v1/types"
"gogs.io/gogs/internal/strutil"
"gogs.io/gogs/internal/testutil"
"gogs.io/gogs/internal/tool"
@@ -230,7 +230,7 @@ func (s *ActionsStore) MirrorSyncPush(ctx context.Context, opts MirrorSyncPushOp
err = PrepareWebhooks(
opts.Repo,
HookEventTypePush,
&api.PushPayload{
&apiv1types.WebhookPushPayload{
Ref: opts.RefName,
Before: opts.OldCommitID,
After: opts.NewCommitID,
@@ -496,10 +496,10 @@ func (s *ActionsStore) CommitRepo(ctx context.Context, opts CommitRepoOptions) e
err = PrepareWebhooks(
opts.Repo,
HookEventTypeDelete,
&api.DeletePayload{
&apiv1types.WebhookDeletePayload{
Ref: refName,
RefType: "branch",
PusherType: api.PUSHER_TYPE_USER,
PusherType: apiv1types.WebhookPusherTypeUser,
Repo: apiRepo,
Sender: apiPusher,
},
@@ -540,7 +540,7 @@ func (s *ActionsStore) CommitRepo(ctx context.Context, opts CommitRepoOptions) e
err = PrepareWebhooks(
opts.Repo,
HookEventTypeCreate,
&api.CreatePayload{
&apiv1types.WebhookCreatePayload{
Ref: refName,
RefType: "branch",
DefaultBranch: opts.Repo.DefaultBranch,
@@ -573,7 +573,7 @@ func (s *ActionsStore) CommitRepo(ctx context.Context, opts CommitRepoOptions) e
err = PrepareWebhooks(
opts.Repo,
HookEventTypePush,
&api.PushPayload{
&apiv1types.WebhookPushPayload{
Ref: opts.RefFullName,
Before: opts.OldCommitID,
After: opts.NewCommitID,
@@ -635,10 +635,10 @@ func (s *ActionsStore) PushTag(ctx context.Context, opts PushTagOptions) error {
err = PrepareWebhooks(
opts.Repo,
HookEventTypeDelete,
&api.DeletePayload{
&apiv1types.WebhookDeletePayload{
Ref: refName,
RefType: "tag",
PusherType: api.PUSHER_TYPE_USER,
PusherType: apiv1types.WebhookPusherTypeUser,
Repo: apiRepo,
Sender: apiPusher,
},
@@ -658,7 +658,7 @@ func (s *ActionsStore) PushTag(ctx context.Context, opts PushTagOptions) error {
err = PrepareWebhooks(
opts.Repo,
HookEventTypeCreate,
&api.CreatePayload{
&apiv1types.WebhookCreatePayload{
Ref: refName,
RefType: "tag",
Sha: opts.NewCommitID,
@@ -848,7 +848,7 @@ func NewPushCommits() *PushCommits {
}
}
func (pcs *PushCommits) APIFormat(ctx context.Context, usersStore *UsersStore, repoPath, repoURL string) ([]*api.PayloadCommit, error) {
func (pcs *PushCommits) APIFormat(ctx context.Context, usersStore *UsersStore, repoPath, repoURL string) ([]*apiv1types.WebhookPayloadCommit, error) {
// NOTE: We cache query results in case there are many commits in a single push.
usernameByEmail := make(map[string]string)
getUsernameByEmail := func(email string) (string, error) {
@@ -870,7 +870,7 @@ func (pcs *PushCommits) APIFormat(ctx context.Context, usersStore *UsersStore, r
return user.Name, nil
}
commits := make([]*api.PayloadCommit, len(pcs.Commits))
commits := make([]*apiv1types.WebhookPayloadCommit, len(pcs.Commits))
for i, commit := range pcs.Commits {
authorUsername, err := getUsernameByEmail(commit.AuthorEmail)
if err != nil {
@@ -890,16 +890,16 @@ func (pcs *PushCommits) APIFormat(ctx context.Context, usersStore *UsersStore, r
}
}
commits[i] = &api.PayloadCommit{
commits[i] = &apiv1types.WebhookPayloadCommit{
ID: commit.Sha1,
Message: commit.Message,
URL: fmt.Sprintf("%s/commit/%s", repoURL, commit.Sha1),
Author: &api.PayloadUser{
Author: &apiv1types.WebhookPayloadUser{
Name: commit.AuthorName,
Email: commit.AuthorEmail,
UserName: authorUsername,
},
Committer: &api.PayloadUser{
Committer: &apiv1types.WebhookPayloadUser{
Name: commit.CommitterName,
Email: commit.CommitterEmail,
UserName: committerUsername,

View File

@@ -11,10 +11,9 @@ import (
log "unknwon.dev/clog/v2"
"xorm.io/xorm"
api "github.com/gogs/go-gogs-client"
"gogs.io/gogs/internal/errutil"
"gogs.io/gogs/internal/markup"
apiv1types "gogs.io/gogs/internal/route/api/v1/types"
)
// CommentType defines whether a comment is just a simple comment, an action (like close) or a reference.
@@ -136,8 +135,8 @@ func (c *Comment) HTMLURL() string {
// This method assumes following fields have been assigned with valid values:
// Required - Poster, Issue
func (c *Comment) APIFormat() *api.Comment {
return &api.Comment{
func (c *Comment) APIFormat() *apiv1types.IssueComment {
return &apiv1types.IssueComment{
ID: c.ID,
HTMLURL: c.HTMLURL(),
Poster: c.Poster.APIFormat(),
@@ -347,8 +346,8 @@ func CreateIssueComment(doer *User, repo *Repository, issue *Issue, content stri
}
comment.Issue = issue
if err = PrepareWebhooks(repo, HookEventTypeIssueComment, &api.IssueCommentPayload{
Action: api.HOOK_ISSUE_COMMENT_CREATED,
if err = PrepareWebhooks(repo, HookEventTypeIssueComment, &apiv1types.WebhookIssueCommentPayload{
Action: apiv1types.WebhookIssueCommentCreated,
Issue: issue.APIFormat(),
Comment: comment.APIFormat(),
Repository: repo.APIFormatLegacy(nil),
@@ -483,12 +482,12 @@ func UpdateComment(doer *User, c *Comment, oldContent string) (err error) {
if err = c.Issue.LoadAttributes(); err != nil {
log.Error("Issue.LoadAttributes [issue_id: %d]: %v", c.IssueID, err)
} else if err = PrepareWebhooks(c.Issue.Repo, HookEventTypeIssueComment, &api.IssueCommentPayload{
Action: api.HOOK_ISSUE_COMMENT_EDITED,
} else if err = PrepareWebhooks(c.Issue.Repo, HookEventTypeIssueComment, &apiv1types.WebhookIssueCommentPayload{
Action: apiv1types.WebhookIssueCommentEdited,
Issue: c.Issue.APIFormat(),
Comment: c.APIFormat(),
Changes: &api.ChangesPayload{
Body: &api.ChangesFromPayload{
Changes: &apiv1types.WebhookChangesPayload{
Body: &apiv1types.WebhookChangesFromPayload{
From: oldContent,
},
},
@@ -538,8 +537,8 @@ func DeleteCommentByID(doer *User, id int64) error {
if err = comment.Issue.LoadAttributes(); err != nil {
log.Error("Issue.LoadAttributes [issue_id: %d]: %v", comment.IssueID, err)
} else if err = PrepareWebhooks(comment.Issue.Repo, HookEventTypeIssueComment, &api.IssueCommentPayload{
Action: api.HOOK_ISSUE_COMMENT_DELETED,
} else if err = PrepareWebhooks(comment.Issue.Repo, HookEventTypeIssueComment, &apiv1types.WebhookIssueCommentPayload{
Action: apiv1types.WebhookIssueCommentDeleted,
Issue: comment.Issue.APIFormat(),
Comment: comment.APIFormat(),
Repository: comment.Issue.Repo.APIFormatLegacy(nil),

View File

@@ -11,11 +11,10 @@ import (
log "unknwon.dev/clog/v2"
"xorm.io/xorm"
api "github.com/gogs/go-gogs-client"
"gogs.io/gogs/internal/conf"
"gogs.io/gogs/internal/errutil"
"gogs.io/gogs/internal/markup"
apiv1types "gogs.io/gogs/internal/route/api/v1/types"
"gogs.io/gogs/internal/tool"
)
@@ -172,23 +171,23 @@ func (issue *Issue) HTMLURL() string {
}
// State returns string representation of issue status.
func (issue *Issue) State() api.StateType {
func (issue *Issue) State() apiv1types.IssueStateType {
if issue.IsClosed {
return api.STATE_CLOSED
return apiv1types.IssueStateClosed
}
return api.STATE_OPEN
return apiv1types.IssueStateOpen
}
// This method assumes some fields assigned with values:
// Required - Poster, Labels,
// Optional - Milestone, Assignee, PullRequest
func (issue *Issue) APIFormat() *api.Issue {
apiLabels := make([]*api.Label, len(issue.Labels))
func (issue *Issue) APIFormat() *apiv1types.Issue {
apiLabels := make([]*apiv1types.IssueLabel, len(issue.Labels))
for i := range issue.Labels {
apiLabels[i] = issue.Labels[i].APIFormat()
}
apiIssue := &api.Issue{
apiIssue := &apiv1types.Issue{
ID: issue.ID,
Index: issue.Index,
Poster: issue.Poster.APIFormat(),
@@ -208,7 +207,7 @@ func (issue *Issue) APIFormat() *api.Issue {
apiIssue.Assignee = issue.Assignee.APIFormat()
}
if issue.IsPull {
apiIssue.PullRequest = &api.PullRequestMeta{
apiIssue.PullRequest = &apiv1types.PullRequestMeta{
HasMerged: issue.PullRequest.HasMerged,
}
if issue.PullRequest.HasMerged {
@@ -246,16 +245,16 @@ func (issue *Issue) sendLabelUpdatedWebhook(doer *User) {
log.Error("LoadIssue: %v", err)
return
}
err = PrepareWebhooks(issue.Repo, HookEventTypePullRequest, &api.PullRequestPayload{
Action: api.HOOK_ISSUE_LABEL_UPDATED,
err = PrepareWebhooks(issue.Repo, HookEventTypePullRequest, &apiv1types.WebhookPullRequestPayload{
Action: apiv1types.WebhookIssueLabelUpdated,
Index: issue.Index,
PullRequest: issue.PullRequest.APIFormat(),
Repository: issue.Repo.APIFormatLegacy(nil),
Sender: doer.APIFormat(),
})
} else {
err = PrepareWebhooks(issue.Repo, HookEventTypeIssues, &api.IssuesPayload{
Action: api.HOOK_ISSUE_LABEL_UPDATED,
err = PrepareWebhooks(issue.Repo, HookEventTypeIssues, &apiv1types.WebhookIssuesPayload{
Action: apiv1types.WebhookIssueLabelUpdated,
Index: issue.Index,
Issue: issue.APIFormat(),
Repository: issue.Repo.APIFormatLegacy(nil),
@@ -359,16 +358,16 @@ func (issue *Issue) ClearLabels(doer *User) (err error) {
log.Error("LoadIssue: %v", err)
return err
}
err = PrepareWebhooks(issue.Repo, HookEventTypePullRequest, &api.PullRequestPayload{
Action: api.HOOK_ISSUE_LABEL_CLEARED,
err = PrepareWebhooks(issue.Repo, HookEventTypePullRequest, &apiv1types.WebhookPullRequestPayload{
Action: apiv1types.WebhookIssueLabelCleared,
Index: issue.Index,
PullRequest: issue.PullRequest.APIFormat(),
Repository: issue.Repo.APIFormatLegacy(nil),
Sender: doer.APIFormat(),
})
} else {
err = PrepareWebhooks(issue.Repo, HookEventTypeIssues, &api.IssuesPayload{
Action: api.HOOK_ISSUE_LABEL_CLEARED,
err = PrepareWebhooks(issue.Repo, HookEventTypeIssues, &apiv1types.WebhookIssuesPayload{
Action: apiv1types.WebhookIssueLabelCleared,
Index: issue.Index,
Issue: issue.APIFormat(),
Repository: issue.Repo.APIFormatLegacy(nil),
@@ -487,29 +486,29 @@ func (issue *Issue) ChangeStatus(doer *User, repo *Repository, isClosed bool) (e
if issue.IsPull {
// Merge pull request calls issue.changeStatus so we need to handle separately.
issue.PullRequest.Issue = issue
apiPullRequest := &api.PullRequestPayload{
apiPullRequest := &apiv1types.WebhookPullRequestPayload{
Index: issue.Index,
PullRequest: issue.PullRequest.APIFormat(),
Repository: repo.APIFormatLegacy(nil),
Sender: doer.APIFormat(),
}
if isClosed {
apiPullRequest.Action = api.HOOK_ISSUE_CLOSED
apiPullRequest.Action = apiv1types.WebhookIssueClosed
} else {
apiPullRequest.Action = api.HOOK_ISSUE_REOPENED
apiPullRequest.Action = apiv1types.WebhookIssueReopened
}
err = PrepareWebhooks(repo, HookEventTypePullRequest, apiPullRequest)
} else {
apiIssues := &api.IssuesPayload{
apiIssues := &apiv1types.WebhookIssuesPayload{
Index: issue.Index,
Issue: issue.APIFormat(),
Repository: repo.APIFormatLegacy(nil),
Sender: doer.APIFormat(),
}
if isClosed {
apiIssues.Action = api.HOOK_ISSUE_CLOSED
apiIssues.Action = apiv1types.WebhookIssueClosed
} else {
apiIssues.Action = api.HOOK_ISSUE_REOPENED
apiIssues.Action = apiv1types.WebhookIssueReopened
}
err = PrepareWebhooks(repo, HookEventTypeIssues, apiIssues)
}
@@ -529,12 +528,12 @@ func (issue *Issue) ChangeTitle(doer *User, title string) (err error) {
if issue.IsPull {
issue.PullRequest.Issue = issue
err = PrepareWebhooks(issue.Repo, HookEventTypePullRequest, &api.PullRequestPayload{
Action: api.HOOK_ISSUE_EDITED,
err = PrepareWebhooks(issue.Repo, HookEventTypePullRequest, &apiv1types.WebhookPullRequestPayload{
Action: apiv1types.WebhookIssueEdited,
Index: issue.Index,
PullRequest: issue.PullRequest.APIFormat(),
Changes: &api.ChangesPayload{
Title: &api.ChangesFromPayload{
Changes: &apiv1types.WebhookChangesPayload{
Title: &apiv1types.WebhookChangesFromPayload{
From: oldTitle,
},
},
@@ -542,12 +541,12 @@ func (issue *Issue) ChangeTitle(doer *User, title string) (err error) {
Sender: doer.APIFormat(),
})
} else {
err = PrepareWebhooks(issue.Repo, HookEventTypeIssues, &api.IssuesPayload{
Action: api.HOOK_ISSUE_EDITED,
err = PrepareWebhooks(issue.Repo, HookEventTypeIssues, &apiv1types.WebhookIssuesPayload{
Action: apiv1types.WebhookIssueEdited,
Index: issue.Index,
Issue: issue.APIFormat(),
Changes: &api.ChangesPayload{
Title: &api.ChangesFromPayload{
Changes: &apiv1types.WebhookChangesPayload{
Title: &apiv1types.WebhookChangesFromPayload{
From: oldTitle,
},
},
@@ -571,12 +570,12 @@ func (issue *Issue) ChangeContent(doer *User, content string) (err error) {
if issue.IsPull {
issue.PullRequest.Issue = issue
err = PrepareWebhooks(issue.Repo, HookEventTypePullRequest, &api.PullRequestPayload{
Action: api.HOOK_ISSUE_EDITED,
err = PrepareWebhooks(issue.Repo, HookEventTypePullRequest, &apiv1types.WebhookPullRequestPayload{
Action: apiv1types.WebhookIssueEdited,
Index: issue.Index,
PullRequest: issue.PullRequest.APIFormat(),
Changes: &api.ChangesPayload{
Body: &api.ChangesFromPayload{
Changes: &apiv1types.WebhookChangesPayload{
Body: &apiv1types.WebhookChangesFromPayload{
From: oldContent,
},
},
@@ -584,12 +583,12 @@ func (issue *Issue) ChangeContent(doer *User, content string) (err error) {
Sender: doer.APIFormat(),
})
} else {
err = PrepareWebhooks(issue.Repo, HookEventTypeIssues, &api.IssuesPayload{
Action: api.HOOK_ISSUE_EDITED,
err = PrepareWebhooks(issue.Repo, HookEventTypeIssues, &apiv1types.WebhookIssuesPayload{
Action: apiv1types.WebhookIssueEdited,
Index: issue.Index,
Issue: issue.APIFormat(),
Changes: &api.ChangesPayload{
Body: &api.ChangesFromPayload{
Changes: &apiv1types.WebhookChangesPayload{
Body: &apiv1types.WebhookChangesFromPayload{
From: oldContent,
},
},
@@ -620,29 +619,29 @@ func (issue *Issue) ChangeAssignee(doer *User, assigneeID int64) (err error) {
isRemoveAssignee := err != nil
if issue.IsPull {
issue.PullRequest.Issue = issue
apiPullRequest := &api.PullRequestPayload{
apiPullRequest := &apiv1types.WebhookPullRequestPayload{
Index: issue.Index,
PullRequest: issue.PullRequest.APIFormat(),
Repository: issue.Repo.APIFormatLegacy(nil),
Sender: doer.APIFormat(),
}
if isRemoveAssignee {
apiPullRequest.Action = api.HOOK_ISSUE_UNASSIGNED
apiPullRequest.Action = apiv1types.WebhookIssueUnassigned
} else {
apiPullRequest.Action = api.HOOK_ISSUE_ASSIGNED
apiPullRequest.Action = apiv1types.WebhookIssueAssigned
}
err = PrepareWebhooks(issue.Repo, HookEventTypePullRequest, apiPullRequest)
} else {
apiIssues := &api.IssuesPayload{
apiIssues := &apiv1types.WebhookIssuesPayload{
Index: issue.Index,
Issue: issue.APIFormat(),
Repository: issue.Repo.APIFormatLegacy(nil),
Sender: doer.APIFormat(),
}
if isRemoveAssignee {
apiIssues.Action = api.HOOK_ISSUE_UNASSIGNED
apiIssues.Action = apiv1types.WebhookIssueUnassigned
} else {
apiIssues.Action = api.HOOK_ISSUE_ASSIGNED
apiIssues.Action = apiv1types.WebhookIssueAssigned
}
err = PrepareWebhooks(issue.Repo, HookEventTypeIssues, apiIssues)
}
@@ -789,8 +788,8 @@ func NewIssue(repo *Repository, issue *Issue, labelIDs []int64, uuids []string)
log.Error("MailParticipants: %v", err)
}
if err = PrepareWebhooks(repo, HookEventTypeIssues, &api.IssuesPayload{
Action: api.HOOK_ISSUE_OPENED,
if err = PrepareWebhooks(repo, HookEventTypeIssues, &apiv1types.WebhookIssuesPayload{
Action: apiv1types.WebhookIssueOpened,
Index: issue.Index,
Issue: issue.APIFormat(),
Repository: repo.APIFormatLegacy(nil),

View File

@@ -9,10 +9,10 @@ import (
"xorm.io/xorm"
"github.com/cockroachdb/errors"
api "github.com/gogs/go-gogs-client"
"gogs.io/gogs/internal/errutil"
"gogs.io/gogs/internal/lazyregexp"
apiv1types "gogs.io/gogs/internal/route/api/v1/types"
"gogs.io/gogs/internal/tool"
)
@@ -62,8 +62,8 @@ type Label struct {
IsChecked bool `xorm:"-" json:"-" gorm:"-"`
}
func (l *Label) APIFormat() *api.Label {
return &api.Label{
func (l *Label) APIFormat() *apiv1types.IssueLabel {
return &apiv1types.IssueLabel{
ID: l.ID,
Name: l.Name,
Color: strings.TrimLeft(l.Color, "#"),

View File

@@ -8,10 +8,10 @@ import (
"xorm.io/xorm"
"github.com/cockroachdb/errors"
api "github.com/gogs/go-gogs-client"
"gogs.io/gogs/internal/conf"
"gogs.io/gogs/internal/errutil"
apiv1types "gogs.io/gogs/internal/route/api/v1/types"
)
// Milestone represents a milestone of repository.
@@ -72,19 +72,19 @@ func (m *Milestone) AfterSet(colName string, _ xorm.Cell) {
}
// State returns string representation of milestone status.
func (m *Milestone) State() api.StateType {
func (m *Milestone) State() apiv1types.IssueStateType {
if m.IsClosed {
return api.STATE_CLOSED
return apiv1types.IssueStateClosed
}
return api.STATE_OPEN
return apiv1types.IssueStateOpen
}
func (m *Milestone) ChangeStatus(isClosed bool) error {
return ChangeMilestoneStatus(m, isClosed)
}
func (m *Milestone) APIFormat() *api.Milestone {
apiMilestone := &api.Milestone{
func (m *Milestone) APIFormat() *apiv1types.IssueMilestone {
apiMilestone := &apiv1types.IssueMilestone{
ID: m.ID,
State: m.State(),
Title: m.Name,
@@ -343,11 +343,11 @@ func ChangeMilestoneAssign(doer *User, issue *Issue, oldMilestoneID int64) (err
return errors.Newf("commit: %v", err)
}
var hookAction api.HookIssueAction
var hookAction apiv1types.WebhookIssueAction
if issue.MilestoneID > 0 {
hookAction = api.HOOK_ISSUE_MILESTONED
hookAction = apiv1types.WebhookIssueMilestoned
} else {
hookAction = api.HOOK_ISSUE_DEMILESTONED
hookAction = apiv1types.WebhookIssueDemilestoned
}
if issue.IsPull {
@@ -356,7 +356,7 @@ func ChangeMilestoneAssign(doer *User, issue *Issue, oldMilestoneID int64) (err
log.Error("LoadIssue: %v", err)
return err
}
err = PrepareWebhooks(issue.Repo, HookEventTypePullRequest, &api.PullRequestPayload{
err = PrepareWebhooks(issue.Repo, HookEventTypePullRequest, &apiv1types.WebhookPullRequestPayload{
Action: hookAction,
Index: issue.Index,
PullRequest: issue.PullRequest.APIFormat(),
@@ -364,7 +364,7 @@ func ChangeMilestoneAssign(doer *User, issue *Issue, oldMilestoneID int64) (err
Sender: doer.APIFormat(),
})
} else {
err = PrepareWebhooks(issue.Repo, HookEventTypeIssues, &api.IssuesPayload{
err = PrepareWebhooks(issue.Repo, HookEventTypeIssues, &apiv1types.WebhookIssuesPayload{
Action: hookAction,
Index: issue.Index,
Issue: issue.APIFormat(),

View File

@@ -13,12 +13,12 @@ import (
"xorm.io/xorm"
"github.com/gogs/git-module"
api "github.com/gogs/go-gogs-client"
"gogs.io/gogs/internal/conf"
"gogs.io/gogs/internal/errutil"
"gogs.io/gogs/internal/osutil"
"gogs.io/gogs/internal/process"
apiv1types "gogs.io/gogs/internal/route/api/v1/types"
"gogs.io/gogs/internal/sync"
)
@@ -127,11 +127,11 @@ func (pr *PullRequest) LoadIssue() (err error) {
// This method assumes following fields have been assigned with valid values:
// Required - Issue, BaseRepo
// Optional - HeadRepo, Merger
func (pr *PullRequest) APIFormat() *api.PullRequest {
func (pr *PullRequest) APIFormat() *apiv1types.PullRequest {
// In case of head repo has been deleted.
var apiHeadRepo *api.Repository
var apiHeadRepo *apiv1types.Repository
if pr.HeadRepo == nil {
apiHeadRepo = &api.Repository{
apiHeadRepo = &apiv1types.Repository{
Name: "deleted",
}
} else {
@@ -139,7 +139,7 @@ func (pr *PullRequest) APIFormat() *api.PullRequest {
}
apiIssue := pr.Issue.APIFormat()
apiPullRequest := &api.PullRequest{
apiPullRequest := &apiv1types.PullRequest{
ID: pr.ID,
Index: pr.Index,
Poster: apiIssue.Poster,
@@ -341,8 +341,8 @@ func (pr *PullRequest) Merge(doer *User, baseGitRepo *git.Repository, mergeStyle
log.Error("LoadAttributes: %v", err)
return nil
}
if err = PrepareWebhooks(pr.Issue.Repo, HookEventTypePullRequest, &api.PullRequestPayload{
Action: api.HOOK_ISSUE_CLOSED,
if err = PrepareWebhooks(pr.Issue.Repo, HookEventTypePullRequest, &apiv1types.WebhookPullRequestPayload{
Action: apiv1types.WebhookIssueClosed,
Index: pr.Index,
PullRequest: pr.APIFormat(),
Repository: pr.Issue.Repo.APIFormatLegacy(nil),
@@ -376,7 +376,7 @@ func (pr *PullRequest) Merge(doer *User, baseGitRepo *git.Repository, mergeStyle
return nil
}
p := &api.PushPayload{
p := &apiv1types.WebhookPushPayload{
Ref: git.RefsHeads + pr.BaseBranch,
Before: pr.MergeBase,
After: mergeCommit.ID.String(),
@@ -500,8 +500,8 @@ func NewPullRequest(repo *Repository, pull *Issue, labelIDs []int64, uuids []str
pr.Issue = pull
pull.PullRequest = pr
if err = PrepareWebhooks(repo, HookEventTypePullRequest, &api.PullRequestPayload{
Action: api.HOOK_ISSUE_OPENED,
if err = PrepareWebhooks(repo, HookEventTypePullRequest, &apiv1types.WebhookPullRequestPayload{
Action: apiv1types.WebhookIssueOpened,
Index: pull.Index,
PullRequest: pr.APIFormat(),
Repository: repo.APIFormatLegacy(nil),
@@ -792,8 +792,8 @@ func AddTestPullRequestTask(doer *User, repoID int64, branch string, isSync bool
log.Error("LoadAttributes: %v", err)
continue
}
if err = PrepareWebhooks(pr.Issue.Repo, HookEventTypePullRequest, &api.PullRequestPayload{
Action: api.HOOK_ISSUE_SYNCHRONIZED,
if err = PrepareWebhooks(pr.Issue.Repo, HookEventTypePullRequest, &apiv1types.WebhookPullRequestPayload{
Action: apiv1types.WebhookIssueSynchronized,
Index: pr.Issue.Index,
PullRequest: pr.Issue.PullRequest.APIFormat(),
Repository: pr.Issue.Repo.APIFormatLegacy(nil),

View File

@@ -11,10 +11,10 @@ import (
"github.com/cockroachdb/errors"
"github.com/gogs/git-module"
api "github.com/gogs/go-gogs-client"
"gogs.io/gogs/internal/errutil"
"gogs.io/gogs/internal/process"
apiv1types "gogs.io/gogs/internal/route/api/v1/types"
)
// Release represents a release of repository.
@@ -90,8 +90,8 @@ func (r *Release) LoadAttributes() error {
// This method assumes some fields assigned with values:
// Required - Publisher
func (r *Release) APIFormat() *api.Release {
return &api.Release{
func (r *Release) APIFormat() *apiv1types.RepositoryRelease {
return &apiv1types.RepositoryRelease{
ID: r.ID,
TagName: r.TagName,
TargetCommitish: r.Target,
@@ -147,8 +147,8 @@ func createTag(gitRepo *git.Repository, r *Release) error {
}
func (r *Release) preparePublishWebhooks() {
if err := PrepareWebhooks(r.Repo, HookEventTypeRelease, &api.ReleasePayload{
Action: api.HOOK_RELEASE_PUBLISHED,
if err := PrepareWebhooks(r.Repo, HookEventTypeRelease, &apiv1types.WebhookReleasePayload{
Action: apiv1types.WebhookReleasePublished,
Release: r.APIFormat(),
Repository: r.Repo.APIFormatLegacy(nil),
Sender: r.Publisher.APIFormat(),

View File

@@ -26,7 +26,6 @@ import (
"xorm.io/xorm"
"github.com/gogs/git-module"
api "github.com/gogs/go-gogs-client"
embedConf "gogs.io/gogs/conf"
"gogs.io/gogs/internal/avatar"
@@ -37,6 +36,7 @@ import (
"gogs.io/gogs/internal/osutil"
"gogs.io/gogs/internal/process"
"gogs.io/gogs/internal/repoutil"
apiv1types "gogs.io/gogs/internal/route/api/v1/types"
"gogs.io/gogs/internal/semverutil"
"gogs.io/gogs/internal/strutil"
"gogs.io/gogs/internal/sync"
@@ -377,9 +377,9 @@ func (r *Repository) DeleteAvatar() error {
// Arguments that are allowed to be nil: permission
//
// Deprecated: Use APIFormat instead.
func (r *Repository) APIFormatLegacy(permission *api.Permission, user ...*User) *api.Repository {
func (r *Repository) APIFormatLegacy(permission *apiv1types.RepositoryPermission, user ...*User) *apiv1types.Repository {
cloneLink := r.CloneLink()
apiRepo := &api.Repository{
apiRepo := &apiv1types.Repository{
ID: r.ID,
Owner: r.Owner.APIFormat(),
Name: r.Name,
@@ -406,7 +406,7 @@ func (r *Repository) APIFormatLegacy(permission *api.Permission, user ...*User)
// AvatarUrl: r.AvatarLink(),
}
if r.IsFork {
p := &api.Permission{Pull: true}
p := &apiv1types.RepositoryPermission{Pull: true}
if len(user) != 0 {
accessMode := Handle.Permissions().AccessMode(
context.TODO(),
@@ -2609,7 +2609,7 @@ func ForkRepository(doer, owner *User, baseRepo *Repository, name, desc string)
if err = repo.UpdateSize(); err != nil {
log.Error("UpdateSize [repo_id: %d]: %v", repo.ID, err)
}
if err = PrepareWebhooks(baseRepo, HookEventTypeFork, &api.ForkPayload{
if err = PrepareWebhooks(baseRepo, HookEventTypeFork, &apiv1types.WebhookForkPayload{
Forkee: repo.APIFormatLegacy(nil),
Repo: baseRepo.APIFormatLegacy(nil),
Sender: doer.APIFormat(),

View File

@@ -1,10 +1,10 @@
package database
import (
"github.com/cockroachdb/errors"
log "unknwon.dev/clog/v2"
"github.com/cockroachdb/errors"
api "github.com/gogs/go-gogs-client"
apiv1types "gogs.io/gogs/internal/route/api/v1/types"
)
// Collaboration represent the relation between an individual and a repository.
@@ -87,10 +87,10 @@ type Collaborator struct {
Collaboration *Collaboration
}
func (c *Collaborator) APIFormat() *api.Collaborator {
return &api.Collaborator{
func (c *Collaborator) APIFormat() *apiv1types.RepositoryCollaborator {
return &apiv1types.RepositoryCollaborator{
User: c.User.APIFormat(),
Permissions: api.Permission{
Permissions: apiv1types.RepositoryPermission{
Admin: c.Collaboration.Mode >= AccessModeAdmin,
Push: c.Collaboration.Mode >= AccessModeWrite,
Pull: c.Collaboration.Mode >= AccessModeRead,

View File

@@ -7,11 +7,11 @@ import (
"time"
"github.com/cockroachdb/errors"
api "github.com/gogs/go-gogs-client"
"gorm.io/gorm"
"gogs.io/gogs/internal/errutil"
"gogs.io/gogs/internal/repoutil"
apiv1types "gogs.io/gogs/internal/route/api/v1/types"
)
// BeforeCreate implements the GORM create hook.
@@ -36,19 +36,19 @@ func (r *Repository) AfterFind(_ *gorm.DB) error {
}
type RepositoryAPIFormatOptions struct {
Permission *api.Permission
Parent *api.Repository
Permission *apiv1types.RepositoryPermission
Parent *apiv1types.Repository
}
// APIFormat returns the API format of a repository.
func (r *Repository) APIFormat(owner *User, opts ...RepositoryAPIFormatOptions) *api.Repository {
func (r *Repository) APIFormat(owner *User, opts ...RepositoryAPIFormatOptions) *apiv1types.Repository {
var opt RepositoryAPIFormatOptions
if len(opts) > 0 {
opt = opts[0]
}
cloneLink := repoutil.NewCloneLink(owner.Name, r.Name, false)
return &api.Repository{
return &apiv1types.Repository{
ID: r.ID,
Owner: owner.APIFormat(),
Name: r.Name,

View File

@@ -11,7 +11,6 @@ import (
"github.com/cockroachdb/errors"
"github.com/go-macaron/binding"
api "github.com/gogs/go-gogs-client"
"gorm.io/gorm"
log "unknwon.dev/clog/v2"
@@ -23,6 +22,7 @@ import (
"gogs.io/gogs/internal/markup"
"gogs.io/gogs/internal/osutil"
"gogs.io/gogs/internal/repoutil"
apiv1types "gogs.io/gogs/internal/route/api/v1/types"
"gogs.io/gogs/internal/strutil"
"gogs.io/gogs/internal/tool"
"gogs.io/gogs/internal/userutil"
@@ -1297,14 +1297,14 @@ func (u *User) IsOrganization() bool {
}
// APIFormat returns the API format of a user.
func (u *User) APIFormat() *api.User {
return &api.User{
func (u *User) APIFormat() *apiv1types.User {
return &apiv1types.User{
ID: u.ID,
UserName: u.Name,
Login: u.Name,
FullName: u.FullName,
Email: u.Email,
AvatarUrl: u.AvatarURL(),
AvatarURL: u.AvatarURL(),
}
}

View File

@@ -17,12 +17,11 @@ import (
log "unknwon.dev/clog/v2"
"xorm.io/xorm"
api "github.com/gogs/go-gogs-client"
"gogs.io/gogs/internal/conf"
"gogs.io/gogs/internal/errutil"
"gogs.io/gogs/internal/httplib"
"gogs.io/gogs/internal/netutil"
apiv1types "gogs.io/gogs/internal/route/api/v1/types"
"gogs.io/gogs/internal/sync"
"gogs.io/gogs/internal/testutil"
)
@@ -430,21 +429,21 @@ type HookResponse struct {
// HookTask represents a hook task.
type HookTask struct {
ID int64
RepoID int64 `xorm:"INDEX"`
HookID int64
UUID string
Type HookTaskType
URL string `xorm:"TEXT"`
Signature string `xorm:"TEXT"`
api.Payloader `xorm:"-" json:"-" gorm:"-"`
PayloadContent string `xorm:"TEXT"`
ContentType HookContentType
EventType HookEventType
IsSSL bool
IsDelivered bool
Delivered int64
DeliveredString string `xorm:"-" json:"-" gorm:"-"`
ID int64
RepoID int64 `xorm:"INDEX"`
HookID int64
UUID string
Type HookTaskType
URL string `xorm:"TEXT"`
Signature string `xorm:"TEXT"`
apiv1types.WebhookPayloader `xorm:"-" json:"-" gorm:"-"`
PayloadContent string `xorm:"TEXT"`
ContentType HookContentType
EventType HookEventType
IsSSL bool
IsDelivered bool
Delivered int64
DeliveredString string `xorm:"-" json:"-" gorm:"-"`
// History info.
IsSucceed bool
@@ -559,12 +558,12 @@ func UpdateHookTask(t *HookTask) error {
}
// prepareHookTasks adds list of webhooks to task queue.
func prepareHookTasks(e Engine, repo *Repository, event HookEventType, p api.Payloader, webhooks []*Webhook) (err error) {
func prepareHookTasks(e Engine, repo *Repository, event HookEventType, p apiv1types.WebhookPayloader, webhooks []*Webhook) (err error) {
if len(webhooks) == 0 {
return nil
}
var payloader api.Payloader
var payloader apiv1types.WebhookPayloader
for _, w := range webhooks {
switch event {
case HookEventTypeCreate:
@@ -634,15 +633,15 @@ func prepareHookTasks(e Engine, repo *Repository, event HookEventType, p api.Pay
}
if err = createHookTask(e, &HookTask{
RepoID: repo.ID,
HookID: w.ID,
Type: w.HookTaskType,
URL: w.URL,
Signature: signature,
Payloader: payloader,
ContentType: w.ContentType,
EventType: event,
IsSSL: w.IsSSL,
RepoID: repo.ID,
HookID: w.ID,
Type: w.HookTaskType,
URL: w.URL,
Signature: signature,
WebhookPayloader: payloader,
ContentType: w.ContentType,
EventType: event,
IsSSL: w.IsSSL,
}); err != nil {
return errors.Newf("createHookTask: %v", err)
}
@@ -655,7 +654,7 @@ func prepareHookTasks(e Engine, repo *Repository, event HookEventType, p api.Pay
return nil
}
func prepareWebhooks(e Engine, repo *Repository, event HookEventType, p api.Payloader) error {
func prepareWebhooks(e Engine, repo *Repository, event HookEventType, p apiv1types.WebhookPayloader) error {
webhooks, err := getActiveWebhooksByRepoID(e, repo.ID)
if err != nil {
return errors.Newf("getActiveWebhooksByRepoID [%d]: %v", repo.ID, err)
@@ -674,7 +673,7 @@ func prepareWebhooks(e Engine, repo *Repository, event HookEventType, p api.Payl
}
// PrepareWebhooks adds all active webhooks to task queue.
func PrepareWebhooks(repo *Repository, event HookEventType, p api.Payloader) error {
func PrepareWebhooks(repo *Repository, event HookEventType, p apiv1types.WebhookPayloader) error {
// NOTE: To prevent too many cascading changes in a single refactoring PR, we
// choose to ignore this function in tests.
if x == nil && testutil.InTest {
@@ -684,7 +683,7 @@ func PrepareWebhooks(repo *Repository, event HookEventType, p api.Payloader) err
}
// TestWebhook adds the test webhook matches the ID to task queue.
func TestWebhook(repo *Repository, event HookEventType, p api.Payloader, webhookID int64) error {
func TestWebhook(repo *Repository, event HookEventType, p apiv1types.WebhookPayloader, webhookID int64) error {
webhook, err := GetWebhookOfRepoByID(repo.ID, webhookID)
if err != nil {
return errors.Newf("GetWebhookOfRepoByID [repo_id: %d, id: %d]: %v", repo.ID, webhookID, err)

View File

@@ -6,9 +6,9 @@ import (
"strings"
"github.com/cockroachdb/errors"
"github.com/gogs/git-module"
api "github.com/gogs/go-gogs-client"
apiv1types "gogs.io/gogs/internal/route/api/v1/types"
)
const (
@@ -55,31 +55,31 @@ func NewDingtalkActionCard(singleTitle, singleURL string) DingtalkActionCard {
}
// TODO: add content
func GetDingtalkPayload(p api.Payloader, event HookEventType) (payload *DingtalkPayload, err error) {
func GetDingtalkPayload(p apiv1types.WebhookPayloader, event HookEventType) (payload *DingtalkPayload, err error) {
switch event {
case HookEventTypeCreate:
payload = getDingtalkCreatePayload(p.(*api.CreatePayload))
payload = getDingtalkCreatePayload(p.(*apiv1types.WebhookCreatePayload))
case HookEventTypeDelete:
payload = getDingtalkDeletePayload(p.(*api.DeletePayload))
payload = getDingtalkDeletePayload(p.(*apiv1types.WebhookDeletePayload))
case HookEventTypeFork:
payload = getDingtalkForkPayload(p.(*api.ForkPayload))
payload = getDingtalkForkPayload(p.(*apiv1types.WebhookForkPayload))
case HookEventTypePush:
payload = getDingtalkPushPayload(p.(*api.PushPayload))
payload = getDingtalkPushPayload(p.(*apiv1types.WebhookPushPayload))
case HookEventTypeIssues:
payload = getDingtalkIssuesPayload(p.(*api.IssuesPayload))
payload = getDingtalkIssuesPayload(p.(*apiv1types.WebhookIssuesPayload))
case HookEventTypeIssueComment:
payload = getDingtalkIssueCommentPayload(p.(*api.IssueCommentPayload))
payload = getDingtalkIssueCommentPayload(p.(*apiv1types.WebhookIssueCommentPayload))
case HookEventTypePullRequest:
payload = getDingtalkPullRequestPayload(p.(*api.PullRequestPayload))
payload = getDingtalkPullRequestPayload(p.(*apiv1types.WebhookPullRequestPayload))
case HookEventTypeRelease:
payload = getDingtalkReleasePayload(p.(*api.ReleasePayload))
payload = getDingtalkReleasePayload(p.(*apiv1types.WebhookReleasePayload))
default:
return nil, errors.Errorf("unexpected event %q", event)
}
return payload, nil
}
func getDingtalkCreatePayload(p *api.CreatePayload) *DingtalkPayload {
func getDingtalkCreatePayload(p *apiv1types.WebhookCreatePayload) *DingtalkPayload {
refName := git.RefShortName(p.Ref)
refType := strings.Title(p.RefType)
@@ -94,7 +94,7 @@ func getDingtalkCreatePayload(p *api.CreatePayload) *DingtalkPayload {
}
}
func getDingtalkDeletePayload(p *api.DeletePayload) *DingtalkPayload {
func getDingtalkDeletePayload(p *apiv1types.WebhookDeletePayload) *DingtalkPayload {
refName := git.RefShortName(p.Ref)
refType := strings.Title(p.RefType)
@@ -109,7 +109,7 @@ func getDingtalkDeletePayload(p *api.DeletePayload) *DingtalkPayload {
}
}
func getDingtalkForkPayload(p *api.ForkPayload) *DingtalkPayload {
func getDingtalkForkPayload(p *apiv1types.WebhookForkPayload) *DingtalkPayload {
actionCard := NewDingtalkActionCard("View Fork", p.Forkee.HTMLURL)
actionCard.Text += "# Repo Fork Event"
actionCard.Text += "\n- From Repo: **" + MarkdownLinkFormatter(p.Repo.HTMLURL, p.Repo.Name) + "**"
@@ -121,7 +121,7 @@ func getDingtalkForkPayload(p *api.ForkPayload) *DingtalkPayload {
}
}
func getDingtalkPushPayload(p *api.PushPayload) *DingtalkPayload {
func getDingtalkPushPayload(p *apiv1types.WebhookPushPayload) *DingtalkPayload {
refName := git.RefShortName(p.Ref)
pusher := p.Pusher.FullName
@@ -150,7 +150,7 @@ func getDingtalkPushPayload(p *api.PushPayload) *DingtalkPayload {
}
}
func getDingtalkIssuesPayload(p *api.IssuesPayload) *DingtalkPayload {
func getDingtalkIssuesPayload(p *apiv1types.WebhookIssuesPayload) *DingtalkPayload {
issueName := fmt.Sprintf("#%d %s", p.Index, p.Issue.Title)
issueURL := fmt.Sprintf("%s/issues/%d", p.Repository.HTMLURL, p.Index)
@@ -159,11 +159,11 @@ func getDingtalkIssuesPayload(p *api.IssuesPayload) *DingtalkPayload {
actionCard.Text += "\n- Issue: **" + MarkdownLinkFormatter(issueURL, issueName) + "**"
switch p.Action {
case api.HOOK_ISSUE_ASSIGNED:
case apiv1types.WebhookIssueAssigned:
actionCard.Text += "\n- New Assignee: **" + p.Issue.Assignee.UserName + "**"
case api.HOOK_ISSUE_MILESTONED:
case apiv1types.WebhookIssueMilestoned:
actionCard.Text += "\n- New Milestone: **" + p.Issue.Milestone.Title + "**"
case api.HOOK_ISSUE_LABEL_UPDATED:
case apiv1types.WebhookIssueLabelUpdated:
if len(p.Issue.Labels) > 0 {
labels := make([]string, len(p.Issue.Labels))
for i, label := range p.Issue.Labels {
@@ -185,10 +185,10 @@ func getDingtalkIssuesPayload(p *api.IssuesPayload) *DingtalkPayload {
}
}
func getDingtalkIssueCommentPayload(p *api.IssueCommentPayload) *DingtalkPayload {
func getDingtalkIssueCommentPayload(p *apiv1types.WebhookIssueCommentPayload) *DingtalkPayload {
issueName := fmt.Sprintf("#%d %s", p.Issue.Index, p.Issue.Title)
commentURL := fmt.Sprintf("%s/issues/%d", p.Repository.HTMLURL, p.Issue.Index)
if p.Action != api.HOOK_ISSUE_COMMENT_DELETED {
if p.Action != apiv1types.WebhookIssueCommentDeleted {
commentURL += "#" + CommentHashTag(p.Comment.ID)
}
@@ -206,9 +206,9 @@ func getDingtalkIssueCommentPayload(p *api.IssueCommentPayload) *DingtalkPayload
}
}
func getDingtalkPullRequestPayload(p *api.PullRequestPayload) *DingtalkPayload {
func getDingtalkPullRequestPayload(p *apiv1types.WebhookPullRequestPayload) *DingtalkPayload {
title := "# Pull Request " + strings.Title(string(p.Action))
if p.Action == api.HOOK_ISSUE_CLOSED && p.PullRequest.HasMerged {
if p.Action == apiv1types.WebhookIssueClosed && p.PullRequest.HasMerged {
title = "# Pull Request Merged"
}
@@ -216,11 +216,11 @@ func getDingtalkPullRequestPayload(p *api.PullRequestPayload) *DingtalkPayload {
content := "- PR: " + MarkdownLinkFormatter(pullRequestURL, fmt.Sprintf("#%d %s", p.Index, p.PullRequest.Title))
switch p.Action {
case api.HOOK_ISSUE_ASSIGNED:
case apiv1types.WebhookIssueAssigned:
content += "\n- New Assignee: **" + p.PullRequest.Assignee.UserName + "**"
case api.HOOK_ISSUE_MILESTONED:
case apiv1types.WebhookIssueMilestoned:
content += "\n- New Milestone: *" + p.PullRequest.Milestone.Title + "*"
case api.HOOK_ISSUE_LABEL_UPDATED:
case apiv1types.WebhookIssueLabelUpdated:
labels := make([]string, len(p.PullRequest.Labels))
for i, label := range p.PullRequest.Labels {
labels[i] = "**" + label.Name + "**"
@@ -231,7 +231,7 @@ func getDingtalkPullRequestPayload(p *api.PullRequestPayload) *DingtalkPayload {
actionCard := NewDingtalkActionCard("View Pull Request", pullRequestURL)
actionCard.Text += title + "\n" + content
if p.Action == api.HOOK_ISSUE_OPENED || p.Action == api.HOOK_ISSUE_EDITED {
if p.Action == apiv1types.WebhookIssueOpened || p.Action == apiv1types.WebhookIssueEdited {
actionCard.Text += "\n> " + p.PullRequest.Body
}
@@ -241,7 +241,7 @@ func getDingtalkPullRequestPayload(p *api.PullRequestPayload) *DingtalkPayload {
}
}
func getDingtalkReleasePayload(p *api.ReleasePayload) *DingtalkPayload {
func getDingtalkReleasePayload(p *apiv1types.WebhookReleasePayload) *DingtalkPayload {
releaseURL := p.Repository.HTMLURL + "/src/" + p.Release.TagName
author := p.Release.Author.FullName

View File

@@ -7,11 +7,10 @@ import (
"strings"
"github.com/cockroachdb/errors"
"github.com/gogs/git-module"
api "github.com/gogs/go-gogs-client"
"gogs.io/gogs/internal/conf"
apiv1types "gogs.io/gogs/internal/route/api/v1/types"
)
type DiscordEmbedFooterObject struct {
@@ -67,7 +66,7 @@ func DiscordSHALinkFormatter(url, text string) string {
}
// getDiscordCreatePayload composes Discord payload for create new branch or tag.
func getDiscordCreatePayload(p *api.CreatePayload) *DiscordPayload {
func getDiscordCreatePayload(p *apiv1types.WebhookCreatePayload) *DiscordPayload {
refName := git.RefShortName(p.Ref)
repoLink := DiscordLinkFormatter(p.Repo.HTMLURL, p.Repo.Name)
refLink := DiscordLinkFormatter(p.Repo.HTMLURL+"/src/"+refName, refName)
@@ -78,14 +77,14 @@ func getDiscordCreatePayload(p *api.CreatePayload) *DiscordPayload {
URL: conf.Server.ExternalURL + p.Sender.UserName,
Author: &DiscordEmbedAuthorObject{
Name: p.Sender.UserName,
IconURL: p.Sender.AvatarUrl,
IconURL: p.Sender.AvatarURL,
},
}},
}
}
// getDiscordDeletePayload composes Discord payload for delete a branch or tag.
func getDiscordDeletePayload(p *api.DeletePayload) *DiscordPayload {
func getDiscordDeletePayload(p *apiv1types.WebhookDeletePayload) *DiscordPayload {
refName := git.RefShortName(p.Ref)
repoLink := DiscordLinkFormatter(p.Repo.HTMLURL, p.Repo.Name)
content := fmt.Sprintf("Deleted %s: %s/%s", p.RefType, repoLink, refName)
@@ -95,14 +94,14 @@ func getDiscordDeletePayload(p *api.DeletePayload) *DiscordPayload {
URL: conf.Server.ExternalURL + p.Sender.UserName,
Author: &DiscordEmbedAuthorObject{
Name: p.Sender.UserName,
IconURL: p.Sender.AvatarUrl,
IconURL: p.Sender.AvatarURL,
},
}},
}
}
// getDiscordForkPayload composes Discord payload for forked by a repository.
func getDiscordForkPayload(p *api.ForkPayload) *DiscordPayload {
func getDiscordForkPayload(p *apiv1types.WebhookForkPayload) *DiscordPayload {
baseLink := DiscordLinkFormatter(p.Repo.HTMLURL, p.Repo.Name)
forkLink := DiscordLinkFormatter(p.Forkee.HTMLURL, p.Forkee.FullName)
content := fmt.Sprintf("%s is forked to %s", baseLink, forkLink)
@@ -112,13 +111,13 @@ func getDiscordForkPayload(p *api.ForkPayload) *DiscordPayload {
URL: conf.Server.ExternalURL + p.Sender.UserName,
Author: &DiscordEmbedAuthorObject{
Name: p.Sender.UserName,
IconURL: p.Sender.AvatarUrl,
IconURL: p.Sender.AvatarURL,
},
}},
}
}
func getDiscordPushPayload(p *api.PushPayload, slack *SlackMeta) *DiscordPayload {
func getDiscordPushPayload(p *apiv1types.WebhookPushPayload, slack *SlackMeta) *DiscordPayload {
// n new commits
var (
branchName = git.RefShortName(p.Ref)
@@ -162,37 +161,37 @@ func getDiscordPushPayload(p *api.PushPayload, slack *SlackMeta) *DiscordPayload
Color: int(color),
Author: &DiscordEmbedAuthorObject{
Name: p.Sender.UserName,
IconURL: p.Sender.AvatarUrl,
IconURL: p.Sender.AvatarURL,
},
}},
}
}
func getDiscordIssuesPayload(p *api.IssuesPayload, slack *SlackMeta) *DiscordPayload {
func getDiscordIssuesPayload(p *apiv1types.WebhookIssuesPayload, slack *SlackMeta) *DiscordPayload {
title := fmt.Sprintf("#%d %s", p.Index, p.Issue.Title)
url := fmt.Sprintf("%s/issues/%d", p.Repository.HTMLURL, p.Index)
content := ""
fields := make([]*DiscordEmbedFieldObject, 0, 1)
switch p.Action {
case api.HOOK_ISSUE_OPENED:
case apiv1types.WebhookIssueOpened:
title = "New issue: " + title
content = p.Issue.Body
case api.HOOK_ISSUE_CLOSED:
case apiv1types.WebhookIssueClosed:
title = "Issue closed: " + title
case api.HOOK_ISSUE_REOPENED:
case apiv1types.WebhookIssueReopened:
title = "Issue re-opened: " + title
case api.HOOK_ISSUE_EDITED:
case apiv1types.WebhookIssueEdited:
title = "Issue edited: " + title
content = p.Issue.Body
case api.HOOK_ISSUE_ASSIGNED:
case apiv1types.WebhookIssueAssigned:
title = "Issue assigned: " + title
fields = []*DiscordEmbedFieldObject{{
Name: "New Assignee",
Value: p.Issue.Assignee.UserName,
}}
case api.HOOK_ISSUE_UNASSIGNED:
case apiv1types.WebhookIssueUnassigned:
title = "Issue unassigned: " + title
case api.HOOK_ISSUE_LABEL_UPDATED:
case apiv1types.WebhookIssueLabelUpdated:
title = "Issue labels updated: " + title
labels := make([]string, len(p.Issue.Labels))
for i := range p.Issue.Labels {
@@ -205,17 +204,17 @@ func getDiscordIssuesPayload(p *api.IssuesPayload, slack *SlackMeta) *DiscordPay
Name: "Labels",
Value: strings.Join(labels, ", "),
}}
case api.HOOK_ISSUE_LABEL_CLEARED:
case apiv1types.WebhookIssueLabelCleared:
title = "Issue labels cleared: " + title
case api.HOOK_ISSUE_SYNCHRONIZED:
case apiv1types.WebhookIssueSynchronized:
title = "Issue synchronized: " + title
case api.HOOK_ISSUE_MILESTONED:
case apiv1types.WebhookIssueMilestoned:
title = "Issue milestoned: " + title
fields = []*DiscordEmbedFieldObject{{
Name: "New Milestone",
Value: p.Issue.Milestone.Title,
}}
case api.HOOK_ISSUE_DEMILESTONED:
case apiv1types.WebhookIssueDemilestoned:
title = "Issue demilestoned: " + title
}
@@ -233,26 +232,26 @@ func getDiscordIssuesPayload(p *api.IssuesPayload, slack *SlackMeta) *DiscordPay
},
Author: &DiscordEmbedAuthorObject{
Name: p.Sender.UserName,
IconURL: p.Sender.AvatarUrl,
IconURL: p.Sender.AvatarURL,
},
Fields: fields,
}},
}
}
func getDiscordIssueCommentPayload(p *api.IssueCommentPayload, slack *SlackMeta) *DiscordPayload {
func getDiscordIssueCommentPayload(p *apiv1types.WebhookIssueCommentPayload, slack *SlackMeta) *DiscordPayload {
title := fmt.Sprintf("#%d %s", p.Issue.Index, p.Issue.Title)
url := fmt.Sprintf("%s/issues/%d#%s", p.Repository.HTMLURL, p.Issue.Index, CommentHashTag(p.Comment.ID))
content := ""
fields := make([]*DiscordEmbedFieldObject, 0, 1)
switch p.Action {
case api.HOOK_ISSUE_COMMENT_CREATED:
case apiv1types.WebhookIssueCommentCreated:
title = "New comment: " + title
content = p.Comment.Body
case api.HOOK_ISSUE_COMMENT_EDITED:
case apiv1types.WebhookIssueCommentEdited:
title = "Comment edited: " + title
content = p.Comment.Body
case api.HOOK_ISSUE_COMMENT_DELETED:
case apiv1types.WebhookIssueCommentDeleted:
title = "Comment deleted: " + title
url = fmt.Sprintf("%s/issues/%d", p.Repository.HTMLURL, p.Issue.Index)
content = p.Comment.Body
@@ -272,42 +271,42 @@ func getDiscordIssueCommentPayload(p *api.IssueCommentPayload, slack *SlackMeta)
},
Author: &DiscordEmbedAuthorObject{
Name: p.Sender.UserName,
IconURL: p.Sender.AvatarUrl,
IconURL: p.Sender.AvatarURL,
},
Fields: fields,
}},
}
}
func getDiscordPullRequestPayload(p *api.PullRequestPayload, slack *SlackMeta) *DiscordPayload {
func getDiscordPullRequestPayload(p *apiv1types.WebhookPullRequestPayload, slack *SlackMeta) *DiscordPayload {
title := fmt.Sprintf("#%d %s", p.Index, p.PullRequest.Title)
url := fmt.Sprintf("%s/pulls/%d", p.Repository.HTMLURL, p.Index)
content := ""
fields := make([]*DiscordEmbedFieldObject, 0, 1)
switch p.Action {
case api.HOOK_ISSUE_OPENED:
case apiv1types.WebhookIssueOpened:
title = "New pull request: " + title
content = p.PullRequest.Body
case api.HOOK_ISSUE_CLOSED:
case apiv1types.WebhookIssueClosed:
if p.PullRequest.HasMerged {
title = "Pull request merged: " + title
} else {
title = "Pull request closed: " + title
}
case api.HOOK_ISSUE_REOPENED:
case apiv1types.WebhookIssueReopened:
title = "Pull request re-opened: " + title
case api.HOOK_ISSUE_EDITED:
case apiv1types.WebhookIssueEdited:
title = "Pull request edited: " + title
content = p.PullRequest.Body
case api.HOOK_ISSUE_ASSIGNED:
case apiv1types.WebhookIssueAssigned:
title = "Pull request assigned: " + title
fields = []*DiscordEmbedFieldObject{{
Name: "New Assignee",
Value: p.PullRequest.Assignee.UserName,
}}
case api.HOOK_ISSUE_UNASSIGNED:
case apiv1types.WebhookIssueUnassigned:
title = "Pull request unassigned: " + title
case api.HOOK_ISSUE_LABEL_UPDATED:
case apiv1types.WebhookIssueLabelUpdated:
title = "Pull request labels updated: " + title
labels := make([]string, len(p.PullRequest.Labels))
for i := range p.PullRequest.Labels {
@@ -317,17 +316,17 @@ func getDiscordPullRequestPayload(p *api.PullRequestPayload, slack *SlackMeta) *
Name: "Labels",
Value: strings.Join(labels, ", "),
}}
case api.HOOK_ISSUE_LABEL_CLEARED:
case apiv1types.WebhookIssueLabelCleared:
title = "Pull request labels cleared: " + title
case api.HOOK_ISSUE_SYNCHRONIZED:
case apiv1types.WebhookIssueSynchronized:
title = "Pull request synchronized: " + title
case api.HOOK_ISSUE_MILESTONED:
case apiv1types.WebhookIssueMilestoned:
title = "Pull request milestoned: " + title
fields = []*DiscordEmbedFieldObject{{
Name: "New Milestone",
Value: p.PullRequest.Milestone.Title,
}}
case api.HOOK_ISSUE_DEMILESTONED:
case apiv1types.WebhookIssueDemilestoned:
title = "Pull request demilestoned: " + title
}
@@ -345,14 +344,14 @@ func getDiscordPullRequestPayload(p *api.PullRequestPayload, slack *SlackMeta) *
},
Author: &DiscordEmbedAuthorObject{
Name: p.Sender.UserName,
IconURL: p.Sender.AvatarUrl,
IconURL: p.Sender.AvatarURL,
},
Fields: fields,
}},
}
}
func getDiscordReleasePayload(p *api.ReleasePayload) *DiscordPayload {
func getDiscordReleasePayload(p *apiv1types.WebhookReleasePayload) *DiscordPayload {
repoLink := DiscordLinkFormatter(p.Repository.HTMLURL, p.Repository.Name)
refLink := DiscordLinkFormatter(p.Repository.HTMLURL+"/src/"+p.Release.TagName, p.Release.TagName)
content := fmt.Sprintf("Published new release %s of %s", refLink, repoLink)
@@ -362,13 +361,13 @@ func getDiscordReleasePayload(p *api.ReleasePayload) *DiscordPayload {
URL: conf.Server.ExternalURL + p.Sender.UserName,
Author: &DiscordEmbedAuthorObject{
Name: p.Sender.UserName,
IconURL: p.Sender.AvatarUrl,
IconURL: p.Sender.AvatarURL,
},
}},
}
}
func GetDiscordPayload(p api.Payloader, event HookEventType, meta string) (payload *DiscordPayload, err error) {
func GetDiscordPayload(p apiv1types.WebhookPayloader, event HookEventType, meta string) (payload *DiscordPayload, err error) {
slack := &SlackMeta{}
if err := json.Unmarshal([]byte(meta), slack); err != nil {
return nil, errors.Newf("unmarshal: %v", err)
@@ -376,21 +375,21 @@ func GetDiscordPayload(p api.Payloader, event HookEventType, meta string) (paylo
switch event {
case HookEventTypeCreate:
payload = getDiscordCreatePayload(p.(*api.CreatePayload))
payload = getDiscordCreatePayload(p.(*apiv1types.WebhookCreatePayload))
case HookEventTypeDelete:
payload = getDiscordDeletePayload(p.(*api.DeletePayload))
payload = getDiscordDeletePayload(p.(*apiv1types.WebhookDeletePayload))
case HookEventTypeFork:
payload = getDiscordForkPayload(p.(*api.ForkPayload))
payload = getDiscordForkPayload(p.(*apiv1types.WebhookForkPayload))
case HookEventTypePush:
payload = getDiscordPushPayload(p.(*api.PushPayload), slack)
payload = getDiscordPushPayload(p.(*apiv1types.WebhookPushPayload), slack)
case HookEventTypeIssues:
payload = getDiscordIssuesPayload(p.(*api.IssuesPayload), slack)
payload = getDiscordIssuesPayload(p.(*apiv1types.WebhookIssuesPayload), slack)
case HookEventTypeIssueComment:
payload = getDiscordIssueCommentPayload(p.(*api.IssueCommentPayload), slack)
payload = getDiscordIssueCommentPayload(p.(*apiv1types.WebhookIssueCommentPayload), slack)
case HookEventTypePullRequest:
payload = getDiscordPullRequestPayload(p.(*api.PullRequestPayload), slack)
payload = getDiscordPullRequestPayload(p.(*apiv1types.WebhookPullRequestPayload), slack)
case HookEventTypeRelease:
payload = getDiscordReleasePayload(p.(*api.ReleasePayload))
payload = getDiscordReleasePayload(p.(*apiv1types.WebhookReleasePayload))
default:
return nil, errors.Errorf("unexpected event %q", event)
}

View File

@@ -6,11 +6,10 @@ import (
"strings"
"github.com/cockroachdb/errors"
"github.com/gogs/git-module"
api "github.com/gogs/go-gogs-client"
"gogs.io/gogs/internal/conf"
apiv1types "gogs.io/gogs/internal/route/api/v1/types"
)
type SlackMeta struct {
@@ -68,7 +67,7 @@ func SlackLinkFormatter(url, text string) string {
}
// getSlackCreatePayload composes Slack payload for create new branch or tag.
func getSlackCreatePayload(p *api.CreatePayload) *SlackPayload {
func getSlackCreatePayload(p *apiv1types.WebhookCreatePayload) *SlackPayload {
refName := git.RefShortName(p.Ref)
repoLink := SlackLinkFormatter(p.Repo.HTMLURL, p.Repo.Name)
refLink := SlackLinkFormatter(p.Repo.HTMLURL+"/src/"+refName, refName)
@@ -79,7 +78,7 @@ func getSlackCreatePayload(p *api.CreatePayload) *SlackPayload {
}
// getSlackDeletePayload composes Slack payload for delete a branch or tag.
func getSlackDeletePayload(p *api.DeletePayload) *SlackPayload {
func getSlackDeletePayload(p *apiv1types.WebhookDeletePayload) *SlackPayload {
refName := git.RefShortName(p.Ref)
repoLink := SlackLinkFormatter(p.Repo.HTMLURL, p.Repo.Name)
text := fmt.Sprintf("[%s:%s] %s deleted by %s", repoLink, refName, p.RefType, p.Sender.UserName)
@@ -89,7 +88,7 @@ func getSlackDeletePayload(p *api.DeletePayload) *SlackPayload {
}
// getSlackForkPayload composes Slack payload for forked by a repository.
func getSlackForkPayload(p *api.ForkPayload) *SlackPayload {
func getSlackForkPayload(p *apiv1types.WebhookForkPayload) *SlackPayload {
baseLink := SlackLinkFormatter(p.Repo.HTMLURL, p.Repo.Name)
forkLink := SlackLinkFormatter(p.Forkee.HTMLURL, p.Forkee.FullName)
text := fmt.Sprintf("%s is forked to %s", baseLink, forkLink)
@@ -98,7 +97,7 @@ func getSlackForkPayload(p *api.ForkPayload) *SlackPayload {
}
}
func getSlackPushPayload(p *api.PushPayload, slack *SlackMeta) *SlackPayload {
func getSlackPushPayload(p *apiv1types.WebhookPushPayload, slack *SlackMeta) *SlackPayload {
// n new commits
var (
branchName = git.RefShortName(p.Ref)
@@ -143,36 +142,36 @@ func getSlackPushPayload(p *api.PushPayload, slack *SlackMeta) *SlackPayload {
}
}
func getSlackIssuesPayload(p *api.IssuesPayload, slack *SlackMeta) *SlackPayload {
func getSlackIssuesPayload(p *apiv1types.WebhookIssuesPayload, slack *SlackMeta) *SlackPayload {
senderLink := SlackLinkFormatter(conf.Server.ExternalURL+p.Sender.UserName, p.Sender.UserName)
titleLink := SlackLinkFormatter(fmt.Sprintf("%s/issues/%d", p.Repository.HTMLURL, p.Index),
fmt.Sprintf("#%d %s", p.Index, p.Issue.Title))
var text, title, attachmentText string
switch p.Action {
case api.HOOK_ISSUE_OPENED:
case apiv1types.WebhookIssueOpened:
text = fmt.Sprintf("[%s] New issue created by %s", p.Repository.FullName, senderLink)
title = titleLink
attachmentText = SlackTextFormatter(p.Issue.Body)
case api.HOOK_ISSUE_CLOSED:
case apiv1types.WebhookIssueClosed:
text = fmt.Sprintf("[%s] Issue closed: %s by %s", p.Repository.FullName, titleLink, senderLink)
case api.HOOK_ISSUE_REOPENED:
case apiv1types.WebhookIssueReopened:
text = fmt.Sprintf("[%s] Issue re-opened: %s by %s", p.Repository.FullName, titleLink, senderLink)
case api.HOOK_ISSUE_EDITED:
case apiv1types.WebhookIssueEdited:
text = fmt.Sprintf("[%s] Issue edited: %s by %s", p.Repository.FullName, titleLink, senderLink)
attachmentText = SlackTextFormatter(p.Issue.Body)
case api.HOOK_ISSUE_ASSIGNED:
case apiv1types.WebhookIssueAssigned:
text = fmt.Sprintf("[%s] Issue assigned to %s: %s by %s", p.Repository.FullName,
SlackLinkFormatter(conf.Server.ExternalURL+p.Issue.Assignee.UserName, p.Issue.Assignee.UserName),
titleLink, senderLink)
case api.HOOK_ISSUE_UNASSIGNED:
case apiv1types.WebhookIssueUnassigned:
text = fmt.Sprintf("[%s] Issue unassigned: %s by %s", p.Repository.FullName, titleLink, senderLink)
case api.HOOK_ISSUE_LABEL_UPDATED:
case apiv1types.WebhookIssueLabelUpdated:
text = fmt.Sprintf("[%s] Issue labels updated: %s by %s", p.Repository.FullName, titleLink, senderLink)
case api.HOOK_ISSUE_LABEL_CLEARED:
case apiv1types.WebhookIssueLabelCleared:
text = fmt.Sprintf("[%s] Issue labels cleared: %s by %s", p.Repository.FullName, titleLink, senderLink)
case api.HOOK_ISSUE_MILESTONED:
case apiv1types.WebhookIssueMilestoned:
text = fmt.Sprintf("[%s] Issue milestoned: %s by %s", p.Repository.FullName, titleLink, senderLink)
case api.HOOK_ISSUE_DEMILESTONED:
case apiv1types.WebhookIssueDemilestoned:
text = fmt.Sprintf("[%s] Issue demilestoned: %s by %s", p.Repository.FullName, titleLink, senderLink)
}
@@ -189,21 +188,21 @@ func getSlackIssuesPayload(p *api.IssuesPayload, slack *SlackMeta) *SlackPayload
}
}
func getSlackIssueCommentPayload(p *api.IssueCommentPayload, slack *SlackMeta) *SlackPayload {
func getSlackIssueCommentPayload(p *apiv1types.WebhookIssueCommentPayload, slack *SlackMeta) *SlackPayload {
senderLink := SlackLinkFormatter(conf.Server.ExternalURL+p.Sender.UserName, p.Sender.UserName)
titleLink := SlackLinkFormatter(fmt.Sprintf("%s/issues/%d#%s", p.Repository.HTMLURL, p.Issue.Index, CommentHashTag(p.Comment.ID)),
fmt.Sprintf("#%d %s", p.Issue.Index, p.Issue.Title))
var text, title, attachmentText string
switch p.Action {
case api.HOOK_ISSUE_COMMENT_CREATED:
case apiv1types.WebhookIssueCommentCreated:
text = fmt.Sprintf("[%s] New comment created by %s", p.Repository.FullName, senderLink)
title = titleLink
attachmentText = SlackTextFormatter(p.Comment.Body)
case api.HOOK_ISSUE_COMMENT_EDITED:
case apiv1types.WebhookIssueCommentEdited:
text = fmt.Sprintf("[%s] Comment edited by %s", p.Repository.FullName, senderLink)
title = titleLink
attachmentText = SlackTextFormatter(p.Comment.Body)
case api.HOOK_ISSUE_COMMENT_DELETED:
case apiv1types.WebhookIssueCommentDeleted:
text = fmt.Sprintf("[%s] Comment deleted by %s", p.Repository.FullName, senderLink)
title = SlackLinkFormatter(fmt.Sprintf("%s/issues/%d", p.Repository.HTMLURL, p.Issue.Index),
fmt.Sprintf("#%d %s", p.Issue.Index, p.Issue.Title))
@@ -223,42 +222,42 @@ func getSlackIssueCommentPayload(p *api.IssueCommentPayload, slack *SlackMeta) *
}
}
func getSlackPullRequestPayload(p *api.PullRequestPayload, slack *SlackMeta) *SlackPayload {
func getSlackPullRequestPayload(p *apiv1types.WebhookPullRequestPayload, slack *SlackMeta) *SlackPayload {
senderLink := SlackLinkFormatter(conf.Server.ExternalURL+p.Sender.UserName, p.Sender.UserName)
titleLink := SlackLinkFormatter(fmt.Sprintf("%s/pulls/%d", p.Repository.HTMLURL, p.Index),
fmt.Sprintf("#%d %s", p.Index, p.PullRequest.Title))
var text, title, attachmentText string
switch p.Action {
case api.HOOK_ISSUE_OPENED:
case apiv1types.WebhookIssueOpened:
text = fmt.Sprintf("[%s] Pull request submitted by %s", p.Repository.FullName, senderLink)
title = titleLink
attachmentText = SlackTextFormatter(p.PullRequest.Body)
case api.HOOK_ISSUE_CLOSED:
case apiv1types.WebhookIssueClosed:
if p.PullRequest.HasMerged {
text = fmt.Sprintf("[%s] Pull request merged: %s by %s", p.Repository.FullName, titleLink, senderLink)
} else {
text = fmt.Sprintf("[%s] Pull request closed: %s by %s", p.Repository.FullName, titleLink, senderLink)
}
case api.HOOK_ISSUE_REOPENED:
case apiv1types.WebhookIssueReopened:
text = fmt.Sprintf("[%s] Pull request re-opened: %s by %s", p.Repository.FullName, titleLink, senderLink)
case api.HOOK_ISSUE_EDITED:
case apiv1types.WebhookIssueEdited:
text = fmt.Sprintf("[%s] Pull request edited: %s by %s", p.Repository.FullName, titleLink, senderLink)
attachmentText = SlackTextFormatter(p.PullRequest.Body)
case api.HOOK_ISSUE_ASSIGNED:
case apiv1types.WebhookIssueAssigned:
text = fmt.Sprintf("[%s] Pull request assigned to %s: %s by %s", p.Repository.FullName,
SlackLinkFormatter(conf.Server.ExternalURL+p.PullRequest.Assignee.UserName, p.PullRequest.Assignee.UserName),
titleLink, senderLink)
case api.HOOK_ISSUE_UNASSIGNED:
case apiv1types.WebhookIssueUnassigned:
text = fmt.Sprintf("[%s] Pull request unassigned: %s by %s", p.Repository.FullName, titleLink, senderLink)
case api.HOOK_ISSUE_LABEL_UPDATED:
case apiv1types.WebhookIssueLabelUpdated:
text = fmt.Sprintf("[%s] Pull request labels updated: %s by %s", p.Repository.FullName, titleLink, senderLink)
case api.HOOK_ISSUE_LABEL_CLEARED:
case apiv1types.WebhookIssueLabelCleared:
text = fmt.Sprintf("[%s] Pull request labels cleared: %s by %s", p.Repository.FullName, titleLink, senderLink)
case api.HOOK_ISSUE_SYNCHRONIZED:
case apiv1types.WebhookIssueSynchronized:
text = fmt.Sprintf("[%s] Pull request synchronized: %s by %s", p.Repository.FullName, titleLink, senderLink)
case api.HOOK_ISSUE_MILESTONED:
case apiv1types.WebhookIssueMilestoned:
text = fmt.Sprintf("[%s] Pull request milestoned: %s by %s", p.Repository.FullName, titleLink, senderLink)
case api.HOOK_ISSUE_DEMILESTONED:
case apiv1types.WebhookIssueDemilestoned:
text = fmt.Sprintf("[%s] Pull request demilestoned: %s by %s", p.Repository.FullName, titleLink, senderLink)
}
@@ -275,7 +274,7 @@ func getSlackPullRequestPayload(p *api.PullRequestPayload, slack *SlackMeta) *Sl
}
}
func getSlackReleasePayload(p *api.ReleasePayload) *SlackPayload {
func getSlackReleasePayload(p *apiv1types.WebhookReleasePayload) *SlackPayload {
repoLink := SlackLinkFormatter(p.Repository.HTMLURL, p.Repository.Name)
refLink := SlackLinkFormatter(p.Repository.HTMLURL+"/src/"+p.Release.TagName, p.Release.TagName)
text := fmt.Sprintf("[%s] new release %s published by %s", repoLink, refLink, p.Sender.UserName)
@@ -284,7 +283,7 @@ func getSlackReleasePayload(p *api.ReleasePayload) *SlackPayload {
}
}
func GetSlackPayload(p api.Payloader, event HookEventType, meta string) (payload *SlackPayload, err error) {
func GetSlackPayload(p apiv1types.WebhookPayloader, event HookEventType, meta string) (payload *SlackPayload, err error) {
slack := &SlackMeta{}
if err := json.Unmarshal([]byte(meta), slack); err != nil {
return nil, errors.Newf("unmarshal: %v", err)
@@ -292,21 +291,21 @@ func GetSlackPayload(p api.Payloader, event HookEventType, meta string) (payload
switch event {
case HookEventTypeCreate:
payload = getSlackCreatePayload(p.(*api.CreatePayload))
payload = getSlackCreatePayload(p.(*apiv1types.WebhookCreatePayload))
case HookEventTypeDelete:
payload = getSlackDeletePayload(p.(*api.DeletePayload))
payload = getSlackDeletePayload(p.(*apiv1types.WebhookDeletePayload))
case HookEventTypeFork:
payload = getSlackForkPayload(p.(*api.ForkPayload))
payload = getSlackForkPayload(p.(*apiv1types.WebhookForkPayload))
case HookEventTypePush:
payload = getSlackPushPayload(p.(*api.PushPayload), slack)
payload = getSlackPushPayload(p.(*apiv1types.WebhookPushPayload), slack)
case HookEventTypeIssues:
payload = getSlackIssuesPayload(p.(*api.IssuesPayload), slack)
payload = getSlackIssuesPayload(p.(*apiv1types.WebhookIssuesPayload), slack)
case HookEventTypeIssueComment:
payload = getSlackIssueCommentPayload(p.(*api.IssueCommentPayload), slack)
payload = getSlackIssueCommentPayload(p.(*apiv1types.WebhookIssueCommentPayload), slack)
case HookEventTypePullRequest:
payload = getSlackPullRequestPayload(p.(*api.PullRequestPayload), slack)
payload = getSlackPullRequestPayload(p.(*apiv1types.WebhookPullRequestPayload), slack)
case HookEventTypeRelease:
payload = getSlackReleasePayload(p.(*api.ReleasePayload))
payload = getSlackReleasePayload(p.(*apiv1types.WebhookReleasePayload))
default:
return nil, errors.Errorf("unexpected event %q", event)
}

View File

@@ -0,0 +1,303 @@
package v1
import (
"context"
"fmt"
"strconv"
"strings"
"github.com/gogs/git-module"
"gogs.io/gogs/internal/conf"
"gogs.io/gogs/internal/database"
"gogs.io/gogs/internal/markup"
"gogs.io/gogs/internal/route/api/v1/types"
)
// toAllowedPageSize makes sure page size is in allowed range.
func toAllowedPageSize(size int) int {
if size <= 0 {
size = 10
} else if size > conf.API.MaxResponseItems {
size = conf.API.MaxResponseItems
}
return size
}
// toUser converts a database user to an API user with the full name sanitized
// for safe HTML rendering.
func toUser(u *database.User) *types.User {
return &types.User{
ID: u.ID,
UserName: u.Name,
Login: u.Name,
FullName: markup.Sanitize(u.FullName),
Email: u.Email,
AvatarURL: u.AvatarURL(),
}
}
func toUserEmail(email *database.EmailAddress) *types.UserEmail {
return &types.UserEmail{
Email: email.Email,
Verified: email.IsActivated,
Primary: email.IsPrimary,
}
}
func toBranch(b *database.Branch, c *git.Commit) *types.RepositoryBranch {
return &types.RepositoryBranch{
Name: b.Name,
Commit: toPayloadCommit(c),
}
}
func toTag(b *database.Tag, c *git.Commit) *tag {
return &tag{
Name: b.Name,
Commit: toPayloadCommit(c),
}
}
func toPayloadCommit(c *git.Commit) *types.WebhookPayloadCommit {
authorUsername := ""
author, err := database.Handle.Users().GetByEmail(context.TODO(), c.Author.Email)
if err == nil {
authorUsername = author.Name
}
committerUsername := ""
committer, err := database.Handle.Users().GetByEmail(context.TODO(), c.Committer.Email)
if err == nil {
committerUsername = committer.Name
}
return &types.WebhookPayloadCommit{
ID: c.ID.String(),
Message: c.Message,
URL: "Not implemented",
Author: &types.WebhookPayloadUser{
Name: c.Author.Name,
Email: c.Author.Email,
UserName: authorUsername,
},
Committer: &types.WebhookPayloadUser{
Name: c.Committer.Name,
Email: c.Committer.Email,
UserName: committerUsername,
},
Timestamp: c.Author.When,
}
}
func toUserPublicKey(apiLink string, key *database.PublicKey) *types.UserPublicKey {
return &types.UserPublicKey{
ID: key.ID,
Key: key.Content,
URL: apiLink + strconv.FormatInt(key.ID, 10),
Title: key.Name,
Created: key.Created,
}
}
func toRepositoryHook(repoLink string, w *database.Webhook) *types.RepositoryHook {
config := map[string]string{
"url": w.URL,
"content_type": w.ContentType.Name(),
}
if w.HookTaskType == database.SLACK {
s := w.SlackMeta()
config["channel"] = s.Channel
config["username"] = s.Username
config["icon_url"] = s.IconURL
config["color"] = s.Color
}
return &types.RepositoryHook{
ID: w.ID,
Type: w.HookTaskType.Name(),
URL: fmt.Sprintf("%s/settings/hooks/%d", repoLink, w.ID),
Active: w.IsActive,
Config: config,
Events: w.EventsArray(),
Updated: w.Updated,
Created: w.Created,
}
}
func toDeployKey(apiLink string, key *database.DeployKey) *types.RepositoryDeployKey {
return &types.RepositoryDeployKey{
ID: key.ID,
Key: key.Content,
URL: apiLink + strconv.FormatInt(key.ID, 10),
Title: key.Name,
Created: key.Created,
ReadOnly: true, // All deploy keys are read-only.
}
}
func toOrganization(org *database.User) *types.Organization {
return &types.Organization{
ID: org.ID,
AvatarURL: org.AvatarURL(),
UserName: org.Name,
FullName: org.FullName,
Description: org.Description,
Website: org.Website,
Location: org.Location,
}
}
func toOrganizationTeam(team *database.Team) *types.OrganizationTeam {
return &types.OrganizationTeam{
ID: team.ID,
Name: team.Name,
Description: team.Description,
Permission: team.Authorize.String(),
}
}
func toIssueLabel(l *database.Label) *types.IssueLabel {
return &types.IssueLabel{
ID: l.ID,
Name: l.Name,
Color: strings.TrimLeft(l.Color, "#"),
}
}
func issueState(isClosed bool) types.IssueStateType {
if isClosed {
return types.IssueStateClosed
}
return types.IssueStateOpen
}
// toIssue converts a database issue to an API issue.
// It assumes the following fields have been assigned with valid values:
// Required - Poster, Labels
// Optional - Milestone, Assignee, PullRequest
func toIssue(issue *database.Issue) *types.Issue {
labels := make([]*types.IssueLabel, len(issue.Labels))
for i := range issue.Labels {
labels[i] = toIssueLabel(issue.Labels[i])
}
apiIssue := &types.Issue{
ID: issue.ID,
Index: issue.Index,
Poster: toUser(issue.Poster),
Title: issue.Title,
Body: issue.Content,
Labels: labels,
State: issueState(issue.IsClosed),
Comments: issue.NumComments,
Created: issue.Created,
Updated: issue.Updated,
}
if issue.Milestone != nil {
apiIssue.Milestone = toIssueMilestone(issue.Milestone)
}
if issue.Assignee != nil {
apiIssue.Assignee = toUser(issue.Assignee)
}
if issue.IsPull {
apiIssue.PullRequest = &types.PullRequestMeta{
HasMerged: issue.PullRequest.HasMerged,
}
if issue.PullRequest.HasMerged {
apiIssue.PullRequest.Merged = &issue.PullRequest.Merged
}
}
return apiIssue
}
func toIssueComment(c *database.Comment) *types.IssueComment {
return &types.IssueComment{
ID: c.ID,
HTMLURL: c.HTMLURL(),
Poster: toUser(c.Poster),
Body: c.Content,
Created: c.Created,
Updated: c.Updated,
}
}
func toIssueMilestone(m *database.Milestone) *types.IssueMilestone {
ms := &types.IssueMilestone{
ID: m.ID,
State: issueState(m.IsClosed),
Title: m.Name,
Description: m.Content,
OpenIssues: m.NumOpenIssues,
ClosedIssues: m.NumClosedIssues,
}
if m.IsClosed {
ms.Closed = &m.ClosedDate
}
if m.Deadline.Year() < 9999 {
ms.Deadline = &m.Deadline
}
return ms
}
// toRelease converts a database release to an API release.
// It assumes the Publisher field has been assigned.
func toRelease(r *database.Release) *types.RepositoryRelease {
return &types.RepositoryRelease{
ID: r.ID,
TagName: r.TagName,
TargetCommitish: r.Target,
Name: r.Title,
Body: r.Note,
Draft: r.IsDraft,
Prerelease: r.IsPrerelease,
Author: toUser(r.Publisher),
Created: r.Created,
}
}
func toRepositoryCollaborator(c *database.Collaborator) *types.RepositoryCollaborator {
return &types.RepositoryCollaborator{
User: toUser(c.User),
Permissions: types.RepositoryPermission{
Admin: c.Collaboration.Mode >= database.AccessModeAdmin,
Push: c.Collaboration.Mode >= database.AccessModeWrite,
Pull: c.Collaboration.Mode >= database.AccessModeRead,
},
}
}
// toRepository converts a database repository to an API repository.
// It assumes the Owner field has been loaded on the repo.
func toRepository(repo *database.Repository, perm *types.RepositoryPermission) *types.Repository {
cloneLink := repo.CloneLink()
apiRepo := &types.Repository{
ID: repo.ID,
Owner: toUser(repo.Owner),
Name: repo.Name,
FullName: repo.FullName(),
Description: repo.Description,
Private: repo.IsPrivate,
Fork: repo.IsFork,
Empty: repo.IsBare,
Mirror: repo.IsMirror,
Size: repo.Size,
HTMLURL: repo.HTMLURL(),
SSHURL: cloneLink.SSH,
CloneURL: cloneLink.HTTPS,
Website: repo.Website,
Stars: repo.NumStars,
Forks: repo.NumForks,
Watchers: repo.NumWatches,
OpenIssues: repo.NumOpenIssues,
DefaultBranch: repo.DefaultBranch,
Created: repo.Created,
Updated: repo.Updated,
Permissions: perm,
}
if repo.IsFork {
p := &types.RepositoryPermission{Pull: true}
apiRepo.Parent = toRepository(repo.BaseRepo, p)
}
return apiRepo
}

View File

@@ -1,13 +0,0 @@
package admin
import (
api "github.com/gogs/go-gogs-client"
"gogs.io/gogs/internal/context"
"gogs.io/gogs/internal/route/api/v1/org"
"gogs.io/gogs/internal/route/api/v1/user"
)
func CreateOrg(c *context.APIContext, form api.CreateOrgOption) {
org.CreateOrgForUser(c, form, user.GetUserByParams(c))
}

View File

@@ -1,18 +0,0 @@
package admin
import (
api "github.com/gogs/go-gogs-client"
"gogs.io/gogs/internal/context"
"gogs.io/gogs/internal/route/api/v1/repo"
"gogs.io/gogs/internal/route/api/v1/user"
)
func CreateRepo(c *context.APIContext, form api.CreateRepoOption) {
owner := user.GetUserByParams(c)
if c.Written() {
return
}
repo.CreateUserRepo(c, owner, form)
}

View File

@@ -0,0 +1,9 @@
package v1
import (
"gogs.io/gogs/internal/context"
)
func adminCreateOrg(c *context.APIContext, form createOrgRequest) {
createOrgForUser(c, form, getUserByParams(c))
}

View File

@@ -1,11 +1,11 @@
package admin
package v1
import (
"gogs.io/gogs/internal/context"
"gogs.io/gogs/internal/database"
)
func GetRepositoryByParams(c *context.APIContext) *database.Repository {
func getRepositoryByParams(c *context.APIContext) *database.Repository {
repo, err := database.GetRepositoryByName(c.Org.Team.OrgID, c.Params(":reponame"))
if err != nil {
c.NotFoundOrError(err, "get repository by name")
@@ -14,8 +14,8 @@ func GetRepositoryByParams(c *context.APIContext) *database.Repository {
return repo
}
func AddTeamRepository(c *context.APIContext) {
repo := GetRepositoryByParams(c)
func adminAddTeamRepository(c *context.APIContext) {
repo := getRepositoryByParams(c)
if c.Written() {
return
}
@@ -27,8 +27,8 @@ func AddTeamRepository(c *context.APIContext) {
c.NoContent()
}
func RemoveTeamRepository(c *context.APIContext) {
repo := GetRepositoryByParams(c)
func adminRemoveTeamRepository(c *context.APIContext) {
repo := getRepositoryByParams(c)
if c.Written() {
return
}

View File

@@ -1,17 +1,20 @@
package admin
package v1
import (
"net/http"
api "github.com/gogs/go-gogs-client"
"gogs.io/gogs/internal/context"
"gogs.io/gogs/internal/database"
"gogs.io/gogs/internal/route/api/v1/convert"
"gogs.io/gogs/internal/route/api/v1/user"
"gogs.io/gogs/internal/route/api/v1/types"
)
func CreateTeam(c *context.APIContext, form api.CreateTeamOption) {
type adminCreateTeamRequest struct {
Name string `json:"name" binding:"Required;AlphaDashDot;MaxSize(30)"`
Description string `json:"description" binding:"MaxSize(255)"`
Permission string `json:"permission"`
}
func adminCreateTeam(c *context.APIContext, form adminCreateTeamRequest) {
team := &database.Team{
OrgID: c.Org.Organization.ID,
Name: form.Name,
@@ -27,11 +30,11 @@ func CreateTeam(c *context.APIContext, form api.CreateTeamOption) {
return
}
c.JSON(http.StatusCreated, convert.ToTeam(team))
c.JSON(http.StatusCreated, toOrganizationTeam(team))
}
func AddTeamMember(c *context.APIContext) {
u := user.GetUserByParams(c)
func adminAddTeamMember(c *context.APIContext) {
u := getUserByParams(c)
if c.Written() {
return
}
@@ -43,8 +46,8 @@ func AddTeamMember(c *context.APIContext) {
c.NoContent()
}
func RemoveTeamMember(c *context.APIContext) {
u := user.GetUserByParams(c)
func adminRemoveTeamMember(c *context.APIContext) {
u := getUserByParams(c)
if c.Written() {
return
}
@@ -57,16 +60,16 @@ func RemoveTeamMember(c *context.APIContext) {
c.NoContent()
}
func ListTeamMembers(c *context.APIContext) {
func adminListTeamMembers(c *context.APIContext) {
team := c.Org.Team
if err := team.GetMembers(); err != nil {
c.Error(err, "get team members")
return
}
apiMembers := make([]*api.User, len(team.Members))
apiMembers := make([]*types.User, len(team.Members))
for i := range team.Members {
apiMembers[i] = team.Members[i].APIFormat()
apiMembers[i] = toUser(team.Members[i])
}
c.JSONSuccess(apiMembers)
}

View File

@@ -0,0 +1,14 @@
package v1
import (
"gogs.io/gogs/internal/context"
)
func adminCreateRepo(c *context.APIContext, form createRepoRequest) {
owner := getUserByParams(c)
if c.Written() {
return
}
createUserRepo(c, owner, form)
}

View File

@@ -1,16 +1,14 @@
package admin
package v1
import (
"net/http"
api "github.com/gogs/go-gogs-client"
log "unknwon.dev/clog/v2"
"gogs.io/gogs/internal/conf"
"gogs.io/gogs/internal/context"
"gogs.io/gogs/internal/database"
"gogs.io/gogs/internal/email"
"gogs.io/gogs/internal/route/api/v1/user"
)
func parseLoginSource(c *context.APIContext, sourceID int64) {
@@ -29,13 +27,23 @@ func parseLoginSource(c *context.APIContext, sourceID int64) {
}
}
func CreateUser(c *context.APIContext, form api.CreateUserOption) {
type adminCreateUserRequest struct {
SourceID int64 `json:"source_id"`
LoginName string `json:"login_name"`
Username string `json:"username" binding:"Required;AlphaDashDot;MaxSize(35)"`
FullName string `json:"full_name" binding:"MaxSize(100)"`
Email string `json:"email" binding:"Required;Email;MaxSize(254)"`
Password string `json:"password" binding:"MaxSize(255)"`
SendNotify bool `json:"send_notify"`
}
func adminCreateUser(c *context.APIContext, form adminCreateUserRequest) {
parseLoginSource(c, form.SourceID)
if c.Written() {
return
}
user, err := database.Handle.Users().Create(
u, err := database.Handle.Users().Create(
c.Req.Context(),
form.Username,
form.Email,
@@ -57,18 +65,33 @@ func CreateUser(c *context.APIContext, form api.CreateUserOption) {
}
return
}
log.Trace("Account %q created by admin %q", user.Name, c.User.Name)
log.Trace("Account %q created by admin %q", u.Name, c.User.Name)
// Send email notification.
if form.SendNotify && conf.Email.Enabled {
email.SendRegisterNotifyMail(c.Context.Context, database.NewMailerUser(user))
email.SendRegisterNotifyMail(c.Context.Context, database.NewMailerUser(u))
}
c.JSON(http.StatusCreated, user.APIFormat())
c.JSON(http.StatusCreated, toUser(u))
}
func EditUser(c *context.APIContext, form api.EditUserOption) {
u := user.GetUserByParams(c)
type adminEditUserRequest struct {
SourceID int64 `json:"source_id"`
LoginName string `json:"login_name"`
FullName string `json:"full_name" binding:"MaxSize(100)"`
Email string `json:"email" binding:"Required;Email;MaxSize(254)"`
Password string `json:"password" binding:"MaxSize(255)"`
Website string `json:"website" binding:"MaxSize(50)"`
Location string `json:"location" binding:"MaxSize(50)"`
Active *bool `json:"active"`
Admin *bool `json:"admin"`
AllowGitHook *bool `json:"allow_git_hook"`
AllowImportLocal *bool `json:"allow_import_local"`
MaxRepoCreation *int `json:"max_repo_creation"`
}
func adminEditUser(c *context.APIContext, form adminEditUserRequest) {
u := getUserByParams(c)
if c.Written() {
return
}
@@ -116,11 +139,11 @@ func EditUser(c *context.APIContext, form api.EditUserOption) {
c.Error(err, "get user")
return
}
c.JSONSuccess(u.APIFormat())
c.JSONSuccess(toUser(u))
}
func DeleteUser(c *context.APIContext) {
u := user.GetUserByParams(c)
func adminDeleteUser(c *context.APIContext) {
u := getUserByParams(c)
if c.Written() {
return
}
@@ -139,10 +162,10 @@ func DeleteUser(c *context.APIContext) {
c.NoContent()
}
func CreatePublicKey(c *context.APIContext, form api.CreateKeyOption) {
u := user.GetUserByParams(c)
func adminCreatePublicKey(c *context.APIContext, form createPublicKeyRequest) {
u := getUserByParams(c)
if c.Written() {
return
}
user.CreateUserPublicKey(c, form, u.ID)
createUserPublicKey(c, form, u.ID)
}

View File

@@ -7,16 +7,9 @@ import (
"github.com/go-macaron/binding"
"gopkg.in/macaron.v1"
api "github.com/gogs/go-gogs-client"
"gogs.io/gogs/internal/context"
"gogs.io/gogs/internal/database"
"gogs.io/gogs/internal/form"
"gogs.io/gogs/internal/route/api/v1/admin"
"gogs.io/gogs/internal/route/api/v1/misc"
"gogs.io/gogs/internal/route/api/v1/org"
"gogs.io/gogs/internal/route/api/v1/repo"
"gogs.io/gogs/internal/route/api/v1/user"
)
// repoAssignment extracts information from URL parameters to retrieve the repository,
@@ -181,245 +174,245 @@ func RegisterRoutes(m *macaron.Macaron) {
m.Options("/*", func() {})
// Miscellaneous
m.Post("/markdown", bind(api.MarkdownOption{}), misc.Markdown)
m.Post("/markdown/raw", misc.MarkdownRaw)
m.Post("/markdown", bind(markdownRequest{}), markdown)
m.Post("/markdown/raw", markdownRaw)
// Users
m.Group("/users", func() {
m.Get("/search", user.Search)
m.Get("/search", searchUsers)
m.Group("/:username", func() {
m.Get("", user.GetInfo)
m.Get("", getUserProfile)
m.Group("/tokens", func() {
accessTokensHandler := user.NewAccessTokensHandler(user.NewAccessTokensStore())
accessTokensHandler := newAccessTokensHandler(newAccessTokensStore())
m.Combo("").
Get(accessTokensHandler.List()).
Post(bind(api.CreateAccessTokenOption{}), accessTokensHandler.Create())
Post(bind(createAccessTokenRequest{}), accessTokensHandler.Create())
}, reqBasicAuth())
})
})
m.Group("/users", func() {
m.Group("/:username", func() {
m.Get("/keys", user.ListPublicKeys)
m.Get("/keys", listPublicKeys)
m.Get("/followers", user.ListFollowers)
m.Get("/followers", listFollowers)
m.Group("/following", func() {
m.Get("", user.ListFollowing)
m.Get("/:target", user.CheckFollowing)
m.Get("", listFollowing)
m.Get("/:target", checkFollowing)
})
})
}, reqToken())
m.Group("/user", func() {
m.Get("", user.GetAuthenticatedUser)
m.Get("", getAuthenticatedUser)
m.Combo("/emails").
Get(user.ListEmails).
Post(bind(api.CreateEmailOption{}), user.AddEmail).
Delete(bind(api.CreateEmailOption{}), user.DeleteEmail)
Get(listEmails).
Post(bind(createEmailRequest{}), addEmail).
Delete(bind(createEmailRequest{}), deleteEmail)
m.Get("/followers", user.ListMyFollowers)
m.Get("/followers", listMyFollowers)
m.Group("/following", func() {
m.Get("", user.ListMyFollowing)
m.Get("", listMyFollowing)
m.Combo("/:username").
Get(user.CheckMyFollowing).
Put(user.Follow).
Delete(user.Unfollow)
Get(checkMyFollowing).
Put(follow).
Delete(unfollow)
})
m.Group("/keys", func() {
m.Combo("").
Get(user.ListMyPublicKeys).
Post(bind(api.CreateKeyOption{}), user.CreatePublicKey)
Get(listMyPublicKeys).
Post(bind(createPublicKeyRequest{}), createPublicKey)
m.Combo("/:id").
Get(user.GetPublicKey).
Delete(user.DeletePublicKey)
Get(getPublicKey).
Delete(deletePublicKey)
})
m.Get("/issues", repo.ListUserIssues)
m.Get("/issues", listUserIssues)
}, reqToken())
// Repositories
m.Get("/users/:username/repos", reqToken(), repo.ListUserRepositories)
m.Get("/orgs/:org/repos", reqToken(), repo.ListOrgRepositories)
m.Get("/users/:username/repos", reqToken(), listUserRepositories)
m.Get("/orgs/:org/repos", reqToken(), listOrgRepositories)
m.Combo("/user/repos", reqToken()).
Get(repo.ListMyRepos).
Post(bind(api.CreateRepoOption{}), repo.Create)
m.Post("/org/:org/repos", reqToken(), bind(api.CreateRepoOption{}), repo.CreateOrgRepo)
Get(listMyRepos).
Post(bind(createRepoRequest{}), createRepo)
m.Post("/org/:org/repos", reqToken(), bind(createRepoRequest{}), createOrgRepo)
m.Group("/repos", func() {
m.Get("/search", repo.Search)
m.Get("/search", searchRepos)
m.Get("/:username/:reponame", repoAssignment(), repo.Get)
m.Get("/:username/:reponame/releases", repoAssignment(), repo.Releases)
m.Get("/:username/:reponame", repoAssignment(), getRepo)
m.Get("/:username/:reponame/releases", repoAssignment(), releases)
})
m.Group("/repos", func() {
m.Post("/migrate", bind(form.MigrateRepo{}), repo.Migrate)
m.Delete("/:username/:reponame", repoAssignment(), reqRepoOwner(), repo.Delete)
m.Post("/migrate", bind(form.MigrateRepo{}), migrate)
m.Delete("/:username/:reponame", repoAssignment(), reqRepoOwner(), deleteRepo)
m.Group("/:username/:reponame", func() {
m.Group("/hooks", func() {
m.Combo("").
Get(repo.ListHooks).
Post(bind(api.CreateHookOption{}), repo.CreateHook)
Get(listHooks).
Post(bind(createHookRequest{}), createHook)
m.Combo("/:id").
Patch(bind(api.EditHookOption{}), repo.EditHook).
Delete(repo.DeleteHook)
Patch(bind(editHookRequest{}), editHook).
Delete(deleteHook)
}, reqRepoAdmin())
m.Group("/collaborators", func() {
m.Get("", repo.ListCollaborators)
m.Get("", listCollaborators)
m.Combo("/:collaborator").
Get(repo.IsCollaborator).
Put(bind(api.AddCollaboratorOption{}), repo.AddCollaborator).
Delete(repo.DeleteCollaborator)
Get(isCollaborator).
Put(bind(addCollaboratorRequest{}), addCollaborator).
Delete(deleteCollaborator)
}, reqRepoAdmin())
m.Get("/raw/*", context.RepoRef(), repo.GetRawFile)
m.Get("/raw/*", context.RepoRef(), getRawFile)
m.Group("/contents", func() {
m.Get("", repo.GetContents)
m.Get("", getContents)
m.Combo("/*").
Get(repo.GetContents).
Put(reqRepoWriter(), bind(repo.PutContentsRequest{}), repo.PutContents)
Get(getContents).
Put(reqRepoWriter(), bind(putContentsRequest{}), putContents)
})
m.Get("/archive/*", repo.GetArchive)
m.Get("/archive/*", getArchive)
m.Group("/git", func() {
m.Group("/trees", func() {
m.Get("/:sha", repo.GetRepoGitTree)
m.Get("/:sha", getRepoGitTree)
})
m.Group("/blobs", func() {
m.Get("/:sha", repo.RepoGitBlob)
m.Get("/:sha", repoGitBlob)
})
})
m.Get("/forks", repo.ListForks)
m.Get("/tags", repo.ListTags)
m.Get("/forks", listForks)
m.Get("/tags", listTags)
m.Group("/branches", func() {
m.Get("", repo.ListBranches)
m.Get("/*", repo.GetBranch)
m.Get("", listBranches)
m.Get("/*", getBranch)
})
m.Group("/commits", func() {
m.Get("/:sha", repo.GetSingleCommit)
m.Get("", repo.GetAllCommits)
m.Get("/*", repo.GetReferenceSHA)
m.Get("/:sha", getSingleCommit)
m.Get("", getAllCommits)
m.Get("/*", getReferenceSHA)
})
m.Group("/keys", func() {
m.Combo("").
Get(repo.ListDeployKeys).
Post(bind(api.CreateKeyOption{}), repo.CreateDeployKey)
Get(listDeployKeys).
Post(bind(createDeployKeyRequest{}), createDeployKey)
m.Combo("/:id").
Get(repo.GetDeployKey).
Delete(repo.DeleteDeploykey)
Get(getDeployKey).
Delete(deleteDeploykey)
}, reqRepoAdmin())
m.Group("/issues", func() {
m.Combo("").
Get(repo.ListIssues).
Post(bind(api.CreateIssueOption{}), repo.CreateIssue)
Get(listIssues).
Post(bind(createIssueRequest{}), createIssue)
m.Group("/comments", func() {
m.Get("", repo.ListRepoIssueComments)
m.Patch("/:id", bind(api.EditIssueCommentOption{}), repo.EditIssueComment)
m.Get("", listRepoIssueComments)
m.Patch("/:id", bind(editIssueCommentRequest{}), editIssueComment)
})
m.Group("/:index", func() {
m.Combo("").
Get(repo.GetIssue).
Patch(bind(api.EditIssueOption{}), repo.EditIssue)
Get(getIssue).
Patch(bind(editIssueRequest{}), editIssue)
m.Group("/comments", func() {
m.Combo("").
Get(repo.ListIssueComments).
Post(bind(api.CreateIssueCommentOption{}), repo.CreateIssueComment)
Get(listIssueComments).
Post(bind(createIssueCommentRequest{}), createIssueComment)
m.Combo("/:id").
Patch(bind(api.EditIssueCommentOption{}), repo.EditIssueComment).
Delete(repo.DeleteIssueComment)
Patch(bind(editIssueCommentRequest{}), editIssueComment).
Delete(deleteIssueComment)
})
m.Get("/labels", repo.ListIssueLabels)
m.Get("/labels", listIssueLabels)
m.Group("/labels", func() {
m.Combo("").
Post(bind(api.IssueLabelsOption{}), repo.AddIssueLabels).
Put(bind(api.IssueLabelsOption{}), repo.ReplaceIssueLabels).
Delete(repo.ClearIssueLabels)
m.Delete("/:id", repo.DeleteIssueLabel)
Post(bind(issueLabelsRequest{}), addIssueLabels).
Put(bind(issueLabelsRequest{}), replaceIssueLabels).
Delete(clearIssueLabels)
m.Delete("/:id", deleteIssueLabel)
}, reqRepoWriter())
})
}, mustEnableIssues)
m.Group("/labels", func() {
m.Get("", repo.ListLabels)
m.Get("/:id", repo.GetLabel)
m.Get("", listLabels)
m.Get("/:id", getLabel)
})
m.Group("/labels", func() {
m.Post("", bind(api.CreateLabelOption{}), repo.CreateLabel)
m.Post("", bind(createLabelRequest{}), createLabel)
m.Combo("/:id").
Patch(bind(api.EditLabelOption{}), repo.EditLabel).
Delete(repo.DeleteLabel)
Patch(bind(editLabelRequest{}), editLabel).
Delete(deleteLabel)
}, reqRepoWriter())
m.Group("/milestones", func() {
m.Get("", repo.ListMilestones)
m.Get("/:id", repo.GetMilestone)
m.Get("", listMilestones)
m.Get("/:id", getMilestone)
})
m.Group("/milestones", func() {
m.Post("", bind(api.CreateMilestoneOption{}), repo.CreateMilestone)
m.Post("", bind(createMilestoneRequest{}), createMilestone)
m.Combo("/:id").
Patch(bind(api.EditMilestoneOption{}), repo.EditMilestone).
Delete(repo.DeleteMilestone)
Patch(bind(editMilestoneRequest{}), editMilestone).
Delete(deleteMilestone)
}, reqRepoWriter())
m.Patch("/issue-tracker", reqRepoWriter(), bind(api.EditIssueTrackerOption{}), repo.IssueTracker)
m.Patch("/wiki", reqRepoWriter(), bind(api.EditWikiOption{}), repo.Wiki)
m.Post("/mirror-sync", reqRepoWriter(), repo.MirrorSync)
m.Get("/editorconfig/:filename", context.RepoRef(), repo.GetEditorconfig)
m.Patch("/issue-tracker", reqRepoWriter(), bind(editIssueTrackerRequest{}), issueTracker)
m.Patch("/wiki", reqRepoWriter(), bind(editWikiRequest{}), wiki)
m.Post("/mirror-sync", reqRepoWriter(), mirrorSync)
m.Get("/editorconfig/:filename", context.RepoRef(), getEditorconfig)
}, repoAssignment())
}, reqToken())
m.Get("/issues", reqToken(), repo.ListUserIssues)
m.Get("/issues", reqToken(), listUserIssues)
// Organizations
m.Combo("/user/orgs", reqToken()).
Get(org.ListMyOrgs).
Post(bind(api.CreateOrgOption{}), org.CreateMyOrg)
Get(listMyOrgs).
Post(bind(createOrgRequest{}), createMyOrg)
m.Get("/users/:username/orgs", org.ListUserOrgs)
m.Get("/users/:username/orgs", listUserOrgs)
m.Group("/orgs/:orgname", func() {
m.Combo("").
Get(org.Get).
Patch(bind(api.EditOrgOption{}), org.Edit)
m.Get("/teams", org.ListTeams)
Get(getOrg).
Patch(bind(editOrgRequest{}), editOrg)
m.Get("/teams", listTeams)
}, orgAssignment(true))
m.Group("/admin", func() {
m.Group("/users", func() {
m.Post("", bind(api.CreateUserOption{}), admin.CreateUser)
m.Post("", bind(adminCreateUserRequest{}), adminCreateUser)
m.Group("/:username", func() {
m.Combo("").
Patch(bind(api.EditUserOption{}), admin.EditUser).
Delete(admin.DeleteUser)
m.Post("/keys", bind(api.CreateKeyOption{}), admin.CreatePublicKey)
m.Post("/orgs", bind(api.CreateOrgOption{}), admin.CreateOrg)
m.Post("/repos", bind(api.CreateRepoOption{}), admin.CreateRepo)
Patch(bind(adminEditUserRequest{}), adminEditUser).
Delete(adminDeleteUser)
m.Post("/keys", bind(createPublicKeyRequest{}), adminCreatePublicKey)
m.Post("/orgs", bind(createOrgRequest{}), adminCreateOrg)
m.Post("/repos", bind(createRepoRequest{}), adminCreateRepo)
})
})
m.Group("/orgs/:orgname", func() {
m.Group("/teams", func() {
m.Post("", orgAssignment(true), bind(api.CreateTeamOption{}), admin.CreateTeam)
m.Post("", orgAssignment(true), bind(adminCreateTeamRequest{}), adminCreateTeam)
})
})
m.Group("/teams", func() {
m.Group("/:teamid", func() {
m.Get("/members", admin.ListTeamMembers)
m.Get("/members", adminListTeamMembers)
m.Combo("/members/:username").
Put(admin.AddTeamMember).
Delete(admin.RemoveTeamMember)
Put(adminAddTeamMember).
Delete(adminRemoveTeamMember)
m.Combo("/repos/:reponame").
Put(admin.AddTeamRepository).
Delete(admin.RemoveTeamRepository)
Put(adminAddTeamRepository).
Delete(adminRemoveTeamRepository)
}, orgAssignment(false, true))
})
}, reqAdmin())

View File

@@ -1,135 +0,0 @@
package convert
import (
"context"
"fmt"
"strconv"
"github.com/gogs/git-module"
api "github.com/gogs/go-gogs-client"
"gogs.io/gogs/internal/database"
)
func ToEmail(email *database.EmailAddress) *api.Email {
return &api.Email{
Email: email.Email,
Verified: email.IsActivated,
Primary: email.IsPrimary,
}
}
func ToBranch(b *database.Branch, c *git.Commit) *api.Branch {
return &api.Branch{
Name: b.Name,
Commit: ToCommit(c),
}
}
type Tag struct {
Name string `json:"name"`
Commit *api.PayloadCommit `json:"commit"`
}
func ToTag(b *database.Tag, c *git.Commit) *Tag {
return &Tag{
Name: b.Name,
Commit: ToCommit(c),
}
}
func ToCommit(c *git.Commit) *api.PayloadCommit {
authorUsername := ""
author, err := database.Handle.Users().GetByEmail(context.TODO(), c.Author.Email)
if err == nil {
authorUsername = author.Name
}
committerUsername := ""
committer, err := database.Handle.Users().GetByEmail(context.TODO(), c.Committer.Email)
if err == nil {
committerUsername = committer.Name
}
return &api.PayloadCommit{
ID: c.ID.String(),
Message: c.Message,
URL: "Not implemented",
Author: &api.PayloadUser{
Name: c.Author.Name,
Email: c.Author.Email,
UserName: authorUsername,
},
Committer: &api.PayloadUser{
Name: c.Committer.Name,
Email: c.Committer.Email,
UserName: committerUsername,
},
Timestamp: c.Author.When,
}
}
func ToPublicKey(apiLink string, key *database.PublicKey) *api.PublicKey {
return &api.PublicKey{
ID: key.ID,
Key: key.Content,
URL: apiLink + strconv.FormatInt(key.ID, 10),
Title: key.Name,
Created: key.Created,
}
}
func ToHook(repoLink string, w *database.Webhook) *api.Hook {
config := map[string]string{
"url": w.URL,
"content_type": w.ContentType.Name(),
}
if w.HookTaskType == database.SLACK {
s := w.SlackMeta()
config["channel"] = s.Channel
config["username"] = s.Username
config["icon_url"] = s.IconURL
config["color"] = s.Color
}
return &api.Hook{
ID: w.ID,
Type: w.HookTaskType.Name(),
URL: fmt.Sprintf("%s/settings/hooks/%d", repoLink, w.ID),
Active: w.IsActive,
Config: config,
Events: w.EventsArray(),
Updated: w.Updated,
Created: w.Created,
}
}
func ToDeployKey(apiLink string, key *database.DeployKey) *api.DeployKey {
return &api.DeployKey{
ID: key.ID,
Key: key.Content,
URL: apiLink + strconv.FormatInt(key.ID, 10),
Title: key.Name,
Created: key.Created,
ReadOnly: true, // All deploy keys are read-only.
}
}
func ToOrganization(org *database.User) *api.Organization {
return &api.Organization{
ID: org.ID,
AvatarUrl: org.AvatarURL(),
UserName: org.Name,
FullName: org.FullName,
Description: org.Description,
Website: org.Website,
Location: org.Location,
}
}
func ToTeam(team *database.Team) *api.Team {
return &api.Team{
ID: team.ID,
Name: team.Name,
Description: team.Description,
Permission: team.Authorize.String(),
}
}

View File

@@ -1,15 +0,0 @@
package convert
import (
"gogs.io/gogs/internal/conf"
)
// ToCorrectPageSize makes sure page size is in allowed range.
func ToCorrectPageSize(size int) int {
if size <= 0 {
size = 10
} else if size > conf.API.MaxResponseItems {
size = conf.API.MaxResponseItems
}
return size
}

View File

@@ -1,13 +1,17 @@
package misc
package v1
import (
api "github.com/gogs/go-gogs-client"
"gogs.io/gogs/internal/context"
"gogs.io/gogs/internal/markup"
)
func Markdown(c *context.APIContext, form api.MarkdownOption) {
// markdownRequest represents the request body for rendering markdown.
type markdownRequest struct {
Text string
Context string
}
func markdown(c *context.APIContext, form markdownRequest) {
if form.Text == "" {
_, _ = c.Write([]byte(""))
return
@@ -16,7 +20,7 @@ func Markdown(c *context.APIContext, form api.MarkdownOption) {
_, _ = c.Write(markup.Markdown([]byte(form.Text), form.Context, nil))
}
func MarkdownRaw(c *context.APIContext) {
func markdownRaw(c *context.APIContext) {
body, err := c.Req.Body().Bytes()
if err != nil {
c.Error(err, "read body")

View File

@@ -1,17 +1,22 @@
package org
package v1
import (
"net/http"
api "github.com/gogs/go-gogs-client"
"gogs.io/gogs/internal/context"
"gogs.io/gogs/internal/database"
"gogs.io/gogs/internal/route/api/v1/convert"
"gogs.io/gogs/internal/route/api/v1/user"
"gogs.io/gogs/internal/route/api/v1/types"
)
func CreateOrgForUser(c *context.APIContext, apiForm api.CreateOrgOption, user *database.User) {
type createOrgRequest struct {
UserName string `json:"username" binding:"Required"`
FullName string `json:"full_name"`
Description string `json:"description"`
Website string `json:"website"`
Location string `json:"location"`
}
func createOrgForUser(c *context.APIContext, apiForm createOrgRequest, user *database.User) {
if c.Written() {
return
}
@@ -35,10 +40,10 @@ func CreateOrgForUser(c *context.APIContext, apiForm api.CreateOrgOption, user *
return
}
c.JSON(201, convert.ToOrganization(org))
c.JSON(201, toOrganization(org))
}
func listUserOrgs(c *context.APIContext, u *database.User, all bool) {
func listOrgsOfUser(c *context.APIContext, u *database.User, all bool) {
orgs, err := database.Handle.Organizations().List(
c.Req.Context(),
database.ListOrgsOptions{
@@ -51,34 +56,41 @@ func listUserOrgs(c *context.APIContext, u *database.User, all bool) {
return
}
apiOrgs := make([]*api.Organization, len(orgs))
apiOrgs := make([]*types.Organization, len(orgs))
for i := range orgs {
apiOrgs[i] = convert.ToOrganization(orgs[i])
apiOrgs[i] = toOrganization(orgs[i])
}
c.JSONSuccess(&apiOrgs)
}
func ListMyOrgs(c *context.APIContext) {
listUserOrgs(c, c.User, true)
func listMyOrgs(c *context.APIContext) {
listOrgsOfUser(c, c.User, true)
}
func CreateMyOrg(c *context.APIContext, apiForm api.CreateOrgOption) {
CreateOrgForUser(c, apiForm, c.User)
func createMyOrg(c *context.APIContext, apiForm createOrgRequest) {
createOrgForUser(c, apiForm, c.User)
}
func ListUserOrgs(c *context.APIContext) {
u := user.GetUserByParams(c)
func listUserOrgs(c *context.APIContext) {
u := getUserByParams(c)
if c.Written() {
return
}
listUserOrgs(c, u, false)
listOrgsOfUser(c, u, false)
}
func Get(c *context.APIContext) {
c.JSONSuccess(convert.ToOrganization(c.Org.Organization))
func getOrg(c *context.APIContext) {
c.JSONSuccess(toOrganization(c.Org.Organization))
}
func Edit(c *context.APIContext, form api.EditOrgOption) {
type editOrgRequest struct {
FullName string `json:"full_name"`
Description string `json:"description"`
Website string `json:"website"`
Location string `json:"location"`
}
func editOrg(c *context.APIContext, form editOrgRequest) {
org := c.Org.Organization
if !org.IsOwnedBy(c.User.ID) {
c.Status(http.StatusForbidden)
@@ -105,5 +117,5 @@ func Edit(c *context.APIContext, form api.EditOrgOption) {
c.Error(err, "get organization")
return
}
c.JSONSuccess(convert.ToOrganization(org))
c.JSONSuccess(toOrganization(org))
}

View File

@@ -1,22 +0,0 @@
package org
import (
api "github.com/gogs/go-gogs-client"
"gogs.io/gogs/internal/context"
"gogs.io/gogs/internal/route/api/v1/convert"
)
func ListTeams(c *context.APIContext) {
org := c.Org.Organization
if err := org.GetTeams(); err != nil {
c.Error(err, "get teams")
return
}
apiTeams := make([]*api.Team, len(org.Teams))
for i := range org.Teams {
apiTeams[i] = convert.ToTeam(org.Teams[i])
}
c.JSONSuccess(apiTeams)
}

View File

@@ -0,0 +1,20 @@
package v1
import (
"gogs.io/gogs/internal/context"
"gogs.io/gogs/internal/route/api/v1/types"
)
func listTeams(c *context.APIContext) {
org := c.Org.Organization
if err := org.GetTeams(); err != nil {
c.Error(err, "get teams")
return
}
apiTeams := make([]*types.OrganizationTeam, len(org.Teams))
for i := range org.Teams {
apiTeams[i] = toOrganizationTeam(org.Teams[i])
}
c.JSONSuccess(apiTeams)
}

View File

@@ -1,4 +1,4 @@
package repo
package v1
import (
"encoding/base64"
@@ -11,7 +11,7 @@ import (
"gogs.io/gogs/internal/repoutil"
)
func RepoGitBlob(c *context.APIContext) {
func repoGitBlob(c *context.APIContext) {
gitRepo, err := git.Open(repoutil.RepositoryPath(c.Params(":username"), c.Params(":reponame")))
if err != nil {
c.Error(err, "open repository")

View File

@@ -1,14 +1,12 @@
package repo
package v1
import (
api "github.com/gogs/go-gogs-client"
"gogs.io/gogs/internal/context"
"gogs.io/gogs/internal/route/api/v1/convert"
"gogs.io/gogs/internal/route/api/v1/types"
)
// https://github.com/gogs/go-gogs-client/wiki/Repositories#get-branch
func GetBranch(c *context.APIContext) {
func getBranch(c *context.APIContext) {
branch, err := c.Repo.Repository.GetBranch(c.Params("*"))
if err != nil {
c.NotFoundOrError(err, "get branch")
@@ -21,25 +19,25 @@ func GetBranch(c *context.APIContext) {
return
}
c.JSONSuccess(convert.ToBranch(branch, commit))
c.JSONSuccess(toBranch(branch, commit))
}
// https://github.com/gogs/go-gogs-client/wiki/Repositories#list-branches
func ListBranches(c *context.APIContext) {
func listBranches(c *context.APIContext) {
branches, err := c.Repo.Repository.GetBranches()
if err != nil {
c.Error(err, "get branches")
return
}
apiBranches := make([]*api.Branch, len(branches))
apiBranches := make([]*types.RepositoryBranch, len(branches))
for i := range branches {
commit, err := branches[i].GetCommit()
if err != nil {
c.Error(err, "get commit")
return
}
apiBranches[i] = convert.ToBranch(branches[i], commit)
apiBranches[i] = toBranch(branches[i], commit)
}
c.JSONSuccess(&apiBranches)

View File

@@ -1,29 +1,32 @@
package repo
package v1
import (
"net/http"
api "github.com/gogs/go-gogs-client"
"gogs.io/gogs/internal/context"
"gogs.io/gogs/internal/database"
"gogs.io/gogs/internal/route/api/v1/types"
)
func ListCollaborators(c *context.APIContext) {
func listCollaborators(c *context.APIContext) {
collaborators, err := c.Repo.Repository.GetCollaborators()
if err != nil {
c.Error(err, "get collaborators")
return
}
apiCollaborators := make([]*api.Collaborator, len(collaborators))
apiCollaborators := make([]*types.RepositoryCollaborator, len(collaborators))
for i := range collaborators {
apiCollaborators[i] = collaborators[i].APIFormat()
apiCollaborators[i] = toRepositoryCollaborator(collaborators[i])
}
c.JSONSuccess(&apiCollaborators)
}
func AddCollaborator(c *context.APIContext, form api.AddCollaboratorOption) {
type addCollaboratorRequest struct {
Permission *string `json:"permission"`
}
func addCollaborator(c *context.APIContext, form addCollaboratorRequest) {
collaborator, err := database.Handle.Users().GetByUsername(c.Req.Context(), c.Params(":collaborator"))
if err != nil {
if database.IsErrUserNotExist(err) {
@@ -49,7 +52,7 @@ func AddCollaborator(c *context.APIContext, form api.AddCollaboratorOption) {
c.NoContent()
}
func IsCollaborator(c *context.APIContext) {
func isCollaborator(c *context.APIContext) {
collaborator, err := database.Handle.Users().GetByUsername(c.Req.Context(), c.Params(":collaborator"))
if err != nil {
if database.IsErrUserNotExist(err) {
@@ -67,7 +70,7 @@ func IsCollaborator(c *context.APIContext) {
}
}
func DeleteCollaborator(c *context.APIContext) {
func deleteCollaborator(c *context.APIContext) {
collaborator, err := database.Handle.Users().GetByUsername(c.Req.Context(), c.Params(":collaborator"))
if err != nil {
if database.IsErrUserNotExist(err) {

View File

@@ -1,4 +1,4 @@
package repo
package v1
import (
"net/http"
@@ -6,16 +6,18 @@ import (
"time"
"github.com/gogs/git-module"
api "github.com/gogs/go-gogs-client"
"gogs.io/gogs/internal/conf"
"gogs.io/gogs/internal/context"
"gogs.io/gogs/internal/database"
"gogs.io/gogs/internal/gitutil"
"gogs.io/gogs/internal/route/api/v1/types"
)
// GetAllCommits returns a slice of commits starting from HEAD.
func GetAllCommits(c *context.APIContext) {
const mediaApplicationSHA = "application/vnd.gogs.sha"
// getAllCommits returns a slice of commits starting from HEAD.
func getAllCommits(c *context.APIContext) {
// Get pagesize, set default if it is not specified.
pageSize := c.QueryInt("pageSize")
if pageSize == 0 {
@@ -29,7 +31,7 @@ func GetAllCommits(c *context.APIContext) {
}
// The response object returned as JSON
result := make([]*api.Commit, 0, pageSize)
result := make([]*types.Commit, 0, pageSize)
commits, err := gitRepo.Log("HEAD", git.LogOptions{MaxCount: pageSize})
if err != nil {
c.Error(err, "git log")
@@ -47,11 +49,11 @@ func GetAllCommits(c *context.APIContext) {
c.JSONSuccess(result)
}
// GetSingleCommit will return a single Commit object based on the specified SHA.
func GetSingleCommit(c *context.APIContext) {
if strings.Contains(c.Req.Header.Get("Accept"), api.MediaApplicationSHA) {
// getSingleCommit will return a single Commit object based on the specified SHA.
func getSingleCommit(c *context.APIContext) {
if strings.Contains(c.Req.Header.Get("Accept"), mediaApplicationSHA) {
c.SetParams("*", c.Params(":sha"))
GetReferenceSHA(c)
getReferenceSHA(c)
return
}
@@ -73,7 +75,7 @@ func GetSingleCommit(c *context.APIContext) {
c.JSONSuccess(apiCommit)
}
func GetReferenceSHA(c *context.APIContext) {
func getReferenceSHA(c *context.APIContext) {
gitRepo, err := git.Open(c.Repo.Repository.RepoPath())
if err != nil {
c.Error(err, "open repository")
@@ -114,14 +116,14 @@ func GetReferenceSHA(c *context.APIContext) {
}
// gitCommitToApiCommit is a helper function to convert git commit object to API commit.
func gitCommitToAPICommit(commit *git.Commit, c *context.APIContext) (*api.Commit, error) {
func gitCommitToAPICommit(commit *git.Commit, c *context.APIContext) (*types.Commit, error) {
// Retrieve author and committer information
var apiAuthor, apiCommitter *api.User
var apiAuthor, apiCommitter *types.User
author, err := database.Handle.Users().GetByEmail(c.Req.Context(), commit.Author.Email)
if err != nil && !database.IsErrUserNotExist(err) {
return nil, err
} else if err == nil {
apiAuthor = author.APIFormat()
apiAuthor = toUser(author)
}
// Save one query if the author is also the committer
@@ -132,40 +134,40 @@ func gitCommitToAPICommit(commit *git.Commit, c *context.APIContext) (*api.Commi
if err != nil && !database.IsErrUserNotExist(err) {
return nil, err
} else if err == nil {
apiCommitter = committer.APIFormat()
apiCommitter = toUser(committer)
}
}
// Retrieve parent(s) of the commit
apiParents := make([]*api.CommitMeta, commit.ParentsCount())
apiParents := make([]*types.CommitMeta, commit.ParentsCount())
for i := 0; i < commit.ParentsCount(); i++ {
sha, _ := commit.ParentID(i)
apiParents[i] = &api.CommitMeta{
apiParents[i] = &types.CommitMeta{
URL: c.BaseURL + "/repos/" + c.Repo.Repository.FullName() + "/commits/" + sha.String(),
SHA: sha.String(),
}
}
return &api.Commit{
CommitMeta: &api.CommitMeta{
return &types.Commit{
CommitMeta: &types.CommitMeta{
URL: conf.Server.ExternalURL + c.Link[1:],
SHA: commit.ID.String(),
},
HTMLURL: c.Repo.Repository.HTMLURL() + "/commits/" + commit.ID.String(),
RepoCommit: &api.RepoCommit{
RepoCommit: &types.RepoCommit{
URL: conf.Server.ExternalURL + c.Link[1:],
Author: &api.CommitUser{
Author: &types.CommitUser{
Name: commit.Author.Name,
Email: commit.Author.Email,
Date: commit.Author.When.Format(time.RFC3339),
},
Committer: &api.CommitUser{
Committer: &types.CommitUser{
Name: commit.Committer.Name,
Email: commit.Committer.Email,
Date: commit.Committer.When.Format(time.RFC3339),
},
Message: commit.Summary(),
Tree: &api.CommitMeta{
Tree: &types.CommitMeta{
URL: c.BaseURL + "/repos/" + c.Repo.Repository.FullName() + "/tree/" + commit.ID.String(),
SHA: commit.ID.String(),
},

View File

@@ -1,4 +1,4 @@
package repo
package v1
import (
"encoding/base64"
@@ -98,7 +98,7 @@ func toRepoContent(c *context.APIContext, ref, subpath string, commit *git.Commi
return content, nil
}
func GetContents(c *context.APIContext) {
func getContents(c *context.APIContext) {
repoPath := repoutil.RepositoryPath(c.Params(":username"), c.Params(":reponame"))
gitRepo, err := git.Open(repoPath)
if err != nil {
@@ -168,15 +168,15 @@ func GetContents(c *context.APIContext) {
c.JSONSuccess(contents)
}
// PutContentsRequest is the API message for creating or updating a file.
type PutContentsRequest struct {
// putContentsRequest is the API message for creating or updating a file.
type putContentsRequest struct {
Message string `json:"message" binding:"Required"`
Content string `json:"content" binding:"Required"`
Branch string `json:"branch"`
}
// PUT /repos/:username/:reponame/contents/*
func PutContents(c *context.APIContext, r PutContentsRequest) {
func putContents(c *context.APIContext, r putContentsRequest) {
content, err := base64.StdEncoding.DecodeString(r.Content)
if err != nil {
c.Error(err, "decoding base64")

View File

@@ -1,4 +1,4 @@
package repo
package v1
import (
"github.com/gogs/git-module"
@@ -6,10 +6,10 @@ import (
"gogs.io/gogs/internal/context"
"gogs.io/gogs/internal/database"
"gogs.io/gogs/internal/gitutil"
"gogs.io/gogs/internal/route/repo"
routerepo "gogs.io/gogs/internal/route/repo"
)
func GetRawFile(c *context.APIContext) {
func getRawFile(c *context.APIContext) {
if !c.Repo.HasAccess() {
c.NotFound()
return
@@ -25,12 +25,12 @@ func GetRawFile(c *context.APIContext) {
c.NotFoundOrError(gitutil.NewError(err), "get blob")
return
}
if err = repo.ServeBlob(c.Context, blob); err != nil {
if err = routerepo.ServeBlob(c.Context, blob); err != nil {
c.Error(err, "serve blob")
}
}
func GetArchive(c *context.APIContext) {
func getArchive(c *context.APIContext) {
repoPath := database.RepoPath(c.Params(":username"), c.Params(":reponame"))
gitRepo, err := git.Open(repoPath)
if err != nil {
@@ -39,10 +39,10 @@ func GetArchive(c *context.APIContext) {
}
c.Repo.GitRepo = gitRepo
repo.Download(c.Context)
routerepo.Download(c.Context)
}
func GetEditorconfig(c *context.APIContext) {
func getEditorconfig(c *context.APIContext) {
ec, err := c.Repo.Editorconfig()
if err != nil {
c.NotFoundOrError(gitutil.NewError(err), "get .editorconfig")

View File

@@ -1,4 +1,4 @@
package repo
package v1
import (
"encoding/json"
@@ -7,30 +7,35 @@ import (
"github.com/cockroachdb/errors"
api "github.com/gogs/go-gogs-client"
"gogs.io/gogs/internal/context"
"gogs.io/gogs/internal/database"
"gogs.io/gogs/internal/route/api/v1/convert"
"gogs.io/gogs/internal/route/api/v1/types"
)
// https://github.com/gogs/go-gogs-client/wiki/Repositories#list-hooks
func ListHooks(c *context.APIContext) {
func listHooks(c *context.APIContext) {
hooks, err := database.GetWebhooksByRepoID(c.Repo.Repository.ID)
if err != nil {
c.Errorf(err, "get webhooks by repository ID")
return
}
apiHooks := make([]*api.Hook, len(hooks))
apiHooks := make([]*types.RepositoryHook, len(hooks))
for i := range hooks {
apiHooks[i] = convert.ToHook(c.Repo.RepoLink, hooks[i])
apiHooks[i] = toRepositoryHook(c.Repo.RepoLink, hooks[i])
}
c.JSONSuccess(&apiHooks)
}
// https://github.com/gogs/go-gogs-client/wiki/Repositories#create-a-hook
func CreateHook(c *context.APIContext, form api.CreateHookOption) {
type createHookRequest struct {
Type string `json:"type" binding:"Required"`
Config map[string]string `json:"config" binding:"Required"`
Events []string `json:"events"`
Active bool `json:"active"`
}
func createHook(c *context.APIContext, form createHookRequest) {
if !database.IsValidHookTaskType(form.Type) {
c.ErrorStatus(http.StatusUnprocessableEntity, errors.New("Invalid hook type."))
return
@@ -97,11 +102,17 @@ func CreateHook(c *context.APIContext, form api.CreateHookOption) {
return
}
c.JSON(http.StatusCreated, convert.ToHook(c.Repo.RepoLink, w))
c.JSON(http.StatusCreated, toRepositoryHook(c.Repo.RepoLink, w))
}
// https://github.com/gogs/go-gogs-client/wiki/Repositories#edit-a-hook
func EditHook(c *context.APIContext, form api.EditHookOption) {
type editHookRequest struct {
Config map[string]string `json:"config"`
Events []string `json:"events"`
Active *bool `json:"active"`
}
func editHook(c *context.APIContext, form editHookRequest) {
w, err := database.GetWebhookOfRepoByID(c.Repo.Repository.ID, c.ParamsInt64(":id"))
if err != nil {
c.NotFoundOrError(err, "get webhook of repository by ID")
@@ -166,10 +177,10 @@ func EditHook(c *context.APIContext, form api.EditHookOption) {
return
}
c.JSONSuccess(convert.ToHook(c.Repo.RepoLink, w))
c.JSONSuccess(toRepositoryHook(c.Repo.RepoLink, w))
}
func DeleteHook(c *context.APIContext) {
func deleteHook(c *context.APIContext) {
if err := database.DeleteWebhookOfRepoByID(c.Repo.Repository.ID, c.ParamsInt64(":id")); err != nil {
c.Errorf(err, "delete webhook of repository by ID")
return

View File

@@ -1,18 +1,18 @@
package repo
package v1
import (
"net/http"
"strings"
"github.com/cockroachdb/errors"
api "github.com/gogs/go-gogs-client"
"gogs.io/gogs/internal/conf"
"gogs.io/gogs/internal/context"
"gogs.io/gogs/internal/database"
"gogs.io/gogs/internal/route/api/v1/types"
)
func listIssues(c *context.APIContext, opts *database.IssuesOptions) {
func queryIssues(c *context.APIContext, opts *database.IssuesOptions) {
issues, err := database.Issues(opts)
if err != nil {
c.Error(err, "list issues")
@@ -26,49 +26,58 @@ func listIssues(c *context.APIContext, opts *database.IssuesOptions) {
}
// FIXME: use IssueList to improve performance.
apiIssues := make([]*api.Issue, len(issues))
apiIssues := make([]*types.Issue, len(issues))
for i := range issues {
if err = issues[i].LoadAttributes(); err != nil {
c.Error(err, "load attributes")
return
}
apiIssues[i] = issues[i].APIFormat()
apiIssues[i] = toIssue(issues[i])
}
c.SetLinkHeader(int(count), conf.UI.IssuePagingNum)
c.JSONSuccess(&apiIssues)
}
func ListUserIssues(c *context.APIContext) {
func listUserIssues(c *context.APIContext) {
opts := database.IssuesOptions{
AssigneeID: c.User.ID,
Page: c.QueryInt("page"),
IsClosed: api.StateType(c.Query("state")) == api.STATE_CLOSED,
IsClosed: types.IssueStateType(c.Query("state")) == types.IssueStateClosed,
}
listIssues(c, &opts)
queryIssues(c, &opts)
}
func ListIssues(c *context.APIContext) {
func listIssues(c *context.APIContext) {
opts := database.IssuesOptions{
RepoID: c.Repo.Repository.ID,
Page: c.QueryInt("page"),
IsClosed: api.StateType(c.Query("state")) == api.STATE_CLOSED,
IsClosed: types.IssueStateType(c.Query("state")) == types.IssueStateClosed,
}
listIssues(c, &opts)
queryIssues(c, &opts)
}
func GetIssue(c *context.APIContext) {
func getIssue(c *context.APIContext) {
issue, err := database.GetIssueByIndex(c.Repo.Repository.ID, c.ParamsInt64(":index"))
if err != nil {
c.NotFoundOrError(err, "get issue by index")
return
}
c.JSONSuccess(issue.APIFormat())
c.JSONSuccess(toIssue(issue))
}
func CreateIssue(c *context.APIContext, form api.CreateIssueOption) {
type createIssueRequest struct {
Title string `json:"title" binding:"Required"`
Body string `json:"body"`
Assignee string `json:"assignee"`
Milestone int64 `json:"milestone"`
Labels []int64 `json:"labels"`
Closed bool `json:"closed"`
}
func createIssue(c *context.APIContext, form createIssueRequest) {
issue := &database.Issue{
RepoID: c.Repo.Repository.ID,
Title: form.Title,
@@ -114,10 +123,18 @@ func CreateIssue(c *context.APIContext, form api.CreateIssueOption) {
c.Error(err, "get issue by ID")
return
}
c.JSON(http.StatusCreated, issue.APIFormat())
c.JSON(http.StatusCreated, toIssue(issue))
}
func EditIssue(c *context.APIContext, form api.EditIssueOption) {
type editIssueRequest struct {
Title string `json:"title"`
Body *string `json:"body"`
Assignee *string `json:"assignee"`
Milestone *int64 `json:"milestone"`
State *string `json:"state"`
}
func editIssue(c *context.APIContext, form editIssueRequest) {
issue, err := database.GetIssueByIndex(c.Repo.Repository.ID, c.ParamsInt64(":index"))
if err != nil {
c.NotFoundOrError(err, "get issue by index")
@@ -173,7 +190,7 @@ func EditIssue(c *context.APIContext, form api.EditIssueOption) {
return
}
if form.State != nil {
if err = issue.ChangeStatus(c.User, c.Repo.Repository, api.STATE_CLOSED == api.StateType(*form.State)); err != nil {
if err = issue.ChangeStatus(c.User, c.Repo.Repository, types.IssueStateClosed == types.IssueStateType(*form.State)); err != nil {
c.Error(err, "change status")
return
}
@@ -185,5 +202,5 @@ func EditIssue(c *context.APIContext, form api.EditIssueOption) {
c.Error(err, "get issue by ID")
return
}
c.JSON(http.StatusCreated, issue.APIFormat())
c.JSON(http.StatusCreated, toIssue(issue))
}

View File

@@ -1,16 +1,15 @@
package repo
package v1
import (
"net/http"
"time"
api "github.com/gogs/go-gogs-client"
"gogs.io/gogs/internal/context"
"gogs.io/gogs/internal/database"
"gogs.io/gogs/internal/route/api/v1/types"
)
func ListIssueComments(c *context.APIContext) {
func listIssueComments(c *context.APIContext) {
var since time.Time
if len(c.Query("since")) > 0 {
var err error
@@ -34,14 +33,14 @@ func ListIssueComments(c *context.APIContext) {
return
}
apiComments := make([]*api.Comment, len(comments))
apiComments := make([]*types.IssueComment, len(comments))
for i := range comments {
apiComments[i] = comments[i].APIFormat()
apiComments[i] = toIssueComment(comments[i])
}
c.JSONSuccess(&apiComments)
}
func ListRepoIssueComments(c *context.APIContext) {
func listRepoIssueComments(c *context.APIContext) {
var since time.Time
if len(c.Query("since")) > 0 {
var err error
@@ -58,14 +57,18 @@ func ListRepoIssueComments(c *context.APIContext) {
return
}
apiComments := make([]*api.Comment, len(comments))
apiComments := make([]*types.IssueComment, len(comments))
for i := range comments {
apiComments[i] = comments[i].APIFormat()
apiComments[i] = toIssueComment(comments[i])
}
c.JSONSuccess(&apiComments)
}
func CreateIssueComment(c *context.APIContext, form api.CreateIssueCommentOption) {
type createIssueCommentRequest struct {
Body string `json:"body" binding:"Required"`
}
func createIssueComment(c *context.APIContext, form createIssueCommentRequest) {
issue, err := database.GetIssueByIndex(c.Repo.Repository.ID, c.ParamsInt64(":index"))
if err != nil {
c.Error(err, "get issue by index")
@@ -78,10 +81,14 @@ func CreateIssueComment(c *context.APIContext, form api.CreateIssueCommentOption
return
}
c.JSON(http.StatusCreated, comment.APIFormat())
c.JSON(http.StatusCreated, toIssueComment(comment))
}
func EditIssueComment(c *context.APIContext, form api.EditIssueCommentOption) {
type editIssueCommentRequest struct {
Body string `json:"body" binding:"Required"`
}
func editIssueComment(c *context.APIContext, form editIssueCommentRequest) {
comment, err := database.GetCommentByID(c.ParamsInt64(":id"))
if err != nil {
c.NotFoundOrError(err, "get comment by ID")
@@ -113,10 +120,10 @@ func EditIssueComment(c *context.APIContext, form api.EditIssueCommentOption) {
c.Error(err, "update comment")
return
}
c.JSONSuccess(comment.APIFormat())
c.JSONSuccess(toIssueComment(comment))
}
func DeleteIssueComment(c *context.APIContext) {
func deleteIssueComment(c *context.APIContext) {
comment, err := database.GetCommentByID(c.ParamsInt64(":id"))
if err != nil {
c.NotFoundOrError(err, "get comment by ID")

View File

@@ -1,29 +1,32 @@
package repo
package v1
import (
"net/http"
api "github.com/gogs/go-gogs-client"
"gogs.io/gogs/internal/context"
"gogs.io/gogs/internal/database"
"gogs.io/gogs/internal/route/api/v1/types"
)
func ListIssueLabels(c *context.APIContext) {
func listIssueLabels(c *context.APIContext) {
issue, err := database.GetIssueByIndex(c.Repo.Repository.ID, c.ParamsInt64(":index"))
if err != nil {
c.NotFoundOrError(err, "get issue by index")
return
}
apiLabels := make([]*api.Label, len(issue.Labels))
apiLabels := make([]*types.IssueLabel, len(issue.Labels))
for i := range issue.Labels {
apiLabels[i] = issue.Labels[i].APIFormat()
apiLabels[i] = toIssueLabel(issue.Labels[i])
}
c.JSONSuccess(&apiLabels)
}
func AddIssueLabels(c *context.APIContext, form api.IssueLabelsOption) {
type issueLabelsRequest struct {
Labels []int64 `json:"labels"`
}
func addIssueLabels(c *context.APIContext, form issueLabelsRequest) {
issue, err := database.GetIssueByIndex(c.Repo.Repository.ID, c.ParamsInt64(":index"))
if err != nil {
c.NotFoundOrError(err, "get issue by index")
@@ -47,14 +50,14 @@ func AddIssueLabels(c *context.APIContext, form api.IssueLabelsOption) {
return
}
apiLabels := make([]*api.Label, len(labels))
apiLabels := make([]*types.IssueLabel, len(labels))
for i := range labels {
apiLabels[i] = issue.Labels[i].APIFormat()
apiLabels[i] = toIssueLabel(issue.Labels[i])
}
c.JSONSuccess(&apiLabels)
}
func DeleteIssueLabel(c *context.APIContext) {
func deleteIssueLabel(c *context.APIContext) {
issue, err := database.GetIssueByIndex(c.Repo.Repository.ID, c.ParamsInt64(":index"))
if err != nil {
c.NotFoundOrError(err, "get issue by index")
@@ -79,7 +82,7 @@ func DeleteIssueLabel(c *context.APIContext) {
c.NoContent()
}
func ReplaceIssueLabels(c *context.APIContext, form api.IssueLabelsOption) {
func replaceIssueLabels(c *context.APIContext, form issueLabelsRequest) {
issue, err := database.GetIssueByIndex(c.Repo.Repository.ID, c.ParamsInt64(":index"))
if err != nil {
c.NotFoundOrError(err, "get issue by index")
@@ -103,14 +106,14 @@ func ReplaceIssueLabels(c *context.APIContext, form api.IssueLabelsOption) {
return
}
apiLabels := make([]*api.Label, len(labels))
apiLabels := make([]*types.IssueLabel, len(labels))
for i := range labels {
apiLabels[i] = issue.Labels[i].APIFormat()
apiLabels[i] = toIssueLabel(issue.Labels[i])
}
c.JSONSuccess(&apiLabels)
}
func ClearIssueLabels(c *context.APIContext) {
func clearIssueLabels(c *context.APIContext) {
issue, err := database.GetIssueByIndex(c.Repo.Repository.ID, c.ParamsInt64(":index"))
if err != nil {
c.NotFoundOrError(err, "get issue by index")

View File

@@ -1,15 +1,14 @@
package repo
package v1
import (
"net/http"
"github.com/cockroachdb/errors"
api "github.com/gogs/go-gogs-client"
"gogs.io/gogs/internal/conf"
"gogs.io/gogs/internal/context"
"gogs.io/gogs/internal/database"
"gogs.io/gogs/internal/route/api/v1/convert"
"gogs.io/gogs/internal/route/api/v1/types"
)
func composeDeployKeysAPILink(repoPath string) string {
@@ -17,7 +16,7 @@ func composeDeployKeysAPILink(repoPath string) string {
}
// https://github.com/gogs/go-gogs-client/wiki/Repositories-Deploy-Keys#list-deploy-keys
func ListDeployKeys(c *context.APIContext) {
func listDeployKeys(c *context.APIContext) {
keys, err := database.ListDeployKeys(c.Repo.Repository.ID)
if err != nil {
c.Error(err, "list deploy keys")
@@ -25,20 +24,20 @@ func ListDeployKeys(c *context.APIContext) {
}
apiLink := composeDeployKeysAPILink(c.Repo.Owner.Name + "/" + c.Repo.Repository.Name)
apiKeys := make([]*api.DeployKey, len(keys))
apiKeys := make([]*types.RepositoryDeployKey, len(keys))
for i := range keys {
if err = keys[i].GetContent(); err != nil {
c.Error(err, "get content")
return
}
apiKeys[i] = convert.ToDeployKey(apiLink, keys[i])
apiKeys[i] = toDeployKey(apiLink, keys[i])
}
c.JSONSuccess(&apiKeys)
}
// https://github.com/gogs/go-gogs-client/wiki/Repositories-Deploy-Keys#get-a-deploy-key
func GetDeployKey(c *context.APIContext) {
func getDeployKey(c *context.APIContext) {
key, err := database.GetDeployKeyByID(c.ParamsInt64(":id"))
if err != nil {
c.NotFoundOrError(err, "get deploy key by ID")
@@ -56,10 +55,10 @@ func GetDeployKey(c *context.APIContext) {
}
apiLink := composeDeployKeysAPILink(c.Repo.Owner.Name + "/" + c.Repo.Repository.Name)
c.JSONSuccess(convert.ToDeployKey(apiLink, key))
c.JSONSuccess(toDeployKey(apiLink, key))
}
func HandleCheckKeyStringError(c *context.APIContext, err error) {
func handleCheckKeyStringError(c *context.APIContext, err error) {
if database.IsErrKeyUnableVerify(err) {
c.ErrorStatus(http.StatusUnprocessableEntity, errors.New("Unable to verify key content"))
} else {
@@ -67,7 +66,7 @@ func HandleCheckKeyStringError(c *context.APIContext, err error) {
}
}
func HandleAddKeyError(c *context.APIContext, err error) {
func handleAddKeyError(c *context.APIContext, err error) {
switch {
case database.IsErrKeyAlreadyExist(err):
c.ErrorStatus(http.StatusUnprocessableEntity, errors.New("Key content has been used as non-deploy key"))
@@ -79,26 +78,31 @@ func HandleAddKeyError(c *context.APIContext, err error) {
}
// https://github.com/gogs/go-gogs-client/wiki/Repositories-Deploy-Keys#add-a-new-deploy-key
func CreateDeployKey(c *context.APIContext, form api.CreateKeyOption) {
type createDeployKeyRequest struct {
Title string `json:"title" binding:"Required"`
Key string `json:"key" binding:"Required"`
}
func createDeployKey(c *context.APIContext, form createDeployKeyRequest) {
content, err := database.CheckPublicKeyString(form.Key)
if err != nil {
HandleCheckKeyStringError(c, err)
handleCheckKeyStringError(c, err)
return
}
key, err := database.AddDeployKey(c.Repo.Repository.ID, form.Title, content)
if err != nil {
HandleAddKeyError(c, err)
handleAddKeyError(c, err)
return
}
key.Content = content
apiLink := composeDeployKeysAPILink(c.Repo.Owner.Name + "/" + c.Repo.Repository.Name)
c.JSON(http.StatusCreated, convert.ToDeployKey(apiLink, key))
c.JSON(http.StatusCreated, toDeployKey(apiLink, key))
}
// https://github.com/gogs/go-gogs-client/wiki/Repositories-Deploy-Keys#remove-a-deploy-key
func DeleteDeploykey(c *context.APIContext) {
func deleteDeploykey(c *context.APIContext) {
key, err := database.GetDeployKeyByID(c.ParamsInt64(":id"))
if err != nil {
c.NotFoundOrError(err, "get deploy key by ID")

View File

@@ -1,30 +1,29 @@
package repo
package v1
import (
"net/http"
"strconv"
api "github.com/gogs/go-gogs-client"
"gogs.io/gogs/internal/context"
"gogs.io/gogs/internal/database"
"gogs.io/gogs/internal/route/api/v1/types"
)
func ListLabels(c *context.APIContext) {
func listLabels(c *context.APIContext) {
labels, err := database.GetLabelsByRepoID(c.Repo.Repository.ID)
if err != nil {
c.Error(err, "get labels by repository ID")
return
}
apiLabels := make([]*api.Label, len(labels))
apiLabels := make([]*types.IssueLabel, len(labels))
for i := range labels {
apiLabels[i] = labels[i].APIFormat()
apiLabels[i] = toIssueLabel(labels[i])
}
c.JSONSuccess(&apiLabels)
}
func GetLabel(c *context.APIContext) {
func getLabel(c *context.APIContext) {
var label *database.Label
var err error
idStr := c.Params(":id")
@@ -38,10 +37,15 @@ func GetLabel(c *context.APIContext) {
return
}
c.JSONSuccess(label.APIFormat())
c.JSONSuccess(toIssueLabel(label))
}
func CreateLabel(c *context.APIContext, form api.CreateLabelOption) {
type createLabelRequest struct {
Name string `json:"name" binding:"Required"`
Color string `json:"color" binding:"Required;Size(7)"`
}
func createLabel(c *context.APIContext, form createLabelRequest) {
label := &database.Label{
Name: form.Name,
Color: form.Color,
@@ -51,10 +55,15 @@ func CreateLabel(c *context.APIContext, form api.CreateLabelOption) {
c.Error(err, "new labels")
return
}
c.JSON(http.StatusCreated, label.APIFormat())
c.JSON(http.StatusCreated, toIssueLabel(label))
}
func EditLabel(c *context.APIContext, form api.EditLabelOption) {
type editLabelRequest struct {
Name *string `json:"name"`
Color *string `json:"color"`
}
func editLabel(c *context.APIContext, form editLabelRequest) {
label, err := database.GetLabelOfRepoByID(c.Repo.Repository.ID, c.ParamsInt64(":id"))
if err != nil {
c.NotFoundOrError(err, "get label of repository by ID")
@@ -71,10 +80,10 @@ func EditLabel(c *context.APIContext, form api.EditLabelOption) {
c.Error(err, "update label")
return
}
c.JSONSuccess(label.APIFormat())
c.JSONSuccess(toIssueLabel(label))
}
func DeleteLabel(c *context.APIContext) {
func deleteLabel(c *context.APIContext) {
if err := database.DeleteLabel(c.Repo.Repository.ID, c.ParamsInt64(":id")); err != nil {
c.Error(err, "delete label")
return

View File

@@ -1,39 +1,44 @@
package repo
package v1
import (
"net/http"
"time"
api "github.com/gogs/go-gogs-client"
"gogs.io/gogs/internal/context"
"gogs.io/gogs/internal/database"
"gogs.io/gogs/internal/route/api/v1/types"
)
func ListMilestones(c *context.APIContext) {
func listMilestones(c *context.APIContext) {
milestones, err := database.GetMilestonesByRepoID(c.Repo.Repository.ID)
if err != nil {
c.Error(err, "get milestones by repository ID")
return
}
apiMilestones := make([]*api.Milestone, len(milestones))
apiMilestones := make([]*types.IssueMilestone, len(milestones))
for i := range milestones {
apiMilestones[i] = milestones[i].APIFormat()
apiMilestones[i] = toIssueMilestone(milestones[i])
}
c.JSONSuccess(&apiMilestones)
}
func GetMilestone(c *context.APIContext) {
func getMilestone(c *context.APIContext) {
milestone, err := database.GetMilestoneByRepoID(c.Repo.Repository.ID, c.ParamsInt64(":id"))
if err != nil {
c.NotFoundOrError(err, "get milestone by repository ID")
return
}
c.JSONSuccess(milestone.APIFormat())
c.JSONSuccess(toIssueMilestone(milestone))
}
func CreateMilestone(c *context.APIContext, form api.CreateMilestoneOption) {
type createMilestoneRequest struct {
Title string `json:"title"`
Description string `json:"description"`
Deadline *time.Time `json:"due_on"`
}
func createMilestone(c *context.APIContext, form createMilestoneRequest) {
if form.Deadline == nil {
defaultDeadline, _ := time.ParseInLocation("2006-01-02", "9999-12-31", time.Local)
form.Deadline = &defaultDeadline
@@ -50,10 +55,17 @@ func CreateMilestone(c *context.APIContext, form api.CreateMilestoneOption) {
c.Error(err, "new milestone")
return
}
c.JSON(http.StatusCreated, milestone.APIFormat())
c.JSON(http.StatusCreated, toIssueMilestone(milestone))
}
func EditMilestone(c *context.APIContext, form api.EditMilestoneOption) {
type editMilestoneRequest struct {
Title string `json:"title"`
Description *string `json:"description"`
State *string `json:"state"`
Deadline *time.Time `json:"due_on"`
}
func editMilestone(c *context.APIContext, form editMilestoneRequest) {
milestone, err := database.GetMilestoneByRepoID(c.Repo.Repository.ID, c.ParamsInt64(":id"))
if err != nil {
c.NotFoundOrError(err, "get milestone by repository ID")
@@ -71,7 +83,7 @@ func EditMilestone(c *context.APIContext, form api.EditMilestoneOption) {
}
if form.State != nil {
if err = milestone.ChangeStatus(api.STATE_CLOSED == api.StateType(*form.State)); err != nil {
if err = milestone.ChangeStatus(types.IssueStateClosed == types.IssueStateType(*form.State)); err != nil {
c.Error(err, "change status")
return
}
@@ -80,10 +92,10 @@ func EditMilestone(c *context.APIContext, form api.EditMilestoneOption) {
return
}
c.JSONSuccess(milestone.APIFormat())
c.JSONSuccess(toIssueMilestone(milestone))
}
func DeleteMilestone(c *context.APIContext) {
func deleteMilestone(c *context.APIContext) {
if err := database.DeleteMilestoneOfRepoByID(c.Repo.Repository.ID, c.ParamsInt64(":id")); err != nil {
c.Error(err, "delete milestone of repository by ID")
return

View File

@@ -1,25 +1,24 @@
package repo
package v1
import (
"net/http"
"path"
"github.com/cockroachdb/errors"
api "github.com/gogs/go-gogs-client"
log "unknwon.dev/clog/v2"
"gogs.io/gogs/internal/conf"
"gogs.io/gogs/internal/context"
"gogs.io/gogs/internal/database"
"gogs.io/gogs/internal/form"
"gogs.io/gogs/internal/route/api/v1/convert"
"gogs.io/gogs/internal/route/api/v1/types"
)
func Search(c *context.APIContext) {
func searchRepos(c *context.APIContext) {
opts := &database.SearchRepoOptions{
Keyword: path.Base(c.Query("q")),
OwnerID: c.QueryInt64("uid"),
PageSize: convert.ToCorrectPageSize(c.QueryInt("limit")),
PageSize: toAllowedPageSize(c.QueryInt("limit")),
Page: c.QueryInt("page"),
}
@@ -60,9 +59,9 @@ func Search(c *context.APIContext) {
return
}
results := make([]*api.Repository, len(repos))
results := make([]*types.Repository, len(repos))
for i := range repos {
results[i] = repos[i].APIFormatLegacy(nil)
results[i] = toRepository(repos[i], nil)
}
c.SetLinkHeader(int(count), opts.PageSize)
@@ -72,7 +71,7 @@ func Search(c *context.APIContext) {
})
}
func listUserRepositories(c *context.APIContext, username string) {
func listReposOfUser(c *context.APIContext, username string) {
user, err := database.Handle.Users().GetByUsername(c.Req.Context(), username)
if err != nil {
c.NotFoundOrError(err, "get user by name")
@@ -104,9 +103,9 @@ func listUserRepositories(c *context.APIContext, username string) {
// Early return for querying other user's repositories
if c.User.ID != user.ID {
repos := make([]*api.Repository, len(ownRepos))
repos := make([]*types.Repository, len(ownRepos))
for i := range ownRepos {
repos[i] = ownRepos[i].APIFormatLegacy(&api.Permission{Admin: true, Push: true, Pull: true})
repos[i] = toRepository(ownRepos[i], &types.RepositoryPermission{Admin: true, Push: true, Pull: true})
}
c.JSONSuccess(&repos)
return
@@ -128,14 +127,14 @@ func listUserRepositories(c *context.APIContext, username string) {
}
numOwnRepos := len(ownRepos)
repos := make([]*api.Repository, 0, numOwnRepos+len(accessibleReposWithAccessMode))
repos := make([]*types.Repository, 0, numOwnRepos+len(accessibleReposWithAccessMode))
for _, r := range ownRepos {
repos = append(repos, r.APIFormatLegacy(&api.Permission{Admin: true, Push: true, Pull: true}))
repos = append(repos, toRepository(r, &types.RepositoryPermission{Admin: true, Push: true, Pull: true}))
}
for repo, access := range accessibleReposWithAccessMode {
repos = append(repos,
repo.APIFormatLegacy(&api.Permission{
toRepository(repo, &types.RepositoryPermission{
Admin: access >= database.AccessModeAdmin,
Push: access >= database.AccessModeWrite,
Pull: true,
@@ -146,19 +145,29 @@ func listUserRepositories(c *context.APIContext, username string) {
c.JSONSuccess(&repos)
}
func ListMyRepos(c *context.APIContext) {
listUserRepositories(c, c.User.Name)
func listMyRepos(c *context.APIContext) {
listReposOfUser(c, c.User.Name)
}
func ListUserRepositories(c *context.APIContext) {
listUserRepositories(c, c.Params(":username"))
func listUserRepositories(c *context.APIContext) {
listReposOfUser(c, c.Params(":username"))
}
func ListOrgRepositories(c *context.APIContext) {
listUserRepositories(c, c.Params(":org"))
func listOrgRepositories(c *context.APIContext) {
listReposOfUser(c, c.Params(":org"))
}
func CreateUserRepo(c *context.APIContext, owner *database.User, opt api.CreateRepoOption) {
type createRepoRequest struct {
Name string `json:"name" binding:"Required;AlphaDashDot;MaxSize(100)"`
Description string `json:"description" binding:"MaxSize(255)"`
Private bool `json:"private"`
AutoInit bool `json:"auto_init"`
Gitignores string `json:"gitignores"`
License string `json:"license"`
Readme string `json:"readme"`
}
func createUserRepo(c *context.APIContext, owner *database.User, opt createRepoRequest) {
repo, err := database.CreateRepository(c.User, owner, database.CreateRepoOptionsLegacy{
Name: opt.Name,
Description: opt.Description,
@@ -183,19 +192,19 @@ func CreateUserRepo(c *context.APIContext, owner *database.User, opt api.CreateR
return
}
c.JSON(201, repo.APIFormatLegacy(&api.Permission{Admin: true, Push: true, Pull: true}))
c.JSON(201, toRepository(repo, &types.RepositoryPermission{Admin: true, Push: true, Pull: true}))
}
func Create(c *context.APIContext, opt api.CreateRepoOption) {
func createRepo(c *context.APIContext, opt createRepoRequest) {
// Shouldn't reach this condition, but just in case.
if c.User.IsOrganization() {
c.ErrorStatus(http.StatusUnprocessableEntity, errors.New("Not allowed to create repository for organization."))
return
}
CreateUserRepo(c, c.User, opt)
createUserRepo(c, c.User, opt)
}
func CreateOrgRepo(c *context.APIContext, opt api.CreateRepoOption) {
func createOrgRepo(c *context.APIContext, opt createRepoRequest) {
org, err := database.GetOrgByName(c.Params(":org"))
if err != nil {
c.NotFoundOrError(err, "get organization by name")
@@ -206,10 +215,10 @@ func CreateOrgRepo(c *context.APIContext, opt api.CreateRepoOption) {
c.ErrorStatus(http.StatusForbidden, errors.New("Given user is not owner of organization."))
return
}
CreateUserRepo(c, org, opt)
createUserRepo(c, org, opt)
}
func Migrate(c *context.APIContext, f form.MigrateRepo) {
func migrate(c *context.APIContext, f form.MigrateRepo) {
ctxUser := c.User
// Not equal means context user is an organization,
// or is another user/organization if current user is admin.
@@ -287,7 +296,7 @@ func Migrate(c *context.APIContext, f form.MigrateRepo) {
}
log.Trace("Repository migrated: %s/%s", ctxUser.Name, f.RepoName)
c.JSON(201, repo.APIFormatLegacy(&api.Permission{Admin: true, Push: true, Pull: true}))
c.JSON(201, toRepository(repo, &types.RepositoryPermission{Admin: true, Push: true, Pull: true}))
}
// FIXME: inject in the handler chain
@@ -311,20 +320,20 @@ func parseOwnerAndRepo(c *context.APIContext) (*database.User, *database.Reposit
return owner, repo
}
func Get(c *context.APIContext) {
func getRepo(c *context.APIContext) {
_, repo := parseOwnerAndRepo(c)
if c.Written() {
return
}
c.JSONSuccess(repo.APIFormatLegacy(&api.Permission{
c.JSONSuccess(toRepository(repo, &types.RepositoryPermission{
Admin: c.Repo.IsAdmin(),
Push: c.Repo.IsWriter(),
Pull: true,
}))
}
func Delete(c *context.APIContext) {
func deleteRepo(c *context.APIContext) {
owner, repo := parseOwnerAndRepo(c)
if c.Written() {
return
@@ -344,14 +353,14 @@ func Delete(c *context.APIContext) {
c.NoContent()
}
func ListForks(c *context.APIContext) {
func listForks(c *context.APIContext) {
forks, err := c.Repo.Repository.GetForks()
if err != nil {
c.Error(err, "get forks")
return
}
apiForks := make([]*api.Repository, len(forks))
apiForks := make([]*types.Repository, len(forks))
for i := range forks {
if err := forks[i].GetOwner(); err != nil {
c.Error(err, "get owner")
@@ -368,8 +377,8 @@ func ListForks(c *context.APIContext) {
},
)
apiForks[i] = forks[i].APIFormatLegacy(
&api.Permission{
apiForks[i] = toRepository(forks[i],
&types.RepositoryPermission{
Admin: accessMode >= database.AccessModeAdmin,
Push: accessMode >= database.AccessModeWrite,
Pull: true,
@@ -380,7 +389,15 @@ func ListForks(c *context.APIContext) {
c.JSONSuccess(&apiForks)
}
func IssueTracker(c *context.APIContext, form api.EditIssueTrackerOption) {
type editIssueTrackerRequest struct {
EnableIssues *bool `json:"enable_issues"`
EnableExternalTracker *bool `json:"enable_external_tracker"`
ExternalTrackerURL *string `json:"external_tracker_url"`
TrackerURLFormat *string `json:"tracker_url_format"`
TrackerIssueStyle *string `json:"tracker_issue_style"`
}
func issueTracker(c *context.APIContext, form editIssueTrackerRequest) {
_, repo := parseOwnerAndRepo(c)
if c.Written() {
return
@@ -410,7 +427,14 @@ func IssueTracker(c *context.APIContext, form api.EditIssueTrackerOption) {
c.NoContent()
}
func Wiki(c *context.APIContext, form api.EditWikiOption) {
type editWikiRequest struct {
EnableWiki *bool `json:"enable_wiki"`
AllowPublicWiki *bool `json:"allow_public_wiki"`
EnableExternalWiki *bool `json:"enable_external_wiki"`
ExternalWikiURL *string `json:"external_wiki_url"`
}
func wiki(c *context.APIContext, form editWikiRequest) {
_, repo := parseOwnerAndRepo(c)
if c.Written() {
return
@@ -436,7 +460,7 @@ func Wiki(c *context.APIContext, form api.EditWikiOption) {
c.NoContent()
}
func MirrorSync(c *context.APIContext) {
func mirrorSync(c *context.APIContext) {
_, repo := parseOwnerAndRepo(c)
if c.Written() {
return
@@ -449,14 +473,14 @@ func MirrorSync(c *context.APIContext) {
c.Status(http.StatusAccepted)
}
func Releases(c *context.APIContext) {
func releases(c *context.APIContext) {
_, repo := parseOwnerAndRepo(c)
releases, err := database.GetReleasesByRepoID(repo.ID)
if err != nil {
c.Error(err, "get releases by repository ID")
return
}
apiReleases := make([]*api.Release, 0, len(releases))
apiReleases := make([]*types.RepositoryRelease, 0, len(releases))
for _, r := range releases {
publisher, err := database.Handle.Users().GetByID(c.Req.Context(), r.PublisherID)
if err != nil {
@@ -466,7 +490,7 @@ func Releases(c *context.APIContext) {
r.Publisher = publisher
}
for _, r := range releases {
apiReleases = append(apiReleases, r.APIFormat())
apiReleases = append(apiReleases, toRelease(r))
}
c.JSONSuccess(&apiReleases)

View File

@@ -1,25 +1,24 @@
package repo
package v1
import (
"gogs.io/gogs/internal/context"
"gogs.io/gogs/internal/route/api/v1/convert"
)
func ListTags(c *context.APIContext) {
func listTags(c *context.APIContext) {
tags, err := c.Repo.Repository.GetTags()
if err != nil {
c.Error(err, "get tags")
return
}
apiTags := make([]*convert.Tag, len(tags))
apiTags := make([]*tag, len(tags))
for i := range tags {
commit, err := tags[i].GetCommit()
if err != nil {
c.Error(err, "get commit")
return
}
apiTags[i] = convert.ToTag(tags[i], commit)
apiTags[i] = toTag(tags[i], commit)
}
c.JSONSuccess(&apiTags)

View File

@@ -1,4 +1,4 @@
package repo
package v1
import (
"fmt"
@@ -9,7 +9,7 @@ import (
"gogs.io/gogs/internal/gitutil"
)
func GetRepoGitTree(c *context.APIContext) {
func getRepoGitTree(c *context.APIContext) {
gitRepo, err := git.Open(c.Repo.Repository.RepoPath())
if err != nil {
c.Error(err, "open repository")

View File

@@ -0,0 +1,8 @@
package v1
import "gogs.io/gogs/internal/route/api/v1/types"
type tag struct {
Name string `json:"name"`
Commit *types.WebhookPayloadCommit `json:"commit"`
}

View File

@@ -0,0 +1,29 @@
package types
type CommitMeta struct {
URL string `json:"url"`
SHA string `json:"sha"`
}
type CommitUser struct {
Name string `json:"name"`
Email string `json:"email"`
Date string `json:"date"`
}
type RepoCommit struct {
URL string `json:"url"`
Author *CommitUser `json:"author"`
Committer *CommitUser `json:"committer"`
Message string `json:"message"`
Tree *CommitMeta `json:"tree"`
}
type Commit struct {
*CommitMeta
HTMLURL string `json:"html_url"`
RepoCommit *RepoCommit `json:"commit"`
Author *User `json:"author"`
Committer *User `json:"committer"`
Parents []*CommitMeta `json:"parents"`
}

View File

@@ -0,0 +1,23 @@
package types
import "time"
type RepositoryHook struct {
ID int64 `json:"id"`
Type string `json:"type"`
URL string `json:"-"`
Config map[string]string `json:"config"`
Events []string `json:"events"`
Active bool `json:"active"`
Updated time.Time `json:"updated_at"`
Created time.Time `json:"created_at"`
}
type RepositoryDeployKey struct {
ID int64 `json:"id"`
Key string `json:"key"`
URL string `json:"url"`
Title string `json:"title"`
Created time.Time `json:"created_at"`
ReadOnly bool `json:"read_only"`
}

View File

@@ -0,0 +1,58 @@
package types
import "time"
type IssueStateType string
const (
IssueStateOpen IssueStateType = "open"
IssueStateClosed IssueStateType = "closed"
)
type PullRequestMeta struct {
HasMerged bool `json:"merged"`
Merged *time.Time `json:"merged_at"`
}
type Issue struct {
ID int64 `json:"id"`
Index int64 `json:"number"`
Poster *User `json:"user"`
Title string `json:"title"`
Body string `json:"body"`
Labels []*IssueLabel `json:"labels"`
Milestone *IssueMilestone `json:"milestone"`
Assignee *User `json:"assignee"`
State IssueStateType `json:"state"`
Comments int `json:"comments"`
Created time.Time `json:"created_at"`
Updated time.Time `json:"updated_at"`
PullRequest *PullRequestMeta `json:"pull_request"`
}
type IssueLabel struct {
ID int64 `json:"id"`
Name string `json:"name"`
Color string `json:"color"`
URL string `json:"url"`
}
type IssueMilestone struct {
ID int64 `json:"id"`
Title string `json:"title"`
Description string `json:"description"`
State IssueStateType `json:"state"`
OpenIssues int `json:"open_issues"`
ClosedIssues int `json:"closed_issues"`
Closed *time.Time `json:"closed_at"`
Deadline *time.Time `json:"due_on"`
}
type IssueComment struct {
ID int64 `json:"id"`
HTMLURL string `json:"html_url"`
Poster *User `json:"user"`
Body string `json:"body"`
Created time.Time `json:"created_at"`
Updated time.Time `json:"updated_at"`
}

View File

@@ -0,0 +1,18 @@
package types
type Organization struct {
ID int64 `json:"id"`
UserName string `json:"username"`
FullName string `json:"full_name"`
AvatarURL string `json:"avatar_url"`
Description string `json:"description"`
Website string `json:"website"`
Location string `json:"location"`
}
type OrganizationTeam struct {
ID int64 `json:"id"`
Name string `json:"name"`
Description string `json:"description"`
Permission string `json:"permission"`
}

View File

@@ -0,0 +1,26 @@
package types
import "time"
type PullRequest struct {
ID int64 `json:"id"`
Index int64 `json:"number"`
Poster *User `json:"user"`
Title string `json:"title"`
Body string `json:"body"`
Labels []*IssueLabel `json:"labels"`
Milestone *IssueMilestone `json:"milestone"`
Assignee *User `json:"assignee"`
State IssueStateType `json:"state"`
Comments int `json:"comments"`
HeadBranch string `json:"head_branch"`
HeadRepo *Repository `json:"head_repo"`
BaseBranch string `json:"base_branch"`
BaseRepo *Repository `json:"base_repo"`
HTMLURL string `json:"html_url"`
Mergeable *bool `json:"mergeable"`
HasMerged bool `json:"merged"`
Merged *time.Time `json:"merged_at"`
MergedCommitID *string `json:"merge_commit_sha"`
MergedBy *User `json:"merged_by"`
}

View File

@@ -0,0 +1,52 @@
package types
import "time"
type RepositoryPermission struct {
Admin bool `json:"admin"`
Push bool `json:"push"`
Pull bool `json:"pull"`
}
type Repository struct {
ID int64 `json:"id"`
Owner *User `json:"owner"`
Name string `json:"name"`
FullName string `json:"full_name"`
Description string `json:"description"`
Private bool `json:"private"`
Fork bool `json:"fork"`
Parent *Repository `json:"parent"`
Empty bool `json:"empty"`
Mirror bool `json:"mirror"`
Size int64 `json:"size"`
HTMLURL string `json:"html_url"`
SSHURL string `json:"ssh_url"`
CloneURL string `json:"clone_url"`
Website string `json:"website"`
Stars int `json:"stars_count"`
Forks int `json:"forks_count"`
Watchers int `json:"watchers_count"`
OpenIssues int `json:"open_issues_count"`
DefaultBranch string `json:"default_branch"`
Created time.Time `json:"created_at"`
Updated time.Time `json:"updated_at"`
Permissions *RepositoryPermission `json:"permissions,omitempty"`
}
type RepositoryBranch struct {
Name string `json:"name"`
Commit *WebhookPayloadCommit `json:"commit"`
}
type RepositoryRelease struct {
ID int64 `json:"id"`
TagName string `json:"tag_name"`
TargetCommitish string `json:"target_commitish"`
Name string `json:"name"`
Body string `json:"body"`
Draft bool `json:"draft"`
Prerelease bool `json:"prerelease"`
Author *User `json:"author"`
Created time.Time `json:"created_at"`
}

View File

@@ -0,0 +1,36 @@
package types
import "time"
type User struct {
ID int64 `json:"id"`
UserName string `json:"username"`
Login string `json:"login"`
FullName string `json:"full_name"`
Email string `json:"email"`
AvatarURL string `json:"avatar_url"`
}
type UserEmail struct {
Email string `json:"email"`
Verified bool `json:"verified"`
Primary bool `json:"primary"`
}
type UserAccessToken struct {
Name string `json:"name"`
Sha1 string `json:"sha1"`
}
type UserPublicKey struct {
ID int64 `json:"id"`
Key string `json:"key"`
URL string `json:"url,omitempty"`
Title string `json:"title,omitempty"`
Created time.Time `json:"created_at,omitempty"`
}
type RepositoryCollaborator struct {
*User
Permissions RepositoryPermission `json:"permissions"`
}

View File

@@ -0,0 +1,158 @@
package types
import (
"encoding/json"
"time"
)
// WebhookPayloader is implemented by webhook payload types.
type WebhookPayloader interface {
JSONPayload() ([]byte, error)
}
func jsonPayload(p any) ([]byte, error) {
return json.MarshalIndent(p, "", " ")
}
type WebhookPayloadUser struct {
Name string `json:"name"`
Email string `json:"email"`
UserName string `json:"username"`
}
type WebhookPayloadCommit struct {
ID string `json:"id"`
Message string `json:"message"`
URL string `json:"url"`
Author *WebhookPayloadUser `json:"author"`
Committer *WebhookPayloadUser `json:"committer"`
Added []string `json:"added"`
Removed []string `json:"removed"`
Modified []string `json:"modified"`
Timestamp time.Time `json:"timestamp"`
}
type WebhookPusherType string
const WebhookPusherTypeUser WebhookPusherType = "user"
type WebhookIssueAction string
const (
WebhookIssueOpened WebhookIssueAction = "opened"
WebhookIssueClosed WebhookIssueAction = "closed"
WebhookIssueReopened WebhookIssueAction = "reopened"
WebhookIssueEdited WebhookIssueAction = "edited"
WebhookIssueAssigned WebhookIssueAction = "assigned"
WebhookIssueUnassigned WebhookIssueAction = "unassigned"
WebhookIssueLabelUpdated WebhookIssueAction = "label_updated"
WebhookIssueLabelCleared WebhookIssueAction = "label_cleared"
WebhookIssueMilestoned WebhookIssueAction = "milestoned"
WebhookIssueDemilestoned WebhookIssueAction = "demilestoned"
WebhookIssueSynchronized WebhookIssueAction = "synchronized"
)
type WebhookIssueCommentAction string
const (
WebhookIssueCommentCreated WebhookIssueCommentAction = "created"
WebhookIssueCommentEdited WebhookIssueCommentAction = "edited"
WebhookIssueCommentDeleted WebhookIssueCommentAction = "deleted"
)
type WebhookReleaseAction string
const WebhookReleasePublished WebhookReleaseAction = "published"
type WebhookChangesFromPayload struct {
From string `json:"from"`
}
type WebhookChangesPayload struct {
Title *WebhookChangesFromPayload `json:"title,omitempty"`
Body *WebhookChangesFromPayload `json:"body,omitempty"`
}
type WebhookCreatePayload struct {
Ref string `json:"ref"`
RefType string `json:"ref_type"`
Sha string `json:"sha"`
DefaultBranch string `json:"default_branch"`
Repo *Repository `json:"repository"`
Sender *User `json:"sender"`
}
func (p *WebhookCreatePayload) JSONPayload() ([]byte, error) { return jsonPayload(p) }
type WebhookDeletePayload struct {
Ref string `json:"ref"`
RefType string `json:"ref_type"`
PusherType WebhookPusherType `json:"pusher_type"`
Repo *Repository `json:"repository"`
Sender *User `json:"sender"`
}
func (p *WebhookDeletePayload) JSONPayload() ([]byte, error) { return jsonPayload(p) }
type WebhookForkPayload struct {
Forkee *Repository `json:"forkee"`
Repo *Repository `json:"repository"`
Sender *User `json:"sender"`
}
func (p *WebhookForkPayload) JSONPayload() ([]byte, error) { return jsonPayload(p) }
type WebhookPushPayload struct {
Ref string `json:"ref"`
Before string `json:"before"`
After string `json:"after"`
CompareURL string `json:"compare_url"`
Commits []*WebhookPayloadCommit `json:"commits"`
Repo *Repository `json:"repository"`
Pusher *User `json:"pusher"`
Sender *User `json:"sender"`
}
func (p *WebhookPushPayload) JSONPayload() ([]byte, error) { return jsonPayload(p) }
type WebhookIssuesPayload struct {
Action WebhookIssueAction `json:"action"`
Index int64 `json:"number"`
Issue *Issue `json:"issue"`
Changes *WebhookChangesPayload `json:"changes,omitempty"`
Repository *Repository `json:"repository"`
Sender *User `json:"sender"`
}
func (p *WebhookIssuesPayload) JSONPayload() ([]byte, error) { return jsonPayload(p) }
type WebhookIssueCommentPayload struct {
Action WebhookIssueCommentAction `json:"action"`
Issue *Issue `json:"issue"`
Comment *IssueComment `json:"comment"`
Changes *WebhookChangesPayload `json:"changes,omitempty"`
Repository *Repository `json:"repository"`
Sender *User `json:"sender"`
}
func (p *WebhookIssueCommentPayload) JSONPayload() ([]byte, error) { return jsonPayload(p) }
type WebhookPullRequestPayload struct {
Action WebhookIssueAction `json:"action"`
Index int64 `json:"number"`
PullRequest *PullRequest `json:"pull_request"`
Changes *WebhookChangesPayload `json:"changes,omitempty"`
Repository *Repository `json:"repository"`
Sender *User `json:"sender"`
}
func (p *WebhookPullRequestPayload) JSONPayload() ([]byte, error) { return jsonPayload(p) }
type WebhookReleasePayload struct {
Action WebhookReleaseAction `json:"action"`
Release *RepositoryRelease `json:"release"`
Repository *Repository `json:"repository"`
Sender *User `json:"sender"`
}
func (p *WebhookReleasePayload) JSONPayload() ([]byte, error) { return jsonPayload(p) }

View File

@@ -1,16 +1,14 @@
package user
package v1
import (
"net/http"
api "github.com/gogs/go-gogs-client"
"gogs.io/gogs/internal/context"
"gogs.io/gogs/internal/database"
"gogs.io/gogs/internal/markup"
"gogs.io/gogs/internal/route/api/v1/types"
)
func Search(c *context.APIContext) {
func searchUsers(c *context.APIContext) {
pageSize := c.QueryInt("limit")
if pageSize <= 0 {
pageSize = 10
@@ -24,16 +22,11 @@ func Search(c *context.APIContext) {
return
}
results := make([]*api.User, len(users))
results := make([]*types.User, len(users))
for i := range users {
results[i] = &api.User{
ID: users[i].ID,
UserName: users[i].Name,
AvatarUrl: users[i].AvatarURL(),
FullName: markup.Sanitize(users[i].FullName),
}
if c.IsLogged {
results[i].Email = users[i].Email
results[i] = toUser(users[i])
if !c.IsLogged {
results[i].Email = ""
}
}
@@ -43,7 +36,7 @@ func Search(c *context.APIContext) {
})
}
func GetInfo(c *context.APIContext) {
func getUserProfile(c *context.APIContext) {
u, err := database.Handle.Users().GetByUsername(c.Req.Context(), c.Params(":username"))
if err != nil {
c.NotFoundOrError(err, "get user by name")
@@ -54,9 +47,9 @@ func GetInfo(c *context.APIContext) {
if !c.IsLogged {
u.Email = ""
}
c.JSONSuccess(u.APIFormat())
c.JSONSuccess(toUser(u))
}
func GetAuthenticatedUser(c *context.APIContext) {
c.JSONSuccess(c.User.APIFormat())
func getAuthenticatedUser(c *context.APIContext) {
c.JSONSuccess(toUser(c.User))
}

View File

@@ -1,30 +1,30 @@
package user
package v1
import (
gocontext "context"
"net/http"
api "github.com/gogs/go-gogs-client"
"gopkg.in/macaron.v1"
"gogs.io/gogs/internal/context"
"gogs.io/gogs/internal/database"
"gogs.io/gogs/internal/route/api/v1/types"
)
// AccessTokensHandler is the handler for users access tokens API endpoints.
type AccessTokensHandler struct {
// accessTokensHandler is the handler for users access tokens API endpoints.
type accessTokensHandler struct {
store AccessTokensStore
}
// NewAccessTokensHandler returns a new AccessTokensHandler for users access
// newAccessTokensHandler returns a new accessTokensHandler for users access
// tokens API endpoints.
func NewAccessTokensHandler(s AccessTokensStore) *AccessTokensHandler {
return &AccessTokensHandler{
func newAccessTokensHandler(s AccessTokensStore) *accessTokensHandler {
return &accessTokensHandler{
store: s,
}
}
func (h *AccessTokensHandler) List() macaron.Handler {
func (h *accessTokensHandler) List() macaron.Handler {
return func(c *context.APIContext) {
tokens, err := h.store.ListAccessTokens(c.Req.Context(), c.User.ID)
if err != nil {
@@ -32,16 +32,23 @@ func (h *AccessTokensHandler) List() macaron.Handler {
return
}
apiTokens := make([]*api.AccessToken, len(tokens))
apiTokens := make([]*types.UserAccessToken, len(tokens))
for i := range tokens {
apiTokens[i] = &api.AccessToken{Name: tokens[i].Name, Sha1: tokens[i].Sha1}
apiTokens[i] = &types.UserAccessToken{
Name: tokens[i].Name,
Sha1: tokens[i].Sha1,
}
}
c.JSONSuccess(&apiTokens)
}
}
func (h *AccessTokensHandler) Create() macaron.Handler {
return func(c *context.APIContext, form api.CreateAccessTokenOption) {
type createAccessTokenRequest struct {
Name string `json:"name" binding:"Required"`
}
func (h *accessTokensHandler) Create() macaron.Handler {
return func(c *context.APIContext, form createAccessTokenRequest) {
t, err := h.store.CreateAccessToken(c.Req.Context(), c.User.ID, form.Name)
if err != nil {
if database.IsErrAccessTokenAlreadyExist(err) {
@@ -51,7 +58,10 @@ func (h *AccessTokensHandler) Create() macaron.Handler {
}
return
}
c.JSON(http.StatusCreated, &api.AccessToken{Name: t.Name, Sha1: t.Sha1})
c.JSON(http.StatusCreated, &types.UserAccessToken{
Name: t.Name,
Sha1: t.Sha1,
})
}
}
@@ -69,9 +79,9 @@ type AccessTokensStore interface {
type accessTokensStore struct{}
// NewAccessTokensStore returns a new AccessTokensStore using the global
// newAccessTokensStore returns a new AccessTokensStore using the global
// database handle.
func NewAccessTokensStore() AccessTokensStore {
func newAccessTokensStore() AccessTokensStore {
return &accessTokensStore{}
}

View File

@@ -1,37 +1,40 @@
package user
package v1
import (
"net/http"
"github.com/cockroachdb/errors"
api "github.com/gogs/go-gogs-client"
"gogs.io/gogs/internal/conf"
"gogs.io/gogs/internal/context"
"gogs.io/gogs/internal/database"
"gogs.io/gogs/internal/route/api/v1/convert"
"gogs.io/gogs/internal/route/api/v1/types"
)
func ListEmails(c *context.APIContext) {
func listEmails(c *context.APIContext) {
emails, err := database.Handle.Users().ListEmails(c.Req.Context(), c.User.ID)
if err != nil {
c.Error(err, "get email addresses")
return
}
apiEmails := make([]*api.Email, len(emails))
apiEmails := make([]*types.UserEmail, len(emails))
for i := range emails {
apiEmails[i] = convert.ToEmail(emails[i])
apiEmails[i] = toUserEmail(emails[i])
}
c.JSONSuccess(&apiEmails)
}
func AddEmail(c *context.APIContext, form api.CreateEmailOption) {
type createEmailRequest struct {
Emails []string `json:"emails"`
}
func addEmail(c *context.APIContext, form createEmailRequest) {
if len(form.Emails) == 0 {
c.Status(http.StatusUnprocessableEntity)
return
}
apiEmails := make([]*api.Email, 0, len(form.Emails))
apiEmails := make([]*types.UserEmail, 0, len(form.Emails))
for _, email := range form.Emails {
err := database.Handle.Users().AddEmail(c.Req.Context(), c.User.ID, email, !conf.Auth.RequireEmailConfirmation)
if err != nil {
@@ -43,17 +46,15 @@ func AddEmail(c *context.APIContext, form api.CreateEmailOption) {
return
}
apiEmails = append(apiEmails,
&api.Email{
Email: email,
Verified: !conf.Auth.RequireEmailConfirmation,
},
)
apiEmails = append(apiEmails, &types.UserEmail{
Email: email,
Verified: !conf.Auth.RequireEmailConfirmation,
})
}
c.JSON(http.StatusCreated, &apiEmails)
}
func DeleteEmail(c *context.APIContext, form api.CreateEmailOption) {
func deleteEmail(c *context.APIContext, form createEmailRequest) {
for _, email := range form.Emails {
if email == c.User.Email {
c.ErrorStatus(http.StatusBadRequest, errors.Errorf("cannot delete primary email %q", email))

View File

@@ -1,16 +1,15 @@
package user
package v1
import (
api "github.com/gogs/go-gogs-client"
"gogs.io/gogs/internal/context"
"gogs.io/gogs/internal/database"
"gogs.io/gogs/internal/route/api/v1/types"
)
func responseAPIUsers(c *context.APIContext, users []*database.User) {
apiUsers := make([]*api.User, len(users))
apiUsers := make([]*types.User, len(users))
for i := range users {
apiUsers[i] = users[i].APIFormat()
apiUsers[i] = toUser(users[i])
}
c.JSONSuccess(&apiUsers)
}
@@ -24,12 +23,12 @@ func listUserFollowers(c *context.APIContext, u *database.User) {
responseAPIUsers(c, users)
}
func ListMyFollowers(c *context.APIContext) {
func listMyFollowers(c *context.APIContext) {
listUserFollowers(c, c.User)
}
func ListFollowers(c *context.APIContext) {
u := GetUserByParams(c)
func listFollowers(c *context.APIContext) {
u := getUserByParams(c)
if c.Written() {
return
}
@@ -45,12 +44,12 @@ func listUserFollowing(c *context.APIContext, u *database.User) {
responseAPIUsers(c, users)
}
func ListMyFollowing(c *context.APIContext) {
func listMyFollowing(c *context.APIContext) {
listUserFollowing(c, c.User)
}
func ListFollowing(c *context.APIContext) {
u := GetUserByParams(c)
func listFollowing(c *context.APIContext) {
u := getUserByParams(c)
if c.Written() {
return
}
@@ -65,28 +64,28 @@ func checkUserFollowing(c *context.APIContext, u *database.User, followID int64)
}
}
func CheckMyFollowing(c *context.APIContext) {
target := GetUserByParams(c)
func checkMyFollowing(c *context.APIContext) {
target := getUserByParams(c)
if c.Written() {
return
}
checkUserFollowing(c, c.User, target.ID)
}
func CheckFollowing(c *context.APIContext) {
u := GetUserByParams(c)
func checkFollowing(c *context.APIContext) {
u := getUserByParams(c)
if c.Written() {
return
}
target := GetUserByParamsName(c, ":target")
target := getUserByParamsName(c, ":target")
if c.Written() {
return
}
checkUserFollowing(c, u, target.ID)
}
func Follow(c *context.APIContext) {
target := GetUserByParams(c)
func follow(c *context.APIContext) {
target := getUserByParams(c)
if c.Written() {
return
}
@@ -97,8 +96,8 @@ func Follow(c *context.APIContext) {
c.NoContent()
}
func Unfollow(c *context.APIContext) {
target := GetUserByParams(c)
func unfollow(c *context.APIContext) {
target := getUserByParams(c)
if c.Written() {
return
}

View File

@@ -1,19 +1,17 @@
package user
package v1
import (
"net/http"
"github.com/cockroachdb/errors"
api "github.com/gogs/go-gogs-client"
"gogs.io/gogs/internal/conf"
"gogs.io/gogs/internal/context"
"gogs.io/gogs/internal/database"
"gogs.io/gogs/internal/route/api/v1/convert"
"gogs.io/gogs/internal/route/api/v1/repo"
"gogs.io/gogs/internal/route/api/v1/types"
)
func GetUserByParamsName(c *context.APIContext, name string) *database.User {
func getUserByParamsName(c *context.APIContext, name string) *database.User {
user, err := database.Handle.Users().GetByUsername(c.Req.Context(), c.Params(name))
if err != nil {
c.NotFoundOrError(err, "get user by name")
@@ -22,16 +20,15 @@ func GetUserByParamsName(c *context.APIContext, name string) *database.User {
return user
}
// GetUserByParams returns user whose name is presented in URL parameter.
func GetUserByParams(c *context.APIContext) *database.User {
return GetUserByParamsName(c, ":username")
func getUserByParams(c *context.APIContext) *database.User {
return getUserByParamsName(c, ":username")
}
func composePublicKeysAPILink() string {
return conf.Server.ExternalURL + "api/v1/user/keys/"
}
func listPublicKeys(c *context.APIContext, uid int64) {
func listPublicKeysOfUser(c *context.APIContext, uid int64) {
keys, err := database.ListPublicKeys(uid)
if err != nil {
c.Error(err, "list public keys")
@@ -39,27 +36,27 @@ func listPublicKeys(c *context.APIContext, uid int64) {
}
apiLink := composePublicKeysAPILink()
apiKeys := make([]*api.PublicKey, len(keys))
apiKeys := make([]*types.UserPublicKey, len(keys))
for i := range keys {
apiKeys[i] = convert.ToPublicKey(apiLink, keys[i])
apiKeys[i] = toUserPublicKey(apiLink, keys[i])
}
c.JSONSuccess(&apiKeys)
}
func ListMyPublicKeys(c *context.APIContext) {
listPublicKeys(c, c.User.ID)
func listMyPublicKeys(c *context.APIContext) {
listPublicKeysOfUser(c, c.User.ID)
}
func ListPublicKeys(c *context.APIContext) {
user := GetUserByParams(c)
func listPublicKeys(c *context.APIContext) {
user := getUserByParams(c)
if c.Written() {
return
}
listPublicKeys(c, user.ID)
listPublicKeysOfUser(c, user.ID)
}
func GetPublicKey(c *context.APIContext) {
func getPublicKey(c *context.APIContext) {
key, err := database.GetPublicKeyByID(c.ParamsInt64(":id"))
if err != nil {
c.NotFoundOrError(err, "get public key by ID")
@@ -67,31 +64,35 @@ func GetPublicKey(c *context.APIContext) {
}
apiLink := composePublicKeysAPILink()
c.JSONSuccess(convert.ToPublicKey(apiLink, key))
c.JSONSuccess(toUserPublicKey(apiLink, key))
}
// CreateUserPublicKey creates new public key to given user by ID.
func CreateUserPublicKey(c *context.APIContext, form api.CreateKeyOption, uid int64) {
type createPublicKeyRequest struct {
Title string `json:"title" binding:"Required"`
Key string `json:"key" binding:"Required"`
}
func createUserPublicKey(c *context.APIContext, form createPublicKeyRequest, uid int64) {
content, err := database.CheckPublicKeyString(form.Key)
if err != nil {
repo.HandleCheckKeyStringError(c, err)
handleCheckKeyStringError(c, err)
return
}
key, err := database.AddPublicKey(uid, form.Title, content)
if err != nil {
repo.HandleAddKeyError(c, err)
handleAddKeyError(c, err)
return
}
apiLink := composePublicKeysAPILink()
c.JSON(http.StatusCreated, convert.ToPublicKey(apiLink, key))
c.JSON(http.StatusCreated, toUserPublicKey(apiLink, key))
}
func CreatePublicKey(c *context.APIContext, form api.CreateKeyOption) {
CreateUserPublicKey(c, form, c.User.ID)
func createPublicKey(c *context.APIContext, form createPublicKeyRequest) {
createUserPublicKey(c, form, c.User.ID)
}
func DeletePublicKey(c *context.APIContext) {
func deletePublicKey(c *context.APIContext) {
if err := database.DeletePublicKey(c.User, c.ParamsInt64(":id")); err != nil {
if database.IsErrKeyAccessDenied(err) {
c.ErrorStatus(http.StatusForbidden, errors.New("You do not have access to this key."))

View File

@@ -6,10 +6,10 @@ import (
log "unknwon.dev/clog/v2"
"github.com/gogs/git-module"
api "github.com/gogs/go-gogs-client"
"gogs.io/gogs/internal/context"
"gogs.io/gogs/internal/database"
apiv1types "gogs.io/gogs/internal/route/api/v1/types"
"gogs.io/gogs/internal/urlutil"
)
@@ -153,10 +153,10 @@ func DeleteBranchPost(c *context.Context) {
return
}
if err := database.PrepareWebhooks(c.Repo.Repository, database.HookEventTypeDelete, &api.DeletePayload{
if err := database.PrepareWebhooks(c.Repo.Repository, database.HookEventTypeDelete, &apiv1types.WebhookDeletePayload{
Ref: branchName,
RefType: "branch",
PusherType: api.PUSHER_TYPE_USER,
PusherType: apiv1types.WebhookPusherTypeUser,
Repo: c.Repo.Repository.APIFormatLegacy(nil),
Sender: c.User.APIFormat(),
}); err != nil {

View File

@@ -10,7 +10,6 @@ import (
"github.com/cockroachdb/errors"
"github.com/gogs/git-module"
api "github.com/gogs/go-gogs-client"
"gopkg.in/macaron.v1"
"gogs.io/gogs/internal/conf"
@@ -18,6 +17,7 @@ import (
"gogs.io/gogs/internal/database"
"gogs.io/gogs/internal/form"
"gogs.io/gogs/internal/netutil"
apiv1types "gogs.io/gogs/internal/route/api/v1/types"
)
const (
@@ -513,21 +513,21 @@ func TestWebhook(c *context.Context) {
}
apiUser := c.User.APIFormat()
p := &api.PushPayload{
p := &apiv1types.WebhookPushPayload{
Ref: git.RefsHeads + c.Repo.Repository.DefaultBranch,
Before: commitID,
After: commitID,
Commits: []*api.PayloadCommit{
Commits: []*apiv1types.WebhookPayloadCommit{
{
ID: commitID,
Message: commitMessage,
URL: c.Repo.Repository.HTMLURL() + "/commit/" + commitID,
Author: &api.PayloadUser{
Author: &apiv1types.WebhookPayloadUser{
Name: author.Name,
Email: author.Email,
UserName: authorUsername,
},
Committer: &api.PayloadUser{
Committer: &apiv1types.WebhookPayloadUser{
Name: committer.Name,
Email: committer.Email,
UserName: committerUsername,