mirror of
https://github.com/zu1k/nali.git
synced 2025-01-22 13:19:02 +08:00
commit
a4169d9db1
2
.github/workflows/go.yml
vendored
2
.github/workflows/go.yml
vendored
@ -38,7 +38,7 @@ jobs:
|
||||
|
||||
- name: Get version
|
||||
id: version
|
||||
run: echo ::set-output name=version::$(git describe --long --tags | sed 's/^v//;s/\([^-]*-g\)/r\1/;s/-/./g')
|
||||
run: echo ::set-output name=version::$(git describe --long --tags | sed 's/^v//;s/\([^-]*-g\)/r\1/;')
|
||||
|
||||
- name: Publish AUR package nali-go-git
|
||||
uses: zu1k/aur-publish-action@master
|
||||
|
@ -12,16 +12,19 @@ import (
|
||||
|
||||
// updateCmd represents the update command
|
||||
var updateCmd = &cobra.Command{
|
||||
Use: "update [--db dbs]",
|
||||
Short: "update qqwry, zxipv6wry, ip2region ip database and cdn",
|
||||
Long: `update qqwry, zxipv6wry, ip2region ip database and cdn. Use commas to separate`,
|
||||
Example: "nali update --db qqwry,cdn",
|
||||
Use: "update [--db dbs -v]",
|
||||
Short: "update qqwry, zxipv6wry, ip2region ip database and cdn, update nali to latest version if -v",
|
||||
Long: `update qqwry, zxipv6wry, ip2region ip database and cdn. Use commas to separate. update nali to latest version if -v`,
|
||||
Example: "nali update --db qqwry,cdn -v",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
DBs, _ := cmd.Flags().GetString("db")
|
||||
|
||||
version, _ := cmd.Flags().GetBool("v")
|
||||
if version {
|
||||
if err := repo.UpdateRepo(); err != nil {
|
||||
log.Printf("update nali to latest version failed: %v \n", err)
|
||||
}
|
||||
}
|
||||
|
||||
var DBNameArray []string
|
||||
if DBs != "" {
|
||||
@ -33,5 +36,6 @@ var updateCmd = &cobra.Command{
|
||||
|
||||
func init() {
|
||||
updateCmd.PersistentFlags().String("db", "", "choose db you want to update")
|
||||
updateCmd.PersistentFlags().Bool("v", false, "decide whether to update the nali version")
|
||||
rootCmd.AddCommand(updateCmd)
|
||||
}
|
||||
|
1
go.mod
1
go.mod
@ -3,7 +3,6 @@ module github.com/zu1k/nali
|
||||
go 1.19
|
||||
|
||||
require (
|
||||
github.com/Masterminds/semver/v3 v3.2.1
|
||||
github.com/adrg/xdg v0.4.0
|
||||
github.com/fatih/color v1.15.0
|
||||
github.com/google/go-github/v55 v55.0.0
|
||||
|
2
go.sum
2
go.sum
@ -38,8 +38,6 @@ cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3f
|
||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||
github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0=
|
||||
github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ=
|
||||
github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8 h1:wPbRQzjjwFc0ih8puEVAOFGELsn1zoIIYdxvML7mDxA=
|
||||
github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8/go.mod h1:I0gYDMZ6Z5GRU7l58bNFSkPTFN6Yl12dsUlAZ8xy98g=
|
||||
github.com/adrg/xdg v0.4.0 h1:RzRqFcjH4nE5C6oTAxhBtoE2IRyjBSa62SCbyPidvls=
|
||||
|
@ -13,7 +13,6 @@ import (
|
||||
|
||||
"github.com/zu1k/nali/internal/constant"
|
||||
|
||||
"github.com/Masterminds/semver/v3"
|
||||
"github.com/google/go-github/v55/github"
|
||||
)
|
||||
|
||||
@ -96,9 +95,6 @@ func update(asset io.Reader, cmdPath string) error {
|
||||
if !canWriteDir(updateDir) {
|
||||
return fmt.Errorf("no write permissions on the directory, consider updating nali manually")
|
||||
}
|
||||
if !canWriteFile(cmdPath) {
|
||||
return fmt.Errorf("no write permissions on the executable, consider updating nali manually")
|
||||
}
|
||||
|
||||
// Copy the contents of new binary to a new executable file
|
||||
newPath := filepath.Join(updateDir, fmt.Sprintf(".%s.new", filename))
|
||||
@ -153,14 +149,26 @@ func update(asset io.Reader, cmdPath string) error {
|
||||
}
|
||||
|
||||
func canUpdate(rel *github.RepositoryRelease) bool {
|
||||
if constant.Version != "unknown version" {
|
||||
latest, _ := semver.NewVersion(rel.GetTagName())
|
||||
cur, _ := semver.NewVersion(constant.Version)
|
||||
// unknown version means that the user compiled it manually instead of downloading it from the release,
|
||||
// in which case we don't take the liberty of updating it to a potentially older version.
|
||||
if constant.Version == "unknown version" {
|
||||
return false
|
||||
}
|
||||
|
||||
latest, err := parseVersion(rel.GetTagName())
|
||||
if err != nil {
|
||||
log.Printf("failed to parse latest version: %v, err: %v \n", rel.GetTagName(), err)
|
||||
return false
|
||||
}
|
||||
|
||||
cur, err := parseVersion(constant.Version)
|
||||
if err != nil {
|
||||
log.Printf("failed to parse current version: %v, err: %v \n", constant.Version, err)
|
||||
return false
|
||||
}
|
||||
|
||||
return latest.GreaterThan(cur)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func canWriteDir(path string) bool {
|
||||
fp := filepath.Join(path, ".tempWriteCheck")
|
||||
@ -173,12 +181,3 @@ func canWriteDir(path string) bool {
|
||||
|
||||
return err == nil
|
||||
}
|
||||
|
||||
func canWriteFile(path string) bool {
|
||||
f, err := os.OpenFile(path, os.O_WRONLY, 0644)
|
||||
if err == nil {
|
||||
defer f.Close()
|
||||
}
|
||||
|
||||
return err == nil
|
||||
}
|
||||
|
62
internal/repo/version.go
Normal file
62
internal/repo/version.go
Normal file
@ -0,0 +1,62 @@
|
||||
package repo
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type Version struct {
|
||||
Major int
|
||||
Minor int
|
||||
Patch int
|
||||
}
|
||||
|
||||
func parseVersion(vStr string) (*Version, error) {
|
||||
vStr = strings.TrimPrefix(vStr, "v")
|
||||
|
||||
// split by hyphen to remove pre-release info, then split by dot to get version info
|
||||
parts := strings.Split(strings.Split(vStr, "-")[0], ".")
|
||||
if len(parts) < 3 {
|
||||
return nil, fmt.Errorf("invalid version format: %s", vStr)
|
||||
}
|
||||
|
||||
major, err := strconv.Atoi(parts[0])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
minor, err := strconv.Atoi(parts[1])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
patch, err := strconv.Atoi(parts[2])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &Version{Major: major, Minor: minor, Patch: patch}, nil
|
||||
}
|
||||
|
||||
func (v *Version) Equal(other *Version) bool {
|
||||
return v.compare(other) == 0
|
||||
}
|
||||
|
||||
func (v *Version) GreaterThan(other *Version) bool {
|
||||
return v.compare(other) > 0
|
||||
}
|
||||
|
||||
func (v *Version) LessThan(other *Version) bool {
|
||||
return v.compare(other) < 0
|
||||
}
|
||||
|
||||
func (v *Version) compare(other *Version) int {
|
||||
if v.Major != other.Major {
|
||||
return v.Major - other.Major
|
||||
}
|
||||
if v.Minor != other.Minor {
|
||||
return v.Minor - other.Minor
|
||||
}
|
||||
return v.Patch - other.Patch
|
||||
}
|
111
internal/repo/version_test.go
Normal file
111
internal/repo/version_test.go
Normal file
@ -0,0 +1,111 @@
|
||||
package repo
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func Test_parseVersion(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
vStr string
|
||||
want *Version
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "happy path for normal release version name",
|
||||
vStr: "v0.7.1",
|
||||
want: &Version{Major: 0, Minor: 7, Patch: 1},
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "happy path for old aur-git release version name",
|
||||
vStr: "0.7.3.r15.g43a3080",
|
||||
want: &Version{Major: 0, Minor: 7, Patch: 3},
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "happy path for new aur-git release version name",
|
||||
vStr: "0.7.3-r15-g43a3080",
|
||||
want: &Version{Major: 0, Minor: 7, Patch: 3},
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "empty version name",
|
||||
vStr: "",
|
||||
want: nil,
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "only major and minor version",
|
||||
vStr: "0.7",
|
||||
want: nil,
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "invalid format version name, major/minor/patch version is not a number",
|
||||
vStr: "xx.xx.xx",
|
||||
want: nil,
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "user customized version name",
|
||||
vStr: "test version",
|
||||
want: nil,
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "only dots, no version number",
|
||||
vStr: "...",
|
||||
want: nil,
|
||||
wantErr: true,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got, err := parseVersion(tt.vStr)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("parseVersion() error = %v, wantErr %v", err, tt.wantErr)
|
||||
return
|
||||
}
|
||||
if !reflect.DeepEqual(got, tt.want) {
|
||||
t.Errorf("parseVersion() got = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestVersion_GreaterThan(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
v *Version
|
||||
other *Version
|
||||
want bool
|
||||
}{
|
||||
{
|
||||
name: "happy path",
|
||||
v: &Version{Major: 0, Minor: 7, Patch: 1},
|
||||
other: &Version{Major: 0, Minor: 7, Patch: 0},
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "same version number",
|
||||
v: &Version{Major: 0, Minor: 7, Patch: 1},
|
||||
other: &Version{Major: 0, Minor: 7, Patch: 1},
|
||||
want: false,
|
||||
},
|
||||
{
|
||||
name: "less than other version number",
|
||||
v: &Version{Major: 0, Minor: 7, Patch: 1},
|
||||
other: &Version{Major: 0, Minor: 7, Patch: 3},
|
||||
want: false,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := tt.v.GreaterThan(tt.other); got != tt.want {
|
||||
t.Errorf("GreaterThan() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user