Add PR checks command, iostreams/text packages for colored table output, top-level run/workflow aliases matching gh CLI structure. Enhance actions, issues, PRs, releases, repos, labels, milestones, and wiki commands with improved flags, JSON output, and error handling.
70 lines
1.6 KiB
Go
70 lines
1.6 KiB
Go
package text
|
|
|
|
import (
|
|
"fmt"
|
|
"math"
|
|
"time"
|
|
)
|
|
|
|
// Pluralize returns "1 issue" or "2 issues" depending on count.
|
|
// It applies a simple "s" suffix rule.
|
|
func Pluralize(count int, singular string) string {
|
|
if count == 1 {
|
|
return fmt.Sprintf("%d %s", count, singular)
|
|
}
|
|
return fmt.Sprintf("%d %ss", count, singular)
|
|
}
|
|
|
|
// FuzzyAgo returns a human-friendly relative time string like "just now",
|
|
// "2 minutes ago", "3 hours ago", etc.
|
|
func FuzzyAgo(t time.Time) string {
|
|
d := time.Since(t)
|
|
|
|
if d < time.Minute {
|
|
return "just now"
|
|
}
|
|
|
|
minutes := int(math.Floor(d.Minutes()))
|
|
if minutes < 60 {
|
|
return fmt.Sprintf("%s ago", Pluralize(minutes, "minute"))
|
|
}
|
|
|
|
hours := int(math.Floor(d.Hours()))
|
|
if hours < 24 {
|
|
return fmt.Sprintf("%s ago", Pluralize(hours, "hour"))
|
|
}
|
|
|
|
days := hours / 24
|
|
if days < 30 {
|
|
return fmt.Sprintf("%s ago", Pluralize(days, "day"))
|
|
}
|
|
|
|
months := days / 30
|
|
if months < 12 {
|
|
return fmt.Sprintf("%s ago", Pluralize(months, "month"))
|
|
}
|
|
|
|
years := months / 12
|
|
return fmt.Sprintf("%s ago", Pluralize(years, "year"))
|
|
}
|
|
|
|
// Truncate shortens text to maxWidth, replacing the end with "..." if it exceeds
|
|
// the limit. If maxWidth is less than or equal to 3, the result is just "...".
|
|
func Truncate(text string, maxWidth int) string {
|
|
if len(text) <= maxWidth {
|
|
return text
|
|
}
|
|
if maxWidth <= 3 {
|
|
return "..."[:maxWidth]
|
|
}
|
|
return text[:maxWidth-3] + "..."
|
|
}
|
|
|
|
// FormatDate returns a human-friendly relative time for TTY output, or an
|
|
// RFC3339 timestamp for piped output.
|
|
func FormatDate(t time.Time, isTTY bool) string {
|
|
if isTTY {
|
|
return FuzzyAgo(t)
|
|
}
|
|
return t.Format(time.RFC3339)
|
|
}
|