diff --git a/cli/main.go b/cli/main.go index ddc5334..c1c893d 100644 --- a/cli/main.go +++ b/cli/main.go @@ -1,7 +1,6 @@ package main import ( - "fyne.io/fyne/dialog" "log" "net/url" "time" @@ -11,6 +10,7 @@ import ( "fyne.io/fyne" "fyne.io/fyne/app" "fyne.io/fyne/canvas" + "fyne.io/fyne/dialog" "fyne.io/fyne/layout" "fyne.io/fyne/widget" ) @@ -163,7 +163,14 @@ const lockfile = "vrc_auto_rejoin_tool.rejoinLock" func main() { vrc := vrcarjt.NewVRCAutoRejoinTool() - + currentVersion, _ := vrc.GetCurrentVersion() + latestVersion, _ := vrc.GetLatestVersion() + if currentVersion != nil && latestVersion != nil { + if currentVersion.Major != latestVersion.Major { + log.Println("auto rejoin tool が更新されました。最新バージョンを入手してください. ") + select {} + } + } home := vrc.GetUserHome() lock := vrcarjt.NewDupRunLock(home + `\AppData\Local\Temp\` + lockfile) ok, err := lock.Try() diff --git a/version.go b/version.go new file mode 100644 index 0000000..21740e2 --- /dev/null +++ b/version.go @@ -0,0 +1,148 @@ +package vrcarjt + +import ( + "encoding/json" + "errors" + "fmt" + "io/ioutil" + "log" + "net/http" + "strconv" + "strings" + "time" +) + +type Version struct { + Major int + Minor int + Patch int +} + +func getVersion(version string) (*Version, error) { + if version == "" { + return nil, errors.New("Please provide a valid version to parse") + } + nums := strings.Split(version, "") + if len(nums) != 6 { + return nil, fmt.Errorf("Please follow the proper versioning format, Got: %v, Expected: v0.0.0", version) + } + if nums[0] != "v" { + return nil, fmt.Errorf("Please follow the proper versioning format, Got: %v, Expected: v0.0.0", version) + } + major, err := strconv.Atoi(nums[1]) + if err != nil { + return nil, err + } + minor, err := strconv.Atoi(nums[3]) + if err != nil { + return nil, err + } + patch, err := strconv.Atoi(nums[5]) + if err != nil { + return nil, err + } + return &Version{ + Major: major, + Minor: minor, + Patch: patch, + }, nil +} + +type LatestVersion struct { + URL string `json:"url"` + AssetsURL string `json:"assets_url"` + UploadURL string `json:"upload_url"` + HTMLURL string `json:"html_url"` + ID int `json:"id"` + Author struct { + Login string `json:"login"` + ID int `json:"id"` + NodeID string `json:"node_id"` + AvatarURL string `json:"avatar_url"` + GravatarID string `json:"gravatar_id"` + URL string `json:"url"` + HTMLURL string `json:"html_url"` + FollowersURL string `json:"followers_url"` + FollowingURL string `json:"following_url"` + GistsURL string `json:"gists_url"` + StarredURL string `json:"starred_url"` + SubscriptionsURL string `json:"subscriptions_url"` + OrganizationsURL string `json:"organizations_url"` + ReposURL string `json:"repos_url"` + EventsURL string `json:"events_url"` + ReceivedEventsURL string `json:"received_events_url"` + Type string `json:"type"` + SiteAdmin bool `json:"site_admin"` + } `json:"author"` + NodeID string `json:"node_id"` + TagName string `json:"tag_name"` + TargetCommitish string `json:"target_commitish"` + Name string `json:"name"` + Draft bool `json:"draft"` + Prerelease bool `json:"prerelease"` + CreatedAt time.Time `json:"created_at"` + PublishedAt time.Time `json:"published_at"` + Assets []struct { + URL string `json:"url"` + ID int `json:"id"` + NodeID string `json:"node_id"` + Name string `json:"name"` + Label string `json:"label"` + Uploader struct { + Login string `json:"login"` + ID int `json:"id"` + NodeID string `json:"node_id"` + AvatarURL string `json:"avatar_url"` + GravatarID string `json:"gravatar_id"` + URL string `json:"url"` + HTMLURL string `json:"html_url"` + FollowersURL string `json:"followers_url"` + FollowingURL string `json:"following_url"` + GistsURL string `json:"gists_url"` + StarredURL string `json:"starred_url"` + SubscriptionsURL string `json:"subscriptions_url"` + OrganizationsURL string `json:"organizations_url"` + ReposURL string `json:"repos_url"` + EventsURL string `json:"events_url"` + ReceivedEventsURL string `json:"received_events_url"` + Type string `json:"type"` + SiteAdmin bool `json:"site_admin"` + } `json:"uploader"` + ContentType string `json:"content_type"` + State string `json:"state"` + Size int `json:"size"` + DownloadCount int `json:"download_count"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` + BrowserDownloadURL string `json:"browser_download_url"` + } `json:"assets"` + TarballURL string `json:"tarball_url"` + ZipballURL string `json:"zipball_url"` + Body string `json:"body"` +} + +func (v *VRCAutoRejoinTool) GetLatestVersion() (*Version, error) { + resp, err := http.Get("https://api.github.com/repos/bootjp/vrc_auto_rejoin_tool/releases/latest") + if err != nil { + log.Println(err) + return nil, err + } + defer resp.Body.Close() + + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + log.Println(err) + return nil, err + } + var latestVersion LatestVersion + err = json.Unmarshal(body, &latestVersion) + if err != nil { + log.Println(err) + return nil, err + } + + return getVersion(latestVersion.TagName) +} +func (v *VRCAutoRejoinTool) GetCurrentVersion() (*Version, error) { + return getVersion(BuildVersion) +} diff --git a/version_test.go b/version_test.go new file mode 100644 index 0000000..e43e54e --- /dev/null +++ b/version_test.go @@ -0,0 +1,82 @@ +package vrcarjt + +import ( + "reflect" + "testing" +) + +func Test_getVersion(t *testing.T) { + type args struct { + version string + } + tests := []struct { + name string + args args + want *Version + wantErr bool + }{ + { + name: "Should return a valid Version for v2.7.0", + args: args{ + "v2.7.0", + }, + want: &Version{ + Major: 2, + Minor: 7, + Patch: 0, + }, + wantErr: false, + }, + { + name: "Should return a valid Version for v2.7.1", + args: args{ + "v2.7.1", + }, + want: &Version{ + Major: 2, + Minor: 7, + Patch: 1, + }, + wantErr: false, + }, + { + name: "Should fail for an invalid version type for 2.7.1", + args: args{ + "2.7.1", + }, + want: nil, + wantErr: true, + }, + { + name: "Should fail for an empty string", + args: args{ + "", + }, + want: nil, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := getVersion(tt.args.version) + if (err != nil) != tt.wantErr { + t.Errorf("getVersion() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("getVersion() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestVRCAutoRejoinTool_GetCurrentVersion(t *testing.T) { + + t.Run("Should return a valid version", func(t *testing.T) { + v := NewVRCAutoRejoinTool() + _, err := v.GetCurrentVersion() + if err != nil { + t.Errorf("VRCAutoRejoinTool.GetCurrentVersion() error = %v", err) + } + }) +} diff --git a/vrc_auto_rejoin_tool.go b/vrc_auto_rejoin_tool.go index a0ce1bd..0bd2cd9 100644 --- a/vrc_auto_rejoin_tool.go +++ b/vrc_auto_rejoin_tool.go @@ -30,6 +30,7 @@ const Location = "Local" const TimeFormat = "2006.01.02 15:04:05" const vrcRelativeLogPath = `\AppData\LocalLow\VRChat\VRChat\` const Timeout = "Timeout: Your connection to VRChat timed out." +const BuildVersion = "v2.7.0" func NewVRCAutoRejoinTool() *VRCAutoRejoinTool { conf := LoadConf("setting.yml")