Skip to content

Commit

Permalink
Work in progress: experimentation with console output
Browse files Browse the repository at this point in the history
Several open issues mention problems with interaction of the
global `--encoding=` flag and the Encoders and PostRun fields of
command structs. This branch contains experimental refactors that
explore approaches to consistent command execution patterns across
offline, online and http modes.

Specific tickets:

- ipfs/kubo#7050 json encoding for `ls`
- ipfs/kubo#1121 json encoding for `add`
- ipfs/kubo#5594 json encoding for `stats bw`
- ipfs#115 postrun design

Possibly related:

- ipfs/kubo#6640 global flags on subcommands

Incomplete PRs:

- ipfs/kubo#5620 json for 'stat'
  • Loading branch information
Jesse Bouwman committed Aug 19, 2021
1 parent 744f3b3 commit c925c16
Show file tree
Hide file tree
Showing 5 changed files with 29 additions and 22 deletions.
10 changes: 0 additions & 10 deletions cli/parse.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,16 +45,6 @@ func Parse(ctx context.Context, input []string, stdin *os.File, root *cmds.Comma
return req, err
}

// if no encoding was specified by user, default to plaintext encoding
// (if command doesn't support plaintext, use JSON instead)
if enc := req.Options[cmds.EncLong]; enc == "" {
if req.Command.Encoders != nil && req.Command.Encoders[cmds.Text] != nil {
req.SetOption(cmds.EncLong, cmds.Text)
} else {
req.SetOption(cmds.EncLong, cmds.JSON)
}
}

return req, nil
}

Expand Down
10 changes: 0 additions & 10 deletions cli/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,6 @@ func Run(ctx context.Context, root *cmds.Command,
return nil
}

cmd := req.Command

env, err := buildEnv(req.Context, req)
if err != nil {
printErr(err)
Expand All @@ -119,14 +117,6 @@ func Run(ctx context.Context, root *cmds.Command,
return err
}

encTypeStr, _ := req.Options[cmds.EncLong].(string)
encType := cmds.EncodingType(encTypeStr)

// use JSON if text was requested but the command doesn't have a text-encoder
if _, ok := cmd.Encoders[encType]; encType == cmds.Text && !ok {
req.Options[cmds.EncLong] = cmds.JSON
}

re, err := NewResponseEmitter(stdout, stderr, req)
if err != nil {
printErr(err)
Expand Down
9 changes: 9 additions & 0 deletions command.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ package cmds
import (
"errors"
"fmt"
"io"
"strings"

files "github.com/ipfs/go-ipfs-files"
Expand All @@ -30,6 +31,10 @@ type Function func(*Request, ResponseEmitter, Environment) error
// PostRunMap is the map used in Command.PostRun.
type PostRunMap map[PostRunType]func(Response, ResponseEmitter) error

// DisplayCLI supplies an function for console output in local
// processes in combination with a text Encoder.
type DisplayCLI func(res Response, stdout, stderr io.Writer) error

// Command is a runnable command, with input arguments and options (flags).
// It can also have Subcommands, to group units of work into sets.
type Command struct {
Expand Down Expand Up @@ -62,6 +67,10 @@ type Command struct {
// the local process.
PostRun PostRunMap

// DisplayCLI is for text output in local process in
// combination with 'text' Encoder.
DisplayCLI DisplayCLI

// Encoders encode results from Run (and/or PostRun) in the desired
// encoding.
Encoders EncoderMap
Expand Down
16 changes: 14 additions & 2 deletions executor.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package cmds

import (
"context"
"os"
)

type Executor interface {
Expand Down Expand Up @@ -51,9 +52,20 @@ func (x *executor) Execute(req *Request, re ResponseEmitter, env Environment) er
}
}

// contains the error returned by PostRun
// contains the error returned by DisplayCLI or PostRun
errCh := make(chan error, 1)
if cmd.PostRun != nil {
if cmd.DisplayCLI != nil && GetEncoding(req, "json") == "text" {
var (
res Response
)

re, res = NewChanResponsePair(req)

go func() {
defer close(errCh)
errCh <- cmd.DisplayCLI(res, os.Stdout, os.Stderr)
}()
} else if cmd.PostRun != nil {
if typer, ok := re.(interface {
Type() PostRunType
}); ok && cmd.PostRun[typer.Type()] != nil {
Expand Down
6 changes: 6 additions & 0 deletions http/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"net"
"net/http"
"net/url"
"os"
"strings"

"github.com/ipfs/go-ipfs-cmds"
Expand Down Expand Up @@ -132,6 +133,11 @@ func (c *client) Execute(req *cmds.Request, re cmds.ResponseEmitter, env cmds.En
}
}

if cmd.DisplayCLI != nil &&
cmds.GetEncoding(req, cmds.Undefined) == cmds.Text {
return cmd.DisplayCLI(res, os.Stdout, os.Stderr)
}

return cmds.Copy(re, res)
}

Expand Down

0 comments on commit c925c16

Please sign in to comment.