gropple/version/version.go

98 lines
2.0 KiB
Go

// 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
}