@cryptotaxi247 / kubo / commits / c24a08be2

delete dead code

This code was making it *really* hard to understand the commands code. License: MIT Signed-off-by: Steven Allen <steven@stebalien.com>

Steven Allen committed Mar 16, 2018 at 11:00 UTC c24a08be2ebb91d1c472442561b5369583c1177f
7 files changed -1068
commands/channelmarshaler.go deleted
-44
@@ -1,44 +0,0 @@
1 -package commands
2 -
3 -import (
4 - "io"
5 -)
6 -
7 -type ChannelMarshaler struct {
8 - Channel <-chan interface{}
9 - Marshaler func(interface{}) (io.Reader, error)
10 - Res Response
11 -
12 - reader io.Reader
13 -}
14 -
15 -func (cr *ChannelMarshaler) Read(p []byte) (int, error) {
16 - if cr.reader == nil {
17 - val, more := <-cr.Channel
18 - if !more {
19 - //check error in response
20 - if cr.Res.Error() != nil {
21 - return 0, cr.Res.Error()
22 - }
23 - return 0, io.EOF
24 - }
25 -
26 - r, err := cr.Marshaler(val)
27 - if err != nil {
28 - return 0, err
29 - }
30 - if r == nil {
31 - return 0, nil
32 - }
33 - cr.reader = r
34 - }
35 -
36 - n, err := cr.reader.Read(p)
37 - if err != nil && err != io.EOF {
38 - return n, err
39 - }
40 - if n == 0 {
41 - cr.reader = nil
42 - }
43 - return n, nil
44 -}
commands/command.go
-228
@@ -9,15 +9,9 @@ output to the user, including text, JSON, and XML marshallers.
9 package commands
10
11 import (
12 - "errors"
13 - "fmt"
12 "io"
15 - "reflect"
16 -
17 - "github.com/ipfs/go-ipfs/path"
13
14 logging "gx/ipfs/QmRb5jh8z2E8hMGN2tkvs1yHynUanqnZ3UeKwgN1i9P1F8/go-log"
20 - cmds "gx/ipfs/QmabLouZTZwhfALuBcssPvkzhbYGMb4394huT7HY4LQ6d3/go-ipfs-cmds"
15 cmdkit "gx/ipfs/QmceUdzxkimdYsgtX733uNgzf1DLHyBKN6ehGSp85ayppM/go-ipfs-cmdkit"
16 )
17
@@ -64,233 +58,11 @@ type Command struct {
58 Subcommands map[string]*Command
59 }
60
67 -// ErrNotCallable signals a command that cannot be called.
68 -var ErrNotCallable = ClientError("This command can't be called directly. Try one of its subcommands.")
69 -
70 -var ErrNoFormatter = ClientError("This command cannot be formatted to plain text")
71 -
72 -var ErrIncorrectType = errors.New("The command returned a value with a different type than expected")
73 -
74 -// Call invokes the command for the given Request
75 -func (c *Command) Call(req Request) Response {
76 - res := NewResponse(req)
77 -
78 - cmds, err := c.Resolve(req.Path())
79 - if err != nil {
80 - res.SetError(err, cmdkit.ErrClient)
81 - return res
82 - }
83 - cmd := cmds[len(cmds)-1]
84 -
85 - if cmd.Run == nil {
86 - res.SetError(ErrNotCallable, cmdkit.ErrClient)
87 - return res
88 - }
89 -
90 - err = cmd.CheckArguments(req)
91 - if err != nil {
92 - res.SetError(err, cmdkit.ErrClient)
93 - return res
94 - }
95 -
96 - err = req.ConvertOptions()
97 - if err != nil {
98 - res.SetError(err, cmdkit.ErrClient)
99 - return res
100 - }
101 -
102 - cmd.Run(req, res)
103 - if res.Error() != nil {
104 - return res
105 - }
106 -
107 - output := res.Output()
108 - isChan := false
109 - actualType := reflect.TypeOf(output)
110 - if actualType != nil {
111 - if actualType.Kind() == reflect.Ptr {
112 - actualType = actualType.Elem()
113 - }
114 -
115 - // test if output is a channel
116 - isChan = actualType.Kind() == reflect.Chan
117 - }
118 -
119 - // If the command specified an output type, ensure the actual value
120 - // returned is of that type
121 - if cmd.Type != nil && !isChan {
122 - expectedType := reflect.TypeOf(cmd.Type)
123 -
124 - if actualType != expectedType {
125 - res.SetError(ErrIncorrectType, cmdkit.ErrNormal)
126 - return res
127 - }
128 - }
129 -
130 - return res
131 -}
132 -
133 -// Resolve returns the subcommands at the given path
134 -func (c *Command) Resolve(pth []string) ([]*Command, error) {
135 - cmds := make([]*Command, len(pth)+1)
136 - cmds[0] = c
137 -
138 - cmd := c
139 - for i, name := range pth {
140 - cmd = cmd.Subcommand(name)
141 -
142 - if cmd == nil {
143 - pathS := path.Join(pth[:i])
144 - return nil, fmt.Errorf("Undefined command: '%s'", pathS)
145 - }
146 -
147 - cmds[i+1] = cmd
148 - }
149 -
150 - return cmds, nil
151 -}
152 -
153 -// Get resolves and returns the Command addressed by path
154 -func (c *Command) Get(path []string) (*Command, error) {
155 - cmds, err := c.Resolve(path)
156 - if err != nil {
157 - return nil, err
158 - }
159 - return cmds[len(cmds)-1], nil
160 -}
161 -
162 -// GetOptions returns the options in the given path of commands
163 -func (c *Command) GetOptions(path []string) (map[string]cmdkit.Option, error) {
164 - options := make([]cmdkit.Option, 0, len(c.Options))
165 -
166 - cmds, err := c.Resolve(path)
167 - if err != nil {
168 - return nil, err
169 - }
170 - cmds = append(cmds, globalCommand)
171 -
172 - for _, cmd := range cmds {
173 - options = append(options, cmd.Options...)
174 - }
175 -
176 - optionsMap := make(map[string]cmdkit.Option)
177 - for _, opt := range options {
178 - for _, name := range opt.Names() {
179 - if _, found := optionsMap[name]; found {
180 - return nil, fmt.Errorf("Option name '%s' used multiple times", name)
181 - }
182 -
183 - optionsMap[name] = opt
184 - }
185 - }
186 -
187 - return optionsMap, nil
188 -}
189 -
190 -func (c *Command) CheckArguments(req Request) error {
191 - args := req.(*request).arguments
192 -
193 - // count required argument definitions
194 - numRequired := 0
195 - for _, argDef := range c.Arguments {
196 - if argDef.Required {
197 - numRequired++
198 - }
199 - }
200 -
201 - // iterate over the arg definitions
202 - valueIndex := 0 // the index of the current value (in `args`)
203 - for i, argDef := range c.Arguments {
204 - // skip optional argument definitions if there aren't
205 - // sufficient remaining values
206 - if len(args)-valueIndex <= numRequired && !argDef.Required ||
207 - argDef.Type == cmdkit.ArgFile {
208 - continue
209 - }
210 -
211 - // the value for this argument definition. can be nil if it
212 - // wasn't provided by the caller
213 - v, found := "", false
214 - if valueIndex < len(args) {
215 - v = args[valueIndex]
216 - found = true
217 - valueIndex++
218 - }
219 -
220 - // in the case of a non-variadic required argument that supports stdin
221 - if !found && len(c.Arguments)-1 == i && argDef.SupportsStdin {
222 - found = true
223 - }
224 -
225 - err := checkArgValue(v, found, argDef)
226 - if err != nil {
227 - return err
228 - }
229 -
230 - // any additional values are for the variadic arg definition
231 - if argDef.Variadic && valueIndex < len(args)-1 {
232 - for _, val := range args[valueIndex:] {
233 - err := checkArgValue(val, true, argDef)
234 - if err != nil {
235 - return err
236 - }
237 - }
238 - }
239 - }
240 -
241 - return nil
242 -}
243 -
61 // Subcommand returns the subcommand with the given id
62 func (c *Command) Subcommand(id string) *Command {
63 return c.Subcommands[id]
64 }
65
249 -type CommandVisitor func(*Command)
250 -
251 -// Walks tree of all subcommands (including this one)
252 -func (c *Command) Walk(visitor CommandVisitor) {
253 - visitor(c)
254 - for _, cm := range c.Subcommands {
255 - cm.Walk(visitor)
256 - }
257 -}
258 -
259 -func (c *Command) ProcessHelp() {
260 - c.Walk(func(cm *Command) {
261 - ht := &cm.Helptext
262 - if len(ht.LongDescription) == 0 {
263 - ht.LongDescription = ht.ShortDescription
264 - }
265 - })
266 -}
267 -
268 -// checkArgValue returns an error if a given arg value is not valid for the
269 -// given Argument
270 -func checkArgValue(v string, found bool, def cmdkit.Argument) error {
271 - if def.Variadic && def.SupportsStdin {
272 - return nil
273 - }
274 -
275 - if !found && def.Required {
276 - return fmt.Errorf("Argument '%s' is required", def.Name)
277 - }
278 -
279 - return nil
280 -}
281 -
66 func ClientError(msg string) error {
67 return &cmdkit.Error{Code: cmdkit.ErrClient, Message: msg}
68 }
285 -
286 -// global options, added to every command
287 -var globalOptions = []cmdkit.Option{
288 - cmds.OptionEncodingType,
289 - cmds.OptionStreamChannels,
290 - cmds.OptionTimeout,
291 -}
292 -
293 -// the above array of Options, wrapped in a Command
294 -var globalCommand = &Command{
295 - Options: globalOptions,
296 -}
commands/command_test.go deleted
-200
@@ -1,200 +0,0 @@
1 -package commands
2 -
3 -import (
4 - "testing"
5 -
6 - cmds "gx/ipfs/QmabLouZTZwhfALuBcssPvkzhbYGMb4394huT7HY4LQ6d3/go-ipfs-cmds"
7 - cmdkit "gx/ipfs/QmceUdzxkimdYsgtX733uNgzf1DLHyBKN6ehGSp85ayppM/go-ipfs-cmdkit"
8 -)
9 -
10 -func noop(req Request, res Response) {
11 -}
12 -
13 -func TestOptionValidation(t *testing.T) {
14 - cmd := Command{
15 - Options: []cmdkit.Option{
16 - cmdkit.IntOption("b", "beep", "enables beeper"),
17 - cmdkit.StringOption("B", "boop", "password for booper"),
18 - },
19 - Run: noop,
20 - }
21 -
22 - opts, _ := cmd.GetOptions(nil)
23 -
24 - req, _ := NewRequest(nil, nil, nil, nil, nil, opts)
25 - req.SetOption("beep", true)
26 - res := cmd.Call(req)
27 - if res.Error() == nil {
28 - t.Error("Should have failed (incorrect type)")
29 - }
30 -
31 - req, _ = NewRequest(nil, nil, nil, nil, nil, opts)
32 - req.SetOption("beep", 5)
33 - res = cmd.Call(req)
34 - if res.Error() != nil {
35 - t.Error(res.Error(), "Should have passed")
36 - }
37 -
38 - req, _ = NewRequest(nil, nil, nil, nil, nil, opts)
39 - req.SetOption("beep", 5)
40 - req.SetOption("boop", "test")
41 - res = cmd.Call(req)
42 - if res.Error() != nil {
43 - t.Error("Should have passed")
44 - }
45 -
46 - req, _ = NewRequest(nil, nil, nil, nil, nil, opts)
47 - req.SetOption("b", 5)
48 - req.SetOption("B", "test")
49 - res = cmd.Call(req)
50 - if res.Error() != nil {
51 - t.Error("Should have passed")
52 - }
53 -
54 - req, _ = NewRequest(nil, nil, nil, nil, nil, opts)
55 - req.SetOption("foo", 5)
56 - res = cmd.Call(req)
57 - if res.Error() != nil {
58 - t.Error("Should have passed")
59 - }
60 -
61 - req, _ = NewRequest(nil, nil, nil, nil, nil, opts)
62 - req.SetOption(cmds.EncLong, "json")
63 - res = cmd.Call(req)
64 - if res.Error() != nil {
65 - t.Error("Should have passed")
66 - }
67 -
68 - req, _ = NewRequest(nil, nil, nil, nil, nil, opts)
69 - req.SetOption("b", "100")
70 - res = cmd.Call(req)
71 - if res.Error() != nil {
72 - t.Error("Should have passed")
73 - }
74 -
75 - req, _ = NewRequest(nil, nil, nil, nil, &cmd, opts)
76 - req.SetOption("b", ":)")
77 - res = cmd.Call(req)
78 - if res.Error() == nil {
79 - t.Error("Should have failed (string value not convertible to int)")
80 - }
81 -
82 - err := req.SetOptions(map[string]interface{}{
83 - "b": 100,
84 - })
85 - if err != nil {
86 - t.Error("Should have passed")
87 - }
88 -
89 - err = req.SetOptions(map[string]interface{}{
90 - "b": ":)",
91 - })
92 - if err == nil {
93 - t.Error("Should have failed (string value not convertible to int)")
94 - }
95 -}
96 -
97 -func TestRegistration(t *testing.T) {
98 - cmdA := &Command{
99 - Options: []cmdkit.Option{
100 - cmdkit.IntOption("beep", "number of beeps"),
101 - },
102 - Run: noop,
103 - }
104 -
105 - cmdB := &Command{
106 - Options: []cmdkit.Option{
107 - cmdkit.IntOption("beep", "number of beeps"),
108 - },
109 - Run: noop,
110 - Subcommands: map[string]*Command{
111 - "a": cmdA,
112 - },
113 - }
114 -
115 - cmdC := &Command{
116 - Options: []cmdkit.Option{
117 - cmdkit.StringOption("encoding", "data encoding type"),
118 - },
119 - Run: noop,
120 - }
121 -
122 - path := []string{"a"}
123 - _, err := cmdB.GetOptions(path)
124 - if err == nil {
125 - t.Error("Should have failed (option name collision)")
126 - }
127 -
128 - _, err = cmdC.GetOptions(nil)
129 - if err == nil {
130 - t.Error("Should have failed (option name collision with global options)")
131 - }
132 -}
133 -
134 -func TestResolving(t *testing.T) {
135 - cmdC := &Command{}
136 - cmdB := &Command{
137 - Subcommands: map[string]*Command{
138 - "c": cmdC,
139 - },
140 - }
141 - cmdB2 := &Command{}
142 - cmdA := &Command{
143 - Subcommands: map[string]*Command{
144 - "b": cmdB,
145 - "B": cmdB2,
146 - },
147 - }
148 - cmd := &Command{
149 - Subcommands: map[string]*Command{
150 - "a": cmdA,
151 - },
152 - }
153 -
154 - cmds, err := cmd.Resolve([]string{"a", "b", "c"})
155 - if err != nil {
156 - t.Error(err)
157 - }
158 - if len(cmds) != 4 || cmds[0] != cmd || cmds[1] != cmdA || cmds[2] != cmdB || cmds[3] != cmdC {
159 - t.Error("Returned command path is different than expected", cmds)
160 - }
161 -}
162 -
163 -func TestWalking(t *testing.T) {
164 - cmdA := &Command{
165 - Subcommands: map[string]*Command{
166 - "b": &Command{},
167 - "B": &Command{},
168 - },
169 - }
170 - i := 0
171 - cmdA.Walk(func(c *Command) {
172 - i = i + 1
173 - })
174 - if i != 3 {
175 - t.Error("Command tree walk didn't work, expected 3 got:", i)
176 - }
177 -}
178 -
179 -func TestHelpProcessing(t *testing.T) {
180 - cmdB := &Command{
181 - Helptext: cmdkit.HelpText{
182 - ShortDescription: "This is other short",
183 - },
184 - }
185 - cmdA := &Command{
186 - Helptext: cmdkit.HelpText{
187 - ShortDescription: "This is short",
188 - },
189 - Subcommands: map[string]*Command{
190 - "a": cmdB,
191 - },
192 - }
193 - cmdA.ProcessHelp()
194 - if len(cmdA.Helptext.LongDescription) == 0 {
195 - t.Error("LongDescription was not set on basis of ShortDescription")
196 - }
197 - if len(cmdB.Helptext.LongDescription) == 0 {
198 - t.Error("LongDescription was not set on basis of ShortDescription")
199 - }
200 -}
commands/legacy/request.go
-26
@@ -147,32 +147,6 @@ func (r *requestWrapper) Values() map[string]interface{} {
147 return nil
148 }
149
150 -func (r *requestWrapper) VarArgs(f func(string) error) error {
151 - if len(r.req.Arguments) >= len(r.req.Command.Arguments) {
152 - for _, arg := range r.req.Arguments {
153 - err := f(arg)
154 - if err != nil {
155 - return err
156 - }
157 - }
158 - return nil
159 - }
160 -
161 - s, err := r.req.BodyArgs()
162 - if err != nil {
163 - return err
164 - }
165 -
166 - for s.Scan() {
167 - err = f(s.Text())
168 - if err != nil {
169 - return err
170 - }
171 - }
172 -
173 - return nil
174 -}
175 -
150 // copied from go-ipfs-cmds/request.go
151 func convertOptions(req *cmds.Request) error {
152 optDefSlice := req.Command.Options
commands/request.go
-319
@@ -1,20 +1,13 @@
1 package commands
2
3 import (
4 - "bufio"
4 "context"
5 "errors"
7 - "fmt"
8 - "io"
9 - "os"
10 - "reflect"
11 - "strconv"
6 "strings"
7 "time"
8
9 "github.com/ipfs/go-ipfs/core"
10 "github.com/ipfs/go-ipfs/repo/config"
17 - u "gx/ipfs/QmNiJuT8Ja3hMVpBHXv3Q6dwmperaQ6JjLtpMQgMCD7xvx/go-ipfs-util"
11
12 "gx/ipfs/QmabLouZTZwhfALuBcssPvkzhbYGMb4394huT7HY4LQ6d3/go-ipfs-cmds"
13 "gx/ipfs/QmceUdzxkimdYsgtX733uNgzf1DLHyBKN6ehGSp85ayppM/go-ipfs-cmdkit"
@@ -59,12 +52,6 @@ func (c *Context) GetNode() (*core.IpfsNode, error) {
52 return c.node, err
53 }
54
62 -// NodeWithoutConstructing returns the underlying node variable
63 -// so that clients may close it.
64 -func (c *Context) NodeWithoutConstructing() *core.IpfsNode {
65 - return c.node
66 -}
67 -
55 // Context returns the node's context.
56 func (c *Context) Context() context.Context {
57 n, err := c.GetNode()
@@ -112,316 +99,10 @@ type Request interface {
99 Path() []string
100 Option(name string) *cmdkit.OptionValue
101 Options() cmdkit.OptMap
115 - SetOption(name string, val interface{})
116 - SetOptions(opts cmdkit.OptMap) error
102 Arguments() []string
103 StringArguments() []string
119 - SetArguments([]string)
104 Files() files.File
121 - SetFiles(files.File)
105 Context() context.Context
106 InvocContext() *Context
124 - SetInvocContext(Context)
107 Command() *Command
126 - Values() map[string]interface{}
127 - Stdin() io.Reader
128 - VarArgs(func(string) error) error
129 -
130 - ConvertOptions() error
131 -}
132 -
133 -type request struct {
134 - path []string
135 - options cmdkit.OptMap
136 - arguments []string
137 - files files.File
138 - cmd *Command
139 - ctx Context
140 - rctx context.Context
141 - optionDefs map[string]cmdkit.Option
142 - values map[string]interface{}
143 - stdin io.Reader
144 -}
145 -
146 -// Path returns the command path of this request
147 -func (r *request) Path() []string {
148 - return r.path
149 -}
150 -
151 -// Option returns the value of the option for given name.
152 -func (r *request) Option(name string) *cmdkit.OptionValue {
153 - // find the option with the specified name
154 - option, found := r.optionDefs[name]
155 - if !found {
156 - return nil
157 - }
158 -
159 - // try all the possible names, break if we find a value
160 - for _, n := range option.Names() {
161 - val, found := r.options[n]
162 - if found {
163 - return &cmdkit.OptionValue{
164 - Value: val,
165 - ValueFound: found,
166 - Def: option,
167 - }
168 - }
169 - }
170 -
171 - return &cmdkit.OptionValue{
172 - Value: option.Default(),
173 - ValueFound: false,
174 - Def: option,
175 - }
176 -}
177 -
178 -// Options returns a copy of the option map
179 -func (r *request) Options() cmdkit.OptMap {
180 - output := make(cmdkit.OptMap)
181 - for k, v := range r.options {
182 - output[k] = v
183 - }
184 - return output
185 -}
186 -
187 -// SetOption sets the value of the option for given name.
188 -func (r *request) SetOption(name string, val interface{}) {
189 - // find the option with the specified name
190 - option, found := r.optionDefs[name]
191 - if !found {
192 - return
193 - }
194 -
195 - // try all the possible names, if we already have a value then set over it
196 - for _, n := range option.Names() {
197 - _, found := r.options[n]
198 - if found {
199 - r.options[n] = val
200 - return
201 - }
202 - }
203 -
204 - r.options[name] = val
205 -}
206 -
207 -// SetOptions sets the option values, unsetting any values that were previously set
208 -func (r *request) SetOptions(opts cmdkit.OptMap) error {
209 - r.options = opts
210 - return r.ConvertOptions()
211 -}
212 -
213 -func (r *request) StringArguments() []string {
214 - return r.arguments
215 -}
216 -
217 -// Arguments returns the arguments slice
218 -func (r *request) Arguments() []string {
219 - if r.haveVarArgsFromStdin() {
220 - err := r.VarArgs(func(s string) error {
221 - r.arguments = append(r.arguments, s)
222 - return nil
223 - })
224 - if err != nil && err != io.EOF {
225 - log.Error(err)
226 - }
227 - }
228 -
229 - return r.arguments
230 -}
231 -
232 -func (r *request) SetArguments(args []string) {
233 - r.arguments = args
234 -}
235 -
236 -func (r *request) Files() files.File {
237 - return r.files
238 -}
239 -
240 -func (r *request) SetFiles(f files.File) {
241 - r.files = f
242 -}
243 -
244 -func (r *request) Context() context.Context {
245 - return r.rctx
246 -}
247 -
248 -func (r *request) haveVarArgsFromStdin() bool {
249 - // we expect varargs if we have a string argument that supports stdin
250 - // and not arguments to satisfy it
251 - if len(r.cmd.Arguments) == 0 {
252 - return false
253 - }
254 -
255 - last := r.cmd.Arguments[len(r.cmd.Arguments)-1]
256 - return last.SupportsStdin && last.Type == cmdkit.ArgString && (last.Required || last.Variadic) &&
257 - len(r.arguments) < len(r.cmd.Arguments)
258 -}
259 -
260 -// VarArgs can be used when you want string arguments as input
261 -// and also want to be able to handle them in a streaming fashion
262 -func (r *request) VarArgs(f func(string) error) error {
263 - if len(r.arguments) >= len(r.cmd.Arguments) {
264 - for _, arg := range r.arguments[len(r.cmd.Arguments)-1:] {
265 - err := f(arg)
266 - if err != nil {
267 - return err
268 - }
269 - }
270 -
271 - return nil
272 - }
273 -
274 - if r.files == nil {
275 - log.Warning("expected more arguments from stdin")
276 - return nil
277 - }
278 -
279 - fi, err := r.files.NextFile()
280 - if err != nil {
281 - return err
282 - }
283 -
284 - var any bool
285 - scan := bufio.NewScanner(fi)
286 - for scan.Scan() {
287 - any = true
288 - err := f(scan.Text())
289 - if err != nil {
290 - return err
291 - }
292 - }
293 - if !any {
294 - return f("")
295 - }
296 -
297 - return nil
298 -}
299 -
300 -func (r *request) InvocContext() *Context {
301 - return &r.ctx
302 -}
303 -
304 -func (r *request) SetInvocContext(ctx Context) {
305 - r.ctx = ctx
306 -}
307 -
308 -func (r *request) Command() *Command {
309 - return r.cmd
310 -}
311 -
312 -type converter func(string) (interface{}, error)
313 -
314 -var converters = map[reflect.Kind]converter{
315 - cmdkit.Bool: func(v string) (interface{}, error) {
316 - if v == "" {
317 - return true, nil
318 - }
319 - return strconv.ParseBool(v)
320 - },
321 - cmdkit.Int: func(v string) (interface{}, error) {
322 - val, err := strconv.ParseInt(v, 0, 32)
323 - if err != nil {
324 - return nil, err
325 - }
326 - return int(val), err
327 - },
328 - cmdkit.Uint: func(v string) (interface{}, error) {
329 - val, err := strconv.ParseUint(v, 0, 32)
330 - if err != nil {
331 - return nil, err
332 - }
333 - return int(val), err
334 - },
335 - cmdkit.Float: func(v string) (interface{}, error) {
336 - return strconv.ParseFloat(v, 64)
337 - },
338 -}
339 -
340 -func (r *request) Values() map[string]interface{} {
341 - return r.values
342 -}
343 -
344 -func (r *request) Stdin() io.Reader {
345 - return r.stdin
346 -}
347 -
348 -func (r *request) ConvertOptions() error {
349 - for k, v := range r.options {
350 - opt, ok := r.optionDefs[k]
351 - if !ok {
352 - continue
353 - }
354 -
355 - kind := reflect.TypeOf(v).Kind()
356 - if kind != opt.Type() {
357 - if kind == cmdkit.String {
358 - convert := converters[opt.Type()]
359 - str, ok := v.(string)
360 - if !ok {
361 - return u.ErrCast()
362 - }
363 - val, err := convert(str)
364 - if err != nil {
365 - value := fmt.Sprintf("value '%v'", v)
366 - if len(str) == 0 {
367 - value = "empty value"
368 - }
369 - return fmt.Errorf("Could not convert %s to type '%s' (for option '-%s')",
370 - value, opt.Type().String(), k)
371 - }
372 - r.options[k] = val
373 -
374 - } else {
375 - return fmt.Errorf("Option '%s' should be type '%s', but got type '%s'",
376 - k, opt.Type().String(), kind.String())
377 - }
378 - } else {
379 - r.options[k] = v
380 - }
381 -
382 - for _, name := range opt.Names() {
383 - if _, ok := r.options[name]; name != k && ok {
384 - return fmt.Errorf("Duplicate command options were provided ('%s' and '%s')",
385 - k, name)
386 - }
387 - }
388 - }
389 -
390 - return nil
391 -}
392 -
393 -// NewEmptyRequest initializes an empty request
394 -func NewEmptyRequest() (Request, error) {
395 - return NewRequest(nil, nil, nil, nil, nil, nil)
396 -}
397 -
398 -// NewRequest returns a request initialized with given arguments
399 -// An non-nil error will be returned if the provided option values are invalid
400 -func NewRequest(path []string, opts cmdkit.OptMap, args []string, file files.File, cmd *Command, optDefs map[string]cmdkit.Option) (Request, error) {
401 - if opts == nil {
402 - opts = make(cmdkit.OptMap)
403 - }
404 - if optDefs == nil {
405 - optDefs = make(map[string]cmdkit.Option)
406 - }
407 -
408 - ctx := Context{}
409 - values := make(map[string]interface{})
410 - req := &request{
411 - path: path,
412 - options: opts,
413 - arguments: args,
414 - files: file,
415 - cmd: cmd,
416 - ctx: ctx,
417 - optionDefs: optDefs,
418 - values: values,
419 - stdin: os.Stdin,
420 - }
421 - err := req.ConvertOptions()
422 - if err != nil {
423 - return nil, err
424 - }
425 -
426 - return req, nil
108 }
commands/response.go
-181
@@ -1,15 +1,8 @@
1 package commands
2
3 import (
4 - "bytes"
5 - "encoding/json"
6 - "encoding/xml"
7 - "fmt"
4 "io"
9 - "os"
10 - "strings"
5
12 - cmds "gx/ipfs/QmabLouZTZwhfALuBcssPvkzhbYGMb4394huT7HY4LQ6d3/go-ipfs-cmds"
6 cmdkit "gx/ipfs/QmceUdzxkimdYsgtX733uNgzf1DLHyBKN6ehGSp85ayppM/go-ipfs-cmdkit"
7 )
8
@@ -28,50 +21,6 @@ const (
21 // TODO: support more encoding types
22 )
23
31 -func marshalJson(value interface{}) (io.Reader, error) {
32 - b, err := json.Marshal(value)
33 - if err != nil {
34 - return nil, err
35 - }
36 - b = append(b, '\n')
37 - return bytes.NewReader(b), nil
38 -}
39 -
40 -var marshallers = map[EncodingType]Marshaler{
41 - JSON: func(res Response) (io.Reader, error) {
42 - ch, ok := res.Output().(<-chan interface{})
43 - if ok {
44 - return &ChannelMarshaler{
45 - Channel: ch,
46 - Marshaler: marshalJson,
47 - Res: res,
48 - }, nil
49 - }
50 -
51 - var value interface{}
52 - if res.Error() != nil {
53 - value = res.Error()
54 - } else {
55 - value = res.Output()
56 - }
57 - return marshalJson(value)
58 - },
59 - XML: func(res Response) (io.Reader, error) {
60 - var value interface{}
61 - if res.Error() != nil {
62 - value = res.Error()
63 - } else {
64 - value = res.Output()
65 - }
66 -
67 - b, err := xml.Marshal(value)
68 - if err != nil {
69 - return nil, err
70 - }
71 - return bytes.NewReader(b), nil
72 - },
73 -}
74 -
24 // Response is the result of a command request. Handlers write to the response,
25 // setting Error or Value. Response is returned to the client.
26 type Response interface {
@@ -104,133 +53,3 @@ type Response interface {
53 Stdout() io.Writer
54 Stderr() io.Writer
55 }
107 -
108 -type response struct {
109 - req Request
110 - err *cmdkit.Error
111 - value interface{}
112 - out io.Reader
113 - length uint64
114 - stdout io.Writer
115 - stderr io.Writer
116 - closer io.Closer
117 -}
118 -
119 -func (r *response) Request() Request {
120 - return r.req
121 -}
122 -
123 -func (r *response) Output() interface{} {
124 - return r.value
125 -}
126 -
127 -func (r *response) SetOutput(v interface{}) {
128 - r.value = v
129 -}
130 -
131 -func (r *response) Length() uint64 {
132 - return r.length
133 -}
134 -
135 -func (r *response) SetLength(l uint64) {
136 - r.length = l
137 -}
138 -
139 -func (r *response) Error() *cmdkit.Error {
140 - return r.err
141 -}
142 -
143 -func (r *response) SetError(err error, code cmdkit.ErrorType) {
144 - r.err = &cmdkit.Error{Message: err.Error(), Code: code}
145 -}
146 -
147 -func (r *response) Marshal() (io.Reader, error) {
148 - if r.err == nil && r.value == nil {
149 - return bytes.NewReader([]byte{}), nil
150 - }
151 -
152 - enc, found, err := r.req.Option(cmds.EncLong).String()
153 - if err != nil {
154 - return nil, err
155 - }
156 - if !found {
157 - return nil, fmt.Errorf("No encoding type was specified")
158 - }
159 - encType := EncodingType(strings.ToLower(enc))
160 -
161 - // Special case: if text encoding and an error, just print it out.
162 - if encType == Text && r.Error() != nil {
163 - return strings.NewReader(r.Error().Error()), nil
164 - }
165 -
166 - var marshaller Marshaler
167 - if r.req.Command() != nil && r.req.Command().Marshalers != nil {
168 - marshaller = r.req.Command().Marshalers[encType]
169 - }
170 - if marshaller == nil {
171 - var ok bool
172 - marshaller, ok = marshallers[encType]
173 - if !ok {
174 - return nil, fmt.Errorf("No marshaller found for encoding type '%s'", enc)
175 - }
176 - }
177 -
178 - output, err := marshaller(r)
179 - if err != nil {
180 - return nil, err
181 - }
182 - if output == nil {
183 - return bytes.NewReader([]byte{}), nil
184 - }
185 - return output, nil
186 -}
187 -
188 -// Reader returns an `io.Reader` representing marshalled output of this Response
189 -// Note that multiple calls to this will return a reference to the same io.Reader
190 -func (r *response) Reader() (io.Reader, error) {
191 - if r.out == nil {
192 - if out, ok := r.value.(io.Reader); ok {
193 - // if command returned a io.Reader, use that as our reader
194 - r.out = out
195 -
196 - } else {
197 - // otherwise, use the response marshaler output
198 - marshalled, err := r.Marshal()
199 - if err != nil {
200 - return nil, err
201 - }
202 -
203 - r.out = marshalled
204 - }
205 - }
206 -
207 - return r.out, nil
208 -}
209 -
210 -func (r *response) Close() error {
211 - if r.closer != nil {
212 - return r.closer.Close()
213 - }
214 - return nil
215 -}
216 -
217 -func (r *response) SetCloser(c io.Closer) {
218 - r.closer = c
219 -}
220 -
221 -func (r *response) Stdout() io.Writer {
222 - return r.stdout
223 -}
224 -
225 -func (r *response) Stderr() io.Writer {
226 - return r.stderr
227 -}
228 -
229 -// NewResponse returns a response to match given Request
230 -func NewResponse(req Request) Response {
231 - return &response{
232 - req: req,
233 - stdout: os.Stdout,
234 - stderr: os.Stderr,
235 - }
236 -}
commands/response_test.go deleted
-70
@@ -1,70 +0,0 @@
1 -package commands
2 -
3 -import (
4 - "bytes"
5 - "fmt"
6 - "strings"
7 - "testing"
8 -
9 - cmds "gx/ipfs/QmabLouZTZwhfALuBcssPvkzhbYGMb4394huT7HY4LQ6d3/go-ipfs-cmds"
10 - cmdkit "gx/ipfs/QmceUdzxkimdYsgtX733uNgzf1DLHyBKN6ehGSp85ayppM/go-ipfs-cmdkit"
11 -)
12 -
13 -type TestOutput struct {
14 - Foo, Bar string
15 - Baz int
16 -}
17 -
18 -func TestMarshalling(t *testing.T) {
19 - cmd := &Command{}
20 - opts, _ := cmd.GetOptions(nil)
21 -
22 - req, _ := NewRequest(nil, nil, nil, nil, nil, opts)
23 -
24 - res := NewResponse(req)
25 - res.SetOutput(TestOutput{"beep", "boop", 1337})
26 -
27 - _, err := res.Marshal()
28 - if err == nil {
29 - t.Error("Should have failed (no encoding type specified in request)")
30 - }
31 -
32 - req.SetOption(cmds.EncLong, JSON)
33 -
34 - reader, err := res.Marshal()
35 - if err != nil {
36 - t.Error(err, "Should have passed")
37 - }
38 - buf := new(bytes.Buffer)
39 - buf.ReadFrom(reader)
40 - output := buf.String()
41 - if removeWhitespace(output) != "{\"Foo\":\"beep\",\"Bar\":\"boop\",\"Baz\":1337}" {
42 - t.Error("Incorrect JSON output")
43 - }
44 -
45 - res.SetError(fmt.Errorf("Oops!"), cmdkit.ErrClient)
46 - reader, err = res.Marshal()
47 - if err != nil {
48 - t.Error("Should have passed")
49 - }
50 - buf.Reset()
51 - buf.ReadFrom(reader)
52 - output = buf.String()
53 - fmt.Println(removeWhitespace(output))
54 - if removeWhitespace(output) != `{"Message":"Oops!","Code":1,"Type":"error"}` {
55 - t.Error("Incorrect JSON output")
56 - }
57 -}
58 -
59 -func TestErrTypeOrder(t *testing.T) {
60 - if cmdkit.ErrNormal != 0 || cmdkit.ErrClient != 1 || cmdkit.ErrImplementation != 2 || cmdkit.ErrNotFound != 3 {
61 - t.Fatal("ErrType order is wrong")
62 - }
63 -}
64 -
65 -func removeWhitespace(input string) string {
66 - input = strings.Replace(input, " ", "", -1)
67 - input = strings.Replace(input, "\t", "", -1)
68 - input = strings.Replace(input, "\n", "", -1)
69 - return strings.Replace(input, "\r", "", -1)
70 -}