11package main
22
33import (
4+ "bufio"
45 "encoding/json"
56 "errors"
67 "flag"
78 "fmt"
89 "io"
10+ "io/fs"
911 "net/http"
1012 "net/url"
1113 "os"
@@ -72,8 +74,34 @@ func main() {
7274 fmt .Sprintf ("%s%s" , language , ".gitignore" ),
7375 )
7476
75- outFileName := ".gitignore"
76- err := downLoadFile (langUrl , outFileName )
77+ outputFileName := ".gitignore"
78+
79+ var shouldAppend bool
80+ var userAction string = "overwrite" // Default to overwrite if no file exists
81+ _ , err := os .Stat (outputFileName )
82+ if err == nil {
83+ choice , promptErr := promptForOverwrite (outputFileName )
84+ if promptErr != nil {
85+ fmt .Fprintf (os .Stderr , "Error reading user input: %v\n " , promptErr )
86+ os .Exit (1 )
87+ }
88+ userAction = choice
89+ switch userAction {
90+ case "cancel" :
91+ fmt .Println ("Operation cancelled by user." )
92+ os .Exit (0 )
93+ case "append" :
94+ shouldAppend = true
95+ case "overwrite" :
96+ fmt .Printf ("Overwriting '%s'...\n " , outputFileName )
97+ shouldAppend = false
98+ }
99+
100+ } else if ! errors .Is (err , fs .ErrNotExist ) { // Some error other than "file not found"
101+ fmt .Fprintf (os .Stderr , "Error checking file status: %v\n " , err )
102+ os .Exit (1 )
103+ }
104+ err = downLoadFile (langUrl , outputFileName , shouldAppend )
77105 if err != nil {
78106 if errors .Is (err , ErrGitignoreNotFound ) {
79107 fmt .Fprintf (os .Stderr , "Error: No .gitignore file found for '%s'.\n " , language )
@@ -102,7 +130,7 @@ type ContentEntry struct {
102130
103131var ErrGitignoreNotFound = errors .New ("gitignore file not found for the specified language" )
104132
105- func downLoadFile (langUrl string , filePath string ) error {
133+ func downLoadFile (langUrl string , filePath string , appendMode bool ) error {
106134
107135 resp , err := http .Get (langUrl )
108136 if err != nil {
@@ -116,12 +144,24 @@ func downLoadFile(langUrl string, filePath string) error {
116144 if resp .StatusCode != http .StatusOK {
117145 return fmt .Errorf ("received non-OK HTTP status for %s: %s" , langUrl , resp .Status )
118146 }
147+ // Determine file opening mode
148+ var fileMode int
149+ if appendMode {
150+ fileMode = os .O_APPEND | os .O_CREATE | os .O_WRONLY
151+ } else {
152+ fileMode = os .O_TRUNC | os .O_CREATE | os .O_WRONLY
153+ }
119154
120- out , err := os .Create (filePath )
155+ out , err := os .OpenFile (filePath , fileMode , 0644 )
121156 if err != nil {
122- return fmt .Errorf ("failed to create file %s: %w" , filePath , err )
157+ return fmt .Errorf ("failed to open/ create file %s: %w" , filePath , err )
123158 }
124159 defer out .Close ()
160+ if appendMode {
161+ if _ , err := out .WriteString ("\n " ); err != nil {
162+ return fmt .Errorf ("failed to write append separator: %w" , err )
163+ }
164+ }
125165
126166 bytesCopied , err := io .Copy (out , resp .Body )
127167 if err != nil {
@@ -185,3 +225,23 @@ func displayFileList(files []string) {
185225 fmt .Println (displayName )
186226 }
187227}
228+
229+ func promptForOverwrite (filePath string ) (string , error ) {
230+ reader := bufio .NewReader (os .Stdin )
231+ for {
232+ fmt .Printf ("A '%s' file already exists. What would you like to do? (o)verwrite / (a)ppend / (c)ancel: " , filePath )
233+ input , _ := reader .ReadString ('\n' )
234+ input = strings .TrimSpace (strings .ToLower (input )) // Clean and normalize input
235+
236+ switch input {
237+ case "o" , "overwrite" :
238+ return "overwrite" , nil
239+ case "a" , "append" :
240+ return "append" , nil
241+ case "c" , "cancel" :
242+ return "cancel" , nil
243+ default :
244+ fmt .Println ("Invalid choice. Please enter 'o', 'a', or 'c'." )
245+ }
246+ }
247+ }
0 commit comments