From aeee144ebbb9e05734ab631b57b881189a94db12 Mon Sep 17 00:00:00 2001 From: Wojciech Kwolek Date: Wed, 29 Sep 2021 23:47:04 +0200 Subject: [PATCH] initial commit --- go.mod | 14 +++++++++ go.sum | 12 ++++++++ main.go | 62 +++++++++++++++++++++++++++++++++++++++ provider_github.go | 19 ++++++++++++ provider_yaml.go | 37 +++++++++++++++++++++++ provider_yaml_test.go | 26 ++++++++++++++++ simple_comparison.go | 42 ++++++++++++++++++++++++++ simple_comparison_test.go | 29 ++++++++++++++++++ 8 files changed, 241 insertions(+) create mode 100644 go.mod create mode 100644 go.sum create mode 100644 main.go create mode 100644 provider_github.go create mode 100644 provider_yaml.go create mode 100644 provider_yaml_test.go create mode 100644 simple_comparison.go create mode 100644 simple_comparison_test.go diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..b14d51e --- /dev/null +++ b/go.mod @@ -0,0 +1,14 @@ +module git.kwolek.io/irth/autoupdate + +go 1.17 + +require ( + github.com/stretchr/testify v1.7.0 + gopkg.in/yaml.v2 v2.4.0 +) + +require ( + github.com/davecgh/go-spew v1.1.0 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..b0fd8d5 --- /dev/null +++ b/go.sum @@ -0,0 +1,12 @@ +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/main.go b/main.go new file mode 100644 index 0000000..ccebfb1 --- /dev/null +++ b/main.go @@ -0,0 +1,62 @@ +package main + +import ( + "encoding/json" + "fmt" + "net/http" +) + +type Version interface { + String() string +} + +type VersionProvider interface { + GetVersion() (Version, error) +} + +func (g *GitHubVersionProvider) GetVersion() (Version, error) { + url := fmt.Sprintf("https://api.github.com/repos/%s/releases", g.Repository) + r, err := http.Get(url) + if err != nil { + return nil, fmt.Errorf("couldn't fetch release list for %s from GitHub: %w", g.Repository, err) + } + defer r.Body.Close() + + var releases []GitHubRelease + err = json.NewDecoder(r.Body).Decode(&releases) + if err != nil { + return nil, fmt.Errorf("couldn't parse json: %w", err) + } + + for _, release := range releases { + if release.Draft && !g.IncludeDrafts { + continue + } + if release.Prerelease && !g.IncludePrereleases { + continue + } + return &release, nil + } + return nil, fmt.Errorf("couldn't find any suitable release on GitHub for project %s", g.Repository) +} + +func main() { + v := GitHubVersionProvider{Repository: "OpenSMTPD/OpenSMTPD"} + latest, err := v.GetVersion() + if err != nil { + return + } + fmt.Println(latest.String()) + + yv := YamlVersionProvider{ + File: "./versions.yml", + Key: "opensmtpd_version", + } + + current, err := yv.GetVersion() + if err != nil { + return + } + fmt.Println(current.String()) + +} diff --git a/provider_github.go b/provider_github.go new file mode 100644 index 0000000..b97e254 --- /dev/null +++ b/provider_github.go @@ -0,0 +1,19 @@ +package main + +type GitHubVersionProvider struct { + Repository string + IncludeDrafts bool + IncludePrereleases bool +} + +type GitHubRelease struct { + TagName string `json:"tag_name"` + Draft bool `json:"draft"` + Prerelease bool `json:"prerelease"` + Body string `json:"body"` +} + +func (g GitHubRelease) String() string { return g.TagName } +func (g GitHubRelease) Compare() int { + return 0 // TODO +} diff --git a/provider_yaml.go b/provider_yaml.go new file mode 100644 index 0000000..cb62ef8 --- /dev/null +++ b/provider_yaml.go @@ -0,0 +1,37 @@ +package main + +import ( + "fmt" + "os" + + "gopkg.in/yaml.v2" +) + +type YamlVersionProvider struct { + File string + Key string +} + +type YamlVersion string + +func (y YamlVersion) String() string { return string(y) } + +func (y YamlVersionProvider) GetVersion() (Version, error) { + f, err := os.Open(y.File) + if err != nil { + return nil, fmt.Errorf("couldn't open yaml file for reading: %w", err) + } + defer f.Close() + var data map[string]interface{} + err = yaml.NewDecoder(f).Decode(&data) + if err != nil { + return nil, fmt.Errorf("couldn't parse yaml file: %w", err) + } + + val, ok := data[y.Key] + if !ok { + return nil, fmt.Errorf("couldn't find key \"%s\"", y.Key) + } + + return YamlVersion(fmt.Sprintf("%v", val)), nil +} diff --git a/provider_yaml_test.go b/provider_yaml_test.go new file mode 100644 index 0000000..38f40db --- /dev/null +++ b/provider_yaml_test.go @@ -0,0 +1,26 @@ +package main + +import ( + "os" + "path" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestReadsVersionFromYaml(t *testing.T) { + tmp := t.TempDir() + path := path.Join(tmp, "test.yml") + f, err := os.Create(path) + assert.NoError(t, err) + f.WriteString("yaml_test_ver: v2137") + f.Close() + + p := YamlVersionProvider{ + File: path, + Key: "yaml_test_ver", + } + v, err := p.GetVersion() + assert.NoError(t, err) + assert.Equal(t, "v2137", v.String()) +} diff --git a/simple_comparison.go b/simple_comparison.go new file mode 100644 index 0000000..5fe854f --- /dev/null +++ b/simple_comparison.go @@ -0,0 +1,42 @@ +package main + +import ( + "regexp" + "strconv" + "strings" +) + +var versionSplitRegex = regexp.MustCompile("([0-9]+|[a-z]+)") + +func splitVer(ver Version) []string { + return versionSplitRegex.FindAllString(ver.String(), -1) +} + +func SimpleCompareVer(ver1 Version, ver2 Version) int { + ver1_split := splitVer(ver1) + ver2_split := splitVer(ver2) + + for i, item := range ver1_split { + if i >= len(ver2_split) { + return 1 + } + item2 := ver2_split[i] + item_int, err := strconv.ParseInt(item, 10, 32) + item2_int, err2 := strconv.ParseInt(item2, 10, 32) + if err == nil && err2 == nil { + if item_int > item2_int { + return 1 + } + if item_int == item2_int { + continue + } + if item_int < item2_int { + return -1 + } + } + if c := strings.Compare(item, ver2_split[i]); c != 0 { + return c + } + } + return 0 +} diff --git a/simple_comparison_test.go b/simple_comparison_test.go new file mode 100644 index 0000000..40ff5ee --- /dev/null +++ b/simple_comparison_test.go @@ -0,0 +1,29 @@ +package main + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestCompareVer(t *testing.T) { + version_pairs := []struct { + lower string + higher string + }{ + {"v21.3", "v21.37"}, + {"R21a", "R21b"}, + {"2137", "2138"}, + {"21.3.6", "21.4"}, + {"21.36", "21.48.6"}, + {"a", "b"}, + } + for _, pair := range version_pairs { + lower := YamlVersion(pair.lower) + higher := YamlVersion(pair.higher) + assert.Equal(t, -1, SimpleCompareVer(lower, higher), "%s, %s", lower, higher) + assert.Equal(t, 1, SimpleCompareVer(higher, lower)) + assert.Equal(t, 0, SimpleCompareVer(lower, lower)) + assert.Equal(t, 0, SimpleCompareVer(higher, higher)) + } +}