mirror of
				https://github.com/go-gitea/gitea
				synced 2025-10-26 00:48:29 +00:00 
			
		
		
		
	enable mirror, usestdlibbars and perfsprint part of: https://github.com/go-gitea/gitea/issues/34083 --------- Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
		
			
				
	
	
		
			350 lines
		
	
	
		
			9.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			350 lines
		
	
	
		
			9.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| // Copyright 2017 The Gitea Authors. All rights reserved.
 | |
| // SPDX-License-Identifier: MIT
 | |
| 
 | |
| package repo
 | |
| 
 | |
| import (
 | |
| 	"context"
 | |
| 	"slices"
 | |
| 	"strings"
 | |
| 
 | |
| 	"code.gitea.io/gitea/models/db"
 | |
| 	"code.gitea.io/gitea/models/perm"
 | |
| 	"code.gitea.io/gitea/models/unit"
 | |
| 	"code.gitea.io/gitea/modules/json"
 | |
| 	"code.gitea.io/gitea/modules/setting"
 | |
| 	"code.gitea.io/gitea/modules/timeutil"
 | |
| 	"code.gitea.io/gitea/modules/util"
 | |
| 
 | |
| 	"xorm.io/xorm"
 | |
| 	"xorm.io/xorm/convert"
 | |
| )
 | |
| 
 | |
| // ErrUnitTypeNotExist represents a "UnitTypeNotExist" kind of error.
 | |
| type ErrUnitTypeNotExist struct {
 | |
| 	UT unit.Type
 | |
| }
 | |
| 
 | |
| // IsErrUnitTypeNotExist checks if an error is a ErrUnitNotExist.
 | |
| func IsErrUnitTypeNotExist(err error) bool {
 | |
| 	_, ok := err.(ErrUnitTypeNotExist)
 | |
| 	return ok
 | |
| }
 | |
| 
 | |
| func (err ErrUnitTypeNotExist) Error() string {
 | |
| 	return "Unit type does not exist: " + err.UT.LogString()
 | |
| }
 | |
| 
 | |
| func (err ErrUnitTypeNotExist) Unwrap() error {
 | |
| 	return util.ErrNotExist
 | |
| }
 | |
| 
 | |
| // RepoUnit describes all units of a repository
 | |
| type RepoUnit struct { //revive:disable-line:exported
 | |
| 	ID                  int64
 | |
| 	RepoID              int64              `xorm:"INDEX(s)"`
 | |
| 	Type                unit.Type          `xorm:"INDEX(s)"`
 | |
| 	Config              convert.Conversion `xorm:"TEXT"`
 | |
| 	CreatedUnix         timeutil.TimeStamp `xorm:"INDEX CREATED"`
 | |
| 	AnonymousAccessMode perm.AccessMode    `xorm:"NOT NULL DEFAULT 0"`
 | |
| 	EveryoneAccessMode  perm.AccessMode    `xorm:"NOT NULL DEFAULT 0"`
 | |
| }
 | |
| 
 | |
| func init() {
 | |
| 	db.RegisterModel(new(RepoUnit))
 | |
| }
 | |
| 
 | |
| // UnitConfig describes common unit config
 | |
| type UnitConfig struct{}
 | |
| 
 | |
| // FromDB fills up a UnitConfig from serialized format.
 | |
| func (cfg *UnitConfig) FromDB(bs []byte) error {
 | |
| 	return json.UnmarshalHandleDoubleEncode(bs, &cfg)
 | |
| }
 | |
| 
 | |
| // ToDB exports a UnitConfig to a serialized format.
 | |
| func (cfg *UnitConfig) ToDB() ([]byte, error) {
 | |
| 	return json.Marshal(cfg)
 | |
| }
 | |
| 
 | |
| // ExternalWikiConfig describes external wiki config
 | |
| type ExternalWikiConfig struct {
 | |
| 	ExternalWikiURL string
 | |
| }
 | |
| 
 | |
| // FromDB fills up a ExternalWikiConfig from serialized format.
 | |
| func (cfg *ExternalWikiConfig) FromDB(bs []byte) error {
 | |
| 	return json.UnmarshalHandleDoubleEncode(bs, &cfg)
 | |
| }
 | |
| 
 | |
| // ToDB exports a ExternalWikiConfig to a serialized format.
 | |
| func (cfg *ExternalWikiConfig) ToDB() ([]byte, error) {
 | |
| 	return json.Marshal(cfg)
 | |
| }
 | |
| 
 | |
| // ExternalTrackerConfig describes external tracker config
 | |
| type ExternalTrackerConfig struct {
 | |
| 	ExternalTrackerURL           string
 | |
| 	ExternalTrackerFormat        string
 | |
| 	ExternalTrackerStyle         string
 | |
| 	ExternalTrackerRegexpPattern string
 | |
| }
 | |
| 
 | |
| // FromDB fills up a ExternalTrackerConfig from serialized format.
 | |
| func (cfg *ExternalTrackerConfig) FromDB(bs []byte) error {
 | |
| 	return json.UnmarshalHandleDoubleEncode(bs, &cfg)
 | |
| }
 | |
| 
 | |
| // ToDB exports a ExternalTrackerConfig to a serialized format.
 | |
| func (cfg *ExternalTrackerConfig) ToDB() ([]byte, error) {
 | |
| 	return json.Marshal(cfg)
 | |
| }
 | |
| 
 | |
| // IssuesConfig describes issues config
 | |
| type IssuesConfig struct {
 | |
| 	EnableTimetracker                bool
 | |
| 	AllowOnlyContributorsToTrackTime bool
 | |
| 	EnableDependencies               bool
 | |
| }
 | |
| 
 | |
| // FromDB fills up a IssuesConfig from serialized format.
 | |
| func (cfg *IssuesConfig) FromDB(bs []byte) error {
 | |
| 	return json.UnmarshalHandleDoubleEncode(bs, &cfg)
 | |
| }
 | |
| 
 | |
| // ToDB exports a IssuesConfig to a serialized format.
 | |
| func (cfg *IssuesConfig) ToDB() ([]byte, error) {
 | |
| 	return json.Marshal(cfg)
 | |
| }
 | |
| 
 | |
| // PullRequestsConfig describes pull requests config
 | |
| type PullRequestsConfig struct {
 | |
| 	IgnoreWhitespaceConflicts     bool
 | |
| 	AllowMerge                    bool
 | |
| 	AllowRebase                   bool
 | |
| 	AllowRebaseMerge              bool
 | |
| 	AllowSquash                   bool
 | |
| 	AllowFastForwardOnly          bool
 | |
| 	AllowManualMerge              bool
 | |
| 	AutodetectManualMerge         bool
 | |
| 	AllowRebaseUpdate             bool
 | |
| 	DefaultDeleteBranchAfterMerge bool
 | |
| 	DefaultMergeStyle             MergeStyle
 | |
| 	DefaultAllowMaintainerEdit    bool
 | |
| }
 | |
| 
 | |
| // FromDB fills up a PullRequestsConfig from serialized format.
 | |
| func (cfg *PullRequestsConfig) FromDB(bs []byte) error {
 | |
| 	// AllowRebaseUpdate = true as default for existing PullRequestConfig in DB
 | |
| 	cfg.AllowRebaseUpdate = true
 | |
| 	return json.UnmarshalHandleDoubleEncode(bs, &cfg)
 | |
| }
 | |
| 
 | |
| // ToDB exports a PullRequestsConfig to a serialized format.
 | |
| func (cfg *PullRequestsConfig) ToDB() ([]byte, error) {
 | |
| 	return json.Marshal(cfg)
 | |
| }
 | |
| 
 | |
| // IsMergeStyleAllowed returns if merge style is allowed
 | |
| func (cfg *PullRequestsConfig) IsMergeStyleAllowed(mergeStyle MergeStyle) bool {
 | |
| 	return mergeStyle == MergeStyleMerge && cfg.AllowMerge ||
 | |
| 		mergeStyle == MergeStyleRebase && cfg.AllowRebase ||
 | |
| 		mergeStyle == MergeStyleRebaseMerge && cfg.AllowRebaseMerge ||
 | |
| 		mergeStyle == MergeStyleSquash && cfg.AllowSquash ||
 | |
| 		mergeStyle == MergeStyleFastForwardOnly && cfg.AllowFastForwardOnly ||
 | |
| 		mergeStyle == MergeStyleManuallyMerged && cfg.AllowManualMerge
 | |
| }
 | |
| 
 | |
| // GetDefaultMergeStyle returns the default merge style for this pull request
 | |
| func (cfg *PullRequestsConfig) GetDefaultMergeStyle() MergeStyle {
 | |
| 	if len(cfg.DefaultMergeStyle) != 0 {
 | |
| 		return cfg.DefaultMergeStyle
 | |
| 	}
 | |
| 
 | |
| 	if setting.Repository.PullRequest.DefaultMergeStyle != "" {
 | |
| 		return MergeStyle(setting.Repository.PullRequest.DefaultMergeStyle)
 | |
| 	}
 | |
| 
 | |
| 	return MergeStyleMerge
 | |
| }
 | |
| 
 | |
| type ActionsConfig struct {
 | |
| 	DisabledWorkflows []string
 | |
| }
 | |
| 
 | |
| func (cfg *ActionsConfig) EnableWorkflow(file string) {
 | |
| 	cfg.DisabledWorkflows = util.SliceRemoveAll(cfg.DisabledWorkflows, file)
 | |
| }
 | |
| 
 | |
| func (cfg *ActionsConfig) ToString() string {
 | |
| 	return strings.Join(cfg.DisabledWorkflows, ",")
 | |
| }
 | |
| 
 | |
| func (cfg *ActionsConfig) IsWorkflowDisabled(file string) bool {
 | |
| 	return slices.Contains(cfg.DisabledWorkflows, file)
 | |
| }
 | |
| 
 | |
| func (cfg *ActionsConfig) DisableWorkflow(file string) {
 | |
| 	for _, workflow := range cfg.DisabledWorkflows {
 | |
| 		if file == workflow {
 | |
| 			return
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	cfg.DisabledWorkflows = append(cfg.DisabledWorkflows, file)
 | |
| }
 | |
| 
 | |
| // FromDB fills up a ActionsConfig from serialized format.
 | |
| func (cfg *ActionsConfig) FromDB(bs []byte) error {
 | |
| 	return json.UnmarshalHandleDoubleEncode(bs, &cfg)
 | |
| }
 | |
| 
 | |
| // ToDB exports a ActionsConfig to a serialized format.
 | |
| func (cfg *ActionsConfig) ToDB() ([]byte, error) {
 | |
| 	return json.Marshal(cfg)
 | |
| }
 | |
| 
 | |
| // ProjectsMode represents the projects enabled for a repository
 | |
| type ProjectsMode string
 | |
| 
 | |
| const (
 | |
| 	// ProjectsModeRepo allows only repo-level projects
 | |
| 	ProjectsModeRepo ProjectsMode = "repo"
 | |
| 	// ProjectsModeOwner allows only owner-level projects
 | |
| 	ProjectsModeOwner ProjectsMode = "owner"
 | |
| 	// ProjectsModeAll allows both kinds of projects
 | |
| 	ProjectsModeAll ProjectsMode = "all"
 | |
| 	// ProjectsModeNone doesn't allow projects
 | |
| 	ProjectsModeNone ProjectsMode = "none"
 | |
| )
 | |
| 
 | |
| // ProjectsConfig describes projects config
 | |
| type ProjectsConfig struct {
 | |
| 	ProjectsMode ProjectsMode
 | |
| }
 | |
| 
 | |
| // FromDB fills up a ProjectsConfig from serialized format.
 | |
| func (cfg *ProjectsConfig) FromDB(bs []byte) error {
 | |
| 	return json.UnmarshalHandleDoubleEncode(bs, &cfg)
 | |
| }
 | |
| 
 | |
| // ToDB exports a ProjectsConfig to a serialized format.
 | |
| func (cfg *ProjectsConfig) ToDB() ([]byte, error) {
 | |
| 	return json.Marshal(cfg)
 | |
| }
 | |
| 
 | |
| func (cfg *ProjectsConfig) GetProjectsMode() ProjectsMode {
 | |
| 	if cfg.ProjectsMode != "" {
 | |
| 		return cfg.ProjectsMode
 | |
| 	}
 | |
| 
 | |
| 	return ProjectsModeAll
 | |
| }
 | |
| 
 | |
| func (cfg *ProjectsConfig) IsProjectsAllowed(m ProjectsMode) bool {
 | |
| 	projectsMode := cfg.GetProjectsMode()
 | |
| 
 | |
| 	if m == ProjectsModeNone {
 | |
| 		return true
 | |
| 	}
 | |
| 
 | |
| 	return projectsMode == m || projectsMode == ProjectsModeAll
 | |
| }
 | |
| 
 | |
| // BeforeSet is invoked from XORM before setting the value of a field of this object.
 | |
| func (r *RepoUnit) BeforeSet(colName string, val xorm.Cell) {
 | |
| 	switch colName {
 | |
| 	case "type":
 | |
| 		switch unit.Type(db.Cell2Int64(val)) {
 | |
| 		case unit.TypeExternalWiki:
 | |
| 			r.Config = new(ExternalWikiConfig)
 | |
| 		case unit.TypeExternalTracker:
 | |
| 			r.Config = new(ExternalTrackerConfig)
 | |
| 		case unit.TypePullRequests:
 | |
| 			r.Config = new(PullRequestsConfig)
 | |
| 		case unit.TypeIssues:
 | |
| 			r.Config = new(IssuesConfig)
 | |
| 		case unit.TypeActions:
 | |
| 			r.Config = new(ActionsConfig)
 | |
| 		case unit.TypeProjects:
 | |
| 			r.Config = new(ProjectsConfig)
 | |
| 		case unit.TypeCode, unit.TypeReleases, unit.TypeWiki, unit.TypePackages:
 | |
| 			fallthrough
 | |
| 		default:
 | |
| 			r.Config = new(UnitConfig)
 | |
| 		}
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // Unit returns Unit
 | |
| func (r *RepoUnit) Unit() unit.Unit {
 | |
| 	return unit.Units[r.Type]
 | |
| }
 | |
| 
 | |
| // CodeConfig returns config for unit.TypeCode
 | |
| func (r *RepoUnit) CodeConfig() *UnitConfig {
 | |
| 	return r.Config.(*UnitConfig)
 | |
| }
 | |
| 
 | |
| // PullRequestsConfig returns config for unit.TypePullRequests
 | |
| func (r *RepoUnit) PullRequestsConfig() *PullRequestsConfig {
 | |
| 	return r.Config.(*PullRequestsConfig)
 | |
| }
 | |
| 
 | |
| // ReleasesConfig returns config for unit.TypeReleases
 | |
| func (r *RepoUnit) ReleasesConfig() *UnitConfig {
 | |
| 	return r.Config.(*UnitConfig)
 | |
| }
 | |
| 
 | |
| // ExternalWikiConfig returns config for unit.TypeExternalWiki
 | |
| func (r *RepoUnit) ExternalWikiConfig() *ExternalWikiConfig {
 | |
| 	return r.Config.(*ExternalWikiConfig)
 | |
| }
 | |
| 
 | |
| // IssuesConfig returns config for unit.TypeIssues
 | |
| func (r *RepoUnit) IssuesConfig() *IssuesConfig {
 | |
| 	return r.Config.(*IssuesConfig)
 | |
| }
 | |
| 
 | |
| // ExternalTrackerConfig returns config for unit.TypeExternalTracker
 | |
| func (r *RepoUnit) ExternalTrackerConfig() *ExternalTrackerConfig {
 | |
| 	return r.Config.(*ExternalTrackerConfig)
 | |
| }
 | |
| 
 | |
| // ActionsConfig returns config for unit.ActionsConfig
 | |
| func (r *RepoUnit) ActionsConfig() *ActionsConfig {
 | |
| 	return r.Config.(*ActionsConfig)
 | |
| }
 | |
| 
 | |
| // ProjectsConfig returns config for unit.ProjectsConfig
 | |
| func (r *RepoUnit) ProjectsConfig() *ProjectsConfig {
 | |
| 	return r.Config.(*ProjectsConfig)
 | |
| }
 | |
| 
 | |
| func getUnitsByRepoID(ctx context.Context, repoID int64) (units []*RepoUnit, err error) {
 | |
| 	var tmpUnits []*RepoUnit
 | |
| 	if err := db.GetEngine(ctx).Where("repo_id = ?", repoID).Find(&tmpUnits); err != nil {
 | |
| 		return nil, err
 | |
| 	}
 | |
| 
 | |
| 	for _, u := range tmpUnits {
 | |
| 		if !u.Type.UnitGlobalDisabled() {
 | |
| 			units = append(units, u)
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	return units, nil
 | |
| }
 | |
| 
 | |
| // UpdateRepoUnit updates the provided repo unit
 | |
| func UpdateRepoUnit(ctx context.Context, unit *RepoUnit) error {
 | |
| 	_, err := db.GetEngine(ctx).ID(unit.ID).Update(unit)
 | |
| 	return err
 | |
| }
 | |
| 
 | |
| func UpdateRepoUnitPublicAccess(ctx context.Context, unit *RepoUnit) error {
 | |
| 	_, err := db.GetEngine(ctx).Where("repo_id=? AND `type`=?", unit.RepoID, unit.Type).
 | |
| 		Cols("anonymous_access_mode", "everyone_access_mode").Update(unit)
 | |
| 	return err
 | |
| }
 |