diff --git a/cli/apiconfig.go b/cli/apiconfig.go index 96f76a6..5e069ab 100644 --- a/cli/apiconfig.go +++ b/cli/apiconfig.go @@ -32,6 +32,7 @@ type TLSConfig struct { // APIProfile contains account-specific API information type APIProfile struct { + Base string `json:"base",omitempty` Headers map[string]string `json:"headers,omitempty"` Query map[string]string `json:"query,omitempty"` Auth *APIAuth `json:"auth"` @@ -189,9 +190,23 @@ func initAPIConfig() { func findAPI(uri string) (string, *APIConfig) { for name, config := range configs { - if strings.HasPrefix(uri, config.Base) { - // TODO: find the longest matching base? - return name, config + profile := viper.GetString("rsh-profile") + if profile != "default" { + if config.Profiles[profile] == nil { + continue + } + if config.Profiles[profile].Base != "" { + if strings.HasPrefix(uri, config.Profiles[profile].Base) { + return name, config + } + } else if strings.HasPrefix(uri, config.Base) { + return name, config + } + } else { + if strings.HasPrefix(uri, config.Base) { + // TODO: find the longest matching base? + return name, config + } } } diff --git a/cli/cli.go b/cli/cli.go index 13906b1..5344356 100644 --- a/cli/cli.go +++ b/cli/cli.go @@ -116,7 +116,17 @@ func completeCurrentConfig(cmd *cobra.Command, args []string, toComplete string, for _, cmd := range Root.Commands() { if cmd.Use == currentConfig.name { // This is the matching command. Load the URL and check each operation. - api, _ := Load(currentConfig.Base, cmd) + currentBase := currentConfig.Base + currentProfile := currentConfig.Profiles[viper.GetString("rsh-profile")] + if currentProfile == nil { + if viper.GetString("rsh-profile") != "default" { + panic("Invalid profile " + viper.GetString("rsh-profile")) + } + } + if currentProfile != nil && currentProfile.Base != "" { + currentBase = currentProfile.Base + } + api, _ := Load(currentBase, cmd) for _, op := range api.Operations { if op.Method != method { // We only care about operations which match the currently selected @@ -679,6 +689,7 @@ func Run() { if headers, _ := GlobalFlags.GetStringSlice("rsh-header"); len(headers) > 0 { viper.Set("rsh-header", headers) } + profile, _ := GlobalFlags.GetString("rsh-profile") // Now that global flags are parsed we can enable verbose mode if requested. if viper.GetBool("rsh-verbose") { @@ -704,7 +715,17 @@ func Run() { currentConfig = cfg for _, cmd := range Root.Commands() { if cmd.Use == apiName { - if _, err := Load(cfg.Base, cmd); err != nil { + currentBase := cfg.Base + currentProfile := cfg.Profiles[profile] + if currentProfile == nil { + if profile != "default" { + panic("Invalid profile " + profile) + } + } + if currentProfile != nil && currentProfile.Base != "" { + currentBase = currentProfile.Base + } + if _, err := Load(currentBase, cmd); err != nil { panic(err) } loaded = true diff --git a/cli/interactive.go b/cli/interactive.go index c3ac832..eb8f732 100644 --- a/cli/interactive.go +++ b/cli/interactive.go @@ -241,6 +241,11 @@ func askEditProfile(a asker, name string, profile *APIProfile) { options = append(options, "Delete query param "+k) } + options = append(options, "Add custom base URL") + if profile.Base != "" { + options = append(options, "Remove custom base URL") + } + options = append(options, "Setup auth", "Finished with profile") choice := a.askSelect("Select option for profile `"+name+"`", options, nil, "") @@ -275,6 +280,11 @@ func askEditProfile(a asker, name string, profile *APIProfile) { profile.Auth = &APIAuth{} } askAuth(a, profile.Auth) + case choice == "Add custom base URL": + url := a.askInput("Base URL", "", true, "") + profile.Base = url + case choice == "Remove custom base URL": + profile.Base = "" case choice == "Finished with profile": return } diff --git a/cli/request.go b/cli/request.go index 5d0be72..50893dd 100644 --- a/cli/request.go +++ b/cli/request.go @@ -26,9 +26,20 @@ func fixAddress(addr string) string { // the base URL for that API. parts := strings.Split(addr, "/") c := configs[parts[0]] - if c != nil && c.Base != "" { - parts[0] = c.Base - return strings.Join(parts, "/") + if c != nil { + p := c.Profiles[viper.GetString("rsh-profile")] + if p == nil { + if viper.GetString("rsh-profile") != "default" { + panic("Invalid profile " + viper.GetString("rsh-profile")) + } + } + if p != nil && p.Base != "" { + parts[0] = p.Base + return strings.Join(parts, "/") + } else if c.Base != "" { + parts[0] = c.Base + return strings.Join(parts, "/") + } } // Local traffic defaults to HTTP, everything else uses TLS. @@ -82,7 +93,6 @@ func MakeRequest(req *http.Request, options ...requestOption) (*http.Response, e if viper.GetString("rsh-profile") != "default" { panic("Invalid profile " + viper.GetString("rsh-profile")) } - profile = &APIProfile{} }