From 8d7315fdbe021b4754ed5573a754eb487953f8bf Mon Sep 17 00:00:00 2001 From: rokuosanai <288084358+rokuosanai@users.noreply.github.com> Date: Fri, 24 Jul 2026 10:49:39 +0000 Subject: [PATCH] fix: prevent init from overwriting config --- cmd/cli/subcommand/init.go | 17 ++++++++++++++--- cmd/cli/subcommand/init_test.go | 22 ++++++++++++++++++++++ 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/cmd/cli/subcommand/init.go b/cmd/cli/subcommand/init.go index 46f5ed2..966ddb3 100644 --- a/cmd/cli/subcommand/init.go +++ b/cmd/cli/subcommand/init.go @@ -3,6 +3,7 @@ package subcommand import ( "fmt" "log/slog" + "os" "github.com/rokuosan/github-issue-cms/pkg/config" "github.com/spf13/cobra" @@ -14,6 +15,7 @@ func NewInitCommand() *cobra.Command { var ( username string repository string + force bool ) cmd := &cobra.Command{ @@ -34,18 +36,28 @@ Examples: # Short form github-issue-cms init -u yourname -r yourrepo`, RunE: func(cmd *cobra.Command, args []string) error { - return runInit(cmd, username, repository) + return runInit(cmd, username, repository, force) }, } // Define flags. cmd.Flags().StringVarP(&username, "username", "u", "", "GitHub username") cmd.Flags().StringVarP(&repository, "repository", "r", "", "GitHub repository name") + cmd.Flags().BoolVar(&force, "force", false, "Overwrite an existing configuration file") return cmd } -func runInit(cmd *cobra.Command, username, repository string) error { +func runInit(cmd *cobra.Command, username, repository string, force bool) error { + configPath := config.GetConfigPath() + if !force { + if _, err := os.Stat(configPath); err == nil { + return fmt.Errorf("configuration file already exists: %s (use --force to overwrite)", configPath) + } else if !os.IsNotExist(err) { + return fmt.Errorf("failed to inspect configuration file %s: %w", configPath, err) + } + } + slog.Info("Generating configuration file...") // Generate the config file. @@ -74,7 +86,6 @@ func runInit(cmd *cobra.Command, username, repository string) error { return fmt.Errorf("failed to write config file: %w", err) } - configPath := config.GetConfigPath() slog.Info("Configuration file created: " + configPath) // Show the resulting configuration values. diff --git a/cmd/cli/subcommand/init_test.go b/cmd/cli/subcommand/init_test.go index abaa3c7..6ba5f6a 100644 --- a/cmd/cli/subcommand/init_test.go +++ b/cmd/cli/subcommand/init_test.go @@ -146,6 +146,28 @@ func TestInitCommand_ShortFlags(t *testing.T) { assert.Contains(t, content, "shortrepo") } +func TestInitCommand_RefusesToOverwriteExistingConfig(t *testing.T) { + tempDir := t.TempDir() + originalWd, err := os.Getwd() + require.NoError(t, err) + t.Cleanup(func() { require.NoError(t, os.Chdir(originalWd)) }) + require.NoError(t, os.Chdir(tempDir)) + + configPath := filepath.Join(tempDir, config.ConfigFileName+"."+config.ConfigFileType) + original := "github:\n username: existing\n" + require.NoError(t, os.WriteFile(configPath, []byte(original), 0o644)) + + cmd := NewInitCommand() + cmd.SetArgs([]string{}) + err = cmd.Execute() + + require.Error(t, err) + assert.Contains(t, err.Error(), "already exists") + data, readErr := os.ReadFile(configPath) + require.NoError(t, readErr) + assert.Equal(t, original, string(data)) +} + func TestInitCommand_Examples(t *testing.T) { cmd := NewInitCommand()