< Summary - go-semantic-release Coverage

Information
Line coverage
72%
Covered lines: 31
Uncovered lines: 12
Coverable lines: 43
Total lines: 107
Line coverage: 72%
Branch coverage
N/A
Covered branches: 0
Total branches: 0
Branch coverage: N/A
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
Load0%0072.09%

File(s)

/home/runner/work/go-semantic-release/go-semantic-release/internal/adapters/config/viper.go

#LineLine coverage
 1package config
 2
 3import (
 4  "fmt"
 5  "strings"
 6
 7  "github.com/go-viper/mapstructure/v2"
 8  "github.com/spf13/viper"
 9
 10  "github.com/jedi-knights/go-semantic-release/internal/domain"
 11  "github.com/jedi-knights/go-semantic-release/internal/ports"
 12)
 13
 14// Compile-time interface compliance check.
 15var _ ports.ConfigProvider = (*ViperProvider)(nil)
 16
 17// Supported config file names, searched in order (matching semantic-release conventions).
 18var configNames = []string{
 19  ".semantic-release",
 20  ".releaserc",
 21  "release.config",
 22}
 23
 24// ViperProvider implements ports.ConfigProvider using Viper.
 25type ViperProvider struct{}
 26
 27// NewViperProvider creates a new Viper-based config provider.
 28func NewViperProvider() *ViperProvider {
 29  return &ViperProvider{}
 30}
 31
 732func (p *ViperProvider) Load(path string) (domain.Config, error) {
 733  cfg := domain.DefaultConfig()
 734
 735  v := viper.New()
 736  v.SetEnvPrefix("SEMANTIC_RELEASE")
 737  v.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))
 738  v.AutomaticEnv()
 739
 640  if path != "" {
 641    v.SetConfigFile(path)
 142  } else {
 143    // Search for multiple config file names/formats.
 144    v.AddConfigPath(".")
 145    found := false
 146    for _, name := range configNames {
 347      v.SetConfigName(name)
 048      if err := v.ReadInConfig(); err == nil {
 049        found = true
 050        break
 51      }
 52    }
 153    if !found {
 154      // No config file found — use defaults + env only.
 155      return cfg, nil
 156    }
 57  }
 58
 659  if path != "" {
 260    if err := v.ReadInConfig(); err != nil {
 261      return cfg, fmt.Errorf("reading config: %w", err)
 262    }
 63  }
 64
 65  // StringToGitHubAssetHookFunc must run first so string values are promoted to
 66  // GitHubAsset{Path: s} before mapstructure attempts its own map→struct decode.
 467  if err := v.Unmarshal(&cfg, viper.DecodeHook(
 468    mapstructure.ComposeDecodeHookFunc(
 469      StringToGitHubAssetHookFunc(),
 470      mapstructure.StringToTimeDurationHookFunc(),
 471      mapstructure.StringToSliceHookFunc(","),
 472    ),
 073  )); err != nil {
 074    return cfg, fmt.Errorf("unmarshaling config: %w", err)
 075  }
 76
 77  // Resolve extended configurations.
 078  if len(cfg.Extends) > 0 {
 079    resolved, err := ResolveExtends(cfg)
 080    if err != nil {
 081      return cfg, fmt.Errorf("resolving extends: %w", err)
 082    }
 083    cfg = resolved
 84  }
 85
 486  return cfg, nil
 87}
 88
 89// WriteDefaultConfig writes a default config file to the given path.
 90func WriteDefaultConfig(path string) error {
 91  v := viper.New()
 92  v.SetConfigType("yaml")
 93
 94  v.Set("release_mode", "repo")
 95  v.Set("tag_format", "v{{.Version}}")
 96  v.Set("project_tag_format", "{{.Project}}/v{{.Version}}")
 97  v.Set("dry_run", false)
 98  v.Set("ci", true)
 99  v.Set("discover_modules", false)
 100  v.Set("dependency_propagation", false)
 101  v.Set("github.create_release", true)
 102
 103  if err := v.WriteConfigAs(path); err != nil {
 104    return fmt.Errorf("writing default config to %s: %w", path, err)
 105  }
 106  return nil
 107}

Methods/Properties

Load