mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2024-12-27 06:03:51 +03:00
13ca6c14f1
This commit allows chaning default branch update style through global and repository settings. The setting affects "Update branch" button in PR view (button shows when some commits are ahead of master branch). When default update style is set to "rebase", dropdown button updates branch by rebase by default. When update style is set to other value, dropdown button updates branch by merge. Any of these actions may be selected using dropdown in any case. Signed-off-by: George Bartolomey <george@bh4.ru>
257 lines
9.7 KiB
Go
257 lines
9.7 KiB
Go
// Copyright 2020 The Gitea Authors. All rights reserved.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package convert
|
|
|
|
import (
|
|
"context"
|
|
"time"
|
|
|
|
"code.gitea.io/gitea/models"
|
|
"code.gitea.io/gitea/models/db"
|
|
"code.gitea.io/gitea/models/perm"
|
|
access_model "code.gitea.io/gitea/models/perm/access"
|
|
repo_model "code.gitea.io/gitea/models/repo"
|
|
unit_model "code.gitea.io/gitea/models/unit"
|
|
"code.gitea.io/gitea/modules/log"
|
|
api "code.gitea.io/gitea/modules/structs"
|
|
)
|
|
|
|
// ToRepo converts a Repository to api.Repository
|
|
func ToRepo(ctx context.Context, repo *repo_model.Repository, permissionInRepo access_model.Permission) *api.Repository {
|
|
return innerToRepo(ctx, repo, permissionInRepo, false)
|
|
}
|
|
|
|
func innerToRepo(ctx context.Context, repo *repo_model.Repository, permissionInRepo access_model.Permission, isParent bool) *api.Repository {
|
|
var parent *api.Repository
|
|
|
|
if permissionInRepo.Units == nil && permissionInRepo.UnitsMode == nil {
|
|
// If Units and UnitsMode are both nil, it means that it's a hard coded permission,
|
|
// like access_model.Permission{AccessMode: perm.AccessModeAdmin}.
|
|
// So we need to load units for the repo, or UnitAccessMode will always return perm.AccessModeNone.
|
|
_ = repo.LoadUnits(ctx) // the error is not important, so ignore it
|
|
permissionInRepo.Units = repo.Units
|
|
}
|
|
|
|
cloneLink := repo.CloneLink()
|
|
permission := &api.Permission{
|
|
Admin: permissionInRepo.AccessMode >= perm.AccessModeAdmin,
|
|
Push: permissionInRepo.UnitAccessMode(unit_model.TypeCode) >= perm.AccessModeWrite,
|
|
Pull: permissionInRepo.UnitAccessMode(unit_model.TypeCode) >= perm.AccessModeRead,
|
|
}
|
|
if !isParent {
|
|
err := repo.GetBaseRepo(ctx)
|
|
if err != nil {
|
|
return nil
|
|
}
|
|
if repo.BaseRepo != nil {
|
|
// FIXME: The permission of the parent repo is not correct.
|
|
// It's the permission of the current repo, so it's probably different from the parent repo.
|
|
// But there isn't a good way to get the permission of the parent repo, because the doer is not passed in.
|
|
// Use the permission of the current repo to keep the behavior consistent with the old API.
|
|
// Maybe the right way is setting the permission of the parent repo to nil, empty is better than wrong.
|
|
parent = innerToRepo(ctx, repo.BaseRepo, permissionInRepo, true)
|
|
}
|
|
}
|
|
|
|
// check enabled/disabled units
|
|
hasIssues := false
|
|
var externalTracker *api.ExternalTracker
|
|
var internalTracker *api.InternalTracker
|
|
if unit, err := repo.GetUnit(ctx, unit_model.TypeIssues); err == nil {
|
|
config := unit.IssuesConfig()
|
|
hasIssues = true
|
|
internalTracker = &api.InternalTracker{
|
|
EnableTimeTracker: config.EnableTimetracker,
|
|
AllowOnlyContributorsToTrackTime: config.AllowOnlyContributorsToTrackTime,
|
|
EnableIssueDependencies: config.EnableDependencies,
|
|
}
|
|
} else if unit, err := repo.GetUnit(ctx, unit_model.TypeExternalTracker); err == nil {
|
|
config := unit.ExternalTrackerConfig()
|
|
hasIssues = true
|
|
externalTracker = &api.ExternalTracker{
|
|
ExternalTrackerURL: config.ExternalTrackerURL,
|
|
ExternalTrackerFormat: config.ExternalTrackerFormat,
|
|
ExternalTrackerStyle: config.ExternalTrackerStyle,
|
|
ExternalTrackerRegexpPattern: config.ExternalTrackerRegexpPattern,
|
|
}
|
|
}
|
|
hasWiki := false
|
|
globallyEditableWiki := false
|
|
var externalWiki *api.ExternalWiki
|
|
if wikiUnit, err := repo.GetUnit(ctx, unit_model.TypeWiki); err == nil {
|
|
hasWiki = true
|
|
if wikiUnit.DefaultPermissions == repo_model.UnitAccessModeWrite {
|
|
globallyEditableWiki = true
|
|
}
|
|
} else if unit, err := repo.GetUnit(ctx, unit_model.TypeExternalWiki); err == nil {
|
|
hasWiki = true
|
|
config := unit.ExternalWikiConfig()
|
|
externalWiki = &api.ExternalWiki{
|
|
ExternalWikiURL: config.ExternalWikiURL,
|
|
}
|
|
}
|
|
hasPullRequests := false
|
|
ignoreWhitespaceConflicts := false
|
|
allowMerge := false
|
|
allowRebase := false
|
|
allowRebaseMerge := false
|
|
allowSquash := false
|
|
allowFastForwardOnly := false
|
|
allowRebaseUpdate := false
|
|
defaultDeleteBranchAfterMerge := false
|
|
defaultMergeStyle := repo_model.MergeStyleMerge
|
|
defaultUpdateStyle := repo_model.UpdateStyleMerge
|
|
defaultAllowMaintainerEdit := false
|
|
if unit, err := repo.GetUnit(ctx, unit_model.TypePullRequests); err == nil {
|
|
config := unit.PullRequestsConfig()
|
|
hasPullRequests = true
|
|
ignoreWhitespaceConflicts = config.IgnoreWhitespaceConflicts
|
|
allowMerge = config.AllowMerge
|
|
allowRebase = config.AllowRebase
|
|
allowRebaseMerge = config.AllowRebaseMerge
|
|
allowSquash = config.AllowSquash
|
|
allowFastForwardOnly = config.AllowFastForwardOnly
|
|
allowRebaseUpdate = config.AllowRebaseUpdate
|
|
defaultDeleteBranchAfterMerge = config.DefaultDeleteBranchAfterMerge
|
|
defaultMergeStyle = config.GetDefaultMergeStyle()
|
|
defaultUpdateStyle = config.GetDefaultUpdateStyle()
|
|
defaultAllowMaintainerEdit = config.DefaultAllowMaintainerEdit
|
|
}
|
|
hasProjects := false
|
|
if _, err := repo.GetUnit(ctx, unit_model.TypeProjects); err == nil {
|
|
hasProjects = true
|
|
}
|
|
|
|
hasReleases := false
|
|
if _, err := repo.GetUnit(ctx, unit_model.TypeReleases); err == nil {
|
|
hasReleases = true
|
|
}
|
|
|
|
hasPackages := false
|
|
if _, err := repo.GetUnit(ctx, unit_model.TypePackages); err == nil {
|
|
hasPackages = true
|
|
}
|
|
|
|
hasActions := false
|
|
if _, err := repo.GetUnit(ctx, unit_model.TypeActions); err == nil {
|
|
hasActions = true
|
|
}
|
|
|
|
if err := repo.LoadOwner(ctx); err != nil {
|
|
return nil
|
|
}
|
|
|
|
numReleases, _ := db.Count[repo_model.Release](ctx, repo_model.FindReleasesOptions{
|
|
IncludeDrafts: false,
|
|
IncludeTags: false,
|
|
RepoID: repo.ID,
|
|
})
|
|
|
|
mirrorInterval := ""
|
|
var mirrorUpdated time.Time
|
|
if repo.IsMirror {
|
|
pullMirror, err := repo_model.GetMirrorByRepoID(ctx, repo.ID)
|
|
if err == nil {
|
|
mirrorInterval = pullMirror.Interval.String()
|
|
mirrorUpdated = pullMirror.UpdatedUnix.AsTime()
|
|
}
|
|
}
|
|
|
|
var transfer *api.RepoTransfer
|
|
if repo.Status == repo_model.RepositoryPendingTransfer {
|
|
t, err := models.GetPendingRepositoryTransfer(ctx, repo)
|
|
if err != nil && !models.IsErrNoPendingTransfer(err) {
|
|
log.Warn("GetPendingRepositoryTransfer: %v", err)
|
|
} else {
|
|
if err := t.LoadAttributes(ctx); err != nil {
|
|
log.Warn("LoadAttributes of RepoTransfer: %v", err)
|
|
} else {
|
|
transfer = ToRepoTransfer(ctx, t)
|
|
}
|
|
}
|
|
}
|
|
|
|
var language string
|
|
if repo.PrimaryLanguage != nil {
|
|
language = repo.PrimaryLanguage.Language
|
|
}
|
|
|
|
repoAPIURL := repo.APIURL()
|
|
|
|
return &api.Repository{
|
|
ID: repo.ID,
|
|
Owner: ToUserWithAccessMode(ctx, repo.Owner, permissionInRepo.AccessMode),
|
|
Name: repo.Name,
|
|
FullName: repo.FullName(),
|
|
Description: repo.Description,
|
|
Private: repo.IsPrivate,
|
|
Template: repo.IsTemplate,
|
|
Empty: repo.IsEmpty,
|
|
Archived: repo.IsArchived,
|
|
Size: int(repo.Size / 1024),
|
|
Fork: repo.IsFork,
|
|
Parent: parent,
|
|
Mirror: repo.IsMirror,
|
|
HTMLURL: repo.HTMLURL(),
|
|
URL: repoAPIURL,
|
|
SSHURL: cloneLink.SSH,
|
|
CloneURL: cloneLink.HTTPS,
|
|
OriginalURL: repo.SanitizedOriginalURL(),
|
|
Website: repo.Website,
|
|
Language: language,
|
|
LanguagesURL: repoAPIURL + "/languages",
|
|
Stars: repo.NumStars,
|
|
Forks: repo.NumForks,
|
|
Watchers: repo.NumWatches,
|
|
OpenIssues: repo.NumOpenIssues,
|
|
OpenPulls: repo.NumOpenPulls,
|
|
Releases: int(numReleases),
|
|
DefaultBranch: repo.DefaultBranch,
|
|
Created: repo.CreatedUnix.AsTime(),
|
|
Updated: repo.UpdatedUnix.AsTime(),
|
|
ArchivedAt: repo.ArchivedUnix.AsTime(),
|
|
Permissions: permission,
|
|
HasIssues: hasIssues,
|
|
ExternalTracker: externalTracker,
|
|
InternalTracker: internalTracker,
|
|
HasWiki: hasWiki,
|
|
WikiBranch: repo.WikiBranch,
|
|
GloballyEditableWiki: globallyEditableWiki,
|
|
HasProjects: hasProjects,
|
|
HasReleases: hasReleases,
|
|
HasPackages: hasPackages,
|
|
HasActions: hasActions,
|
|
ExternalWiki: externalWiki,
|
|
HasPullRequests: hasPullRequests,
|
|
IgnoreWhitespaceConflicts: ignoreWhitespaceConflicts,
|
|
AllowMerge: allowMerge,
|
|
AllowRebase: allowRebase,
|
|
AllowRebaseMerge: allowRebaseMerge,
|
|
AllowSquash: allowSquash,
|
|
AllowFastForwardOnly: allowFastForwardOnly,
|
|
AllowRebaseUpdate: allowRebaseUpdate,
|
|
DefaultDeleteBranchAfterMerge: defaultDeleteBranchAfterMerge,
|
|
DefaultMergeStyle: string(defaultMergeStyle),
|
|
DefaultUpdateStyle: string(defaultUpdateStyle),
|
|
DefaultAllowMaintainerEdit: defaultAllowMaintainerEdit,
|
|
AvatarURL: repo.AvatarLink(ctx),
|
|
Internal: !repo.IsPrivate && repo.Owner.Visibility == api.VisibleTypePrivate,
|
|
MirrorInterval: mirrorInterval,
|
|
MirrorUpdated: mirrorUpdated,
|
|
RepoTransfer: transfer,
|
|
Topics: repo.Topics,
|
|
ObjectFormatName: repo.ObjectFormatName,
|
|
}
|
|
}
|
|
|
|
// ToRepoTransfer convert a models.RepoTransfer to a structs.RepeTransfer
|
|
func ToRepoTransfer(ctx context.Context, t *models.RepoTransfer) *api.RepoTransfer {
|
|
teams, _ := ToTeams(ctx, t.Teams, false)
|
|
|
|
return &api.RepoTransfer{
|
|
Doer: ToUser(ctx, t.Doer, nil),
|
|
Recipient: ToUser(ctx, t.Recipient, nil),
|
|
Teams: teams,
|
|
}
|
|
}
|