summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEltrac <hi@guhub.cn>2025-11-11 16:52:22 +0800
committerEltrac <hi@guhub.cn>2025-11-11 16:52:22 +0800
commit9cc339569c2014d6f58f6fc585f5bf952962ba19 (patch)
treeb7c066a8582f8028a7a3bb0d44b6c9c4d08050db
parentda95e9b0cab8d7aa0ee0bb7b85809159d20c4f8e (diff)
feat(cli): print how recent a formulae is used
-rw-r--r--go.mod1
-rw-r--r--go.sum2
-rw-r--r--print.go45
3 files changed, 46 insertions, 2 deletions
diff --git a/go.mod b/go.mod
index e83fa49..e4ccc5b 100644
--- a/go.mod
+++ b/go.mod
@@ -5,6 +5,7 @@ go 1.25.4
require (
github.com/adrg/xdg v0.5.3 // direct
github.com/fatih/color v1.18.0 // direct
+ github.com/hako/durafmt v0.0.0-20180520121703-7b7ae1e72ead // direct
github.com/urfave/cli/v3 v3.6.0 // direct
)
diff --git a/go.sum b/go.sum
index 17a574c..0b9ea11 100644
--- a/go.sum
+++ b/go.sum
@@ -4,6 +4,8 @@ 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=
github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=
github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=
+github.com/hako/durafmt v0.0.0-20180520121703-7b7ae1e72ead h1:Y9WOGZY2nw5ksbEf5AIpk+vK52Tdg/VN/rHFRfEeeGQ=
+github.com/hako/durafmt v0.0.0-20180520121703-7b7ae1e72ead/go.mod h1:5Scbynm8dF1XAPwIwkGPqzkM/shndPm79Jd1003hTjE=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
diff --git a/print.go b/print.go
index ad85957..f268ec5 100644
--- a/print.go
+++ b/print.go
@@ -4,6 +4,11 @@ import (
"fmt"
"github.com/fatih/color"
"strings"
+ "os"
+ "path/filepath"
+ "syscall"
+ "time"
+ "github.com/hako/durafmt"
)
func PrintInfo(formula *FormulaInfo, cask *CaskInfo, pkgName string) {
@@ -14,6 +19,7 @@ func PrintInfo(formula *FormulaInfo, cask *CaskInfo, pkgName string) {
printHeader(formula, cask)
printInstallDesc(formula, cask)
+ printRecentActivity(formula, cask, pkgName)
printVersionInfo(formula, cask)
printMetadata(formula, cask)
@@ -53,9 +59,9 @@ func printInstallDesc(formula *FormulaInfo, cask *CaskInfo) {
if len(formula.Installed) == 0 {
return
} else if formula.Installed[0].InstalledOnRequest {
- color.Blue("You installed this package by running `brew install`.\n")
+ color.Blue("► You installed this package by running `brew install`.\n")
} else if formula.Installed[0].InstalledAsDependency {
- color.Blue("This package was installed automatically as a dependency.\n")
+ color.Blue("► This package was installed automatically as a dependency.\n")
// list reverse dependencies
dependencies, err := GetReverseDependencies(formula.Name)
if err != nil {
@@ -67,6 +73,41 @@ func printInstallDesc(formula *FormulaInfo, cask *CaskInfo) {
fmt.Println()
}
+// answers questions like "have I used this recently?"
+func printRecentActivity(formula *FormulaInfo, cask *CaskInfo, pkgName string) {
+ // skip if not installed
+ if (formula != nil && len(formula.Installed) == 0) ||
+ (cask != nil && cask.Installed == "") {
+ return
+ }
+
+ // get last access time (atime)
+ binPath := filepath.Join("/opt/homebrew/bin", pkgName)
+ info, err := os.Stat(binPath)
+ if err != nil {
+ return // skip if no binary is found
+ }
+ atime := info.Sys().(*syscall.Stat_t).Atimespec
+
+ // print usage info
+ var format string
+ var humanReadableDuration string
+
+ timestamp := time.Unix(atime.Unix())
+ humanReadableDuration = durafmt.ParseShort(time.Since(timestamp)).String()
+ format = func() string {
+ if atime.Nano() == 0 {
+ return "► You never used this."
+ } else if time.Since(timestamp) < 24*7*time.Hour {
+ return "► You used this in %s."
+ } else {
+ return "► You haven't used this for %s."
+ }
+ }()
+
+ color.Blue(format, humanReadableDuration)
+}
+
// prints badges like [Outdated] [Up to date] ...
// used by printMetadata
func printVersionInfo(formula *FormulaInfo, cask *CaskInfo) {