diff --git a/cmd/variables.go b/cmd/variables.go index 4b259e3f5..e3d7a613c 100644 --- a/cmd/variables.go +++ b/cmd/variables.go @@ -63,6 +63,29 @@ func (h *Handler) VariablesSet(ctx context.Context, req *entity.CommandRequest) skipRedeploy = false } + replace, err := req.Cmd.Flags().GetBool("replace") + if err != nil { + // The flag is optional; default to false. + replace = false + } + + yes, err := req.Cmd.Flags().GetBool("yes") + if err != nil { + // The flag is optional; default to false. + yes = false + } + + if replace && !yes { + fmt.Println(ui.Bold(ui.RedText(fmt.Sprintf("Warning! You are about to fully replace all your variables for the service '%s'.", serviceName)).String())) + confirm, err := ui.PromptYesNo("Continue?") + if err != nil { + return err + } + if !confirm { + return nil + } + } + variables := &entity.Envs{} updatedEnvNames := make([]string, 0) @@ -78,7 +101,7 @@ func (h *Handler) VariablesSet(ctx context.Context, req *entity.CommandRequest) updatedEnvNames = append(updatedEnvNames, key) } - err = h.ctrl.UpsertEnvs(ctx, variables, &serviceName) + err = h.ctrl.UpdateEnvs(ctx, variables, &serviceName, replace) if err != nil { return err @@ -89,7 +112,12 @@ func (h *Handler) VariablesSet(ctx context.Context, req *entity.CommandRequest) return err } - fmt.Print(ui.Heading(fmt.Sprintf("Updated %s for \"%s\"", strings.Join(updatedEnvNames, ", "), environment.Name))) + operation := "Updated" + if replace { + operation = "Replaced existing variables with" + } + + fmt.Print(ui.Heading(fmt.Sprintf("%s %s for \"%s\"", operation, strings.Join(updatedEnvNames, ", "), environment.Name))) fmt.Print(ui.KeyValues(*variables)) if !skipRedeploy { diff --git a/controller/envs.go b/controller/envs.go index d33dc28c6..822f97485 100644 --- a/controller/envs.go +++ b/controller/envs.go @@ -104,7 +104,7 @@ func (c *Controller) AutoImportDotEnv(ctx context.Context) error { return err } if len(envMap) > 0 { - return c.UpsertEnvs(ctx, (*entity.Envs)(&envMap), nil) + return c.UpdateEnvs(ctx, (*entity.Envs)(&envMap), nil, false) } } return nil @@ -134,7 +134,7 @@ func (c *Controller) SaveEnvsToFile(ctx context.Context) error { return nil } -func (c *Controller) UpsertEnvs(ctx context.Context, envs *entity.Envs, serviceName *string) error { +func (c *Controller) UpdateEnvs(ctx context.Context, envs *entity.Envs, serviceName *string, replace bool) error { projectCfg, err := c.GetProjectConfigs(ctx) if err != nil { return err @@ -185,12 +185,13 @@ func (c *Controller) UpsertEnvs(ctx context.Context, envs *entity.Envs, serviceN } } - return c.gtwy.UpsertVariablesFromObject(ctx, &entity.UpdateEnvsRequest{ + return c.gtwy.UpdateVariablesFromObject(ctx, &entity.UpdateEnvsRequest{ ProjectID: projectCfg.Project, EnvironmentID: projectCfg.Environment, PluginID: pluginID, ServiceID: serviceID, Envs: envs, + Replace: replace, }) } diff --git a/entity/envs.go b/entity/envs.go index 0a490dd76..d285ef37c 100644 --- a/entity/envs.go +++ b/entity/envs.go @@ -18,6 +18,7 @@ type UpdateEnvsRequest struct { PluginID string ServiceID string Envs *Envs + Replace bool } type DeleteVariableRequest struct { diff --git a/gateway/envs.go b/gateway/envs.go index a82555661..3c3af2cc2 100644 --- a/gateway/envs.go +++ b/gateway/envs.go @@ -2,6 +2,7 @@ package gateway import ( "context" + "fmt" "github.com/railwayapp/cli/entity" ) @@ -32,12 +33,19 @@ func (g *Gateway) GetEnvs(ctx context.Context, req *entity.GetEnvsRequest) (*ent return resp.Envs, nil } -func (g *Gateway) UpsertVariablesFromObject(ctx context.Context, req *entity.UpdateEnvsRequest) error { - gqlReq, err := g.NewRequestWithAuth(` +func (g *Gateway) UpdateVariablesFromObject(ctx context.Context, req *entity.UpdateEnvsRequest) error { + queryName := "upsertVariablesFromObject" + + if req.Replace { + // When replacing, use the set query which will blow away all old variables and only set the ones in this query + queryName = "variablesSetFromObject" + } + + gqlReq, err := g.NewRequestWithAuth(fmt.Sprintf(` mutation($projectId: String!, $environmentId: String!, $pluginId: String, $serviceId: String, $variables: Json!) { - upsertVariablesFromObject(projectId: $projectId, environmentId: $environmentId, pluginId: $pluginId, serviceId: $serviceId, variables: $variables) + %s(projectId: $projectId, environmentId: $environmentId, pluginId: $pluginId, serviceId: $serviceId, variables: $variables) } - `) + `, queryName)) if err != nil { return err } diff --git a/main.go b/main.go index d3dfbcfa8..ba0bd724b 100644 --- a/main.go +++ b/main.go @@ -154,6 +154,8 @@ func init() { variablesCmd.AddCommand(variablesSetCmd) variablesSetCmd.Flags().StringP("service", "s", "", "Fetch variables accessible to a specific service") variablesSetCmd.Flags().Bool("skip-redeploy", false, "Skip redeploying the specified service after changing the variables") + variablesSetCmd.Flags().Bool("replace", false, "Fully replace all previous variables instead of updating them") + variablesSetCmd.Flags().Bool("yes", false, "Skip all confirmation dialogs") variablesDeleteCmd := &cobra.Command{ Use: "delete key",