mirror of
https://github.com/harness/drone.git
synced 2025-05-12 06:59:54 +08:00
143 lines
3.7 KiB
Go
143 lines
3.7 KiB
Go
// Copyright 2023 Harness, Inc.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
package protection
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
|
|
"github.com/bmatcuk/doublestar/v4"
|
|
)
|
|
|
|
type Pattern struct {
|
|
Default bool `json:"default,omitempty"`
|
|
Include []string `json:"include,omitempty"`
|
|
Exclude []string `json:"exclude,omitempty"`
|
|
}
|
|
|
|
func (p *Pattern) JSON() json.RawMessage {
|
|
message, _ := ToJSON(p)
|
|
return message
|
|
}
|
|
|
|
func (p *Pattern) Validate() error {
|
|
for _, pattern := range p.Include {
|
|
if err := patternValidate(pattern); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
for _, pattern := range p.Exclude {
|
|
if err := patternValidate(pattern); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (p *Pattern) Matches(branchName, defaultName string) bool {
|
|
// Initially match everything, unless the default is set or the include patterns are defined.
|
|
matches := !p.Default && len(p.Include) == 0
|
|
|
|
// Apply the default branch.
|
|
matches = matches || p.Default && branchName == defaultName
|
|
|
|
// Apply the include patterns.
|
|
if !matches {
|
|
for _, include := range p.Include {
|
|
if matches = patternMatches(include, branchName); matches {
|
|
break
|
|
}
|
|
}
|
|
}
|
|
|
|
// Apply the exclude patterns.
|
|
for _, exclude := range p.Exclude {
|
|
matches = matches && !patternMatches(exclude, branchName)
|
|
}
|
|
|
|
return matches
|
|
}
|
|
|
|
func patternValidate(pattern string) error {
|
|
if pattern == "" {
|
|
return ErrPatternEmpty
|
|
}
|
|
_, err := doublestar.Match(pattern, "test")
|
|
if err != nil {
|
|
return ErrInvalidGlobstarPattern
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// patternMatches matches a name against the provided file name pattern. From the doublestar library:
|
|
//
|
|
// The pattern syntax is:
|
|
//
|
|
// pattern:
|
|
//
|
|
// { term }
|
|
//
|
|
// term:
|
|
//
|
|
// '*' matches any sequence of non-path-separators
|
|
// '**' matches any sequence of characters, including
|
|
// path separators.
|
|
// '?' matches any single non-path-separator character
|
|
// '[' [ '^' ] { character-range } ']'
|
|
// character class (must be non-empty)
|
|
// '{' { term } [ ',' { term } ... ] '}'
|
|
// c matches character c (c != '*', '?', '\\', '[')
|
|
// '\\' c matches character c
|
|
//
|
|
// character-range:
|
|
//
|
|
// c matches character c (c != '\\', '-', ']')
|
|
// '\\' c matches character c
|
|
// lo '-' hi matches character c for lo <= c <= hi
|
|
func patternMatches(pattern, branchName string) bool {
|
|
ok, _ := doublestar.Match(pattern, branchName)
|
|
return ok
|
|
}
|
|
|
|
func matchesName(rawPattern json.RawMessage, defaultBranchName, branchName string) (bool, error) {
|
|
pattern := Pattern{}
|
|
|
|
if err := json.Unmarshal(rawPattern, &pattern); err != nil {
|
|
return false, fmt.Errorf("failed to parse branch pattern: %w", err)
|
|
}
|
|
|
|
return pattern.Matches(branchName, defaultBranchName), nil
|
|
}
|
|
|
|
func matchedNames(rawPattern json.RawMessage, defaultBranchName string, branchNames ...string) ([]string, error) {
|
|
pattern := Pattern{}
|
|
|
|
if err := json.Unmarshal(rawPattern, &pattern); err != nil {
|
|
return nil, fmt.Errorf("failed to parse branch pattern: %w", err)
|
|
}
|
|
|
|
matched := make([]string, 0, len(branchNames))
|
|
|
|
for _, branchName := range branchNames {
|
|
if pattern.Matches(branchName, defaultBranchName) {
|
|
matched = append(matched, branchName)
|
|
}
|
|
}
|
|
|
|
return matched, nil
|
|
}
|