< Summary - go-semantic-release Coverage

Information
Line coverage
88%
Covered lines: 22
Uncovered lines: 3
Coverable lines: 25
Total lines: 110
Line coverage: 88%
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
Calculate0%0088%

File(s)

/home/runner/work/go-semantic-release/go-semantic-release/internal/app/version_calculator.go

#LineLine coverage
 1package app
 2
 3import (
 4  "fmt"
 5
 6  "github.com/jedi-knights/go-semantic-release/internal/domain"
 7  "github.com/jedi-knights/go-semantic-release/internal/ports"
 8)
 9
 10// Compile-time interface compliance check.
 11var _ ports.VersionCalculator = (*VersionCalculatorService)(nil)
 12
 13// VersionCalculatorService implements ports.VersionCalculator.
 14type VersionCalculatorService struct{}
 15
 16// NewVersionCalculatorService creates a new version calculator.
 17func NewVersionCalculatorService() *VersionCalculatorService {
 18  return &VersionCalculatorService{}
 19}
 20
 21func (s *VersionCalculatorService) Calculate(
 22  current domain.Version,
 23  commits []domain.Commit,
 24  policy *domain.BranchPolicy,
 25  typeMapping map[string]domain.ReleaseType,
 26  prereleaseCounter int,
 1627) (domain.Version, domain.ReleaseType, error) {
 1628  bump := aggregateBump(commits, typeMapping)
 229  if !bump.IsReleasable() {
 230    return current, domain.ReleaseNone, nil
 231  }
 32
 33  // For maintenance branches, constrain the allowed bump type.
 534  if policy != nil && policy.IsMaintenance() {
 535    original := bump
 536    bump = constrainMaintenanceBump(bump, policy)
 437    if !bump.IsReleasable() {
 438      return current, domain.ReleaseNone,
 439        fmt.Errorf("commit requires %s bump but maintenance branch %q does not allow it",
 440          original, policy.Name)
 441    }
 42  }
 43
 1044  next := current.Bump(bump)
 1045
 1046  // Validate maintenance range.
 147  if policy != nil && policy.IsMaintenance() {
 048    if err := domain.ValidateMaintenanceVersion(next, *policy); err != nil {
 049      return current, domain.ReleaseNone, err
 050    }
 51  }
 52
 53  // Apply prerelease identifier.
 454  if policy != nil && policy.IsPrerelease() {
 455    pre := buildPrereleaseID(policy.Channel, prereleaseCounter)
 456    next = next.WithPrerelease(pre)
 457  }
 58
 1059  return next, bump, nil
 60}
 61
 62// constrainMaintenanceBump limits the bump type based on the maintenance range.
 63// A "N.N.x" range only allows patch bumps; "N.x" allows patch and minor.
 64//
 65// NOTE: for "N.x" ranges this function permits minor bumps but does not verify
 66// that the resulting version stays within the major boundary. That upper-bound
 67// check is performed by ValidateMaintenanceVersion (called by Calculate after
 68// Bump). Callers must invoke both functions in sequence; calling this function
 69// alone is not sufficient to enforce the full maintenance constraint.
 70func constrainMaintenanceBump(bump domain.ReleaseType, policy *domain.BranchPolicy) domain.ReleaseType {
 71  _, maxVer, err := policy.MaintenanceRange()
 72  if err != nil {
 73    return domain.ReleaseNone
 74  }
 75
 76  // Major bumps are never allowed on any maintenance branch.
 77  if bump == domain.ReleaseMajor {
 78    return domain.ReleaseNone
 79  }
 80
 81  // "N.N.x" range (max differs only in minor): only patch is allowed.
 82  // "N.x" range (max differs in major): patch and minor are both allowed.
 83  if maxVer.Minor > 0 && maxVer.Patch == 0 {
 84    // Range like "1.2.x" → max is "1.3.0" → only patch allowed.
 85    if bump > domain.ReleasePatch {
 86      return domain.ReleaseNone
 87    }
 88  }
 89
 90  return bump
 91}
 92
 93func aggregateBump(commits []domain.Commit, typeMapping map[string]domain.ReleaseType) domain.ReleaseType {
 94  highest := domain.ReleaseNone
 95  for i := range commits {
 96    rt := commits[i].ReleaseType(typeMapping)
 97    highest = highest.Higher(rt)
 98  }
 99  return highest
 100}
 101
 102func buildPrereleaseID(channel string, counter int) string {
 103  if channel == "" {
 104    channel = "pre"
 105  }
 106  if counter < 0 {
 107    counter = 0
 108  }
 109  return fmt.Sprintf("%s.%d", channel, counter)
 110}

Methods/Properties

Calculate