diff --git a/cmd/installer/root.go b/cmd/installer/root.go index 1ac3e95a..9e7493b2 100644 --- a/cmd/installer/root.go +++ b/cmd/installer/root.go @@ -153,8 +153,18 @@ func AddPack(packPath string, checkEula, extractEula, forceReinstall, noRequirem log.Debugf("Moved pack to temporary path \"%s\"", backupPackPath) dropPreInstalled = true } else { - log.Errorf("Pack \"%s@%s\" is already installed here: \"%s\", use the --force-reinstall (-F) flag to force installation", - packPath, pack.targetVersion, filepath.Join(Installation.PackRoot, pack.Vendor, pack.Name, pack.GetVersionNoMeta())) + if pack.versionModifier == utils.AnyVersion { + if len(pack.installedVersions) > 1 { + log.Infof("Pack \"%s\" is already installed here: \"%s\", versions: %s", + packPath, filepath.Join(Installation.PackRoot, pack.Vendor, pack.Name), utils.VersionList(pack.installedVersions)) + } else { + log.Infof("Pack \"%s\" is already installed here: \"%s\"", + packPath, filepath.Join(Installation.PackRoot, pack.Vendor, pack.Name, pack.installedVersions[0])) + } + } else { + log.Errorf("Pack \"%s@%s\" is already installed here: \"%s\", use the --force-reinstall (-F) flag to force installation", + packPath, pack.targetVersion, filepath.Join(Installation.PackRoot, pack.Vendor, pack.Name, pack.GetVersionNoMeta())) + } return nil } } diff --git a/cmd/utils/semver.go b/cmd/utils/semver.go index 2f91660e..f0094195 100644 --- a/cmd/utils/semver.go +++ b/cmd/utils/semver.go @@ -76,3 +76,18 @@ func SemverStripMeta(version string) string { } return version } + +// VersionList takes a slice of version strings, strips any semantic version metadata +// from each version using SemverStripMeta, and returns a single comma-separated string +// of the processed versions. Empty strings in the input slice are ignored. +// If the input slice is empty, it returns an empty string. +func VersionList(versions []string) string { + var processedVersions []string + for _, version := range versions { + ver := SemverStripMeta(version) + if ver != "" { + processedVersions = append(processedVersions, ver) + } + } + return strings.Join(processedVersions, ", ") +} diff --git a/cmd/utils/semver_test.go b/cmd/utils/semver_test.go index 1a02f7ec..4f7ac0ed 100644 --- a/cmd/utils/semver_test.go +++ b/cmd/utils/semver_test.go @@ -55,6 +55,27 @@ func TestSemverCompare(t *testing.T) { } +func TestSemverCompareRange(t *testing.T) { + assert := assert.New(t) + + t.Run("test version range compare", func(t *testing.T) { + assert.True(utils.SemverCompareRange("1.2.3", "1.2.3") == 0) + assert.True(utils.SemverCompareRange("1.2.3", "1.2.3:") == 0) + assert.True(utils.SemverCompareRange("1.2.3", "1.2.3:_") == 0) + assert.True(utils.SemverCompareRange("1.2.3", ":1.2.3") == 0) + assert.True(utils.SemverCompareRange("1.2.3", "1.2.3:1.2.3") == 0) + assert.True(utils.SemverCompareRange("1.2.3", "1.2.0:1.2.3") == 0) + assert.True(utils.SemverCompareRange("1.2.3", "1.2.3:1.2.4") == 0) + assert.True(utils.SemverCompareRange("1.2.3", "1.2.0:1.2.4") == 0) + assert.True(utils.SemverCompareRange("1.2.3", "1.2.0") == 0) + assert.True(utils.SemverCompareRange("1.2.3", ":1.2.4") == 0) + assert.True(utils.SemverCompareRange("1.2.3", "1.2.4") < 0) + assert.True(utils.SemverCompareRange("1.2.3", ":1.2.0") > 0) + assert.True(utils.SemverCompareRange("1.2.3", "1.2.4:1.2.5") < 0) + assert.True(utils.SemverCompareRange("1.2.3", "1.2.0:1.2.1") > 0) + }) +} + func TestSemverMajor(t *testing.T) { assert := assert.New(t) @@ -99,23 +120,38 @@ func TestSemverStripMeta(t *testing.T) { }) } -func TestSemverCompareRange(t *testing.T) { +func TestVersionList(t *testing.T) { assert := assert.New(t) - t.Run("test version range compare", func(t *testing.T) { - assert.True(utils.SemverCompareRange("1.2.3", "1.2.3") == 0) - assert.True(utils.SemverCompareRange("1.2.3", "1.2.3:") == 0) - assert.True(utils.SemverCompareRange("1.2.3", "1.2.3:_") == 0) - assert.True(utils.SemverCompareRange("1.2.3", ":1.2.3") == 0) - assert.True(utils.SemverCompareRange("1.2.3", "1.2.3:1.2.3") == 0) - assert.True(utils.SemverCompareRange("1.2.3", "1.2.0:1.2.3") == 0) - assert.True(utils.SemverCompareRange("1.2.3", "1.2.3:1.2.4") == 0) - assert.True(utils.SemverCompareRange("1.2.3", "1.2.0:1.2.4") == 0) - assert.True(utils.SemverCompareRange("1.2.3", "1.2.0") == 0) - assert.True(utils.SemverCompareRange("1.2.3", ":1.2.4") == 0) - assert.True(utils.SemverCompareRange("1.2.3", "1.2.4") < 0) - assert.True(utils.SemverCompareRange("1.2.3", ":1.2.0") > 0) - assert.True(utils.SemverCompareRange("1.2.3", "1.2.4:1.2.5") < 0) - assert.True(utils.SemverCompareRange("1.2.3", "1.2.0:1.2.1") > 0) + t.Run("empty slice", func(t *testing.T) { + assert.Equal("", utils.VersionList([]string{})) + }) + + t.Run("single version, no meta", func(t *testing.T) { + assert.Equal("1.2.3", utils.VersionList([]string{"1.2.3"})) + }) + + t.Run("single version, with meta", func(t *testing.T) { + assert.Equal("1.2.3", utils.VersionList([]string{"1.2.3+meta"})) + }) + + t.Run("multiple versions, no meta", func(t *testing.T) { + assert.Equal("1.2.3, 2.3.4, 3.4.5", utils.VersionList([]string{"1.2.3", "2.3.4", "3.4.5"})) + }) + + t.Run("multiple versions, some with meta", func(t *testing.T) { + assert.Equal("1.2.3, 2.3.4, 3.4.5", utils.VersionList([]string{"1.2.3+meta", "2.3.4", "3.4.5+build"})) + }) + + t.Run("multiple versions, all with meta", func(t *testing.T) { + assert.Equal("1.2.3, 2.3.4, 3.4.5", utils.VersionList([]string{"1.2.3+meta", "2.3.4+build", "3.4.5+test"})) + }) + + t.Run("versions with empty string", func(t *testing.T) { + assert.Equal("1.2.3", utils.VersionList([]string{"", "1.2.3"})) + }) + + t.Run("versions with empty strings in between", func(t *testing.T) { + assert.Equal("1.2.3, 2.3.4, 3.4.5", utils.VersionList([]string{"1.2.3", "", "2.3.4", "", "3.4.5"})) }) }