in go/wsl/driver/driver.go [139:303]
func extractWSLCaps(sessionID string, caps map[string]interface{}) (*wslCaps, error) {
binary := ""
if b, ok := caps["binary"]; ok {
bs, ok := b.(string)
if !ok {
return nil, fmt.Errorf("binary %#v is not a string", b)
}
binary = bs
}
port := 0
if p, ok := caps["port"]; ok {
switch pt := p.(type) {
case float64:
port = int(pt)
case string:
pi, err := strconv.Atoi(pt)
if err != nil {
return nil, err
}
port = pi
default:
return nil, fmt.Errorf("port %#v is not a number or string", p)
}
}
if port == 0 {
return nil, errors.New(`port must be set (use "%WSLPORT:DRIVER%" if you don't care what port is used)`)
}
var args []string
if a, ok := caps["args"]; ok {
if binary == "" {
return nil, fmt.Errorf("args set to %#v when binary is not set", a)
}
argsInterface, ok := a.([]interface{})
if !ok {
return nil, fmt.Errorf("args %#v is not a list", a)
}
for _, argInterface := range argsInterface {
arg, ok := argInterface.(string)
if !ok {
return nil, fmt.Errorf("element %#v in args is not a string", argInterface)
}
args = append(args, arg)
}
}
timeout := 1 * time.Second
if t, ok := caps["timeout"]; ok {
switch tt := t.(type) {
case float64:
// Incoming value is in seconds.
to, err := time.ParseDuration(fmt.Sprintf("%fs", tt))
if err != nil {
return nil, err
}
timeout = to
case string:
to, err := time.ParseDuration(tt)
if err != nil {
return nil, err
}
timeout = to
default:
return nil, fmt.Errorf("timeout %#v is not a number or string", t)
}
}
env := map[string]string{}
if e, ok := caps["env"]; ok {
if binary == "" {
return nil, fmt.Errorf("env set to %#v when binary is not set", e)
}
em, ok := e.(map[string]interface{})
if !ok {
return nil, fmt.Errorf("env %#v is not a map", e)
}
for k, v := range em {
vs, ok := v.(string)
if !ok {
return nil, fmt.Errorf("value %#v for key %q in env is not a string", v, k)
}
env[k] = vs
}
}
shutdown := true
if s, ok := caps["shutdown"]; ok {
sb, ok := s.(bool)
if !ok {
return nil, fmt.Errorf("shutdown %#v is not a boolean", s)
}
shutdown = sb
}
status := true
if s, ok := caps["status"]; ok {
sb, ok := s.(bool)
if !ok {
return nil, fmt.Errorf("status %#v is not a boolean", s)
}
status = sb
}
stdout := ""
if s, ok := caps["stdout"]; ok {
if binary == "" {
return nil, fmt.Errorf("stdout set to %#v when binary is not set", s)
}
sb, ok := s.(string)
if !ok {
return nil, fmt.Errorf("stdout %#v is not a string", s)
}
stdout = sb
}
stderr := ""
if s, ok := caps["stderr"]; ok {
if binary == "" {
return nil, fmt.Errorf("stderr set to %#v when binary is not set", s)
}
sb, ok := s.(string)
if !ok {
return nil, fmt.Errorf("stderr %#v is not a string", s)
}
stderr = sb
}
quitTimeout := 0 * time.Second
if t, ok := caps["quitTimeout"]; ok {
switch tt := t.(type) {
case float64:
// Incoming value is in seconds.
to, err := time.ParseDuration(fmt.Sprintf("%fs", tt))
if err != nil {
return nil, err
}
quitTimeout = to
case string:
to, err := time.ParseDuration(tt)
if err != nil {
return nil, err
}
quitTimeout = to
default:
return nil, fmt.Errorf("quitTimeout %#v is not a number or string", t)
}
}
return &wslCaps{
binary: binary,
args: args,
port: port,
timeout: timeout,
env: env,
shutdown: shutdown,
status: status,
stdout: stdout,
stderr: stderr,
quitTimeout: quitTimeout,
}, nil
}