func extractWSLCaps()

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
}