1717package main
1818
1919import (
20+ "bufio"
2021 "bytes"
2122 "fmt"
2223 "log"
2324 "os"
2425 "os/exec"
2526 "path/filepath"
2627 "strings"
28+ "time"
2729
2830 "github.com/spf13/cobra"
2931)
3032
31- const Version = "v0.0.1"
33+ // Version is the version of gs-init tool.
34+ const Version = "v0.0.2"
35+
36+ func init () {
37+ log .SetOutput (os .Stdout )
38+ log .SetFlags (log .Ltime )
39+ }
3240
3341func main () {
3442 var (
@@ -55,7 +63,7 @@ func main() {
5563 }
5664
5765 if module == "" {
58- log .Fatalln ("module name is required" )
66+ log .Fatalln ("[ERROR] module name is required" )
5967 }
6068
6169 // Extract project name from module path
@@ -65,25 +73,25 @@ func main() {
6573 // Check if project directory already exists
6674 if _ , err := os .Stat (projectName ); err != nil {
6775 if ! os .IsNotExist (err ) {
68- log .Fatalln ( err )
76+ log .Fatalf ( "[ERROR] Stat directory %s failed: %v" , projectName , err )
6977 }
7078 } else {
71- log .Fatalln ( "project already exists" )
79+ log .Fatalf ( "[ERROR] Directory %s already exists", projectName )
7280 }
7381
74- // Clone the skeleton repository
75- srcDir := gitClone (branch )
76- fmt .Println (srcDir )
77-
7882 // Convert project name to PascalCase for Go package naming
7983 pkgName := toPascal (projectName )
84+
85+ // Clone the skeleton repository
86+ srcDir := gitClone (branch )
8087 replaceFiles (srcDir , module , pkgName )
8188
8289 // Rename project directory
8390 if err := os .Rename (srcDir , projectName ); err != nil {
84- log .Fatalln ( err )
91+ log .Fatalf ( "[ERROR] Rename directory %s to %s failed: %v" , srcDir , projectName , err )
8592 }
8693
94+ runGen (projectName )
8795 return nil
8896 }
8997
@@ -96,9 +104,9 @@ func main() {
96104func gitClone (branch string ) string {
97105 tempDir , err := os .MkdirTemp (os .TempDir (), "" )
98106 if err != nil {
99- log .Fatalln ( err )
107+ log .Fatalf ( "[ERROR] Create temp directory failed: %v" , err )
100108 }
101- log .Println (tempDir ) // log temp directory path
109+ log .Println ("[INFO] " , tempDir ) // log temp directory path
102110
103111 // Execute git clone
104112 cmd := exec .Command (
@@ -109,21 +117,21 @@ func gitClone(branch string) string {
109117 "--branch" ,
110118 branch ,
111119 "--single-branch" ,
120+ "--progress" ,
112121 "https://github.com/go-spring/skeleton.git" ,
113122 )
114123 cmd .Dir = tempDir
115124 cmd .Env = os .Environ ()
116- b , err := cmd .CombinedOutput ()
117- if err != nil {
118- log .Fatalln (err , string (b ))
125+ if err = runCommand (cmd ); err != nil {
126+ log .Fatalf ("[ERROR] Git clone failed: %v" , err )
119127 }
120- log .Println (string ( b )) // output git clone result
128+ log .Println ("[INFO] Git clone completed successfully" )
121129
122130 // Remove .git folder to detach from skeleton repo
123131 projectDir := filepath .Join (tempDir , "skeleton" )
124132 gitDir := filepath .Join (projectDir , ".git" )
125133 if err = os .RemoveAll (gitDir ); err != nil {
126- log .Fatalln ( err )
134+ log .Fatalf ( "[ERROR] Remove .git directory failed: %v" , err )
127135 }
128136 return projectDir
129137}
@@ -152,7 +160,7 @@ func toPascal(s string) string {
152160func replaceFiles (dir string , module , pkgName string ) {
153161 entries , err := os .ReadDir (dir )
154162 if err != nil {
155- log .Fatalln ( err )
163+ log .Fatalf ( "[ERROR] Read directory %s failed: %v" , dir , err )
156164 }
157165 for _ , e := range entries {
158166 if e .IsDir () {
@@ -163,7 +171,7 @@ func replaceFiles(dir string, module, pkgName string) {
163171 fileName := filepath .Join (dir , e .Name ())
164172 b , err := os .ReadFile (fileName )
165173 if err != nil {
166- log .Fatalln ( err )
174+ log .Fatalf ( "[ERROR] Read file %s failed: %v" , fileName , err )
167175 }
168176
169177 // Replace placeholders in file content
@@ -172,13 +180,57 @@ func replaceFiles(dir string, module, pkgName string) {
172180
173181 // Remove original file (preparing to rename if necessary)
174182 if err = os .Remove (fileName ); err != nil {
175- log .Fatalln ( err )
183+ log .Fatalf ( "[ERROR] Remove file %s failed: %v" , fileName , err )
176184 }
177185
178186 // Write updated content to file
179187 fileName = strings .ReplaceAll (fileName , "GS_PROJECT_NAME" , pkgName )
180188 if err = os .WriteFile (fileName , b , os .ModePerm ); err != nil {
181- log .Fatalln ( err )
189+ log .Fatalf ( "[ERROR] Write file %s failed: %v" , fileName , err )
182190 }
183191 }
184192}
193+
194+ // runGen runs `gs gen` command.
195+ func runGen (dir string ) {
196+ cmd := exec .Command ("gs" , "gen" )
197+ cmd .Dir = dir
198+ cmd .Env = os .Environ ()
199+ if err := runCommand (cmd ); err != nil {
200+ log .Fatalf ("[ERROR] Run `gs gen` failed: %v" , err )
201+ }
202+ log .Println ("[INFO] Run `gs gen` completed successfully" )
203+ }
204+
205+ // runCommand runs a command and prints its output to stdout.
206+ func runCommand (cmd * exec.Cmd ) error {
207+
208+ r , w , err := os .Pipe ()
209+ if err != nil {
210+ log .Fatalf ("[ERROR] Create pipe error: %v" , err )
211+ }
212+
213+ go func () {
214+ defer func () { _ = r .Close () }()
215+ scanner := bufio .NewScanner (r )
216+ for scanner .Scan () {
217+ s := scanner .Text ()
218+ if strings .TrimSpace (s ) == "" {
219+ continue
220+ }
221+ fmt .Println (s )
222+ }
223+ if err := scanner .Err (); err != nil {
224+ log .Fatalf ("[ERROR] Scan pipe error: %v" , err )
225+ }
226+ }()
227+
228+ defer func () {
229+ time .Sleep (time .Millisecond * 100 )
230+ _ = w .Close ()
231+ }()
232+
233+ cmd .Stdout = w
234+ cmd .Stderr = w
235+ return cmd .Run ()
236+ }
0 commit comments