diff --git a/Taskfile.yml b/Taskfile.yml
index b78e8955..f9686331 100644
--- a/Taskfile.yml
+++ b/Taskfile.yml
@@ -52,7 +52,7 @@ tasks:
 
   test:
     cmds:
-      - go test -v -coverprofile=coverage.txt ./...
+      - go run gotest.tools/gotestsum --format testname -- -v -coverprofile=coverage.txt ./...
     desc: run unit tests
     sources:
       - "**/*.go"
diff --git a/cmd/showconfig.go b/cmd/showconfig.go
index 99c47b0c..d87844b2 100644
--- a/cmd/showconfig.go
+++ b/cmd/showconfig.go
@@ -37,6 +37,11 @@ func showConfig(
 	if err != nil {
 		return stackerr.NewStackErrf(err, "failed to unmarshal config")
 	}
+	log, err := logging.GetLogger(config.LogLevel)
+	if err != nil {
+		return fmt.Errorf("getting logger: %w", err)
+	}
+	ctx = log.WithContext(ctx)
 	if err := config.Initialize(ctx); err != nil {
 		return err
 	}
@@ -48,10 +53,7 @@ func showConfig(
 	if err != nil {
 		return stackerr.NewStackErrf(err, "failed to marshal yaml")
 	}
-	log, err := logging.GetLogger(config.LogLevel)
-	if err != nil {
-		panic(err)
-	}
+
 	log.Info().Msgf("Using config: %s", config.Config)
 
 	fmt.Fprintf(outputter, "%s", string(out))
diff --git a/pkg/config/config.go b/pkg/config/config.go
index 3747da20..c709f4ba 100644
--- a/pkg/config/config.go
+++ b/pkg/config/config.go
@@ -195,7 +195,14 @@ func (c *Config) GetPackages(ctx context.Context) ([]string, error) {
 	return packageList, nil
 }
 
+// getPackageConfigMap returns the map for the particular package, which includes
+// (but is not limited to) both the `configs` section and the `interfaces` section.
+// Note this does NOT return the `configs` section for the package. It returns the
+// entire mapping for the package.
 func (c *Config) getPackageConfigMap(ctx context.Context, packageName string) (map[string]any, error) {
+	log := zerolog.Ctx(ctx)
+	log.Trace().Msg("getting package config map")
+
 	cfgMap, err := c.CfgAsMap(ctx)
 	if err != nil {
 		return nil, err
@@ -207,13 +214,27 @@ func (c *Config) getPackageConfigMap(ctx context.Context, packageName string) (m
 	}
 	configAsMap, isMap := configUnmerged.(map[string]any)
 	if isMap {
+		log.Trace().Msg("package's value is a map, returning")
 		return configAsMap, nil
 	}
-	return map[string]any{}, nil
+	log.Trace().Msg("package's value is not a map")
+
+	// Package is something other than map, so set its value to an
+	// empty map.
+	emptyMap := map[string]any{}
+	packageSection[packageName] = emptyMap
+	return emptyMap, nil
 
 }
+
+// GetPackageConfig returns a struct representation of the package's config
+// as provided in yaml. If the package did not specify a config section,
+// this method will inject the top-level config into the package's config.
+// This is especially useful as it allows us to lazily evaluate a package's
+// config. If the package does specify config, this method takes care to merge
+// the top-level config with the values specified for this package.
 func (c *Config) GetPackageConfig(ctx context.Context, packageName string) (*Config, error) {
-	log := zerolog.Ctx(ctx)
+	log := zerolog.Ctx(ctx).With().Str("package-path", packageName).Logger()
 
 	if c.pkgConfigCache == nil {
 		log.Debug().Msg("package cache is nil")
@@ -223,11 +244,10 @@ func (c *Config) GetPackageConfig(ctx context.Context, packageName string) (*Con
 		return pkgConf, nil
 	}
 
-	pkgConfig := reflect.New(reflect.ValueOf(c).Elem().Type()).Interface()
+	pkgConfig := &Config{}
 	if err := copier.Copy(pkgConfig, c); err != nil {
 		return nil, fmt.Errorf("failed to copy config: %w", err)
 	}
-	pkgConfigTyped := pkgConfig.(*Config)
 
 	configMap, err := c.getPackageConfigMap(ctx, packageName)
 	if err != nil {
@@ -237,18 +257,24 @@ func (c *Config) GetPackageConfig(ctx context.Context, packageName string) (*Con
 	configSection, ok := configMap["config"]
 	if !ok {
 		log.Debug().Msg("config section not provided for package")
-		return pkgConfigTyped, nil
+		configMap["config"] = map[string]any{}
+		c.pkgConfigCache[packageName] = pkgConfig
+		return pkgConfig, nil
 	}
 
-	decoder, err := c.getDecoder(pkgConfigTyped)
+	// We know that the package specified config that is overriding the top-level
+	// config. We use a mapstructure decoder to decode the values in the yaml
+	// into the pkgConfig struct. This has the effect of merging top-level
+	// config with package-level config.
+	decoder, err := c.getDecoder(pkgConfig)
 	if err != nil {
 		return nil, stackerr.NewStackErrf(err, "failed to get decoder")
 	}
 	if err := decoder.Decode(configSection); err != nil {
 		return nil, err
 	}
-	c.pkgConfigCache[packageName] = pkgConfigTyped
-	return pkgConfigTyped, nil
+	c.pkgConfigCache[packageName] = pkgConfig
+	return pkgConfig, nil
 }
 
 func (c *Config) ExcludePath(path string) bool {
@@ -347,16 +373,15 @@ func (c *Config) GetInterfaceConfig(ctx context.Context, packageName string, int
 	}
 
 	// Copy the package-level config to our interface-level config
-	pkgConfigCopy := reflect.New(reflect.ValueOf(pkgConfig).Elem().Type()).Interface()
+	pkgConfigCopy := &Config{}
 	if err := copier.Copy(pkgConfigCopy, pkgConfig); err != nil {
 		return nil, stackerr.NewStackErrf(err, "failed to create a copy of package config")
 	}
-	baseConfigTyped := pkgConfigCopy.(*Config)
 
 	interfaceSection, ok := interfacesSection[interfaceName]
 	if !ok {
 		log.Debug().Msg("interface not defined in package configuration")
-		return []*Config{baseConfigTyped}, nil
+		return []*Config{pkgConfigCopy}, nil
 	}
 
 	interfaceSectionTyped, ok := interfaceSection.(map[string]any)
@@ -365,7 +390,7 @@ func (c *Config) GetInterfaceConfig(ctx context.Context, packageName string, int
 		// the interface but not provide any additional config beyond what
 		// is provided at the package level
 		if reflect.ValueOf(&interfaceSection).Elem().IsZero() {
-			return []*Config{baseConfigTyped}, nil
+			return []*Config{pkgConfigCopy}, nil
 		}
 		msgString := "bad type provided for interface config"
 		log.Error().Msgf(msgString)
@@ -376,11 +401,11 @@ func (c *Config) GetInterfaceConfig(ctx context.Context, packageName string, int
 	if ok {
 		log.Debug().Msg("config section exists for interface")
 		// if `config` is provided, we'll overwrite the values in our
-		// baseConfigTyped struct to act as the "new" base config.
+		// pkgConfigCopy struct to act as the "new" base config.
 		// This will allow us to set the default values for the interface
 		// but override them further for each mock defined in the
 		// `configs` section.
-		decoder, err := c.getDecoder(baseConfigTyped)
+		decoder, err := c.getDecoder(pkgConfigCopy)
 		if err != nil {
 			return nil, stackerr.NewStackErrf(err, "unable to create mapstructure decoder")
 		}
@@ -397,8 +422,8 @@ func (c *Config) GetInterfaceConfig(ctx context.Context, packageName string, int
 		configsSectionTyped := configsSection.([]any)
 		for _, configMap := range configsSectionTyped {
 			// Create a copy of the package-level config
-			currentInterfaceConfig := reflect.New(reflect.ValueOf(baseConfigTyped).Elem().Type()).Interface()
-			if err := copier.Copy(currentInterfaceConfig, baseConfigTyped); err != nil {
+			currentInterfaceConfig := reflect.New(reflect.ValueOf(pkgConfigCopy).Elem().Type()).Interface()
+			if err := copier.Copy(currentInterfaceConfig, pkgConfigCopy); err != nil {
 				return nil, stackerr.NewStackErrf(err, "failed to copy package config")
 			}
 
@@ -418,7 +443,7 @@ func (c *Config) GetInterfaceConfig(ctx context.Context, packageName string, int
 	log.Debug().Msg("configs section doesn't exist for interface")
 
 	if len(configs) == 0 {
-		configs = append(configs, baseConfigTyped)
+		configs = append(configs, pkgConfigCopy)
 	}
 	return configs, nil
 }
@@ -429,8 +454,9 @@ func (c *Config) addSubPkgConfig(ctx context.Context, subPkgPath string, parentP
 	log := zerolog.Ctx(ctx).With().
 		Str("parent-package", parentPkgPath).
 		Str("sub-package", subPkgPath).Logger()
+	ctx = log.WithContext(ctx)
 
-	log.Trace().Msg("adding sub-package to config map")
+	log.Debug().Msg("adding sub-package to config map")
 	parentPkgConfig, err := c.getPackageConfigMap(ctx, parentPkgPath)
 	if err != nil {
 		log.Err(err).
@@ -438,22 +464,23 @@ func (c *Config) addSubPkgConfig(ctx context.Context, subPkgPath string, parentP
 		return fmt.Errorf("failed to get package config: %w", err)
 	}
 
-	log.Trace().Msg("getting config")
-	cfg, err := c.CfgAsMap(ctx)
+	log.Debug().Msg("getting config")
+	topLevelConfig, err := c.CfgAsMap(ctx)
 	if err != nil {
 		return fmt.Errorf("failed to get configuration map: %w", err)
 	}
 
-	log.Trace().Msg("getting packages section")
-	packagesSection := cfg["packages"].(map[string]any)
+	log.Debug().Msg("getting packages section")
+	packagesSection := topLevelConfig["packages"].(map[string]any)
 
-	// Don't overwrite any config that already exists
 	_, pkgExists := packagesSection[subPkgPath]
 	if !pkgExists {
 		log.Trace().Msg("sub-package doesn't exist in config")
+
+		// Copy the parent package directly into the subpackage config section
 		packagesSection[subPkgPath] = map[string]any{}
 		newPkgSection := packagesSection[subPkgPath].(map[string]any)
-		newPkgSection["config"] = parentPkgConfig["config"]
+		newPkgSection["config"] = deepCopyConfigMap(parentPkgConfig["config"].(map[string]any))
 	} else {
 		log.Trace().Msg("sub-package exists in config")
 		// The sub-package exists in config. Check if it has its
@@ -465,10 +492,15 @@ func (c *Config) addSubPkgConfig(ctx context.Context, subPkgPath string, parentP
 			log.Err(err).Msg("could not get child package config")
 			return fmt.Errorf("failed to get sub-package config: %w", err)
 		}
-
-		for key, val := range parentPkgConfig {
-			if _, keyInSubPkg := subPkgConfig[key]; !keyInSubPkg {
-				subPkgConfig[key] = val
+		log.Trace().Msgf("sub-package config: %v", subPkgConfig)
+		log.Trace().Msgf("parent-package config: %v", parentPkgConfig)
+
+		// Merge the parent config with the sub-package config.
+		parentConfigSection := parentPkgConfig["config"].(map[string]any)
+		subPkgConfigSection := subPkgConfig["config"].(map[string]any)
+		for key, val := range parentConfigSection {
+			if _, keyInSubPkg := subPkgConfigSection[key]; !keyInSubPkg {
+				subPkgConfigSection[key] = val
 			}
 
 		}
@@ -595,6 +627,7 @@ func (c *Config) subPackages(
 // recursive and recurses the file tree to find all sub-packages.
 func (c *Config) discoverRecursivePackages(ctx context.Context) error {
 	log := zerolog.Ctx(ctx)
+	log.Trace().Msg("discovering recursive packages")
 	recursivePackages := map[string]*Config{}
 	packageList, err := c.GetPackages(ctx)
 	if err != nil {
@@ -602,11 +635,16 @@ func (c *Config) discoverRecursivePackages(ctx context.Context) error {
 	}
 	for _, pkg := range packageList {
 		pkgConfig, err := c.GetPackageConfig(ctx, pkg)
+		pkgLog := log.With().Str("package", pkg).Logger()
+		pkgLog.Trace().Msg("iterating over package")
 		if err != nil {
 			return fmt.Errorf("failed to get package config: %w", err)
 		}
 		if pkgConfig.Recursive {
+			pkgLog.Trace().Msg("package marked as recursive")
 			recursivePackages[pkg] = pkgConfig
+		} else {
+			pkgLog.Trace().Msg("package not marked as recursive")
 		}
 	}
 	if len(recursivePackages) == 0 {
@@ -658,6 +696,17 @@ func contains[T comparable](slice []T, elem T) bool {
 	return false
 }
 
+func deepCopyConfigMap(src map[string]any) map[string]any {
+	newMap := map[string]any{}
+	for key, val := range src {
+		if contains([]string{"packages", "config", "interfaces"}, key) {
+			continue
+		}
+		newMap[key] = val
+	}
+	return newMap
+}
+
 // mergeInConfig takes care of merging inheritable configuration
 // in the config map. For example, it merges default config, then
 // package-level config, then interface-level config.
@@ -677,34 +726,62 @@ func (c *Config) mergeInConfig(ctx context.Context) error {
 	}
 	for _, pkgPath := range pkgs {
 		pkgLog := log.With().Str("package-path", pkgPath).Logger()
+		pkgCtx := pkgLog.WithContext(ctx)
+
 		pkgLog.Trace().Msg("merging for package")
-		packageConfig, err := c.getPackageConfigMap(ctx, pkgPath)
+		packageConfig, err := c.getPackageConfigMap(pkgCtx, pkgPath)
 		if err != nil {
 			pkgLog.Err(err).Msg("failed to get package config")
 			return fmt.Errorf("failed to get package config: %w", err)
 		}
+		pkgLog.Trace().Msgf("got package config map: %v", packageConfig)
+
 		configSectionUntyped, configExists := packageConfig["config"]
 		if !configExists {
-			packageConfig["config"] = defaultCfg
-			continue
+			// The reason why this should never happen is because getPackageConfigMap
+			// should be populating the config section with the top-level config if it
+			// wasn't defined in the yaml.
+			msg := "config section does not exist for package, this should never happen"
+			pkgLog.Error().Msg(msg)
+			return fmt.Errorf(msg)
+		}
+
+		pkgLog.Trace().Msg("got config section for package")
+		// Sometimes the config section may be provided, but it's nil.
+		// We need to account for this fact.
+		if configSectionUntyped == nil {
+			pkgLog.Trace().Msg("config section is nil, converting to empty map")
+			emptyMap := map[string]any{}
+
+			// We need to add this to the "global" config mapping so the change
+			// gets persisted, and also into configSectionUntyped for the logic
+			// further down.
+			packageConfig["config"] = emptyMap
+			configSectionUntyped = emptyMap
+		} else {
+			pkgLog.Trace().Msg("config section is not nil")
 		}
-		packageConfigSection := configSectionUntyped.(map[string]any)
+
+		configSectionTyped := configSectionUntyped.(map[string]any)
 
 		for key, value := range defaultCfg {
 			if contains([]string{"packages", "config"}, key) {
 				continue
 			}
-			_, keyExists := packageConfigSection[key]
+			keyValLog := pkgLog.With().Str("key", key).Str("value", fmt.Sprintf("%v", value)).Logger()
+
+			_, keyExists := configSectionTyped[key]
 			if !keyExists {
-				packageConfigSection[key] = value
+				keyValLog.Trace().Msg("setting key to value")
+				configSectionTyped[key] = value
 			}
 		}
-		interfaces, err := c.getInterfacesForPackage(ctx, pkgPath)
+		interfaces, err := c.getInterfacesForPackage(pkgCtx, pkgPath)
 		if err != nil {
 			return fmt.Errorf("failed to get interfaces for package: %w", err)
 		}
 		for _, interfaceName := range interfaces {
-			interfacesSection, err := c.getInterfacesSection(ctx, pkgPath)
+			interfacesSection, err := c.getInterfacesSection(pkgCtx, pkgPath)
 			if err != nil {
 				return err
 			}
@@ -728,7 +805,7 @@ func (c *Config) mergeInConfig(ctx context.Context) error {
 				// Assume this interface's value in the map is nil. Just skip it.
 				continue
 			}
-			for key, value := range packageConfigSection {
+			for key, value := range configSectionTyped {
 				if key == "packages" {
 					continue
 				}
diff --git a/pkg/config/config_test.go b/pkg/config/config_test.go
index 51550bf3..ce5cad6b 100644
--- a/pkg/config/config_test.go
+++ b/pkg/config/config_test.go
@@ -1172,26 +1172,93 @@ packages:
             recursive: true
             with-expecter: true
 with-expecter: false
+`,
+		},
+		{
+			name: "empty map for recursive package",
+			cfgYaml: `
+with-expecter: False
+dir: foobar
+recursive: True
+all: True
+packages:
+    github.com/vektra/mockery/v2/pkg/fixtures/example_project/pkg_with_subpkgs/subpkg2:
+`,
+			wantCfgMap: `all: true
+dir: foobar
+packages:
+    github.com/vektra/mockery/v2/pkg/fixtures/example_project/pkg_with_subpkgs/subpkg2:
+        config:
+            all: true
+            dir: foobar
+            recursive: true
+            with-expecter: false
+    github.com/vektra/mockery/v2/pkg/fixtures/example_project/pkg_with_subpkgs/subpkg2/subpkg3:
+        config:
+            all: true
+            dir: foobar
+            recursive: true
+            with-expecter: false
+recursive: true
+with-expecter: false
+`,
+		},
+		{
+			name: "empty map for subpackage of recursive package",
+			cfgYaml: `
+with-expecter: False
+dir: foobar
+packages:
+    github.com/vektra/mockery/v2/pkg/fixtures/example_project/pkg_with_subpkgs/subpkg2:
+        config:
+            recursive: True
+            with-expecter: True
+            all: True
+    github.com/vektra/mockery/v2/pkg/fixtures/example_project/pkg_with_subpkgs/subpkg2/subpkg3: {}
+`,
+			wantCfgMap: `dir: foobar
+packages:
+    github.com/vektra/mockery/v2/pkg/fixtures/example_project/pkg_with_subpkgs/subpkg2:
+        config:
+            all: true
+            dir: foobar
+            recursive: true
+            with-expecter: true
+    github.com/vektra/mockery/v2/pkg/fixtures/example_project/pkg_with_subpkgs/subpkg2/subpkg3:
+        config:
+            all: true
+            dir: foobar
+            recursive: true
+            with-expecter: true
+with-expecter: false
 `,
 		},
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
+
+			ctx := context.Background()
 			tmpdir := pathlib.NewPath(t.TempDir())
 			cfg := tmpdir.Join("config.yaml")
 			require.NoError(t, cfg.WriteFile([]byte(tt.cfgYaml)))
 
-			c := &Config{
-				Config: cfg.String(),
-			}
+			viperObj := viper.New()
+			viperObj.SetConfigFile(cfg.String())
+			require.NoError(t, viperObj.ReadInConfig())
+			c, err := NewConfigFromViper(viperObj)
+			require.NoError(t, err)
+
 			log, err := logging.GetLogger("TRACE")
 			require.NoError(t, err)
 
-			if err := c.Initialize(log.WithContext(context.Background())); !errors.Is(err, tt.wantErr) {
+			if err := c.Initialize(log.WithContext(ctx)); !errors.Is(err, tt.wantErr) {
 				t.Errorf("Config.Initialize() error = %v, wantErr %v", err, tt.wantErr)
 			}
 
-			cfgAsStr, err := yaml.Marshal(c._cfgAsMap)
+			cfgAsMap, err := c.CfgAsMap(ctx)
+			require.NoError(t, err)
+
+			cfgAsStr, err := yaml.Marshal(cfgAsMap)
 			require.NoError(t, err)
 
 			if tt.wantCfgMap != "" && !reflect.DeepEqual(string(cfgAsStr), tt.wantCfgMap) {
diff --git a/tools/go.mod b/tools/go.mod
index 0468ca23..a5a931b2 100644
--- a/tools/go.mod
+++ b/tools/go.mod
@@ -5,6 +5,7 @@ go 1.19
 require (
 	github.com/go-task/task/v3 v3.24.0
 	github.com/golangci/golangci-lint v1.52.2
+	gotest.tools/gotestsum v1.11.0
 )
 
 require (
@@ -24,6 +25,7 @@ require (
 	github.com/ashanbrown/forbidigo v1.5.1 // indirect
 	github.com/ashanbrown/makezero v1.1.1 // indirect
 	github.com/beorn7/perks v1.0.1 // indirect
+	github.com/bitfield/gotestdox v0.2.1 // indirect
 	github.com/bkielbasa/cyclop v1.2.0 // indirect
 	github.com/blizzy78/varnamelen v0.8.0 // indirect
 	github.com/bombsimon/wsl/v3 v3.4.0 // indirect
@@ -37,6 +39,7 @@ require (
 	github.com/daixiang0/gci v0.10.1 // indirect
 	github.com/davecgh/go-spew v1.1.1 // indirect
 	github.com/denis-tingaikin/go-header v0.4.3 // indirect
+	github.com/dnephin/pflag v1.0.7 // indirect
 	github.com/esimonov/ifshort v1.0.4 // indirect
 	github.com/ettle/strcase v0.1.1 // indirect
 	github.com/fatih/color v1.15.0 // indirect
@@ -67,6 +70,7 @@ require (
 	github.com/golangci/revgrep v0.0.0-20220804021717-745bb2f7c2e6 // indirect
 	github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4 // indirect
 	github.com/google/go-cmp v0.5.9 // indirect
+	github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
 	github.com/gordonklaus/ineffassign v0.0.0-20230107090616-13ace0543b28 // indirect
 	github.com/gostaticanalysis/analysisutil v0.7.1 // indirect
 	github.com/gostaticanalysis/comment v1.4.2 // indirect
@@ -99,7 +103,7 @@ require (
 	github.com/maratori/testpackage v1.1.1 // indirect
 	github.com/matoous/godox v0.0.0-20230222163458-006bad1f9d26 // indirect
 	github.com/mattn/go-colorable v0.1.13 // indirect
-	github.com/mattn/go-isatty v0.0.17 // indirect
+	github.com/mattn/go-isatty v0.0.19 // indirect
 	github.com/mattn/go-runewidth v0.0.9 // indirect
 	github.com/mattn/go-zglob v0.0.4 // indirect
 	github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
@@ -171,12 +175,12 @@ require (
 	go.uber.org/zap v1.24.0 // indirect
 	golang.org/x/exp v0.0.0-20230212135524-a684f29349b6 // indirect
 	golang.org/x/exp/typeparams v0.0.0-20230224173230-c95f2b4c22f2 // indirect
-	golang.org/x/mod v0.9.0 // indirect
-	golang.org/x/sync v0.1.0 // indirect
-	golang.org/x/sys v0.6.0 // indirect
-	golang.org/x/term v0.5.0 // indirect
-	golang.org/x/text v0.7.0 // indirect
-	golang.org/x/tools v0.7.0 // indirect
+	golang.org/x/mod v0.12.0 // indirect
+	golang.org/x/sync v0.3.0 // indirect
+	golang.org/x/sys v0.10.0 // indirect
+	golang.org/x/term v0.10.0 // indirect
+	golang.org/x/text v0.11.0 // indirect
+	golang.org/x/tools v0.11.0 // indirect
 	google.golang.org/protobuf v1.28.0 // indirect
 	gopkg.in/ini.v1 v1.67.0 // indirect
 	gopkg.in/yaml.v2 v2.4.0 // indirect
diff --git a/tools/go.sum b/tools/go.sum
index 2ae83f24..a08b263b 100644
--- a/tools/go.sum
+++ b/tools/go.sum
@@ -78,6 +78,8 @@ github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24
 github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
 github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
 github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
+github.com/bitfield/gotestdox v0.2.1 h1:Zj8IMLAO5/oiAKoMmtN96eyFiPZraJRTH2p0zDgtxc0=
+github.com/bitfield/gotestdox v0.2.1/go.mod h1:D+gwtS0urjBrzguAkTM2wodsTQYFHdpx8eqRJ3N+9pY=
 github.com/bkielbasa/cyclop v1.2.0 h1:7Jmnh0yL2DjKfw28p86YTd/B4lRGcNuu12sKE35sM7A=
 github.com/bkielbasa/cyclop v1.2.0/go.mod h1:qOI0yy6A7dYC4Zgsa72Ppm9kONl0RoIlPbzot9mhmeI=
 github.com/blizzy78/varnamelen v0.8.0 h1:oqSblyuQvFsW1hbBHh1zfwrKe3kcSj0rnXkKzsQ089M=
@@ -116,6 +118,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/denis-tingaikin/go-header v0.4.3 h1:tEaZKAlqql6SKCY++utLmkPLd6K8IBM20Ha7UVm+mtU=
 github.com/denis-tingaikin/go-header v0.4.3/go.mod h1:0wOCWuN71D5qIgE2nz9KrKmuYBAC2Mra5RassOIQ2/c=
+github.com/dnephin/pflag v1.0.7 h1:oxONGlWxhmUct0YzKTgrpQv9AUA1wtPBn7zuSjJqptk=
+github.com/dnephin/pflag v1.0.7/go.mod h1:uxE91IoWURlOiTUIA8Mq5ZZkAv3dPUfZNaT80Zm7OQE=
 github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
 github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
 github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
@@ -257,6 +261,8 @@ github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLe
 github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
 github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
 github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
+github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4=
+github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
 github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
 github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
 github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
@@ -354,8 +360,9 @@ github.com/matryer/is v1.4.0/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwM
 github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
 github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
 github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
-github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng=
 github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
+github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
+github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
 github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0=
 github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
 github.com/mattn/go-zglob v0.0.4 h1:LQi2iOm0/fGgu80AioIJ/1j9w9Oh+9DZ39J4VAGzHQM=
@@ -448,7 +455,8 @@ github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567/go.mod h1:DWNGW8
 github.com/radovskyb/watcher v1.0.7 h1:AYePLih6dpmS32vlHfhCeli8127LzkIgwJGcwwe8tUE=
 github.com/radovskyb/watcher v1.0.7/go.mod h1:78okwvY5wPdzcb1UYnip1pvrZNIVEIh/Cm+ZuvsUYIg=
 github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
-github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
+github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
+github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
 github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
 github.com/ryancurrah/gomodguard v1.3.0 h1:q15RT/pd6UggBXVBuLps8BXRvl5GPBcwVA7BJHMLuTw=
 github.com/ryancurrah/gomodguard v1.3.0/go.mod h1:ggBxb3luypPEzqVtq33ee7YSN35V28XeGnid8dnni50=
@@ -491,6 +499,7 @@ github.com/spf13/cobra v1.6.1 h1:o94oiPyS4KD1mPy2fmcYYHHfCxLqYjJOhGsCHFZtEzA=
 github.com/spf13/cobra v1.6.1/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY=
 github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=
 github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
+github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
 github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
 github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
 github.com/spf13/viper v1.12.0 h1:CZ7eSOd3kZoaYDLbXnmzgQI5RlciuXBMA+18HwHRfZQ=
@@ -576,6 +585,7 @@ golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm
 golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
 golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
 golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw=
+golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio=
 golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
 golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
 golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@@ -622,8 +632,9 @@ golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91
 golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI=
 golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
 golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
-golang.org/x/mod v0.9.0 h1:KENHtAZL2y3NLMYZeHY9DW8HW8V+kQyJsY/V9JlKvCs=
 golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
+golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc=
+golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
 golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -666,7 +677,9 @@ golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
 golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE=
 golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws=
 golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
-golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ=
+golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
+golang.org/x/net v0.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50=
+golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA=
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
 golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
 golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -689,8 +702,9 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ
 golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
 golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E=
+golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
 golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -750,16 +764,20 @@ golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ=
 golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA=
+golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
 golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
 golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
 golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA=
 golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ=
-golang.org/x/term v0.5.0 h1:n2a8QNdAb0sZNpU9R1ALUXBbY+w51fCQDN+7EdxNBsY=
 golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
+golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
+golang.org/x/term v0.10.0 h1:3R7pNqamzBraeqj/Tj8qt1aQ2HpmlC+Cx/qL/7hn4/c=
+golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o=
 golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -771,8 +789,10 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
 golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
 golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
 golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
-golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo=
 golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
+golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
+golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4=
+golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
 golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@@ -846,8 +866,8 @@ golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k=
 golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ=
 golang.org/x/tools v0.5.0/go.mod h1:N+Kgy78s5I24c24dU8OfWNEotWjutIs8SnJvn5IDq+k=
 golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
-golang.org/x/tools v0.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4=
-golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s=
+golang.org/x/tools v0.11.0 h1:EMCa6U9S2LtZXLAMoWiR/R8dAQFRqbAitmbJ2UKhoi8=
+golang.org/x/tools v0.11.0/go.mod h1:anzJrxPjNtfgiYQYirP2CPGzGLxrH2u2QBhn6Bf3qY8=
 golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@@ -962,6 +982,10 @@ gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
 gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
 gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
 gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gotest.tools/gotestsum v1.11.0 h1:A88/QWw7acMjZH1dMe6KZFhw32odUOIjCiAU/Q4n3mI=
+gotest.tools/gotestsum v1.11.0/go.mod h1:cUOKgFEvWAP0twchmiOvdzX0SBZX0UI58bGRpRIu4xs=
+gotest.tools/v3 v3.3.0 h1:MfDY1b1/0xN1CyMlQDac0ziEy9zJQd9CXBRRDHw2jJo=
+gotest.tools/v3 v3.3.0/go.mod h1:Mcr9QNxkg0uMvy/YElmo4SpXgJKWgQvYrT7Kw5RzJ1A=
 honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
 honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
 honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
diff --git a/tools/tools.go b/tools/tools.go
index 3744723b..e6e237e6 100644
--- a/tools/tools.go
+++ b/tools/tools.go
@@ -5,4 +5,5 @@ package tools
 import (
 	_ "github.com/go-task/task/v3/cmd/task"
 	_ "github.com/golangci/golangci-lint/cmd/golangci-lint"
+	_ "gotest.tools/gotestsum"
 )