// Package version deals with versioning of the software package version import ( "encoding/json" "errors" "fmt" "io" "log" "net/http" "sync" "golang.org/x/mod/semver" ) type Info struct { CurrentVersion string `json:"current_version"` GithubVersion string `json:"github_version"` UpgradeAvailable bool `json:"upgrade_available"` GithubVersionFetched bool `json:"-"` } type Manager struct { VersionInfo Info lock sync.Mutex } func (m *Manager) GetInfo() Info { m.lock.Lock() defer m.lock.Unlock() return m.VersionInfo } func (m *Manager) UpdateGitHubVersion() error { m.lock.Lock() m.VersionInfo.GithubVersionFetched = false m.lock.Unlock() versionUrl := "https://api.github.com/repos/tardisx/gropple/releases" resp, err := http.Get(versionUrl) if err != nil { log.Printf("Error getting response: %v", err) return err } defer resp.Body.Close() b, err := io.ReadAll(resp.Body) if err != nil { return fmt.Errorf("failed to read body: %v", err) } type release struct { HTMLUrl string `json:"html_url"` TagName string `json:"tag_name"` Name string `json:"name"` } var releases []release err = json.Unmarshal(b, &releases) if err != nil { return fmt.Errorf("failed to read unmarshal: %v", err) } if len(releases) == 0 { log.Printf("found no releases on github?") return errors.New("no releases found") } m.lock.Lock() defer m.lock.Unlock() m.VersionInfo.GithubVersion = releases[0].Name m.VersionInfo.GithubVersionFetched = true m.VersionInfo.UpgradeAvailable = m.canUpgrade() return nil } func (m *Manager) canUpgrade() bool { if !m.VersionInfo.GithubVersionFetched { return false } if !semver.IsValid(m.VersionInfo.CurrentVersion) { log.Printf("current version %s is invalid", m.VersionInfo.CurrentVersion) } if !semver.IsValid(m.VersionInfo.GithubVersion) { log.Printf("github version %s is invalid", m.VersionInfo.GithubVersion) } if semver.Compare(m.VersionInfo.CurrentVersion, m.VersionInfo.GithubVersion) == -1 { return true } return false }