From 5a1d99989fa32be1684b9290b4a58e8418b7b92d Mon Sep 17 00:00:00 2001
From: shenwc <spd260@126.com>
Date: 星期二, 26 十一月 2024 17:57:50 +0800
Subject: [PATCH] 11111

---
 stores/github/github.go |  148 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 148 insertions(+), 0 deletions(-)

diff --git a/stores/github/github.go b/stores/github/github.go
new file mode 100755
index 0000000..bed1f9a
--- /dev/null
+++ b/stores/github/github.go
@@ -0,0 +1,148 @@
+// Package github provides a GitHub release store.
+package github
+
+import (
+	"context"
+	"fmt"
+	"runtime"
+	"time"
+
+	"github.com/google/go-github/github"
+	update "github.com/zan8in/goupdate"
+	"github.com/zan8in/goupdate/progress"
+)
+
+// Store is the store implementation.
+type Store struct {
+	Owner   string
+	Repo    string
+	Version string
+}
+
+type GithubResult struct {
+	Status        int // update success = 1; have latest version = 2;
+	LatestVersion string
+}
+
+// 更新最新版本
+// owner = zan8in
+// repo = afrog
+// version = 2.8.8 当前版本
+func Update(owner, repo, version string) (*GithubResult, error) {
+	var (
+		result = &GithubResult{}
+		err    error
+	)
+
+	m := &update.Manager{
+		Command: repo + ".exe",
+		Store: &Store{
+			Owner:   owner,
+			Repo:    repo,
+			Version: version,
+		},
+	}
+
+	// fetch the new releases
+	releases, err := m.LatestReleases()
+	if err != nil {
+		return result, fmt.Errorf("error fetching releases: %s", err)
+	}
+
+	// no updates
+	if len(releases) == 0 {
+		result.Status = 2
+		return result, nil
+	}
+
+	// latest release
+	latest := releases[0]
+
+	// find the tarball for this system
+	a := latest.FindZip(runtime.GOOS, runtime.GOARCH)
+	if a == nil {
+		return result, fmt.Errorf("no binary for your system")
+	}
+
+	// download tarball to a tmp dir
+	tarball, err := a.DownloadProxy(progress.Reader)
+	if err != nil {
+		return result, fmt.Errorf("error downloading: %s", err)
+	}
+
+	// install it
+	if err := m.Install(tarball); err != nil {
+		return result, fmt.Errorf("error installing: %s", err)
+	}
+
+	// gologger.Info().Msgf("Successfully updated to %s %s\n", repo, version)
+	result.LatestVersion = version
+	result.Status = 1
+	return result, nil
+}
+
+// GetRelease returns the specified release or ErrNotFound.
+func (s *Store) GetRelease(version string) (*update.Release, error) {
+	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+	defer cancel()
+
+	gh := github.NewClient(nil)
+
+	r, res, err := gh.Repositories.GetReleaseByTag(ctx, s.Owner, s.Repo, "v"+version)
+
+	if res.StatusCode == 404 {
+		return nil, update.ErrNotFound
+	}
+
+	if err != nil {
+		return nil, err
+	}
+
+	return githubRelease(r), nil
+}
+
+// LatestReleases returns releases newer than Version, or nil.
+func (s *Store) LatestReleases() (latest []*update.Release, err error) {
+	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+	defer cancel()
+
+	gh := github.NewClient(nil)
+
+	releases, _, err := gh.Repositories.ListReleases(ctx, s.Owner, s.Repo, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	for _, r := range releases {
+		tag := r.GetTagName()
+
+		if tag == s.Version || "v"+s.Version == tag {
+			break
+		}
+
+		latest = append(latest, githubRelease(r))
+	}
+
+	return
+}
+
+// githubRelease returns a Release.
+func githubRelease(r *github.RepositoryRelease) *update.Release {
+	out := &update.Release{
+		Version:     r.GetTagName(),
+		Notes:       r.GetBody(),
+		PublishedAt: r.GetPublishedAt().Time,
+		URL:         r.GetURL(),
+	}
+
+	for _, a := range r.Assets {
+		out.Assets = append(out.Assets, &update.Asset{
+			Name:      a.GetName(),
+			Size:      a.GetSize(),
+			URL:       a.GetBrowserDownloadURL(),
+			Downloads: a.GetDownloadCount(),
+		})
+	}
+
+	return out
+}

--
Gitblit v1.8.0