Merge pull request #26880 from containers/renovate/github.com-onsi-ginkgo-v2-2.x

fix(deps): update module github.com/onsi/ginkgo/v2 to v2.25.0
This commit is contained in:
openshift-merge-bot[bot]
2025-08-21 13:13:55 +00:00
committed by GitHub
12 changed files with 222 additions and 15 deletions

2
go.mod
View File

@ -50,7 +50,7 @@ require (
github.com/moby/sys/user v0.4.0 github.com/moby/sys/user v0.4.0
github.com/moby/term v0.5.2 github.com/moby/term v0.5.2
github.com/nxadm/tail v1.4.11 github.com/nxadm/tail v1.4.11
github.com/onsi/ginkgo/v2 v2.24.0 github.com/onsi/ginkgo/v2 v2.25.0
github.com/onsi/gomega v1.38.0 github.com/onsi/gomega v1.38.0
github.com/opencontainers/cgroups v0.0.4 github.com/opencontainers/cgroups v0.0.4
github.com/opencontainers/go-digest v1.0.0 github.com/opencontainers/go-digest v1.0.0

4
go.sum
View File

@ -320,8 +320,8 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
github.com/nxadm/tail v1.4.11 h1:8feyoE3OzPrcshW5/MJ4sGESc5cqmGkGCWlco4l0bqY= github.com/nxadm/tail v1.4.11 h1:8feyoE3OzPrcshW5/MJ4sGESc5cqmGkGCWlco4l0bqY=
github.com/nxadm/tail v1.4.11/go.mod h1:OTaG3NK980DZzxbRq6lEuzgU+mug70nY11sMd4JXXHc= github.com/nxadm/tail v1.4.11/go.mod h1:OTaG3NK980DZzxbRq6lEuzgU+mug70nY11sMd4JXXHc=
github.com/onsi/ginkgo/v2 v2.24.0 h1:obZz8LAnHicNdbBqvG3ytAFx8fgza+i1IDpBVcHT2YE= github.com/onsi/ginkgo/v2 v2.25.0 h1:LJu94oDZUdgnw+GD0Sk/iwG9c5Fnr1vLgMb4FUUwWxE=
github.com/onsi/ginkgo/v2 v2.24.0/go.mod h1:ppTWQ1dh9KM/F1XgpeRqelR+zHVwV81DGRSDnFxK7Sk= github.com/onsi/ginkgo/v2 v2.25.0/go.mod h1:ppTWQ1dh9KM/F1XgpeRqelR+zHVwV81DGRSDnFxK7Sk=
github.com/onsi/gomega v1.38.0 h1:c/WX+w8SLAinvuKKQFh77WEucCnPk4j2OTUr7lt7BeY= github.com/onsi/gomega v1.38.0 h1:c/WX+w8SLAinvuKKQFh77WEucCnPk4j2OTUr7lt7BeY=
github.com/onsi/gomega v1.38.0/go.mod h1:OcXcwId0b9QsE7Y49u+BTrL4IdKOBOKnD6VQNTJEB6o= github.com/onsi/gomega v1.38.0/go.mod h1:OcXcwId0b9QsE7Y49u+BTrL4IdKOBOKnD6VQNTJEB6o=
github.com/opencontainers/cgroups v0.0.4 h1:XVj8P/IHVms/j+7eh8ggdkTLAxjz84ZzuFyGoE28DR4= github.com/opencontainers/cgroups v0.0.4 h1:XVj8P/IHVms/j+7eh8ggdkTLAxjz84ZzuFyGoE28DR4=

View File

@ -1,3 +1,29 @@
## 2.25.0
### `AroundNode`
This release introduces a new decorator to support more complex spec setup usecases.
`AroundNode` registers a function that runs before each individual node. This is considered a more advanced decorator.
Please read the [docs](https://onsi.github.io/ginkgo/#advanced-around-node) for more information and some examples.
Allowed signatures:
- `AroundNode(func())` - `func` will be called before the node is run.
- `AroundNode(func(ctx context.Context) context.Context)` - `func` can wrap the passed in context and return a new one which will be passed on to the node.
- `AroundNode(func(ctx context.Context, body func(ctx context.Context)))` - `ctx` is the context for the node and `body` is a function that must be called to run the node. This gives you complete control over what runs before and after the node.
Multiple `AroundNode` decorators can be applied to a single node and they will run in the order they are applied.
Unlike setup nodes like `BeforeEach` and `DeferCleanup`, `AroundNode` is guaranteed to run in the same goroutine as the decorated node. This is necessary when working with lower-level libraries that must run on a single thread (you can call `runtime.LockOSThread()` in the `AroundNode` to ensure that the node runs on a single thread).
Since `AroundNode` allows you to modify the context you can also use `AroundNode` to implement shared setup that attaches values to the context.
If applied to a container, `AroundNode` will run before every node in the container. Including setup nodes like `BeforeEach` and `DeferCleanup`.
`AroundNode` can also be applied to `RunSpecs` to run before every node in the suite. This opens up new mechanisms for instrumenting individual nodes across an entire suite.
## 2.24.0 ## 2.24.0
### Features ### Features

View File

@ -268,7 +268,7 @@ func RunSpecs(t GinkgoTestingT, description string, args ...any) bool {
} }
defer global.PopClone() defer global.PopClone()
suiteLabels, suiteSemVerConstraints := extractSuiteConfiguration(args) suiteLabels, suiteSemVerConstraints, suiteAroundNodes := extractSuiteConfiguration(args)
var reporter reporters.Reporter var reporter reporters.Reporter
if suiteConfig.ParallelTotal == 1 { if suiteConfig.ParallelTotal == 1 {
@ -311,7 +311,7 @@ func RunSpecs(t GinkgoTestingT, description string, args ...any) bool {
suitePath, err = filepath.Abs(suitePath) suitePath, err = filepath.Abs(suitePath)
exitIfErr(err) exitIfErr(err)
passed, hasFocusedTests := global.Suite.Run(description, suiteLabels, suiteSemVerConstraints, suitePath, global.Failer, reporter, writer, outputInterceptor, interrupt_handler.NewInterruptHandler(client), client, internal.RegisterForProgressSignal, suiteConfig) passed, hasFocusedTests := global.Suite.Run(description, suiteLabels, suiteSemVerConstraints, suiteAroundNodes, suitePath, global.Failer, reporter, writer, outputInterceptor, interrupt_handler.NewInterruptHandler(client), client, internal.RegisterForProgressSignal, suiteConfig)
outputInterceptor.Shutdown() outputInterceptor.Shutdown()
flagSet.ValidateDeprecations(deprecationTracker) flagSet.ValidateDeprecations(deprecationTracker)
@ -330,9 +330,10 @@ func RunSpecs(t GinkgoTestingT, description string, args ...any) bool {
return passed return passed
} }
func extractSuiteConfiguration(args []any) (Labels, SemVerConstraints) { func extractSuiteConfiguration(args []any) (Labels, SemVerConstraints, types.AroundNodes) {
suiteLabels := Labels{} suiteLabels := Labels{}
suiteSemVerConstraints := SemVerConstraints{} suiteSemVerConstraints := SemVerConstraints{}
aroundNodes := types.AroundNodes{}
configErrors := []error{} configErrors := []error{}
for _, arg := range args { for _, arg := range args {
switch arg := arg.(type) { switch arg := arg.(type) {
@ -344,6 +345,8 @@ func extractSuiteConfiguration(args []any) (Labels, SemVerConstraints) {
suiteLabels = append(suiteLabels, arg...) suiteLabels = append(suiteLabels, arg...)
case SemVerConstraints: case SemVerConstraints:
suiteSemVerConstraints = append(suiteSemVerConstraints, arg...) suiteSemVerConstraints = append(suiteSemVerConstraints, arg...)
case types.AroundNodeDecorator:
aroundNodes = append(aroundNodes, arg)
default: default:
configErrors = append(configErrors, types.GinkgoErrors.UnknownTypePassedToRunSpecs(arg)) configErrors = append(configErrors, types.GinkgoErrors.UnknownTypePassedToRunSpecs(arg))
} }
@ -359,7 +362,7 @@ func extractSuiteConfiguration(args []any) (Labels, SemVerConstraints) {
os.Exit(1) os.Exit(1)
} }
return suiteLabels, suiteSemVerConstraints return suiteLabels, suiteSemVerConstraints, aroundNodes
} }
func getwd() (string, error) { func getwd() (string, error) {
@ -382,7 +385,7 @@ func PreviewSpecs(description string, args ...any) Report {
} }
defer global.PopClone() defer global.PopClone()
suiteLabels, suiteSemVerConstraints := extractSuiteConfiguration(args) suiteLabels, suiteSemVerConstraints, suiteAroundNodes := extractSuiteConfiguration(args)
priorDryRun, priorParallelTotal, priorParallelProcess := suiteConfig.DryRun, suiteConfig.ParallelTotal, suiteConfig.ParallelProcess priorDryRun, priorParallelTotal, priorParallelProcess := suiteConfig.DryRun, suiteConfig.ParallelTotal, suiteConfig.ParallelProcess
suiteConfig.DryRun, suiteConfig.ParallelTotal, suiteConfig.ParallelProcess = true, 1, 1 suiteConfig.DryRun, suiteConfig.ParallelTotal, suiteConfig.ParallelProcess = true, 1, 1
defer func() { defer func() {
@ -400,7 +403,7 @@ func PreviewSpecs(description string, args ...any) Report {
suitePath, err = filepath.Abs(suitePath) suitePath, err = filepath.Abs(suitePath)
exitIfErr(err) exitIfErr(err)
global.Suite.Run(description, suiteLabels, suiteSemVerConstraints, suitePath, global.Failer, reporter, writer, outputInterceptor, interrupt_handler.NewInterruptHandler(client), client, internal.RegisterForProgressSignal, suiteConfig) global.Suite.Run(description, suiteLabels, suiteSemVerConstraints, suiteAroundNodes, suitePath, global.Failer, reporter, writer, outputInterceptor, interrupt_handler.NewInterruptHandler(client), client, internal.RegisterForProgressSignal, suiteConfig)
return global.Suite.GetPreviewReport() return global.Suite.GetPreviewReport()
} }

View File

@ -2,6 +2,7 @@ package ginkgo
import ( import (
"github.com/onsi/ginkgo/v2/internal" "github.com/onsi/ginkgo/v2/internal"
"github.com/onsi/ginkgo/v2/types"
) )
/* /*
@ -158,3 +159,28 @@ SuppressProgressReporting is a decorator that allows you to disable progress rep
if you have a `ReportAfterEach` node that is running for every skipped spec and is generating lots of progress reports. if you have a `ReportAfterEach` node that is running for every skipped spec and is generating lots of progress reports.
*/ */
const SuppressProgressReporting = internal.SuppressProgressReporting const SuppressProgressReporting = internal.SuppressProgressReporting
/*
AroundNode registers a function that runs before each individual node. This is considered a more advanced decorator.
Please read the [docs](https://onsi.github.io/ginkgo/#advanced-around-node) for more information.
Allowed signatures:
- AroundNode(func()) - func will be called before the node is run.
- AroundNode(func(ctx context.Context) context.Context) - func can wrap the passed in context and return a new one which will be passed on to the node.
- AroundNode(func(ctx context.Context, body func(ctx context.Context))) - ctx is the context for the node and body is a function that must be called to run the node. This gives you complete control over what runs before and after the node.
Multiple AroundNode decorators can be applied to a single node and they will run in the order they are applied.
Unlike setup nodes like BeforeEach and DeferCleanup, AroundNode is guaranteed to run in the same goroutine as the decorated node. This is necessary when working with lower-level libraries that must run on a single thread (you can call runtime.LockOSThread() in the AroundNode to ensure that the node runs on a single thread).
Since AroundNode allows you to modify the context you can also use AroundNode to implement shared setup that attaches values to the context. You must return a context that inherits from the passed in context.
If applied to a container, AroundNode will run before every node in the container. Including setup nodes like BeforeEach and DeferCleanup.
AroundNode can also be applied to RunSpecs to run before every node in the suite.
*/
func AroundNode[F types.AroundNodeAllowedFuncs](f F) types.AroundNodeDecorator {
return types.AroundNode(f, types.NewCodeLocation(1))
}

View File

@ -0,0 +1,34 @@
package internal
import (
"github.com/onsi/ginkgo/v2/types"
)
func ComputeAroundNodes(specs Specs) Specs {
out := Specs{}
for _, spec := range specs {
nodes := Nodes{}
currentNestingLevel := 0
aroundNodes := types.AroundNodes{}
nestingLevelIndices := []int{}
for _, node := range spec.Nodes {
switch node.NodeType {
case types.NodeTypeContainer:
currentNestingLevel = node.NestingLevel + 1
nestingLevelIndices = append(nestingLevelIndices, len(aroundNodes))
aroundNodes = aroundNodes.Append(node.AroundNodes...)
nodes = append(nodes, node)
default:
if currentNestingLevel > node.NestingLevel {
currentNestingLevel = node.NestingLevel
aroundNodes = aroundNodes[:nestingLevelIndices[currentNestingLevel]]
}
node.AroundNodes = types.AroundNodes{}.Append(aroundNodes...).Append(node.AroundNodes...)
nodes = append(nodes, node)
}
}
spec.Nodes = nodes
out = append(out, spec)
}
return out
}

View File

@ -61,6 +61,7 @@ type Node struct {
NodeTimeout time.Duration NodeTimeout time.Duration
SpecTimeout time.Duration SpecTimeout time.Duration
GracePeriod time.Duration GracePeriod time.Duration
AroundNodes types.AroundNodes
NodeIDWhereCleanupWasGenerated uint NodeIDWhereCleanupWasGenerated uint
} }
@ -86,18 +87,20 @@ type FlakeAttempts uint
type MustPassRepeatedly uint type MustPassRepeatedly uint
type Offset uint type Offset uint
type Done chan<- any // Deprecated Done Channel for asynchronous testing type Done chan<- any // Deprecated Done Channel for asynchronous testing
type Labels []string
type SemVerConstraints []string
type PollProgressInterval time.Duration type PollProgressInterval time.Duration
type PollProgressAfter time.Duration type PollProgressAfter time.Duration
type NodeTimeout time.Duration type NodeTimeout time.Duration
type SpecTimeout time.Duration type SpecTimeout time.Duration
type GracePeriod time.Duration type GracePeriod time.Duration
type Labels []string
func (l Labels) MatchesLabelFilter(query string) bool { func (l Labels) MatchesLabelFilter(query string) bool {
return types.MustParseLabelFilter(query)(l) return types.MustParseLabelFilter(query)(l)
} }
type SemVerConstraints []string
func (svc SemVerConstraints) MatchesSemVerFilter(version string) bool { func (svc SemVerConstraints) MatchesSemVerFilter(version string) bool {
return types.MustParseSemVerFilter(version)(svc) return types.MustParseSemVerFilter(version)(svc)
} }
@ -177,6 +180,8 @@ func isDecoration(arg any) bool {
return true return true
case t == reflect.TypeOf(GracePeriod(0)): case t == reflect.TypeOf(GracePeriod(0)):
return true return true
case t == reflect.TypeOf(types.AroundNodeDecorator{}):
return true
case t.Kind() == reflect.Slice && isSliceOfDecorations(arg): case t.Kind() == reflect.Slice && isSliceOfDecorations(arg):
return true return true
default: default:
@ -317,6 +322,8 @@ func NewNode(deprecationTracker *types.DeprecationTracker, nodeType types.NodeTy
if nodeType.Is(types.NodeTypeContainer) { if nodeType.Is(types.NodeTypeContainer) {
appendError(types.GinkgoErrors.InvalidDecoratorForNodeType(node.CodeLocation, nodeType, "GracePeriod")) appendError(types.GinkgoErrors.InvalidDecoratorForNodeType(node.CodeLocation, nodeType, "GracePeriod"))
} }
case t == reflect.TypeOf(types.AroundNodeDecorator{}):
node.AroundNodes = append(node.AroundNodes, arg.(types.AroundNodeDecorator))
case t == reflect.TypeOf(Labels{}): case t == reflect.TypeOf(Labels{}):
if !nodeType.Is(types.NodeTypesForContainerAndIt) { if !nodeType.Is(types.NodeTypesForContainerAndIt) {
appendError(types.GinkgoErrors.InvalidDecoratorForNodeType(node.CodeLocation, nodeType, "Label")) appendError(types.GinkgoErrors.InvalidDecoratorForNodeType(node.CodeLocation, nodeType, "Label"))

View File

@ -2,6 +2,7 @@ package internal
import ( import (
"context" "context"
"reflect"
"github.com/onsi/ginkgo/v2/types" "github.com/onsi/ginkgo/v2/types"
) )
@ -11,6 +12,7 @@ type SpecContext interface {
SpecReport() types.SpecReport SpecReport() types.SpecReport
AttachProgressReporter(func() string) func() AttachProgressReporter(func() string) func()
WrappedContext() context.Context
} }
type specContext struct { type specContext struct {
@ -45,3 +47,28 @@ func NewSpecContext(suite *Suite) *specContext {
func (sc *specContext) SpecReport() types.SpecReport { func (sc *specContext) SpecReport() types.SpecReport {
return sc.suite.CurrentSpecReport() return sc.suite.CurrentSpecReport()
} }
func (sc *specContext) WrappedContext() context.Context {
return sc.Context
}
/*
The user is allowed to wrap `SpecContext` in a new context.Context when using AroundNodes. But body functions expect SpecContext.
We support this by taking their context.Context and returning a SpecContext that wraps it.
*/
func wrapContextChain(ctx context.Context) SpecContext {
if ctx == nil {
return nil
}
if reflect.TypeOf(ctx) == reflect.TypeOf(&specContext{}) {
return ctx.(*specContext)
} else if sc, ok := ctx.Value("GINKGO_SPEC_CONTEXT").(*specContext); ok {
return &specContext{
Context: ctx,
ProgressReporterManager: sc.ProgressReporterManager,
cancel: sc.cancel,
suite: sc.suite,
}
}
return nil
}

View File

@ -32,6 +32,7 @@ type Suite struct {
suiteNodes Nodes suiteNodes Nodes
cleanupNodes Nodes cleanupNodes Nodes
aroundNodes types.AroundNodes
failer *Failer failer *Failer
reporter reporters.Reporter reporter reporters.Reporter
@ -87,6 +88,7 @@ func (suite *Suite) Clone() (*Suite, error) {
ProgressReporterManager: NewProgressReporterManager(), ProgressReporterManager: NewProgressReporterManager(),
topLevelContainers: suite.topLevelContainers.Clone(), topLevelContainers: suite.topLevelContainers.Clone(),
suiteNodes: suite.suiteNodes.Clone(), suiteNodes: suite.suiteNodes.Clone(),
aroundNodes: suite.aroundNodes.Clone(),
selectiveLock: &sync.Mutex{}, selectiveLock: &sync.Mutex{},
}, nil }, nil
} }
@ -104,13 +106,14 @@ func (suite *Suite) BuildTree() error {
return nil return nil
} }
func (suite *Suite) Run(description string, suiteLabels Labels, suiteSemVerConstraints SemVerConstraints, suitePath string, failer *Failer, reporter reporters.Reporter, writer WriterInterface, outputInterceptor OutputInterceptor, interruptHandler interrupt_handler.InterruptHandlerInterface, client parallel_support.Client, progressSignalRegistrar ProgressSignalRegistrar, suiteConfig types.SuiteConfig) (bool, bool) { func (suite *Suite) Run(description string, suiteLabels Labels, suiteSemVerConstraints SemVerConstraints, suiteAroundNodes types.AroundNodes, suitePath string, failer *Failer, reporter reporters.Reporter, writer WriterInterface, outputInterceptor OutputInterceptor, interruptHandler interrupt_handler.InterruptHandlerInterface, client parallel_support.Client, progressSignalRegistrar ProgressSignalRegistrar, suiteConfig types.SuiteConfig) (bool, bool) {
if suite.phase != PhaseBuildTree { if suite.phase != PhaseBuildTree {
panic("cannot run before building the tree = call suite.BuildTree() first") panic("cannot run before building the tree = call suite.BuildTree() first")
} }
ApplyNestedFocusPolicyToTree(suite.tree) ApplyNestedFocusPolicyToTree(suite.tree)
specs := GenerateSpecsFromTreeRoot(suite.tree) specs := GenerateSpecsFromTreeRoot(suite.tree)
specs, hasProgrammaticFocus := ApplyFocusToSpecs(specs, description, suiteLabels, suiteSemVerConstraints, suiteConfig) specs, hasProgrammaticFocus := ApplyFocusToSpecs(specs, description, suiteLabels, suiteSemVerConstraints, suiteConfig)
specs = ComputeAroundNodes(specs)
suite.phase = PhaseRun suite.phase = PhaseRun
suite.client = client suite.client = client
@ -120,6 +123,7 @@ func (suite *Suite) Run(description string, suiteLabels Labels, suiteSemVerConst
suite.outputInterceptor = outputInterceptor suite.outputInterceptor = outputInterceptor
suite.interruptHandler = interruptHandler suite.interruptHandler = interruptHandler
suite.config = suiteConfig suite.config = suiteConfig
suite.aroundNodes = suiteAroundNodes
if suite.config.Timeout > 0 { if suite.config.Timeout > 0 {
suite.deadline = time.Now().Add(suite.config.Timeout) suite.deadline = time.Now().Add(suite.config.Timeout)
@ -259,6 +263,7 @@ func (suite *Suite) pushCleanupNode(node Node) error {
node.NodeIDWhereCleanupWasGenerated = suite.currentNode.ID node.NodeIDWhereCleanupWasGenerated = suite.currentNode.ID
node.NestingLevel = suite.currentNode.NestingLevel node.NestingLevel = suite.currentNode.NestingLevel
node.AroundNodes = types.AroundNodes{}.Append(suite.currentNode.AroundNodes...).Append(node.AroundNodes...)
suite.selectiveLock.Lock() suite.selectiveLock.Lock()
suite.cleanupNodes = append(suite.cleanupNodes, node) suite.cleanupNodes = append(suite.cleanupNodes, node)
suite.selectiveLock.Unlock() suite.selectiveLock.Unlock()
@ -892,7 +897,30 @@ func (suite *Suite) runNode(node Node, specDeadline time.Time, text string) (typ
failureC <- failureFromRun failureC <- failureFromRun
}() }()
node.Body(sc) aroundNodes := types.AroundNodes{}.Append(suite.aroundNodes...).Append(node.AroundNodes...)
if len(aroundNodes) > 0 {
i := 0
var f func(context.Context)
f = func(c context.Context) {
sc := wrapContextChain(c)
if sc == nil {
suite.failer.Fail("An AroundNode failed to pass a valid Ginkgo SpecContext in. You must always pass in a context derived from the context passed to you.", aroundNodes[i].CodeLocation)
return
}
i++
if i < len(aroundNodes) {
aroundNodes[i].Body(sc, f)
} else {
node.Body(sc)
}
}
aroundNodes[0].Body(sc, f)
if i != len(aroundNodes) {
suite.failer.Fail("An AroundNode failed to call the passed in function.", aroundNodes[i].CodeLocation)
}
} else {
node.Body(sc)
}
finished = true finished = true
}() }()

56
vendor/github.com/onsi/ginkgo/v2/types/around_node.go generated vendored Normal file
View File

@ -0,0 +1,56 @@
package types
import (
"context"
)
type AroundNodeAllowedFuncs interface {
~func(context.Context, func(context.Context)) | ~func(context.Context) context.Context | ~func()
}
type AroundNodeFunc func(ctx context.Context, body func(ctx context.Context))
func AroundNode[F AroundNodeAllowedFuncs](f F, cl CodeLocation) AroundNodeDecorator {
if f == nil {
panic("BuildAroundNode cannot be called with a nil function.")
}
var aroundNodeFunc func(context.Context, func(context.Context))
switch x := any(f).(type) {
case func(context.Context, func(context.Context)):
aroundNodeFunc = x
case func(context.Context) context.Context:
aroundNodeFunc = func(ctx context.Context, body func(context.Context)) {
ctx = x(ctx)
body(ctx)
}
case func():
aroundNodeFunc = func(ctx context.Context, body func(context.Context)) {
x()
body(ctx)
}
}
return AroundNodeDecorator{
Body: aroundNodeFunc,
CodeLocation: cl,
}
}
type AroundNodeDecorator struct {
Body AroundNodeFunc
CodeLocation CodeLocation
}
type AroundNodes []AroundNodeDecorator
func (an AroundNodes) Clone() AroundNodes {
out := make(AroundNodes, len(an))
copy(out, an)
return out
}
func (an AroundNodes) Append(other ...AroundNodeDecorator) AroundNodes {
out := make(AroundNodes, len(an)+len(other))
copy(out, an)
copy(out[len(an):], other)
return out
}

View File

@ -1,3 +1,3 @@
package types package types
const VERSION = "2.24.0" const VERSION = "2.25.0"

2
vendor/modules.txt vendored
View File

@ -706,7 +706,7 @@ github.com/nxadm/tail/ratelimiter
github.com/nxadm/tail/util github.com/nxadm/tail/util
github.com/nxadm/tail/watch github.com/nxadm/tail/watch
github.com/nxadm/tail/winfile github.com/nxadm/tail/winfile
# github.com/onsi/ginkgo/v2 v2.24.0 # github.com/onsi/ginkgo/v2 v2.25.0
## explicit; go 1.23.0 ## explicit; go 1.23.0
github.com/onsi/ginkgo/v2 github.com/onsi/ginkgo/v2
github.com/onsi/ginkgo/v2/config github.com/onsi/ginkgo/v2/config