Skip to content

Commit a4169d9

Browse files
authored
Merge pull request #178 from DateBro/master
fix: fix self-update bugs
2 parents 43a3080 + 4452272 commit a4169d9

File tree

7 files changed

+201
-28
lines changed

7 files changed

+201
-28
lines changed

.github/workflows/go.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ jobs:
3838

3939
- name: Get version
4040
id: version
41-
run: echo ::set-output name=version::$(git describe --long --tags | sed 's/^v//;s/\([^-]*-g\)/r\1/;s/-/./g')
41+
run: echo ::set-output name=version::$(git describe --long --tags | sed 's/^v//;s/\([^-]*-g\)/r\1/;')
4242

4343
- name: Publish AUR package nali-go-git
4444
uses: zu1k/aur-publish-action@master

cmd/update.go

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,18 @@ import (
1212

1313
// updateCmd represents the update command
1414
var updateCmd = &cobra.Command{
15-
Use: "update [--db dbs]",
16-
Short: "update qqwry, zxipv6wry, ip2region ip database and cdn",
17-
Long: `update qqwry, zxipv6wry, ip2region ip database and cdn. Use commas to separate`,
18-
Example: "nali update --db qqwry,cdn",
15+
Use: "update [--db dbs -v]",
16+
Short: "update qqwry, zxipv6wry, ip2region ip database and cdn, update nali to latest version if -v",
17+
Long: `update qqwry, zxipv6wry, ip2region ip database and cdn. Use commas to separate. update nali to latest version if -v`,
18+
Example: "nali update --db qqwry,cdn -v",
1919
Run: func(cmd *cobra.Command, args []string) {
2020
DBs, _ := cmd.Flags().GetString("db")
2121

22-
if err := repo.UpdateRepo(); err != nil {
23-
log.Printf("update nali to latest version failed: %v \n", err)
22+
version, _ := cmd.Flags().GetBool("v")
23+
if version {
24+
if err := repo.UpdateRepo(); err != nil {
25+
log.Printf("update nali to latest version failed: %v \n", err)
26+
}
2427
}
2528

2629
var DBNameArray []string
@@ -33,5 +36,6 @@ var updateCmd = &cobra.Command{
3336

3437
func init() {
3538
updateCmd.PersistentFlags().String("db", "", "choose db you want to update")
39+
updateCmd.PersistentFlags().Bool("v", false, "decide whether to update the nali version")
3640
rootCmd.AddCommand(updateCmd)
3741
}

go.mod

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ module github.com/zu1k/nali
33
go 1.19
44

55
require (
6-
github.com/Masterminds/semver/v3 v3.2.1
76
github.com/adrg/xdg v0.4.0
87
github.com/fatih/color v1.15.0
98
github.com/google/go-github/v55 v55.0.0

go.sum

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,6 @@ cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3f
3838
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
3939
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
4040
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
41-
github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0=
42-
github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ=
4341
github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8 h1:wPbRQzjjwFc0ih8puEVAOFGELsn1zoIIYdxvML7mDxA=
4442
github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8/go.mod h1:I0gYDMZ6Z5GRU7l58bNFSkPTFN6Yl12dsUlAZ8xy98g=
4543
github.com/adrg/xdg v0.4.0 h1:RzRqFcjH4nE5C6oTAxhBtoE2IRyjBSa62SCbyPidvls=

internal/repo/update.go

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import (
1313

1414
"github.com/zu1k/nali/internal/constant"
1515

16-
"github.com/Masterminds/semver/v3"
1716
"github.com/google/go-github/v55/github"
1817
)
1918

@@ -96,9 +95,6 @@ func update(asset io.Reader, cmdPath string) error {
9695
if !canWriteDir(updateDir) {
9796
return fmt.Errorf("no write permissions on the directory, consider updating nali manually")
9897
}
99-
if !canWriteFile(cmdPath) {
100-
return fmt.Errorf("no write permissions on the executable, consider updating nali manually")
101-
}
10298

10399
// Copy the contents of new binary to a new executable file
104100
newPath := filepath.Join(updateDir, fmt.Sprintf(".%s.new", filename))
@@ -153,13 +149,25 @@ func update(asset io.Reader, cmdPath string) error {
153149
}
154150

155151
func canUpdate(rel *github.RepositoryRelease) bool {
156-
if constant.Version != "unknown version" {
157-
latest, _ := semver.NewVersion(rel.GetTagName())
158-
cur, _ := semver.NewVersion(constant.Version)
152+
// unknown version means that the user compiled it manually instead of downloading it from the release,
153+
// in which case we don't take the liberty of updating it to a potentially older version.
154+
if constant.Version == "unknown version" {
155+
return false
156+
}
159157

160-
return latest.GreaterThan(cur)
158+
latest, err := parseVersion(rel.GetTagName())
159+
if err != nil {
160+
log.Printf("failed to parse latest version: %v, err: %v \n", rel.GetTagName(), err)
161+
return false
161162
}
162-
return false
163+
164+
cur, err := parseVersion(constant.Version)
165+
if err != nil {
166+
log.Printf("failed to parse current version: %v, err: %v \n", constant.Version, err)
167+
return false
168+
}
169+
170+
return latest.GreaterThan(cur)
163171
}
164172

165173
func canWriteDir(path string) bool {
@@ -173,12 +181,3 @@ func canWriteDir(path string) bool {
173181

174182
return err == nil
175183
}
176-
177-
func canWriteFile(path string) bool {
178-
f, err := os.OpenFile(path, os.O_WRONLY, 0644)
179-
if err == nil {
180-
defer f.Close()
181-
}
182-
183-
return err == nil
184-
}

internal/repo/version.go

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
package repo
2+
3+
import (
4+
"fmt"
5+
"strconv"
6+
"strings"
7+
)
8+
9+
type Version struct {
10+
Major int
11+
Minor int
12+
Patch int
13+
}
14+
15+
func parseVersion(vStr string) (*Version, error) {
16+
vStr = strings.TrimPrefix(vStr, "v")
17+
18+
// split by hyphen to remove pre-release info, then split by dot to get version info
19+
parts := strings.Split(strings.Split(vStr, "-")[0], ".")
20+
if len(parts) < 3 {
21+
return nil, fmt.Errorf("invalid version format: %s", vStr)
22+
}
23+
24+
major, err := strconv.Atoi(parts[0])
25+
if err != nil {
26+
return nil, err
27+
}
28+
29+
minor, err := strconv.Atoi(parts[1])
30+
if err != nil {
31+
return nil, err
32+
}
33+
34+
patch, err := strconv.Atoi(parts[2])
35+
if err != nil {
36+
return nil, err
37+
}
38+
39+
return &Version{Major: major, Minor: minor, Patch: patch}, nil
40+
}
41+
42+
func (v *Version) Equal(other *Version) bool {
43+
return v.compare(other) == 0
44+
}
45+
46+
func (v *Version) GreaterThan(other *Version) bool {
47+
return v.compare(other) > 0
48+
}
49+
50+
func (v *Version) LessThan(other *Version) bool {
51+
return v.compare(other) < 0
52+
}
53+
54+
func (v *Version) compare(other *Version) int {
55+
if v.Major != other.Major {
56+
return v.Major - other.Major
57+
}
58+
if v.Minor != other.Minor {
59+
return v.Minor - other.Minor
60+
}
61+
return v.Patch - other.Patch
62+
}

internal/repo/version_test.go

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
package repo
2+
3+
import (
4+
"reflect"
5+
"testing"
6+
)
7+
8+
func Test_parseVersion(t *testing.T) {
9+
tests := []struct {
10+
name string
11+
vStr string
12+
want *Version
13+
wantErr bool
14+
}{
15+
{
16+
name: "happy path for normal release version name",
17+
vStr: "v0.7.1",
18+
want: &Version{Major: 0, Minor: 7, Patch: 1},
19+
wantErr: false,
20+
},
21+
{
22+
name: "happy path for old aur-git release version name",
23+
vStr: "0.7.3.r15.g43a3080",
24+
want: &Version{Major: 0, Minor: 7, Patch: 3},
25+
wantErr: false,
26+
},
27+
{
28+
name: "happy path for new aur-git release version name",
29+
vStr: "0.7.3-r15-g43a3080",
30+
want: &Version{Major: 0, Minor: 7, Patch: 3},
31+
wantErr: false,
32+
},
33+
{
34+
name: "empty version name",
35+
vStr: "",
36+
want: nil,
37+
wantErr: true,
38+
},
39+
{
40+
name: "only major and minor version",
41+
vStr: "0.7",
42+
want: nil,
43+
wantErr: true,
44+
},
45+
{
46+
name: "invalid format version name, major/minor/patch version is not a number",
47+
vStr: "xx.xx.xx",
48+
want: nil,
49+
wantErr: true,
50+
},
51+
{
52+
name: "user customized version name",
53+
vStr: "test version",
54+
want: nil,
55+
wantErr: true,
56+
},
57+
{
58+
name: "only dots, no version number",
59+
vStr: "...",
60+
want: nil,
61+
wantErr: true,
62+
},
63+
}
64+
for _, tt := range tests {
65+
t.Run(tt.name, func(t *testing.T) {
66+
got, err := parseVersion(tt.vStr)
67+
if (err != nil) != tt.wantErr {
68+
t.Errorf("parseVersion() error = %v, wantErr %v", err, tt.wantErr)
69+
return
70+
}
71+
if !reflect.DeepEqual(got, tt.want) {
72+
t.Errorf("parseVersion() got = %v, want %v", got, tt.want)
73+
}
74+
})
75+
}
76+
}
77+
78+
func TestVersion_GreaterThan(t *testing.T) {
79+
tests := []struct {
80+
name string
81+
v *Version
82+
other *Version
83+
want bool
84+
}{
85+
{
86+
name: "happy path",
87+
v: &Version{Major: 0, Minor: 7, Patch: 1},
88+
other: &Version{Major: 0, Minor: 7, Patch: 0},
89+
want: true,
90+
},
91+
{
92+
name: "same version number",
93+
v: &Version{Major: 0, Minor: 7, Patch: 1},
94+
other: &Version{Major: 0, Minor: 7, Patch: 1},
95+
want: false,
96+
},
97+
{
98+
name: "less than other version number",
99+
v: &Version{Major: 0, Minor: 7, Patch: 1},
100+
other: &Version{Major: 0, Minor: 7, Patch: 3},
101+
want: false,
102+
},
103+
}
104+
for _, tt := range tests {
105+
t.Run(tt.name, func(t *testing.T) {
106+
if got := tt.v.GreaterThan(tt.other); got != tt.want {
107+
t.Errorf("GreaterThan() = %v, want %v", got, tt.want)
108+
}
109+
})
110+
}
111+
}

0 commit comments

Comments
 (0)