Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
10
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Open sidebar
dms3
go-unixfs
Commits
b10fc2cc
Commit
b10fc2cc
authored
Oct 20, 2014
by
Juan Batiz-Benet
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
turned req + res into interfaces
parent
bbef82f4
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
124 additions
and
71 deletions
+124
-71
commands/cli/parse.go
commands/cli/parse.go
+1
-1
commands/command.go
commands/command.go
+10
-6
commands/command_test.go
commands/command_test.go
+28
-27
commands/request.go
commands/request.go
+31
-18
commands/response.go
commands/response.go
+51
-14
commands/response_test.go
commands/response_test.go
+3
-5
No files found.
commands/cli/parse.go
View file @
b10fc2cc
...
...
@@ -9,7 +9,7 @@ import (
// Parse parses the input commandline string (cmd, flags, and args).
// returns the corresponding command Request object.
func
Parse
(
input
[]
string
,
root
*
commands
.
Command
)
(
*
commands
.
Request
,
error
)
{
func
Parse
(
input
[]
string
,
root
*
commands
.
Command
)
(
commands
.
Request
,
error
)
{
path
,
input
:=
parsePath
(
input
,
root
)
opts
,
args
,
err
:=
parseOptions
(
input
)
if
err
!=
nil
{
...
...
commands/command.go
View file @
b10fc2cc
...
...
@@ -4,11 +4,15 @@ import (
"errors"
"fmt"
"strings"
u
"github.com/jbenet/go-ipfs/util"
)
var
log
=
u
.
Logger
(
"command"
)
// Function is the type of function that Commands use.
// It reads from the Request, and writes results to the Response.
type
Function
func
(
*
Request
,
*
Response
)
type
Function
func
(
Request
,
Response
)
// Command is a runnable command, with input arguments and options (flags).
// It can also have subcommands, to group units of work into sets.
...
...
@@ -43,10 +47,10 @@ func (c *Command) Register(id string, sub *Command) error {
}
// Call invokes the command at the given subcommand path
func
(
c
*
Command
)
Call
(
req
*
Request
)
*
Response
{
res
:=
&
Response
{
req
:
req
}
func
(
c
*
Command
)
Call
(
req
Request
)
Response
{
res
:=
New
Response
(
req
)
cmds
,
err
:=
c
.
Resolve
(
req
.
p
ath
)
cmds
,
err
:=
c
.
Resolve
(
req
.
P
ath
()
)
if
err
!=
nil
{
res
.
SetError
(
err
,
ErrClient
)
return
res
...
...
@@ -58,13 +62,13 @@ func (c *Command) Call(req *Request) *Response {
return
res
}
options
,
err
:=
c
.
GetOptions
(
req
.
p
ath
)
options
,
err
:=
c
.
GetOptions
(
req
.
P
ath
()
)
if
err
!=
nil
{
res
.
SetError
(
err
,
ErrClient
)
return
res
}
err
=
req
.
c
onvertOptions
(
options
)
err
=
req
.
C
onvertOptions
(
options
)
if
err
!=
nil
{
res
.
SetError
(
err
,
ErrClient
)
return
res
...
...
commands/command_test.go
View file @
b10fc2cc
...
...
@@ -8,70 +8,70 @@ func TestOptionValidation(t *testing.T) {
Option
{[]
string
{
"b"
,
"beep"
},
Int
},
Option
{[]
string
{
"B"
,
"boop"
},
String
},
},
run
:
func
(
req
*
Request
,
res
*
Response
)
{},
run
:
func
(
req
Request
,
res
Response
)
{},
}
req
:=
NewEmptyRequest
()
req
.
o
ption
s
[
"foo"
]
=
5
req
.
SetO
ption
(
"foo"
,
5
)
res
:=
cmd
.
Call
(
req
)
if
res
.
Error
==
nil
{
if
res
.
Error
()
==
nil
{
t
.
Error
(
"Should have failed (unrecognized option)"
)
}
req
=
NewEmptyRequest
()
req
.
o
ption
s
[
"beep"
]
=
5
req
.
o
ption
s
[
"b"
]
=
10
req
.
SetO
ption
(
"beep"
,
5
)
req
.
SetO
ption
(
"b"
,
10
)
res
=
cmd
.
Call
(
req
)
if
res
.
Error
==
nil
{
if
res
.
Error
()
==
nil
{
t
.
Error
(
"Should have failed (duplicate options)"
)
}
req
=
NewEmptyRequest
()
req
.
o
ption
s
[
"beep"
]
=
"foo"
req
.
SetO
ption
(
"beep"
,
"foo"
)
res
=
cmd
.
Call
(
req
)
if
res
.
Error
==
nil
{
if
res
.
Error
()
==
nil
{
t
.
Error
(
"Should have failed (incorrect type)"
)
}
req
=
NewEmptyRequest
()
req
.
o
ption
s
[
"beep"
]
=
5
req
.
SetO
ption
(
"beep"
,
5
)
res
=
cmd
.
Call
(
req
)
if
res
.
Error
!=
nil
{
t
.
Error
(
res
.
Error
,
"Should have passed"
)
if
res
.
Error
()
!=
nil
{
t
.
Error
(
res
.
Error
()
,
"Should have passed"
)
}
req
=
NewEmptyRequest
()
req
.
o
ption
s
[
"beep"
]
=
5
req
.
o
ption
s
[
"boop"
]
=
"test"
req
.
SetO
ption
(
"beep"
,
5
)
req
.
SetO
ption
(
"boop"
,
"test"
)
res
=
cmd
.
Call
(
req
)
if
res
.
Error
!=
nil
{
if
res
.
Error
()
!=
nil
{
t
.
Error
(
"Should have passed"
)
}
req
=
NewEmptyRequest
()
req
.
o
ption
s
[
"b"
]
=
5
req
.
o
ption
s
[
"B"
]
=
"test"
req
.
SetO
ption
(
"b"
,
5
)
req
.
SetO
ption
(
"B"
,
"test"
)
res
=
cmd
.
Call
(
req
)
if
res
.
Error
!=
nil
{
if
res
.
Error
()
!=
nil
{
t
.
Error
(
"Should have passed"
)
}
req
=
NewEmptyRequest
()
req
.
o
ption
s
[
EncShort
]
=
"json"
req
.
SetO
ption
(
EncShort
,
"json"
)
res
=
cmd
.
Call
(
req
)
if
res
.
Error
!=
nil
{
if
res
.
Error
()
!=
nil
{
t
.
Error
(
"Should have passed"
)
}
req
=
NewEmptyRequest
()
req
.
o
ption
s
[
"b"
]
=
"100"
req
.
SetO
ption
(
"b"
,
"100"
)
res
=
cmd
.
Call
(
req
)
if
res
.
Error
!=
nil
{
if
res
.
Error
()
!=
nil
{
t
.
Error
(
"Should have passed"
)
}
req
=
NewEmptyRequest
()
req
.
o
ption
s
[
"b"
]
=
":)"
req
.
SetO
ption
(
"b"
,
":)"
)
res
=
cmd
.
Call
(
req
)
if
res
.
Error
==
nil
{
t
.
Error
(
res
.
Error
,
"Should have failed (string value not convertible to int)"
)
...
...
@@ -79,40 +79,41 @@ func TestOptionValidation(t *testing.T) {
}
func
TestRegistration
(
t
*
testing
.
T
)
{
noop
:=
func
(
req
Request
,
res
Response
)
{}
cmds
:=
[]
*
Command
{
&
Command
{
Options
:
[]
Option
{
Option
{[]
string
{
"beep"
},
Int
},
},
run
:
func
(
req
*
Request
,
res
*
Response
)
{}
,
run
:
noop
,
},
&
Command
{
Options
:
[]
Option
{
Option
{[]
string
{
"boop"
},
Int
},
},
run
:
func
(
req
*
Request
,
res
*
Response
)
{}
,
run
:
noop
,
},
&
Command
{
Options
:
[]
Option
{
Option
{[]
string
{
"boop"
},
String
},
},
run
:
func
(
req
*
Request
,
res
*
Response
)
{}
,
run
:
noop
,
},
&
Command
{
Options
:
[]
Option
{
Option
{[]
string
{
"bop"
},
String
},
},
run
:
func
(
req
*
Request
,
res
*
Response
)
{}
,
run
:
noop
,
},
&
Command
{
Options
:
[]
Option
{
Option
{[]
string
{
EncShort
},
String
},
},
run
:
func
(
req
*
Request
,
res
*
Response
)
{}
,
run
:
noop
,
},
}
...
...
commands/request.go
View file @
b10fc2cc
...
...
@@ -6,37 +6,48 @@ import (
"strconv"
)
type
optMap
map
[
string
]
interface
{}
// Request represents a call to a command from a consumer
type
Request
struct
{
type
Request
interface
{
Path
()
[]
string
Option
(
name
string
)
(
interface
{},
bool
)
SetOption
(
name
string
,
val
interface
{})
Arguments
()
[]
string
ConvertOptions
(
options
map
[
string
]
Option
)
error
}
type
request
struct
{
path
[]
string
options
map
[
string
]
interface
{}
options
optMap
arguments
[]
string
}
func
(
r
*
Request
)
Path
()
[]
string
{
// Path returns the command path of this request
func
(
r
*
request
)
Path
()
[]
string
{
return
r
.
path
}
func
(
r
*
Request
)
SetPath
(
path
[]
string
)
{
r
.
path
=
path
}
func
(
r
*
Request
)
Option
(
name
string
)
(
interface
{},
bool
)
{
val
,
ok
:=
r
.
options
[
name
]
return
val
,
ok
// Option returns the value of the option for given name.
func
(
r
*
request
)
Option
(
name
string
)
(
interface
{},
bool
)
{
val
,
err
:=
r
.
options
[
name
]
return
val
,
err
}
func
(
r
*
Request
)
SetOption
(
name
string
,
value
interface
{})
{
r
.
options
[
name
]
=
value
// SetOption sets the value of the option for given name.
func
(
r
*
request
)
SetOption
(
name
string
,
val
interface
{})
{
r
.
options
[
name
]
=
val
}
func
(
r
*
Request
)
Arguments
()
[]
string
{
// Arguments returns the arguments slice
func
(
r
*
request
)
Arguments
()
[]
string
{
return
r
.
arguments
}
type
converter
func
(
string
)
(
interface
{},
error
)
var
converters
map
[
reflect
.
Kind
]
converter
=
map
[
reflect
.
Kind
]
converter
{
var
converters
=
map
[
reflect
.
Kind
]
converter
{
Bool
:
func
(
v
string
)
(
interface
{},
error
)
{
if
v
==
""
{
return
true
,
nil
...
...
@@ -54,7 +65,7 @@ var converters map[reflect.Kind]converter = map[reflect.Kind]converter{
},
}
func
(
r
*
R
equest
)
c
onvertOptions
(
options
map
[
string
]
Option
)
error
{
func
(
r
*
r
equest
)
C
onvertOptions
(
options
map
[
string
]
Option
)
error
{
converted
:=
make
(
map
[
string
]
interface
{})
for
k
,
v
:=
range
r
.
options
{
...
...
@@ -98,11 +109,13 @@ func (r *Request) convertOptions(options map[string]Option) error {
return
nil
}
func
NewEmptyRequest
()
*
Request
{
// NewEmptyRequest initializes an empty request
func
NewEmptyRequest
()
Request
{
return
NewRequest
(
nil
,
nil
,
nil
)
}
func
NewRequest
(
path
[]
string
,
opts
map
[
string
]
interface
{},
args
[]
string
)
*
Request
{
// NewRequest returns a request initialized with given arguments
func
NewRequest
(
path
[]
string
,
opts
optMap
,
args
[]
string
)
Request
{
if
path
==
nil
{
path
=
make
([]
string
,
0
)
}
...
...
@@ -112,5 +125,5 @@ func NewRequest(path []string, opts map[string]interface{}, args []string) *Requ
if
args
==
nil
{
args
=
make
([]
string
,
0
)
}
return
&
R
equest
{
path
,
opts
,
args
}
return
&
r
equest
{
path
,
opts
,
args
}
}
commands/response.go
View file @
b10fc2cc
...
...
@@ -48,21 +48,53 @@ var marshallers = map[EncodingType]Marshaller{
// Response is the result of a command request. Handlers write to the response,
// setting Error or Value. Response is returned to the client.
type
Response
struct
{
req
*
Request
Error
*
Error
Value
interface
{}
type
Response
interface
{
Request
()
Request
// Set/Return the response Error
SetError
(
err
error
,
code
ErrorType
)
Error
()
error
// Sets/Returns the response value
SetValue
(
interface
{})
Value
()
interface
{}
// Marshal marshals out the response into a buffer. It uses the EncodingType
// on the Request to chose a Marshaller (Codec).
Marshal
()
([]
byte
,
error
)
}
type
response
struct
{
req
Request
err
*
Error
value
interface
{}
}
func
(
r
*
response
)
Request
()
Request
{
return
r
.
req
}
func
(
r
*
response
)
Value
()
interface
{}
{
return
r
.
value
}
func
(
r
*
response
)
SetValue
(
v
interface
{})
{
r
.
value
=
v
}
func
(
r
*
response
)
Error
()
error
{
if
r
.
err
==
nil
{
return
nil
}
return
r
.
err
}
// SetError updates the response Error.
func
(
r
*
Response
)
SetError
(
err
error
,
code
ErrorType
)
{
r
.
Error
=
&
Error
{
Message
:
err
.
Error
(),
Code
:
code
}
func
(
r
*
response
)
SetError
(
err
error
,
code
ErrorType
)
{
r
.
err
=
&
Error
{
Message
:
err
.
Error
(),
Code
:
code
}
}
// Marshal marshals out the response into a buffer. It uses the EncodingType
// on the Request to chose a Marshaller (Codec).
func
(
r
*
Response
)
Marshal
()
([]
byte
,
error
)
{
if
r
.
Error
==
nil
&&
r
.
Value
==
nil
{
func
(
r
*
response
)
Marshal
()
([]
byte
,
error
)
{
if
r
.
err
==
nil
&&
r
.
value
==
nil
{
return
nil
,
fmt
.
Errorf
(
"No error or value set, there is nothing to marshal"
)
}
...
...
@@ -77,8 +109,13 @@ func (r *Response) Marshal() ([]byte, error) {
return
nil
,
fmt
.
Errorf
(
"No marshaller found for encoding type '%s'"
,
enc
)
}
if
r
.
Erro
r
!=
nil
{
return
marshaller
(
r
.
Erro
r
)
if
r
.
er
r
!=
nil
{
return
marshaller
(
r
.
er
r
)
}
return
marshaller
(
r
.
Value
)
return
marshaller
(
r
.
value
)
}
// NewResponse returns a response to match given Request
func
NewResponse
(
req
Request
)
Response
{
return
&
response
{
req
:
req
}
}
commands/response_test.go
View file @
b10fc2cc
...
...
@@ -13,10 +13,8 @@ type TestOutput struct {
func
TestMarshalling
(
t
*
testing
.
T
)
{
req
:=
NewEmptyRequest
()
res
:=
Response
{
req
:
req
,
Value
:
TestOutput
{
"beep"
,
"boop"
,
1337
},
}
res
:=
NewResponse
(
req
)
res
.
SetValue
(
TestOutput
{
"beep"
,
"boop"
,
1337
})
// get command global options so we can set the encoding option
cmd
:=
Command
{}
...
...
@@ -31,7 +29,7 @@ func TestMarshalling(t *testing.T) {
}
req
.
SetOption
(
EncShort
,
JSON
)
req
.
c
onvertOptions
(
options
)
req
.
C
onvertOptions
(
options
)
bytes
,
err
:=
res
.
Marshal
()
if
err
!=
nil
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment