summaryrefslogtreecommitdiffstats
path: root/models/repo/repo_unit.go
diff options
context:
space:
mode:
Diffstat (limited to 'models/repo/repo_unit.go')
-rw-r--r--models/repo/repo_unit.go318
1 files changed, 318 insertions, 0 deletions
diff --git a/models/repo/repo_unit.go b/models/repo/repo_unit.go
new file mode 100644
index 00000000..ca82d54c
--- /dev/null
+++ b/models/repo/repo_unit.go
@@ -0,0 +1,318 @@
+// Copyright 2017 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package repo
+
+import (
+ "context"
+ "fmt"
+ "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 fmt.Sprintf("Unit type does not exist: %s", err.UT.String())
+}
+
+func (err ErrUnitTypeNotExist) Unwrap() error {
+ return util.ErrNotExist
+}
+
+// RepoUnitAccessMode specifies the users access mode to a repo unit
+type UnitAccessMode int
+
+const (
+ // UnitAccessModeUnset - no unit mode set
+ UnitAccessModeUnset UnitAccessMode = iota // 0
+ // UnitAccessModeNone no access
+ UnitAccessModeNone // 1
+ // UnitAccessModeRead read access
+ UnitAccessModeRead // 2
+ // UnitAccessModeWrite write access
+ UnitAccessModeWrite // 3
+)
+
+func (mode UnitAccessMode) ToAccessMode(modeIfUnset perm.AccessMode) perm.AccessMode {
+ switch mode {
+ case UnitAccessModeUnset:
+ return modeIfUnset
+ case UnitAccessModeNone:
+ return perm.AccessModeNone
+ case UnitAccessModeRead:
+ return perm.AccessModeRead
+ case UnitAccessModeWrite:
+ return perm.AccessModeWrite
+ default:
+ return perm.AccessModeNone
+ }
+}
+
+// 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"`
+ DefaultPermissions UnitAccessMode `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)
+}
+
+// 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.TypeCode, unit.TypeReleases, unit.TypeWiki, unit.TypeProjects, 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)
+}
+
+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
+}