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 }