@@ -10,9 +10,10 @@ import (
1010 "regexp"
1111 "strings"
1212
13+ "github.com/carolynvs/magex/pkg/gopath"
14+
1315 "github.com/Masterminds/semver/v3"
1416 "github.com/carolynvs/magex/pkg/downloads"
15- "github.com/carolynvs/magex/pkg/gopath"
1617 "github.com/carolynvs/magex/shx"
1718 "github.com/carolynvs/magex/xplat"
1819)
@@ -45,31 +46,77 @@ func EnsureMage(defaultVersion string) error {
4546// is used as the minimum version and sets the allowed major version. For example,
4647// a defaultVersion of 1.2.3 would result in a constraint of ^1.2.3.
4748// When no defaultVersion is specified, the latest version is installed.
49+ //
50+ // Deprecated: Use EnsurePackageWith.
4851func EnsurePackage (pkg string , defaultVersion string , versionArgs ... string ) error {
49- cmd := getCommandName ( pkg )
52+ var versionCmd , allowedVersion string
5053
51- // Apply optional arguments: versionCmd, versionConstraint
52- versionCmd := ""
53- versionConstraint := ""
5454 if len (versionArgs ) > 0 {
5555 versionCmd = versionArgs [0 ]
5656 if len (versionArgs ) > 1 {
57- versionConstraint = versionArgs [1 ]
57+ allowedVersion = versionArgs [1 ]
5858 }
5959 }
6060
61+ return EnsurePackageWith (EnsurePackageOptions {
62+ Name : pkg ,
63+ DefaultVersion : defaultVersion ,
64+ AllowedVersion : allowedVersion ,
65+ VersionCommand : versionCmd ,
66+ })
67+ }
68+
69+ // EnsurePackageOptions are the set of options that can be passed to EnsurePackageWith.
70+ type EnsurePackageOptions struct {
71+ // Name of the Go package
72+ // Provide the name of the package that should be compiled into a cli,
73+ // such as github.com/gobuffalo/packr/v2/packr2
74+ Name string
75+
76+ // DefaultVersion is the version to install, if not found. When specified, and
77+ // AllowedVersion is not, DefaultVersion is used as the minimum version and sets
78+ // the allowed major version. For example, a DefaultVersion of 1.2.3 would result
79+ // in an AllowedVersion of ^1.2.3. When no DefaultVersion is specified, the
80+ // latest version is installed.
81+ DefaultVersion string
82+
83+ // AllowedVersion is a semver range that specifies which versions are acceptable
84+ // if found. For example, ^1.2.3 or 2.x. When unspecified, any installed version
85+ // is acceptable. See https://github.com/Masterminds/semver for further
86+ // documentation.
87+ AllowedVersion string
88+
89+ // Destination is the location where the CLI should be installed
90+ // Defaults to GOPATH/bin. Using ./bin is recommended to require build tools
91+ // without modifying the host environment.
92+ Destination string
93+
94+ // VersionCommand is the arguments to pass to the CLI to determine the installed version.
95+ // For example, "version" or "--version". When unspecified the CLI is called without any arguments.
96+ VersionCommand string
97+ }
98+
99+ // EnsurePackageWith checks if the package is installed and installs it if needed.
100+ func EnsurePackageWith (opts EnsurePackageOptions ) error {
101+ cmd := getCommandName (opts .Name )
102+
61103 // Default the constraint to [defaultVersion - next major)
62- if versionConstraint == "" {
63- versionConstraint = makeDefaultVersionConstraint (defaultVersion )
104+ if opts . AllowedVersion == "" {
105+ opts . AllowedVersion = makeDefaultVersionConstraint (opts . DefaultVersion )
64106 }
65107
66- found , err := IsCommandAvailable (cmd , versionCmd , versionConstraint )
108+ found , err := IsCommandAvailable (cmd , opts . VersionCommand , opts . AllowedVersion )
67109 if err != nil {
68110 return err
69111 }
70112
71113 if ! found {
72- return InstallPackage (pkg , defaultVersion )
114+ installOpts := InstallPackageOptions {
115+ Name : opts .Name ,
116+ Destination : opts .Destination ,
117+ Version : opts .DefaultVersion ,
118+ }
119+ return InstallPackageWith (installOpts )
73120 }
74121 return nil
75122}
@@ -91,26 +138,61 @@ func getCommandName(pkg string) string {
91138 return name
92139}
93140
141+ // InstallPackageOptions are the set of options that can be passed to InstallPackageWith.
142+ type InstallPackageOptions struct {
143+ // Name of the Go package
144+ // Provide the name of the package that should be compiled into a cli,
145+ // such as github.com/gobuffalo/packr/v2/packr2
146+ Name string
147+
148+ // Destination is the location where the CLI should be installed
149+ // Defaults to GOPATH/bin. Using ./bin is recommended to require build tools
150+ // without modifying the host environment.
151+ Destination string
152+
153+ // Version of the package to install.
154+ Version string
155+ }
156+
94157// InstallPackage installs the latest version of a package.
95158//
96- // When version is specified, install that version. Otherwise install the most
159+ // When version is specified, install that version. Otherwise, install the most
97160// recent version.
161+ // Deprecated: Use InstallPackageWith instead.
98162func InstallPackage (pkg string , version string ) error {
99- gopath .EnsureGopathBin ()
163+ opts := InstallPackageOptions {
164+ Name : pkg ,
165+ Version : version ,
166+ }
167+ return InstallPackageWith (opts )
168+ }
100169
101- cmd := getCommandName (pkg )
170+ // InstallPackageWith unconditionally installs a package
171+ func InstallPackageWith (opts InstallPackageOptions ) error {
172+ cmd := getCommandName (opts .Name )
102173
103- if version == "" {
104- version = "latest"
174+ if opts . Version == "" {
175+ opts . Version = "latest"
105176 } else {
106- if version != "latest" && ! strings .HasPrefix (version , "v" ) {
107- version = "v" + version
177+ if opts . Version != "latest" && ! strings .HasPrefix (opts . Version , "v" ) {
178+ opts . Version = "v" + opts . Version
108179 }
109180 }
110181
111- fmt .Printf ("Installing %s@%s\n " , cmd , version )
112- return shx .Command ("go" , "install" , pkg + "@" + version ).
113- Env ("GO111MODULE=on" ).In (os .TempDir ()).RunE ()
182+ installCmd := shx .Command ("go" , "install" , opts .Name + "@" + opts .Version ).
183+ Env ("GO111MODULE=on" ).In (os .TempDir ())
184+ if opts .Destination == "" {
185+ gopath .EnsureGopathBin ()
186+ fmt .Printf ("Installing %s@%s into GOPATH/bin\n " , cmd , opts .Version )
187+ } else {
188+ dest , err := filepath .Abs (opts .Destination )
189+ if err != nil {
190+ return fmt .Errorf ("error converting %s to an absolute path" , opts .Destination )
191+ }
192+ installCmd .Env ("GOBIN=" + dest )
193+ fmt .Printf ("Installing %s@%s into %s\n " , cmd , opts .Version , dest )
194+ }
195+ return installCmd .RunE ()
114196}
115197
116198// InstallMage mage into GOPATH and add GOPATH/bin to PATH if necessary.
0 commit comments