Skip to content

Commit

Permalink
Fix the issue that tiup may choose yanked version if it's already ins…
Browse files Browse the repository at this point in the history
…talled (#1191)
  • Loading branch information
lucklove authored Mar 5, 2021
1 parent a389747 commit c256bed
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 57 deletions.
2 changes: 1 addition & 1 deletion cmd/help.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ Simply type tiup help <command>|<component> for full details.`,
func externalHelp(env *environment.Environment, spec string, args ...string) {
profile := env.Profile()
component, version := environment.ParseCompVersion(spec)
selectVer, err := profile.SelectInstalledVersion(component, version)
selectVer, err := env.SelectInstalledVersion(component, version)
if err != nil {
fmt.Println(err)
return
Expand Down
87 changes: 63 additions & 24 deletions pkg/environment/env.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ const (
tiupName = "tiup"
)

var (
// ErrInstallFirst indicates that a component/version is not installed
ErrInstallFirst = errors.New("component not installed")
)

// Mirror return mirror of tiup.
// If it's not defined, it will use "https://tiup-mirrors.pingcap.com/".
func Mirror() string {
Expand Down Expand Up @@ -179,17 +184,64 @@ func (env *Environment) downloadComponent(component string, version pkgver.Versi

// SelectInstalledVersion selects the installed versions and the latest release version
// will be chosen if there is an empty version
func (env *Environment) SelectInstalledVersion(component string, version pkgver.Version) (pkgver.Version, error) {
return env.profile.SelectInstalledVersion(component, version)
func (env *Environment) SelectInstalledVersion(component string, ver pkgver.Version) (pkgver.Version, error) {
installed, err := env.Profile().InstalledVersions(component)
if err != nil {
return ver, err
}

versions := []string{}
for _, v := range installed {
vi, err := env.v1Repo.ComponentVersion(component, v, true)
if err != nil {
return ver, err
}
if vi.Yanked {
continue
}
versions = append(versions, v)
}

errInstallFirst := errors.Annotatef(ErrInstallFirst, "use `tiup install %s` to install component `%s` first", component, component)
if len(installed) == 0 {
return ver, errInstallFirst
}

if !ver.IsEmpty() {
for _, v := range versions {
if pkgver.Version(v) == ver {
return ver, nil
}
}
return ver, errInstallFirst
}

sort.Slice(versions, func(i, j int) bool {
// Reverse sort: v5.0.0-rc,v5.0.0-nightly-20210305,v4.0.11
return semver.Compare(versions[i], versions[j]) > 0
})

for _, v := range versions {
if pkgver.Version(v).IsNightly() {
continue
}
if semver.Prerelease(v) == "" {
ver = pkgver.Version(v)
break
} else if ver.IsEmpty() {
ver = pkgver.Version(v)
}
}

if ver.IsEmpty() {
return ver, errInstallFirst
}
return ver, nil
}

// DownloadComponentIfMissing downloads the specific version of a component if it is missing
func (env *Environment) DownloadComponentIfMissing(component string, ver pkgver.Version) (pkgver.Version, error) {
versions, err := env.profile.InstalledVersions(component)
if err != nil {
return "", err
}

var err error
if ver.String() == version.NightlyVersion {
if ver, _, err = env.v1Repo.LatestNightlyVersion(component); err != nil {
return "", err
Expand All @@ -200,23 +252,10 @@ func (env *Environment) DownloadComponentIfMissing(component string, ver pkgver.
// download the latest version if the specific component doesn't be installed

// Check whether the specific version exist in local
if ver.IsEmpty() && len(versions) > 0 {
sort.Slice(versions, func(i, j int) bool {
return semver.Compare(versions[i], versions[j]) < 0
})
ver = pkgver.Version(versions[len(versions)-1])
}

needDownload := ver.IsEmpty()
if !ver.IsEmpty() {
installed := false
for _, v := range versions {
if pkgver.Version(v) == ver {
installed = true
break
}
}
needDownload = !installed
ver, err = env.SelectInstalledVersion(component, ver)
needDownload := errors.Cause(err) == ErrInstallFirst
if err != nil && !needDownload {
return "", err
}

if needDownload {
Expand Down
32 changes: 0 additions & 32 deletions pkg/localdata/profile.go
Original file line number Diff line number Diff line change
Expand Up @@ -224,38 +224,6 @@ func (p *Profile) VersionIsInstalled(component, version string) (bool, error) {
return false, nil
}

// SelectInstalledVersion selects the installed versions and the latest release version
// will be chosen if there is an empty version
func (p *Profile) SelectInstalledVersion(component string, version pkgver.Version) (pkgver.Version, error) {
installed, err := p.InstalledVersions(component)
if err != nil {
return "", err
}

errInstallFirst := fmt.Errorf("use `tiup install %[1]s` to install `%[1]s` first", component)
if len(installed) < 1 {
return "", errInstallFirst
}

if version.IsEmpty() {
sort.Slice(installed, func(i, j int) bool {
return semver.Compare(installed[i], installed[j]) < 0
})
version = pkgver.Version(installed[len(installed)-1])
}
found := false
for _, v := range installed {
if pkgver.Version(v) == version {
found = true
break
}
}
if !found {
return "", errInstallFirst
}
return version, nil
}

// ResetMirror reset root.json and cleanup manifests directory
func (p *Profile) ResetMirror(addr, root string) error {
// Calculating root.json path
Expand Down

0 comments on commit c256bed

Please sign in to comment.