diff options
Diffstat (limited to 'internal/cli')
| -rw-r--r-- | internal/cli/check.go | 100 | ||||
| -rw-r--r-- | internal/cli/cli.go | 3 | ||||
| -rw-r--r-- | internal/cli/commands.go | 19 | ||||
| -rw-r--r-- | internal/cli/styles.go | 2 |
4 files changed, 118 insertions, 6 deletions
diff --git a/internal/cli/check.go b/internal/cli/check.go new file mode 100644 index 0000000..1df5137 --- /dev/null +++ b/internal/cli/check.go @@ -0,0 +1,100 @@ +package cli + +import ( + "fmt" + + tea "github.com/charmbracelet/bubbletea" + "github.com/charmbracelet/lipgloss" + + "github.com/hachem-wtf/benson/internal/config" + "github.com/hachem-wtf/benson/internal/modrinth" +) + +type compatMod struct { + slug string + filename string +} + +type checkResult struct { + compatible []compatMod + incompatible []string + failed []string +} + +func runCheck(m *model) tea.Cmd { + m.busy = true + cfg := m.cfg + return tea.Batch(m.spin.Tick, func() tea.Msg { + return outputMsg{text: checkReport(cfg)} + }) +} + +func checkReport(cfg *config.Config) string { + client := modrinth.NewClient() + var res checkResult + + for _, slug := range cfg.ModrinthMods { + versions, err := client.GetVersions(slug) + if err != nil { + res.failed = append(res.failed, slug) + continue + } + + match := modrinth.CompatibleVersion(versions, cfg.MinecraftVersion, "fabric") + if match == nil { + res.incompatible = append(res.incompatible, slug) + continue + } + + filename := match.VersionNumber + if len(match.Files) > 0 { + filename = match.Files[0].Filename + } + res.compatible = append(res.compatible, compatMod{slug: slug, filename: filename}) + } + + return renderCheck(cfg, res) +} + +func renderCheck(cfg *config.Config, res checkResult) string { + rows := []string{ + headingStyle.Render(fmt.Sprintf("Compatibility · MC %s · Fabric", cfg.MinecraftVersion)), + "", + } + + if len(res.compatible) > 0 { + rows = append(rows, successStyle.Render("Compatible")) + for _, c := range res.compatible { + rows = append(rows, " "+successStyle.Render("✓ ")+c.slug+mutedStyle.Render(" → "+c.filename)) + } + rows = append(rows, "") + } + + if len(res.incompatible) > 0 { + rows = append(rows, errorStyle.Render("No compatible version")) + for _, slug := range res.incompatible { + rows = append(rows, " "+errorStyle.Render("✗ ")+slug) + } + rows = append(rows, "") + } + + if len(res.failed) > 0 { + rows = append(rows, warnStyle.Render("Failed to check")) + for _, slug := range res.failed { + rows = append(rows, " "+warnStyle.Render("! ")+slug) + } + rows = append(rows, "") + } + + total := len(cfg.ModrinthMods) + ok := len(res.compatible) + rows = append(rows, mutedStyle.Render(fmt.Sprintf("Summary: %d/%d mods compatible", ok, total))) + + if len(res.incompatible) == 0 && len(res.failed) == 0 { + rows = append(rows, successStyle.Render("Safe to generate.")) + } else { + rows = append(rows, warnStyle.Render("Not all mods are compatible — generate may have issues.")) + } + + return lipgloss.JoinVertical(lipgloss.Left, rows...) +} diff --git a/internal/cli/cli.go b/internal/cli/cli.go index 4e394e6..6609a7e 100644 --- a/internal/cli/cli.go +++ b/internal/cli/cli.go @@ -101,6 +101,9 @@ func (m *model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { return m, tea.Println(msg.text) case spinner.TickMsg: + if !m.busy { + return m, nil + } var cmd tea.Cmd m.spin, cmd = m.spin.Update(msg) return m, cmd diff --git a/internal/cli/commands.go b/internal/cli/commands.go index 1f1f132..cf7cc90 100644 --- a/internal/cli/commands.go +++ b/internal/cli/commands.go @@ -20,6 +20,11 @@ func defaultCommands() []command { }, }, { + name: "check", + desc: "Check whether the configured mods are compatible", + run: runCheck, + }, + { name: "help", desc: "Show available commands", run: func(m *model) tea.Cmd { @@ -30,15 +35,19 @@ func defaultCommands() []command { } func welcomeBlock(cfg *config.Config, version string) string { + header := lipgloss.JoinHorizontal( + lipgloss.Bottom, + titleStyle.Render("BENSON"), + subtitleStyle.Render(" v"+version), + ) + inner := lipgloss.JoinVertical( lipgloss.Left, - titleStyle.Render("BENSON"), - subtitleStyle.Render("a Minecraft server manager from hell"), - "", - mutedStyle.Render(fmt.Sprintf("Fabric · MC %s · v%s", cfg.MinecraftVersion, version)), + header, + mutedStyle.Render("Fabric · MC "+cfg.MinecraftVersion), ) - hint := mutedStyle.Render("Type a command below. Tab autocompletes · Ctrl+C quits.") + hint := mutedStyle.Render("Tab autocompletes · Ctrl+C quits") return lipgloss.JoinVertical(lipgloss.Left, bannerStyle.Render(inner), "", hint) } diff --git a/internal/cli/styles.go b/internal/cli/styles.go index c0a61e5..78d5cb4 100644 --- a/internal/cli/styles.go +++ b/internal/cli/styles.go @@ -14,7 +14,7 @@ var ( bannerStyle = lipgloss.NewStyle(). Border(lipgloss.RoundedBorder()). BorderForeground(colPrimary). - Padding(0, 3) + Padding(0, 2) titleStyle = lipgloss.NewStyle().Bold(true).Foreground(colPrimary) subtitleStyle = lipgloss.NewStyle().Foreground(colMuted) |
