github.com/tomwright/dasel@v1.27.3/internal/command/update.go (about)

     1  // +build !noupdater
     2  
     3  package command
     4  
     5  import (
     6  	"errors"
     7  	"fmt"
     8  	"github.com/spf13/cobra"
     9  	"github.com/tomwright/dasel/internal/selfupdate"
    10  	"runtime"
    11  )
    12  
    13  type updateOpts struct {
    14  	Updater           *selfupdate.Updater
    15  	UpdateDevelopment bool
    16  }
    17  
    18  var (
    19  	// ErrHaveLatestVersion is returned when you are already on the latest version.
    20  	ErrHaveLatestVersion = errors.New("you already have the latest version")
    21  	// ErrNewerVersion is returned when you are on a newer version that the latest release.
    22  	ErrNewerVersion = errors.New("current version is newer than the latest release")
    23  	// ErrIgnoredDev is returned when your local version is development and you have not used the --dev flag.
    24  	ErrIgnoredDev = errors.New("ignoring update for development version")
    25  )
    26  
    27  func runUpdateCommand(opts updateOpts, cmd *cobra.Command) error {
    28  	currentVersion := opts.Updater.CurrentVersion()
    29  
    30  	out := cmd.OutOrStdout()
    31  
    32  	_, _ = fmt.Fprintf(out, "Updating...\nCurrent version: %s\n", currentVersion)
    33  
    34  	if currentVersion.IsDevelopment() && !opts.UpdateDevelopment {
    35  		return ErrIgnoredDev
    36  	}
    37  
    38  	release, err := opts.Updater.FindLatestRelease()
    39  	if err != nil {
    40  		return fmt.Errorf("could not find latest release: %w", err)
    41  	}
    42  
    43  	releaseVersion := release.Version()
    44  	_, _ = fmt.Fprintf(out, "Release version: %s\n", releaseVersion)
    45  
    46  	if !currentVersion.IsDevelopment() {
    47  		switch currentVersion.Compare(releaseVersion) {
    48  		case 1:
    49  			return ErrNewerVersion
    50  		case 0:
    51  			return ErrHaveLatestVersion
    52  		case -1:
    53  			// Latest version is newer.
    54  		}
    55  	}
    56  
    57  	asset := release.FindAssetForSystem(runtime.GOOS, runtime.GOARCH)
    58  	if asset == nil {
    59  		return fmt.Errorf("could not find asset for %s %s", runtime.GOOS, runtime.GOARCH)
    60  	}
    61  
    62  	downloadPath, err := opts.Updater.DownloadAsset(asset)
    63  	if err != nil {
    64  		return fmt.Errorf("could not download asset: %w", err)
    65  	}
    66  
    67  	// Make sure the downloaded file is deleted if an error occurs.
    68  	defer opts.Updater.CleanUp(downloadPath)
    69  
    70  	latestVersion, err := opts.Updater.GetVersion(downloadPath)
    71  	if err != nil {
    72  		return fmt.Errorf("could not get version information: %w", err)
    73  	}
    74  
    75  	_, _ = fmt.Fprintf(out, "New version: %s\n", latestVersion)
    76  
    77  	if err := opts.Updater.Replace(downloadPath); err != nil {
    78  		return err
    79  	}
    80  
    81  	_, _ = fmt.Fprintln(out, "Successfully updated")
    82  
    83  	return nil
    84  }
    85  
    86  func updateCommand(updater *selfupdate.Updater) *cobra.Command {
    87  	var updateDevFlag bool
    88  	cmd := &cobra.Command{
    89  		Use:   "update",
    90  		Short: "Update dasel to the latest stable release.",
    91  		Args:  cobra.NoArgs,
    92  		RunE: func(cmd *cobra.Command, args []string) error {
    93  			dev, _ := cmd.Flags().GetBool("dev")
    94  			opts := updateOpts{
    95  				Updater:           updater,
    96  				UpdateDevelopment: dev,
    97  			}
    98  			return runUpdateCommand(opts, cmd)
    99  		},
   100  	}
   101  
   102  	cmd.Flags().BoolVar(&updateDevFlag, "dev", false, "Allow updates in development version of dasel.")
   103  
   104  	return cmd
   105  }