mirror of https://github.com/containers/podman.git
				
				
				
			Merge pull request #22808 from containers/renovate/github.com-onsi-ginkgo-v2-2.x
fix(deps): update module github.com/onsi/ginkgo/v2 to v2.19.0
This commit is contained in:
		
						commit
						a74e8e8ba2
					
				
							
								
								
									
										2
									
								
								go.mod
								
								
								
								
							
							
						
						
									
										2
									
								
								go.mod
								
								
								
								
							| 
						 | 
				
			
			@ -52,7 +52,7 @@ require (
 | 
			
		|||
	github.com/moby/sys/user v0.1.0
 | 
			
		||||
	github.com/moby/term v0.5.0
 | 
			
		||||
	github.com/nxadm/tail v1.4.11
 | 
			
		||||
	github.com/onsi/ginkgo/v2 v2.18.0
 | 
			
		||||
	github.com/onsi/ginkgo/v2 v2.19.0
 | 
			
		||||
	github.com/onsi/gomega v1.33.1
 | 
			
		||||
	github.com/opencontainers/go-digest v1.0.0
 | 
			
		||||
	github.com/opencontainers/image-spec v1.1.0
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										4
									
								
								go.sum
								
								
								
								
							
							
						
						
									
										4
									
								
								go.sum
								
								
								
								
							| 
						 | 
				
			
			@ -397,8 +397,8 @@ github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W
 | 
			
		|||
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
 | 
			
		||||
github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0=
 | 
			
		||||
github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c=
 | 
			
		||||
github.com/onsi/ginkgo/v2 v2.18.0 h1:W9Y7IWXxPUpAit9ieMOLI7PJZGaW22DTKgiVAuhDTLc=
 | 
			
		||||
github.com/onsi/ginkgo/v2 v2.18.0/go.mod h1:rlwLi9PilAFJ8jCg9UE1QP6VBpd6/xj3SRC0d6TU0To=
 | 
			
		||||
github.com/onsi/ginkgo/v2 v2.19.0 h1:9Cnnf7UHo57Hy3k6/m5k3dRfGTMXGvxhHFvkDTCTpvA=
 | 
			
		||||
github.com/onsi/ginkgo/v2 v2.19.0/go.mod h1:rlwLi9PilAFJ8jCg9UE1QP6VBpd6/xj3SRC0d6TU0To=
 | 
			
		||||
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
 | 
			
		||||
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
 | 
			
		||||
github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,7 +5,7 @@ go 1.20
 | 
			
		|||
require (
 | 
			
		||||
	github.com/cpuguy83/go-md2man/v2 v2.0.4
 | 
			
		||||
	github.com/go-swagger/go-swagger v0.30.5
 | 
			
		||||
	github.com/onsi/ginkgo/v2 v2.18.0
 | 
			
		||||
	github.com/onsi/ginkgo/v2 v2.19.0
 | 
			
		||||
	github.com/vbatts/git-validation v1.2.1
 | 
			
		||||
	golang.org/x/tools v0.21.0
 | 
			
		||||
)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -280,8 +280,8 @@ github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJ
 | 
			
		|||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
 | 
			
		||||
github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4=
 | 
			
		||||
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
 | 
			
		||||
github.com/onsi/ginkgo/v2 v2.18.0 h1:W9Y7IWXxPUpAit9ieMOLI7PJZGaW22DTKgiVAuhDTLc=
 | 
			
		||||
github.com/onsi/ginkgo/v2 v2.18.0/go.mod h1:rlwLi9PilAFJ8jCg9UE1QP6VBpd6/xj3SRC0d6TU0To=
 | 
			
		||||
github.com/onsi/ginkgo/v2 v2.19.0 h1:9Cnnf7UHo57Hy3k6/m5k3dRfGTMXGvxhHFvkDTCTpvA=
 | 
			
		||||
github.com/onsi/ginkgo/v2 v2.19.0/go.mod h1:rlwLi9PilAFJ8jCg9UE1QP6VBpd6/xj3SRC0d6TU0To=
 | 
			
		||||
github.com/onsi/gomega v1.33.1 h1:dsYjIxxSR755MDmKVsaFQTE22ChNBcuuTWgkUDSubOk=
 | 
			
		||||
github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE=
 | 
			
		||||
github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ=
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -45,6 +45,83 @@ func orAction(a, b LabelFilter) LabelFilter {
 | 
			
		|||
	return func(labels []string) bool { return a(labels) || b(labels) }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func labelSetFor(key string, labels []string) map[string]bool {
 | 
			
		||||
	key = strings.ToLower(strings.TrimSpace(key))
 | 
			
		||||
	out := map[string]bool{}
 | 
			
		||||
	for _, label := range labels {
 | 
			
		||||
		components := strings.SplitN(label, ":", 2)
 | 
			
		||||
		if len(components) < 2 {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		if key == strings.ToLower(strings.TrimSpace(components[0])) {
 | 
			
		||||
			out[strings.ToLower(strings.TrimSpace(components[1]))] = true
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return out
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func isEmptyLabelSetAction(key string) LabelFilter {
 | 
			
		||||
	return func(labels []string) bool {
 | 
			
		||||
		return len(labelSetFor(key, labels)) == 0
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func containsAnyLabelSetAction(key string, expectedValues []string) LabelFilter {
 | 
			
		||||
	return func(labels []string) bool {
 | 
			
		||||
		set := labelSetFor(key, labels)
 | 
			
		||||
		for _, value := range expectedValues {
 | 
			
		||||
			if set[value] {
 | 
			
		||||
				return true
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func containsAllLabelSetAction(key string, expectedValues []string) LabelFilter {
 | 
			
		||||
	return func(labels []string) bool {
 | 
			
		||||
		set := labelSetFor(key, labels)
 | 
			
		||||
		for _, value := range expectedValues {
 | 
			
		||||
			if !set[value] {
 | 
			
		||||
				return false
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return true
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func consistsOfLabelSetAction(key string, expectedValues []string) LabelFilter {
 | 
			
		||||
	return func(labels []string) bool {
 | 
			
		||||
		set := labelSetFor(key, labels)
 | 
			
		||||
		if len(set) != len(expectedValues) {
 | 
			
		||||
			return false
 | 
			
		||||
		}
 | 
			
		||||
		for _, value := range expectedValues {
 | 
			
		||||
			if !set[value] {
 | 
			
		||||
				return false
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return true
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func isSubsetOfLabelSetAction(key string, expectedValues []string) LabelFilter {
 | 
			
		||||
	expectedSet := map[string]bool{}
 | 
			
		||||
	for _, value := range expectedValues {
 | 
			
		||||
		expectedSet[value] = true
 | 
			
		||||
	}
 | 
			
		||||
	return func(labels []string) bool {
 | 
			
		||||
		set := labelSetFor(key, labels)
 | 
			
		||||
		for value := range set {
 | 
			
		||||
			if !expectedSet[value] {
 | 
			
		||||
				return false
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return true
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type lfToken uint
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
| 
						 | 
				
			
			@ -58,6 +135,9 @@ const (
 | 
			
		|||
	lfTokenOr
 | 
			
		||||
	lfTokenRegexp
 | 
			
		||||
	lfTokenLabel
 | 
			
		||||
	lfTokenSetKey
 | 
			
		||||
	lfTokenSetOperation
 | 
			
		||||
	lfTokenSetArgument
 | 
			
		||||
	lfTokenEOF
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -71,6 +151,8 @@ func (l lfToken) Precedence() int {
 | 
			
		|||
		return 2
 | 
			
		||||
	case lfTokenNot:
 | 
			
		||||
		return 3
 | 
			
		||||
	case lfTokenSetOperation:
 | 
			
		||||
		return 4
 | 
			
		||||
	}
 | 
			
		||||
	return -1
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -93,6 +175,12 @@ func (l lfToken) String() string {
 | 
			
		|||
		return "/regexp/"
 | 
			
		||||
	case lfTokenLabel:
 | 
			
		||||
		return "label"
 | 
			
		||||
	case lfTokenSetKey:
 | 
			
		||||
		return "set_key"
 | 
			
		||||
	case lfTokenSetOperation:
 | 
			
		||||
		return "set_operation"
 | 
			
		||||
	case lfTokenSetArgument:
 | 
			
		||||
		return "set_argument"
 | 
			
		||||
	case lfTokenEOF:
 | 
			
		||||
		return "EOF"
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -148,6 +236,35 @@ func (tn *treeNode) constructLabelFilter(input string) (LabelFilter, error) {
 | 
			
		|||
			return nil, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, tn.location, fmt.Sprintf("RegExp compilation error: %s", err))
 | 
			
		||||
		}
 | 
			
		||||
		return matchLabelRegexAction(re), nil
 | 
			
		||||
	case lfTokenSetOperation:
 | 
			
		||||
		tokenSetOperation := strings.ToLower(tn.value)
 | 
			
		||||
		if tokenSetOperation == "isempty" {
 | 
			
		||||
			return isEmptyLabelSetAction(tn.leftNode.value), nil
 | 
			
		||||
		}
 | 
			
		||||
		if tn.rightNode == nil {
 | 
			
		||||
			return nil, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, tn.location, fmt.Sprintf("Set operation '%s' is missing an argument.", tn.value))
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		rawValues := strings.Split(tn.rightNode.value, ",")
 | 
			
		||||
		values := make([]string, len(rawValues))
 | 
			
		||||
		for i := range rawValues {
 | 
			
		||||
			values[i] = strings.ToLower(strings.TrimSpace(rawValues[i]))
 | 
			
		||||
			if strings.ContainsAny(values[i], "&|!,()/") {
 | 
			
		||||
				return nil, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, tn.rightNode.location, fmt.Sprintf("Invalid label value '%s' in set operation argument.", values[i]))
 | 
			
		||||
			} else if values[i] == "" {
 | 
			
		||||
				return nil, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, tn.rightNode.location, "Empty label value in set operation argument.")
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		switch tokenSetOperation {
 | 
			
		||||
		case "containsany":
 | 
			
		||||
			return containsAnyLabelSetAction(tn.leftNode.value, values), nil
 | 
			
		||||
		case "containsall":
 | 
			
		||||
			return containsAllLabelSetAction(tn.leftNode.value, values), nil
 | 
			
		||||
		case "consistsof":
 | 
			
		||||
			return consistsOfLabelSetAction(tn.leftNode.value, values), nil
 | 
			
		||||
		case "issubsetof":
 | 
			
		||||
			return isSubsetOfLabelSetAction(tn.leftNode.value, values), nil
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if tn.rightNode == nil {
 | 
			
		||||
| 
						 | 
				
			
			@ -203,7 +320,17 @@ func (tn *treeNode) toString(indent int) string {
 | 
			
		|||
	return out
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var validSetOperations = map[string]string{
 | 
			
		||||
	"containsany": "containsAny",
 | 
			
		||||
	"containsall": "containsAll",
 | 
			
		||||
	"consistsof":  "consistsOf",
 | 
			
		||||
	"issubsetof":  "isSubsetOf",
 | 
			
		||||
	"isempty":     "isEmpty",
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func tokenize(input string) func() (*treeNode, error) {
 | 
			
		||||
	lastToken := lfTokenInvalid
 | 
			
		||||
	lastValue := ""
 | 
			
		||||
	runes, i := []rune(input), 0
 | 
			
		||||
 | 
			
		||||
	peekIs := func(r rune) bool {
 | 
			
		||||
| 
						 | 
				
			
			@ -233,6 +360,53 @@ func tokenize(input string) func() (*treeNode, error) {
 | 
			
		|||
		}
 | 
			
		||||
 | 
			
		||||
		node := &treeNode{location: i}
 | 
			
		||||
		defer func() {
 | 
			
		||||
			lastToken = node.token
 | 
			
		||||
			lastValue = node.value
 | 
			
		||||
		}()
 | 
			
		||||
 | 
			
		||||
		if lastToken == lfTokenSetKey {
 | 
			
		||||
			//we should get a valid set operation next
 | 
			
		||||
			value, n := consumeUntil(" )")
 | 
			
		||||
			if validSetOperations[strings.ToLower(value)] == "" {
 | 
			
		||||
				return &treeNode{}, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, i, fmt.Sprintf("Invalid set operation '%s'.", value))
 | 
			
		||||
			}
 | 
			
		||||
			i += n
 | 
			
		||||
			node.token, node.value = lfTokenSetOperation, value
 | 
			
		||||
			return node, nil
 | 
			
		||||
		}
 | 
			
		||||
		if lastToken == lfTokenSetOperation {
 | 
			
		||||
			//we should get an argument next, if we aren't isempty
 | 
			
		||||
			var arg = ""
 | 
			
		||||
			origI := i
 | 
			
		||||
			if runes[i] == '{' {
 | 
			
		||||
				i += 1
 | 
			
		||||
				value, n := consumeUntil("}")
 | 
			
		||||
				if i+n >= len(runes) {
 | 
			
		||||
					return &treeNode{}, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, i-1, "Missing closing '}' in set operation argument?")
 | 
			
		||||
				}
 | 
			
		||||
				i += n + 1
 | 
			
		||||
				arg = value
 | 
			
		||||
			} else {
 | 
			
		||||
				value, n := consumeUntil("&|!,()/")
 | 
			
		||||
				i += n
 | 
			
		||||
				arg = strings.TrimSpace(value)
 | 
			
		||||
			}
 | 
			
		||||
			if strings.ToLower(lastValue) == "isempty" && arg != "" {
 | 
			
		||||
				return &treeNode{}, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, origI, fmt.Sprintf("isEmpty does not take arguments, was passed '%s'.", arg))
 | 
			
		||||
			}
 | 
			
		||||
			if arg == "" && strings.ToLower(lastValue) != "isempty" {
 | 
			
		||||
				if i < len(runes) && runes[i] == '/' {
 | 
			
		||||
					return &treeNode{}, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, origI, "Set operations do not support regular expressions.")
 | 
			
		||||
				} else {
 | 
			
		||||
					return &treeNode{}, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, origI, fmt.Sprintf("Set operation '%s' requires an argument.", lastValue))
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			// note that we sent an empty SetArgument token if we are isempty
 | 
			
		||||
			node.token, node.value = lfTokenSetArgument, arg
 | 
			
		||||
			return node, nil
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		switch runes[i] {
 | 
			
		||||
		case '&':
 | 
			
		||||
			if !peekIs('&') {
 | 
			
		||||
| 
						 | 
				
			
			@ -264,8 +438,38 @@ func tokenize(input string) func() (*treeNode, error) {
 | 
			
		|||
			i += n + 1
 | 
			
		||||
			node.token, node.value = lfTokenRegexp, value
 | 
			
		||||
		default:
 | 
			
		||||
			value, n := consumeUntil("&|!,()/")
 | 
			
		||||
			value, n := consumeUntil("&|!,()/:")
 | 
			
		||||
			i += n
 | 
			
		||||
			value = strings.TrimSpace(value)
 | 
			
		||||
 | 
			
		||||
			//are we the beginning of a set operation?
 | 
			
		||||
			if i < len(runes) && runes[i] == ':' {
 | 
			
		||||
				if peekIs(' ') {
 | 
			
		||||
					if value == "" {
 | 
			
		||||
						return &treeNode{}, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, i, "Missing set key.")
 | 
			
		||||
					}
 | 
			
		||||
					i += 1
 | 
			
		||||
					//we are the beginning of a set operation
 | 
			
		||||
					node.token, node.value = lfTokenSetKey, value
 | 
			
		||||
					return node, nil
 | 
			
		||||
				}
 | 
			
		||||
				additionalValue, n := consumeUntil("&|!,()/")
 | 
			
		||||
				additionalValue = strings.TrimSpace(additionalValue)
 | 
			
		||||
				if additionalValue == ":" {
 | 
			
		||||
					return &treeNode{}, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, i, "Missing set operation.")
 | 
			
		||||
				}
 | 
			
		||||
				i += n
 | 
			
		||||
				value += additionalValue
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			valueToCheckForSetOperation := strings.ToLower(value)
 | 
			
		||||
			for setOperation := range validSetOperations {
 | 
			
		||||
				idx := strings.Index(valueToCheckForSetOperation, " "+setOperation)
 | 
			
		||||
				if idx > 0 {
 | 
			
		||||
					return &treeNode{}, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, i-n+idx+1, fmt.Sprintf("Looks like you are using the set operator '%s' but did not provide a set key.  Did you forget the ':'?", validSetOperations[setOperation]))
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			node.token, node.value = lfTokenLabel, strings.TrimSpace(value)
 | 
			
		||||
		}
 | 
			
		||||
		return node, nil
 | 
			
		||||
| 
						 | 
				
			
			@ -307,7 +511,7 @@ LOOP:
 | 
			
		|||
		switch node.token {
 | 
			
		||||
		case lfTokenEOF:
 | 
			
		||||
			break LOOP
 | 
			
		||||
		case lfTokenLabel, lfTokenRegexp:
 | 
			
		||||
		case lfTokenLabel, lfTokenRegexp, lfTokenSetKey:
 | 
			
		||||
			if current.rightNode != nil {
 | 
			
		||||
				return nil, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, node.location, "Found two adjacent labels.  You need an operator between them.")
 | 
			
		||||
			}
 | 
			
		||||
| 
						 | 
				
			
			@ -326,6 +530,18 @@ LOOP:
 | 
			
		|||
			node.setLeftNode(nodeToStealFrom.rightNode)
 | 
			
		||||
			nodeToStealFrom.setRightNode(node)
 | 
			
		||||
			current = node
 | 
			
		||||
		case lfTokenSetOperation:
 | 
			
		||||
			if current.rightNode == nil {
 | 
			
		||||
				return nil, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, node.location, fmt.Sprintf("Set operation '%s' missing left hand operand.", node.value))
 | 
			
		||||
			}
 | 
			
		||||
			node.setLeftNode(current.rightNode)
 | 
			
		||||
			current.setRightNode(node)
 | 
			
		||||
			current = node
 | 
			
		||||
		case lfTokenSetArgument:
 | 
			
		||||
			if current.rightNode != nil {
 | 
			
		||||
				return nil, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, node.location, fmt.Sprintf("Unexpected set argument '%s'.", node.token))
 | 
			
		||||
			}
 | 
			
		||||
			current.setRightNode(node)
 | 
			
		||||
		case lfTokenCloseGroup:
 | 
			
		||||
			firstUnmatchedOpenNode := current.firstUnmatchedOpenNode()
 | 
			
		||||
			if firstUnmatchedOpenNode == nil {
 | 
			
		||||
| 
						 | 
				
			
			@ -354,5 +570,14 @@ func ValidateAndCleanupLabel(label string, cl CodeLocation) (string, error) {
 | 
			
		|||
	if strings.ContainsAny(out, "&|!,()/") {
 | 
			
		||||
		return "", GinkgoErrors.InvalidLabel(label, cl)
 | 
			
		||||
	}
 | 
			
		||||
	if out[0] == ':' {
 | 
			
		||||
		return "", GinkgoErrors.InvalidLabel(label, cl)
 | 
			
		||||
	}
 | 
			
		||||
	if strings.Contains(out, ":") {
 | 
			
		||||
		components := strings.SplitN(out, ":", 2)
 | 
			
		||||
		if len(components) < 2 || components[1] == "" {
 | 
			
		||||
			return "", GinkgoErrors.InvalidLabel(label, cl)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return out, nil
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,3 +1,3 @@
 | 
			
		|||
package types
 | 
			
		||||
 | 
			
		||||
const VERSION = "2.18.0"
 | 
			
		||||
const VERSION = "2.19.0"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -154,7 +154,7 @@ github.com/mitchellh/reflectwalk
 | 
			
		|||
# github.com/oklog/ulid v1.3.1
 | 
			
		||||
## explicit
 | 
			
		||||
github.com/oklog/ulid
 | 
			
		||||
# github.com/onsi/ginkgo/v2 v2.18.0
 | 
			
		||||
# github.com/onsi/ginkgo/v2 v2.19.0
 | 
			
		||||
## explicit; go 1.20
 | 
			
		||||
github.com/onsi/ginkgo/v2/config
 | 
			
		||||
github.com/onsi/ginkgo/v2/formatter
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,3 +1,9 @@
 | 
			
		|||
## 2.19.0
 | 
			
		||||
 | 
			
		||||
### Features
 | 
			
		||||
 | 
			
		||||
[Label Sets](https://onsi.github.io/ginkgo/#label-sets) allow for more expressive and flexible label filtering.
 | 
			
		||||
 | 
			
		||||
## 2.18.0
 | 
			
		||||
 | 
			
		||||
### Features
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -45,6 +45,83 @@ func orAction(a, b LabelFilter) LabelFilter {
 | 
			
		|||
	return func(labels []string) bool { return a(labels) || b(labels) }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func labelSetFor(key string, labels []string) map[string]bool {
 | 
			
		||||
	key = strings.ToLower(strings.TrimSpace(key))
 | 
			
		||||
	out := map[string]bool{}
 | 
			
		||||
	for _, label := range labels {
 | 
			
		||||
		components := strings.SplitN(label, ":", 2)
 | 
			
		||||
		if len(components) < 2 {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		if key == strings.ToLower(strings.TrimSpace(components[0])) {
 | 
			
		||||
			out[strings.ToLower(strings.TrimSpace(components[1]))] = true
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return out
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func isEmptyLabelSetAction(key string) LabelFilter {
 | 
			
		||||
	return func(labels []string) bool {
 | 
			
		||||
		return len(labelSetFor(key, labels)) == 0
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func containsAnyLabelSetAction(key string, expectedValues []string) LabelFilter {
 | 
			
		||||
	return func(labels []string) bool {
 | 
			
		||||
		set := labelSetFor(key, labels)
 | 
			
		||||
		for _, value := range expectedValues {
 | 
			
		||||
			if set[value] {
 | 
			
		||||
				return true
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func containsAllLabelSetAction(key string, expectedValues []string) LabelFilter {
 | 
			
		||||
	return func(labels []string) bool {
 | 
			
		||||
		set := labelSetFor(key, labels)
 | 
			
		||||
		for _, value := range expectedValues {
 | 
			
		||||
			if !set[value] {
 | 
			
		||||
				return false
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return true
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func consistsOfLabelSetAction(key string, expectedValues []string) LabelFilter {
 | 
			
		||||
	return func(labels []string) bool {
 | 
			
		||||
		set := labelSetFor(key, labels)
 | 
			
		||||
		if len(set) != len(expectedValues) {
 | 
			
		||||
			return false
 | 
			
		||||
		}
 | 
			
		||||
		for _, value := range expectedValues {
 | 
			
		||||
			if !set[value] {
 | 
			
		||||
				return false
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return true
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func isSubsetOfLabelSetAction(key string, expectedValues []string) LabelFilter {
 | 
			
		||||
	expectedSet := map[string]bool{}
 | 
			
		||||
	for _, value := range expectedValues {
 | 
			
		||||
		expectedSet[value] = true
 | 
			
		||||
	}
 | 
			
		||||
	return func(labels []string) bool {
 | 
			
		||||
		set := labelSetFor(key, labels)
 | 
			
		||||
		for value := range set {
 | 
			
		||||
			if !expectedSet[value] {
 | 
			
		||||
				return false
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return true
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type lfToken uint
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
| 
						 | 
				
			
			@ -58,6 +135,9 @@ const (
 | 
			
		|||
	lfTokenOr
 | 
			
		||||
	lfTokenRegexp
 | 
			
		||||
	lfTokenLabel
 | 
			
		||||
	lfTokenSetKey
 | 
			
		||||
	lfTokenSetOperation
 | 
			
		||||
	lfTokenSetArgument
 | 
			
		||||
	lfTokenEOF
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -71,6 +151,8 @@ func (l lfToken) Precedence() int {
 | 
			
		|||
		return 2
 | 
			
		||||
	case lfTokenNot:
 | 
			
		||||
		return 3
 | 
			
		||||
	case lfTokenSetOperation:
 | 
			
		||||
		return 4
 | 
			
		||||
	}
 | 
			
		||||
	return -1
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -93,6 +175,12 @@ func (l lfToken) String() string {
 | 
			
		|||
		return "/regexp/"
 | 
			
		||||
	case lfTokenLabel:
 | 
			
		||||
		return "label"
 | 
			
		||||
	case lfTokenSetKey:
 | 
			
		||||
		return "set_key"
 | 
			
		||||
	case lfTokenSetOperation:
 | 
			
		||||
		return "set_operation"
 | 
			
		||||
	case lfTokenSetArgument:
 | 
			
		||||
		return "set_argument"
 | 
			
		||||
	case lfTokenEOF:
 | 
			
		||||
		return "EOF"
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -148,6 +236,35 @@ func (tn *treeNode) constructLabelFilter(input string) (LabelFilter, error) {
 | 
			
		|||
			return nil, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, tn.location, fmt.Sprintf("RegExp compilation error: %s", err))
 | 
			
		||||
		}
 | 
			
		||||
		return matchLabelRegexAction(re), nil
 | 
			
		||||
	case lfTokenSetOperation:
 | 
			
		||||
		tokenSetOperation := strings.ToLower(tn.value)
 | 
			
		||||
		if tokenSetOperation == "isempty" {
 | 
			
		||||
			return isEmptyLabelSetAction(tn.leftNode.value), nil
 | 
			
		||||
		}
 | 
			
		||||
		if tn.rightNode == nil {
 | 
			
		||||
			return nil, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, tn.location, fmt.Sprintf("Set operation '%s' is missing an argument.", tn.value))
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		rawValues := strings.Split(tn.rightNode.value, ",")
 | 
			
		||||
		values := make([]string, len(rawValues))
 | 
			
		||||
		for i := range rawValues {
 | 
			
		||||
			values[i] = strings.ToLower(strings.TrimSpace(rawValues[i]))
 | 
			
		||||
			if strings.ContainsAny(values[i], "&|!,()/") {
 | 
			
		||||
				return nil, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, tn.rightNode.location, fmt.Sprintf("Invalid label value '%s' in set operation argument.", values[i]))
 | 
			
		||||
			} else if values[i] == "" {
 | 
			
		||||
				return nil, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, tn.rightNode.location, "Empty label value in set operation argument.")
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		switch tokenSetOperation {
 | 
			
		||||
		case "containsany":
 | 
			
		||||
			return containsAnyLabelSetAction(tn.leftNode.value, values), nil
 | 
			
		||||
		case "containsall":
 | 
			
		||||
			return containsAllLabelSetAction(tn.leftNode.value, values), nil
 | 
			
		||||
		case "consistsof":
 | 
			
		||||
			return consistsOfLabelSetAction(tn.leftNode.value, values), nil
 | 
			
		||||
		case "issubsetof":
 | 
			
		||||
			return isSubsetOfLabelSetAction(tn.leftNode.value, values), nil
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if tn.rightNode == nil {
 | 
			
		||||
| 
						 | 
				
			
			@ -203,7 +320,17 @@ func (tn *treeNode) toString(indent int) string {
 | 
			
		|||
	return out
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var validSetOperations = map[string]string{
 | 
			
		||||
	"containsany": "containsAny",
 | 
			
		||||
	"containsall": "containsAll",
 | 
			
		||||
	"consistsof":  "consistsOf",
 | 
			
		||||
	"issubsetof":  "isSubsetOf",
 | 
			
		||||
	"isempty":     "isEmpty",
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func tokenize(input string) func() (*treeNode, error) {
 | 
			
		||||
	lastToken := lfTokenInvalid
 | 
			
		||||
	lastValue := ""
 | 
			
		||||
	runes, i := []rune(input), 0
 | 
			
		||||
 | 
			
		||||
	peekIs := func(r rune) bool {
 | 
			
		||||
| 
						 | 
				
			
			@ -233,6 +360,53 @@ func tokenize(input string) func() (*treeNode, error) {
 | 
			
		|||
		}
 | 
			
		||||
 | 
			
		||||
		node := &treeNode{location: i}
 | 
			
		||||
		defer func() {
 | 
			
		||||
			lastToken = node.token
 | 
			
		||||
			lastValue = node.value
 | 
			
		||||
		}()
 | 
			
		||||
 | 
			
		||||
		if lastToken == lfTokenSetKey {
 | 
			
		||||
			//we should get a valid set operation next
 | 
			
		||||
			value, n := consumeUntil(" )")
 | 
			
		||||
			if validSetOperations[strings.ToLower(value)] == "" {
 | 
			
		||||
				return &treeNode{}, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, i, fmt.Sprintf("Invalid set operation '%s'.", value))
 | 
			
		||||
			}
 | 
			
		||||
			i += n
 | 
			
		||||
			node.token, node.value = lfTokenSetOperation, value
 | 
			
		||||
			return node, nil
 | 
			
		||||
		}
 | 
			
		||||
		if lastToken == lfTokenSetOperation {
 | 
			
		||||
			//we should get an argument next, if we aren't isempty
 | 
			
		||||
			var arg = ""
 | 
			
		||||
			origI := i
 | 
			
		||||
			if runes[i] == '{' {
 | 
			
		||||
				i += 1
 | 
			
		||||
				value, n := consumeUntil("}")
 | 
			
		||||
				if i+n >= len(runes) {
 | 
			
		||||
					return &treeNode{}, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, i-1, "Missing closing '}' in set operation argument?")
 | 
			
		||||
				}
 | 
			
		||||
				i += n + 1
 | 
			
		||||
				arg = value
 | 
			
		||||
			} else {
 | 
			
		||||
				value, n := consumeUntil("&|!,()/")
 | 
			
		||||
				i += n
 | 
			
		||||
				arg = strings.TrimSpace(value)
 | 
			
		||||
			}
 | 
			
		||||
			if strings.ToLower(lastValue) == "isempty" && arg != "" {
 | 
			
		||||
				return &treeNode{}, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, origI, fmt.Sprintf("isEmpty does not take arguments, was passed '%s'.", arg))
 | 
			
		||||
			}
 | 
			
		||||
			if arg == "" && strings.ToLower(lastValue) != "isempty" {
 | 
			
		||||
				if i < len(runes) && runes[i] == '/' {
 | 
			
		||||
					return &treeNode{}, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, origI, "Set operations do not support regular expressions.")
 | 
			
		||||
				} else {
 | 
			
		||||
					return &treeNode{}, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, origI, fmt.Sprintf("Set operation '%s' requires an argument.", lastValue))
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			// note that we sent an empty SetArgument token if we are isempty
 | 
			
		||||
			node.token, node.value = lfTokenSetArgument, arg
 | 
			
		||||
			return node, nil
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		switch runes[i] {
 | 
			
		||||
		case '&':
 | 
			
		||||
			if !peekIs('&') {
 | 
			
		||||
| 
						 | 
				
			
			@ -264,8 +438,38 @@ func tokenize(input string) func() (*treeNode, error) {
 | 
			
		|||
			i += n + 1
 | 
			
		||||
			node.token, node.value = lfTokenRegexp, value
 | 
			
		||||
		default:
 | 
			
		||||
			value, n := consumeUntil("&|!,()/")
 | 
			
		||||
			value, n := consumeUntil("&|!,()/:")
 | 
			
		||||
			i += n
 | 
			
		||||
			value = strings.TrimSpace(value)
 | 
			
		||||
 | 
			
		||||
			//are we the beginning of a set operation?
 | 
			
		||||
			if i < len(runes) && runes[i] == ':' {
 | 
			
		||||
				if peekIs(' ') {
 | 
			
		||||
					if value == "" {
 | 
			
		||||
						return &treeNode{}, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, i, "Missing set key.")
 | 
			
		||||
					}
 | 
			
		||||
					i += 1
 | 
			
		||||
					//we are the beginning of a set operation
 | 
			
		||||
					node.token, node.value = lfTokenSetKey, value
 | 
			
		||||
					return node, nil
 | 
			
		||||
				}
 | 
			
		||||
				additionalValue, n := consumeUntil("&|!,()/")
 | 
			
		||||
				additionalValue = strings.TrimSpace(additionalValue)
 | 
			
		||||
				if additionalValue == ":" {
 | 
			
		||||
					return &treeNode{}, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, i, "Missing set operation.")
 | 
			
		||||
				}
 | 
			
		||||
				i += n
 | 
			
		||||
				value += additionalValue
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			valueToCheckForSetOperation := strings.ToLower(value)
 | 
			
		||||
			for setOperation := range validSetOperations {
 | 
			
		||||
				idx := strings.Index(valueToCheckForSetOperation, " "+setOperation)
 | 
			
		||||
				if idx > 0 {
 | 
			
		||||
					return &treeNode{}, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, i-n+idx+1, fmt.Sprintf("Looks like you are using the set operator '%s' but did not provide a set key.  Did you forget the ':'?", validSetOperations[setOperation]))
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			node.token, node.value = lfTokenLabel, strings.TrimSpace(value)
 | 
			
		||||
		}
 | 
			
		||||
		return node, nil
 | 
			
		||||
| 
						 | 
				
			
			@ -307,7 +511,7 @@ LOOP:
 | 
			
		|||
		switch node.token {
 | 
			
		||||
		case lfTokenEOF:
 | 
			
		||||
			break LOOP
 | 
			
		||||
		case lfTokenLabel, lfTokenRegexp:
 | 
			
		||||
		case lfTokenLabel, lfTokenRegexp, lfTokenSetKey:
 | 
			
		||||
			if current.rightNode != nil {
 | 
			
		||||
				return nil, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, node.location, "Found two adjacent labels.  You need an operator between them.")
 | 
			
		||||
			}
 | 
			
		||||
| 
						 | 
				
			
			@ -326,6 +530,18 @@ LOOP:
 | 
			
		|||
			node.setLeftNode(nodeToStealFrom.rightNode)
 | 
			
		||||
			nodeToStealFrom.setRightNode(node)
 | 
			
		||||
			current = node
 | 
			
		||||
		case lfTokenSetOperation:
 | 
			
		||||
			if current.rightNode == nil {
 | 
			
		||||
				return nil, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, node.location, fmt.Sprintf("Set operation '%s' missing left hand operand.", node.value))
 | 
			
		||||
			}
 | 
			
		||||
			node.setLeftNode(current.rightNode)
 | 
			
		||||
			current.setRightNode(node)
 | 
			
		||||
			current = node
 | 
			
		||||
		case lfTokenSetArgument:
 | 
			
		||||
			if current.rightNode != nil {
 | 
			
		||||
				return nil, GinkgoErrors.SyntaxErrorParsingLabelFilter(input, node.location, fmt.Sprintf("Unexpected set argument '%s'.", node.token))
 | 
			
		||||
			}
 | 
			
		||||
			current.setRightNode(node)
 | 
			
		||||
		case lfTokenCloseGroup:
 | 
			
		||||
			firstUnmatchedOpenNode := current.firstUnmatchedOpenNode()
 | 
			
		||||
			if firstUnmatchedOpenNode == nil {
 | 
			
		||||
| 
						 | 
				
			
			@ -354,5 +570,14 @@ func ValidateAndCleanupLabel(label string, cl CodeLocation) (string, error) {
 | 
			
		|||
	if strings.ContainsAny(out, "&|!,()/") {
 | 
			
		||||
		return "", GinkgoErrors.InvalidLabel(label, cl)
 | 
			
		||||
	}
 | 
			
		||||
	if out[0] == ':' {
 | 
			
		||||
		return "", GinkgoErrors.InvalidLabel(label, cl)
 | 
			
		||||
	}
 | 
			
		||||
	if strings.Contains(out, ":") {
 | 
			
		||||
		components := strings.SplitN(out, ":", 2)
 | 
			
		||||
		if len(components) < 2 || components[1] == "" {
 | 
			
		||||
			return "", GinkgoErrors.InvalidLabel(label, cl)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return out, nil
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,3 +1,3 @@
 | 
			
		|||
package types
 | 
			
		||||
 | 
			
		||||
const VERSION = "2.18.0"
 | 
			
		||||
const VERSION = "2.19.0"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -840,7 +840,7 @@ github.com/nxadm/tail/winfile
 | 
			
		|||
# github.com/oklog/ulid v1.3.1
 | 
			
		||||
## explicit
 | 
			
		||||
github.com/oklog/ulid
 | 
			
		||||
# github.com/onsi/ginkgo/v2 v2.18.0
 | 
			
		||||
# github.com/onsi/ginkgo/v2 v2.19.0
 | 
			
		||||
## explicit; go 1.20
 | 
			
		||||
github.com/onsi/ginkgo/v2
 | 
			
		||||
github.com/onsi/ginkgo/v2/config
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue