From b5261f04fee271034069ab19cf2e2ed6c3202a8e Mon Sep 17 00:00:00 2001 From: Zachary Yedidia Date: Fri, 27 May 2022 10:17:12 -0700 Subject: [PATCH] Support option to only download on upgrade Closes #14 --- README.md | 2 ++ eget.go | 25 +++++++++++++++++++++++++ find.go | 14 ++++++++++++-- flags.go | 1 + man/eget.md | 4 ++++ 5 files changed, 44 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index afcb4ed..99d9472 100644 --- a/README.md +++ b/README.md @@ -132,6 +132,8 @@ Application Options: --all extract all candidate files -q, --quiet only print essential output --download-only stop after downloading the asset (no extraction) + --upgrade-only only download if release is more recent than current + version -a, --asset= download a specific asset containing the given string; can be specified multiple times for additional filtering --sha256 show the SHA-256 hash of the downloaded asset diff --git a/eget.go b/eget.go index 35e8211..050380c 100644 --- a/eget.go +++ b/eget.go @@ -2,6 +2,7 @@ package main import ( "bytes" + "errors" "fmt" "io" "io/fs" @@ -104,10 +105,18 @@ func getFinder(project string, opts *Flags) (finder Finder, tool string) { tag = fmt.Sprintf("tags/%s", opts.Tag) } + var mint time.Time + if opts.UpgradeOnly { + parts := strings.Split(project, "/") + last := parts[len(parts)-1] + mint = bintime(last) + } + finder = &GithubAssetFinder{ Repo: repo, Tag: tag, Prerelease: opts.Prerelease, + MinTime: mint, } } return finder, tool @@ -227,6 +236,18 @@ func userSelect(choices []interface{}) int { return choice } +func bintime(bin string) (t time.Time) { + dir := "." + if ebin := os.Getenv("EGET_BIN"); ebin != "" { + dir = ebin + } + fi, err := os.Stat(filepath.Join(dir, bin)) + if err != nil { + return + } + return fi.ModTime() +} + func main() { var opts Flags flagparser := flags.NewParser(&opts, flags.PassDoubleDash|flags.PrintErrors) @@ -270,6 +291,10 @@ func main() { finder, tool := getFinder(args[0], &opts) assets, err := finder.Find() if err != nil { + if errors.Is(err, ErrNoUpgrade) { + fmt.Fprintf(output, "%v\n", err) + os.Exit(0) + } fatal(err) } diff --git a/find.go b/find.go index 92dd52e..9c6d51e 100644 --- a/find.go +++ b/find.go @@ -2,9 +2,11 @@ package main import ( "encoding/json" + "errors" "fmt" "io" "net/http" + "time" ) // A Finder returns a list of URLs making up a project's assets. @@ -18,8 +20,9 @@ type GithubRelease struct { DownloadURL string `json:"browser_download_url"` } `json:"assets"` - Prerelease bool `json:"prerelease"` - Tag string `json:"tag_name"` + Prerelease bool `json:"prerelease"` + Tag string `json:"tag_name"` + CreatedAt time.Time `json:"created_at"` } type GithubError struct { @@ -49,8 +52,11 @@ type GithubAssetFinder struct { Repo string Tag string Prerelease bool + MinTime time.Time // release must be after MinTime to be found } +var ErrNoUpgrade = errors.New("requested release is not more recent than current version") + func (f *GithubAssetFinder) Find() ([]string, error) { if f.Prerelease && f.Tag == "latest" { tag, err := f.getLatestTag() @@ -94,6 +100,10 @@ func (f *GithubAssetFinder) Find() ([]string, error) { return nil, err } + if release.CreatedAt.Before(f.MinTime) { + return nil, ErrNoUpgrade + } + // accumulate all assets from the json into a slice assets := make([]string, 0, len(release.Assets)) for _, a := range release.Assets { diff --git a/flags.go b/flags.go index d4b8b4f..da16186 100644 --- a/flags.go +++ b/flags.go @@ -9,6 +9,7 @@ type Flags struct { All bool `long:"all" description:"extract all candidate files"` Quiet bool `short:"q" long:"quiet" description:"only print essential output"` DLOnly bool `long:"download-only" description:"stop after downloading the asset (no extraction)"` + UpgradeOnly bool `long:"upgrade-only" description:"only download if release is more recent than current version"` Asset []string `short:"a" long:"asset" description:"download a specific asset containing the given string; can be specified multiple times for additional filtering"` Hash bool `long:"sha256" description:"show the SHA-256 hash of the downloaded asset"` Verify string `long:"verify-sha256" description:"verify the downloaded asset checksum against the one provided"` diff --git a/man/eget.md b/man/eget.md index cbdf490..54df26f 100644 --- a/man/eget.md +++ b/man/eget.md @@ -83,6 +83,10 @@ header: Eget Manual : Stop after downloading the asset. This prevents Eget from performing extraction, allowing you to perform manual installation after the asset is downloaded. + --upgrade-only + +: Only download the asset if the release is more recent than an existing asset with the same name in `$EGET_BIN`, or the current directory if `$EGET_BIN` is not defined. + `-a, --asset=` : Download a specific asset containing the given string. If there is an exact match with an asset, that asset is used regardless. This option can be specified multiple times for additional filtering. Example: **`eget --asset nvim.appimage neovim/neovim`**. Example **`eget --download-only --asset amd64.deb --asset musl sharkdp/bat`**.