mirror of
https://github.com/veggiemonk/awesome-docker.git
synced 2026-04-02 13:35:42 +02:00
Feat/tui browse (#1266)
* Add interactive TUI browser command using Bubbletea v2 Adds `awesome-docker browse` to interactively explore the curated list in a terminal UI with a category tree (left panel) and detailed resource view (right panel). Enriches health_cache.yaml with category and description fields so the cache is self-contained for the TUI. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Add TUI pagination, scrolloff, and fix visual overflow Add pagination keybindings (Ctrl+D/PgDn, Ctrl+U/PgUp, g/Home, G/End) to both tree and list panels. Implement scrolloff (4 lines) to keep context visible around the cursor. Fix list panel overflow caused by Unicode characters (★, ⑂) rendering wider than lipgloss measures, which pushed the footer off-screen. Improve selection highlight visibility with background colors. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -14,6 +14,7 @@ import (
|
||||
"github.com/veggiemonk/awesome-docker/internal/linter"
|
||||
"github.com/veggiemonk/awesome-docker/internal/parser"
|
||||
"github.com/veggiemonk/awesome-docker/internal/scorer"
|
||||
"github.com/veggiemonk/awesome-docker/internal/tui"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -49,6 +50,7 @@ func main() {
|
||||
reportCmd(),
|
||||
validateCmd(),
|
||||
ciCmd(),
|
||||
browseCmd(),
|
||||
)
|
||||
|
||||
if err := root.Execute(); err != nil {
|
||||
@@ -82,6 +84,24 @@ func collectURLs(sections []parser.Section, urls *[]string) {
|
||||
}
|
||||
}
|
||||
|
||||
type entryMeta struct {
|
||||
Category string
|
||||
Description string
|
||||
}
|
||||
|
||||
func collectEntriesWithCategory(sections []parser.Section, parentPath string, out map[string]entryMeta) {
|
||||
for _, s := range sections {
|
||||
path := s.Title
|
||||
if parentPath != "" {
|
||||
path = parentPath + " > " + s.Title
|
||||
}
|
||||
for _, e := range s.Entries {
|
||||
out[e.URL] = entryMeta{Category: path, Description: e.Description}
|
||||
}
|
||||
collectEntriesWithCategory(s.Children, path, out)
|
||||
}
|
||||
}
|
||||
|
||||
func runLinkChecks(prMode bool) (checkSummary, error) {
|
||||
doc, err := parseReadme()
|
||||
if err != nil {
|
||||
@@ -159,6 +179,16 @@ func runHealth(ctx context.Context) error {
|
||||
}
|
||||
|
||||
scored := scorer.ScoreAll(infos)
|
||||
|
||||
meta := make(map[string]entryMeta)
|
||||
collectEntriesWithCategory(doc.Sections, "", meta)
|
||||
for i := range scored {
|
||||
if m, ok := meta[scored[i].URL]; ok {
|
||||
scored[i].Category = m.Category
|
||||
scored[i].Description = m.Description
|
||||
}
|
||||
}
|
||||
|
||||
cacheEntries := scorer.ToCacheEntries(scored)
|
||||
|
||||
hc, err := cache.LoadHealthCache(healthCachePath)
|
||||
@@ -186,12 +216,15 @@ func scoredFromCache() ([]scorer.ScoredEntry, error) {
|
||||
scored := make([]scorer.ScoredEntry, 0, len(hc.Entries))
|
||||
for _, e := range hc.Entries {
|
||||
scored = append(scored, scorer.ScoredEntry{
|
||||
URL: e.URL,
|
||||
Name: e.Name,
|
||||
Status: scorer.Status(e.Status),
|
||||
Stars: e.Stars,
|
||||
HasLicense: e.HasLicense,
|
||||
LastPush: e.LastPush,
|
||||
URL: e.URL,
|
||||
Name: e.Name,
|
||||
Status: scorer.Status(e.Status),
|
||||
Stars: e.Stars,
|
||||
Forks: e.Forks,
|
||||
HasLicense: e.HasLicense,
|
||||
LastPush: e.LastPush,
|
||||
Category: e.Category,
|
||||
Description: e.Description,
|
||||
})
|
||||
}
|
||||
return scored, nil
|
||||
@@ -628,3 +661,23 @@ func ciHealthReportCmd() *cobra.Command {
|
||||
cmd.Flags().BoolVar(&strict, "strict", false, "Return non-zero when health/report fails")
|
||||
return cmd
|
||||
}
|
||||
|
||||
func browseCmd() *cobra.Command {
|
||||
var cachePath string
|
||||
cmd := &cobra.Command{
|
||||
Use: "browse",
|
||||
Short: "Interactive TUI browser for awesome-docker resources",
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
hc, err := cache.LoadHealthCache(cachePath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("load cache: %w", err)
|
||||
}
|
||||
if len(hc.Entries) == 0 {
|
||||
return fmt.Errorf("no cache data; run 'awesome-docker health' first")
|
||||
}
|
||||
return tui.Run(hc.Entries)
|
||||
},
|
||||
}
|
||||
cmd.Flags().StringVar(&cachePath, "cache", healthCachePath, "Path to health cache YAML")
|
||||
return cmd
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user