From 3177f755e2a56b534e6dcf439f77bfa2b57a2236 Mon Sep 17 00:00:00 2001 From: yeti Date: Tue, 31 Mar 2026 03:04:23 +0000 Subject: [PATCH] refactor: extract writeFeatureDropIn helper from EnableFeature and DisableFeature Both methods contained near-identical code for creating the drop-in directory, writing the drop-in file, and handling dry-run logging. The only difference was the content (Enabled=true vs Enabled=false). Extract a shared writeFeatureDropIn method to consolidate this logic. Co-Authored-By: Claude Opus 4.6 (1M context) --- updex/features.go | 83 ++++++++++++++++++++++------------------------- yeti/OVERVIEW.md | 3 +- 2 files changed, 41 insertions(+), 45 deletions(-) diff --git a/updex/features.go b/updex/features.go index 25fb7e2..9d41ea8 100644 --- a/updex/features.go +++ b/updex/features.go @@ -92,6 +92,31 @@ func (c *Client) loadFeatureTransfers(name string) ([]*config.Transfer, error) { return config.GetTransfersForFeature(transfers, name), nil } +// writeFeatureDropIn creates a drop-in configuration file that sets a +// feature's enabled state. In dry-run mode it only logs what would happen +// and returns the path without writing anything. +func (c *Client) writeFeatureDropIn(name string, enabled bool, dryRun bool) (string, error) { + dropInDir := filepath.Join("/etc/sysupdate.d", name+".feature.d") + dropInFile := filepath.Join(dropInDir, "00-updex.conf") + + if dryRun { + c.msg("Would create drop-in: %s", dropInFile) + return dropInFile, nil + } + + if err := os.MkdirAll(dropInDir, 0755); err != nil { + return "", fmt.Errorf("failed to create drop-in directory: %w", err) + } + + content := fmt.Sprintf("[Feature]\nEnabled=%v\n", enabled) + if err := os.WriteFile(dropInFile, []byte(content), 0644); err != nil { + return "", fmt.Errorf("failed to write drop-in file: %w", err) + } + + c.msg("Created drop-in: %s", dropInFile) + return dropInFile, nil +} + // EnableFeature enables a feature by creating a drop-in configuration file. func (c *Client) EnableFeature(ctx context.Context, name string, opts EnableFeatureOptions) (*FeatureActionResult, error) { c.msg("Enabling %s", name) @@ -110,29 +135,14 @@ func (c *Client) EnableFeature(ctx context.Context, name string, opts EnableFeat } // Create drop-in directory and file - dropInDir := filepath.Join("/etc/sysupdate.d", name+".feature.d") - dropInFile := filepath.Join(dropInDir, "00-updex.conf") - - if opts.DryRun { - c.msg("Would create drop-in: %s", dropInFile) - } else { - if err := os.MkdirAll(dropInDir, 0755); err != nil { - err = fmt.Errorf("failed to create drop-in directory: %w", err) - result.Error = err.Error() - c.warn("%s", result.Error) - return result, err - } - - content := "[Feature]\nEnabled=true\n" - if err := os.WriteFile(dropInFile, []byte(content), 0644); err != nil { - err = fmt.Errorf("failed to write drop-in file: %w", err) - result.Error = err.Error() - c.warn("%s", result.Error) - return result, err - } - + dropInFile, err := c.writeFeatureDropIn(name, true, opts.DryRun) + if err != nil { + result.Error = err.Error() + c.warn("%s", result.Error) + return result, err + } + if !opts.DryRun { result.DropIn = dropInFile - c.msg("Created drop-in: %s", dropInFile) } // Handle --now flag: download extensions immediately @@ -261,29 +271,14 @@ func (c *Client) DisableFeature(ctx context.Context, name string, opts DisableFe } // Create drop-in directory and file - dropInDir := filepath.Join("/etc/sysupdate.d", name+".feature.d") - dropInFile := filepath.Join(dropInDir, "00-updex.conf") - - if opts.DryRun { - c.msg("Would create drop-in: %s", dropInFile) - } else { - if err := os.MkdirAll(dropInDir, 0755); err != nil { - err = fmt.Errorf("failed to create drop-in directory: %w", err) - result.Error = err.Error() - c.warn("%s", result.Error) - return result, err - } - - content := "[Feature]\nEnabled=false\n" - if err := os.WriteFile(dropInFile, []byte(content), 0644); err != nil { - err = fmt.Errorf("failed to write drop-in file: %w", err) - result.Error = err.Error() - c.warn("%s", result.Error) - return result, err - } - + dropInFile, err := c.writeFeatureDropIn(name, false, opts.DryRun) + if err != nil { + result.Error = err.Error() + c.warn("%s", result.Error) + return result, err + } + if !opts.DryRun { result.DropIn = dropInFile - c.msg("Created drop-in: %s", dropInFile) } // Handle --now (or --remove for backward compat): remove files and unmerge diff --git a/yeti/OVERVIEW.md b/yeti/OVERVIEW.md index a6e1b78..79623b0 100644 --- a/yeti/OVERVIEW.md +++ b/yeti/OVERVIEW.md @@ -19,7 +19,8 @@ cmd/updex/client.go CLI → SDK client factory updex/ Public SDK (Client + methods) updex.go Client struct, NewClient() features.go Features(), EnableFeature(), DisableFeature(), - UpdateFeatures(), CheckFeatures() + UpdateFeatures(), CheckFeatures(), + writeFeatureDropIn() helper install.go installTransfer() — complete install pipeline (download, symlink, sysext link, refresh, vacuum) Reuses parsed patterns from getAvailableVersions