1
1
package commands
2
2
3
3
import (
4
+ ioutils "github.com/jfrog/jfrog-client-go/utils/io"
5
+ "github.com/mholt/archiver/v3"
4
6
"net/http"
5
7
"os"
6
8
"path/filepath"
7
9
"strings"
8
10
9
11
"github.com/jfrog/jfrog-cli-core/v2/utils/config"
12
+ "github.com/jfrog/jfrog-cli-core/v2/utils/plugins"
10
13
commandsUtils "github.com/jfrog/jfrog-cli/plugins/commands/utils"
11
14
clientUtils "github.com/jfrog/jfrog-client-go/utils"
12
15
@@ -30,6 +33,10 @@ func InstallCmd(c *cli.Context) error {
30
33
if err != nil {
31
34
return err
32
35
}
36
+ err = plugins .CheckPluginsVersionAndConvertIfNeeded ()
37
+ if err != nil {
38
+ return err
39
+ }
33
40
return runInstallCmd (c .Args ().Get (0 ))
34
41
}
35
42
@@ -44,26 +51,26 @@ func runInstallCmd(requestedPlugin string) error {
44
51
return err
45
52
}
46
53
47
- url , httpDetails , err := getServerDetails ()
54
+ url , serverDetails , err := getServerDetails ()
48
55
if err != nil {
49
56
return err
50
57
}
51
58
52
- pluginRtPath , err := getRequiredPluginRtPath (pluginName , version )
59
+ pluginRtDirPath , err := getRequiredPluginRtDirPath (pluginName , version )
53
60
if err != nil {
54
61
return err
55
62
}
56
- downloadUrl := clientUtils .AddTrailingSlashIfNeeded (url ) + pluginRtPath
63
+ execDownloadUrl := clientUtils .AddTrailingSlashIfNeeded (url ) + pluginRtDirPath + "/"
57
64
58
- should , err := shouldDownloadPlugin (pluginsDir , pluginName , downloadUrl , httpDetails )
65
+ should , err := shouldDownloadPlugin (pluginsDir , pluginName , execDownloadUrl , commandsUtils . CreatePluginsHttpDetails ( & serverDetails ) )
59
66
if err != nil {
60
67
return err
61
68
}
62
69
if ! should {
63
70
return errorutils .CheckErrorf ("the plugin with the requested version already exists locally" )
64
71
}
65
72
66
- return downloadPlugin (pluginsDir , pluginName , downloadUrl , httpDetails )
73
+ return downloadPlugin (pluginsDir , pluginName , execDownloadUrl , commandsUtils . CreatePluginsHttpDetails ( & serverDetails ) )
67
74
}
68
75
69
76
// Assert repo env is not passed without server env.
@@ -99,22 +106,22 @@ func createPluginsDirIfNeeded() (string, error) {
99
106
}
100
107
101
108
// Use the server ID if provided, else use the official registry.
102
- func getServerDetails () (string , httputils. HttpClientDetails , error ) {
109
+ func getServerDetails () (string , config. ServerDetails , error ) {
103
110
serverId := os .Getenv (commandsUtils .PluginsServerEnv )
104
111
if serverId == "" {
105
- return commandsUtils .PluginsOfficialRegistryUrl , httputils. HttpClientDetails { }, nil
112
+ return commandsUtils .PluginsOfficialRegistryUrl , config. ServerDetails { ArtifactoryUrl : commandsUtils . PluginsOfficialRegistryUrl }, nil
106
113
}
107
114
108
115
rtDetails , err := config .GetSpecificConfig (serverId , false , true )
109
116
if err != nil {
110
- return "" , httputils. HttpClientDetails {}, err
117
+ return "" , config. ServerDetails {}, err
111
118
}
112
- return rtDetails .ArtifactoryUrl , commandsUtils . CreatePluginsHttpDetails ( rtDetails ) , nil
119
+ return rtDetails .ArtifactoryUrl , * rtDetails , nil
113
120
}
114
121
115
122
// Checks if the requested plugin exists in registry and does not exists locally.
116
123
func shouldDownloadPlugin (pluginsDir , pluginName , downloadUrl string , httpDetails httputils.HttpClientDetails ) (bool , error ) {
117
- exists , err := fileutils .IsFileExists (filepath .Join (pluginsDir , commandsUtils . GetLocalPluginExecutableName ( pluginName ) ), false )
124
+ exists , err := fileutils .IsDirExists (filepath .Join (pluginsDir , pluginName ), false )
118
125
if err != nil {
119
126
return false , err
120
127
}
@@ -137,38 +144,30 @@ func shouldDownloadPlugin(pluginsDir, pluginName, downloadUrl string, httpDetail
137
144
if err != nil {
138
145
return false , err
139
146
}
140
- equal , err := fileutils .IsEqualToLocalFile (filepath .Join (pluginsDir , pluginName ), details .Checksum .Md5 , details .Checksum .Sha1 )
147
+ equal , err := fileutils .IsEqualToLocalFile (filepath .Join (pluginsDir , pluginName , coreutils . PluginsExecDirName , plugins . GetLocalPluginExecutableName ( pluginName ) ), details .Checksum .Md5 , details .Checksum .Sha1 )
141
148
return ! equal , err
142
149
}
143
150
144
- // Returns the path of the plugin's executable in registry, corresponding to the local architecture.
145
- func getRequiredPluginRtPath (pluginName , version string ) (string , error ) {
151
+ // Returns the path of the JFrog CLI plugin's directory in registry, corresponding to the local architecture.
152
+ func getRequiredPluginRtDirPath (pluginName , version string ) (pluginDirRtPath string , err error ) {
146
153
arc , err := commandsUtils .GetLocalArchitecture ()
147
154
if err != nil {
148
- return "" , err
155
+ return
149
156
}
150
- return commandsUtils .GetPluginPathInArtifactory (pluginName , version , arc ), nil
157
+ pluginDirRtPath = commandsUtils .GetPluginDirPath (pluginName , version , arc )
158
+ return
151
159
}
152
160
153
161
func createPluginsDir (pluginsDir string ) error {
154
- return os .MkdirAll (pluginsDir , 0777 )
162
+ err := os .MkdirAll (pluginsDir , 0777 )
163
+ if err != nil {
164
+ return errorutils .CheckError (err )
165
+ }
166
+ _ , err = plugins .CreatePluginsConfigFile ()
167
+ return err
155
168
}
156
169
157
170
func downloadPlugin (pluginsDir , pluginName , downloadUrl string , httpDetails httputils.HttpClientDetails ) (err error ) {
158
- exeName := commandsUtils .GetLocalPluginExecutableName (pluginName )
159
- log .Debug ("Downloading plugin from: " , downloadUrl )
160
- downloadDetails := & httpclient.DownloadFileDetails {
161
- FileName : pluginName ,
162
- DownloadPath : downloadUrl ,
163
- LocalPath : pluginsDir ,
164
- LocalFileName : exeName ,
165
- RelativePath : exeName ,
166
- }
167
-
168
- client , err := httpclient .ClientBuilder ().Build ()
169
- if err != nil {
170
- return
171
- }
172
171
// Init progress bar.
173
172
progressMgr , logFile , err := progressbar .InitProgressBarIfPossible (false )
174
173
if err != nil {
@@ -185,19 +184,16 @@ func downloadPlugin(pluginsDir, pluginName, downloadUrl string, httpDetails http
185
184
}
186
185
}()
187
186
}
188
- log .Info ("Downloading plugin: " + pluginName )
189
187
190
- resp , err := client . DownloadFileWithProgress ( downloadDetails , "" , httpDetails , false , progressMgr )
188
+ err = downloadPluginExec ( downloadUrl , pluginName , pluginsDir , httpDetails , progressMgr )
191
189
if err != nil {
192
190
return
193
191
}
194
- log .Debug ("Artifactory response: " , resp .Status )
195
- err = errorutils .CheckResponseStatus (resp , http .StatusOK )
192
+ err = downloadPluginsResources (downloadUrl , pluginName , pluginsDir , httpDetails , progressMgr )
196
193
if err != nil {
197
194
return
198
195
}
199
- log .Debug ("Plugin downloaded successfully." )
200
- err = os .Chmod (filepath .Join (pluginsDir , exeName ), 0777 )
196
+ log .Info ("Plugin downloaded successfully." )
201
197
return
202
198
}
203
199
@@ -211,3 +207,74 @@ func getNameAndVersion(requested string) (name, version string, err error) {
211
207
}
212
208
return split [0 ], split [1 ], nil
213
209
}
210
+
211
+ func downloadPluginExec (downloadUrl , pluginName , pluginsDir string , httpDetails httputils.HttpClientDetails , progressMgr ioutils.ProgressMgr ) (err error ) {
212
+ exeName := plugins .GetLocalPluginExecutableName (pluginName )
213
+ downloadDetails := & httpclient.DownloadFileDetails {
214
+ FileName : pluginName ,
215
+ DownloadPath : clientUtils .AddTrailingSlashIfNeeded (downloadUrl ) + exeName ,
216
+ LocalPath : filepath .Join (pluginsDir , pluginName , coreutils .PluginsExecDirName ),
217
+ LocalFileName : exeName ,
218
+ RelativePath : exeName ,
219
+ }
220
+ log .Debug ("Downloading plugin's executable from: " , downloadDetails .DownloadPath )
221
+ _ , err = downloadFromArtifactory (downloadDetails , httpDetails , progressMgr )
222
+ if err != nil {
223
+ return
224
+ }
225
+ err = os .Chmod (filepath .Join (downloadDetails .LocalPath , downloadDetails .LocalFileName ), 0777 )
226
+ if errorutils .CheckError (err ) != nil {
227
+ return
228
+ }
229
+ log .Debug ("Plugin's executable downloaded successfully." )
230
+ return
231
+ }
232
+
233
+ func downloadPluginsResources (downloadUrl , pluginName , pluginsDir string , httpDetails httputils.HttpClientDetails , progressMgr ioutils.ProgressMgr ) (err error ) {
234
+ downloadDetails := & httpclient.DownloadFileDetails {
235
+ FileName : pluginName ,
236
+ DownloadPath : clientUtils .AddTrailingSlashIfNeeded (downloadUrl ) + coreutils .PluginsResourcesDirName + ".zip" ,
237
+ LocalPath : filepath .Join (pluginsDir , pluginName ),
238
+ LocalFileName : coreutils .PluginsResourcesDirName + ".zip" ,
239
+ RelativePath : coreutils .PluginsResourcesDirName + ".zip" ,
240
+ }
241
+ log .Debug ("Downloading plugin's resources from: " , downloadDetails .DownloadPath )
242
+ statusCode , err := downloadFromArtifactory (downloadDetails , httpDetails , progressMgr )
243
+ if err != nil {
244
+ return
245
+ }
246
+ if statusCode == http .StatusNotFound {
247
+ log .Debug ("No resources were downloaded." )
248
+ return nil
249
+ }
250
+ err = archiver .Unarchive (filepath .Join (downloadDetails .LocalPath , downloadDetails .LocalFileName ), filepath .Join (downloadDetails .LocalPath , coreutils .PluginsResourcesDirName )+ string (os .PathSeparator ))
251
+ if errorutils .CheckError (err ) != nil {
252
+ return
253
+ }
254
+ err = os .Remove (filepath .Join (downloadDetails .LocalPath , downloadDetails .LocalFileName ))
255
+ if err != nil {
256
+ return
257
+ }
258
+ err = coreutils .ChmodPluginsDirectoryContent ()
259
+ if errorutils .CheckError (err ) != nil {
260
+ return
261
+ }
262
+ log .Debug ("Plugin's resources downloaded successfully." )
263
+ return
264
+ }
265
+
266
+ func downloadFromArtifactory (downloadDetails * httpclient.DownloadFileDetails , httpDetails httputils.HttpClientDetails , progressMgr ioutils.ProgressMgr ) (statusCode int , err error ) {
267
+ client , err := httpclient .ClientBuilder ().Build ()
268
+ if err != nil {
269
+ return
270
+ }
271
+ log .Info ("Downloading: " + downloadDetails .FileName )
272
+ resp , err := client .DownloadFileWithProgress (downloadDetails , "" , httpDetails , false , progressMgr )
273
+ if err != nil {
274
+ return
275
+ }
276
+ statusCode = resp .StatusCode
277
+ log .Debug ("Artifactory response: " , statusCode )
278
+ err = errorutils .CheckResponseStatus (resp , http .StatusOK , http .StatusNotFound )
279
+ return
280
+ }
0 commit comments