diff --git a/cmd/cmd.go b/cmd/cmd.go index e286ec2..0afd647 100644 --- a/cmd/cmd.go +++ b/cmd/cmd.go @@ -9,13 +9,13 @@ import ( "gabe565.com/ascii-movie/cmd/ls" "gabe565.com/ascii-movie/cmd/play" "gabe565.com/ascii-movie/cmd/serve" - "gabe565.com/ascii-movie/cmd/util" "gabe565.com/ascii-movie/internal/config" + "gabe565.com/utils/cobrax" "github.com/spf13/cobra" flag "github.com/spf13/pflag" ) -func NewCommand(opts ...util.Option) *cobra.Command { +func NewCommand(opts ...cobrax.Option) *cobra.Command { cmd := &cobra.Command{ Use: "ascii-movie", Short: "Command line ASCII movie player.", diff --git a/cmd/get/cmd.go b/cmd/get/cmd.go index 8d01e2e..2e8c154 100644 --- a/cmd/get/cmd.go +++ b/cmd/get/cmd.go @@ -5,13 +5,14 @@ import ( "net/url" "gabe565.com/ascii-movie/cmd/get/stream" - "gabe565.com/ascii-movie/cmd/util" "gabe565.com/ascii-movie/internal/config" "gabe565.com/ascii-movie/internal/server" + "gabe565.com/utils/cobrax" + "gabe565.com/utils/must" "github.com/spf13/cobra" ) -func NewCommand(opts ...util.Option) *cobra.Command { +func NewCommand(opts ...cobrax.Option) *cobra.Command { cmd := &cobra.Command{ Use: "get", Short: "Fetches data from a running server.", @@ -31,10 +32,7 @@ func NewCommand(opts ...util.Option) *cobra.Command { } func preRun(cmd *cobra.Command, _ []string) error { - apiAddr, err := cmd.Flags().GetString(server.APIFlagPrefix + server.AddressFlag) - if err != nil { - panic(err) - } + apiAddr := must.Must2(cmd.Flags().GetString(server.APIFlagPrefix + server.AddressFlag)) u, err := url.Parse(apiAddr) if err != nil { diff --git a/cmd/get/stream/cmd.go b/cmd/get/stream/cmd.go index dc730e3..f316d7a 100644 --- a/cmd/get/stream/cmd.go +++ b/cmd/get/stream/cmd.go @@ -10,9 +10,10 @@ import ( "text/tabwriter" "time" - "gabe565.com/ascii-movie/cmd/util" "gabe565.com/ascii-movie/internal/config" "gabe565.com/ascii-movie/internal/server" + "gabe565.com/utils/cobrax" + "gabe565.com/utils/must" "github.com/spf13/cobra" ) @@ -21,7 +22,7 @@ const ( CountTotal = "total" ) -func NewCommand(opts ...util.Option) *cobra.Command { +func NewCommand(opts ...cobrax.Option) *cobra.Command { cmd := &cobra.Command{ Use: "stream", Aliases: []string{"streams", "connection", "connections", "client", "clients"}, @@ -59,9 +60,7 @@ func preRun(cmd *cobra.Command, args []string) error { count = "total" } if count != "" { - if err := cmd.Flags().Set("count", count); err != nil { - panic(err) - } + must.Must(cmd.Flags().Set("count", count)) } } return nil @@ -74,17 +73,14 @@ var ( ) func run(cmd *cobra.Command, _ []string) error { - countFlag, err := cmd.Flags().GetString("count") - if err != nil { - panic(err) - } + countFlag := must.Must2(cmd.Flags().GetString("count")) u, ok := cmd.Context().Value(config.URLContextKey).(*url.URL) if !ok { panic(fmt.Errorf("%w: %v", ErrInvalidURL, u)) } - u, err = u.Parse("/streams") + u, err := u.Parse("/streams") if err != nil { return err } diff --git a/cmd/ls/cmd.go b/cmd/ls/cmd.go index 2372774..0c2f58b 100644 --- a/cmd/ls/cmd.go +++ b/cmd/ls/cmd.go @@ -8,14 +8,14 @@ import ( "text/tabwriter" "time" - cmdutil "gabe565.com/ascii-movie/cmd/util" "gabe565.com/ascii-movie/internal/movie" "gabe565.com/ascii-movie/internal/util" + "gabe565.com/utils/cobrax" "github.com/dustin/go-humanize" "github.com/spf13/cobra" ) -func NewCommand(opts ...cmdutil.Option) *cobra.Command { +func NewCommand(opts ...cobrax.Option) *cobra.Command { cmd := &cobra.Command{ Use: "ls [PATH]...", Aliases: []string{"ls-embedded"}, diff --git a/cmd/play/cmd.go b/cmd/play/cmd.go index a57888b..8e467c5 100644 --- a/cmd/play/cmd.go +++ b/cmd/play/cmd.go @@ -3,15 +3,15 @@ package play import ( "log/slog" - "gabe565.com/ascii-movie/cmd/util" "gabe565.com/ascii-movie/internal/config" "gabe565.com/ascii-movie/internal/movie" "gabe565.com/ascii-movie/internal/player" + "gabe565.com/utils/cobrax" tea "github.com/charmbracelet/bubbletea" "github.com/spf13/cobra" ) -func NewCommand(opts ...util.Option) *cobra.Command { +func NewCommand(opts ...cobrax.Option) *cobra.Command { cmd := &cobra.Command{ Use: "play [movie]", Short: "Play an ASCII movie locally.", diff --git a/cmd/serve/cmd.go b/cmd/serve/cmd.go index 0ac7cb4..08ba9ab 100644 --- a/cmd/serve/cmd.go +++ b/cmd/serve/cmd.go @@ -8,16 +8,16 @@ import ( "os/signal" "syscall" - "gabe565.com/ascii-movie/cmd/util" "gabe565.com/ascii-movie/internal/movie" "gabe565.com/ascii-movie/internal/server" + "gabe565.com/utils/cobrax" "github.com/charmbracelet/lipgloss" "github.com/muesli/termenv" "github.com/spf13/cobra" "golang.org/x/sync/errgroup" ) -func NewCommand(opts ...util.Option) *cobra.Command { +func NewCommand(opts ...cobrax.Option) *cobra.Command { cmd := &cobra.Command{ Use: "serve [movie]", Aliases: []string{"server", "listen"}, @@ -43,8 +43,8 @@ var ErrAllDisabled = errors.New("all server types are disabled") func run(cmd *cobra.Command, args []string) error { if parent := cmd.Parent(); parent != nil { slog.Info("ASCII Movie", - "version", parent.Annotations["version"], - "commit", parent.Annotations["commit"], + "version", cobrax.GetVersion(cmd), + "commit", cobrax.GetCommit(cmd), ) } diff --git a/cmd/util/options.go b/cmd/util/options.go deleted file mode 100644 index a50a876..0000000 --- a/cmd/util/options.go +++ /dev/null @@ -1,21 +0,0 @@ -package util - -import "github.com/spf13/cobra" - -type Option func(cmd *cobra.Command) - -const ( - VersioonKey = "version" - CommitKey = "commit" -) - -func WithVersion(version string) Option { - return func(cmd *cobra.Command) { - if cmd.Annotations == nil { - cmd.Annotations = make(map[string]string, 2) - } - cmd.Annotations[VersioonKey] = version - cmd.Version, cmd.Annotations[CommitKey] = buildVersion(version) - cmd.InitDefaultVersionFlag() - } -} diff --git a/cmd/util/version.go b/cmd/util/version.go deleted file mode 100644 index 5ea76ff..0000000 --- a/cmd/util/version.go +++ /dev/null @@ -1,31 +0,0 @@ -package util - -import "runtime/debug" - -func buildVersion(version string) (string, string) { - var commit string - var modified bool - if info, ok := debug.ReadBuildInfo(); ok { - for _, setting := range info.Settings { - switch setting.Key { - case "vcs.revision": - commit = setting.Value - case "vcs.modified": - if setting.Value == "true" { - modified = true - } - } - } - } - - if commit != "" { - if len(commit) > 8 { - commit = commit[:8] - } - if modified { - commit = "*" + commit - } - version += " (" + commit + ")" - } - return version, commit -} diff --git a/cmd/util/version_test.go b/cmd/util/version_test.go deleted file mode 100644 index 1cfeaef..0000000 --- a/cmd/util/version_test.go +++ /dev/null @@ -1,12 +0,0 @@ -package util - -import ( - "testing" - - "github.com/stretchr/testify/assert" -) - -func Test_buildVersion(t *testing.T) { - got, _ := buildVersion("0.0.0-next") - assert.Equal(t, "0.0.0-next", got) -} diff --git a/go.mod b/go.mod index b343643..282b79e 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module gabe565.com/ascii-movie go 1.23.3 require ( + gabe565.com/utils v0.0.0-20241111053222-0f59399cbb3c github.com/charmbracelet/bubbles v0.20.0 github.com/charmbracelet/bubbletea v1.2.2 github.com/charmbracelet/lipgloss v1.0.0 @@ -12,7 +13,6 @@ require ( github.com/dustin/go-humanize v1.0.1 github.com/lmittmann/tint v1.0.5 github.com/lrstanley/bubblezone v0.0.0-20240914071701-b48c55a5e78e - github.com/mattn/go-isatty v0.0.20 github.com/muesli/termenv v0.15.3-0.20240509142007-81b8f94111d5 github.com/prometheus/client_golang v1.20.5 github.com/spf13/cobra v1.8.1 @@ -36,7 +36,7 @@ require ( github.com/charmbracelet/x/term v0.2.1 // indirect github.com/charmbracelet/x/termios v0.1.0 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.4 // indirect - github.com/creack/pty v1.1.21 // indirect + github.com/creack/pty v1.1.24 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect github.com/go-logfmt/logfmt v0.6.0 // indirect @@ -44,6 +44,7 @@ require ( github.com/klauspost/compress v1.17.9 // indirect github.com/kr/text v0.2.0 // indirect github.com/lucasb-eyer/go-colorful v1.2.0 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-localereader v0.0.1 // indirect github.com/mattn/go-runewidth v0.0.16 // indirect github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect diff --git a/go.sum b/go.sum index 9cedc85..629f913 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,5 @@ +gabe565.com/utils v0.0.0-20241111053222-0f59399cbb3c h1:xKxZ9fGvYYihnqbyt1OE5Giz+rDQf5junHUxmvkFBfw= +gabe565.com/utils v0.0.0-20241111053222-0f59399cbb3c/go.mod h1:ekV9VNVFXI1E8niHsgfb76RQHP2oJH2zYaCw1cEWrhA= github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8= github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4= github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k= @@ -35,8 +37,8 @@ github.com/charmbracelet/x/termios v0.1.0/go.mod h1:H/EVv/KRnrYjz+fCYa9bsKdqF3S8 github.com/cpuguy83/go-md2man/v2 v2.0.4 h1:wfIWP927BUkWJb2NmU/kNDYIBTh/ziUX91+lVfRxZq4= github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/creack/pty v1.1.21 h1:1/QdRyBaHHJP61QkWMXlOIBfsgdDeeKfK8SYVUWJKf0= -github.com/creack/pty v1.1.21/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= +github.com/creack/pty v1.1.24 h1:bJrF4RRfyJnbTJqzRLHzcGaZK1NeM5kTC9jGgovnR1s= +github.com/creack/pty v1.1.24/go.mod h1:08sCNb52WyoAwi2QDyzUCTgcvVFhUzewun7wtTfvcwE= 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/dmarkham/enumer v1.5.10 h1:ygL0L6quiTiH1jpp68DyvsWaea6MaZLZrTTkIS++R0M= diff --git a/internal/config/log.go b/internal/config/log.go index bb60005..5450c54 100644 --- a/internal/config/log.go +++ b/internal/config/log.go @@ -1,16 +1,15 @@ package config import ( - "errors" "io" "log/slog" - "os" "strconv" "strings" "time" + "gabe565.com/utils/must" + "gabe565.com/utils/termx" "github.com/lmittmann/tint" - "github.com/mattn/go-isatty" "github.com/spf13/cobra" ) @@ -35,32 +34,26 @@ func RegisterLogFlags(cmd *cobra.Command) { cmd.PersistentFlags().StringP(LogLevelFlag, "l", strings.ToLower(slog.LevelInfo.String()), "log level (one of debug, info, warn, error)") cmd.PersistentFlags().String(LogFormatFlag, FormatAuto.String(), "log formatter (one of "+strings.Join(LogFormatStrings(), ", ")+")") - if err := errors.Join( - cmd.RegisterFlagCompletionFunc(LogLevelFlag, - func(_ *cobra.Command, _ []string, _ string) ([]string, cobra.ShellCompDirective) { - return []string{ - strings.ToLower(slog.LevelDebug.String()), - strings.ToLower(slog.LevelInfo.String()), - strings.ToLower(slog.LevelWarn.String()), - strings.ToLower(slog.LevelError.String()), - }, cobra.ShellCompDirectiveNoFileComp - }, - ), - cmd.RegisterFlagCompletionFunc(LogFormatFlag, - func(_ *cobra.Command, _ []string, _ string) ([]string, cobra.ShellCompDirective) { - return LogFormatStrings(), cobra.ShellCompDirectiveNoFileComp - }, - ), - ); err != nil { - panic(err) - } + must.Must(cmd.RegisterFlagCompletionFunc(LogLevelFlag, + func(_ *cobra.Command, _ []string, _ string) ([]string, cobra.ShellCompDirective) { + return []string{ + strings.ToLower(slog.LevelDebug.String()), + strings.ToLower(slog.LevelInfo.String()), + strings.ToLower(slog.LevelWarn.String()), + strings.ToLower(slog.LevelError.String()), + }, cobra.ShellCompDirectiveNoFileComp + }, + )) + + must.Must(cmd.RegisterFlagCompletionFunc(LogFormatFlag, + func(_ *cobra.Command, _ []string, _ string) ([]string, cobra.ShellCompDirective) { + return LogFormatStrings(), cobra.ShellCompDirectiveNoFileComp + }, + )) } func InitLogCmd(cmd *cobra.Command) { - levelStr, err := cmd.Flags().GetString("log-level") - if err != nil { - panic(err) - } + levelStr := must.Must2(cmd.Flags().GetString("log-level")) var level slog.Level if v, err := strconv.Atoi(levelStr); err == nil { level = slog.Level(v) @@ -71,10 +64,7 @@ func InitLogCmd(cmd *cobra.Command) { level = slog.LevelInfo } - formatStr, err := cmd.Flags().GetString("log-format") - if err != nil { - panic(err) - } + formatStr := must.Must2(cmd.Flags().GetString("log-format")) var format LogFormat if err := format.UnmarshalText([]byte(formatStr)); err != nil { defer func() { @@ -96,9 +86,7 @@ func InitLog(w io.Writer, level slog.Level, format LogFormat) { var color bool switch format { case FormatAuto: - if f, ok := w.(*os.File); ok { - color = isatty.IsTerminal(f.Fd()) || isatty.IsCygwinTerminal(f.Fd()) - } + color = termx.IsColor(w) case FormatColor: color = true } diff --git a/internal/generate/docs/main.go b/internal/generate/docs/main.go index bb10eca..ae12404 100644 --- a/internal/generate/docs/main.go +++ b/internal/generate/docs/main.go @@ -6,8 +6,8 @@ import ( "os" "gabe565.com/ascii-movie/cmd" - "gabe565.com/ascii-movie/cmd/util" "gabe565.com/ascii-movie/internal/config" + "gabe565.com/utils/cobrax" "github.com/spf13/cobra/doc" ) @@ -31,7 +31,7 @@ func run() error { return fmt.Errorf("failed to create output directory: %w", err) } - rootCmd := cmd.NewCommand(util.WithVersion("beta")) + rootCmd := cmd.NewCommand(cobrax.WithVersion("beta")) if err := doc.GenMarkdownTree(rootCmd, output); err != nil { return fmt.Errorf("failed to generate docs: %w", err) } diff --git a/internal/server/config.go b/internal/server/config.go index 4ab62e4..17d58c4 100644 --- a/internal/server/config.go +++ b/internal/server/config.go @@ -4,6 +4,7 @@ import ( "log/slog" "gabe565.com/ascii-movie/internal/movie" + "gabe565.com/utils/must" flag "github.com/spf13/pflag" ) @@ -19,26 +20,13 @@ type MovieServer struct { } func NewServer(flags *flag.FlagSet, prefix string) Server { - var config Server - var err error - - config.Log = slog.With("server", prefix) - - if config.Enabled, err = flags.GetBool(prefix + EnabledFlag); err != nil { - panic(err) - } - - if config.Address, err = flags.GetString(prefix + AddressFlag); err != nil { - panic(err) + return Server{ + Enabled: must.Must2(flags.GetBool(prefix + EnabledFlag)), + Address: must.Must2(flags.GetString(prefix + AddressFlag)), + Log: slog.With("server", prefix), } - - return config } func NewMovieServer(flags *flag.FlagSet, prefix string) MovieServer { - var config MovieServer - - config.Server = NewServer(flags, prefix) - - return config + return MovieServer{Server: NewServer(flags, prefix)} } diff --git a/internal/server/flags.go b/internal/server/flags.go index f793106..21d23e4 100644 --- a/internal/server/flags.go +++ b/internal/server/flags.go @@ -3,6 +3,7 @@ package server import ( "time" + "gabe565.com/utils/must" flag "github.com/spf13/pflag" ) @@ -46,9 +47,7 @@ func Flags(flags *flag.FlagSet) { flags.DurationVar(&maxTimeout, MaxTimeoutFlag, 2*time.Hour, "Absolute connection timeout.") flags.Duration(TimeoutFlag, time.Hour, "Maximum amount of time that a connection may stay active.") - if err := flags.MarkDeprecated(TimeoutFlag, "please use --idle-timeout and --max-timeout instead."); err != nil { - panic(err) - } + must.Must(flags.MarkDeprecated(TimeoutFlag, "please use --idle-timeout and --max-timeout instead.")) } func LoadDeprecated(flags *flag.FlagSet) { diff --git a/internal/server/ssh.go b/internal/server/ssh.go index e54ea84..34f80cf 100644 --- a/internal/server/ssh.go +++ b/internal/server/ssh.go @@ -11,6 +11,7 @@ import ( "gabe565.com/ascii-movie/internal/movie" "gabe565.com/ascii-movie/internal/player" "gabe565.com/ascii-movie/internal/util" + "gabe565.com/utils/must" tea "github.com/charmbracelet/bubbletea" "github.com/charmbracelet/ssh" "github.com/charmbracelet/wish" @@ -31,17 +32,11 @@ type SSHServer struct { } func NewSSH(flags *flag.FlagSet) SSHServer { - ssh := SSHServer{MovieServer: NewMovieServer(flags, SSHFlagPrefix)} - var err error - - if ssh.HostKeyPath, err = flags.GetStringSlice(SSHHostKeyPathFlag); err != nil { - panic(err) - } - - if ssh.HostKeyPEM, err = flags.GetStringSlice(SSHHostKeyDataFlag); err != nil { - panic(err) + ssh := SSHServer{ + MovieServer: NewMovieServer(flags, SSHFlagPrefix), + HostKeyPath: must.Must2(flags.GetStringSlice(SSHHostKeyPathFlag)), + HostKeyPEM: must.Must2(flags.GetStringSlice(SSHHostKeyDataFlag)), } - if len(ssh.HostKeyPath) == 0 && len(ssh.HostKeyPEM) == 0 { ssh.HostKeyPath = []string{"$HOME/.ssh/ascii_movie_ed25519", "$HOME/.ssh/ascii_movie_rsa"} } diff --git a/main.go b/main.go index dcd2fa1..6fe2feb 100644 --- a/main.go +++ b/main.go @@ -5,7 +5,7 @@ import ( "os" "gabe565.com/ascii-movie/cmd" - "gabe565.com/ascii-movie/cmd/util" + "gabe565.com/utils/cobrax" ) //go:generate go run ./internal/generate/gzip @@ -13,7 +13,7 @@ import ( var version = "beta" func main() { - root := cmd.NewCommand(util.WithVersion(version)) + root := cmd.NewCommand(cobrax.WithVersion(version)) if err := root.Execute(); err != nil { slog.Error(err.Error()) os.Exit(1)