github.com/henvic/wedeploycli@v1.7.6-0.20200319005353-3630f582f284/command/update/update.go (about)

     1  package update
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"os"
     7  
     8  	"github.com/henvic/wedeploycli/fancy"
     9  	"github.com/henvic/wedeploycli/isterm"
    10  	"github.com/henvic/wedeploycli/update"
    11  
    12  	version "github.com/hashicorp/go-version"
    13  	"github.com/henvic/wedeploycli/command/canceled"
    14  	"github.com/henvic/wedeploycli/command/internal/we"
    15  	"github.com/henvic/wedeploycli/command/update/releasenotes"
    16  	"github.com/henvic/wedeploycli/defaults"
    17  	"github.com/henvic/wedeploycli/verbose"
    18  	"github.com/spf13/cobra"
    19  )
    20  
    21  // UpdateCmd is used for updating this tool
    22  var UpdateCmd = &cobra.Command{
    23  	Use:   "update",
    24  	Args:  cobra.NoArgs,
    25  	RunE:  updateRun,
    26  	Short: "Update CLI to the latest version",
    27  }
    28  
    29  var (
    30  	channel       string
    31  	updateVersion string
    32  )
    33  
    34  func updateRun(cmd *cobra.Command, args []string) error {
    35  	var wectx = we.Context()
    36  	var conf = wectx.Config()
    37  	var params = conf.GetParams()
    38  
    39  	if !cmd.Flag("channel").Changed {
    40  		channel = params.ReleaseChannel
    41  	}
    42  
    43  	if err := checkDowngrade(); err != nil {
    44  		return err
    45  	}
    46  
    47  	return update.Update(context.Background(), wectx.Config(), channel, updateVersion)
    48  }
    49  
    50  func checkDowngrade() error {
    51  	if updateVersion == "" {
    52  		verbose.Debug("updating to latest available version")
    53  		return nil
    54  	}
    55  
    56  	fromV, fromErr := version.NewVersion(defaults.Version)
    57  	toV, toErr := version.NewVersion(updateVersion)
    58  
    59  	if fromErr != nil {
    60  		verbose.Debug(fmt.Sprintf("bypassing checking updating: current version error: %v", fromErr))
    61  		return nil
    62  	}
    63  
    64  	if toErr != nil {
    65  		verbose.Debug(fmt.Sprintf("checking updating to newer version: %v", toErr))
    66  		fmt.Printf("You are using version %s\n", defaults.Version)
    67  		return confirmDowngrade("New version doesn't follow semantic versioning. Update anyway?")
    68  	}
    69  
    70  	if toV.GreaterThan(fromV) {
    71  		return nil
    72  	}
    73  
    74  	fmt.Printf("You are using version %s\n", defaults.Version)
    75  	return confirmDowngrade("Downgrade to version " + updateVersion + "?")
    76  }
    77  
    78  func confirmDowngrade(question string) error {
    79  	if !isterm.Check() {
    80  		verbose.Debug("skipping checking newer version: no tty")
    81  		return nil
    82  	}
    83  
    84  	ok, err := fancy.Boolean(question)
    85  
    86  	if err != nil {
    87  		fmt.Fprintf(os.Stderr, "bypassing confirming new version: %v\n", err)
    88  		return nil
    89  	}
    90  
    91  	if !ok {
    92  		return canceled.CancelCommand("update canceled")
    93  	}
    94  
    95  	return nil
    96  }
    97  
    98  func init() {
    99  	UpdateCmd.Flags().StringVar(&channel, "channel", defaults.StableReleaseChannel, "Release channel")
   100  	UpdateCmd.Flags().StringVar(&updateVersion, "version", "", "Update to a specific version")
   101  	UpdateCmd.AddCommand(releasenotes.Cmd)
   102  
   103  	UpdateCmd.Flag("version").Hidden = true
   104  }