Skip to content

Commit 6dd8100

Browse files
lvan100lianghuan
authored andcommitted
run gs gen
1 parent e51ef31 commit 6dd8100

File tree

2 files changed

+150
-20
lines changed

2 files changed

+150
-20
lines changed

main.go

Lines changed: 72 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -17,18 +17,26 @@
1717
package main
1818

1919
import (
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

3341
func 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() {
96104
func 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 {
152160
func 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+
}

main_test.go

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
package main
2+
3+
import (
4+
"testing"
5+
)
6+
7+
func TestToPascal(t *testing.T) {
8+
tests := []struct {
9+
name string
10+
input string
11+
expected string
12+
}{
13+
{
14+
name: "single word",
15+
input: "hello",
16+
expected: "Hello",
17+
},
18+
{
19+
name: "snake case with two words",
20+
input: "hello_world",
21+
expected: "HelloWorld",
22+
},
23+
{
24+
name: "snake case with multiple words",
25+
input: "hello_world_test_case",
26+
expected: "HelloWorldTestCase",
27+
},
28+
{
29+
name: "leading underscore",
30+
input: "_hello_world",
31+
expected: "HelloWorld",
32+
},
33+
{
34+
name: "trailing underscore",
35+
input: "hello_world_",
36+
expected: "HelloWorld",
37+
},
38+
{
39+
name: "multiple consecutive underscores",
40+
input: "hello__world",
41+
expected: "HelloWorld",
42+
},
43+
{
44+
name: "empty string",
45+
input: "",
46+
expected: "",
47+
},
48+
{
49+
name: "only underscores",
50+
input: "___",
51+
expected: "",
52+
},
53+
{
54+
name: "already pascal case",
55+
input: "HelloWorld",
56+
expected: "HelloWorld",
57+
},
58+
{
59+
name: "with numbers",
60+
input: "hello_2_world",
61+
expected: "Hello2World",
62+
},
63+
{
64+
name: "mixed case input",
65+
input: "Hello_world_Test",
66+
expected: "HelloWorldTest",
67+
},
68+
}
69+
70+
for _, tt := range tests {
71+
t.Run(tt.name, func(t *testing.T) {
72+
result := toPascal(tt.input)
73+
if result != tt.expected {
74+
t.Errorf("toPascal(%q) = %q, want %q", tt.input, result, tt.expected)
75+
}
76+
})
77+
}
78+
}

0 commit comments

Comments
 (0)