diff options
author | Daniel Baumann <daniel@debian.org> | 2024-10-18 20:33:49 +0200 |
---|---|---|
committer | Daniel Baumann <daniel@debian.org> | 2024-12-12 23:57:56 +0100 |
commit | e68b9d00a6e05b3a941f63ffb696f91e554ac5ec (patch) | |
tree | 97775d6c13b0f416af55314eb6a89ef792474615 /modules/structs | |
parent | Initial commit. (diff) | |
download | forgejo-e68b9d00a6e05b3a941f63ffb696f91e554ac5ec.tar.xz forgejo-e68b9d00a6e05b3a941f63ffb696f91e554ac5ec.zip |
Adding upstream version 9.0.3.
Signed-off-by: Daniel Baumann <daniel@debian.org>
Diffstat (limited to '')
62 files changed, 4142 insertions, 0 deletions
diff --git a/modules/structs/activity.go b/modules/structs/activity.go new file mode 100644 index 0000000..1bb8313 --- /dev/null +++ b/modules/structs/activity.go @@ -0,0 +1,25 @@ +// Copyright 2023 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package structs + +import "time" + +type Activity struct { + ID int64 `json:"id"` + UserID int64 `json:"user_id"` // Receiver user + // the type of action + // + // enum: ["create_repo", "rename_repo", "star_repo", "watch_repo", "commit_repo", "create_issue", "create_pull_request", "transfer_repo", "push_tag", "comment_issue", "merge_pull_request", "close_issue", "reopen_issue", "close_pull_request", "reopen_pull_request", "delete_tag", "delete_branch", "mirror_sync_push", "mirror_sync_create", "mirror_sync_delete", "approve_pull_request", "reject_pull_request", "comment_pull", "publish_release", "pull_review_dismissed", "pull_request_ready_for_review", "auto_merge_pull_request"] + OpType string `json:"op_type"` + ActUserID int64 `json:"act_user_id"` + ActUser *User `json:"act_user"` + RepoID int64 `json:"repo_id"` + Repo *Repository `json:"repo"` + CommentID int64 `json:"comment_id"` + Comment *Comment `json:"comment"` + RefName string `json:"ref_name"` + IsPrivate bool `json:"is_private"` + Content string `json:"content"` + Created time.Time `json:"created"` +} diff --git a/modules/structs/activitypub.go b/modules/structs/activitypub.go new file mode 100644 index 0000000..117eb0b --- /dev/null +++ b/modules/structs/activitypub.go @@ -0,0 +1,9 @@ +// Copyright 2022 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package structs + +// ActivityPub type +type ActivityPub struct { + Context string `json:"@context"` +} diff --git a/modules/structs/admin_user.go b/modules/structs/admin_user.go new file mode 100644 index 0000000..5b7df12 --- /dev/null +++ b/modules/structs/admin_user.go @@ -0,0 +1,53 @@ +// Copyright 2015 The Gogs Authors. All rights reserved. +// Copyright 2019 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package structs + +import "time" + +// CreateUserOption create user options +type CreateUserOption struct { + SourceID int64 `json:"source_id"` + LoginName string `json:"login_name"` + // required: true + Username string `json:"username" binding:"Required;Username;MaxSize(40)"` + FullName string `json:"full_name" binding:"MaxSize(100)"` + // required: true + // swagger:strfmt email + Email string `json:"email" binding:"Required;Email;MaxSize(254)"` + Password string `json:"password" binding:"MaxSize(255)"` + MustChangePassword *bool `json:"must_change_password"` + SendNotify bool `json:"send_notify"` + Restricted *bool `json:"restricted"` + Visibility string `json:"visibility" binding:"In(,public,limited,private)"` + + // For explicitly setting the user creation timestamp. Useful when users are + // migrated from other systems. When omitted, the user's creation timestamp + // will be set to "now". + Created *time.Time `json:"created_at"` +} + +// EditUserOption edit user options +type EditUserOption struct { + SourceID *int64 `json:"source_id"` + LoginName *string `json:"login_name"` + // swagger:strfmt email + Email *string `json:"email" binding:"MaxSize(254)"` + FullName *string `json:"full_name" binding:"MaxSize(100)"` + Password string `json:"password" binding:"MaxSize(255)"` + MustChangePassword *bool `json:"must_change_password"` + Website *string `json:"website" binding:"OmitEmpty;ValidUrl;MaxSize(255)"` + Location *string `json:"location" binding:"MaxSize(50)"` + Pronouns *string `json:"pronouns" binding:"MaxSize(50)"` + Description *string `json:"description" binding:"MaxSize(255)"` + 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"` + ProhibitLogin *bool `json:"prohibit_login"` + AllowCreateOrganization *bool `json:"allow_create_organization"` + Restricted *bool `json:"restricted"` + Visibility string `json:"visibility" binding:"In(,public,limited,private)"` +} diff --git a/modules/structs/attachment.go b/modules/structs/attachment.go new file mode 100644 index 0000000..c97cdcb --- /dev/null +++ b/modules/structs/attachment.go @@ -0,0 +1,31 @@ +// Copyright 2017 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package structs // import "code.gitea.io/gitea/modules/structs" + +import ( + "time" +) + +// Attachment a generic attachment +// swagger:model +type Attachment struct { + ID int64 `json:"id"` + Name string `json:"name"` + Size int64 `json:"size"` + DownloadCount int64 `json:"download_count"` + // swagger:strfmt date-time + Created time.Time `json:"created_at"` + UUID string `json:"uuid"` + DownloadURL string `json:"browser_download_url"` + // enum: ["attachment", "external"] + Type string `json:"type"` +} + +// EditAttachmentOptions options for editing attachments +// swagger:model +type EditAttachmentOptions struct { + Name string `json:"name"` + // (Can only be set if existing attachment is of external type) + DownloadURL string `json:"browser_download_url"` +} diff --git a/modules/structs/commit_status.go b/modules/structs/commit_status.go new file mode 100644 index 0000000..dc880ef --- /dev/null +++ b/modules/structs/commit_status.go @@ -0,0 +1,73 @@ +// Copyright 2020 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package structs + +// CommitStatusState holds the state of a CommitStatus +// It can be "pending", "success", "error" and "failure" +type CommitStatusState string + +const ( + // CommitStatusPending is for when the CommitStatus is Pending + CommitStatusPending CommitStatusState = "pending" + // CommitStatusSuccess is for when the CommitStatus is Success + CommitStatusSuccess CommitStatusState = "success" + // CommitStatusError is for when the CommitStatus is Error + CommitStatusError CommitStatusState = "error" + // CommitStatusFailure is for when the CommitStatus is Failure + CommitStatusFailure CommitStatusState = "failure" + // CommitStatusWarning is for when the CommitStatus is Warning + CommitStatusWarning CommitStatusState = "warning" +) + +var commitStatusPriorities = map[CommitStatusState]int{ + CommitStatusError: 0, + CommitStatusFailure: 1, + CommitStatusWarning: 2, + CommitStatusPending: 3, + CommitStatusSuccess: 4, +} + +func (css CommitStatusState) String() string { + return string(css) +} + +// NoBetterThan returns true if this State is no better than the given State +// This function only handles the states defined in CommitStatusPriorities +func (css CommitStatusState) NoBetterThan(css2 CommitStatusState) bool { + // NoBetterThan only handles the 5 states above + if _, exist := commitStatusPriorities[css]; !exist { + return false + } + + if _, exist := commitStatusPriorities[css2]; !exist { + return false + } + + return commitStatusPriorities[css] <= commitStatusPriorities[css2] +} + +// IsPending represents if commit status state is pending +func (css CommitStatusState) IsPending() bool { + return css == CommitStatusPending +} + +// IsSuccess represents if commit status state is success +func (css CommitStatusState) IsSuccess() bool { + return css == CommitStatusSuccess +} + +// IsError represents if commit status state is error +func (css CommitStatusState) IsError() bool { + return css == CommitStatusError +} + +// IsFailure represents if commit status state is failure +func (css CommitStatusState) IsFailure() bool { + return css == CommitStatusFailure +} + +// IsWarning represents if commit status state is warning +func (css CommitStatusState) IsWarning() bool { + return css == CommitStatusWarning +} diff --git a/modules/structs/commit_status_test.go b/modules/structs/commit_status_test.go new file mode 100644 index 0000000..f068085 --- /dev/null +++ b/modules/structs/commit_status_test.go @@ -0,0 +1,174 @@ +// Copyright 2023 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package structs + +import ( + "testing" +) + +func TestNoBetterThan(t *testing.T) { + type args struct { + css CommitStatusState + css2 CommitStatusState + } + var unExpectedState CommitStatusState + tests := []struct { + name string + args args + want bool + }{ + { + name: "success is no better than success", + args: args{ + css: CommitStatusSuccess, + css2: CommitStatusSuccess, + }, + want: true, + }, + { + name: "success is no better than pending", + args: args{ + css: CommitStatusSuccess, + css2: CommitStatusPending, + }, + want: false, + }, + { + name: "success is no better than failure", + args: args{ + css: CommitStatusSuccess, + css2: CommitStatusFailure, + }, + want: false, + }, + { + name: "success is no better than error", + args: args{ + css: CommitStatusSuccess, + css2: CommitStatusError, + }, + want: false, + }, + { + name: "pending is no better than success", + args: args{ + css: CommitStatusPending, + css2: CommitStatusSuccess, + }, + want: true, + }, + { + name: "pending is no better than pending", + args: args{ + css: CommitStatusPending, + css2: CommitStatusPending, + }, + want: true, + }, + { + name: "pending is no better than failure", + args: args{ + css: CommitStatusPending, + css2: CommitStatusFailure, + }, + want: false, + }, + { + name: "pending is no better than error", + args: args{ + css: CommitStatusPending, + css2: CommitStatusError, + }, + want: false, + }, + { + name: "failure is no better than success", + args: args{ + css: CommitStatusFailure, + css2: CommitStatusSuccess, + }, + want: true, + }, + { + name: "failure is no better than pending", + args: args{ + css: CommitStatusFailure, + css2: CommitStatusPending, + }, + want: true, + }, + { + name: "failure is no better than failure", + args: args{ + css: CommitStatusFailure, + css2: CommitStatusFailure, + }, + want: true, + }, + { + name: "failure is no better than error", + args: args{ + css: CommitStatusFailure, + css2: CommitStatusError, + }, + want: false, + }, + { + name: "error is no better than success", + args: args{ + css: CommitStatusError, + css2: CommitStatusSuccess, + }, + want: true, + }, + { + name: "error is no better than pending", + args: args{ + css: CommitStatusError, + css2: CommitStatusPending, + }, + want: true, + }, + { + name: "error is no better than failure", + args: args{ + css: CommitStatusError, + css2: CommitStatusFailure, + }, + want: true, + }, + { + name: "error is no better than error", + args: args{ + css: CommitStatusError, + css2: CommitStatusError, + }, + want: true, + }, + { + name: "unExpectedState is no better than success", + args: args{ + css: unExpectedState, + css2: CommitStatusSuccess, + }, + want: false, + }, + { + name: "unExpectedState is no better than unExpectedState", + args: args{ + css: unExpectedState, + css2: unExpectedState, + }, + want: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result := tt.args.css.NoBetterThan(tt.args.css2) + if result != tt.want { + t.Errorf("NoBetterThan() = %v, want %v", result, tt.want) + } + }) + } +} diff --git a/modules/structs/cron.go b/modules/structs/cron.go new file mode 100644 index 0000000..39c6a06 --- /dev/null +++ b/modules/structs/cron.go @@ -0,0 +1,15 @@ +// Copyright 2020 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package structs + +import "time" + +// Cron represents a Cron task +type Cron struct { + Name string `json:"name"` + Schedule string `json:"schedule"` + Next time.Time `json:"next"` + Prev time.Time `json:"prev"` + ExecTimes int64 `json:"exec_times"` +} diff --git a/modules/structs/doc.go b/modules/structs/doc.go new file mode 100644 index 0000000..0db0a25 --- /dev/null +++ b/modules/structs/doc.go @@ -0,0 +1,4 @@ +// Copyright 2016 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package structs diff --git a/modules/structs/fork.go b/modules/structs/fork.go new file mode 100644 index 0000000..eb7774a --- /dev/null +++ b/modules/structs/fork.go @@ -0,0 +1,12 @@ +// Copyright 2016 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package structs + +// CreateForkOption options for creating a fork +type CreateForkOption struct { + // organization name, if forking into an organization + Organization *string `json:"organization"` + // name of the forked repository + Name *string `json:"name"` +} diff --git a/modules/structs/git_blob.go b/modules/structs/git_blob.go new file mode 100644 index 0000000..96c7a27 --- /dev/null +++ b/modules/structs/git_blob.go @@ -0,0 +1,13 @@ +// Copyright 2019 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package structs + +// GitBlobResponse represents a git blob +type GitBlobResponse struct { + Content string `json:"content"` + Encoding string `json:"encoding"` + URL string `json:"url"` + SHA string `json:"sha"` + Size int64 `json:"size"` +} diff --git a/modules/structs/git_hook.go b/modules/structs/git_hook.go new file mode 100644 index 0000000..2023025 --- /dev/null +++ b/modules/structs/git_hook.go @@ -0,0 +1,19 @@ +// Copyright 2019 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package structs + +// GitHook represents a Git repository hook +type GitHook struct { + Name string `json:"name"` + IsActive bool `json:"is_active"` + Content string `json:"content,omitempty"` +} + +// GitHookList represents a list of Git hooks +type GitHookList []*GitHook + +// EditGitHookOption options when modifying one Git hook +type EditGitHookOption struct { + Content string `json:"content"` +} diff --git a/modules/structs/hook.go b/modules/structs/hook.go new file mode 100644 index 0000000..1940fd8 --- /dev/null +++ b/modules/structs/hook.go @@ -0,0 +1,520 @@ +// Copyright 2014 The Gogs Authors. All rights reserved. +// Copyright 2017 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package structs + +import ( + "errors" + "strings" + "time" + + "code.gitea.io/gitea/modules/json" +) + +// ErrInvalidReceiveHook FIXME +var ErrInvalidReceiveHook = errors.New("Invalid JSON payload received over webhook") + +// Hook a hook is a web hook when one repository changed +type Hook struct { + ID int64 `json:"id"` + Type string `json:"type"` + BranchFilter string `json:"branch_filter"` + URL string `json:"url"` + + // Deprecated: use Metadata instead + Config map[string]string `json:"config"` + Events []string `json:"events"` + AuthorizationHeader string `json:"authorization_header"` + ContentType string `json:"content_type"` + Metadata any `json:"metadata"` + Active bool `json:"active"` + // swagger:strfmt date-time + Updated time.Time `json:"updated_at"` + // swagger:strfmt date-time + Created time.Time `json:"created_at"` +} + +// HookList represents a list of API hook. +type HookList []*Hook + +// CreateHookOptionConfig has all config options in it +// required are "content_type" and "url" Required +type CreateHookOptionConfig map[string]string + +// CreateHookOption options when create a hook +type CreateHookOption struct { + // required: true + // enum: ["forgejo", "dingtalk", "discord", "gitea", "gogs", "msteams", "slack", "telegram", "feishu", "wechatwork", "packagist"] + Type string `json:"type" binding:"Required"` + // required: true + Config CreateHookOptionConfig `json:"config" binding:"Required"` + Events []string `json:"events"` + BranchFilter string `json:"branch_filter" binding:"GlobPattern"` + AuthorizationHeader string `json:"authorization_header"` + // default: false + Active bool `json:"active"` +} + +// EditHookOption options when modify one hook +type EditHookOption struct { + Config map[string]string `json:"config"` + Events []string `json:"events"` + BranchFilter string `json:"branch_filter" binding:"GlobPattern"` + AuthorizationHeader string `json:"authorization_header"` + Active *bool `json:"active"` +} + +// Payloader payload is some part of one hook +type Payloader interface { + JSONPayload() ([]byte, error) +} + +// PayloadUser represents the author or committer of a commit +type PayloadUser struct { + // Full name of the commit author + Name string `json:"name"` + // swagger:strfmt email + Email string `json:"email"` + UserName string `json:"username"` +} + +// FIXME: consider using same format as API when commits API are added. +// applies to PayloadCommit and PayloadCommitVerification + +// PayloadCommit represents a commit +type PayloadCommit struct { + // sha1 hash of the commit + ID string `json:"id"` + Message string `json:"message"` + URL string `json:"url"` + Author *PayloadUser `json:"author"` + Committer *PayloadUser `json:"committer"` + Verification *PayloadCommitVerification `json:"verification"` + // swagger:strfmt date-time + Timestamp time.Time `json:"timestamp"` + Added []string `json:"added"` + Removed []string `json:"removed"` + Modified []string `json:"modified"` +} + +// PayloadCommitVerification represents the GPG verification of a commit +type PayloadCommitVerification struct { + Verified bool `json:"verified"` + Reason string `json:"reason"` + Signature string `json:"signature"` + Signer *PayloadUser `json:"signer"` + Payload string `json:"payload"` +} + +var ( + _ Payloader = &CreatePayload{} + _ Payloader = &DeletePayload{} + _ Payloader = &ForkPayload{} + _ Payloader = &PushPayload{} + _ Payloader = &IssuePayload{} + _ Payloader = &IssueCommentPayload{} + _ Payloader = &PullRequestPayload{} + _ Payloader = &RepositoryPayload{} + _ Payloader = &ReleasePayload{} + _ Payloader = &PackagePayload{} +) + +// _________ __ +// \_ ___ \_______ ____ _____ _/ |_ ____ +// / \ \/\_ __ \_/ __ \\__ \\ __\/ __ \ +// \ \____| | \/\ ___/ / __ \| | \ ___/ +// \______ /|__| \___ >____ /__| \___ > +// \/ \/ \/ \/ + +// CreatePayload FIXME +type CreatePayload struct { + Sha string `json:"sha"` + Ref string `json:"ref"` + RefType string `json:"ref_type"` + Repo *Repository `json:"repository"` + Sender *User `json:"sender"` +} + +// JSONPayload return payload information +func (p *CreatePayload) JSONPayload() ([]byte, error) { + return json.MarshalIndent(p, "", " ") +} + +// ParseCreateHook parses create event hook content. +func ParseCreateHook(raw []byte) (*CreatePayload, error) { + hook := new(CreatePayload) + if err := json.Unmarshal(raw, hook); err != nil { + return nil, err + } + + // it is possible the JSON was parsed, however, + // was not from Gogs (maybe was from Bitbucket) + // So we'll check to be sure certain key fields + // were populated + switch { + case hook.Repo == nil: + return nil, ErrInvalidReceiveHook + case len(hook.Ref) == 0: + return nil, ErrInvalidReceiveHook + } + return hook, nil +} + +// ________ .__ __ +// \______ \ ____ | | _____/ |_ ____ +// | | \_/ __ \| | _/ __ \ __\/ __ \ +// | ` \ ___/| |_\ ___/| | \ ___/ +// /_______ /\___ >____/\___ >__| \___ > +// \/ \/ \/ \/ + +// PusherType define the type to push +type PusherType string + +// describe all the PusherTypes +const ( + PusherTypeUser PusherType = "user" +) + +// DeletePayload represents delete payload +type DeletePayload struct { + Ref string `json:"ref"` + RefType string `json:"ref_type"` + PusherType PusherType `json:"pusher_type"` + Repo *Repository `json:"repository"` + Sender *User `json:"sender"` +} + +// JSONPayload implements Payload +func (p *DeletePayload) JSONPayload() ([]byte, error) { + return json.MarshalIndent(p, "", " ") +} + +// ___________ __ +// \_ _____/__________| | __ +// | __)/ _ \_ __ \ |/ / +// | \( <_> ) | \/ < +// \___ / \____/|__| |__|_ \ +// \/ \/ + +// ForkPayload represents fork payload +type ForkPayload struct { + Forkee *Repository `json:"forkee"` + Repo *Repository `json:"repository"` + Sender *User `json:"sender"` +} + +// JSONPayload implements Payload +func (p *ForkPayload) JSONPayload() ([]byte, error) { + return json.MarshalIndent(p, "", " ") +} + +// HookIssueCommentAction defines hook issue comment action +type HookIssueCommentAction string + +// all issue comment actions +const ( + HookIssueCommentCreated HookIssueCommentAction = "created" + HookIssueCommentEdited HookIssueCommentAction = "edited" + HookIssueCommentDeleted HookIssueCommentAction = "deleted" +) + +// IssueCommentPayload represents a payload information of issue comment event. +type IssueCommentPayload struct { + Action HookIssueCommentAction `json:"action"` + Issue *Issue `json:"issue"` + Comment *Comment `json:"comment"` + Changes *ChangesPayload `json:"changes,omitempty"` + Repository *Repository `json:"repository"` + Sender *User `json:"sender"` + IsPull bool `json:"is_pull"` +} + +// JSONPayload implements Payload +func (p *IssueCommentPayload) JSONPayload() ([]byte, error) { + return json.MarshalIndent(p, "", " ") +} + +// __________ .__ +// \______ \ ____ | | ____ _____ ______ ____ +// | _// __ \| | _/ __ \\__ \ / ___// __ \ +// | | \ ___/| |_\ ___/ / __ \_\___ \\ ___/ +// |____|_ /\___ >____/\___ >____ /____ >\___ > +// \/ \/ \/ \/ \/ \/ + +// HookReleaseAction defines hook release action type +type HookReleaseAction string + +// all release actions +const ( + HookReleasePublished HookReleaseAction = "published" + HookReleaseUpdated HookReleaseAction = "updated" + HookReleaseDeleted HookReleaseAction = "deleted" +) + +// ReleasePayload represents a payload information of release event. +type ReleasePayload struct { + Action HookReleaseAction `json:"action"` + Release *Release `json:"release"` + Repository *Repository `json:"repository"` + Sender *User `json:"sender"` +} + +// JSONPayload implements Payload +func (p *ReleasePayload) JSONPayload() ([]byte, error) { + return json.MarshalIndent(p, "", " ") +} + +// __________ .__ +// \______ \__ __ _____| |__ +// | ___/ | \/ ___/ | \ +// | | | | /\___ \| Y \ +// |____| |____//____ >___| / +// \/ \/ + +// PushPayload represents a payload information of push event. +type PushPayload struct { + Ref string `json:"ref"` + Before string `json:"before"` + After string `json:"after"` + CompareURL string `json:"compare_url"` + Commits []*PayloadCommit `json:"commits"` + TotalCommits int `json:"total_commits"` + HeadCommit *PayloadCommit `json:"head_commit"` + Repo *Repository `json:"repository"` + Pusher *User `json:"pusher"` + Sender *User `json:"sender"` +} + +// JSONPayload FIXME +func (p *PushPayload) JSONPayload() ([]byte, error) { + return json.MarshalIndent(p, "", " ") +} + +// ParsePushHook parses push event hook content. +func ParsePushHook(raw []byte) (*PushPayload, error) { + hook := new(PushPayload) + if err := json.Unmarshal(raw, hook); err != nil { + return nil, err + } + + switch { + case hook.Repo == nil: + return nil, ErrInvalidReceiveHook + case len(hook.Ref) == 0: + return nil, ErrInvalidReceiveHook + } + return hook, nil +} + +// Branch returns branch name from a payload +func (p *PushPayload) Branch() string { + return strings.ReplaceAll(p.Ref, "refs/heads/", "") +} + +// .___ +// | | ______ ________ __ ____ +// | |/ ___// ___/ | \_/ __ \ +// | |\___ \ \___ \| | /\ ___/ +// |___/____ >____ >____/ \___ > +// \/ \/ \/ + +// HookIssueAction FIXME +type HookIssueAction string + +const ( + // HookIssueOpened opened + HookIssueOpened HookIssueAction = "opened" + // HookIssueClosed closed + HookIssueClosed HookIssueAction = "closed" + // HookIssueReOpened reopened + HookIssueReOpened HookIssueAction = "reopened" + // HookIssueEdited edited + HookIssueEdited HookIssueAction = "edited" + // HookIssueAssigned assigned + HookIssueAssigned HookIssueAction = "assigned" + // HookIssueUnassigned unassigned + HookIssueUnassigned HookIssueAction = "unassigned" + // HookIssueLabelUpdated label_updated + HookIssueLabelUpdated HookIssueAction = "label_updated" + // HookIssueLabelCleared label_cleared + HookIssueLabelCleared HookIssueAction = "label_cleared" + // HookIssueSynchronized synchronized + HookIssueSynchronized HookIssueAction = "synchronized" + // HookIssueMilestoned is an issue action for when a milestone is set on an issue. + HookIssueMilestoned HookIssueAction = "milestoned" + // HookIssueDemilestoned is an issue action for when a milestone is cleared on an issue. + HookIssueDemilestoned HookIssueAction = "demilestoned" + // HookIssueReviewed is an issue action for when a pull request is reviewed + HookIssueReviewed HookIssueAction = "reviewed" + // HookIssueReviewRequested is an issue action for when a reviewer is requested for a pull request. + HookIssueReviewRequested HookIssueAction = "review_requested" + // HookIssueReviewRequestRemoved is an issue action for removing a review request to someone on a pull request. + HookIssueReviewRequestRemoved HookIssueAction = "review_request_removed" +) + +// IssuePayload represents the payload information that is sent along with an issue event. +type IssuePayload struct { + Action HookIssueAction `json:"action"` + Index int64 `json:"number"` + Changes *ChangesPayload `json:"changes,omitempty"` + Issue *Issue `json:"issue"` + Repository *Repository `json:"repository"` + Sender *User `json:"sender"` + CommitID string `json:"commit_id"` + Label *Label `json:"label,omitempty"` +} + +// JSONPayload encodes the IssuePayload to JSON, with an indentation of two spaces. +func (p *IssuePayload) JSONPayload() ([]byte, error) { + return json.MarshalIndent(p, "", " ") +} + +// ChangesFromPayload FIXME +type ChangesFromPayload struct { + From string `json:"from"` +} + +// ChangesPayload represents the payload information of issue change +type ChangesPayload struct { + Title *ChangesFromPayload `json:"title,omitempty"` + Body *ChangesFromPayload `json:"body,omitempty"` + Ref *ChangesFromPayload `json:"ref,omitempty"` +} + +// __________ .__ .__ __________ __ +// \______ \__ __| | | | \______ \ ____ ________ __ ____ _______/ |_ +// | ___/ | \ | | | | _// __ \/ ____/ | \_/ __ \ / ___/\ __\ +// | | | | / |_| |__ | | \ ___< <_| | | /\ ___/ \___ \ | | +// |____| |____/|____/____/ |____|_ /\___ >__ |____/ \___ >____ > |__| +// \/ \/ |__| \/ \/ + +// PullRequestPayload represents a payload information of pull request event. +type PullRequestPayload struct { + Action HookIssueAction `json:"action"` + Index int64 `json:"number"` + Changes *ChangesPayload `json:"changes,omitempty"` + PullRequest *PullRequest `json:"pull_request"` + RequestedReviewer *User `json:"requested_reviewer"` + Repository *Repository `json:"repository"` + Sender *User `json:"sender"` + CommitID string `json:"commit_id"` + Review *ReviewPayload `json:"review"` + Label *Label `json:"label,omitempty"` +} + +// JSONPayload FIXME +func (p *PullRequestPayload) JSONPayload() ([]byte, error) { + return json.MarshalIndent(p, "", " ") +} + +type HookScheduleAction string + +const ( + HookScheduleCreated HookScheduleAction = "schedule" +) + +type SchedulePayload struct { + Action HookScheduleAction `json:"action"` +} + +type WorkflowDispatchPayload struct { + Inputs map[string]string `json:"inputs"` + Ref string `json:"ref"` + Repository *Repository `json:"repository"` + Sender *User `json:"sender"` + Workflow string `json:"workflow"` +} + +// ReviewPayload FIXME +type ReviewPayload struct { + Type string `json:"type"` + Content string `json:"content"` +} + +// __ __.__ __ .__ +// / \ / \__| | _|__| +// \ \/\/ / | |/ / | +// \ /| | <| | +// \__/\ / |__|__|_ \__| +// \/ \/ + +// HookWikiAction an action that happens to a wiki page +type HookWikiAction string + +const ( + // HookWikiCreated created + HookWikiCreated HookWikiAction = "created" + // HookWikiEdited edited + HookWikiEdited HookWikiAction = "edited" + // HookWikiDeleted deleted + HookWikiDeleted HookWikiAction = "deleted" +) + +// WikiPayload payload for repository webhooks +type WikiPayload struct { + Action HookWikiAction `json:"action"` + Repository *Repository `json:"repository"` + Sender *User `json:"sender"` + Page string `json:"page"` + Comment string `json:"comment"` +} + +// JSONPayload JSON representation of the payload +func (p *WikiPayload) JSONPayload() ([]byte, error) { + return json.MarshalIndent(p, "", " ") +} + +//__________ .__ __ +//\______ \ ____ ______ ____ _____|__|/ |_ ___________ ___.__. +// | _// __ \\____ \ / _ \/ ___/ \ __\/ _ \_ __ < | | +// | | \ ___/| |_> > <_> )___ \| || | ( <_> ) | \/\___ | +// |____|_ /\___ > __/ \____/____ >__||__| \____/|__| / ____| +// \/ \/|__| \/ \/ + +// HookRepoAction an action that happens to a repo +type HookRepoAction string + +const ( + // HookRepoCreated created + HookRepoCreated HookRepoAction = "created" + // HookRepoDeleted deleted + HookRepoDeleted HookRepoAction = "deleted" +) + +// RepositoryPayload payload for repository webhooks +type RepositoryPayload struct { + Action HookRepoAction `json:"action"` + Repository *Repository `json:"repository"` + Organization *User `json:"organization"` + Sender *User `json:"sender"` +} + +// JSONPayload JSON representation of the payload +func (p *RepositoryPayload) JSONPayload() ([]byte, error) { + return json.MarshalIndent(p, "", " ") +} + +// HookPackageAction an action that happens to a package +type HookPackageAction string + +const ( + // HookPackageCreated created + HookPackageCreated HookPackageAction = "created" + // HookPackageDeleted deleted + HookPackageDeleted HookPackageAction = "deleted" +) + +// PackagePayload represents a package payload +type PackagePayload struct { + Action HookPackageAction `json:"action"` + Repository *Repository `json:"repository"` + Package *Package `json:"package"` + Organization *User `json:"organization"` + Sender *User `json:"sender"` +} + +// JSONPayload implements Payload +func (p *PackagePayload) JSONPayload() ([]byte, error) { + return json.MarshalIndent(p, "", " ") +} diff --git a/modules/structs/issue.go b/modules/structs/issue.go new file mode 100644 index 0000000..a67bdcf --- /dev/null +++ b/modules/structs/issue.go @@ -0,0 +1,269 @@ +// Copyright 2016 The Gogs Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package structs + +import ( + "fmt" + "path" + "slices" + "strings" + "time" + + "gopkg.in/yaml.v3" +) + +// StateType issue state type +type StateType string + +const ( + // StateOpen pr is opend + StateOpen StateType = "open" + // StateClosed pr is closed + StateClosed StateType = "closed" + // StateAll is all + StateAll StateType = "all" +) + +// PullRequestMeta PR info if an issue is a PR +type PullRequestMeta struct { + HasMerged bool `json:"merged"` + Merged *time.Time `json:"merged_at"` + IsWorkInProgress bool `json:"draft"` + HTMLURL string `json:"html_url"` +} + +// RepositoryMeta basic repository information +type RepositoryMeta struct { + ID int64 `json:"id"` + Name string `json:"name"` + Owner string `json:"owner"` + FullName string `json:"full_name"` +} + +// Issue represents an issue in a repository +// swagger:model +type Issue struct { + ID int64 `json:"id"` + URL string `json:"url"` + HTMLURL string `json:"html_url"` + Index int64 `json:"number"` + Poster *User `json:"user"` + OriginalAuthor string `json:"original_author"` + OriginalAuthorID int64 `json:"original_author_id"` + Title string `json:"title"` + Body string `json:"body"` + Ref string `json:"ref"` + Attachments []*Attachment `json:"assets"` + Labels []*Label `json:"labels"` + Milestone *Milestone `json:"milestone"` + // deprecated + Assignee *User `json:"assignee"` + Assignees []*User `json:"assignees"` + // Whether the issue is open or closed + // + // type: string + // enum: ["open", "closed"] + State StateType `json:"state"` + IsLocked bool `json:"is_locked"` + Comments int `json:"comments"` + // swagger:strfmt date-time + Created time.Time `json:"created_at"` + // swagger:strfmt date-time + Updated time.Time `json:"updated_at"` + // swagger:strfmt date-time + Closed *time.Time `json:"closed_at"` + // swagger:strfmt date-time + Deadline *time.Time `json:"due_date"` + + PullRequest *PullRequestMeta `json:"pull_request"` + Repo *RepositoryMeta `json:"repository"` + + PinOrder int `json:"pin_order"` +} + +// CreateIssueOption options to create one issue +type CreateIssueOption struct { + // required:true + Title string `json:"title" binding:"Required"` + Body string `json:"body"` + Ref string `json:"ref"` + // deprecated + Assignee string `json:"assignee"` + Assignees []string `json:"assignees"` + // swagger:strfmt date-time + Deadline *time.Time `json:"due_date"` + // milestone id + Milestone int64 `json:"milestone"` + // list of label ids + Labels []int64 `json:"labels"` + Closed bool `json:"closed"` +} + +// EditIssueOption options for editing an issue +type EditIssueOption struct { + Title string `json:"title"` + Body *string `json:"body"` + Ref *string `json:"ref"` + // deprecated + Assignee *string `json:"assignee"` + Assignees []string `json:"assignees"` + Milestone *int64 `json:"milestone"` + State *string `json:"state"` + // swagger:strfmt date-time + Deadline *time.Time `json:"due_date"` + RemoveDeadline *bool `json:"unset_due_date"` + // swagger:strfmt date-time + Updated *time.Time `json:"updated_at"` +} + +// EditDeadlineOption options for creating a deadline +type EditDeadlineOption struct { + // required:true + // swagger:strfmt date-time + Deadline *time.Time `json:"due_date"` +} + +// IssueDeadline represents an issue deadline +// swagger:model +type IssueDeadline struct { + // swagger:strfmt date-time + Deadline *time.Time `json:"due_date"` +} + +// IssueFormFieldType defines issue form field type, can be "markdown", "textarea", "input", "dropdown" or "checkboxes" +type IssueFormFieldType string + +const ( + IssueFormFieldTypeMarkdown IssueFormFieldType = "markdown" + IssueFormFieldTypeTextarea IssueFormFieldType = "textarea" + IssueFormFieldTypeInput IssueFormFieldType = "input" + IssueFormFieldTypeDropdown IssueFormFieldType = "dropdown" + IssueFormFieldTypeCheckboxes IssueFormFieldType = "checkboxes" +) + +// IssueFormField represents a form field +// swagger:model +type IssueFormField struct { + Type IssueFormFieldType `json:"type" yaml:"type"` + ID string `json:"id" yaml:"id"` + Attributes map[string]any `json:"attributes" yaml:"attributes"` + Validations map[string]any `json:"validations" yaml:"validations"` + Visible []IssueFormFieldVisible `json:"visible,omitempty"` +} + +func (iff IssueFormField) VisibleOnForm() bool { + if len(iff.Visible) == 0 { + return true + } + return slices.Contains(iff.Visible, IssueFormFieldVisibleForm) +} + +func (iff IssueFormField) VisibleInContent() bool { + if len(iff.Visible) == 0 { + // we have our markdown exception + return iff.Type != IssueFormFieldTypeMarkdown + } + return slices.Contains(iff.Visible, IssueFormFieldVisibleContent) +} + +// IssueFormFieldVisible defines issue form field visible +// swagger:model +type IssueFormFieldVisible string + +const ( + IssueFormFieldVisibleForm IssueFormFieldVisible = "form" + IssueFormFieldVisibleContent IssueFormFieldVisible = "content" +) + +// IssueTemplate represents an issue template for a repository +// swagger:model +type IssueTemplate struct { + Name string `json:"name" yaml:"name"` + Title string `json:"title" yaml:"title"` + About string `json:"about" yaml:"about"` // Using "description" in a template file is compatible + Labels IssueTemplateLabels `json:"labels" yaml:"labels"` + Ref string `json:"ref" yaml:"ref"` + Content string `json:"content" yaml:"-"` + Fields []*IssueFormField `json:"body" yaml:"body"` + FileName string `json:"file_name" yaml:"-"` +} + +type IssueTemplateLabels []string + +func (l *IssueTemplateLabels) UnmarshalYAML(value *yaml.Node) error { + var labels []string + if value.IsZero() { + *l = labels + return nil + } + switch value.Kind { + case yaml.ScalarNode: + str := "" + err := value.Decode(&str) + if err != nil { + return err + } + for _, v := range strings.Split(str, ",") { + if v = strings.TrimSpace(v); v == "" { + continue + } + labels = append(labels, v) + } + *l = labels + return nil + case yaml.SequenceNode: + if err := value.Decode(&labels); err != nil { + return err + } + *l = labels + return nil + } + return fmt.Errorf("line %d: cannot unmarshal %s into IssueTemplateLabels", value.Line, value.ShortTag()) +} + +type IssueConfigContactLink struct { + Name string `json:"name" yaml:"name"` + URL string `json:"url" yaml:"url"` + About string `json:"about" yaml:"about"` +} + +type IssueConfig struct { + BlankIssuesEnabled bool `json:"blank_issues_enabled" yaml:"blank_issues_enabled"` + ContactLinks []IssueConfigContactLink `json:"contact_links" yaml:"contact_links"` +} + +type IssueConfigValidation struct { + Valid bool `json:"valid"` + Message string `json:"message"` +} + +// IssueTemplateType defines issue template type +type IssueTemplateType string + +const ( + IssueTemplateTypeMarkdown IssueTemplateType = "md" + IssueTemplateTypeYaml IssueTemplateType = "yaml" +) + +// Type returns the type of IssueTemplate, can be "md", "yaml" or empty for known +func (it IssueTemplate) Type() IssueTemplateType { + if base := path.Base(it.FileName); base == "config.yaml" || base == "config.yml" { + // ignore config.yaml which is a special configuration file + return "" + } + if ext := path.Ext(it.FileName); ext == ".md" { + return IssueTemplateTypeMarkdown + } else if ext == ".yaml" || ext == ".yml" { + return IssueTemplateTypeYaml + } + return "" +} + +// IssueMeta basic issue information +// swagger:model +type IssueMeta struct { + Index int64 `json:"index"` + Owner string `json:"owner"` + Name string `json:"repo"` +} diff --git a/modules/structs/issue_comment.go b/modules/structs/issue_comment.go new file mode 100644 index 0000000..9ecb4a1 --- /dev/null +++ b/modules/structs/issue_comment.go @@ -0,0 +1,86 @@ +// Copyright 2016 The Gogs Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package structs + +import ( + "time" +) + +// Comment represents a comment on a commit or issue +type Comment struct { + ID int64 `json:"id"` + HTMLURL string `json:"html_url"` + PRURL string `json:"pull_request_url"` + IssueURL string `json:"issue_url"` + Poster *User `json:"user"` + OriginalAuthor string `json:"original_author"` + OriginalAuthorID int64 `json:"original_author_id"` + Body string `json:"body"` + Attachments []*Attachment `json:"assets"` + // swagger:strfmt date-time + Created time.Time `json:"created_at"` + // swagger:strfmt date-time + Updated time.Time `json:"updated_at"` +} + +// CreateIssueCommentOption options for creating a comment on an issue +type CreateIssueCommentOption struct { + // required:true + Body string `json:"body" binding:"Required"` + // swagger:strfmt date-time + Updated *time.Time `json:"updated_at"` +} + +// EditIssueCommentOption options for editing a comment +type EditIssueCommentOption struct { + // required: true + Body string `json:"body" binding:"Required"` + // swagger:strfmt date-time + Updated *time.Time `json:"updated_at"` +} + +// TimelineComment represents a timeline comment (comment of any type) on a commit or issue +type TimelineComment struct { + ID int64 `json:"id"` + Type string `json:"type"` + + HTMLURL string `json:"html_url"` + PRURL string `json:"pull_request_url"` + IssueURL string `json:"issue_url"` + Poster *User `json:"user"` + Body string `json:"body"` + // swagger:strfmt date-time + Created time.Time `json:"created_at"` + // swagger:strfmt date-time + Updated time.Time `json:"updated_at"` + + OldProjectID int64 `json:"old_project_id"` + ProjectID int64 `json:"project_id"` + OldMilestone *Milestone `json:"old_milestone"` + Milestone *Milestone `json:"milestone"` + TrackedTime *TrackedTime `json:"tracked_time"` + OldTitle string `json:"old_title"` + NewTitle string `json:"new_title"` + OldRef string `json:"old_ref"` + NewRef string `json:"new_ref"` + + RefIssue *Issue `json:"ref_issue"` + RefComment *Comment `json:"ref_comment"` + RefAction string `json:"ref_action"` + // commit SHA where issue/PR was referenced + RefCommitSHA string `json:"ref_commit_sha"` + + ReviewID int64 `json:"review_id"` + + Label *Label `json:"label"` + + Assignee *User `json:"assignee"` + AssigneeTeam *Team `json:"assignee_team"` + // whether the assignees were removed or added + RemovedAssignee bool `json:"removed_assignee"` + + ResolveDoer *User `json:"resolve_doer"` + + DependentIssue *Issue `json:"dependent_issue"` +} diff --git a/modules/structs/issue_label.go b/modules/structs/issue_label.go new file mode 100644 index 0000000..153c412 --- /dev/null +++ b/modules/structs/issue_label.go @@ -0,0 +1,75 @@ +// Copyright 2016 The Gogs Authors. All rights reserved. +// Copyright 2019 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package structs + +import ( + "time" +) + +// Label a label to an issue or a pr +// swagger:model +type Label struct { + ID int64 `json:"id"` + Name string `json:"name"` + // example: false + Exclusive bool `json:"exclusive"` + // example: false + IsArchived bool `json:"is_archived"` + // example: 00aabb + Color string `json:"color"` + Description string `json:"description"` + URL string `json:"url"` +} + +// CreateLabelOption options for creating a label +type CreateLabelOption struct { + // required:true + Name string `json:"name" binding:"Required"` + // example: false + Exclusive bool `json:"exclusive"` + // required:true + // example: #00aabb + Color string `json:"color" binding:"Required"` + Description string `json:"description"` + // example: false + IsArchived bool `json:"is_archived"` +} + +// EditLabelOption options for editing a label +type EditLabelOption struct { + Name *string `json:"name"` + // example: false + Exclusive *bool `json:"exclusive"` + // example: #00aabb + Color *string `json:"color"` + Description *string `json:"description"` + // example: false + IsArchived *bool `json:"is_archived"` +} + +// DeleteLabelOption options for deleting a label +type DeleteLabelsOption struct { + // swagger:strfmt date-time + Updated *time.Time `json:"updated_at"` +} + +// IssueLabelsOption a collection of labels +type IssueLabelsOption struct { + // Labels can be a list of integers representing label IDs + // or a list of strings representing label names + Labels []any `json:"labels"` + // swagger:strfmt date-time + Updated *time.Time `json:"updated_at"` +} + +// LabelTemplate info of a Label template +type LabelTemplate struct { + Name string `json:"name"` + // example: false + Exclusive bool `json:"exclusive"` + // example: 00aabb + Color string `json:"color"` + Description string `json:"description"` +} diff --git a/modules/structs/issue_milestone.go b/modules/structs/issue_milestone.go new file mode 100644 index 0000000..0518244 --- /dev/null +++ b/modules/structs/issue_milestone.go @@ -0,0 +1,44 @@ +// Copyright 2016 The Gogs Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package structs + +import ( + "time" +) + +// Milestone milestone is a collection of issues on one repository +type Milestone struct { + ID int64 `json:"id"` + Title string `json:"title"` + Description string `json:"description"` + State StateType `json:"state"` + OpenIssues int `json:"open_issues"` + ClosedIssues int `json:"closed_issues"` + // swagger:strfmt date-time + Created time.Time `json:"created_at"` + // swagger:strfmt date-time + Updated *time.Time `json:"updated_at"` + // swagger:strfmt date-time + Closed *time.Time `json:"closed_at"` + // swagger:strfmt date-time + Deadline *time.Time `json:"due_on"` +} + +// CreateMilestoneOption options for creating a milestone +type CreateMilestoneOption struct { + Title string `json:"title"` + Description string `json:"description"` + // swagger:strfmt date-time + Deadline *time.Time `json:"due_on"` + // enum: ["open", "closed"] + State string `json:"state"` +} + +// EditMilestoneOption options for editing a milestone +type EditMilestoneOption struct { + Title string `json:"title"` + Description *string `json:"description"` + State *string `json:"state"` + Deadline *time.Time `json:"due_on"` +} diff --git a/modules/structs/issue_reaction.go b/modules/structs/issue_reaction.go new file mode 100644 index 0000000..8d907a4 --- /dev/null +++ b/modules/structs/issue_reaction.go @@ -0,0 +1,21 @@ +// Copyright 2019 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package structs + +import ( + "time" +) + +// EditReactionOption contain the reaction type +type EditReactionOption struct { + Reaction string `json:"content"` +} + +// Reaction contain one reaction +type Reaction struct { + User *User `json:"user"` + Reaction string `json:"content"` + // swagger:strfmt date-time + Created time.Time `json:"created_at"` +} diff --git a/modules/structs/issue_stopwatch.go b/modules/structs/issue_stopwatch.go new file mode 100644 index 0000000..ceade1d --- /dev/null +++ b/modules/structs/issue_stopwatch.go @@ -0,0 +1,23 @@ +// Copyright 2019 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package structs + +import ( + "time" +) + +// StopWatch represent a running stopwatch +type StopWatch struct { + // swagger:strfmt date-time + Created time.Time `json:"created"` + Seconds int64 `json:"seconds"` + Duration string `json:"duration"` + IssueIndex int64 `json:"issue_index"` + IssueTitle string `json:"issue_title"` + RepoOwnerName string `json:"repo_owner_name"` + RepoName string `json:"repo_name"` +} + +// StopWatches represent a list of stopwatches +type StopWatches []StopWatch diff --git a/modules/structs/issue_test.go b/modules/structs/issue_test.go new file mode 100644 index 0000000..2003e22 --- /dev/null +++ b/modules/structs/issue_test.go @@ -0,0 +1,106 @@ +// Copyright 2022 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package structs + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "gopkg.in/yaml.v3" +) + +func TestIssueTemplate_Type(t *testing.T) { + tests := []struct { + fileName string + want IssueTemplateType + }{ + { + fileName: ".gitea/ISSUE_TEMPLATE/bug_report.yaml", + want: IssueTemplateTypeYaml, + }, + { + fileName: ".gitea/ISSUE_TEMPLATE/bug_report.md", + want: IssueTemplateTypeMarkdown, + }, + { + fileName: ".gitea/ISSUE_TEMPLATE/bug_report.txt", + want: "", + }, + { + fileName: ".gitea/ISSUE_TEMPLATE/config.yaml", + want: "", + }, + } + for _, tt := range tests { + t.Run(tt.fileName, func(t *testing.T) { + it := IssueTemplate{ + FileName: tt.fileName, + } + assert.Equal(t, tt.want, it.Type()) + }) + } +} + +func TestIssueTemplateLabels_UnmarshalYAML(t *testing.T) { + tests := []struct { + name string + content string + tmpl *IssueTemplate + want *IssueTemplate + wantErr string + }{ + { + name: "array", + content: `labels: ["a", "b", "c"]`, + tmpl: &IssueTemplate{ + Labels: []string{"should_be_overwrote"}, + }, + want: &IssueTemplate{ + Labels: []string{"a", "b", "c"}, + }, + }, + { + name: "string", + content: `labels: "a,b,c"`, + tmpl: &IssueTemplate{ + Labels: []string{"should_be_overwrote"}, + }, + want: &IssueTemplate{ + Labels: []string{"a", "b", "c"}, + }, + }, + { + name: "empty", + content: `labels:`, + tmpl: &IssueTemplate{ + Labels: []string{"should_be_overwrote"}, + }, + want: &IssueTemplate{ + Labels: nil, + }, + }, + { + name: "error", + content: ` +labels: + a: aa + b: bb +`, + tmpl: &IssueTemplate{}, + wantErr: "line 3: cannot unmarshal !!map into IssueTemplateLabels", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + err := yaml.Unmarshal([]byte(tt.content), tt.tmpl) + if tt.wantErr != "" { + assert.EqualError(t, err, tt.wantErr) + } else { + require.NoError(t, err) + assert.Equal(t, tt.want, tt.tmpl) + } + }) + } +} diff --git a/modules/structs/issue_tracked_time.go b/modules/structs/issue_tracked_time.go new file mode 100644 index 0000000..a3904af --- /dev/null +++ b/modules/structs/issue_tracked_time.go @@ -0,0 +1,37 @@ +// Copyright 2017 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package structs + +import ( + "time" +) + +// AddTimeOption options for adding time to an issue +type AddTimeOption struct { + // time in seconds + // required: true + Time int64 `json:"time" binding:"Required"` + // swagger:strfmt date-time + Created time.Time `json:"created"` + // User who spent the time (optional) + User string `json:"user_name"` +} + +// TrackedTime worked time for an issue / pr +type TrackedTime struct { + ID int64 `json:"id"` + // swagger:strfmt date-time + Created time.Time `json:"created"` + // Time in seconds + Time int64 `json:"time"` + // deprecated (only for backwards compatibility) + UserID int64 `json:"user_id"` + UserName string `json:"user_name"` + // deprecated (only for backwards compatibility) + IssueID int64 `json:"issue_id"` + Issue *Issue `json:"issue"` +} + +// TrackedTimeList represents a list of tracked times +type TrackedTimeList []*TrackedTime diff --git a/modules/structs/lfs_lock.go b/modules/structs/lfs_lock.go new file mode 100644 index 0000000..6b4c0bc --- /dev/null +++ b/modules/structs/lfs_lock.go @@ -0,0 +1,64 @@ +// Copyright 2017 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package structs + +import ( + "time" +) + +// LFSLock represent a lock +// for use with the locks API. +type LFSLock struct { + ID string `json:"id"` + Path string `json:"path"` + LockedAt time.Time `json:"locked_at"` + Owner *LFSLockOwner `json:"owner"` +} + +// LFSLockOwner represent a lock owner +// for use with the locks API. +type LFSLockOwner struct { + Name string `json:"name"` +} + +// LFSLockRequest contains the path of the lock to create +// https://github.com/git-lfs/git-lfs/blob/master/docs/api/locking.md#create-lock +type LFSLockRequest struct { + Path string `json:"path"` +} + +// LFSLockResponse represent a lock created +// https://github.com/git-lfs/git-lfs/blob/master/docs/api/locking.md#create-lock +type LFSLockResponse struct { + Lock *LFSLock `json:"lock"` +} + +// LFSLockList represent a list of lock requested +// https://github.com/git-lfs/git-lfs/blob/master/docs/api/locking.md#list-locks +type LFSLockList struct { + Locks []*LFSLock `json:"locks"` + Next string `json:"next_cursor,omitempty"` +} + +// LFSLockListVerify represent a list of lock verification requested +// https://github.com/git-lfs/git-lfs/blob/master/docs/api/locking.md#list-locks-for-verification +type LFSLockListVerify struct { + Ours []*LFSLock `json:"ours"` + Theirs []*LFSLock `json:"theirs"` + Next string `json:"next_cursor,omitempty"` +} + +// LFSLockError contains information on the error that occurs +type LFSLockError struct { + Message string `json:"message"` + Lock *LFSLock `json:"lock,omitempty"` + Documentation string `json:"documentation_url,omitempty"` + RequestID string `json:"request_id,omitempty"` +} + +// LFSLockDeleteRequest contains params of a delete request +// https://github.com/git-lfs/git-lfs/blob/master/docs/api/locking.md#delete-lock +type LFSLockDeleteRequest struct { + Force bool `json:"force"` +} diff --git a/modules/structs/mirror.go b/modules/structs/mirror.go new file mode 100644 index 0000000..1b65668 --- /dev/null +++ b/modules/structs/mirror.go @@ -0,0 +1,32 @@ +// Copyright 2021 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package structs + +import "time" + +// CreatePushMirrorOption represents need information to create a push mirror of a repository. +type CreatePushMirrorOption struct { + RemoteAddress string `json:"remote_address"` + RemoteUsername string `json:"remote_username"` + RemotePassword string `json:"remote_password"` + Interval string `json:"interval"` + SyncOnCommit bool `json:"sync_on_commit"` + UseSSH bool `json:"use_ssh"` +} + +// PushMirror represents information of a push mirror +// swagger:model +type PushMirror struct { + RepoName string `json:"repo_name"` + RemoteName string `json:"remote_name"` + RemoteAddress string `json:"remote_address"` + // swagger:strfmt date-time + CreatedUnix time.Time `json:"created"` + // swagger:strfmt date-time + LastUpdateUnix *time.Time `json:"last_update"` + LastError string `json:"last_error"` + Interval string `json:"interval"` + SyncOnCommit bool `json:"sync_on_commit"` + PublicKey string `json:"public_key"` +} diff --git a/modules/structs/miscellaneous.go b/modules/structs/miscellaneous.go new file mode 100644 index 0000000..bff10f9 --- /dev/null +++ b/modules/structs/miscellaneous.go @@ -0,0 +1,101 @@ +// Copyright 2015 The Gogs Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package structs + +// SearchResults results of a successful search +type SearchResults struct { + OK bool `json:"ok"` + Data []*Repository `json:"data"` +} + +// SearchError error of a failed search +type SearchError struct { + OK bool `json:"ok"` + Error string `json:"error"` +} + +// MarkupOption markup options +type MarkupOption struct { + // Text markup to render + // + // in: body + Text string + // Mode to render (comment, gfm, markdown, file) + // + // in: body + Mode string + // Context to render + // + // in: body + Context string + // Is it a wiki page ? + // + // in: body + Wiki bool + // File path for detecting extension in file mode + // + // in: body + FilePath string +} + +// MarkupRender is a rendered markup document +// swagger:response MarkupRender +type MarkupRender string + +// MarkdownOption markdown options +type MarkdownOption struct { + // Text markdown to render + // + // in: body + Text string + // Mode to render (comment, gfm, markdown) + // + // in: body + Mode string + // Context to render + // + // in: body + Context string + // Is it a wiki page ? + // + // in: body + Wiki bool +} + +// MarkdownRender is a rendered markdown document +// swagger:response MarkdownRender +type MarkdownRender string + +// ServerVersion wraps the version of the server +type ServerVersion struct { + Version string `json:"version"` +} + +// GitignoreTemplateInfo name and text of a gitignore template +type GitignoreTemplateInfo struct { + Name string `json:"name"` + Source string `json:"source"` +} + +// LicensesListEntry is used for the API +type LicensesTemplateListEntry struct { + Key string `json:"key"` + Name string `json:"name"` + URL string `json:"url"` +} + +// LicensesInfo contains information about a License +type LicenseTemplateInfo struct { + Key string `json:"key"` + Name string `json:"name"` + URL string `json:"url"` + Implementation string `json:"implementation"` + Body string `json:"body"` +} + +// APIError is an api error with a message +type APIError struct { + Message string `json:"message"` + URL string `json:"url"` +} diff --git a/modules/structs/moderation.go b/modules/structs/moderation.go new file mode 100644 index 0000000..c1e5508 --- /dev/null +++ b/modules/structs/moderation.go @@ -0,0 +1,13 @@ +// Copyright 2023 The Forgejo Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package structs + +import "time" + +// BlockedUser represents a blocked user. +type BlockedUser struct { + BlockID int64 `json:"block_id"` + // swagger:strfmt date-time + Created time.Time `json:"created_at"` +} diff --git a/modules/structs/nodeinfo.go b/modules/structs/nodeinfo.go new file mode 100644 index 0000000..802c8d3 --- /dev/null +++ b/modules/structs/nodeinfo.go @@ -0,0 +1,43 @@ +// Copyright 2021 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package structs + +// NodeInfo contains standardized way of exposing metadata about a server running one of the distributed social networks +type NodeInfo struct { + Version string `json:"version"` + Software NodeInfoSoftware `json:"software"` + Protocols []string `json:"protocols"` + Services NodeInfoServices `json:"services"` + OpenRegistrations bool `json:"openRegistrations"` + Usage NodeInfoUsage `json:"usage"` + Metadata struct{} `json:"metadata"` +} + +// NodeInfoSoftware contains Metadata about server software in use +type NodeInfoSoftware struct { + Name string `json:"name"` + Version string `json:"version"` + Repository string `json:"repository"` + Homepage string `json:"homepage"` +} + +// NodeInfoServices contains the third party sites this server can connect to via their application API +type NodeInfoServices struct { + Inbound []string `json:"inbound"` + Outbound []string `json:"outbound"` +} + +// NodeInfoUsage contains usage statistics for this server +type NodeInfoUsage struct { + Users NodeInfoUsageUsers `json:"users"` + LocalPosts int `json:"localPosts,omitempty"` + LocalComments int `json:"localComments,omitempty"` +} + +// NodeInfoUsageUsers contains statistics about the users of this server +type NodeInfoUsageUsers struct { + Total int `json:"total,omitempty"` + ActiveHalfyear int `json:"activeHalfyear,omitempty"` + ActiveMonth int `json:"activeMonth,omitempty"` +} diff --git a/modules/structs/notifications.go b/modules/structs/notifications.go new file mode 100644 index 0000000..7fbf4cb --- /dev/null +++ b/modules/structs/notifications.go @@ -0,0 +1,49 @@ +// Copyright 2019 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package structs + +import ( + "time" +) + +// NotificationThread expose Notification on API +type NotificationThread struct { + ID int64 `json:"id"` + Repository *Repository `json:"repository"` + Subject *NotificationSubject `json:"subject"` + Unread bool `json:"unread"` + Pinned bool `json:"pinned"` + UpdatedAt time.Time `json:"updated_at"` + URL string `json:"url"` +} + +// NotificationSubject contains the notification subject (Issue/Pull/Commit) +type NotificationSubject struct { + Title string `json:"title"` + URL string `json:"url"` + LatestCommentURL string `json:"latest_comment_url"` + HTMLURL string `json:"html_url"` + LatestCommentHTMLURL string `json:"latest_comment_html_url"` + Type NotifySubjectType `json:"type" binding:"In(Issue,Pull,Commit,Repository)"` + State StateType `json:"state"` +} + +// NotificationCount number of unread notifications +type NotificationCount struct { + New int64 `json:"new"` +} + +// NotifySubjectType represent type of notification subject +type NotifySubjectType string + +const ( + // NotifySubjectIssue an issue is subject of an notification + NotifySubjectIssue NotifySubjectType = "Issue" + // NotifySubjectPull an pull is subject of an notification + NotifySubjectPull NotifySubjectType = "Pull" + // NotifySubjectCommit an commit is subject of an notification + NotifySubjectCommit NotifySubjectType = "Commit" + // NotifySubjectRepository an repository is subject of an notification + NotifySubjectRepository NotifySubjectType = "Repository" +) diff --git a/modules/structs/org.go b/modules/structs/org.go new file mode 100644 index 0000000..b2b2c61 --- /dev/null +++ b/modules/structs/org.go @@ -0,0 +1,59 @@ +// Copyright 2015 The Gogs Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package structs + +// Organization represents an organization +type Organization struct { + ID int64 `json:"id"` + Name string `json:"name"` + FullName string `json:"full_name"` + Email string `json:"email"` + AvatarURL string `json:"avatar_url"` + Description string `json:"description"` + Website string `json:"website"` + Location string `json:"location"` + Visibility string `json:"visibility"` + RepoAdminChangeTeamAccess bool `json:"repo_admin_change_team_access"` + // deprecated + UserName string `json:"username"` +} + +// OrganizationPermissions list different users permissions on an organization +type OrganizationPermissions struct { + IsOwner bool `json:"is_owner"` + IsAdmin bool `json:"is_admin"` + CanWrite bool `json:"can_write"` + CanRead bool `json:"can_read"` + CanCreateRepository bool `json:"can_create_repository"` +} + +// CreateOrgOption options for creating an organization +type CreateOrgOption struct { + // required: true + UserName string `json:"username" binding:"Required;Username;MaxSize(40)"` + FullName string `json:"full_name" binding:"MaxSize(100)"` + Email string `json:"email" binding:"MaxSize(255)"` + Description string `json:"description" binding:"MaxSize(255)"` + Website string `json:"website" binding:"ValidUrl;MaxSize(255)"` + Location string `json:"location" binding:"MaxSize(50)"` + // possible values are `public` (default), `limited` or `private` + // enum: ["public", "limited", "private"] + Visibility string `json:"visibility" binding:"In(,public,limited,private)"` + RepoAdminChangeTeamAccess bool `json:"repo_admin_change_team_access"` +} + +// TODO: make EditOrgOption fields optional after https://gitea.com/go-chi/binding/pulls/5 got merged + +// EditOrgOption options for editing an organization +type EditOrgOption struct { + FullName string `json:"full_name" binding:"MaxSize(100)"` + Email string `json:"email" binding:"MaxSize(255)"` + Description string `json:"description" binding:"MaxSize(255)"` + Website string `json:"website" binding:"ValidUrl;MaxSize(255)"` + Location string `json:"location" binding:"MaxSize(50)"` + // possible values are `public`, `limited` or `private` + // enum: ["public", "limited", "private"] + Visibility string `json:"visibility" binding:"In(,public,limited,private)"` + RepoAdminChangeTeamAccess *bool `json:"repo_admin_change_team_access"` +} diff --git a/modules/structs/org_member.go b/modules/structs/org_member.go new file mode 100644 index 0000000..2df5099 --- /dev/null +++ b/modules/structs/org_member.go @@ -0,0 +1,9 @@ +// Copyright 2016 The Gogs Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package structs + +// AddOrgMembershipOption add user to organization options +type AddOrgMembershipOption struct { + Role string `json:"role" binding:"Required"` +} diff --git a/modules/structs/org_team.go b/modules/structs/org_team.go new file mode 100644 index 0000000..4417758 --- /dev/null +++ b/modules/structs/org_team.go @@ -0,0 +1,54 @@ +// Copyright 2016 The Gogs Authors. All rights reserved. +// Copyright 2018 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package structs + +// Team represents a team in an organization +type Team struct { + ID int64 `json:"id"` + Name string `json:"name"` + Description string `json:"description"` + Organization *Organization `json:"organization"` + IncludesAllRepositories bool `json:"includes_all_repositories"` + // enum: ["none", "read", "write", "admin", "owner"] + Permission string `json:"permission"` + // example: ["repo.code","repo.issues","repo.ext_issues","repo.wiki","repo.pulls","repo.releases","repo.projects","repo.ext_wiki"] + // Deprecated: This variable should be replaced by UnitsMap and will be dropped in later versions. + Units []string `json:"units"` + // example: {"repo.code":"read","repo.issues":"write","repo.ext_issues":"none","repo.wiki":"admin","repo.pulls":"owner","repo.releases":"none","repo.projects":"none","repo.ext_wiki":"none"} + UnitsMap map[string]string `json:"units_map"` + CanCreateOrgRepo bool `json:"can_create_org_repo"` +} + +// CreateTeamOption options for creating a team +type CreateTeamOption struct { + // required: true + Name string `json:"name" binding:"Required;AlphaDashDot;MaxSize(255)"` + Description string `json:"description" binding:"MaxSize(255)"` + IncludesAllRepositories bool `json:"includes_all_repositories"` + // enum: ["read", "write", "admin"] + Permission string `json:"permission"` + // example: ["repo.actions","repo.code","repo.issues","repo.ext_issues","repo.wiki","repo.ext_wiki","repo.pulls","repo.releases","repo.projects","repo.ext_wiki"] + // Deprecated: This variable should be replaced by UnitsMap and will be dropped in later versions. + Units []string `json:"units"` + // example: {"repo.actions","repo.packages","repo.code":"read","repo.issues":"write","repo.ext_issues":"none","repo.wiki":"admin","repo.pulls":"owner","repo.releases":"none","repo.projects":"none","repo.ext_wiki":"none"} + UnitsMap map[string]string `json:"units_map"` + CanCreateOrgRepo bool `json:"can_create_org_repo"` +} + +// EditTeamOption options for editing a team +type EditTeamOption struct { + // required: true + Name string `json:"name" binding:"AlphaDashDot;MaxSize(255)"` + Description *string `json:"description" binding:"MaxSize(255)"` + IncludesAllRepositories *bool `json:"includes_all_repositories"` + // enum: ["read", "write", "admin"] + Permission string `json:"permission"` + // example: ["repo.code","repo.issues","repo.ext_issues","repo.wiki","repo.pulls","repo.releases","repo.projects","repo.ext_wiki"] + // Deprecated: This variable should be replaced by UnitsMap and will be dropped in later versions. + Units []string `json:"units"` + // example: {"repo.code":"read","repo.issues":"write","repo.ext_issues":"none","repo.wiki":"admin","repo.pulls":"owner","repo.releases":"none","repo.projects":"none","repo.ext_wiki":"none"} + UnitsMap map[string]string `json:"units_map"` + CanCreateOrgRepo *bool `json:"can_create_org_repo"` +} diff --git a/modules/structs/package.go b/modules/structs/package.go new file mode 100644 index 0000000..a9a9429 --- /dev/null +++ b/modules/structs/package.go @@ -0,0 +1,33 @@ +// Copyright 2021 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package structs + +import ( + "time" +) + +// Package represents a package +type Package struct { + ID int64 `json:"id"` + Owner *User `json:"owner"` + Repository *Repository `json:"repository"` + Creator *User `json:"creator"` + Type string `json:"type"` + Name string `json:"name"` + Version string `json:"version"` + HTMLURL string `json:"html_url"` + // swagger:strfmt date-time + CreatedAt time.Time `json:"created_at"` +} + +// PackageFile represents a package file +type PackageFile struct { + ID int64 `json:"id"` + Size int64 + Name string `json:"name"` + HashMD5 string `json:"md5"` + HashSHA1 string `json:"sha1"` + HashSHA256 string `json:"sha256"` + HashSHA512 string `json:"sha512"` +} diff --git a/modules/structs/pull.go b/modules/structs/pull.go new file mode 100644 index 0000000..ab62766 --- /dev/null +++ b/modules/structs/pull.go @@ -0,0 +1,119 @@ +// Copyright 2016 The Gogs Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package structs + +import ( + "time" +) + +// PullRequest represents a pull request +type PullRequest struct { + ID int64 `json:"id"` + URL string `json:"url"` + Index int64 `json:"number"` + Poster *User `json:"user"` + Title string `json:"title"` + Body string `json:"body"` + Labels []*Label `json:"labels"` + Milestone *Milestone `json:"milestone"` + Assignee *User `json:"assignee"` + Assignees []*User `json:"assignees"` + RequestedReviewers []*User `json:"requested_reviewers"` + RequestedReviewersTeams []*Team `json:"requested_reviewers_teams"` + State StateType `json:"state"` + Draft bool `json:"draft"` + IsLocked bool `json:"is_locked"` + Comments int `json:"comments"` + // number of review comments made on the diff of a PR review (not including comments on commits or issues in a PR) + ReviewComments int `json:"review_comments"` + Additions int `json:"additions"` + Deletions int `json:"deletions"` + ChangedFiles int `json:"changed_files"` + + HTMLURL string `json:"html_url"` + DiffURL string `json:"diff_url"` + PatchURL string `json:"patch_url"` + + Mergeable bool `json:"mergeable"` + HasMerged bool `json:"merged"` + // swagger:strfmt date-time + Merged *time.Time `json:"merged_at"` + MergedCommitID *string `json:"merge_commit_sha"` + MergedBy *User `json:"merged_by"` + AllowMaintainerEdit bool `json:"allow_maintainer_edit"` + + Base *PRBranchInfo `json:"base"` + Head *PRBranchInfo `json:"head"` + MergeBase string `json:"merge_base"` + + // swagger:strfmt date-time + Deadline *time.Time `json:"due_date"` + + // swagger:strfmt date-time + Created *time.Time `json:"created_at"` + // swagger:strfmt date-time + Updated *time.Time `json:"updated_at"` + // swagger:strfmt date-time + Closed *time.Time `json:"closed_at"` + + PinOrder int `json:"pin_order"` +} + +// PRBranchInfo information about a branch +type PRBranchInfo struct { + Name string `json:"label"` + Ref string `json:"ref"` + Sha string `json:"sha"` + RepoID int64 `json:"repo_id"` + Repository *Repository `json:"repo"` +} + +// ListPullRequestsOptions options for listing pull requests +type ListPullRequestsOptions struct { + Page int `json:"page"` + State string `json:"state"` +} + +// CreatePullRequestOption options when creating a pull request +type CreatePullRequestOption struct { + Head string `json:"head" binding:"Required"` + Base string `json:"base" binding:"Required"` + Title string `json:"title" binding:"Required"` + Body string `json:"body"` + Assignee string `json:"assignee"` + Assignees []string `json:"assignees"` + Milestone int64 `json:"milestone"` + Labels []int64 `json:"labels"` + // swagger:strfmt date-time + Deadline *time.Time `json:"due_date"` +} + +// EditPullRequestOption options when modify pull request +type EditPullRequestOption struct { + Title string `json:"title"` + Body *string `json:"body"` + Base string `json:"base"` + Assignee string `json:"assignee"` + Assignees []string `json:"assignees"` + Milestone int64 `json:"milestone"` + Labels []int64 `json:"labels"` + State *string `json:"state"` + // swagger:strfmt date-time + Deadline *time.Time `json:"due_date"` + RemoveDeadline *bool `json:"unset_due_date"` + AllowMaintainerEdit *bool `json:"allow_maintainer_edit"` +} + +// ChangedFile store information about files affected by the pull request +type ChangedFile struct { + Filename string `json:"filename"` + PreviousFilename string `json:"previous_filename,omitempty"` + Status string `json:"status"` + Additions int `json:"additions"` + Deletions int `json:"deletions"` + Changes int `json:"changes"` + HTMLURL string `json:"html_url,omitempty"` + ContentsURL string `json:"contents_url,omitempty"` + RawURL string `json:"raw_url,omitempty"` +} diff --git a/modules/structs/pull_review.go b/modules/structs/pull_review.go new file mode 100644 index 0000000..c77ebea --- /dev/null +++ b/modules/structs/pull_review.go @@ -0,0 +1,111 @@ +// Copyright 2020 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package structs + +import ( + "time" +) + +// ReviewStateType review state type +type ReviewStateType string + +const ( + // ReviewStateApproved pr is approved + ReviewStateApproved ReviewStateType = "APPROVED" + // ReviewStatePending pr state is pending + ReviewStatePending ReviewStateType = "PENDING" + // ReviewStateComment is a comment review + ReviewStateComment ReviewStateType = "COMMENT" + // ReviewStateRequestChanges changes for pr are requested + ReviewStateRequestChanges ReviewStateType = "REQUEST_CHANGES" + // ReviewStateRequestReview review is requested from user + ReviewStateRequestReview ReviewStateType = "REQUEST_REVIEW" + // ReviewStateUnknown state of pr is unknown + ReviewStateUnknown ReviewStateType = "" +) + +// PullReview represents a pull request review +type PullReview struct { + ID int64 `json:"id"` + Reviewer *User `json:"user"` + ReviewerTeam *Team `json:"team"` + State ReviewStateType `json:"state"` + Body string `json:"body"` + CommitID string `json:"commit_id"` + Stale bool `json:"stale"` + Official bool `json:"official"` + Dismissed bool `json:"dismissed"` + CodeCommentsCount int `json:"comments_count"` + // swagger:strfmt date-time + Submitted time.Time `json:"submitted_at"` + // swagger:strfmt date-time + Updated time.Time `json:"updated_at"` + + HTMLURL string `json:"html_url"` + HTMLPullURL string `json:"pull_request_url"` +} + +// PullReviewComment represents a comment on a pull request review +type PullReviewComment struct { + ID int64 `json:"id"` + Body string `json:"body"` + Poster *User `json:"user"` + Resolver *User `json:"resolver"` + ReviewID int64 `json:"pull_request_review_id"` + + // swagger:strfmt date-time + Created time.Time `json:"created_at"` + // swagger:strfmt date-time + Updated time.Time `json:"updated_at"` + + Path string `json:"path"` + CommitID string `json:"commit_id"` + OrigCommitID string `json:"original_commit_id"` + DiffHunk string `json:"diff_hunk"` + LineNum uint64 `json:"position"` + OldLineNum uint64 `json:"original_position"` + + HTMLURL string `json:"html_url"` + HTMLPullURL string `json:"pull_request_url"` +} + +// CreatePullReviewOptions are options to create a pull review +type CreatePullReviewOptions struct { + Event ReviewStateType `json:"event"` + Body string `json:"body"` + CommitID string `json:"commit_id"` + Comments []CreatePullReviewComment `json:"comments"` +} + +// CreatePullReviewComment represent a review comment for creation api +type CreatePullReviewComment struct { + // the tree path + Path string `json:"path"` + Body string `json:"body"` + // if comment to old file line or 0 + OldLineNum int64 `json:"old_position"` + // if comment to new file line or 0 + NewLineNum int64 `json:"new_position"` +} + +// CreatePullReviewCommentOptions are options to create a pull review comment +type CreatePullReviewCommentOptions CreatePullReviewComment + +// SubmitPullReviewOptions are options to submit a pending pull review +type SubmitPullReviewOptions struct { + Event ReviewStateType `json:"event"` + Body string `json:"body"` +} + +// DismissPullReviewOptions are options to dismiss a pull review +type DismissPullReviewOptions struct { + Message string `json:"message"` + Priors bool `json:"priors"` +} + +// PullReviewRequestOptions are options to add or remove pull review requests +type PullReviewRequestOptions struct { + Reviewers []string `json:"reviewers"` + TeamReviewers []string `json:"team_reviewers"` +} diff --git a/modules/structs/quota.go b/modules/structs/quota.go new file mode 100644 index 0000000..cb8874a --- /dev/null +++ b/modules/structs/quota.go @@ -0,0 +1,163 @@ +// Copyright 2024 The Forgejo Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package structs + +// QuotaInfo represents information about a user's quota +type QuotaInfo struct { + Used QuotaUsed `json:"used"` + Groups QuotaGroupList `json:"groups"` +} + +// QuotaUsed represents the quota usage of a user +type QuotaUsed struct { + Size QuotaUsedSize `json:"size"` +} + +// QuotaUsedSize represents the size-based quota usage of a user +type QuotaUsedSize struct { + Repos QuotaUsedSizeRepos `json:"repos"` + Git QuotaUsedSizeGit `json:"git"` + Assets QuotaUsedSizeAssets `json:"assets"` +} + +// QuotaUsedSizeRepos represents the size-based repository quota usage of a user +type QuotaUsedSizeRepos struct { + // Storage size of the user's public repositories + Public int64 `json:"public"` + // Storage size of the user's private repositories + Private int64 `json:"private"` +} + +// QuotaUsedSizeGit represents the size-based git (lfs) quota usage of a user +type QuotaUsedSizeGit struct { + // Storage size of the user's Git LFS objects + LFS int64 `json:"LFS"` +} + +// QuotaUsedSizeAssets represents the size-based asset usage of a user +type QuotaUsedSizeAssets struct { + Attachments QuotaUsedSizeAssetsAttachments `json:"attachments"` + // Storage size used for the user's artifacts + Artifacts int64 `json:"artifacts"` + Packages QuotaUsedSizeAssetsPackages `json:"packages"` +} + +// QuotaUsedSizeAssetsAttachments represents the size-based attachment quota usage of a user +type QuotaUsedSizeAssetsAttachments struct { + // Storage size used for the user's issue & comment attachments + Issues int64 `json:"issues"` + // Storage size used for the user's release attachments + Releases int64 `json:"releases"` +} + +// QuotaUsedSizeAssetsPackages represents the size-based package quota usage of a user +type QuotaUsedSizeAssetsPackages struct { + // Storage suze used for the user's packages + All int64 `json:"all"` +} + +// QuotaRuleInfo contains information about a quota rule +type QuotaRuleInfo struct { + // Name of the rule (only shown to admins) + Name string `json:"name,omitempty"` + // The limit set by the rule + Limit int64 `json:"limit"` + // Subjects the rule affects + Subjects []string `json:"subjects,omitempty"` +} + +// QuotaGroupList represents a list of quota groups +type QuotaGroupList []QuotaGroup + +// QuotaGroup represents a quota group +type QuotaGroup struct { + // Name of the group + Name string `json:"name,omitempty"` + // Rules associated with the group + Rules []QuotaRuleInfo `json:"rules"` +} + +// CreateQutaGroupOptions represents the options for creating a quota group +type CreateQuotaGroupOptions struct { + // Name of the quota group to create + Name string `json:"name" binding:"Required"` + // Rules to add to the newly created group. + // If a rule does not exist, it will be created. + Rules []CreateQuotaRuleOptions `json:"rules"` +} + +// CreateQuotaRuleOptions represents the options for creating a quota rule +type CreateQuotaRuleOptions struct { + // Name of the rule to create + Name string `json:"name" binding:"Required"` + // The limit set by the rule + Limit *int64 `json:"limit"` + // The subjects affected by the rule + Subjects []string `json:"subjects"` +} + +// EditQuotaRuleOptions represents the options for editing a quota rule +type EditQuotaRuleOptions struct { + // The limit set by the rule + Limit *int64 `json:"limit"` + // The subjects affected by the rule + Subjects *[]string `json:"subjects"` +} + +// SetUserQuotaGroupsOptions represents the quota groups of a user +type SetUserQuotaGroupsOptions struct { + // Quota groups the user shall have + // required: true + Groups *[]string `json:"groups"` +} + +// QuotaUsedAttachmentList represents a list of attachment counting towards a user's quota +type QuotaUsedAttachmentList []*QuotaUsedAttachment + +// QuotaUsedAttachment represents an attachment counting towards a user's quota +type QuotaUsedAttachment struct { + // Filename of the attachment + Name string `json:"name"` + // Size of the attachment (in bytes) + Size int64 `json:"size"` + // API URL for the attachment + APIURL string `json:"api_url"` + // Context for the attachment: URLs to the containing object + ContainedIn struct { + // API URL for the object that contains this attachment + APIURL string `json:"api_url"` + // HTML URL for the object that contains this attachment + HTMLURL string `json:"html_url"` + } `json:"contained_in"` +} + +// QuotaUsedPackageList represents a list of packages counting towards a user's quota +type QuotaUsedPackageList []*QuotaUsedPackage + +// QuotaUsedPackage represents a package counting towards a user's quota +type QuotaUsedPackage struct { + // Name of the package + Name string `json:"name"` + // Type of the package + Type string `json:"type"` + // Version of the package + Version string `json:"version"` + // Size of the package version + Size int64 `json:"size"` + // HTML URL to the package version + HTMLURL string `json:"html_url"` +} + +// QuotaUsedArtifactList represents a list of artifacts counting towards a user's quota +type QuotaUsedArtifactList []*QuotaUsedArtifact + +// QuotaUsedArtifact represents an artifact counting towards a user's quota +type QuotaUsedArtifact struct { + // Name of the artifact + Name string `json:"name"` + // Size of the artifact (compressed) + Size int64 `json:"size"` + // HTML URL to the action run containing the artifact + HTMLURL string `json:"html_url"` +} diff --git a/modules/structs/release.go b/modules/structs/release.go new file mode 100644 index 0000000..d8da924 --- /dev/null +++ b/modules/structs/release.go @@ -0,0 +1,55 @@ +// Copyright 2016 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package structs + +import ( + "time" +) + +// Release represents a repository release +type Release struct { + ID int64 `json:"id"` + TagName string `json:"tag_name"` + Target string `json:"target_commitish"` + Title string `json:"name"` + Note string `json:"body"` + URL string `json:"url"` + HTMLURL string `json:"html_url"` + TarURL string `json:"tarball_url"` + ZipURL string `json:"zipball_url"` + HideArchiveLinks bool `json:"hide_archive_links"` + UploadURL string `json:"upload_url"` + IsDraft bool `json:"draft"` + IsPrerelease bool `json:"prerelease"` + // swagger:strfmt date-time + CreatedAt time.Time `json:"created_at"` + // swagger:strfmt date-time + PublishedAt time.Time `json:"published_at"` + Publisher *User `json:"author"` + Attachments []*Attachment `json:"assets"` + ArchiveDownloadCount *TagArchiveDownloadCount `json:"archive_download_count"` +} + +// CreateReleaseOption options when creating a release +type CreateReleaseOption struct { + // required: true + TagName string `json:"tag_name" binding:"Required"` + Target string `json:"target_commitish"` + Title string `json:"name"` + Note string `json:"body"` + IsDraft bool `json:"draft"` + IsPrerelease bool `json:"prerelease"` + HideArchiveLinks bool `json:"hide_archive_links"` +} + +// EditReleaseOption options when editing a release +type EditReleaseOption struct { + TagName string `json:"tag_name"` + Target string `json:"target_commitish"` + Title string `json:"name"` + Note string `json:"body"` + IsDraft *bool `json:"draft"` + IsPrerelease *bool `json:"prerelease"` + HideArchiveLinks *bool `json:"hide_archive_links"` +} diff --git a/modules/structs/repo.go b/modules/structs/repo.go new file mode 100644 index 0000000..f2fe9c7 --- /dev/null +++ b/modules/structs/repo.go @@ -0,0 +1,421 @@ +// Copyright 2014 The Gogs Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package structs + +import ( + "strings" + "time" +) + +// Permission represents a set of permissions +type Permission struct { + Admin bool `json:"admin"` // Admin indicates if the user is an administrator of the repository. + Push bool `json:"push"` // Push indicates if the user can push code to the repository. + Pull bool `json:"pull"` // Pull indicates if the user can pull code from the repository. +} + +// InternalTracker represents settings for internal tracker +// swagger:model +type InternalTracker struct { + // Enable time tracking (Built-in issue tracker) + EnableTimeTracker bool `json:"enable_time_tracker"` + // Let only contributors track time (Built-in issue tracker) + AllowOnlyContributorsToTrackTime bool `json:"allow_only_contributors_to_track_time"` + // Enable dependencies for issues and pull requests (Built-in issue tracker) + EnableIssueDependencies bool `json:"enable_issue_dependencies"` +} + +// ExternalTracker represents settings for external tracker +// swagger:model +type ExternalTracker struct { + // URL of external issue tracker. + ExternalTrackerURL string `json:"external_tracker_url"` + // External Issue Tracker URL Format. Use the placeholders {user}, {repo} and {index} for the username, repository name and issue index. + ExternalTrackerFormat string `json:"external_tracker_format"` + // External Issue Tracker Number Format, either `numeric`, `alphanumeric`, or `regexp` + ExternalTrackerStyle string `json:"external_tracker_style"` + // External Issue Tracker issue regular expression + ExternalTrackerRegexpPattern string `json:"external_tracker_regexp_pattern"` +} + +// ExternalWiki represents setting for external wiki +// swagger:model +type ExternalWiki struct { + // URL of external wiki. + ExternalWikiURL string `json:"external_wiki_url"` +} + +// Repository represents a repository +type Repository struct { + ID int64 `json:"id"` + Owner *User `json:"owner"` + Name string `json:"name"` + FullName string `json:"full_name"` + Description string `json:"description"` + Empty bool `json:"empty"` + Private bool `json:"private"` + Fork bool `json:"fork"` + Template bool `json:"template"` + Parent *Repository `json:"parent"` + Mirror bool `json:"mirror"` + Size int `json:"size"` + Language string `json:"language"` + LanguagesURL string `json:"languages_url"` + HTMLURL string `json:"html_url"` + URL string `json:"url"` + Link string `json:"link"` + SSHURL string `json:"ssh_url"` + CloneURL string `json:"clone_url"` + OriginalURL string `json:"original_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"` + OpenPulls int `json:"open_pr_counter"` + Releases int `json:"release_counter"` + DefaultBranch string `json:"default_branch"` + Archived bool `json:"archived"` + // swagger:strfmt date-time + Created time.Time `json:"created_at"` + // swagger:strfmt date-time + Updated time.Time `json:"updated_at"` + ArchivedAt time.Time `json:"archived_at"` + Permissions *Permission `json:"permissions,omitempty"` + HasIssues bool `json:"has_issues"` + InternalTracker *InternalTracker `json:"internal_tracker,omitempty"` + ExternalTracker *ExternalTracker `json:"external_tracker,omitempty"` + HasWiki bool `json:"has_wiki"` + ExternalWiki *ExternalWiki `json:"external_wiki,omitempty"` + WikiBranch string `json:"wiki_branch,omitempty"` + GloballyEditableWiki bool `json:"globally_editable_wiki"` + HasPullRequests bool `json:"has_pull_requests"` + HasProjects bool `json:"has_projects"` + HasReleases bool `json:"has_releases"` + HasPackages bool `json:"has_packages"` + HasActions bool `json:"has_actions"` + IgnoreWhitespaceConflicts bool `json:"ignore_whitespace_conflicts"` + AllowMerge bool `json:"allow_merge_commits"` + AllowRebase bool `json:"allow_rebase"` + AllowRebaseMerge bool `json:"allow_rebase_explicit"` + AllowSquash bool `json:"allow_squash_merge"` + AllowFastForwardOnly bool `json:"allow_fast_forward_only_merge"` + AllowRebaseUpdate bool `json:"allow_rebase_update"` + DefaultDeleteBranchAfterMerge bool `json:"default_delete_branch_after_merge"` + DefaultMergeStyle string `json:"default_merge_style"` + DefaultAllowMaintainerEdit bool `json:"default_allow_maintainer_edit"` + AvatarURL string `json:"avatar_url"` + Internal bool `json:"internal"` + MirrorInterval string `json:"mirror_interval"` + // ObjectFormatName of the underlying git repository + // enum: ["sha1", "sha256"] + ObjectFormatName string `json:"object_format_name"` + // swagger:strfmt date-time + MirrorUpdated time.Time `json:"mirror_updated,omitempty"` + RepoTransfer *RepoTransfer `json:"repo_transfer"` + Topics []string `json:"topics"` +} + +// GetName implements the gitrepo.Repository interface +func (r Repository) GetName() string { + return r.Name +} + +// GetOwnerName implements the gitrepo.Repository interface +func (r Repository) GetOwnerName() string { + return r.Owner.UserName +} + +// CreateRepoOption options when creating repository +// swagger:model +type CreateRepoOption struct { + // Name of the repository to create + // + // required: true + // unique: true + Name string `json:"name" binding:"Required;AlphaDashDot;MaxSize(100)"` + // Description of the repository to create + Description string `json:"description" binding:"MaxSize(2048)"` + // Whether the repository is private + Private bool `json:"private"` + // Label-Set to use + IssueLabels string `json:"issue_labels"` + // Whether the repository should be auto-initialized? + AutoInit bool `json:"auto_init"` + // Whether the repository is template + Template bool `json:"template"` + // Gitignores to use + Gitignores string `json:"gitignores"` + // License to use + License string `json:"license"` + // Readme of the repository to create + Readme string `json:"readme"` + // DefaultBranch of the repository (used when initializes and in template) + DefaultBranch string `json:"default_branch" binding:"GitRefName;MaxSize(100)"` + // TrustModel of the repository + // enum: ["default", "collaborator", "committer", "collaboratorcommitter"] + TrustModel string `json:"trust_model"` + // ObjectFormatName of the underlying git repository + // enum: ["sha1", "sha256"] + ObjectFormatName string `json:"object_format_name" binding:"MaxSize(6)"` +} + +// EditRepoOption options when editing a repository's properties +// swagger:model +type EditRepoOption struct { + // name of the repository + // unique: true + Name *string `json:"name,omitempty" binding:"OmitEmpty;AlphaDashDot;MaxSize(100);"` + // a short description of the repository. + Description *string `json:"description,omitempty" binding:"MaxSize(2048)"` + // a URL with more information about the repository. + Website *string `json:"website,omitempty" binding:"MaxSize(1024)"` + // either `true` to make the repository private or `false` to make it public. + // Note: you will get a 422 error if the organization restricts changing repository visibility to organization + // owners and a non-owner tries to change the value of private. + Private *bool `json:"private,omitempty"` + // either `true` to make this repository a template or `false` to make it a normal repository + Template *bool `json:"template,omitempty"` + // either `true` to enable issues for this repository or `false` to disable them. + HasIssues *bool `json:"has_issues,omitempty"` + // set this structure to configure internal issue tracker + InternalTracker *InternalTracker `json:"internal_tracker,omitempty"` + // set this structure to use external issue tracker + ExternalTracker *ExternalTracker `json:"external_tracker,omitempty"` + // either `true` to enable the wiki for this repository or `false` to disable it. + HasWiki *bool `json:"has_wiki,omitempty"` + // set this structure to use external wiki instead of internal + ExternalWiki *ExternalWiki `json:"external_wiki,omitempty"` + // set the globally editable state of the wiki + GloballyEditableWiki *bool `json:"globally_editable_wiki,omitempty"` + // sets the default branch for this repository. + DefaultBranch *string `json:"default_branch,omitempty"` + // sets the branch used for this repository's wiki. + WikiBranch *string `json:"wiki_branch,omitempty"` + // either `true` to allow pull requests, or `false` to prevent pull request. + HasPullRequests *bool `json:"has_pull_requests,omitempty"` + // either `true` to enable project unit, or `false` to disable them. + HasProjects *bool `json:"has_projects,omitempty"` + // either `true` to enable releases unit, or `false` to disable them. + HasReleases *bool `json:"has_releases,omitempty"` + // either `true` to enable packages unit, or `false` to disable them. + HasPackages *bool `json:"has_packages,omitempty"` + // either `true` to enable actions unit, or `false` to disable them. + HasActions *bool `json:"has_actions,omitempty"` + // either `true` to ignore whitespace for conflicts, or `false` to not ignore whitespace. + IgnoreWhitespaceConflicts *bool `json:"ignore_whitespace_conflicts,omitempty"` + // either `true` to allow merging pull requests with a merge commit, or `false` to prevent merging pull requests with merge commits. + AllowMerge *bool `json:"allow_merge_commits,omitempty"` + // either `true` to allow rebase-merging pull requests, or `false` to prevent rebase-merging. + AllowRebase *bool `json:"allow_rebase,omitempty"` + // either `true` to allow rebase with explicit merge commits (--no-ff), or `false` to prevent rebase with explicit merge commits. + AllowRebaseMerge *bool `json:"allow_rebase_explicit,omitempty"` + // either `true` to allow squash-merging pull requests, or `false` to prevent squash-merging. + AllowSquash *bool `json:"allow_squash_merge,omitempty"` + // either `true` to allow fast-forward-only merging pull requests, or `false` to prevent fast-forward-only merging. + AllowFastForwardOnly *bool `json:"allow_fast_forward_only_merge,omitempty"` + // either `true` to allow mark pr as merged manually, or `false` to prevent it. + AllowManualMerge *bool `json:"allow_manual_merge,omitempty"` + // either `true` to enable AutodetectManualMerge, or `false` to prevent it. Note: In some special cases, misjudgments can occur. + AutodetectManualMerge *bool `json:"autodetect_manual_merge,omitempty"` + // either `true` to allow updating pull request branch by rebase, or `false` to prevent it. + AllowRebaseUpdate *bool `json:"allow_rebase_update,omitempty"` + // set to `true` to delete pr branch after merge by default + DefaultDeleteBranchAfterMerge *bool `json:"default_delete_branch_after_merge,omitempty"` + // set to a merge style to be used by this repository: "merge", "rebase", "rebase-merge", "squash", or "fast-forward-only". + DefaultMergeStyle *string `json:"default_merge_style,omitempty"` + // set to `true` to allow edits from maintainers by default + DefaultAllowMaintainerEdit *bool `json:"default_allow_maintainer_edit,omitempty"` + // set to `true` to archive this repository. + Archived *bool `json:"archived,omitempty"` + // set to a string like `8h30m0s` to set the mirror interval time + MirrorInterval *string `json:"mirror_interval,omitempty"` + // enable prune - remove obsolete remote-tracking references when mirroring + EnablePrune *bool `json:"enable_prune,omitempty"` +} + +// GenerateRepoOption options when creating repository using a template +// swagger:model +type GenerateRepoOption struct { + // The organization or person who will own the new repository + // + // required: true + Owner string `json:"owner"` + // Name of the repository to create + // + // required: true + // unique: true + Name string `json:"name" binding:"Required;AlphaDashDot;MaxSize(100)"` + // Default branch of the new repository + DefaultBranch string `json:"default_branch"` + // Description of the repository to create + Description string `json:"description" binding:"MaxSize(2048)"` + // Whether the repository is private + Private bool `json:"private"` + // include git content of default branch in template repo + GitContent bool `json:"git_content"` + // include topics in template repo + Topics bool `json:"topics"` + // include git hooks in template repo + GitHooks bool `json:"git_hooks"` + // include webhooks in template repo + Webhooks bool `json:"webhooks"` + // include avatar of the template repo + Avatar bool `json:"avatar"` + // include labels in template repo + Labels bool `json:"labels"` + // include protected branches in template repo + ProtectedBranch bool `json:"protected_branch"` +} + +// CreateBranchRepoOption options when creating a branch in a repository +// swagger:model +type CreateBranchRepoOption struct { + // Name of the branch to create + // + // required: true + // unique: true + BranchName string `json:"new_branch_name" binding:"Required;GitRefName;MaxSize(100)"` + + // Deprecated: true + // Name of the old branch to create from + // + // unique: true + OldBranchName string `json:"old_branch_name" binding:"GitRefName;MaxSize(100)"` + + // Name of the old branch/tag/commit to create from + // + // unique: true + OldRefName string `json:"old_ref_name" binding:"GitRefName;MaxSize(100)"` +} + +// TransferRepoOption options when transfer a repository's ownership +// swagger:model +type TransferRepoOption struct { + // required: true + NewOwner string `json:"new_owner"` + // ID of the team or teams to add to the repository. Teams can only be added to organization-owned repositories. + TeamIDs *[]int64 `json:"team_ids"` +} + +// GitServiceType represents a git service +type GitServiceType int + +// enumerate all GitServiceType +const ( + NotMigrated GitServiceType = iota // 0 not migrated from external sites + PlainGitService // 1 plain git service + GithubService // 2 github.com + GiteaService // 3 gitea service + GitlabService // 4 gitlab service + GogsService // 5 gogs service + OneDevService // 6 onedev service + GitBucketService // 7 gitbucket service + CodebaseService // 8 codebase service + ForgejoService // 9 forgejo service +) + +// Name represents the service type's name +// WARNING: the name have to be equal to that on goth's library +func (gt GitServiceType) Name() string { + return strings.ToLower(gt.Title()) +} + +// Title represents the service type's proper title +func (gt GitServiceType) Title() string { + switch gt { + case GithubService: + return "GitHub" + case GiteaService: + return "Gitea" + case GitlabService: + return "GitLab" + case GogsService: + return "Gogs" + case OneDevService: + return "OneDev" + case GitBucketService: + return "GitBucket" + case CodebaseService: + return "Codebase" + case ForgejoService: + return "Forgejo" + case PlainGitService: + return "Git" + } + return "" +} + +// MigrateRepoOptions options for migrating repository's +// this is used to interact with api v1 +type MigrateRepoOptions struct { + // required: true + CloneAddr string `json:"clone_addr" binding:"Required"` + // deprecated (only for backwards compatibility) + RepoOwnerID int64 `json:"uid"` + // Name of User or Organisation who will own Repo after migration + RepoOwner string `json:"repo_owner"` + // required: true + RepoName string `json:"repo_name" binding:"Required;AlphaDashDot;MaxSize(100)"` + + // enum: ["git", "github", "gitea", "gitlab", "gogs", "onedev", "gitbucket", "codebase"] + Service string `json:"service"` + AuthUsername string `json:"auth_username"` + AuthPassword string `json:"auth_password"` + AuthToken string `json:"auth_token"` + + Mirror bool `json:"mirror"` + LFS bool `json:"lfs"` + LFSEndpoint string `json:"lfs_endpoint"` + Private bool `json:"private"` + Description string `json:"description" binding:"MaxSize(2048)"` + Wiki bool `json:"wiki"` + Milestones bool `json:"milestones"` + Labels bool `json:"labels"` + Issues bool `json:"issues"` + PullRequests bool `json:"pull_requests"` + Releases bool `json:"releases"` + MirrorInterval string `json:"mirror_interval"` +} + +// TokenAuth represents whether a service type supports token-based auth +func (gt GitServiceType) TokenAuth() bool { + switch gt { + case GithubService, GiteaService, GitlabService, ForgejoService: + return true + } + return false +} + +// SupportedFullGitService represents all git services supported to migrate issues/labels/prs and etc. +// TODO: add to this list after new git service added +var SupportedFullGitService = []GitServiceType{ + GithubService, + GitlabService, + ForgejoService, + GiteaService, + GogsService, + OneDevService, + GitBucketService, + CodebaseService, +} + +// RepoTransfer represents a pending repo transfer +type RepoTransfer struct { + Doer *User `json:"doer"` + Recipient *User `json:"recipient"` + Teams []*Team `json:"teams"` +} + +// NewIssuePinsAllowed represents an API response that says if new Issue Pins are allowed +type NewIssuePinsAllowed struct { + Issues bool `json:"issues"` + PullRequests bool `json:"pull_requests"` +} + +// UpdateRepoAvatarUserOption options when updating the repo avatar +type UpdateRepoAvatarOption struct { + // image must be base64 encoded + Image string `json:"image" binding:"Required"` +} diff --git a/modules/structs/repo_actions.go b/modules/structs/repo_actions.go new file mode 100644 index 0000000..b13f344 --- /dev/null +++ b/modules/structs/repo_actions.go @@ -0,0 +1,34 @@ +// Copyright 2023 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package structs + +import ( + "time" +) + +// ActionTask represents a ActionTask +type ActionTask struct { + ID int64 `json:"id"` + Name string `json:"name"` + HeadBranch string `json:"head_branch"` + HeadSHA string `json:"head_sha"` + RunNumber int64 `json:"run_number"` + Event string `json:"event"` + DisplayTitle string `json:"display_title"` + Status string `json:"status"` + WorkflowID string `json:"workflow_id"` + URL string `json:"url"` + // swagger:strfmt date-time + CreatedAt time.Time `json:"created_at"` + // swagger:strfmt date-time + UpdatedAt time.Time `json:"updated_at"` + // swagger:strfmt date-time + RunStartedAt time.Time `json:"run_started_at"` +} + +// ActionTaskResponse returns a ActionTask +type ActionTaskResponse struct { + Entries []*ActionTask `json:"workflow_runs"` + TotalCount int64 `json:"total_count"` +} diff --git a/modules/structs/repo_branch.go b/modules/structs/repo_branch.go new file mode 100644 index 0000000..0b3b0bb --- /dev/null +++ b/modules/structs/repo_branch.go @@ -0,0 +1,112 @@ +// Copyright 2016 The Gogs Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package structs + +import ( + "time" +) + +// Branch represents a repository branch +type Branch struct { + Name string `json:"name"` + Commit *PayloadCommit `json:"commit"` + Protected bool `json:"protected"` + RequiredApprovals int64 `json:"required_approvals"` + EnableStatusCheck bool `json:"enable_status_check"` + StatusCheckContexts []string `json:"status_check_contexts"` + UserCanPush bool `json:"user_can_push"` + UserCanMerge bool `json:"user_can_merge"` + EffectiveBranchProtectionName string `json:"effective_branch_protection_name"` +} + +// BranchProtection represents a branch protection for a repository +type BranchProtection struct { + // Deprecated: true + BranchName string `json:"branch_name"` + RuleName string `json:"rule_name"` + EnablePush bool `json:"enable_push"` + EnablePushWhitelist bool `json:"enable_push_whitelist"` + PushWhitelistUsernames []string `json:"push_whitelist_usernames"` + PushWhitelistTeams []string `json:"push_whitelist_teams"` + PushWhitelistDeployKeys bool `json:"push_whitelist_deploy_keys"` + EnableMergeWhitelist bool `json:"enable_merge_whitelist"` + MergeWhitelistUsernames []string `json:"merge_whitelist_usernames"` + MergeWhitelistTeams []string `json:"merge_whitelist_teams"` + EnableStatusCheck bool `json:"enable_status_check"` + StatusCheckContexts []string `json:"status_check_contexts"` + RequiredApprovals int64 `json:"required_approvals"` + EnableApprovalsWhitelist bool `json:"enable_approvals_whitelist"` + ApprovalsWhitelistUsernames []string `json:"approvals_whitelist_username"` + ApprovalsWhitelistTeams []string `json:"approvals_whitelist_teams"` + BlockOnRejectedReviews bool `json:"block_on_rejected_reviews"` + BlockOnOfficialReviewRequests bool `json:"block_on_official_review_requests"` + BlockOnOutdatedBranch bool `json:"block_on_outdated_branch"` + DismissStaleApprovals bool `json:"dismiss_stale_approvals"` + IgnoreStaleApprovals bool `json:"ignore_stale_approvals"` + RequireSignedCommits bool `json:"require_signed_commits"` + ProtectedFilePatterns string `json:"protected_file_patterns"` + UnprotectedFilePatterns string `json:"unprotected_file_patterns"` + ApplyToAdmins bool `json:"apply_to_admins"` + // swagger:strfmt date-time + Created time.Time `json:"created_at"` + // swagger:strfmt date-time + Updated time.Time `json:"updated_at"` +} + +// CreateBranchProtectionOption options for creating a branch protection +type CreateBranchProtectionOption struct { + // Deprecated: true + BranchName string `json:"branch_name"` + RuleName string `json:"rule_name"` + EnablePush bool `json:"enable_push"` + EnablePushWhitelist bool `json:"enable_push_whitelist"` + PushWhitelistUsernames []string `json:"push_whitelist_usernames"` + PushWhitelistTeams []string `json:"push_whitelist_teams"` + PushWhitelistDeployKeys bool `json:"push_whitelist_deploy_keys"` + EnableMergeWhitelist bool `json:"enable_merge_whitelist"` + MergeWhitelistUsernames []string `json:"merge_whitelist_usernames"` + MergeWhitelistTeams []string `json:"merge_whitelist_teams"` + EnableStatusCheck bool `json:"enable_status_check"` + StatusCheckContexts []string `json:"status_check_contexts"` + RequiredApprovals int64 `json:"required_approvals"` + EnableApprovalsWhitelist bool `json:"enable_approvals_whitelist"` + ApprovalsWhitelistUsernames []string `json:"approvals_whitelist_username"` + ApprovalsWhitelistTeams []string `json:"approvals_whitelist_teams"` + BlockOnRejectedReviews bool `json:"block_on_rejected_reviews"` + BlockOnOfficialReviewRequests bool `json:"block_on_official_review_requests"` + BlockOnOutdatedBranch bool `json:"block_on_outdated_branch"` + DismissStaleApprovals bool `json:"dismiss_stale_approvals"` + IgnoreStaleApprovals bool `json:"ignore_stale_approvals"` + RequireSignedCommits bool `json:"require_signed_commits"` + ProtectedFilePatterns string `json:"protected_file_patterns"` + UnprotectedFilePatterns string `json:"unprotected_file_patterns"` + ApplyToAdmins bool `json:"apply_to_admins"` +} + +// EditBranchProtectionOption options for editing a branch protection +type EditBranchProtectionOption struct { + EnablePush *bool `json:"enable_push"` + EnablePushWhitelist *bool `json:"enable_push_whitelist"` + PushWhitelistUsernames []string `json:"push_whitelist_usernames"` + PushWhitelistTeams []string `json:"push_whitelist_teams"` + PushWhitelistDeployKeys *bool `json:"push_whitelist_deploy_keys"` + EnableMergeWhitelist *bool `json:"enable_merge_whitelist"` + MergeWhitelistUsernames []string `json:"merge_whitelist_usernames"` + MergeWhitelistTeams []string `json:"merge_whitelist_teams"` + EnableStatusCheck *bool `json:"enable_status_check"` + StatusCheckContexts []string `json:"status_check_contexts"` + RequiredApprovals *int64 `json:"required_approvals"` + EnableApprovalsWhitelist *bool `json:"enable_approvals_whitelist"` + ApprovalsWhitelistUsernames []string `json:"approvals_whitelist_username"` + ApprovalsWhitelistTeams []string `json:"approvals_whitelist_teams"` + BlockOnRejectedReviews *bool `json:"block_on_rejected_reviews"` + BlockOnOfficialReviewRequests *bool `json:"block_on_official_review_requests"` + BlockOnOutdatedBranch *bool `json:"block_on_outdated_branch"` + DismissStaleApprovals *bool `json:"dismiss_stale_approvals"` + IgnoreStaleApprovals *bool `json:"ignore_stale_approvals"` + RequireSignedCommits *bool `json:"require_signed_commits"` + ProtectedFilePatterns *string `json:"protected_file_patterns"` + UnprotectedFilePatterns *string `json:"unprotected_file_patterns"` + ApplyToAdmins *bool `json:"apply_to_admins"` +} diff --git a/modules/structs/repo_collaborator.go b/modules/structs/repo_collaborator.go new file mode 100644 index 0000000..2f03f0a --- /dev/null +++ b/modules/structs/repo_collaborator.go @@ -0,0 +1,17 @@ +// Copyright 2016 The Gogs Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package structs + +// AddCollaboratorOption options when adding a user as a collaborator of a repository +type AddCollaboratorOption struct { + // enum: ["read", "write", "admin"] + Permission *string `json:"permission"` +} + +// RepoCollaboratorPermission to get repository permission for a collaborator +type RepoCollaboratorPermission struct { + Permission string `json:"permission"` + RoleName string `json:"role_name"` + User *User `json:"user"` +} diff --git a/modules/structs/repo_commit.go b/modules/structs/repo_commit.go new file mode 100644 index 0000000..fec7d97 --- /dev/null +++ b/modules/structs/repo_commit.go @@ -0,0 +1,73 @@ +// Copyright 2018 The Gogs Authors. All rights reserved. +// Copyright 2019 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package structs + +import ( + "time" +) + +// Identity for a person's identity like an author or committer +type Identity struct { + Name string `json:"name" binding:"MaxSize(100)"` + // swagger:strfmt email + Email string `json:"email" binding:"MaxSize(254)"` +} + +// CommitMeta contains meta information of a commit in terms of API. +type CommitMeta struct { + URL string `json:"url"` + SHA string `json:"sha"` + // swagger:strfmt date-time + Created time.Time `json:"created"` +} + +// CommitUser contains information of a user in the context of a commit. +type CommitUser struct { + Identity + Date string `json:"date"` +} + +// RepoCommit contains information of a commit in the context of a repository. +type RepoCommit struct { + URL string `json:"url"` + Author *CommitUser `json:"author"` + Committer *CommitUser `json:"committer"` + Message string `json:"message"` + Tree *CommitMeta `json:"tree"` + Verification *PayloadCommitVerification `json:"verification"` +} + +// CommitStats is statistics for a RepoCommit +type CommitStats struct { + Total int `json:"total"` + Additions int `json:"additions"` + Deletions int `json:"deletions"` +} + +// Commit contains information generated from a Git commit. +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"` + Files []*CommitAffectedFiles `json:"files"` + Stats *CommitStats `json:"stats"` +} + +// CommitDateOptions store dates for GIT_AUTHOR_DATE and GIT_COMMITTER_DATE +type CommitDateOptions struct { + // swagger:strfmt date-time + Author time.Time `json:"author"` + // swagger:strfmt date-time + Committer time.Time `json:"committer"` +} + +// CommitAffectedFiles store information about files affected by the commit +type CommitAffectedFiles struct { + Filename string `json:"filename"` + Status string `json:"status"` +} diff --git a/modules/structs/repo_compare.go b/modules/structs/repo_compare.go new file mode 100644 index 0000000..8a12498 --- /dev/null +++ b/modules/structs/repo_compare.go @@ -0,0 +1,10 @@ +// Copyright 2024 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package structs + +// Compare represents a comparison between two commits. +type Compare struct { + TotalCommits int `json:"total_commits"` // Total number of commits in the comparison. + Commits []*Commit `json:"commits"` // List of commits in the comparison. +} diff --git a/modules/structs/repo_file.go b/modules/structs/repo_file.go new file mode 100644 index 0000000..00c8041 --- /dev/null +++ b/modules/structs/repo_file.go @@ -0,0 +1,172 @@ +// Copyright 2014 The Gogs Authors. All rights reserved. +// Copyright 2019 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package structs + +// FileOptions options for all file APIs +type FileOptions struct { + // message (optional) for the commit of this file. if not supplied, a default message will be used + Message string `json:"message"` + // branch (optional) to base this file from. if not given, the default branch is used + BranchName string `json:"branch" binding:"GitRefName;MaxSize(100)"` + // new_branch (optional) will make a new branch from `branch` before creating the file + NewBranchName string `json:"new_branch" binding:"GitRefName;MaxSize(100)"` + // `author` and `committer` are optional (if only one is given, it will be used for the other, otherwise the authenticated user will be used) + Author Identity `json:"author"` + Committer Identity `json:"committer"` + Dates CommitDateOptions `json:"dates"` + // Add a Signed-off-by trailer by the committer at the end of the commit log message. + Signoff bool `json:"signoff"` +} + +// CreateFileOptions options for creating files +// Note: `author` and `committer` are optional (if only one is given, it will be used for the other, otherwise the authenticated user will be used) +type CreateFileOptions struct { + FileOptions + // content must be base64 encoded + // required: true + ContentBase64 string `json:"content"` +} + +// Branch returns branch name +func (o *CreateFileOptions) Branch() string { + return o.FileOptions.BranchName +} + +// DeleteFileOptions options for deleting files (used for other File structs below) +// Note: `author` and `committer` are optional (if only one is given, it will be used for the other, otherwise the authenticated user will be used) +type DeleteFileOptions struct { + FileOptions + // sha is the SHA for the file that already exists + // required: true + SHA string `json:"sha" binding:"Required"` +} + +// Branch returns branch name +func (o *DeleteFileOptions) Branch() string { + return o.FileOptions.BranchName +} + +// UpdateFileOptions options for updating files +// Note: `author` and `committer` are optional (if only one is given, it will be used for the other, otherwise the authenticated user will be used) +type UpdateFileOptions struct { + DeleteFileOptions + // content must be base64 encoded + // required: true + ContentBase64 string `json:"content"` + // from_path (optional) is the path of the original file which will be moved/renamed to the path in the URL + FromPath string `json:"from_path" binding:"MaxSize(500)"` +} + +// Branch returns branch name +func (o *UpdateFileOptions) Branch() string { + return o.FileOptions.BranchName +} + +// ChangeFileOperation for creating, updating or deleting a file +type ChangeFileOperation struct { + // indicates what to do with the file + // required: true + // enum: ["create", "update", "delete"] + Operation string `json:"operation" binding:"Required"` + // path to the existing or new file + // required: true + Path string `json:"path" binding:"Required;MaxSize(500)"` + // new or updated file content, must be base64 encoded + ContentBase64 string `json:"content"` + // sha is the SHA for the file that already exists, required for update or delete + SHA string `json:"sha"` + // old path of the file to move + FromPath string `json:"from_path"` +} + +// ChangeFilesOptions options for creating, updating or deleting multiple files +// Note: `author` and `committer` are optional (if only one is given, it will be used for the other, otherwise the authenticated user will be used) +type ChangeFilesOptions struct { + FileOptions + // list of file operations + // required: true + Files []*ChangeFileOperation `json:"files" binding:"Required"` +} + +// Branch returns branch name +func (o *ChangeFilesOptions) Branch() string { + return o.FileOptions.BranchName +} + +// FileOptionInterface provides a unified interface for the different file options +type FileOptionInterface interface { + Branch() string +} + +// ApplyDiffPatchFileOptions options for applying a diff patch +// Note: `author` and `committer` are optional (if only one is given, it will be used for the other, otherwise the authenticated user will be used) +type ApplyDiffPatchFileOptions struct { + DeleteFileOptions + // required: true + Content string `json:"content"` +} + +// FileLinksResponse contains the links for a repo's file +type FileLinksResponse struct { + Self *string `json:"self"` + GitURL *string `json:"git"` + HTMLURL *string `json:"html"` +} + +// ContentsResponse contains information about a repo's entry's (dir, file, symlink, submodule) metadata and content +type ContentsResponse struct { + Name string `json:"name"` + Path string `json:"path"` + SHA string `json:"sha"` + LastCommitSHA string `json:"last_commit_sha"` + // `type` will be `file`, `dir`, `symlink`, or `submodule` + Type string `json:"type"` + Size int64 `json:"size"` + // `encoding` is populated when `type` is `file`, otherwise null + Encoding *string `json:"encoding"` + // `content` is populated when `type` is `file`, otherwise null + Content *string `json:"content"` + // `target` is populated when `type` is `symlink`, otherwise null + Target *string `json:"target"` + URL *string `json:"url"` + HTMLURL *string `json:"html_url"` + GitURL *string `json:"git_url"` + DownloadURL *string `json:"download_url"` + // `submodule_git_url` is populated when `type` is `submodule`, otherwise null + SubmoduleGitURL *string `json:"submodule_git_url"` + Links *FileLinksResponse `json:"_links"` +} + +// FileCommitResponse contains information generated from a Git commit for a repo's file. +type FileCommitResponse struct { + CommitMeta + HTMLURL string `json:"html_url"` + Author *CommitUser `json:"author"` + Committer *CommitUser `json:"committer"` + Parents []*CommitMeta `json:"parents"` + Message string `json:"message"` + Tree *CommitMeta `json:"tree"` +} + +// FileResponse contains information about a repo's file +type FileResponse struct { + Content *ContentsResponse `json:"content"` + Commit *FileCommitResponse `json:"commit"` + Verification *PayloadCommitVerification `json:"verification"` +} + +// FilesResponse contains information about multiple files from a repo +type FilesResponse struct { + Files []*ContentsResponse `json:"files"` + Commit *FileCommitResponse `json:"commit"` + Verification *PayloadCommitVerification `json:"verification"` +} + +// FileDeleteResponse contains information about a repo's file that was deleted +type FileDeleteResponse struct { + Content any `json:"content"` // to be set to nil + Commit *FileCommitResponse `json:"commit"` + Verification *PayloadCommitVerification `json:"verification"` +} diff --git a/modules/structs/repo_flags.go b/modules/structs/repo_flags.go new file mode 100644 index 0000000..5db7145 --- /dev/null +++ b/modules/structs/repo_flags.go @@ -0,0 +1,9 @@ +// Copyright 2024 The Forgejo Authors c/o Codeberg e.V.. All rights reserved. +// SPDX-License-Identifier: MIT + +package structs + +// ReplaceFlagsOption options when replacing the flags of a repository +type ReplaceFlagsOption struct { + Flags []string `json:"flags"` +} diff --git a/modules/structs/repo_key.go b/modules/structs/repo_key.go new file mode 100644 index 0000000..27b9d05 --- /dev/null +++ b/modules/structs/repo_key.go @@ -0,0 +1,40 @@ +// Copyright 2015 The Gogs Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package structs + +import ( + "time" +) + +// DeployKey a deploy key +type DeployKey struct { + ID int64 `json:"id"` + KeyID int64 `json:"key_id"` + Key string `json:"key"` + URL string `json:"url"` + Title string `json:"title"` + Fingerprint string `json:"fingerprint"` + // swagger:strfmt date-time + Created time.Time `json:"created_at"` + ReadOnly bool `json:"read_only"` + Repository *Repository `json:"repository,omitempty"` +} + +// CreateKeyOption options when creating a key +type CreateKeyOption struct { + // Title of the key to add + // + // required: true + // unique: true + Title string `json:"title" binding:"Required"` + // An armored SSH key to add + // + // required: true + // unique: true + Key string `json:"key" binding:"Required"` + // Describe if the key has only read access or read/write + // + // required: false + ReadOnly bool `json:"read_only"` +} diff --git a/modules/structs/repo_note.go b/modules/structs/repo_note.go new file mode 100644 index 0000000..4eaf5a2 --- /dev/null +++ b/modules/structs/repo_note.go @@ -0,0 +1,10 @@ +// Copyright 2021 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package structs + +// Note contains information related to a git note +type Note struct { + Message string `json:"message"` + Commit *Commit `json:"commit"` +} diff --git a/modules/structs/repo_refs.go b/modules/structs/repo_refs.go new file mode 100644 index 0000000..6ffbc74 --- /dev/null +++ b/modules/structs/repo_refs.go @@ -0,0 +1,18 @@ +// Copyright 2018 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package structs + +// Reference represents a Git reference. +type Reference struct { + Ref string `json:"ref"` + URL string `json:"url"` + Object *GitObject `json:"object"` +} + +// GitObject represents a Git object. +type GitObject struct { + Type string `json:"type"` + SHA string `json:"sha"` + URL string `json:"url"` +} diff --git a/modules/structs/repo_tag.go b/modules/structs/repo_tag.go new file mode 100644 index 0000000..1bea5b3 --- /dev/null +++ b/modules/structs/repo_tag.go @@ -0,0 +1,76 @@ +// Copyright 2019 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package structs + +import "time" + +// Tag represents a repository tag +type Tag struct { + Name string `json:"name"` + Message string `json:"message"` + ID string `json:"id"` + Commit *CommitMeta `json:"commit"` + ZipballURL string `json:"zipball_url"` + TarballURL string `json:"tarball_url"` + ArchiveDownloadCount *TagArchiveDownloadCount `json:"archive_download_count"` +} + +// AnnotatedTag represents an annotated tag +type AnnotatedTag struct { + Tag string `json:"tag"` + SHA string `json:"sha"` + URL string `json:"url"` + Message string `json:"message"` + Tagger *CommitUser `json:"tagger"` + Object *AnnotatedTagObject `json:"object"` + Verification *PayloadCommitVerification `json:"verification"` + ArchiveDownloadCount *TagArchiveDownloadCount `json:"archive_download_count"` +} + +// AnnotatedTagObject contains meta information of the tag object +type AnnotatedTagObject struct { + Type string `json:"type"` + URL string `json:"url"` + SHA string `json:"sha"` +} + +// CreateTagOption options when creating a tag +type CreateTagOption struct { + // required: true + TagName string `json:"tag_name" binding:"Required"` + Message string `json:"message"` + Target string `json:"target"` +} + +// TagArchiveDownloadCount counts how many times a archive was downloaded +type TagArchiveDownloadCount struct { + Zip int64 `json:"zip"` + TarGz int64 `json:"tar_gz"` +} + +// TagProtection represents a tag protection +type TagProtection struct { + ID int64 `json:"id"` + NamePattern string `json:"name_pattern"` + WhitelistUsernames []string `json:"whitelist_usernames"` + WhitelistTeams []string `json:"whitelist_teams"` + // swagger:strfmt date-time + Created time.Time `json:"created_at"` + // swagger:strfmt date-time + Updated time.Time `json:"updated_at"` +} + +// CreateTagProtectionOption options for creating a tag protection +type CreateTagProtectionOption struct { + NamePattern string `json:"name_pattern"` + WhitelistUsernames []string `json:"whitelist_usernames"` + WhitelistTeams []string `json:"whitelist_teams"` +} + +// EditTagProtectionOption options for editing a tag protection +type EditTagProtectionOption struct { + NamePattern *string `json:"name_pattern"` + WhitelistUsernames []string `json:"whitelist_usernames"` + WhitelistTeams []string `json:"whitelist_teams"` +} diff --git a/modules/structs/repo_topic.go b/modules/structs/repo_topic.go new file mode 100644 index 0000000..fea193e --- /dev/null +++ b/modules/structs/repo_topic.go @@ -0,0 +1,28 @@ +// Copyright 2019 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package structs + +import ( + "time" +) + +// TopicResponse for returning topics +type TopicResponse struct { + ID int64 `json:"id"` + Name string `json:"topic_name"` + RepoCount int `json:"repo_count"` + Created time.Time `json:"created"` + Updated time.Time `json:"updated"` +} + +// TopicName a list of repo topic names +type TopicName struct { + TopicNames []string `json:"topics"` +} + +// RepoTopicOptions a collection of repo topic names +type RepoTopicOptions struct { + // list of topic names + Topics []string `json:"topics"` +} diff --git a/modules/structs/repo_tree.go b/modules/structs/repo_tree.go new file mode 100644 index 0000000..86b221e --- /dev/null +++ b/modules/structs/repo_tree.go @@ -0,0 +1,24 @@ +// Copyright 2018 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package structs + +// GitEntry represents a git tree +type GitEntry struct { + Path string `json:"path"` + Mode string `json:"mode"` + Type string `json:"type"` + Size int64 `json:"size"` + SHA string `json:"sha"` + URL string `json:"url"` +} + +// GitTreeResponse returns a git tree +type GitTreeResponse struct { + SHA string `json:"sha"` + URL string `json:"url"` + Entries []GitEntry `json:"tree"` + Truncated bool `json:"truncated"` + Page int `json:"page"` + TotalCount int `json:"total_count"` +} diff --git a/modules/structs/repo_watch.go b/modules/structs/repo_watch.go new file mode 100644 index 0000000..0d0b7c4 --- /dev/null +++ b/modules/structs/repo_watch.go @@ -0,0 +1,18 @@ +// Copyright 2017 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package structs + +import ( + "time" +) + +// WatchInfo represents an API watch status of one repository +type WatchInfo struct { + Subscribed bool `json:"subscribed"` + Ignored bool `json:"ignored"` + Reason any `json:"reason"` + CreatedAt time.Time `json:"created_at"` + URL string `json:"url"` + RepositoryURL string `json:"repository_url"` +} diff --git a/modules/structs/repo_wiki.go b/modules/structs/repo_wiki.go new file mode 100644 index 0000000..3df5a0b --- /dev/null +++ b/modules/structs/repo_wiki.go @@ -0,0 +1,46 @@ +// Copyright 2021 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package structs + +// WikiCommit page commit/revision +type WikiCommit struct { + ID string `json:"sha"` + Author *CommitUser `json:"author"` + Committer *CommitUser `json:"commiter"` + Message string `json:"message"` +} + +// WikiPage a wiki page +type WikiPage struct { + *WikiPageMetaData + // Page content, base64 encoded + ContentBase64 string `json:"content_base64"` + CommitCount int64 `json:"commit_count"` + Sidebar string `json:"sidebar"` + Footer string `json:"footer"` +} + +// WikiPageMetaData wiki page meta information +type WikiPageMetaData struct { + Title string `json:"title"` + HTMLURL string `json:"html_url"` + SubURL string `json:"sub_url"` + LastCommit *WikiCommit `json:"last_commit"` +} + +// CreateWikiPageOptions form for creating wiki +type CreateWikiPageOptions struct { + // page title. leave empty to keep unchanged + Title string `json:"title"` + // content must be base64 encoded + ContentBase64 string `json:"content_base64"` + // optional commit message summarizing the change + Message string `json:"message"` +} + +// WikiCommitList commit/revision list +type WikiCommitList struct { + WikiCommits []*WikiCommit `json:"commits"` + Count int64 `json:"count"` +} diff --git a/modules/structs/secret.go b/modules/structs/secret.go new file mode 100644 index 0000000..a0673ca --- /dev/null +++ b/modules/structs/secret.go @@ -0,0 +1,24 @@ +// Copyright 2023 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package structs + +import "time" + +// Secret represents a secret +// swagger:model +type Secret struct { + // the secret's name + Name string `json:"name"` + // swagger:strfmt date-time + Created time.Time `json:"created_at"` +} + +// CreateOrUpdateSecretOption options when creating or updating secret +// swagger:model +type CreateOrUpdateSecretOption struct { + // Data of the secret to update + // + // required: true + Data string `json:"data" binding:"Required"` +} diff --git a/modules/structs/settings.go b/modules/structs/settings.go new file mode 100644 index 0000000..b127b58 --- /dev/null +++ b/modules/structs/settings.go @@ -0,0 +1,38 @@ +// Copyright 2020 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package structs + +// GeneralRepoSettings contains global repository settings exposed by API +type GeneralRepoSettings struct { + MirrorsDisabled bool `json:"mirrors_disabled"` + HTTPGitDisabled bool `json:"http_git_disabled"` + MigrationsDisabled bool `json:"migrations_disabled"` + StarsDisabled bool `json:"stars_disabled"` + ForksDisabled bool `json:"forks_disabled"` + TimeTrackingDisabled bool `json:"time_tracking_disabled"` + LFSDisabled bool `json:"lfs_disabled"` +} + +// GeneralUISettings contains global ui settings exposed by API +type GeneralUISettings struct { + DefaultTheme string `json:"default_theme"` + AllowedReactions []string `json:"allowed_reactions"` + CustomEmojis []string `json:"custom_emojis"` +} + +// GeneralAPISettings contains global api settings exposed by it +type GeneralAPISettings struct { + MaxResponseItems int `json:"max_response_items"` + DefaultPagingNum int `json:"default_paging_num"` + DefaultGitTreesPerPage int `json:"default_git_trees_per_page"` + DefaultMaxBlobSize int64 `json:"default_max_blob_size"` +} + +// GeneralAttachmentSettings contains global Attachment settings exposed by API +type GeneralAttachmentSettings struct { + Enabled bool `json:"enabled"` + AllowedTypes string `json:"allowed_types"` + MaxSize int64 `json:"max_size"` + MaxFiles int `json:"max_files"` +} diff --git a/modules/structs/status.go b/modules/structs/status.go new file mode 100644 index 0000000..c1d8b90 --- /dev/null +++ b/modules/structs/status.go @@ -0,0 +1,42 @@ +// Copyright 2017 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package structs + +import ( + "time" +) + +// CommitStatus holds a single status of a single Commit +type CommitStatus struct { + ID int64 `json:"id"` + State CommitStatusState `json:"status"` + TargetURL string `json:"target_url"` + Description string `json:"description"` + URL string `json:"url"` + Context string `json:"context"` + Creator *User `json:"creator"` + // swagger:strfmt date-time + Created time.Time `json:"created_at"` + // swagger:strfmt date-time + Updated time.Time `json:"updated_at"` +} + +// CombinedStatus holds the combined state of several statuses for a single commit +type CombinedStatus struct { + State CommitStatusState `json:"state"` + SHA string `json:"sha"` + TotalCount int `json:"total_count"` + Statuses []*CommitStatus `json:"statuses"` + Repository *Repository `json:"repository"` + CommitURL string `json:"commit_url"` + URL string `json:"url"` +} + +// CreateStatusOption holds the information needed to create a new CommitStatus for a Commit +type CreateStatusOption struct { + State CommitStatusState `json:"state"` + TargetURL string `json:"target_url"` + Description string `json:"description"` + Context string `json:"context"` +} diff --git a/modules/structs/task.go b/modules/structs/task.go new file mode 100644 index 0000000..84b6181 --- /dev/null +++ b/modules/structs/task.go @@ -0,0 +1,31 @@ +// Copyright 2019 Gitea. All rights reserved. +// SPDX-License-Identifier: MIT + +package structs + +// TaskType defines task type +type TaskType int + +const TaskTypeMigrateRepo TaskType = iota // migrate repository from external or local disk + +// Name returns the task type name +func (taskType TaskType) Name() string { + switch taskType { + case TaskTypeMigrateRepo: + return "Migrate Repository" + default: + return "" + } +} + +// TaskStatus defines task status +type TaskStatus int + +// enumerate all the kinds of task status +const ( + TaskStatusQueued TaskStatus = iota // 0 task is queued + TaskStatusRunning // 1 task is running + TaskStatusStopped // 2 task is stopped (never used) + TaskStatusFailed // 3 task is failed + TaskStatusFinished // 4 task is finished +) diff --git a/modules/structs/user.go b/modules/structs/user.go new file mode 100644 index 0000000..f2747b1 --- /dev/null +++ b/modules/structs/user.go @@ -0,0 +1,120 @@ +// Copyright 2014 The Gogs Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package structs + +import ( + "time" + + "code.gitea.io/gitea/modules/json" +) + +// User represents a user +// swagger:model +type User struct { + // the user's id + ID int64 `json:"id"` + // the user's username + UserName string `json:"login"` + // the user's authentication sign-in name. + // default: empty + LoginName string `json:"login_name"` + // The ID of the user's Authentication Source + SourceID int64 `json:"source_id"` + // the user's full name + FullName string `json:"full_name"` + // swagger:strfmt email + Email string `json:"email"` + // URL to the user's avatar + AvatarURL string `json:"avatar_url"` + // URL to the user's gitea page + HTMLURL string `json:"html_url"` + // User locale + Language string `json:"language"` + // Is the user an administrator + IsAdmin bool `json:"is_admin"` + // swagger:strfmt date-time + LastLogin time.Time `json:"last_login,omitempty"` + // swagger:strfmt date-time + Created time.Time `json:"created,omitempty"` + // Is user restricted + Restricted bool `json:"restricted"` + // Is user active + IsActive bool `json:"active"` + // Is user login prohibited + ProhibitLogin bool `json:"prohibit_login"` + // the user's location + Location string `json:"location"` + // the user's pronouns + Pronouns string `json:"pronouns"` + // the user's website + Website string `json:"website"` + // the user's description + Description string `json:"description"` + // User visibility level option: public, limited, private + Visibility string `json:"visibility"` + + // user counts + Followers int `json:"followers_count"` + Following int `json:"following_count"` + StarredRepos int `json:"starred_repos_count"` +} + +// MarshalJSON implements the json.Marshaler interface for User, adding field(s) for backward compatibility +func (u User) MarshalJSON() ([]byte, error) { + // Redeclaring User to avoid recursion + type shadow User + return json.Marshal(struct { + shadow + CompatUserName string `json:"username"` + }{shadow(u), u.UserName}) +} + +// UserSettings represents user settings +// swagger:model +type UserSettings struct { + FullName string `json:"full_name"` + Website string `json:"website"` + Description string `json:"description"` + Location string `json:"location"` + Pronouns string `json:"pronouns"` + Language string `json:"language"` + Theme string `json:"theme"` + DiffViewStyle string `json:"diff_view_style"` + EnableRepoUnitHints bool `json:"enable_repo_unit_hints"` + // Privacy + HideEmail bool `json:"hide_email"` + HideActivity bool `json:"hide_activity"` +} + +// UserSettingsOptions represents options to change user settings +// swagger:model +type UserSettingsOptions struct { + FullName *string `json:"full_name" binding:"MaxSize(100)"` + Website *string `json:"website" binding:"OmitEmpty;ValidUrl;MaxSize(255)"` + Description *string `json:"description" binding:"MaxSize(255)"` + Location *string `json:"location" binding:"MaxSize(50)"` + Pronouns *string `json:"pronouns" binding:"MaxSize(50)"` + Language *string `json:"language"` + Theme *string `json:"theme"` + DiffViewStyle *string `json:"diff_view_style"` + EnableRepoUnitHints *bool `json:"enable_repo_unit_hints"` + // Privacy + HideEmail *bool `json:"hide_email"` + HideActivity *bool `json:"hide_activity"` +} + +// RenameUserOption options when renaming a user +type RenameUserOption struct { + // New username for this user. This name cannot be in use yet by any other user. + // + // required: true + // unique: true + NewName string `json:"new_username" binding:"Required"` +} + +// UpdateUserAvatarUserOption options when updating the user avatar +type UpdateUserAvatarOption struct { + // image must be base64 encoded + Image string `json:"image" binding:"Required"` +} diff --git a/modules/structs/user_app.go b/modules/structs/user_app.go new file mode 100644 index 0000000..7f78fbd --- /dev/null +++ b/modules/structs/user_app.go @@ -0,0 +1,53 @@ +// Copyright 2014 The Gogs Authors. All rights reserved. +// Copyright 2019 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package structs + +import ( + "time" +) + +// AccessToken represents an API access token. +// swagger:response AccessToken +type AccessToken struct { + ID int64 `json:"id"` + Name string `json:"name"` + Token string `json:"sha1"` + TokenLastEight string `json:"token_last_eight"` + Scopes []string `json:"scopes"` +} + +// AccessTokenList represents a list of API access token. +// swagger:response AccessTokenList +type AccessTokenList []*AccessToken + +// CreateAccessTokenOption options when create access token +type CreateAccessTokenOption struct { + // required: true + Name string `json:"name" binding:"Required"` + Scopes []string `json:"scopes"` +} + +// CreateOAuth2ApplicationOptions holds options to create an oauth2 application +type CreateOAuth2ApplicationOptions struct { + Name string `json:"name" binding:"Required"` + ConfidentialClient bool `json:"confidential_client"` + RedirectURIs []string `json:"redirect_uris" binding:"Required"` +} + +// OAuth2Application represents an OAuth2 application. +// swagger:response OAuth2Application +type OAuth2Application struct { + ID int64 `json:"id"` + Name string `json:"name"` + ClientID string `json:"client_id"` + ClientSecret string `json:"client_secret"` + ConfidentialClient bool `json:"confidential_client"` + RedirectURIs []string `json:"redirect_uris"` + Created time.Time `json:"created"` +} + +// OAuth2ApplicationList represents a list of OAuth2 applications. +// swagger:response OAuth2ApplicationList +type OAuth2ApplicationList []*OAuth2Application diff --git a/modules/structs/user_email.go b/modules/structs/user_email.go new file mode 100644 index 0000000..9319667 --- /dev/null +++ b/modules/structs/user_email.go @@ -0,0 +1,27 @@ +// Copyright 2015 The Gogs Authors. All rights reserved. +// Copyright 2023 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package structs + +// Email an email address belonging to a user +type Email struct { + // swagger:strfmt email + Email string `json:"email"` + Verified bool `json:"verified"` + Primary bool `json:"primary"` + UserID int64 `json:"user_id"` + UserName string `json:"username"` +} + +// CreateEmailOption options when creating email addresses +type CreateEmailOption struct { + // email addresses to add + Emails []string `json:"emails"` +} + +// DeleteEmailOption options when deleting email addresses +type DeleteEmailOption struct { + // email addresses to delete + Emails []string `json:"emails"` +} diff --git a/modules/structs/user_gpgkey.go b/modules/structs/user_gpgkey.go new file mode 100644 index 0000000..ff9b0ae --- /dev/null +++ b/modules/structs/user_gpgkey.go @@ -0,0 +1,53 @@ +// Copyright 2017 Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package structs + +import ( + "time" +) + +// GPGKey a user GPG key to sign commit and tag in repository +type GPGKey struct { + ID int64 `json:"id"` + PrimaryKeyID string `json:"primary_key_id"` + KeyID string `json:"key_id"` + PublicKey string `json:"public_key"` + Emails []*GPGKeyEmail `json:"emails"` + SubsKey []*GPGKey `json:"subkeys"` + CanSign bool `json:"can_sign"` + CanEncryptComms bool `json:"can_encrypt_comms"` + CanEncryptStorage bool `json:"can_encrypt_storage"` + CanCertify bool `json:"can_certify"` + Verified bool `json:"verified"` + // swagger:strfmt date-time + Created time.Time `json:"created_at,omitempty"` + // swagger:strfmt date-time + Expires time.Time `json:"expires_at,omitempty"` +} + +// GPGKeyEmail an email attached to a GPGKey +// swagger:model GPGKeyEmail +type GPGKeyEmail struct { + Email string `json:"email"` + Verified bool `json:"verified"` +} + +// CreateGPGKeyOption options create user GPG key +type CreateGPGKeyOption struct { + // An armored GPG key to add + // + // required: true + // unique: true + ArmoredKey string `json:"armored_public_key" binding:"Required"` + Signature string `json:"armored_signature,omitempty"` +} + +// VerifyGPGKeyOption options verifies user GPG key +type VerifyGPGKeyOption struct { + // An Signature for a GPG key token + // + // required: true + KeyID string `json:"key_id" binding:"Required"` + Signature string `json:"armored_signature" binding:"Required"` +} diff --git a/modules/structs/user_key.go b/modules/structs/user_key.go new file mode 100644 index 0000000..08eed59 --- /dev/null +++ b/modules/structs/user_key.go @@ -0,0 +1,22 @@ +// Copyright 2015 The Gogs Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package structs + +import ( + "time" +) + +// PublicKey publickey is a user key to push code to repository +type PublicKey struct { + ID int64 `json:"id"` + Key string `json:"key"` + URL string `json:"url,omitempty"` + Title string `json:"title,omitempty"` + Fingerprint string `json:"fingerprint,omitempty"` + // swagger:strfmt date-time + Created time.Time `json:"created_at,omitempty"` + Owner *User `json:"user,omitempty"` + ReadOnly bool `json:"read_only,omitempty"` + KeyType string `json:"key_type,omitempty"` +} diff --git a/modules/structs/variable.go b/modules/structs/variable.go new file mode 100644 index 0000000..cc846cf --- /dev/null +++ b/modules/structs/variable.go @@ -0,0 +1,37 @@ +// Copyright 2024 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package structs + +// CreateVariableOption the option when creating variable +// swagger:model +type CreateVariableOption struct { + // Value of the variable to create + // + // required: true + Value string `json:"value" binding:"Required"` +} + +// UpdateVariableOption the option when updating variable +// swagger:model +type UpdateVariableOption struct { + // New name for the variable. If the field is empty, the variable name won't be updated. + Name string `json:"name"` + // Value of the variable to update + // + // required: true + Value string `json:"value" binding:"Required"` +} + +// ActionVariable return value of the query API +// swagger:model +type ActionVariable struct { + // the owner to which the variable belongs + OwnerID int64 `json:"owner_id"` + // the repository to which the variable belongs + RepoID int64 `json:"repo_id"` + // the name of the variable + Name string `json:"name"` + // the value of the variable + Data string `json:"data"` +} diff --git a/modules/structs/visible_type.go b/modules/structs/visible_type.go new file mode 100644 index 0000000..b5ff353 --- /dev/null +++ b/modules/structs/visible_type.go @@ -0,0 +1,58 @@ +// Copyright 2019 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package structs + +// VisibleType defines the visibility of user and org +type VisibleType int + +const ( + // VisibleTypePublic Visible for everyone + VisibleTypePublic VisibleType = iota + + // VisibleTypeLimited Visible for every connected user + VisibleTypeLimited + + // VisibleTypePrivate Visible only for self or admin user + VisibleTypePrivate +) + +// VisibilityModes is a map of Visibility types +var VisibilityModes = map[string]VisibleType{ + "public": VisibleTypePublic, + "limited": VisibleTypeLimited, + "private": VisibleTypePrivate, +} + +// IsPublic returns true if VisibleType is public +func (vt VisibleType) IsPublic() bool { + return vt == VisibleTypePublic +} + +// IsLimited returns true if VisibleType is limited +func (vt VisibleType) IsLimited() bool { + return vt == VisibleTypeLimited +} + +// IsPrivate returns true if VisibleType is private +func (vt VisibleType) IsPrivate() bool { + return vt == VisibleTypePrivate +} + +// VisibilityString provides the mode string of the visibility type (public, limited, private) +func (vt VisibleType) String() string { + for k, v := range VisibilityModes { + if vt == v { + return k + } + } + return "" +} + +// ExtractKeysFromMapString provides a slice of keys from map +func ExtractKeysFromMapString(in map[string]VisibleType) (keys []string) { + for k := range in { + keys = append(keys, k) + } + return keys +} diff --git a/modules/structs/workflow.go b/modules/structs/workflow.go new file mode 100644 index 0000000..c4429ea --- /dev/null +++ b/modules/structs/workflow.go @@ -0,0 +1,15 @@ +// Copyright The Forgejo Authors. +// SPDX-License-Identifier: MIT + +package structs + +// DispatchWorkflowOption options when dispatching a workflow +// swagger:model +type DispatchWorkflowOption struct { + // Git reference for the workflow + // + // required: true + Ref string `json:"ref"` + // Input keys and values configured in the workflow file. + Inputs map[string]string `json:"inputs"` +} |