mirror of
https://github.com/neilotoole/sq.git
synced 2024-12-25 09:16:59 +03:00
PIng command json output (#141)
* cmd_ping now respects --json * ctrl-c doesn't print the cancel message for sq ping * changelog update
This commit is contained in:
parent
5d799a8820
commit
82dfd1c703
16
CHANGELOG.md
16
CHANGELOG.md
@ -5,13 +5,23 @@ All notable changes to this project will be documented in this file.
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## Unreleased
|
||||
|
||||
### Added
|
||||
|
||||
- `sq ping` now respects `--json` flag.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Improved handling of file paths on Windows.
|
||||
|
||||
## [v0.23.0] - 2022-12-31
|
||||
|
||||
### Added
|
||||
|
||||
- `sq ls` now respects `--json flag`.
|
||||
- `sq rm` now respects `--json flag`.
|
||||
- `sq add` now respects `--json flag`.
|
||||
- `sq ls` now respects `--json` flag.
|
||||
- `sq rm` now respects `--json` flag.
|
||||
- `sq add` now respects `--json` flag.
|
||||
- CI pipeline now verifies install packages after publish.
|
||||
|
||||
### Changed
|
||||
|
@ -593,6 +593,7 @@ func newWriters(log lg.Log, cmd *cobra.Command, defaults config.Defaults, out, e
|
||||
w.srcw = jsonw.NewSourceWriter(out2, fm)
|
||||
w.errw = jsonw.NewErrorWriter(log, errOut2, fm)
|
||||
w.versionw = jsonw.NewVersionWriter(out2, fm)
|
||||
w.pingw = jsonw.NewPingWriter(out2, fm)
|
||||
|
||||
case config.FormatTable:
|
||||
// Table is the base format, already set above, no need to do anything.
|
||||
@ -819,7 +820,7 @@ func printError(rc *RunContext, err error) {
|
||||
switch {
|
||||
default:
|
||||
case errors.Is(err, context.Canceled):
|
||||
err = errz.New("stopped")
|
||||
err = errz.New("canceled")
|
||||
case errors.Is(err, context.DeadlineExceeded):
|
||||
err = errz.New("timeout")
|
||||
}
|
||||
|
@ -46,6 +46,7 @@ The exit code is 1 if ping fails for any of the sources.`,
|
||||
cmd.Flags().BoolP(flagTable, flagTableShort, false, flagTableUsage)
|
||||
cmd.Flags().BoolP(flagCSV, flagCSVShort, false, flagCSVUsage)
|
||||
cmd.Flags().BoolP(flagTSV, flagTSVShort, false, flagTSVUsage)
|
||||
cmd.Flags().BoolP(flagJSON, flagJSONShort, false, flagJSONUsage)
|
||||
cmd.Flags().Duration(flagPingTimeout, time.Second*10, flagPingTimeoutUsage)
|
||||
cmd.Flags().BoolP(flagPingAll, flagPingAllShort, false, flagPingAllUsage)
|
||||
|
||||
@ -98,21 +99,28 @@ func execPing(cmd *cobra.Command, args []string) error {
|
||||
|
||||
rc.Log.Debugf("Using ping timeout value: %s", timeout)
|
||||
|
||||
return pingSources(cmd.Context(), rc.Log, rc.registry, srcs, rc.writers.pingw, timeout)
|
||||
err := pingSources(cmd.Context(), rc.Log, rc.registry, srcs, rc.writers.pingw, timeout)
|
||||
if errors.Is(err, context.Canceled) {
|
||||
// It's common to cancel "sq ping". We don't want to print the cancel message.
|
||||
return errNoMsg
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// pingSources pings each of the sources in srcs, and prints results
|
||||
// to w. If any error occurs pinging any of srcs, that error is printed
|
||||
// inline as part of the ping results, and an errNoMsg is returned.
|
||||
//
|
||||
// NOTE: This ping code has an ancient lineage, in that it was written
|
||||
//
|
||||
// originally laid down before context.Context was a thing. Thus,
|
||||
// the entire thing could probably be rewritten for simplicity.
|
||||
// NOTE: This ping code has an ancient lineage, in that it was
|
||||
// originally laid down before context.Context was a thing. Thus,
|
||||
// the entire thing could probably be rewritten for simplicity.
|
||||
func pingSources(ctx context.Context, log lg.Log, dp driver.Provider, srcs []*source.Source, w output.PingWriter,
|
||||
timeout time.Duration,
|
||||
) error {
|
||||
w.Open(srcs)
|
||||
if err := w.Open(srcs); err != nil {
|
||||
return err
|
||||
}
|
||||
defer log.WarnIfFuncError(w.Close)
|
||||
|
||||
resultCh := make(chan pingResult, len(srcs))
|
||||
@ -147,7 +155,7 @@ func pingSources(ctx context.Context, log lg.Log, dp driver.Provider, srcs []*so
|
||||
pingErrExists = true
|
||||
}
|
||||
|
||||
w.Result(result.src, result.duration, result.err)
|
||||
log.WarnIfError(w.Result(result.src, result.duration, result.err))
|
||||
}
|
||||
|
||||
// If there's at least one error, we return the
|
||||
|
@ -27,11 +27,12 @@ type pingWriter struct {
|
||||
}
|
||||
|
||||
// Open implements output.PingWriter.
|
||||
func (p *pingWriter) Open(srcs []*source.Source) {
|
||||
func (p *pingWriter) Open(srcs []*source.Source) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Result implements output.PingWriter.
|
||||
func (p *pingWriter) Result(src *source.Source, d time.Duration, err error) {
|
||||
func (p *pingWriter) Result(src *source.Source, d time.Duration, err error) error {
|
||||
rec := make([]string, 3)
|
||||
rec[0] = src.Handle
|
||||
rec[1] = d.Truncate(time.Millisecond).String()
|
||||
@ -47,6 +48,7 @@ func (p *pingWriter) Result(src *source.Source, d time.Duration, err error) {
|
||||
|
||||
_ = p.csvw.Write(rec)
|
||||
p.csvw.Flush()
|
||||
return nil
|
||||
}
|
||||
|
||||
// Close implements output.PingWriter.
|
||||
|
59
cli/output/jsonw/pingwriter.go
Normal file
59
cli/output/jsonw/pingwriter.go
Normal file
@ -0,0 +1,59 @@
|
||||
package jsonw
|
||||
|
||||
import (
|
||||
"io"
|
||||
"time"
|
||||
|
||||
"github.com/neilotoole/sq/cli/output"
|
||||
"github.com/neilotoole/sq/cli/output/jsonw/internal"
|
||||
jcolorenc "github.com/neilotoole/sq/cli/output/jsonw/internal/jcolorenc"
|
||||
"github.com/neilotoole/sq/libsq/core/errz"
|
||||
"github.com/neilotoole/sq/libsq/source"
|
||||
)
|
||||
|
||||
var _ output.PingWriter = (*pingWriter)(nil)
|
||||
|
||||
// NewPingWriter returns JSON impl of output.PingWriter.
|
||||
func NewPingWriter(out io.Writer, fm *output.Formatting) output.PingWriter {
|
||||
return &pingWriter{out: out, fm: fm}
|
||||
}
|
||||
|
||||
type pingWriter struct {
|
||||
out io.Writer
|
||||
fm *output.Formatting
|
||||
}
|
||||
|
||||
// Open implements output.PingWriter.
|
||||
func (p pingWriter) Open(srcs []*source.Source) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Result implements output.PingWriter.
|
||||
func (p pingWriter) Result(src *source.Source, d time.Duration, err error) error {
|
||||
r := struct {
|
||||
*source.Source
|
||||
Pong bool `json:"pong"`
|
||||
Duration time.Duration `json:"duration"`
|
||||
Error string `json:"error,omitempty"`
|
||||
}{
|
||||
Source: src,
|
||||
Pong: err == nil,
|
||||
Duration: d,
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
r.Error = err.Error()
|
||||
}
|
||||
|
||||
enc := jcolorenc.NewEncoder(p.out)
|
||||
enc.SetColors(internal.NewColors(p.fm))
|
||||
enc.SetEscapeHTML(false)
|
||||
enc.SetIndent("", " ")
|
||||
|
||||
return errz.Err(enc.Encode(r))
|
||||
}
|
||||
|
||||
// Close implements output.PingWriter.
|
||||
func (p pingWriter) Close() error {
|
||||
return nil
|
||||
}
|
@ -28,15 +28,16 @@ type PingWriter struct {
|
||||
handleWidthMax int
|
||||
}
|
||||
|
||||
func (w *PingWriter) Open(srcs []*source.Source) {
|
||||
func (w *PingWriter) Open(srcs []*source.Source) error {
|
||||
for _, src := range srcs {
|
||||
if len(src.Handle) > w.handleWidthMax {
|
||||
w.handleWidthMax = len(src.Handle)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (w *PingWriter) Result(src *source.Source, d time.Duration, err error) {
|
||||
func (w *PingWriter) Result(src *source.Source, d time.Duration, err error) error {
|
||||
w.fm.Number.Fprintf(w.out, "%-"+strconv.Itoa(w.handleWidthMax)+"s", src.Handle)
|
||||
fmt.Fprintf(w.out, "%10s ", d.Truncate(time.Millisecond).String())
|
||||
|
||||
@ -60,6 +61,7 @@ func (w *PingWriter) Result(src *source.Source, d time.Duration, err error) {
|
||||
}
|
||||
|
||||
fmt.Fprintf(w.out, "\n")
|
||||
return nil
|
||||
}
|
||||
|
||||
func (w *PingWriter) Close() error {
|
||||
|
@ -74,12 +74,12 @@ type ErrorWriter interface {
|
||||
// PingWriter writes ping results.
|
||||
type PingWriter interface {
|
||||
// Open opens the writer to write the supplied sources.
|
||||
Open(srcs []*source.Source)
|
||||
Open(srcs []*source.Source) error
|
||||
|
||||
// Result prints a ping result. The ping succeeded if
|
||||
// err is nil. If err is context.DeadlineExceeded, the d
|
||||
// arg will be the timeout value.
|
||||
Result(src *source.Source, d time.Duration, err error)
|
||||
Result(src *source.Source, d time.Duration, err error) error
|
||||
|
||||
// Close is called after all results have been received.
|
||||
Close() error
|
||||
|
Loading…
Reference in New Issue
Block a user