Skip to content

Commit

Permalink
feat(variable): Allow updating variables from .env file (#104)
Browse files Browse the repository at this point in the history
  • Loading branch information
pan93412 authored Aug 2, 2024
1 parent ecce42f commit 98ba157
Show file tree
Hide file tree
Showing 4 changed files with 117 additions and 0 deletions.
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ require (
github.com/coreos/go-semver v0.3.0
github.com/fatih/color v1.13.0
github.com/google/go-github v17.0.0+incompatible
github.com/hashicorp/go-envparse v0.1.0
github.com/hasura/go-graphql-client v0.9.3
github.com/onsi/ginkgo/v2 v2.11.0
github.com/onsi/gomega v1.27.8
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,8 @@ github.com/graph-gophers/graphql-go v1.5.0 h1:fDqblo50TEpD0LY7RXk/LFVYEVqo3+tXMN
github.com/graph-gophers/graphql-go v1.5.0/go.mod h1:YtmJZDLbF1YYNrlNAuiO5zAStUWc3XZT07iGsVqe1Os=
github.com/graph-gophers/graphql-transport-ws v0.0.2 h1:DbmSkbIGzj8SvHei6n8Mh9eLQin8PtA8xY9eCzjRpvo=
github.com/graph-gophers/graphql-transport-ws v0.0.2/go.mod h1:5BVKvFzOd2BalVIBFfnfmHjpJi/MZ5rOj8G55mXvZ8g=
github.com/hashicorp/go-envparse v0.1.0 h1:bE++6bhIsNCPLvgDZkYqo3nA+/PFI51pkrHdmPSDFPY=
github.com/hashicorp/go-envparse v0.1.0/go.mod h1:OHheN1GoygLlAkTlXLXvAdnXdZxy8JUweQ1rAXx1xnc=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
Expand Down
112 changes: 112 additions & 0 deletions internal/cmd/variable/env/env.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
package env

import (
"context"
"fmt"
"os"

"github.com/briandowns/spinner"
"github.com/hashicorp/go-envparse"
"github.com/spf13/cobra"
"github.com/zeabur/cli/internal/cmdutil"
"github.com/zeabur/cli/internal/util"
"github.com/zeabur/cli/pkg/fill"
)

type Options struct {
id string
name string
environmentID string
envFilename string
}

func NewCmdEnvVariable(f *cmdutil.Factory) *cobra.Command {
opts := &Options{}
zctx := f.Config.GetContext()

cmd := &cobra.Command{
Use: "env",
Short: "update variables from .env",
Long: "overwrite variables from a .env file",
PreRunE: util.RunEChain(
util.NeedProjectContextWhenNonInteractive(f),
util.DefaultIDNameByContext(zctx.GetService(), &opts.id, &opts.name),
util.DefaultIDByContext(zctx.GetEnvironment(), &opts.environmentID),
),
RunE: func(cmd *cobra.Command, args []string) error {
return runUpdateVariableByEnv(f, opts)
},
}

util.AddServiceParam(cmd, &opts.id, &opts.name)
util.AddEnvOfServiceParam(cmd, &opts.environmentID)
cmd.Flags().StringVarP(&opts.envFilename, "file", "f", ".env", "Path to the .env file")

return cmd
}

func runUpdateVariableByEnv(f *cmdutil.Factory, opts *Options) error {
if _, err := os.Stat(opts.envFilename); err != nil {
if os.IsNotExist(err) {
return fmt.Errorf("file not found: %s", opts.envFilename)
}

return fmt.Errorf("file cannot open: %s (%w)", opts.envFilename, err)
}

return runUpdateVariableNonInteractive(f, opts)
}

func runUpdateVariableNonInteractive(f *cmdutil.Factory, opts *Options) error {
zctx := f.Config.GetContext()

if _, err := f.ParamFiller.ServiceByNameWithEnvironment(fill.ServiceByNameWithEnvironmentOptions{
ProjectCtx: zctx,
ServiceID: &opts.id,
ServiceName: &opts.name,
EnvironmentID: &opts.environmentID,
CreateNew: false,
}); err != nil {
return err
}

s := spinner.New(cmdutil.SpinnerCharSet, cmdutil.SpinnerInterval,
spinner.WithColor(cmdutil.SpinnerColor),
spinner.WithSuffix(fmt.Sprintf(" Updating variables of service: %s...", opts.name)),
)

// read files from .env
envFile, err := os.Open(opts.envFilename)
if err != nil {
return fmt.Errorf("open file: %w", err)
}
defer func() {
_ = envFile.Close()
}()

envMap, err := envparse.Parse(envFile)
if err != nil {
return fmt.Errorf("parse env file: %w", err)
}

createVarResult, err := f.ApiClient.UpdateVariables(context.Background(), opts.id, opts.environmentID, envMap)
if err != nil {
s.Stop()
return err
}
if !createVarResult {
s.Stop()
return fmt.Errorf("failed to update variables of service: %s", opts.name)
}
s.Stop()

f.Log.Infof("Successfully updated variables of service: %s\n\tRestart your service manually to apply the changes.\n", opts.name)

table := make([][]string, 0, len(envMap))
for k, v := range envMap {
table = append(table, []string{k, v})
}
f.Printer.Table([]string{"Key", "Value"}, table)

return nil
}
2 changes: 2 additions & 0 deletions internal/cmd/variable/variable.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (

variableCreateCmd "github.com/zeabur/cli/internal/cmd/variable/create"
varableDeleteCmd "github.com/zeabur/cli/internal/cmd/variable/delete"
variableEnvCmd "github.com/zeabur/cli/internal/cmd/variable/env"
variableListCmd "github.com/zeabur/cli/internal/cmd/variable/list"
variableUpdateCmd "github.com/zeabur/cli/internal/cmd/variable/update"
"github.com/zeabur/cli/internal/cmdutil"
Expand All @@ -22,6 +23,7 @@ func NewCmdVariable(f *cmdutil.Factory) *cobra.Command {
cmd.AddCommand(variableCreateCmd.NewCmdCreateVariable(f))
cmd.AddCommand(variableUpdateCmd.NewCmdUpdateVariable(f))
cmd.AddCommand(varableDeleteCmd.NewCmdDeleteVariable(f))
cmd.AddCommand(variableEnvCmd.NewCmdEnvVariable(f))

return cmd
}

0 comments on commit 98ba157

Please sign in to comment.