code.gitea.io/gitea@v1.21.7/models/repo/repo_unit.go (about)

     1  // Copyright 2017 The Gitea Authors. All rights reserved.
     2  // SPDX-License-Identifier: MIT
     3  
     4  package repo
     5  
     6  import (
     7  	"context"
     8  	"fmt"
     9  	"slices"
    10  	"strings"
    11  
    12  	"code.gitea.io/gitea/models/db"
    13  	"code.gitea.io/gitea/models/unit"
    14  	"code.gitea.io/gitea/modules/json"
    15  	"code.gitea.io/gitea/modules/setting"
    16  	"code.gitea.io/gitea/modules/timeutil"
    17  	"code.gitea.io/gitea/modules/util"
    18  
    19  	"xorm.io/xorm"
    20  	"xorm.io/xorm/convert"
    21  )
    22  
    23  // ErrUnitTypeNotExist represents a "UnitTypeNotExist" kind of error.
    24  type ErrUnitTypeNotExist struct {
    25  	UT unit.Type
    26  }
    27  
    28  // IsErrUnitTypeNotExist checks if an error is a ErrUnitNotExist.
    29  func IsErrUnitTypeNotExist(err error) bool {
    30  	_, ok := err.(ErrUnitTypeNotExist)
    31  	return ok
    32  }
    33  
    34  func (err ErrUnitTypeNotExist) Error() string {
    35  	return fmt.Sprintf("Unit type does not exist: %s", err.UT.String())
    36  }
    37  
    38  func (err ErrUnitTypeNotExist) Unwrap() error {
    39  	return util.ErrNotExist
    40  }
    41  
    42  // RepoUnit describes all units of a repository
    43  type RepoUnit struct { //revive:disable-line:exported
    44  	ID          int64
    45  	RepoID      int64              `xorm:"INDEX(s)"`
    46  	Type        unit.Type          `xorm:"INDEX(s)"`
    47  	Config      convert.Conversion `xorm:"TEXT"`
    48  	CreatedUnix timeutil.TimeStamp `xorm:"INDEX CREATED"`
    49  }
    50  
    51  func init() {
    52  	db.RegisterModel(new(RepoUnit))
    53  }
    54  
    55  // UnitConfig describes common unit config
    56  type UnitConfig struct{}
    57  
    58  // FromDB fills up a UnitConfig from serialized format.
    59  func (cfg *UnitConfig) FromDB(bs []byte) error {
    60  	return json.UnmarshalHandleDoubleEncode(bs, &cfg)
    61  }
    62  
    63  // ToDB exports a UnitConfig to a serialized format.
    64  func (cfg *UnitConfig) ToDB() ([]byte, error) {
    65  	return json.Marshal(cfg)
    66  }
    67  
    68  // ExternalWikiConfig describes external wiki config
    69  type ExternalWikiConfig struct {
    70  	ExternalWikiURL string
    71  }
    72  
    73  // FromDB fills up a ExternalWikiConfig from serialized format.
    74  func (cfg *ExternalWikiConfig) FromDB(bs []byte) error {
    75  	return json.UnmarshalHandleDoubleEncode(bs, &cfg)
    76  }
    77  
    78  // ToDB exports a ExternalWikiConfig to a serialized format.
    79  func (cfg *ExternalWikiConfig) ToDB() ([]byte, error) {
    80  	return json.Marshal(cfg)
    81  }
    82  
    83  // ExternalTrackerConfig describes external tracker config
    84  type ExternalTrackerConfig struct {
    85  	ExternalTrackerURL           string
    86  	ExternalTrackerFormat        string
    87  	ExternalTrackerStyle         string
    88  	ExternalTrackerRegexpPattern string
    89  }
    90  
    91  // FromDB fills up a ExternalTrackerConfig from serialized format.
    92  func (cfg *ExternalTrackerConfig) FromDB(bs []byte) error {
    93  	return json.UnmarshalHandleDoubleEncode(bs, &cfg)
    94  }
    95  
    96  // ToDB exports a ExternalTrackerConfig to a serialized format.
    97  func (cfg *ExternalTrackerConfig) ToDB() ([]byte, error) {
    98  	return json.Marshal(cfg)
    99  }
   100  
   101  // IssuesConfig describes issues config
   102  type IssuesConfig struct {
   103  	EnableTimetracker                bool
   104  	AllowOnlyContributorsToTrackTime bool
   105  	EnableDependencies               bool
   106  }
   107  
   108  // FromDB fills up a IssuesConfig from serialized format.
   109  func (cfg *IssuesConfig) FromDB(bs []byte) error {
   110  	return json.UnmarshalHandleDoubleEncode(bs, &cfg)
   111  }
   112  
   113  // ToDB exports a IssuesConfig to a serialized format.
   114  func (cfg *IssuesConfig) ToDB() ([]byte, error) {
   115  	return json.Marshal(cfg)
   116  }
   117  
   118  // PullRequestsConfig describes pull requests config
   119  type PullRequestsConfig struct {
   120  	IgnoreWhitespaceConflicts     bool
   121  	AllowMerge                    bool
   122  	AllowRebase                   bool
   123  	AllowRebaseMerge              bool
   124  	AllowSquash                   bool
   125  	AllowManualMerge              bool
   126  	AutodetectManualMerge         bool
   127  	AllowRebaseUpdate             bool
   128  	DefaultDeleteBranchAfterMerge bool
   129  	DefaultMergeStyle             MergeStyle
   130  	DefaultAllowMaintainerEdit    bool
   131  }
   132  
   133  // FromDB fills up a PullRequestsConfig from serialized format.
   134  func (cfg *PullRequestsConfig) FromDB(bs []byte) error {
   135  	// AllowRebaseUpdate = true as default for existing PullRequestConfig in DB
   136  	cfg.AllowRebaseUpdate = true
   137  	return json.UnmarshalHandleDoubleEncode(bs, &cfg)
   138  }
   139  
   140  // ToDB exports a PullRequestsConfig to a serialized format.
   141  func (cfg *PullRequestsConfig) ToDB() ([]byte, error) {
   142  	return json.Marshal(cfg)
   143  }
   144  
   145  // IsMergeStyleAllowed returns if merge style is allowed
   146  func (cfg *PullRequestsConfig) IsMergeStyleAllowed(mergeStyle MergeStyle) bool {
   147  	return mergeStyle == MergeStyleMerge && cfg.AllowMerge ||
   148  		mergeStyle == MergeStyleRebase && cfg.AllowRebase ||
   149  		mergeStyle == MergeStyleRebaseMerge && cfg.AllowRebaseMerge ||
   150  		mergeStyle == MergeStyleSquash && cfg.AllowSquash ||
   151  		mergeStyle == MergeStyleManuallyMerged && cfg.AllowManualMerge
   152  }
   153  
   154  // GetDefaultMergeStyle returns the default merge style for this pull request
   155  func (cfg *PullRequestsConfig) GetDefaultMergeStyle() MergeStyle {
   156  	if len(cfg.DefaultMergeStyle) != 0 {
   157  		return cfg.DefaultMergeStyle
   158  	}
   159  
   160  	if setting.Repository.PullRequest.DefaultMergeStyle != "" {
   161  		return MergeStyle(setting.Repository.PullRequest.DefaultMergeStyle)
   162  	}
   163  
   164  	return MergeStyleMerge
   165  }
   166  
   167  type ActionsConfig struct {
   168  	DisabledWorkflows []string
   169  }
   170  
   171  func (cfg *ActionsConfig) EnableWorkflow(file string) {
   172  	cfg.DisabledWorkflows = util.SliceRemoveAll(cfg.DisabledWorkflows, file)
   173  }
   174  
   175  func (cfg *ActionsConfig) ToString() string {
   176  	return strings.Join(cfg.DisabledWorkflows, ",")
   177  }
   178  
   179  func (cfg *ActionsConfig) IsWorkflowDisabled(file string) bool {
   180  	return slices.Contains(cfg.DisabledWorkflows, file)
   181  }
   182  
   183  func (cfg *ActionsConfig) DisableWorkflow(file string) {
   184  	for _, workflow := range cfg.DisabledWorkflows {
   185  		if file == workflow {
   186  			return
   187  		}
   188  	}
   189  
   190  	cfg.DisabledWorkflows = append(cfg.DisabledWorkflows, file)
   191  }
   192  
   193  // FromDB fills up a ActionsConfig from serialized format.
   194  func (cfg *ActionsConfig) FromDB(bs []byte) error {
   195  	return json.UnmarshalHandleDoubleEncode(bs, &cfg)
   196  }
   197  
   198  // ToDB exports a ActionsConfig to a serialized format.
   199  func (cfg *ActionsConfig) ToDB() ([]byte, error) {
   200  	return json.Marshal(cfg)
   201  }
   202  
   203  // BeforeSet is invoked from XORM before setting the value of a field of this object.
   204  func (r *RepoUnit) BeforeSet(colName string, val xorm.Cell) {
   205  	switch colName {
   206  	case "type":
   207  		switch unit.Type(db.Cell2Int64(val)) {
   208  		case unit.TypeExternalWiki:
   209  			r.Config = new(ExternalWikiConfig)
   210  		case unit.TypeExternalTracker:
   211  			r.Config = new(ExternalTrackerConfig)
   212  		case unit.TypePullRequests:
   213  			r.Config = new(PullRequestsConfig)
   214  		case unit.TypeIssues:
   215  			r.Config = new(IssuesConfig)
   216  		case unit.TypeActions:
   217  			r.Config = new(ActionsConfig)
   218  		case unit.TypeCode, unit.TypeReleases, unit.TypeWiki, unit.TypeProjects, unit.TypePackages:
   219  			fallthrough
   220  		default:
   221  			r.Config = new(UnitConfig)
   222  		}
   223  	}
   224  }
   225  
   226  // Unit returns Unit
   227  func (r *RepoUnit) Unit() unit.Unit {
   228  	return unit.Units[r.Type]
   229  }
   230  
   231  // CodeConfig returns config for unit.TypeCode
   232  func (r *RepoUnit) CodeConfig() *UnitConfig {
   233  	return r.Config.(*UnitConfig)
   234  }
   235  
   236  // PullRequestsConfig returns config for unit.TypePullRequests
   237  func (r *RepoUnit) PullRequestsConfig() *PullRequestsConfig {
   238  	return r.Config.(*PullRequestsConfig)
   239  }
   240  
   241  // ReleasesConfig returns config for unit.TypeReleases
   242  func (r *RepoUnit) ReleasesConfig() *UnitConfig {
   243  	return r.Config.(*UnitConfig)
   244  }
   245  
   246  // ExternalWikiConfig returns config for unit.TypeExternalWiki
   247  func (r *RepoUnit) ExternalWikiConfig() *ExternalWikiConfig {
   248  	return r.Config.(*ExternalWikiConfig)
   249  }
   250  
   251  // IssuesConfig returns config for unit.TypeIssues
   252  func (r *RepoUnit) IssuesConfig() *IssuesConfig {
   253  	return r.Config.(*IssuesConfig)
   254  }
   255  
   256  // ExternalTrackerConfig returns config for unit.TypeExternalTracker
   257  func (r *RepoUnit) ExternalTrackerConfig() *ExternalTrackerConfig {
   258  	return r.Config.(*ExternalTrackerConfig)
   259  }
   260  
   261  // ActionsConfig returns config for unit.ActionsConfig
   262  func (r *RepoUnit) ActionsConfig() *ActionsConfig {
   263  	return r.Config.(*ActionsConfig)
   264  }
   265  
   266  func getUnitsByRepoID(ctx context.Context, repoID int64) (units []*RepoUnit, err error) {
   267  	var tmpUnits []*RepoUnit
   268  	if err := db.GetEngine(ctx).Where("repo_id = ?", repoID).Find(&tmpUnits); err != nil {
   269  		return nil, err
   270  	}
   271  
   272  	for _, u := range tmpUnits {
   273  		if !u.Type.UnitGlobalDisabled() {
   274  			units = append(units, u)
   275  		}
   276  	}
   277  
   278  	return units, nil
   279  }
   280  
   281  // UpdateRepoUnit updates the provided repo unit
   282  func UpdateRepoUnit(unit *RepoUnit) error {
   283  	_, err := db.GetEngine(db.DefaultContext).ID(unit.ID).Update(unit)
   284  	return err
   285  }