edit.go (2329B)
1 package cmd 2 3 import ( 4 "bufio" 5 "fmt" 6 "os" 7 "os/exec" 8 "strings" 9 10 "github.com/spf13/cobra" 11 12 "github.com/louloulibs/esync/internal/config" 13 ) 14 15 // --------------------------------------------------------------------------- 16 // Command 17 // --------------------------------------------------------------------------- 18 19 var editCmd = &cobra.Command{ 20 Use: "edit", 21 Short: "Open config in $EDITOR, then validate and preview", 22 Long: "Open the esync configuration file in your editor. After saving, the config is validated and a file preview is shown.", 23 RunE: runEdit, 24 } 25 26 func init() { 27 rootCmd.AddCommand(editCmd) 28 } 29 30 // --------------------------------------------------------------------------- 31 // Run 32 // --------------------------------------------------------------------------- 33 34 func runEdit(cmd *cobra.Command, args []string) error { 35 // 1. Find config file 36 path := cfgFile 37 if path == "" { 38 path = config.FindConfigFile() 39 } 40 if path == "" { 41 fmt.Fprintln(os.Stderr, "No config file found. Run `esync init` first to create one.") 42 return nil 43 } 44 45 // 2. Determine editor 46 editor := os.Getenv("EDITOR") 47 if editor == "" { 48 editor = "vi" 49 } 50 51 reader := bufio.NewReader(os.Stdin) 52 53 // 3. Edit loop 54 for { 55 // Open editor 56 editorCmd := exec.Command(editor, path) 57 editorCmd.Stdin = os.Stdin 58 editorCmd.Stdout = os.Stdout 59 editorCmd.Stderr = os.Stderr 60 61 if err := editorCmd.Run(); err != nil { 62 return fmt.Errorf("editor exited with error: %w", err) 63 } 64 65 // Validate config 66 cfg, err := config.Load(path) 67 if err != nil { 68 fmt.Fprintf(os.Stderr, "\nConfig error: %s\n", err) 69 fmt.Print("Press 'e' to edit again, or 'q' to cancel: ") 70 answer, _ := reader.ReadString('\n') 71 answer = strings.TrimSpace(strings.ToLower(answer)) 72 if answer == "q" { 73 fmt.Println("Cancelled.") 74 return nil 75 } 76 continue 77 } 78 79 // Valid config — show preview 80 if err := printPreview(cfg); err != nil { 81 return err 82 } 83 84 // Ask user what to do 85 fmt.Print("Press Enter to accept, 'e' to edit again, or 'q' to cancel: ") 86 answer, _ := reader.ReadString('\n') 87 answer = strings.TrimSpace(strings.ToLower(answer)) 88 89 switch answer { 90 case "q": 91 fmt.Println("Cancelled.") 92 return nil 93 case "e": 94 continue 95 default: 96 // Enter or anything else: accept 97 fmt.Println("Config saved.") 98 return nil 99 } 100 } 101 }