code.gitea.io/gitea@v1.21.7/models/git/protected_branch_list.go (about)

     1  // Copyright 2022 The Gitea Authors. All rights reserved.
     2  // SPDX-License-Identifier: MIT
     3  
     4  package git
     5  
     6  import (
     7  	"context"
     8  	"sort"
     9  
    10  	"code.gitea.io/gitea/models/db"
    11  	"code.gitea.io/gitea/modules/util"
    12  
    13  	"github.com/gobwas/glob"
    14  )
    15  
    16  type ProtectedBranchRules []*ProtectedBranch
    17  
    18  func (rules ProtectedBranchRules) GetFirstMatched(branchName string) *ProtectedBranch {
    19  	for _, rule := range rules {
    20  		if rule.Match(branchName) {
    21  			return rule
    22  		}
    23  	}
    24  	return nil
    25  }
    26  
    27  func (rules ProtectedBranchRules) sort() {
    28  	sort.Slice(rules, func(i, j int) bool {
    29  		rules[i].loadGlob()
    30  		rules[j].loadGlob()
    31  		if rules[i].isPlainName != rules[j].isPlainName {
    32  			return rules[i].isPlainName // plain name comes first, so plain name means "less"
    33  		}
    34  		return rules[i].CreatedUnix < rules[j].CreatedUnix
    35  	})
    36  }
    37  
    38  // FindRepoProtectedBranchRules load all repository's protected rules
    39  func FindRepoProtectedBranchRules(ctx context.Context, repoID int64) (ProtectedBranchRules, error) {
    40  	var rules ProtectedBranchRules
    41  	err := db.GetEngine(ctx).Where("repo_id = ?", repoID).Asc("created_unix").Find(&rules)
    42  	if err != nil {
    43  		return nil, err
    44  	}
    45  	rules.sort() // to make non-glob rules have higher priority, and for same glob/non-glob rules, first created rules have higher priority
    46  	return rules, nil
    47  }
    48  
    49  // FindAllMatchedBranches find all matched branches
    50  func FindAllMatchedBranches(ctx context.Context, repoID int64, ruleName string) ([]string, error) {
    51  	results := make([]string, 0, 10)
    52  	for page := 1; ; page++ {
    53  		brancheNames, err := FindBranchNames(ctx, FindBranchOptions{
    54  			ListOptions: db.ListOptions{
    55  				PageSize: 100,
    56  				Page:     page,
    57  			},
    58  			RepoID:          repoID,
    59  			IsDeletedBranch: util.OptionalBoolFalse,
    60  		})
    61  		if err != nil {
    62  			return nil, err
    63  		}
    64  		rule := glob.MustCompile(ruleName)
    65  
    66  		for _, branch := range brancheNames {
    67  			if rule.Match(branch) {
    68  				results = append(results, branch)
    69  			}
    70  		}
    71  		if len(brancheNames) < 100 {
    72  			break
    73  		}
    74  	}
    75  
    76  	return results, nil
    77  }
    78  
    79  // GetFirstMatchProtectedBranchRule returns the first matched rules
    80  func GetFirstMatchProtectedBranchRule(ctx context.Context, repoID int64, branchName string) (*ProtectedBranch, error) {
    81  	rules, err := FindRepoProtectedBranchRules(ctx, repoID)
    82  	if err != nil {
    83  		return nil, err
    84  	}
    85  	return rules.GetFirstMatched(branchName), nil
    86  }
    87  
    88  // IsBranchProtected checks if branch is protected
    89  func IsBranchProtected(ctx context.Context, repoID int64, branchName string) (bool, error) {
    90  	rule, err := GetFirstMatchProtectedBranchRule(ctx, repoID, branchName)
    91  	if err != nil {
    92  		return false, err
    93  	}
    94  	return rule != nil, nil
    95  }