diff --git a/app/app_download.go b/app/app_download.go index 4cde2e2..6507bab 100644 --- a/app/app_download.go +++ b/app/app_download.go @@ -30,7 +30,7 @@ var ErrNoToken = errors.New("no github token") func getGithubToken() (string, error) { if os.Getenv("ZEGET_GITHUB_TOKEN") != "" { - return tokenFrom(os.Getenv("ZEGET_GITHUB_TOKEN")) + return tokenFrom(os.Getenv("EGET_GITHUB_TOKEN")) } if os.Getenv("EGET_GITHUB_TOKEN") != "" { return tokenFrom(os.Getenv("EGET_GITHUB_TOKEN")) @@ -61,6 +61,7 @@ func (app *Application) getDownloadProgressBar(size int64) *pb.ProgressBar { pb.OptionOnCompletion(func() { fmt.Fprint(pbout, "\n") }), + pb.OptionUseANSICodes(true), pb.OptionSetTheme(pb.Theme{ Saucer: "=", SaucerHead: ">", diff --git a/app/app_run.go b/app/app_run.go index aa3a443..f4b0514 100644 --- a/app/app_run.go +++ b/app/app_run.go @@ -89,7 +89,7 @@ func (app *Application) Run() *ReturnStatus { assetWrapper.Asset = &asset - app.WriteLine("› downloading %s...", assetWrapper.Asset.DownloadURL) // print the URL + app.WriteLine("› " + "downloading " + assetWrapper.Asset.DownloadURL + "...") // print the URL body, err := app.downloadAsset(assetWrapper.Asset, &findResult) // download with progress bar and get the response body if err != nil { @@ -103,6 +103,7 @@ func (app *Application) Run() *ReturnStatus { tagDownloaded := utilities.SetIf(app.Opts.Tag != "", "latest", app.Opts.Tag) app.Cache.Data.GetRepositoryEntryByKey(app.Target, &app.Cache).UpdateDownloadedAt(tagDownloaded) + // app.Cache.Data.GetRepositoryEntryByKey(app.Target, &app.Cache).UpdateReleaseDate(asset.ReleaseDate) extractor, err := app.getExtractor(assetWrapper.Asset, finder.Tool) if err != nil { diff --git a/app/app_write.go b/app/app_write.go index 88d92dd..f9085f7 100644 --- a/app/app_write.go +++ b/app/app_write.go @@ -2,10 +2,33 @@ package app import ( "fmt" + "reflect" + + "github.com/charmbracelet/lipgloss" ) +var checkMarkStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("#1bef52")).Bold(true) +var filenameStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("#efe51b")) +var fadedStyle = lipgloss.NewStyle().Foreground(lipgloss.Color("#fffff")) + func (app *Application) Write(format string, args ...any) (n int, err error) { - return fmt.Fprintf(app.Output, format, args...) + temp := []interface{}{} + var style *lipgloss.Style = nil + + for _, arg := range args { + if reflect.TypeOf(arg).Kind() == reflect.TypeOf(filenameStyle).Kind() { + s := arg.(lipgloss.Style) + style = &s + continue + } + temp = append(temp, arg) + } + + if style != nil { + format = style.Render(format) + } + + return fmt.Fprintf(app.Output, format, temp...) } func (app *Application) WriteLine(format string, args ...any) (n int, err error) { @@ -36,6 +59,14 @@ func (app *Application) WriteErrorLine(format string, args ...any) { app.WriteError(format+"\n", args...) } +func (app *Application) WriteCheck(newLine bool) { + if newLine { + app.WriteLine(checkMarkStyle.Render("✔ ")) + } else { + app.Write(checkMarkStyle.Render("✔ ")) + } +} + func (app *Application) initOutputs() { if app.Output != nil { return diff --git a/app/application.go b/app/application.go index f78ae48..d85237f 100644 --- a/app/application.go +++ b/app/application.go @@ -233,11 +233,14 @@ func (app *Application) RateLimitExceeded() error { func (app *Application) RefreshRateLimit() error { //diff in minutes between the current time and the rate limit reset time: - diff := app.Cache.Data.RateLimit.Reset.Sub(time.Now().Local()).Round(time.Second).Seconds() / 60 + var rate int64 = 10 - // not a percentage per se, but the rate limit remaining divided by the number of minutes until the rate limit resets - // provides a rough estimate of the rate of requests that can be made per minute until the rate limit resets. - rate := int64(app.Cache.Data.RateLimit.Remaining) / int64(diff) + if app.Cache.Data.RateLimit.Reset != nil { + diff := app.Cache.Data.RateLimit.Reset.Sub(time.Now().Local()).Round(time.Second).Seconds() / 60 + // not a percentage per se, but the rate limit remaining divided by the number of minutes until the rate limit resets + // provides a rough estimate of the rate of requests that can be made per minute until the rate limit resets. + rate = int64(app.Cache.Data.RateLimit.Remaining) / int64(diff) + } // fmt.Printf("Rate limit reset in %v ,minutes\n", diff) // fmt.Printf("Remaining rate limit: %d\n", app.Cache.Data.RateLimit.Remaining) @@ -372,6 +375,7 @@ func (app *Application) downloadAsset(asset *Asset, findResult *finders.FindResu } repo.UpdateDownloadedAt(asset.DownloadURL) + repo.UpdateReleaseDate(asset.ReleaseDate) return buf.Bytes(), nil } @@ -381,7 +385,7 @@ func (app *Application) VerifyChecksums(wrapper *AssetWrapper, body []byte) veri needsNewLine := false if verifier != nil && verifier.String() != (verifiers.NoVerifier{}).String() { - app.Write("› performing verification for %s...", wrapper.Asset.Name) + app.Write("› " + "validating checksums for " + filenameStyle.Render(wrapper.Asset.Name) + "...") needsNewLine = true } @@ -396,12 +400,14 @@ func (app *Application) VerifyChecksums(wrapper *AssetWrapper, body []byte) veri } if app.Opts.Verify == "" && sumAsset.Name != "" { - app.WriteLine("verified ✔") + app.Write("passed ") + app.WriteCheck(true) return verifiers.VerifyChecksumSuccess } if app.Opts.Verify != "" { - app.WriteLine("verified ✔") + app.Write("passed ") + app.WriteCheck(true) return verifiers.VerifyChecksumSuccess } @@ -461,7 +467,8 @@ func (app *Application) extract(bin ExtractedFile) error { return err } - app.WriteLine("› extracted `%s` to `%s` ✔", bin.ArchiveName, home.NewPathCompactor().Compact(out)) + app.Write("› extracted `%s` to `%s` ", filenameStyle.Render(bin.ArchiveName), filenameStyle.Render(home.NewPathCompactor().Compact(out))) + app.WriteCheck(true) return nil } diff --git a/go.mod b/go.mod index daaa6bc..88db67a 100644 --- a/go.mod +++ b/go.mod @@ -15,10 +15,16 @@ require ( ) require ( + github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect github.com/go-logr/logr v1.4.1 // indirect github.com/go-task/slim-sprig/v3 v3.0.0 // indirect github.com/google/go-cmp v0.6.0 // indirect github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6 // indirect + github.com/lucasb-eyer/go-colorful v1.2.0 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect + github.com/mattn/go-runewidth v0.0.15 // indirect + github.com/muesli/reflow v0.3.0 // indirect + github.com/muesli/termenv v0.15.2 // indirect golang.org/x/net v0.24.0 // indirect golang.org/x/text v0.14.0 // indirect golang.org/x/tools v0.20.0 // indirect @@ -26,6 +32,7 @@ require ( ) require ( + github.com/charmbracelet/lipgloss v0.10.0 github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db // indirect github.com/oklog/ulid/v2 v2.1.0 github.com/onsi/ginkgo/v2 v2.17.2 diff --git a/go.sum b/go.sum index ae87b74..1466f04 100644 --- a/go.sum +++ b/go.sum @@ -4,8 +4,12 @@ github.com/alecthomas/assert/v2 v2.6.0 h1:o3WJwILtexrEUk3cUVal3oiQY2tfgr/FHWiz/v github.com/alecthomas/assert/v2 v2.6.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k= github.com/alecthomas/repr v0.4.0 h1:GhI2A8MACjfegCPVq9f1FLvIBS+DrQ2KQBFZP1iFzXc= github.com/alecthomas/repr v0.4.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4= +github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k= +github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8= github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ= github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= +github.com/charmbracelet/lipgloss v0.10.0 h1:KWeXFSexGcfahHX+54URiZGkBFazf70JNMtwg/AFW3s= +github.com/charmbracelet/lipgloss v0.10.0/go.mod h1:Wig9DSfvANsxqkRsqj6x87irdy123SR4dOXlKa91ciE= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -26,9 +30,19 @@ github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c github.com/k0kubun/go-ansi v0.0.0-20180517002512-3bf9e2903213/go.mod h1:vNUNkEQ1e29fT/6vq2aBdFsgNPmy8qMdSay1npru+Sw= github.com/klauspost/compress v1.17.8 h1:YcnTYrq7MikUT7k0Yb5eceMmALQPYBW/Xltxn0NAMnU= github.com/klauspost/compress v1.17.8/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= +github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= +github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk= +github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= +github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db h1:62I3jR2EmQ4l5rM/4FEfDWcRD+abF5XlKShorW5LRoQ= github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db/go.mod h1:l0dey0ia/Uv7NcFFVbCLtqEBQbrT4OCwCSKTEv6enCw= +github.com/muesli/reflow v0.3.0 h1:IFsN6K9NfGtjeggFP+68I4chLZV2yIKsXJFNZ+eWh6s= +github.com/muesli/reflow v0.3.0/go.mod h1:pbwTDkVPibjO2kyvBQRBxTWEEGDGq0FlB1BIKtnHY/8= +github.com/muesli/termenv v0.15.2 h1:GohcuySI0QmI3wN8Ok9PtKGkgkFIk7y6Vpb5PvrY+Wo= +github.com/muesli/termenv v0.15.2/go.mod h1:Epx+iuz8sNs7mNKhxzH4fWXGNpZwUaJKRS1noLXviQ8= github.com/oklog/ulid/v2 v2.1.0 h1:+9lhoxAP56we25tyYETBBY1YLA2SaoLvUFgrP2miPJU= github.com/oklog/ulid/v2 v2.1.0/go.mod h1:rcEKHmBBKfef9DhnvX7y1HZBYxjXb0cP5ExxNsTT1QQ= github.com/onsi/ginkgo/v2 v2.17.2 h1:7eMhcy3GimbsA3hEnVKdw/PQM9XN9krpKVXsZdph0/g= @@ -38,6 +52,8 @@ github.com/onsi/gomega v1.33.1/go.mod h1:U4R44UsT+9eLIaYRB2a5qajjtQYn0hauxvRm16A github.com/pborman/getopt v0.0.0-20170112200414-7148bc3a4c30/go.mod h1:85jBQOZwpVEaDAr341tbn15RS4fCAsIst0qp7i8ex1o= 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/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/schollz/progressbar/v3 v3.14.2 h1:EducH6uNLIWsr560zSV1KrTeUb/wZGAHqyMFIEa99ks= diff --git a/lib/data/cache.go b/lib/data/cache.go index 02c50f3..3dccb41 100644 --- a/lib/data/cache.go +++ b/lib/data/cache.go @@ -98,6 +98,10 @@ func (c *Cache) AddRepository(name, target string, filters []string, findResult LastCheckAt: time.Now(), } + if len(findResult.Assets) > 0 { + entry.LastReleaseDate = findResult.Assets[0].ReleaseDate + } + c.Set(entry.Name, &entry) c.SaveToFile() diff --git a/lib/data/types.go b/lib/data/types.go index 8714a42..3d4d7f9 100644 --- a/lib/data/types.go +++ b/lib/data/types.go @@ -67,6 +67,14 @@ func (rce *RepositoryCacheEntry) UpdateCheckedAt() { } } +func (rce *RepositoryCacheEntry) UpdateReleaseDate(date time.Time) { + rce.LastReleaseDate = date + + if rce.owner != nil { + rce.owner.SaveToFile() + } +} + func (rce *RepositoryCacheEntry) UpdateDownloadedAt(tag string) { rce.LastDownloadAt = time.Now().Local() rce.LastDownloadTag = tag