|
5 | 5 | package main
|
6 | 6 |
|
7 | 7 | import (
|
8 |
| - "fmt" |
9 |
| - "github.com/zhgo/console" |
10 |
| - "os" |
11 |
| - "os/exec" |
12 |
| - "path/filepath" |
13 |
| - "runtime" |
14 |
| - "time" |
| 8 | + "fmt" |
| 9 | + "os" |
| 10 | + "os/exec" |
| 11 | + "path/filepath" |
| 12 | + "runtime" |
| 13 | + "strings" |
| 14 | + "time" |
| 15 | + |
| 16 | + "github.com/zhgo/console" |
15 | 17 | )
|
16 | 18 |
|
17 | 19 | //Dogo struct
|
18 | 20 | type Dogo struct {
|
19 |
| - //source files |
20 |
| - SourceDir []string |
| 21 | + //source files |
| 22 | + SourceDir []string |
21 | 23 |
|
22 |
| - //source files |
23 |
| - sourceDir []string |
| 24 | + //source files |
| 25 | + sourceDir []string |
24 | 26 |
|
25 |
| - //file extends |
26 |
| - SourceExt []string |
| 27 | + //file extends |
| 28 | + SourceExt []string |
27 | 29 |
|
28 |
| - //Working Dir |
29 |
| - WorkingDir string |
| 30 | + //Working Dir |
| 31 | + WorkingDir string |
30 | 32 |
|
31 |
| - //build command |
32 |
| - BuildCmd string |
| 33 | + //build command |
| 34 | + BuildCmd string |
33 | 35 |
|
34 |
| - //run command |
35 |
| - RunCmd string |
| 36 | + //run command |
| 37 | + RunCmd string |
36 | 38 |
|
37 |
| - //Decreasing |
38 |
| - Decreasing uint8 |
| 39 | + //Decreasing |
| 40 | + Decreasing uint8 |
39 | 41 |
|
40 |
| - //file list |
41 |
| - Files map[string]time.Time |
| 42 | + //file list |
| 43 | + Files map[string]time.Time |
42 | 44 |
|
43 |
| - //Cmd object |
44 |
| - cmd *exec.Cmd |
| 45 | + //Ignored |
| 46 | + Ignored []string |
45 | 47 |
|
46 |
| - //file modified |
47 |
| - isModified bool |
| 48 | + //Cmd object |
| 49 | + cmd *exec.Cmd |
| 50 | + |
| 51 | + //file modified |
| 52 | + isModified bool |
48 | 53 | }
|
49 | 54 |
|
50 | 55 | //start new monitor
|
51 | 56 | func (d *Dogo) NewMonitor() {
|
52 |
| - if d.WorkingDir == "" { |
53 |
| - d.WorkingDir = console.WorkingDir |
54 |
| - } |
55 |
| - if len(d.SourceDir) == 0 { |
56 |
| - d.SourceDir = append(d.SourceDir, console.WorkingDir) |
57 |
| - } |
58 |
| - if d.SourceExt == nil || len(d.SourceExt) == 0 { |
59 |
| - d.SourceExt = []string{".c", ".cpp", ".go", ".h"} |
60 |
| - } |
61 |
| - if d.BuildCmd == "" { |
62 |
| - d.BuildCmd = "go build ." |
63 |
| - } |
64 |
| - if d.RunCmd == "" { |
65 |
| - d.RunCmd = filepath.Base(console.WorkingDir) |
66 |
| - if runtime.GOOS == "windows" { |
67 |
| - d.RunCmd += ".exe" |
68 |
| - } |
69 |
| - } |
70 |
| - |
71 |
| - // Append the current directory to the PATH for compatible linux. |
72 |
| - console.Setenv("PATH", console.Getenv("PATH")+string(os.PathListSeparator)+d.WorkingDir) |
73 |
| - |
74 |
| - console.Chdir(d.WorkingDir) |
75 |
| - fmt.Printf("[dogo] Working Directory:\n") |
76 |
| - fmt.Printf(" %s\n", d.WorkingDir) |
77 |
| - |
78 |
| - fmt.Printf("[dogo] Monitoring Directories:\n") |
79 |
| - for _, dir := range d.SourceDir { |
80 |
| - fmt.Printf(" %s\n", dir) |
81 |
| - } |
82 |
| - |
83 |
| - fmt.Printf("[dogo] File extends:\n") |
84 |
| - fmt.Printf(" %s\n", d.SourceExt) |
85 |
| - |
86 |
| - fmt.Printf("[dogo] Build command:\n") |
87 |
| - fmt.Printf(" %s\n", d.BuildCmd) |
88 |
| - |
89 |
| - fmt.Printf("[dogo] Run command:\n") |
90 |
| - fmt.Printf(" %s\n", d.RunCmd) |
91 |
| - |
92 |
| - d.Files = make(map[string]time.Time) |
93 |
| - d.InitFiles() |
94 |
| - |
95 |
| - //TODO: add console support. |
96 |
| - //TODO: Multi commands. |
| 57 | + if d.WorkingDir == "" { |
| 58 | + d.WorkingDir = console.WorkingDir |
| 59 | + } |
| 60 | + if len(d.SourceDir) == 0 { |
| 61 | + d.SourceDir = append(d.SourceDir, console.WorkingDir) |
| 62 | + } |
| 63 | + if d.SourceExt == nil || len(d.SourceExt) == 0 { |
| 64 | + d.SourceExt = []string{".c", ".cpp", ".go", ".h"} |
| 65 | + } |
| 66 | + if d.BuildCmd == "" { |
| 67 | + d.BuildCmd = "go build ." |
| 68 | + } |
| 69 | + if d.RunCmd == "" { |
| 70 | + d.RunCmd = filepath.Base(console.WorkingDir) |
| 71 | + if runtime.GOOS == "windows" { |
| 72 | + d.RunCmd += ".exe" |
| 73 | + } |
| 74 | + } |
| 75 | + |
| 76 | + // Append the current directory to the PATH for compatible linux. |
| 77 | + console.Setenv("PATH", console.Getenv("PATH")+string(os.PathListSeparator)+d.WorkingDir) |
| 78 | + |
| 79 | + console.Chdir(d.WorkingDir) |
| 80 | + fmt.Printf("[dogo] Working Directory:\n") |
| 81 | + fmt.Printf(" %s\n", d.WorkingDir) |
| 82 | + |
| 83 | + if len(d.Ignored) > 0 { |
| 84 | + fmt.Printf("[dogo] Ignoring:\n") |
| 85 | + for i, ignored := range d.Ignored { |
| 86 | + if !filepath.IsAbs(ignored) { |
| 87 | + absPath, err := filepath.Abs(ignored) |
| 88 | + if err != nil { |
| 89 | + fmt.Printf("Resource %s not found, skipping", ignored) |
| 90 | + } else { |
| 91 | + d.Ignored[i] = absPath |
| 92 | + fmt.Printf(" %s\n", d.Ignored[i]) |
| 93 | + } |
| 94 | + } |
| 95 | + } |
| 96 | + } |
| 97 | + |
| 98 | + fmt.Printf("[dogo] Monitoring Directories:\n") |
| 99 | + for _, dir := range d.SourceDir { |
| 100 | + fmt.Printf(" %s\n", dir) |
| 101 | + } |
| 102 | + |
| 103 | + fmt.Printf("[dogo] File extends:\n") |
| 104 | + fmt.Printf(" %s\n", d.SourceExt) |
| 105 | + |
| 106 | + fmt.Printf("[dogo] Build command:\n") |
| 107 | + fmt.Printf(" %s\n", d.BuildCmd) |
| 108 | + |
| 109 | + fmt.Printf("[dogo] Run command:\n") |
| 110 | + fmt.Printf(" %s\n", d.RunCmd) |
| 111 | + |
| 112 | + d.Files = make(map[string]time.Time) |
| 113 | + d.InitFiles() |
| 114 | + |
| 115 | + //TODO: add console support. |
| 116 | + //TODO: Multi commands. |
97 | 117 | }
|
98 | 118 |
|
99 | 119 | func (d *Dogo) InitFiles() {
|
100 |
| - //scan source directories |
101 |
| - for _, dir := range d.SourceDir { |
102 |
| - filepath.Walk(dir, func(path string, f os.FileInfo, err error) error { |
103 |
| - if err != nil { |
104 |
| - fmt.Printf("%s\n", err) |
105 |
| - return err |
106 |
| - } |
107 |
| - |
108 |
| - if f.IsDir() { |
109 |
| - d.sourceDir = append(d.sourceDir, path) |
110 |
| - } |
111 |
| - |
112 |
| - for _, ext := range d.SourceExt { |
113 |
| - if filepath.Ext(path) == ext { |
114 |
| - d.Files[path] = f.ModTime() |
115 |
| - break |
116 |
| - } |
117 |
| - } |
118 |
| - |
119 |
| - return nil |
120 |
| - }) |
121 |
| - } |
| 120 | + //scan source directories |
| 121 | + for _, dir := range d.SourceDir { |
| 122 | + filepath.Walk(dir, func(path string, f os.FileInfo, err error) error { |
| 123 | + if err != nil { |
| 124 | + fmt.Printf("%s\n", err) |
| 125 | + return err |
| 126 | + } |
| 127 | + |
| 128 | + if f.IsDir() { |
| 129 | + if d.isDirectoryIgnored(path) { |
| 130 | + return nil |
| 131 | + } |
| 132 | + d.sourceDir = append(d.sourceDir, path) |
| 133 | + } else { |
| 134 | + if d.isFileIgnored(path) { |
| 135 | + return nil |
| 136 | + } |
| 137 | + } |
| 138 | + |
| 139 | + for _, ext := range d.SourceExt { |
| 140 | + if filepath.Ext(path) == ext { |
| 141 | + d.Files[path] = f.ModTime() |
| 142 | + break |
| 143 | + } |
| 144 | + } |
| 145 | + |
| 146 | + return nil |
| 147 | + }) |
| 148 | + } |
122 | 149 | }
|
123 | 150 |
|
124 | 151 | func (d *Dogo) BuildAndRun() {
|
125 |
| - if d.cmd != nil && d.cmd.Process != nil { |
126 |
| - fmt.Printf("[dogo] Terminate the process %d: ", d.cmd.Process.Pid) |
127 |
| - |
128 |
| - if err := d.cmd.Process.Kill(); err != nil { |
129 |
| - fmt.Printf("\n%s %s\n", d.cmd.ProcessState.String(), err) |
130 |
| - } else { |
131 |
| - fmt.Printf("%s\n", d.cmd.ProcessState.String()) |
132 |
| - } |
133 |
| - } |
134 |
| - |
135 |
| - if err := d.Build(); err != nil { |
136 |
| - fmt.Printf("[dogo] Build failed: %s\n\n", err) |
137 |
| - } else { |
138 |
| - fmt.Printf("[dogo] Start the process: %s\n\n", d.RunCmd) |
139 |
| - go d.Run() |
140 |
| - } |
| 152 | + if d.cmd != nil && d.cmd.Process != nil { |
| 153 | + fmt.Printf("[dogo] Terminate the process %d: ", d.cmd.Process.Pid) |
| 154 | + |
| 155 | + if err := d.cmd.Process.Kill(); err != nil { |
| 156 | + fmt.Printf("\n%s %s\n", d.cmd.ProcessState.String(), err) |
| 157 | + } else { |
| 158 | + fmt.Printf("%s\n", d.cmd.ProcessState.String()) |
| 159 | + } |
| 160 | + } |
| 161 | + |
| 162 | + if err := d.Build(); err != nil { |
| 163 | + fmt.Printf("[dogo] Build failed: %s\n\n", err) |
| 164 | + } else { |
| 165 | + fmt.Printf("[dogo] Start the process: %s\n\n", d.RunCmd) |
| 166 | + go d.Run() |
| 167 | + } |
141 | 168 | }
|
142 | 169 |
|
143 | 170 | //build
|
144 | 171 | func (d *Dogo) Build() error {
|
145 |
| - fmt.Printf("[dogo] Start build: ") |
| 172 | + fmt.Printf("[dogo] Start build: ") |
146 | 173 |
|
147 |
| - args := console.ParseText(d.BuildCmd) |
148 |
| - out, err := exec.Command(args[0], args[1:]...).CombinedOutput() |
149 |
| - if err != nil { |
150 |
| - fmt.Printf("\n%s", string(out)) |
151 |
| - return err |
152 |
| - } |
| 174 | + args := console.ParseText(d.BuildCmd) |
| 175 | + out, err := exec.Command(args[0], args[1:]...).CombinedOutput() |
| 176 | + if err != nil { |
| 177 | + fmt.Printf("\n%s", string(out)) |
| 178 | + return err |
| 179 | + } |
153 | 180 |
|
154 |
| - fmt.Printf("success.\n") |
155 |
| - return nil |
| 181 | + fmt.Printf("success.\n") |
| 182 | + return nil |
156 | 183 | }
|
157 | 184 |
|
158 | 185 | //run it
|
159 | 186 | func (d *Dogo) Run() {
|
160 |
| - args := console.ParseText(d.RunCmd) |
161 |
| - |
162 |
| - d.cmd = exec.Command(args[0], args[1:]...) |
163 |
| - d.cmd.Stdin = os.Stdin |
164 |
| - d.cmd.Stdout = os.Stdout |
165 |
| - d.cmd.Stderr = os.Stderr |
166 |
| - err := d.cmd.Run() |
167 |
| - if err != nil { |
168 |
| - fmt.Printf("%s\n", err) |
169 |
| - } |
170 |
| - |
171 |
| - d.cmd = nil |
| 187 | + args := console.ParseText(d.RunCmd) |
| 188 | + |
| 189 | + d.cmd = exec.Command(args[0], args[1:]...) |
| 190 | + d.cmd.Stdin = os.Stdin |
| 191 | + d.cmd.Stdout = os.Stdout |
| 192 | + d.cmd.Stderr = os.Stderr |
| 193 | + err := d.cmd.Run() |
| 194 | + if err != nil { |
| 195 | + fmt.Printf("%s\n", err) |
| 196 | + } |
| 197 | + |
| 198 | + d.cmd = nil |
| 199 | +} |
| 200 | + |
| 201 | +func (d *Dogo) isDirectoryIgnored(path string) bool { |
| 202 | + for _, ignored := range d.Ignored { |
| 203 | + if ignored == path { |
| 204 | + return true |
| 205 | + } |
| 206 | + } |
| 207 | + return false |
| 208 | +} |
| 209 | + |
| 210 | +func (d *Dogo) isFileIgnored(path string) bool { |
| 211 | + for _, ignored := range d.Ignored { |
| 212 | + if strings.HasPrefix(path, ignored) { |
| 213 | + return true |
| 214 | + } |
| 215 | + } |
| 216 | + return false |
172 | 217 | }
|
0 commit comments