Skip to content

Commit b8cf088

Browse files
committed
uninstall: reuse GetAvailableVersions
1 parent e2e61b8 commit b8cf088

File tree

2 files changed

+48
-108
lines changed

2 files changed

+48
-108
lines changed

cli/uninstall/uninstall.go

+38-98
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

@@ -170,31 +165,15 @@ func getAllTtVersionFormats(programName, ttVersion string) ([]string, error) {
170165

171166
// getDefault returns a default version of an installed program.
172167
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 {
195170
return "", fmt.Errorf("%s has no installed version", program)
196171
}
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
198177
}
199178

200179
// GetAvailableVersions returns a list of the program's versions installed into
@@ -220,82 +199,43 @@ func GetAvailableVersions(program string, dir string) []string {
220199
}
221200

222201
// 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() {
247211
continue
248212
}
249-
binaryName := binary.Name()
250-
matches := util.FindNamedMatches(programRegex, binaryName)
251213

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 {
267217
continue
268218
}
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)
293220
}
294221
}
295-
if latestVersion != "" {
296-
return latestVersion, nil
222+
223+
if len(versions) == 0 {
224+
return "", fmt.Errorf("no version found")
297225
}
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
299239
}
300240

301241
// switchProgramToLatestVersion switches the active version of the program to the latest installed.
@@ -305,7 +245,7 @@ func switchProgramToLatestVersion(program, binDst, headerDst string) error {
305245
linkName = "tarantool"
306246
}
307247

308-
progToSwitch, err := searchLatestVersion(linkName, binDst, headerDst)
248+
progToSwitch, err := searchLatestVersion(program, binDst, headerDst)
309249
if err != nil {
310250
return err
311251
}

cli/uninstall/uninstall_test.go

+10-10
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ func TestGetAvailableVersions(t *testing.T) {
6565
func TestSearchLatestVersion(t *testing.T) {
6666
type testCase struct {
6767
name string
68-
linkName string
68+
program string
6969
binDst string
7070
headerDst string
7171
expectedVer string
@@ -75,57 +75,57 @@ func TestSearchLatestVersion(t *testing.T) {
7575
cases := []testCase{
7676
{
7777
name: "basic",
78-
linkName: "tarantool",
78+
program: "tarantool",
7979
binDst: "./testdata/bin_basic",
8080
headerDst: "./testdata/inc_basic",
8181
expectedVer: "tarantool_3.0.0-entrypoint",
8282
},
8383
{
8484
name: "no includes",
85-
linkName: "tarantool",
85+
program: "tarantool-ee",
8686
binDst: "./testdata/bin_basic",
8787
headerDst: "./testdata/inc_invalid",
8888
expectedVer: "tarantool-ee_2.8.4-0-r510",
8989
},
9090
{
9191
name: "tarantool-dev",
92-
linkName: "tarantool",
92+
program: "tarantool-dev",
9393
binDst: "./testdata/bin_dev",
9494
headerDst: "./testdata/inc_basic",
9595
expectedVer: "",
9696
},
9797
{
9898
name: "hash version",
99-
linkName: "tarantool",
99+
program: "tarantool",
100100
binDst: "./testdata/bin_hash",
101101
headerDst: "./testdata/inc_hash",
102102
expectedVer: "tarantool_aaaaaaa",
103103
},
104104
{
105105
name: "hash invalid headers",
106-
linkName: "tarantool",
106+
program: "tarantool",
107107
binDst: "./testdata/bin_hash",
108108
headerDst: "./testdata/inc_invalid_hash",
109109
expectedVer: "tarantool_bbbbbbb",
110110
},
111111
{
112112
name: "tt, include-dir basic",
113-
linkName: "tt",
113+
program: "tt",
114114
binDst: "./testdata/bin_basic",
115115
headerDst: "./testdata/inc_basic",
116116
expectedVer: "tt_2.0.0",
117117
},
118118
// Test that include dir doesn't affect the search for `tt`.
119119
{
120120
name: "tt, include-dir invalid",
121-
linkName: "tt",
121+
program: "tt",
122122
binDst: "./testdata/bin_basic",
123123
headerDst: "./testdata/inc_invalid",
124124
expectedVer: "tt_2.0.0",
125125
},
126126
{
127127
name: "filename as a bin dir",
128-
linkName: "tt",
128+
program: "tt",
129129
binDst: "./testdata/bin_basic/tarantool",
130130
headerDst: "./testdata/inc_basic",
131131
isErr: true,
@@ -134,7 +134,7 @@ func TestSearchLatestVersion(t *testing.T) {
134134

135135
for _, tc := range cases {
136136
t.Run(tc.name, func(t *testing.T) {
137-
ver, err := searchLatestVersion(tc.linkName, tc.binDst, tc.headerDst)
137+
ver, err := searchLatestVersion(tc.program, tc.binDst, tc.headerDst)
138138
if !tc.isErr {
139139
assert.NoError(t, err)
140140
assert.Equal(t, tc.expectedVer, ver)

0 commit comments

Comments
 (0)