Skip to content

Commit 1ea93e3

Browse files
committed
uninstall: reuse GetAvailableVersions
1 parent 545bb39 commit 1ea93e3

File tree

3 files changed

+134
-146
lines changed

3 files changed

+134
-146
lines changed

cli/cmd/uninstall.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ func uninstallValidArgsFunc(cmd *cobra.Command, args []string, toComplete string
1111
if len(args) > 0 {
1212
return []string{}, cobra.ShellCompDirectiveNoFileComp
1313
}
14-
return uninstall.GetAvailableVersions(cmd.Name(), cliOpts.Env.BinDir),
15-
cobra.ShellCompDirectiveNoFileComp
14+
versions, _ := uninstall.GetAvailableVersions(cmd.Name(), cliOpts.Env.BinDir)
15+
return versions, cobra.ShellCompDirectiveNoFileComp
1616
}
1717

1818
// newUninstallTtCmd creates a command to install tt.

cli/uninstall/uninstall.go

+44-93
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"os"
77
"path/filepath"
88
"regexp"
9+
"slices"
910
"strings"
1011

1112
"github.com/tarantool/tt/cli/install"
@@ -17,12 +18,6 @@ import (
1718
)
1819

1920
const (
20-
progRegexp = "(?P<prog>" +
21-
search.ProgramTt + "|" +
22-
search.ProgramCe + "|" +
23-
search.ProgramEe + ")"
24-
verRegexp = "(?P<ver>.*)"
25-
2621
MajorMinorPatchRegexp = `^[0-9]+\.[0-9]+\.[0-9]+`
2722
)
2823

@@ -180,132 +175,88 @@ func getAllTtVersionFormats(programName, ttVersion string) ([]string, error) {
180175

181176
// getDefault returns a default version of an installed program.
182177
func getDefault(program, dir string) (string, error) {
183-
var ver string
184-
185-
re := regexp.MustCompile(
186-
"^" + program + version.FsSeparator + verRegexp + "$",
187-
)
188-
189-
installedPrograms, err := os.ReadDir(dir)
178+
versions, err := GetAvailableVersions(program, dir)
190179
if err != nil {
191180
return "", err
192181
}
193-
194-
for _, file := range installedPrograms {
195-
matches := util.FindNamedMatches(re, file.Name())
196-
if ver != "" {
197-
return "", fmt.Errorf("%s has more than one installed version, "+
198-
"please specify the version to uninstall", program)
199-
} else {
200-
ver = matches["ver"]
201-
}
202-
}
203-
204-
if ver == "" {
182+
if len(versions) == 0 {
205183
return "", fmt.Errorf("%s has no installed version", program)
206184
}
207-
return ver, nil
185+
if len(versions) > 1 {
186+
return "", fmt.Errorf("%s has more than one installed version, "+
187+
"please specify the version to uninstall", program)
188+
}
189+
return versions[0], nil
208190
}
209191

210192
// GetAvailableVersions returns a list of the program's versions installed into
211193
// the 'dir' directory.
212-
func GetAvailableVersions(program string, dir string) []string {
213-
if dir == "" {
214-
return nil
194+
func GetAvailableVersions(program string, dir string) ([]string, error) {
195+
if !util.IsDir(dir) {
196+
return nil, fmt.Errorf("%q is missing or not a directory", dir)
215197
}
216198

217199
versionPrefix := filepath.Join(dir, program+version.FsSeparator)
218200

219201
programFiles, err := filepath.Glob(versionPrefix + "*")
220202
if err != nil {
221-
return nil
203+
return nil, err
222204
}
223205

224206
versions := []string{}
225207
for _, file := range programFiles {
226208
versions = append(versions, file[len(versionPrefix):])
227209
}
228210

229-
return versions
211+
return versions, nil
230212
}
231213

232214
// searchLatestVersion searches for the latest installed version of the program.
233-
func searchLatestVersion(linkName, binDst, headerDst string) (string, error) {
234-
var programsToSearch []string
235-
if linkName == "tarantool" {
236-
programsToSearch = []string{search.ProgramCe, search.ProgramEe}
237-
} else {
238-
programsToSearch = []string{linkName}
215+
func searchLatestVersion(program, binDst, headerDst string) (string, error) {
216+
binVersions, err := GetAvailableVersions(program, binDst)
217+
if err != nil {
218+
return "", err
239219
}
240220

241-
programRegex := regexp.MustCompile(
242-
"^" + progRegexp + version.FsSeparator + verRegexp + "$",
243-
)
244-
245-
binaries, err := os.ReadDir(binDst)
221+
headerVersions, err := GetAvailableVersions(program, headerDst)
246222
if err != nil {
247223
return "", err
248224
}
249225

250-
latestVersionInfo := version.Version{}
251-
latestVersion := ""
252-
hashFound := false
253-
latestHash := ""
254-
255-
for _, binary := range binaries {
256-
if binary.IsDir() {
257-
continue
258-
}
259-
binaryName := binary.Name()
260-
matches := util.FindNamedMatches(programRegex, binaryName)
226+
binPrefix := filepath.Join(binDst, program+version.FsSeparator)
261227

262-
// Need to match for the program and version.
263-
if len(matches) != 2 {
264-
log.Debugf("%q skipped: unexpected format", binaryName)
228+
// Find intersection and convert to version.Version
229+
versions := []version.Version{}
230+
for _, binVersion := range binVersions {
231+
if util.IsDir(binPrefix + binVersion) {
265232
continue
266233
}
267234

268-
programName := matches["prog"]
269-
// Need to find the program in the list of suitable.
270-
if util.Find(programsToSearch, programName) == -1 {
271-
continue
272-
}
273-
isRightFormat, _ := util.IsValidCommitHash(matches["ver"])
274-
275-
if isRightFormat {
276-
if hashFound {
235+
if slices.Contains(headerVersions, binVersion) {
236+
ver, err := version.Parse(binVersion)
237+
if err != nil {
277238
continue
278239
}
279-
if strings.Contains(programName, "tarantool") {
280-
// Check for headers.
281-
if _, err := os.Stat(filepath.Join(headerDst, binaryName)); os.IsNotExist(err) {
282-
continue
283-
}
284-
}
285-
hashFound = true
286-
latestHash = binaryName
287-
continue
288-
}
289-
ver, err := version.Parse(matches["ver"])
290-
if err != nil {
291-
continue
292-
}
293-
if strings.Contains(programName, "tarantool") {
294-
// Check for headers.
295-
if _, err := os.Stat(filepath.Join(headerDst, binaryName)); os.IsNotExist(err) {
296-
continue
297-
}
298-
}
299-
// Update latest version.
300-
if latestVersion == "" || version.IsLess(latestVersionInfo, ver) {
301-
latestVersionInfo = ver
302-
latestVersion = binaryName
240+
versions = append(versions, ver)
303241
}
304242
}
305-
if latestVersion != "" {
306-
return latestVersion, nil
243+
244+
if len(versions) == 0 {
245+
return "", nil
307246
}
308-
return latestHash, nil
247+
248+
latestVersion := slices.MaxFunc(versions, func(a, b version.Version) int {
249+
if a.Str == b.Str {
250+
return 0
251+
}
252+
isCommitHash, _ := util.IsValidCommitHash(a.Str)
253+
if isCommitHash || version.IsLess(a, b) {
254+
return -1
255+
}
256+
return 1
257+
})
258+
259+
return program + version.FsSeparator + latestVersion.Str, nil
309260
}
310261

311262
// switchProgramToLatestVersion switches the active version of the program to the latest installed.
@@ -315,7 +266,7 @@ func switchProgramToLatestVersion(program, binDst, headerDst string) error {
315266
linkName = "tarantool"
316267
}
317268

318-
progToSwitch, err := searchLatestVersion(linkName, binDst, headerDst)
269+
progToSwitch, err := searchLatestVersion(program, binDst, headerDst)
319270
if err != nil {
320271
return err
321272
}

0 commit comments

Comments
 (0)