@@ -9,76 +9,105 @@ import (
99 "github.com/stepbeta/vrsr/internal/utils"
1010)
1111
12+ var useOnInstall bool
13+
14+ type InstallCmdType int
15+
16+ const (
17+ InstallGitHubCmd InstallCmdType = iota
18+ InstallDownloadCmd
19+ )
20+
1221// newGithubInstallCommand creates a new 'install' command for the specified tool.
13- // Installation is done via GitHub releases.
14- func newGithubInstallCommand (tool string , repoConf github.RepoConfDef ) * cobra.Command {
15- return & cobra.Command {
22+ func newInstallCommand (tool string , repoConf github.RepoConfDef , installType InstallCmdType ) * cobra.Command {
23+ installCmd := & cobra.Command {
1624 Use : "install <version>" ,
1725 Short : fmt .Sprintf ("Download and install %s for the current OS/ARCH" , tool ),
1826 Long : fmt .Sprintf ("Download the %s binary for the current OS/ARCH at the specified version.\n \n " +
1927 "This binary will be saved into the path specified by the \" bin-path\" flag. It will be named \" %s-$version\" .\n \n " +
2028 "Make sure to check the \" use <version>\" command after installing a new version" , tool , tool ),
2129 Args : cobra .ExactArgs (1 ),
2230 RunE : func (cmd * cobra.Command , args []string ) error {
23- return installGithub (cmd , args [0 ], tool , repoConf )
31+ skipMsg := len (args ) > 1 && args [1 ] == "true"
32+ return install (cmd , args [0 ], tool , repoConf , installType , skipMsg )
2433 },
2534 }
35+ // Bind flags to Viper keys so config file / env / flags work together.
36+ installCmd .Flags ().BoolVarP (& useOnInstall , "use" , "u" , false , "Immediately use the version once installed (best effort)" )
37+ if err := viper .BindPFlag (fmt .Sprintf ("%s.install.use" , tool ), installCmd .Flags ().Lookup ("use" )); err != nil {
38+ installCmd .PrintErr (err )
39+ panic (err )
40+ }
41+ return installCmd
2642}
2743
28- // installGithub downloads and installs the specified version of the tool from GitHub releases
29- func installGithub (cmd * cobra.Command , vrs , tool string , repoConf github.RepoConfDef ) error {
44+ // install downloads and installs the specified version of the tool from GitHub releases
45+ func install (cmd * cobra.Command , vrs , tool string , repoConf github.RepoConfDef , installType InstallCmdType , skipMsg bool ) error {
3046 if utils .IsToolInUse (tool , vrs ) {
31- cmd .Printf ("%s version %s is already in use. Nothing to do\n " , tool , vrs )
47+ cmd .Printf ("%s version %s is already installed and in use. Nothing to do\n " , tool , vrs )
3248 return nil
3349 }
50+ useOnInstall = viper .GetBool (tool + ".install.use" )
3451 if utils .IsToolInstalled (tool , vrs ) {
3552 cmd .Printf ("%s version %s is already installed.\n " , tool , vrs )
36- cmd .Printf ("To switch to that version run `vrsr %s use %s`\n " , tool , vrs )
37- return nil
53+ if ! useOnInstall {
54+ if ! skipMsg {
55+ cmd .Printf ("To switch to that version run `vrsr %s use %s`\n " , tool , vrs )
56+ }
57+ return nil
58+ }
59+ if err := useOnInstallFn (cmd , vrs , tool ); err != nil {
60+ return err
61+ }
3862 }
3963
4064 vrsPath := viper .GetString ("vrs-path" )
41- ghc := github .New (nil )
42- if err := ghc .DownloadRelease (tool , vrs , vrsPath , repoConf ); err != nil {
43- return err
65+ // depending on the install type we use the appropriate install method
66+ switch installType {
67+ case InstallGitHubCmd :
68+ ghc := github .New (nil )
69+ if err := ghc .DownloadRelease (tool , vrs , vrsPath , repoConf ); err != nil {
70+ return err
71+ }
72+ case InstallDownloadCmd :
73+ if err := utils .DownloadBinary (repoConf .DownloadURL , tool , vrs , vrsPath , repoConf .Zipped ); err != nil {
74+ return err
75+ }
76+ default :
77+ return fmt .Errorf ("unknown install type" )
4478 }
45-
4679 cmd .Printf ("%s version %s successfully installed\n " , tool , vrs )
47- cmd .Printf ("To switch to that version run `vrsr %s use %s`\n " , tool , vrs )
48- return nil
49- }
5080
51- // newDownloadInstallCommand creates a new 'install' command for the specified tool
52- func newDownloadInstallCommand (tool string , repoConf github.RepoConfDef ) * cobra.Command {
53- return & cobra.Command {
54- Use : "install <version>" ,
55- Short : fmt .Sprintf ("Download and install %s for the current OS/ARCH" , tool ),
56- Long : fmt .Sprintf ("Download the %s binary for the current OS/ARCH at the specified version.\n \n " +
57- "This binary will be saved into the path specified by the \" bin-path\" flag. It will be named \" %s-$version\" .\n \n " +
58- "Make sure to check the \" use <version>\" command after installing a new version" , tool , tool ),
59- Args : cobra .ExactArgs (1 ),
60- RunE : func (cmd * cobra.Command , args []string ) error {
61- return installDownload (cmd , args [0 ], tool , repoConf )
62- },
81+ if ! useOnInstall {
82+ if ! skipMsg {
83+ cmd .Printf ("To switch to that version run `vrsr %s use %s`\n " , tool , vrs )
84+ }
85+ return nil
6386 }
87+ return useOnInstallFn (cmd , vrs , tool )
6488}
6589
66- // installDownload downloads and installs the specified version of the tool from GitHub releases
67- func installDownload (cmd * cobra.Command , vrs , tool string , repoConf github.RepoConfDef ) error {
68- if utils .IsToolInUse (tool , vrs ) {
69- cmd .Printf ("%s version %s is already in use. Nothing to do\n " , tool , vrs )
70- return nil
90+ // useOnInstallFn attempts to use the installed version immediately
91+ func useOnInstallFn (cmd * cobra.Command , vrs , tool string ) error {
92+ pCmd := cmd .Parent ()
93+ if pCmd == nil {
94+ // this is a sign of something wrong, so we return an error
95+ return fmt .Errorf ("internal error: install command has no parent" )
7196 }
72- if utils .IsToolInstalled (tool , vrs ) {
73- cmd .Printf ("%s version %s is already installed.\n " , tool , vrs )
97+ uCmd , _ , err := pCmd .Find ([]string {"use" })
98+ if err != nil || uCmd .Name () != "use" {
99+ cmd .Println ("could not find sibling 'use' command" )
100+ cmd .Println ("Skipping action" )
74101 cmd .Printf ("To switch to that version run `vrsr %s use %s`\n " , tool , vrs )
102+ // this is a best effort, if there's an error we just return
75103 return nil
76104 }
77- vrsPath := viper .GetString ("vrs-path" )
78- if err := utils .DownloadBinary (repoConf .DownloadURL , tool , vrs , vrsPath , repoConf .Zipped ); err != nil {
79- return err
105+ if err := uCmd .RunE (uCmd , []string {vrs }); err != nil {
106+ cmd .Println ("Error executing use:" , err )
107+ cmd .Println ("Skipping action" )
108+ cmd .Printf ("To switch to that version run `vrsr %s use %s`\n " , tool , vrs )
109+ // this is a best effort, if there's an error we just return
110+ return nil
80111 }
81- cmd .Printf ("%s version %s successfully installed\n " , tool , vrs )
82- cmd .Printf ("To switch to that version run `vrsr %s use %s`\n " , tool , vrs )
83112 return nil
84113}
0 commit comments