Skip to content

Commit 70348e3

Browse files
authored
fix(tag-manager): require enabled plugin for sley tag commands (#212)
* fix(tag-manager): require enabled plugin for sley tag commands * refactor(tag-manager): rename IsEnabled to IsAutoCreateEnabled
1 parent 83857d2 commit 70348e3

5 files changed

Lines changed: 116 additions & 22 deletions

File tree

internal/commands/bump/helpers.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ func validateTagAvailable(registry *plugins.PluginRegistry, version semver.SemVe
9292

9393
// Check if the plugin is enabled and auto-create is on
9494
if plugin, ok := tm.(*tagmanager.TagManagerPlugin); ok {
95-
if !plugin.IsEnabled() {
95+
if !plugin.IsAutoCreateEnabled() {
9696
return nil
9797
}
9898
}
@@ -109,7 +109,7 @@ func createTagAfterBump(registry *plugins.PluginRegistry, version semver.SemVers
109109

110110
// Check if the plugin is enabled and auto-create is on
111111
plugin, ok := tm.(*tagmanager.TagManagerPlugin)
112-
if !ok || !plugin.IsEnabled() {
112+
if !ok || !plugin.IsAutoCreateEnabled() {
113113
return nil
114114
}
115115

internal/commands/tag/tagcmd.go

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@ func Run(cfg *config.Config) *cli.Command {
3838
Name: "tag",
3939
Usage: "Manage git tags for versions",
4040
Flags: cliflags.MultiModuleFlags(),
41+
Before: func(_ context.Context, _ *cli.Command) (context.Context, error) {
42+
return requireTagManagerEnabled(cfg)
43+
},
4144
Commands: []*cli.Command{
4245
tc.createCmd(cfg),
4346
tc.listCmd(cfg),
@@ -126,20 +129,6 @@ func (tc *TagCommand) deleteCmd(cfg *config.Config) *cli.Command {
126129

127130
// runCreateCmd creates a git tag for the current version.
128131
func (tc *TagCommand) runCreateCmd(ctx context.Context, cmd *cli.Command, cfg *config.Config) error {
129-
// Check if tag-manager plugin is enabled
130-
if !isTagManagerEnabled(cfg) {
131-
printer.PrintWarning("Warning: The tag-manager plugin is not enabled.")
132-
printer.PrintInfo("To enable it, add the following to your .sley.yaml:")
133-
fmt.Println("")
134-
fmt.Println(" plugins:")
135-
fmt.Println(" tag-manager:")
136-
fmt.Println(" enabled: true")
137-
fmt.Println(" auto-create: false # Disable auto-tagging during bump")
138-
fmt.Println("")
139-
printer.PrintInfo("Proceeding with tag creation using default settings...")
140-
fmt.Println("")
141-
}
142-
143132
path, err := resolveVersionPath(ctx, cmd, cfg)
144133
if err != nil {
145134
return err
@@ -315,6 +304,15 @@ func isTagManagerEnabled(cfg *config.Config) bool {
315304
return cfg.Plugins.TagManager.Enabled
316305
}
317306

307+
// requireTagManagerEnabled returns an error if the tag-manager plugin is not enabled.
308+
// Used as a Before hook on the parent "tag" command to gate all subcommands.
309+
func requireTagManagerEnabled(cfg *config.Config) (context.Context, error) {
310+
if isTagManagerEnabled(cfg) {
311+
return context.Background(), nil
312+
}
313+
return nil, fmt.Errorf("tag-manager plugin is not enabled\n\n Enable it in your .sley.yaml:\n\n plugins:\n tag-manager:\n enabled: true\n\n See: https://sley.indaco.dev/plugins/tag-manager")
314+
}
315+
318316
// resolveVersionPath uses clix.GetExecutionContext to properly detect multi-module
319317
// workspaces. In single-module mode it returns the resolved .version file path.
320318
// In multi-module mode it shows a TUI prompt so the user can choose which module's

internal/commands/tag/tagcmd_test.go

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -712,6 +712,91 @@ func TestIsTagManagerEnabled(t *testing.T) {
712712
}
713713
}
714714

715+
func TestRequireTagManagerEnabled(t *testing.T) {
716+
tests := []struct {
717+
name string
718+
cfg *config.Config
719+
wantErr bool
720+
}{
721+
{
722+
name: "nil config",
723+
cfg: nil,
724+
wantErr: true,
725+
},
726+
{
727+
name: "nil plugins",
728+
cfg: &config.Config{},
729+
wantErr: true,
730+
},
731+
{
732+
name: "disabled",
733+
cfg: &config.Config{
734+
Plugins: &config.PluginConfig{
735+
TagManager: &config.TagManagerConfig{Enabled: false},
736+
},
737+
},
738+
wantErr: true,
739+
},
740+
{
741+
name: "enabled",
742+
cfg: &config.Config{
743+
Plugins: &config.PluginConfig{
744+
TagManager: &config.TagManagerConfig{Enabled: true},
745+
},
746+
},
747+
wantErr: false,
748+
},
749+
}
750+
751+
for _, tt := range tests {
752+
t.Run(tt.name, func(t *testing.T) {
753+
_, err := requireTagManagerEnabled(tt.cfg)
754+
if (err != nil) != tt.wantErr {
755+
t.Errorf("requireTagManagerEnabled() error = %v, wantErr %v", err, tt.wantErr)
756+
}
757+
if tt.wantErr && err != nil {
758+
if !strings.Contains(err.Error(), "tag-manager plugin is not enabled") {
759+
t.Errorf("requireTagManagerEnabled() error message = %q, want it to contain 'tag-manager plugin is not enabled'", err.Error())
760+
}
761+
}
762+
})
763+
}
764+
}
765+
766+
func TestTagCommand_BeforeHookBlocksSubcommands(t *testing.T) {
767+
// Verify that running any tag subcommand via Run() fails when plugin is disabled.
768+
cfg := &config.Config{
769+
Path: ".version",
770+
// No tag-manager plugin configured.
771+
}
772+
773+
app := &cli.Command{
774+
Name: "sley",
775+
Writer: io.Discard,
776+
ErrWriter: io.Discard,
777+
Commands: []*cli.Command{Run(cfg)},
778+
}
779+
780+
subcommands := [][]string{
781+
{"sley", "tag", "list"},
782+
{"sley", "tag", "create"},
783+
{"sley", "tag", "push", "v1.0.0"},
784+
{"sley", "tag", "delete", "v1.0.0"},
785+
}
786+
787+
for _, args := range subcommands {
788+
t.Run(strings.Join(args[1:], " "), func(t *testing.T) {
789+
err := app.Run(context.Background(), args)
790+
if err == nil {
791+
t.Errorf("expected error for %v when tag-manager is not enabled", args)
792+
}
793+
if err != nil && !strings.Contains(err.Error(), "tag-manager plugin is not enabled") {
794+
t.Errorf("unexpected error for %v: %v", args, err)
795+
}
796+
})
797+
}
798+
}
799+
715800
func TestRunCommand(t *testing.T) {
716801
cfg := &config.Config{
717802
Path: ".version",
@@ -1530,6 +1615,11 @@ func TestCLI_TagCreate_MultiModule(t *testing.T) {
15301615
maxDepth := 10
15311616
cfg := &config.Config{
15321617
Path: ".version",
1618+
Plugins: &config.PluginConfig{
1619+
TagManager: &config.TagManagerConfig{
1620+
Enabled: true,
1621+
},
1622+
},
15331623
Workspace: &config.WorkspaceConfig{
15341624
Discovery: &config.DiscoveryConfig{
15351625
Enabled: &enabled,
@@ -1612,6 +1702,11 @@ func TestCLI_TagPush_MultiModule_NoArg(t *testing.T) {
16121702
maxDepth := 10
16131703
cfg := &config.Config{
16141704
Path: ".version",
1705+
Plugins: &config.PluginConfig{
1706+
TagManager: &config.TagManagerConfig{
1707+
Enabled: true,
1708+
},
1709+
},
16151710
Workspace: &config.WorkspaceConfig{
16161711
Discovery: &config.DiscoveryConfig{
16171712
Enabled: &enabled,

internal/plugins/tagmanager/plugin.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -225,8 +225,9 @@ func (p *TagManagerPlugin) ValidateTagAvailable(version semver.SemVersion) error
225225
return nil
226226
}
227227

228-
// IsEnabled returns whether auto-create is enabled.
229-
func (p *TagManagerPlugin) IsEnabled() bool {
228+
// IsAutoCreateEnabled returns whether the plugin is enabled with auto-create on.
229+
// This gates automatic tag validation and creation during bumps.
230+
func (p *TagManagerPlugin) IsAutoCreateEnabled() bool {
230231
return p.config.Enabled && p.config.AutoCreate
231232
}
232233

@@ -240,7 +241,7 @@ func (p *TagManagerPlugin) GetConfig() *Config {
240241
// - The version is a stable release (no pre-release), or
241242
// - The version is a pre-release and TagPrereleases is true.
242243
func (p *TagManagerPlugin) ShouldCreateTag(version semver.SemVersion) bool {
243-
if !p.IsEnabled() {
244+
if !p.IsAutoCreateEnabled() {
244245
return false
245246
}
246247

internal/plugins/tagmanager/plugin_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -332,7 +332,7 @@ func TestTagManagerPlugin_GetLatestTag(t *testing.T) {
332332
}
333333
}
334334

335-
func TestTagManagerPlugin_IsEnabled(t *testing.T) {
335+
func TestTagManagerPlugin_IsAutoCreateEnabled(t *testing.T) {
336336
tests := []struct {
337337
name string
338338
cfg *Config
@@ -358,8 +358,8 @@ func TestTagManagerPlugin_IsEnabled(t *testing.T) {
358358
for _, tt := range tests {
359359
t.Run(tt.name, func(t *testing.T) {
360360
tm := NewTagManager(tt.cfg)
361-
if got := tm.IsEnabled(); got != tt.want {
362-
t.Errorf("IsEnabled() = %v, want %v", got, tt.want)
361+
if got := tm.IsAutoCreateEnabled(); got != tt.want {
362+
t.Errorf("IsAutoCreateEnabled() = %v, want %v", got, tt.want)
363363
}
364364
})
365365
}

0 commit comments

Comments
 (0)