diff --git a/plugins/ghupdate/ghupdate.go b/plugins/ghupdate/ghupdate.go index 274037ad..ca48028c 100644 --- a/plugins/ghupdate/ghupdate.go +++ b/plugins/ghupdate/ghupdate.go @@ -105,12 +105,9 @@ func (p *plugin) updateCmd() *cobra.Command { var withBackup bool command := &cobra.Command{ - Use: "update", - Short: "Automatically updates the current PocketBase executable with the latest available version", - // @todo remove after logs generalization - // prevents printing the error log twice - SilenceErrors: true, - SilenceUsage: true, + Use: "update", + Short: "Automatically updates the current PocketBase executable with the latest available version", + SilenceUsage: true, RunE: func(command *cobra.Command, args []string) error { var needConfirm bool if isMaybeRunningInDocker() { diff --git a/plugins/migratecmd/migratecmd.go b/plugins/migratecmd/migratecmd.go index c4bf1c6d..185a0a88 100644 --- a/plugins/migratecmd/migratecmd.go +++ b/plugins/migratecmd/migratecmd.go @@ -118,13 +118,11 @@ func (p *plugin) createCommand() *cobra.Command { ` command := &cobra.Command{ - Use: "migrate", - Short: "Executes app DB migration scripts", - Long: cmdDesc, - ValidArgs: []string{"up", "down", "create", "collections"}, - // prevents printing the error log twice - SilenceErrors: true, - SilenceUsage: true, + Use: "migrate", + Short: "Executes app DB migration scripts", + Long: cmdDesc, + ValidArgs: []string{"up", "down", "create", "collections"}, + SilenceUsage: true, RunE: func(command *cobra.Command, args []string) error { cmd := "" if len(args) > 0 { diff --git a/pocketbase.go b/pocketbase.go index 34d3236a..648d9f22 100644 --- a/pocketbase.go +++ b/pocketbase.go @@ -1,12 +1,14 @@ package pocketbase import ( + "io" "os" "os/signal" "path/filepath" "strings" "syscall" + "github.com/fatih/color" "github.com/pocketbase/pocketbase/cmd" "github.com/pocketbase/pocketbase/core" "github.com/pocketbase/pocketbase/tools/list" @@ -98,6 +100,9 @@ func NewWithConfig(config Config) *PocketBase { hideStartBanner: config.HideStartBanner, } + // replace with a colored stderr writer + pb.RootCmd.SetErr(newErrWriter()) + // parse base flags // (errors are ignored, since the full flags parsing happens on Execute()) pb.eagerParseFlags(&config) @@ -152,9 +157,8 @@ func (pb *PocketBase) Execute() error { // execute the root command go func() { - if err := pb.RootCmd.Execute(); err != nil { - pb.Logger().Error("rootCmd.Execute error", "error", err) - } + // leave to the commands to decide whether to print their error or not + pb.RootCmd.Execute() done <- true }() @@ -246,3 +250,25 @@ func inspectRuntime() (baseDir string, withGoRun bool) { } return } + +// newErrWriter returns a red colored stderr writter. +func newErrWriter() *coloredWriter { + return &coloredWriter{ + w: os.Stderr, + c: color.New(color.FgRed), + } +} + +// coloredWriter is a small wrapper struct to construct a [color.Color] writter. +type coloredWriter struct { + w io.Writer + c *color.Color +} + +// Write writes the p bytes using the colored writer. +func (colored *coloredWriter) Write(p []byte) (n int, err error) { + colored.c.SetWriter(colored.w) + defer colored.c.UnsetWriter(colored.w) + + return colored.c.Print(string(p)) +}