@@ -2,32 +2,31 @@ package bump
22
33import (
44 "context"
5+ "fmt"
56
67 "github.com/indaco/sley/internal/clix"
78 "github.com/indaco/sley/internal/commands/depsync"
89 "github.com/indaco/sley/internal/config"
10+ "github.com/indaco/sley/internal/core"
911 "github.com/indaco/sley/internal/operations"
1012 "github.com/indaco/sley/internal/plugins"
1113 "github.com/indaco/sley/internal/semver"
1214 "github.com/urfave/cli/v3"
1315)
1416
15- // versionCalculator is a function that calculates the new version from the previous version.
16- // It receives the previous version and returns the new version.
17- type versionCalculator func (prev semver.SemVersion ) semver.SemVersion
18-
1917// bumpParams holds all parameters needed for a bump operation.
2018type bumpParams struct {
2119 pre string
2220 meta string
2321 preserveMeta bool
2422 skipHooks bool
2523 bumpType string
26- versionCalc versionCalculator
24+ opBumpType operations. BumpType
2725}
2826
2927// executeSingleModuleBump is the unified execution pipeline for single-module bump operations.
30- // It handles all common logic: validation, hooks, update, and post-actions.
28+ // It delegates version calculation and writing to operations.BumpOperation,
29+ // the same implementation used by multi-module bumps, ensuring consistent behavior.
3130func executeSingleModuleBump (
3231 ctx context.Context ,
3332 cmd * cli.Command ,
@@ -41,57 +40,55 @@ func executeSingleModuleBump(
4140 return err
4241 }
4342
44- // Read current version
45- previousVersion , err := semver .ReadVersion (execCtx .Path )
43+ // Create BumpOperation - the same path used by multi-module bumps
44+ fs := core .NewOSFileSystem ()
45+ bumper := newVersionBumper ()
46+ op := operations .NewBumpOperation (
47+ fs , bumper , params .opBumpType ,
48+ params .pre , params .meta , params .preserveMeta ,
49+ )
50+
51+ // Preview: calculate new version without writing
52+ result , err := op .Preview (ctx , execCtx .Path )
4653 if err != nil {
4754 return err
4855 }
4956
50- // Calculate new version using the provided calculator
51- newVersion := params .versionCalc (previousVersion )
52-
53- // Apply pre-release and build metadata
54- newVersion .Build = calculateNewBuild (params .meta , params .preserveMeta , previousVersion .Build )
55-
5657 // Run pre-bump extension hooks first - extensions may set up state that plugins need to validate
57- if err := runPreBumpExtensionHooks (ctx , cfg , execCtx .Path , newVersion . String (), previousVersion .String (), params .bumpType , params .skipHooks ); err != nil {
58+ if err := runPreBumpExtensionHooks (ctx , cfg , execCtx .Path , result . NewVersion . String (), result . PreviousVersion .String (), params .bumpType , params .skipHooks ); err != nil {
5859 return err
5960 }
6061
61- // Re-read the current version in case an extension modified the .version file
62- // (e.g., an extension that fetches the latest release from GitHub and updates .version)
62+ // Re-preview in case an extension modified the .version file
6363 if ! params .skipHooks {
64- previousVersion , err = semver . ReadVersion ( execCtx .Path )
64+ result , err = op . Preview ( ctx , execCtx .Path )
6565 if err != nil {
6666 return err
6767 }
68- // Recalculate the new version based on the potentially updated previous version
69- newVersion = params .versionCalc (previousVersion )
70- newVersion .Build = calculateNewBuild (params .meta , params .preserveMeta , previousVersion .Build )
7168 }
7269
7370 // Execute all pre-bump validations after extensions have run
74- if err := executePreBumpValidations (registry , newVersion , previousVersion , params .bumpType ); err != nil {
71+ if err := executePreBumpValidations (registry , result . NewVersion , result . PreviousVersion , params .bumpType ); err != nil {
7572 return err
7673 }
7774
78- // Update the version file
79- if err := semver . UpdateVersion ( execCtx .Path , params . bumpType , params . pre , params . meta , params . preserveMeta ); err != nil {
80- return err
75+ // Write the new version using BumpOperation
76+ if err := op . Write ( ctx , execCtx .Path , result . NewVersion ); err != nil {
77+ return fmt . Errorf ( "failed to write version: %w" , err )
8178 }
8279
8380 // Execute all post-bump actions
84- if err := executePostBumpActions (registry , newVersion , previousVersion , params .bumpType , execCtx .Path ); err != nil {
81+ if err := executePostBumpActions (registry , result . NewVersion , result . PreviousVersion , params .bumpType , execCtx .Path ); err != nil {
8582 return err
8683 }
8784
8885 // Run post-bump extension hooks
89- if err := runPostBumpExtensionHooks (ctx , cfg , execCtx .Path , previousVersion .String (), params .bumpType , params .skipHooks ); err != nil {
86+ if err := runPostBumpExtensionHooks (ctx , cfg , execCtx .Path , result . PreviousVersion .String (), params .bumpType , params .skipHooks ); err != nil {
9087 return err
9188 }
9289
9390 // Commit (if auto-commit enabled) and create tag after successful bump
94- return commitAndTagAfterBump (registry , newVersion , params .bumpType , execCtx .Path )
91+ return commitAndTagAfterBump (registry , result . NewVersion , params .bumpType , execCtx .Path )
9592}
9693
9794// executePreBumpValidations runs all validation checks before performing a bump.
@@ -135,50 +132,15 @@ func executePostBumpActions(registry *plugins.PluginRegistry, newVersion, previo
135132 return recordAuditLogEntry (registry , newVersion , previousVersion , bumpType )
136133}
137134
138- // makePatchCalculator returns a version calculator for patch bumps.
139- func makePatchCalculator (pre , meta string , preserveMeta bool ) versionCalculator {
140- return func (prev semver.SemVersion ) semver.SemVersion {
141- next := prev
142- next .Patch ++
143- next .PreRelease = pre
144- next .Build = calculateNewBuild (meta , preserveMeta , prev .Build )
145- return next
146- }
147- }
148-
149- // makeMinorCalculator returns a version calculator for minor bumps.
150- func makeMinorCalculator (pre , meta string , preserveMeta bool ) versionCalculator {
151- return func (prev semver.SemVersion ) semver.SemVersion {
152- next := prev
153- next .Minor ++
154- next .Patch = 0
155- next .PreRelease = pre
156- next .Build = calculateNewBuild (meta , preserveMeta , prev .Build )
157- return next
158- }
159- }
160-
161- // makeMajorCalculator returns a version calculator for major bumps.
162- func makeMajorCalculator (pre , meta string , preserveMeta bool ) versionCalculator {
163- return func (prev semver.SemVersion ) semver.SemVersion {
164- next := prev
165- next .Major ++
166- next .Minor = 0
167- next .Patch = 0
168- next .PreRelease = pre
169- next .Build = calculateNewBuild (meta , preserveMeta , prev .Build )
170- return next
171- }
172- }
173-
174135// extractBumpParams extracts common bump parameters from CLI command.
175- func extractBumpParams (cmd * cli.Command , bumpType string ) bumpParams {
136+ func extractBumpParams (cmd * cli.Command , bumpType string , opBumpType operations. BumpType ) bumpParams {
176137 return bumpParams {
177138 pre : cmd .String ("pre" ),
178139 meta : cmd .String ("meta" ),
179140 preserveMeta : cmd .Bool ("preserve-meta" ),
180141 skipHooks : cmd .Bool ("skip-hooks" ),
181142 bumpType : bumpType ,
143+ opBumpType : opBumpType ,
182144 }
183145}
184146
@@ -190,7 +152,6 @@ func executeStandardBump(
190152 cfg * config.Config ,
191153 registry * plugins.PluginRegistry ,
192154 params bumpParams ,
193- multiModuleOp operations.BumpType ,
194155) error {
195156 execCtx , err := clix .GetExecutionContext (ctx , cmd , cfg )
196157 if err != nil {
@@ -199,7 +160,7 @@ func executeStandardBump(
199160
200161 if ! execCtx .IsSingleModule () {
201162 // Multi-module mode delegates to runMultiModuleBump
202- return runMultiModuleBump (ctx , cmd , execCtx , registry , multiModuleOp , params .pre , params .meta , params .preserveMeta )
163+ return runMultiModuleBump (ctx , cmd , execCtx , registry , params . opBumpType , params .pre , params .meta , params .preserveMeta )
203164 }
204165
205166 // Single-module mode uses the unified executor
0 commit comments