Skip to content

Commit

Permalink
add JSON error parsing and highlighting
Browse files Browse the repository at this point in the history
  • Loading branch information
zamicol committed May 23, 2023
1 parent 25cc942 commit d105f5d
Show file tree
Hide file tree
Showing 7 changed files with 52 additions and 6 deletions.
25 changes: 24 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ installed and a config exists, simply run
watchmod
```


For system wide install with Go:

```sh
Expand Down Expand Up @@ -89,6 +88,30 @@ will result in it's exclusion.
exit, instead of running in daemon mode and listening for changes.


# JSON Errors
If command output is JSON, watchmod print the error if the JSON has the field
"success" with the bool false and/or the field "error" with a not nil value. (If
command output is not JSON it is not parsed.)

Command output that includes JSON of

```JSON
{"success":false}

```
Or
```JSON
{"error":"call had an error"}
```

Results in a log like the following:

```sh
2023/05/23 13:58:52 ⚠️ watchmod command error: test/echo_error_test.sh
{"success":false,"foo":"bar",...}
```


# Notes
- Expands environmental vars in flags and config file.
- Config support JSON5 for comments and trailing commas. Alternatively, config
Expand Down
Binary file removed cmd/watchmod
Binary file not shown.
Empty file removed test/.gitkeep
Empty file.
2 changes: 2 additions & 0 deletions test/echo_error_test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#!/usr/bin/env bash
echo '{"success":false}'
File renamed without changes.
24 changes: 22 additions & 2 deletions watchmod.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ type flags struct {
Daemon bool
}

type Config struct { // Config options setable by config file.
type Config struct { // Config options settable by config file.
WatchCommand map[string]string
ExcludeFiles []string
ExcludeStrings []string
Expand Down Expand Up @@ -141,18 +141,38 @@ func Watch(dir, cmd string) {
<-done
}

// jError is for parsing errors from JSON. If JSON, check for error by looking
// for `"success":false` and field "error" not nil. i.e.
//
// {"success":false,"msg":"call had an error","path":"/admin/job/minPage"} Or
// {"error":"call had an error","path":"/admin/job/minPage"}
type jError struct {
Success bool `json:"success,omitempty" `
Err json.RawMessage `json:"error,omitempty" `
}

func runCmd(cmd string) {
log.Printf("Start run %q\n", cmd)
start := time.Now()

commandOut := exec.Command(cmd)
stdoutStderr, err := commandOut.CombinedOutput()
if err != nil {
log.Printf("watchmod error: %s; On cmd: %s; Error: \n%s\n", err, cmd, stdoutStderr)
// See "fatih/color" for color codes: https://github.com/fatih/color/blob/f4c431696a22e834b83444f720bd144b2dbbccff/color.go#L64
log.Printf("\x1b[31m⚠️ watchmod error:\x1b[0m %s; On cmd: %s; Error: \n%s\n", err, cmd, stdoutStderr)
} else if C.PrintStdOut && len(stdoutStderr) != 0 {
log.Printf("%s", stdoutStderr)
}

// Check for JSON errors.
je := new(jError)
err = json.Unmarshal(stdoutStderr, je)
if err == nil { // Ignore errors assuming command output is not JSON.
if je.Success == false || len(je.Err) != 0 {
log.Printf("\x1b[31m⚠️ watchmod command error:\x1b[0m %s\n%s\n\n", cmd, stdoutStderr)
}
}

elapsed := time.Since(start)
log.Printf("End run %q in %s\n", cmd, elapsed)
}
Expand Down
7 changes: 4 additions & 3 deletions watchmod.json5
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
// This is a test watch config.
// Do testing with:
// `go run watchmod.go`
// `go test`

{
"WatchCommand":{
"$WATCHMOD":"$WATCHMOD/example.sh",
"$WATCHMOD/test":"$WATCHMOD/example.sh",
"$WATCHMOD":"$WATCHMOD/test/example.sh",
"$WATCHMOD/test":"$WATCHMOD/test/example.sh",
"$WATCHMOD":"$WATCHMOD/test/echo_error_test.sh",
},
"ExcludeFiles":[
"app.min.js",
Expand Down

0 comments on commit d105f5d

Please sign in to comment.