Skip to content

Commit e792800

Browse files
authored
refactor(internal/semver): pass options into DeriveNext functions (#3421)
Update DeriveNext and DeriveNextPreview to accept DeriveNextOptions as an explicit argument rather than being methods on a receiver. This removes the need to instantiate an empty struct solely to access behavior and makes the required inputs explicit at the call site. The top-level convenience wrappers have been removed in favor of calling the underlying functions directly.
1 parent 7249668 commit e792800

5 files changed

Lines changed: 75 additions & 88 deletions

File tree

internal/legacylibrarian/legacylibrarian/commit_version_analyzer.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ func isUnderAnyPath(file string, paths []string) bool {
171171
// NextVersion calculates the next semantic version based on a slice of conventional commits.
172172
func NextVersion(commits []*legacygitrepo.ConventionalCommit, currentVersion string) (string, error) {
173173
highestChange := getHighestChange(commits)
174-
return semver.DeriveNext(highestChange, currentVersion)
174+
return semver.DeriveNext(highestChange, currentVersion, semver.DeriveNextOptions{})
175175
}
176176

177177
// getHighestChange determines the highest-ranking change type from a slice of commits.

internal/librarian/rust/release.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,11 @@ func ReleaseLibrary(library *config.Library, srcPath string) error {
4949
if manifest.Package == nil {
5050
return err
5151
}
52-
newVersion, err := semver.DeriveNextOptions{
53-
BumpVersionCore: true,
54-
DowngradePreGAChanges: true,
55-
}.DeriveNext(semver.Minor, manifest.Package.Version)
52+
newVersion, err := semver.DeriveNext(semver.Minor, manifest.Package.Version,
53+
semver.DeriveNextOptions{
54+
BumpVersionCore: true,
55+
DowngradePreGAChanges: true,
56+
})
5657
if err != nil {
5758
return err
5859
}

internal/semver/semver.go

Lines changed: 9 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,7 @@ type DeriveNextOptions struct {
271271

272272
// DeriveNext determines the appropriate SemVer version bump based on the
273273
// provided [ChangeLevel] and the provided [DeriveNextOptions].
274-
func (o DeriveNextOptions) DeriveNext(changeLevel ChangeLevel, currentVersion string) (string, error) {
274+
func DeriveNext(changeLevel ChangeLevel, currentVersion string, opts DeriveNextOptions) (string, error) {
275275
if changeLevel == None {
276276
return currentVersion, nil
277277
}
@@ -281,13 +281,13 @@ func (o DeriveNextOptions) DeriveNext(changeLevel ChangeLevel, currentVersion st
281281
return "", err
282282
}
283283

284-
return o.deriveNext(changeLevel, v), nil
284+
return deriveNext(changeLevel, v, opts), nil
285285
}
286286

287287
// deriveNext implements next version derivation based on the [DeriveNextOptions].
288-
func (o DeriveNextOptions) deriveNext(changeLevel ChangeLevel, v version) string {
288+
func deriveNext(changeLevel ChangeLevel, v version, opts DeriveNextOptions) string {
289289
// Only bump the prerelease version number.
290-
if v.Prerelease != "" && !o.BumpVersionCore {
290+
if v.Prerelease != "" && !opts.BumpVersionCore {
291291
// Append prerelease number if there isn't one.
292292
if v.PrereleaseNumber == nil {
293293
v.PrereleaseSeparator = "."
@@ -302,7 +302,7 @@ func (o DeriveNextOptions) deriveNext(changeLevel ChangeLevel, v version) string
302302
}
303303

304304
// Reset prerelease number, if present, then fallthrough to bump version core.
305-
if v.PrereleaseNumber != nil && o.BumpVersionCore {
305+
if v.PrereleaseNumber != nil && opts.BumpVersionCore {
306306
*v.PrereleaseNumber = 1
307307
}
308308

@@ -312,7 +312,7 @@ func (o DeriveNextOptions) deriveNext(changeLevel ChangeLevel, v version) string
312312
if v.Major == 0 {
313313
if changeLevel == Major {
314314
changeLevel = Minor
315-
} else if changeLevel == Minor && o.DowngradePreGAChanges {
315+
} else if changeLevel == Minor && opts.DowngradePreGAChanges {
316316
changeLevel = Patch
317317
}
318318
}
@@ -351,7 +351,7 @@ var (
351351
// version, it must be caught up. When the preview version is ahead, a
352352
// prerelease number bump is all that is necessary. Every change is treated as a
353353
// [Minor] change. The provided preview version must have a prerelease segment.
354-
func (o DeriveNextOptions) DeriveNextPreview(previewVersion, stableVersion string) (string, error) {
354+
func DeriveNextPreview(previewVersion, stableVersion string, opts DeriveNextOptions) (string, error) {
355355
pv, err := parse(previewVersion)
356356
if err != nil {
357357
return "", errors.Join(errInvalidPreviewVersion, err)
@@ -365,7 +365,7 @@ func (o DeriveNextOptions) DeriveNextPreview(previewVersion, stableVersion strin
365365
}
366366

367367
// Make a shallow copy of original options to retain any language-specific needs.
368-
nextVerOpts := o
368+
nextVerOpts := opts
369369
coreStrOpts := stringifyOptions{
370370
VersionCoreOnly: true,
371371
IncludeVPrefix: true,
@@ -386,20 +386,5 @@ func (o DeriveNextOptions) DeriveNextPreview(previewVersion, stableVersion strin
386386

387387
nextVerOpts.BumpVersionCore = true
388388
}
389-
390-
return nextVerOpts.deriveNext(Minor, pv), nil
391-
}
392-
393-
// DeriveNext calculates the next version based on the highest change type and
394-
// current version using the default [DeriveNextOptions]. This is a convenience
395-
// method.
396-
func DeriveNext(highestChange ChangeLevel, currentVersion string) (string, error) {
397-
return DeriveNextOptions{}.DeriveNext(highestChange, currentVersion)
398-
}
399-
400-
// DeriveNextPreview calculates the next preview version based on the provided
401-
// stable version using the default [DeriveNextOptions]. This is a convenience
402-
// method.
403-
func DeriveNextPreview(previewVersion, stableVersion string) (string, error) {
404-
return DeriveNextOptions{}.DeriveNextPreview(previewVersion, stableVersion)
389+
return deriveNext(Minor, pv, nextVerOpts), nil
405390
}

internal/semver/semver_test.go

Lines changed: 55 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -215,79 +215,79 @@ func TestVersion_String(t *testing.T) {
215215

216216
func TestDeriveNext(t *testing.T) {
217217
for _, test := range []struct {
218-
name string
219-
highestChange ChangeLevel
220-
currentVersion string
221-
expectedVersion string
218+
name string
219+
highestChange ChangeLevel
220+
currentVersion string
221+
want string
222222
}{
223223
{
224-
name: "major bump",
225-
highestChange: Major,
226-
currentVersion: "1.2.3",
227-
expectedVersion: "2.0.0",
224+
name: "major bump",
225+
highestChange: Major,
226+
currentVersion: "1.2.3",
227+
want: "2.0.0",
228228
},
229229
{
230-
name: "minor bump",
231-
highestChange: Minor,
232-
currentVersion: "1.2.3",
233-
expectedVersion: "1.3.0",
230+
name: "minor bump",
231+
highestChange: Minor,
232+
currentVersion: "1.2.3",
233+
want: "1.3.0",
234234
},
235235
{
236-
name: "patch bump",
237-
highestChange: Patch,
238-
currentVersion: "1.2.3",
239-
expectedVersion: "1.2.4",
236+
name: "patch bump",
237+
highestChange: Patch,
238+
currentVersion: "1.2.3",
239+
want: "1.2.4",
240240
},
241241
{
242-
name: "pre-1.0.0 feat is patch bump",
243-
highestChange: Minor, // feat is minor
244-
currentVersion: "0.2.3",
245-
expectedVersion: "0.3.0",
242+
name: "pre-1.0.0 feat is patch bump",
243+
highestChange: Minor, // feat is minor
244+
currentVersion: "0.2.3",
245+
want: "0.3.0",
246246
},
247247
{
248-
name: "pre-1.0.0 fix is patch bump",
249-
highestChange: Patch,
250-
currentVersion: "0.2.3",
251-
expectedVersion: "0.2.4",
248+
name: "pre-1.0.0 fix is patch bump",
249+
highestChange: Patch,
250+
currentVersion: "0.2.3",
251+
want: "0.2.4",
252252
},
253253
{
254-
name: "pre-1.0.0 breaking change is minor bump",
255-
highestChange: Major,
256-
currentVersion: "0.2.3",
257-
expectedVersion: "0.3.0",
254+
name: "pre-1.0.0 breaking change is minor bump",
255+
highestChange: Major,
256+
currentVersion: "0.2.3",
257+
want: "0.3.0",
258258
},
259259
{
260-
name: "prerelease bump with numeric trailer",
261-
highestChange: Minor,
262-
currentVersion: "1.2.3-beta.1",
263-
expectedVersion: "1.2.3-beta.2",
260+
name: "prerelease bump with numeric trailer",
261+
highestChange: Minor,
262+
currentVersion: "1.2.3-beta.1",
263+
want: "1.2.3-beta.2",
264264
},
265265
{
266-
name: "prerelease bump without numeric trailer",
267-
highestChange: Patch,
268-
currentVersion: "1.2.3-beta",
269-
expectedVersion: "1.2.3-beta.1",
266+
name: "prerelease bump without numeric trailer",
267+
highestChange: Patch,
268+
currentVersion: "1.2.3-beta",
269+
want: "1.2.3-beta.1",
270270
},
271271
{
272-
name: "prerelease bump with betaXX format",
273-
highestChange: Major,
274-
currentVersion: "1.2.3-beta21",
275-
expectedVersion: "1.2.3-beta22",
272+
name: "prerelease bump with betaXX format",
273+
highestChange: Major,
274+
currentVersion: "1.2.3-beta21",
275+
want: "1.2.3-beta22",
276276
},
277277
{
278-
name: "no bump",
279-
highestChange: None,
280-
currentVersion: "1.2.3",
281-
expectedVersion: "1.2.3",
278+
name: "no bump",
279+
highestChange: None,
280+
currentVersion: "1.2.3",
281+
want: "1.2.3",
282282
},
283283
} {
284284
t.Run(test.name, func(t *testing.T) {
285-
nextVersion, err := DeriveNext(test.highestChange, test.currentVersion)
285+
got, err := DeriveNext(test.highestChange, test.currentVersion, DeriveNextOptions{})
286286
if err != nil {
287-
t.Fatalf("DeriveNext() returned an error: %v", err)
287+
t.Fatal(err)
288288
}
289-
if diff := cmp.Diff(test.expectedVersion, nextVersion); diff != "" {
290-
t.Errorf("mismatch (-want +got):\n%s", diff)
289+
if got != test.want {
290+
t.Errorf("DeriveNext(%v, %q) = %q, want %q", test.highestChange, test.currentVersion, got, test.want)
291291
}
292292
})
293293
}
@@ -405,9 +405,9 @@ func TestDeriveNextOptions_DeriveNext(t *testing.T) {
405405
},
406406
} {
407407
t.Run(test.name, func(t *testing.T) {
408-
nextVersion, err := test.opts.DeriveNext(test.highestChange, test.currentVersion)
408+
nextVersion, err := DeriveNext(test.highestChange, test.currentVersion, test.opts)
409409
if err != nil {
410-
t.Fatalf("DeriveNextOptions.DeriveNext() returned an error: %v", err)
410+
t.Fatal(err)
411411
}
412412
if diff := cmp.Diff(test.expectedVersion, nextVersion); diff != "" {
413413
t.Errorf("mismatch (-want +got):\n%s", diff)
@@ -431,7 +431,7 @@ func TestDeriveNextOptions_DeriveNext_Error(t *testing.T) {
431431
},
432432
} {
433433
t.Run(test.name, func(t *testing.T) {
434-
_, err := DeriveNextOptions{}.DeriveNext(test.changeLevel, test.currentVersion)
434+
_, err := DeriveNext(test.changeLevel, test.currentVersion, DeriveNextOptions{})
435435
if err == nil {
436436
t.Errorf("DeriveNextOptions.DeriveNext(%v, %q) did not return an error as expected.", test.changeLevel, test.currentVersion)
437437
} else if !errors.Is(err, test.wantErr) {
@@ -539,9 +539,9 @@ func TestDeriveNextOptions_DeriveNextPreview(t *testing.T) {
539539
},
540540
} {
541541
t.Run(test.name, func(t *testing.T) {
542-
nextVersion, err := test.opts.DeriveNextPreview(test.previewVersion, test.stableVersion)
542+
nextVersion, err := DeriveNextPreview(test.previewVersion, test.stableVersion, test.opts)
543543
if err != nil {
544-
t.Fatalf("DeriveNextOptions.DeriveNextPreview() returned an error: %v", err)
544+
t.Fatalf("DeriveNextPreview() returned an error: %v", err)
545545
}
546546
if diff := cmp.Diff(test.want, nextVersion); diff != "" {
547547
t.Errorf("mismatch (-want +got):\n%s", diff)
@@ -577,9 +577,9 @@ func TestDeriveNextOptions_DeriveNextPreview_Errors(t *testing.T) {
577577
},
578578
} {
579579
t.Run(test.name, func(t *testing.T) {
580-
_, err := DeriveNextOptions{}.DeriveNextPreview(test.previewVersion, test.stableVersion)
580+
_, err := DeriveNextPreview(test.previewVersion, test.stableVersion, DeriveNextOptions{})
581581
if err == nil {
582-
t.Errorf("DeriveNextOptions.DeriveNextPreview(%q, %q) did not return an error as expected.", test.previewVersion, test.stableVersion)
582+
t.Errorf("DeriveNextPreview(%q, %q) did not return an error as expected.", test.previewVersion, test.stableVersion)
583583
} else if !errors.Is(err, test.wantErr) {
584584
t.Errorf("mismatch, got %v, wanted inclusion of %v", err, test.wantErr)
585585
}

internal/sidekick/rust_release/update_manifest.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,11 @@ func updateManifest(config *config.Release, lastTag, manifest string) ([]string,
6161
if !info.Package.Publish {
6262
return nil, nil
6363
}
64-
newVersion, err := semver.DeriveNextOptions{
65-
BumpVersionCore: true,
66-
DowngradePreGAChanges: true,
67-
}.DeriveNext(semver.Minor, info.Package.Version)
64+
newVersion, err := semver.DeriveNext(semver.Minor, info.Package.Version,
65+
semver.DeriveNextOptions{
66+
BumpVersionCore: true,
67+
DowngradePreGAChanges: true,
68+
})
6869
if err != nil {
6970
return nil, err
7071
}

0 commit comments

Comments
 (0)