Files
streamrip-go/cmd/rip/cmd_config.go
T
JorenandClaude Opus 5 78d4f0316d refactor: split the command dispatch out of main.go
Completes the restructuring started when main() became run() int. main.go goes
from 1217 lines to 130: global option handling, config loading, signal setup,
and a dispatch switch that delegates to one function per command.

The command bodies move to cmd_rip.go (url, file, id), cmd_search.go (search,
lastfm), cmd_config.go (config, database) and cmd_smoke.go (the developer smoke
commands), each taking (ctx, cfg, gopts, args) and returning an exit code.

They also stop reading the process global. Previously run() did

    os.Args = append([]string{os.Args[0], gopts.command}, gopts.commandArgs...)

and the arms then indexed back into os.Args[2:], os.Args[5:] and so on, so the
already-parsed options were round-tripped through os.Args. The arms now take
the parsed gopts.commandArgs directly, which is a uniform index shift of two
(os.Args[5:] -> args[3:], len(os.Args) < 5 -> len(args) < 3).

No behaviour change. Verified by running each command's argument validation and
help path against the built binary, plus the existing suite.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-10-03 17:17:24 +02:00

129 lines
3.4 KiB
Go

package main
import (
"context"
"fmt"
"os"
"strings"
"streamrip-go/internal/config"
"golang.org/x/term"
)
// Commands that inspect local state: config and database.
func cmdConfig(_ context.Context, cfg *config.Config, _ globalOptions, args []string) int {
var err error
if len(args) < 1 {
printCommandHelp(os.Stdout, "config")
return 2
}
switch args[0] {
case "open":
vim := false
for _, arg := range args[1:] {
switch arg {
case "-v", "--vim":
vim = true
default:
fmt.Fprintf(os.Stderr, "option error: unknown option %q\n", arg)
return 2
}
}
fmt.Printf("opening file at %s\n", cfg.Path)
if err = openConfigInEditor(cfg.Path, vim); err != nil {
fmt.Fprintf(os.Stderr, "open config error: %v\n", err)
return 1
}
case "reset":
yes := false
for _, arg := range args[1:] {
switch arg {
case "-y", "--yes":
yes = true
default:
fmt.Fprintf(os.Stderr, "option error: unknown option %q\n", arg)
return 2
}
}
if !yes {
if !term.IsTerminal(int(os.Stdin.Fd())) {
fmt.Fprintln(os.Stderr, "reset requires --yes in non-interactive mode")
return 2
}
ok, askErr := promptYesNo(fmt.Sprintf("Are you sure you want to reset the config file at %s? [y/N]: ", cfg.Path))
if askErr != nil {
fmt.Fprintf(os.Stderr, "prompt error: %v\n", askErr)
return 1
}
if !ok {
fmt.Println("reset aborted")
return 0
}
}
def := config.DefaultConfigData()
// Separate copies: assigning the same value to both halves made
// File.Qobuz.Secrets and Session.Qobuz.Secrets share one backing
// array.
cfg.File = config.CloneConfigData(def)
cfg.Session = config.CloneConfigData(def)
if err = cfg.SaveFile(); err != nil {
fmt.Fprintf(os.Stderr, "reset config error: %v\n", err)
return 1
}
fmt.Printf("reset the config file at %s\n", cfg.Path)
case "path":
if len(args) > 1 {
fmt.Fprintf(os.Stderr, "option error: unexpected argument %q\n", args[1])
return 2
}
fmt.Printf("config path: '%s'\n", cfg.Path)
default:
fmt.Fprintf(os.Stderr, "unknown config command: %s\n", args[0])
return 2
}
return 0
}
func cmdDatabase(_ context.Context, cfg *config.Config, _ globalOptions, args []string) int {
if len(args) < 2 || args[0] != "browse" {
printCommandHelp(os.Stdout, "database")
return 2
}
table := strings.ToLower(strings.TrimSpace(args[1]))
switch table {
case "downloads":
rows, listErr := listDownloadsRows(cfg.Session.Database.DownloadsPath)
if listErr != nil {
fmt.Fprintf(os.Stderr, "database browse error: %v\n", listErr)
return 1
}
fmt.Println("downloads database")
fmt.Println("row id")
for i, id := range rows {
fmt.Printf("%02d %s\n", i, id)
}
case "failed":
rows, listErr := listFailedRows(cfg.Session.Database.FailedDownloadsPath)
if listErr != nil && isNoSuchTableErr(listErr) && cfg.Session.Database.FailedDownloadsPath != cfg.Session.Database.DownloadsPath {
rows, listErr = listFailedRows(cfg.Session.Database.DownloadsPath)
}
if listErr != nil {
fmt.Fprintf(os.Stderr, "database browse error: %v\n", listErr)
return 1
}
fmt.Println("failed downloads database")
fmt.Println("row source media_type id")
for i, row := range rows {
fmt.Printf("%02d %s %s %s\n", i, row.Source, row.MediaType, row.ID)
}
default:
fmt.Fprintf(os.Stderr, "invalid database %q. choose downloads or failed\n", table)
return 2
}
return 0
}