@@ -22,6 +22,17 @@ import (
2222 "github.com/miekg/dns"
2323)
2424
25+ var version = "v1.0.0"
26+
27+ const (
28+ colorReset = "\033 [0m"
29+ colorBold = "\033 [1m"
30+ colorDim = "\033 [2m"
31+ colorGreen = "\033 [32m"
32+ colorRed = "\033 [31m"
33+ colorCyan = "\033 [36m"
34+ )
35+
2536func main () {
2637 if len (os .Args ) < 2 {
2738 fmt .Fprintln (os .Stderr , "usage: devproxy <command>" )
@@ -104,6 +115,17 @@ func runDown() {
104115}
105116
106117func runStatus () {
118+ jsonFlag := false
119+ verboseFlag := false
120+ for _ , arg := range os .Args [2 :] {
121+ switch arg {
122+ case "--json" :
123+ jsonFlag = true
124+ case "--verbose" , "-v" :
125+ verboseFlag = true
126+ }
127+ }
128+
107129 client := unixClient ("/run/devproxy/devproxy.sock" )
108130 resp , err := client .Get ("http://devproxy/status" )
109131 if err != nil {
@@ -112,7 +134,6 @@ func runStatus() {
112134 }
113135 defer resp .Body .Close ()
114136
115- jsonFlag := len (os .Args ) > 2 && os .Args [2 ] == "--json"
116137 if jsonFlag {
117138 var raw json.RawMessage
118139 json .NewDecoder (resp .Body ).Decode (& raw )
@@ -136,21 +157,63 @@ func runStatus() {
136157 json .NewDecoder (resp .Body ).Decode (& result )
137158
138159 if len (result .Projects ) == 0 {
139- fmt .Println ("No active projects" )
160+ fmt .Println ()
161+ fmt .Printf (" %sNo projects running.%s\n " , colorDim , colorReset )
162+ fmt .Printf (" Start a docker-compose project to get started.\n " )
163+ fmt .Println ()
140164 return
141165 }
142166
143- fmt . Printf ( "%-20s %-15s %-30s %-15s \n " , "PROJECT" , "SERVICE" , "WSL2" , "WINDOWS IP" )
167+ totalServices := 0
144168 for _ , p := range result .Projects {
145- for _ , port := range p .Ports {
146- fmt .Printf ("%-20s %-15s %-30s %-15s\n " ,
147- p .Name ,
148- port .Service ,
149- fmt .Sprintf ("%s.localhost:%d" , p .Name , port .Container ),
150- fmt .Sprintf ("%s:%d" , p .WindowsIP , port .Container ),
151- )
169+ totalServices += len (p .Ports )
170+ }
171+
172+ fmt .Println ()
173+ fmt .Printf (" %sdevproxy%s %s%s%s · %d projects · %d services\n " ,
174+ colorBold , colorReset , colorDim , version , colorReset ,
175+ len (result .Projects ), totalServices )
176+ fmt .Println ()
177+
178+ if verboseFlag {
179+ fmt .Printf (" %s SERVICE ENDPOINT WINDOWS%s\n " , colorDim , colorReset )
180+ } else {
181+ fmt .Printf (" %s SERVICE ENDPOINT%s\n " , colorDim , colorReset )
182+ }
183+
184+ for i , p := range result .Projects {
185+ fmt .Printf (" %s%s%s %s· %s%s\n " ,
186+ colorBold , p .Name , colorReset ,
187+ colorDim , p .IP , colorReset )
188+
189+ for j , port := range p .Ports {
190+ connector := "├─"
191+ if j == len (p .Ports )- 1 {
192+ connector = "└─"
193+ }
194+
195+ endpoint := fmt .Sprintf ("%s.localhost:%d" , p .Name , port .Container )
196+
197+ if verboseFlag {
198+ winEndpoint := fmt .Sprintf ("%s:%d" , p .WindowsIP , port .Container )
199+ fmt .Printf (" %s %s●%s %-20s %s%-33s%s %s%s%s\n " ,
200+ connector , colorGreen , colorReset ,
201+ port .Service ,
202+ colorCyan , endpoint , colorReset ,
203+ colorDim , winEndpoint , colorReset )
204+ } else {
205+ fmt .Printf (" %s %s●%s %-20s %s%s%s\n " ,
206+ connector , colorGreen , colorReset ,
207+ port .Service ,
208+ colorCyan , endpoint , colorReset )
209+ }
210+ }
211+
212+ if i < len (result .Projects )- 1 {
213+ fmt .Println ()
152214 }
153215 }
216+ fmt .Println ()
154217}
155218
156219func runCleanup () {
@@ -255,13 +318,14 @@ func runDoctor() {
255318 allPassed := true
256319 dnsDirectOK := false
257320
321+ fmt .Println ()
258322 for _ , c := range checks {
259323 err := c .fn ()
260324 if err != nil {
261- fmt .Printf (" [FAIL] %s: %v\n " , c .name , err )
325+ fmt .Printf (" %s✗%s %s: %v\n " , colorRed , colorReset , c .name , err )
262326 allPassed = false
263327 } else {
264- fmt .Printf (" [ OK ] %s\n " , c .name )
328+ fmt .Printf (" %s✓%s %s\n " , colorGreen , colorReset , c .name )
265329 if c .name == "DNS server (127.0.53.53)" {
266330 dnsDirectOK = true
267331 }
@@ -273,19 +337,19 @@ func runDoctor() {
273337 // Check if resolved was the one that failed
274338 if err := checkResolved (); err != nil {
275339 fmt .Println ()
276- fmt .Println (" Hint: DNS server is running but systemd-resolved cannot resolve" )
277- fmt .Println (" devproxy domains. Check that /etc/systemd/resolved.conf.d/" )
278- fmt .Println (" has the correct devproxy DNS delegation configuration." )
340+ fmt .Printf (" %sHint: DNS server is running but systemd-resolved cannot resolve%s\n " , colorDim , colorReset )
341+ fmt .Printf (" %sdevproxy domains. Check /etc/systemd/resolved.conf.d/ config.%s\n " , colorDim , colorReset )
279342 }
280343 }
281344
282345 fmt .Println ()
283346 if allPassed {
284- fmt .Println ( "All checks passed." )
347+ fmt .Printf ( " %s%sAll checks passed.%s \n " , colorBold , colorGreen , colorReset )
285348 } else {
286- fmt .Println ( "Some checks failed. See above for details." )
349+ fmt .Printf ( " %sSome checks failed. See above for details.%s \n " , colorRed , colorReset )
287350 os .Exit (1 )
288351 }
352+ fmt .Println ()
289353}
290354
291355// getWSLIP returns the WSL2 eth0 IPv4 address.
0 commit comments