6
6
"os"
7
7
"path/filepath"
8
8
"regexp"
9
+ "slices"
9
10
"strings"
10
11
11
12
"github.com/tarantool/tt/cli/install"
@@ -17,12 +18,6 @@ import (
17
18
)
18
19
19
20
const (
20
- progRegexp = "(?P<prog>" +
21
- search .ProgramTt + "|" +
22
- search .ProgramCe + "|" +
23
- search .ProgramEe + ")"
24
- verRegexp = "(?P<ver>.*)"
25
-
26
21
MajorMinorPatchRegexp = `^[0-9]+\.[0-9]+\.[0-9]+`
27
22
)
28
23
@@ -170,31 +165,15 @@ func getAllTtVersionFormats(programName, ttVersion string) ([]string, error) {
170
165
171
166
// getDefault returns a default version of an installed program.
172
167
func getDefault (program , dir string ) (string , error ) {
173
- var ver string
174
-
175
- re := regexp .MustCompile (
176
- "^" + program + version .FsSeparator + verRegexp + "$" ,
177
- )
178
-
179
- installedPrograms , err := os .ReadDir (dir )
180
- if err != nil {
181
- return "" , err
182
- }
183
-
184
- for _ , file := range installedPrograms {
185
- matches := util .FindNamedMatches (re , file .Name ())
186
- if ver != "" {
187
- return "" , fmt .Errorf ("%s has more than one installed version, " +
188
- "please specify the version to uninstall" , program )
189
- } else {
190
- ver = matches ["ver" ]
191
- }
192
- }
193
-
194
- if ver == "" {
168
+ versions := GetAvailableVersions (program , dir )
169
+ if len (versions ) == 0 {
195
170
return "" , fmt .Errorf ("%s has no installed version" , program )
196
171
}
197
- return ver , nil
172
+ if len (versions ) > 1 {
173
+ return "" , fmt .Errorf ("%s has more than one installed version, " +
174
+ "please specify the version to uninstall" , program )
175
+ }
176
+ return versions [0 ], nil
198
177
}
199
178
200
179
// GetAvailableVersions returns a list of the program's versions installed into
@@ -220,82 +199,43 @@ func GetAvailableVersions(program string, dir string) []string {
220
199
}
221
200
222
201
// searchLatestVersion searches for the latest installed version of the program.
223
- func searchLatestVersion (linkName , binDst , headerDst string ) (string , error ) {
224
- var programsToSearch []string
225
- if linkName == "tarantool" {
226
- programsToSearch = []string {search .ProgramCe , search .ProgramEe }
227
- } else {
228
- programsToSearch = []string {linkName }
229
- }
230
-
231
- programRegex := regexp .MustCompile (
232
- "^" + progRegexp + version .FsSeparator + verRegexp + "$" ,
233
- )
234
-
235
- binaries , err := os .ReadDir (binDst )
236
- if err != nil {
237
- return "" , err
238
- }
239
-
240
- latestVersionInfo := version.Version {}
241
- latestVersion := ""
242
- hashFound := false
243
- latestHash := ""
244
-
245
- for _ , binary := range binaries {
246
- if binary .IsDir () {
202
+ func searchLatestVersion (program , binDst , headerDst string ) (string , error ) {
203
+ binVersions := GetAvailableVersions (program , binDst )
204
+ headerVersions := GetAvailableVersions (program , headerDst )
205
+
206
+ // Find intersection and convert to version.Version
207
+ versions := []version.Version {}
208
+ for _ , binVersion := range binVersions {
209
+ binFileInfo , err := os .Stat (program + version .FsSeparator + binVersion )
210
+ if err != nil || binFileInfo .IsDir () {
247
211
continue
248
212
}
249
- binaryName := binary .Name ()
250
- matches := util .FindNamedMatches (programRegex , binaryName )
251
213
252
- // Need to match for the program and version.
253
- if len (matches ) != 2 {
254
- log .Debugf ("%q skipped: unexpected format" , binaryName )
255
- continue
256
- }
257
-
258
- programName := matches ["prog" ]
259
- // Need to find the program in the list of suitable.
260
- if util .Find (programsToSearch , programName ) == - 1 {
261
- continue
262
- }
263
- isRightFormat , _ := util .IsValidCommitHash (matches ["ver" ])
264
-
265
- if isRightFormat {
266
- if hashFound {
214
+ if slices .Contains (headerVersions , binVersion ) {
215
+ ver , err := version .Parse (binVersion )
216
+ if err != nil {
267
217
continue
268
218
}
269
- if strings .Contains (programName , "tarantool" ) {
270
- // Check for headers.
271
- if _ , err := os .Stat (filepath .Join (headerDst , binaryName )); os .IsNotExist (err ) {
272
- continue
273
- }
274
- }
275
- hashFound = true
276
- latestHash = binaryName
277
- continue
278
- }
279
- ver , err := version .Parse (matches ["ver" ])
280
- if err != nil {
281
- continue
282
- }
283
- if strings .Contains (programName , "tarantool" ) {
284
- // Check for headers.
285
- if _ , err := os .Stat (filepath .Join (headerDst , binaryName )); os .IsNotExist (err ) {
286
- continue
287
- }
288
- }
289
- // Update latest version.
290
- if latestVersion == "" || version .IsLess (latestVersionInfo , ver ) {
291
- latestVersionInfo = ver
292
- latestVersion = binaryName
219
+ versions = append (versions , ver )
293
220
}
294
221
}
295
- if latestVersion != "" {
296
- return latestVersion , nil
222
+
223
+ if len (versions ) == 0 {
224
+ return "" , fmt .Errorf ("no version found" )
297
225
}
298
- return latestHash , nil
226
+
227
+ latestVersion := slices .MaxFunc (versions , func (a , b version.Version ) int {
228
+ if a .Str == b .Str {
229
+ return 0
230
+ }
231
+ isCommitHash , _ := util .IsValidCommitHash (a .Str )
232
+ if isCommitHash || version .IsLess (a , b ) {
233
+ return - 1
234
+ }
235
+ return 1
236
+ })
237
+
238
+ return program + version .FsSeparator + latestVersion .Str , nil
299
239
}
300
240
301
241
// switchProgramToLatestVersion switches the active version of the program to the latest installed.
@@ -305,7 +245,7 @@ func switchProgramToLatestVersion(program, binDst, headerDst string) error {
305
245
linkName = "tarantool"
306
246
}
307
247
308
- progToSwitch , err := searchLatestVersion (linkName , binDst , headerDst )
248
+ progToSwitch , err := searchLatestVersion (program , binDst , headerDst )
309
249
if err != nil {
310
250
return err
311
251
}
0 commit comments