Skip to content

Commit

Permalink
perf: optimize version compare
Browse files Browse the repository at this point in the history
  • Loading branch information
voocel committed May 26, 2022
1 parent b4a2c53 commit 8a44ea3
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 106 deletions.
9 changes: 6 additions & 3 deletions app.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@ func (a *app) Start() (err error) {
p.Name = a.tagToName(p.Tag)
return p.remove()
case "upgrade":
checkUpgrade()
u := NewUpgrade()
return u.checkUpgrade()
}
return
}
Expand Down Expand Up @@ -107,7 +108,7 @@ func (a *app) list() error {

func (a *app) selectVersions(versions []string) (target string, err error) {
if len(versions) == 0 {
return "", errors.New("no available versions to select")
return "", errors.New("no available versions locally to select")
}

surveyIcon := func() survey.AskOpt {
Expand All @@ -116,7 +117,9 @@ func (a *app) selectVersions(versions []string) (target string, err error) {
})
}

sort.Sort(sortVersion(versions))
sort.Slice(versions, func(i, j int) bool {
return versionCompare(versions[i]) > versionCompare(versions[j])
})
err = survey.AskOne(&survey.Select{
Message: "Choose a version:",
Help: "Enter to install the selected version",
Expand Down
41 changes: 23 additions & 18 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
var (
svHome string
svRoot string
svBin string
svCache string
svDownload string
)
Expand All @@ -26,11 +27,11 @@ func main() {
//app.Action = baseCmd
app.Commands = []*cli.Command{
{
Name: "list",
Usage: "show all local versions",
Name: "list",
Usage: "show all local versions",
UsageText: "sv ls",
Action: baseCmd,
Aliases: []string{"ls", "l"},
Action: baseCmd,
Aliases: []string{"ls", "l"},
Flags: []cli.Flag{
&cli.BoolFlag{
Name: "remote",
Expand All @@ -40,10 +41,10 @@ func main() {
},
},
}, {
Name: "use",
Usage: "input a specific local version",
Name: "use",
Usage: "input a specific local version",
UsageText: "sv use <version>",
Action: baseCmd,
Action: baseCmd,
Flags: []cli.Flag{
&cli.BoolFlag{
Name: "remote",
Expand All @@ -53,22 +54,22 @@ func main() {
},
},
}, {
Name: "install",
Usage: "install a specific remote version",
Name: "install",
Usage: "install a specific remote version",
UsageText: "sv install <version>",
Action: baseCmd,
Aliases: []string{"i"},
Action: baseCmd,
Aliases: []string{"i"},
}, {
Name: "uninstall",
Usage: "uninstall a specific local version",
Name: "uninstall",
Usage: "uninstall a specific local version",
UsageText: "sv uninstall <version>",
Action: baseCmd,
Aliases: []string{"ui"},
Action: baseCmd,
Aliases: []string{"ui"},
}, {
Name: "upgrade",
Usage: "upgrade sv",
Name: "upgrade",
Usage: "upgrade sv",
UsageText: "sv upgrade",
Action: baseCmd,
Action: baseCmd,
},
}
app.Before = func(context *cli.Context) (err error) {
Expand All @@ -78,6 +79,7 @@ func main() {
}
svHome = filepath.Join(homeDir, ".sv")
svRoot = filepath.Join(svHome, "go")
svBin = filepath.Join(svHome, "bin")
svDownload = filepath.Join(svHome, "downloads")
svCache = filepath.Join(svHome, "cache")
if err = os.MkdirAll(svDownload, 0755); err != nil {
Expand All @@ -86,6 +88,9 @@ func main() {
if err = os.MkdirAll(svCache, 0755); err != nil {
return err
}
if err = os.MkdirAll(svBin, 0755); err != nil {
return err
}
return
}

Expand Down
45 changes: 0 additions & 45 deletions sort.go

This file was deleted.

56 changes: 17 additions & 39 deletions upgrade.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,17 @@ package main

import (
"encoding/json"
"errors"
"net/http"
"strings"
)

const (
upgradeApi = "https://api.github.com/repos/voocel/sv/releases/latest"
)

type Upgrade struct {
latestTag string
DownloadURL string
latestTag string
downloadURL string
}

type Release struct {
Expand All @@ -26,49 +26,27 @@ type Asset struct {
BrowserDownloadURL string `json:"browser_download_url"`
}

func checkUpgrade() (bool, error) {
func NewUpgrade() *Upgrade {
return &Upgrade{}
}

func (u *Upgrade) checkUpgrade() error {
resp, err := http.Get(upgradeApi)
if err != nil {
return false, err
return err
}

latest := &Release{}
err = json.NewDecoder(resp.Body).Decode(latest)
if err != nil {
return false, err
return err
}
if versionCompare(latest.TagName) > versionCompare(Ver) {
return true, nil
}
return false, nil
}

func versionCompare(version string) string {
if strings.HasPrefix(version, "v") {
version = strings.TrimPrefix(version, "v")
if versionCompare(Ver) >= versionCompare(latest.TagName) {
return errors.New("it's already the latest version")
}
const maxByte = 1<<8 - 1
vo := make([]byte, 0, len(version)+8)
j := -1
for i := 0; i < len(version); i++ {
b := version[i]
if '0' > b || b > '9' {
vo = append(vo, b)
j = -1
continue
}
if j == -1 {
vo = append(vo, 0x00)
j = len(vo) - 1
}
if vo[j] == 1 && vo[j+1] == '0' {
vo[j+1] = b
continue
}
if vo[j]+1 > maxByte {
panic("invalid version")
}
vo = append(vo, b)
vo[j]++
}
return string(vo)

return err
}


33 changes: 32 additions & 1 deletion utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -268,4 +268,35 @@ func checkStringExistsFile(filename, value string) (bool, error) {
}

return false, scanner.Err()
}
}

func versionCompare(version string) string {
if strings.HasPrefix(version, "v") {
version = strings.TrimPrefix(version, "v")
}
const maxByte = 1<<8 - 1
vo := make([]byte, 0, len(version)+8)
j := -1
for i := 0; i < len(version); i++ {
b := version[i]
if '0' > b || b > '9' {
vo = append(vo, b)
j = -1
continue
}
if j == -1 {
vo = append(vo, 0x00)
j = len(vo) - 1
}
if vo[j] == 1 && vo[j+1] == '0' {
vo[j+1] = b
continue
}
if vo[j]+1 > maxByte {
panic("invalid version")
}
vo = append(vo, b)
vo[j]++
}
return string(vo)
}

0 comments on commit 8a44ea3

Please sign in to comment.