From 1a376722fd5f33bef181d59256b47b868fa2c1af Mon Sep 17 00:00:00 2001 From: jsandai <130126800+jsandai@users.noreply.github.com> Date: Thu, 29 Jan 2026 07:22:29 -0600 Subject: [PATCH 1/4] feat: add --quiet and --verbose flags to serve command - Add -q/--quiet flag to suppress output (FATAL level only) - Add -v/--verbose flag for debug output - Document verbosity options in SELF-HOSTED.md - Helps reduce noise when running self-hosted networks --- cmd/serve/serve.go | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/cmd/serve/serve.go b/cmd/serve/serve.go index 9321901..58b9c43 100644 --- a/cmd/serve/serve.go +++ b/cmd/serve/serve.go @@ -1,6 +1,8 @@ package serve import ( + "os" + "github.com/kardianos/service" "github.com/spf13/cobra" @@ -9,7 +11,11 @@ import ( "github.com/anyproto/anytype-cli/core/serviceprogram" ) -var listenAddress string +var ( + listenAddress string + quietMode bool + verboseMode bool +) func NewServeCmd() *cobra.Command { cmd := &cobra.Command{ @@ -21,11 +27,25 @@ func NewServeCmd() *cobra.Command { } cmd.Flags().StringVar(&listenAddress, "listen-address", config.DefaultAPIAddress, "API listen address in `host:port` format") + cmd.Flags().BoolVarP(&quietMode, "quiet", "q", false, "Suppress most output (only errors)") + cmd.Flags().BoolVarP(&verboseMode, "verbose", "v", false, "Show detailed output (debug level)") return cmd } func runServer(cmd *cobra.Command, args []string) error { + // Configure log level based on flags (before server starts) + if quietMode && verboseMode { + return output.Error("cannot use --quiet and --verbose together") + } + if quietMode { + os.Setenv("ANYTYPE_LOG_LEVEL", "*=FATAL") + os.Setenv("ANYTYPE_LOG_NOGELF", "1") + } else if verboseMode { + os.Setenv("ANYTYPE_LOG_LEVEL", "*=DEBUG") + } + // Default (ERROR) is set in grpcserver/server.go if not specified + svcConfig := &service.Config{ Name: "anytype", DisplayName: "Anytype", From 9e1aab08bd8933fc662aa61e075d2507a3a18535 Mon Sep 17 00:00:00 2001 From: Jannis Metrikat <120120832+jmetrikat@users.noreply.github.com> Date: Tue, 3 Feb 2026 00:15:00 +0100 Subject: [PATCH 2/4] Add tests for verbose and quiet flags --- cmd/serve/serve_test.go | 49 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/cmd/serve/serve_test.go b/cmd/serve/serve_test.go index a08123f..79934f6 100644 --- a/cmd/serve/serve_test.go +++ b/cmd/serve/serve_test.go @@ -51,3 +51,52 @@ func TestServeCmd_ListenAddressFlagCustomValue(t *testing.T) { t.Errorf("listen-address value = %v, want %v", flag.Value.String(), customAddr) } } + +func TestServeCmd_QuietFlag(t *testing.T) { + cmd := NewServeCmd() + + flag := cmd.Flag("quiet") + if flag == nil { + t.Fatal("quiet flag not found") + } + + if flag.Shorthand != "q" { + t.Errorf("quiet shorthand = %v, want q", flag.Shorthand) + } + + if flag.DefValue != "false" { + t.Errorf("quiet default = %v, want false", flag.DefValue) + } +} + +func TestServeCmd_VerboseFlag(t *testing.T) { + cmd := NewServeCmd() + + flag := cmd.Flag("verbose") + if flag == nil { + t.Fatal("verbose flag not found") + } + + if flag.Shorthand != "v" { + t.Errorf("verbose shorthand = %v, want v", flag.Shorthand) + } + + if flag.DefValue != "false" { + t.Errorf("verbose default = %v, want false", flag.DefValue) + } +} + +func TestServeCmd_QuietAndVerboseMutuallyExclusive(t *testing.T) { + cmd := NewServeCmd() + cmd.SetArgs([]string{"--quiet", "--verbose"}) + + err := cmd.Execute() + if err == nil { + t.Error("expected error when using --quiet and --verbose together, got nil") + } + + expectedMsg := "cannot use --quiet and --verbose together" + if err.Error() != expectedMsg { + t.Errorf("error message = %v, want %v", err.Error(), expectedMsg) + } +} From 654c3faef40ce727af7ac380f266508280d1f0a6 Mon Sep 17 00:00:00 2001 From: Jannis Metrikat <120120832+jmetrikat@users.noreply.github.com> Date: Tue, 3 Feb 2026 00:20:25 +0100 Subject: [PATCH 3/4] Refactor error handling for mutually exclusive flags --- cmd/serve/serve.go | 8 +++----- cmd/serve/serve_test.go | 6 +++--- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/cmd/serve/serve.go b/cmd/serve/serve.go index 58b9c43..79767f8 100644 --- a/cmd/serve/serve.go +++ b/cmd/serve/serve.go @@ -29,22 +29,20 @@ func NewServeCmd() *cobra.Command { cmd.Flags().StringVar(&listenAddress, "listen-address", config.DefaultAPIAddress, "API listen address in `host:port` format") cmd.Flags().BoolVarP(&quietMode, "quiet", "q", false, "Suppress most output (only errors)") cmd.Flags().BoolVarP(&verboseMode, "verbose", "v", false, "Show detailed output (debug level)") + cmd.MarkFlagsMutuallyExclusive("quiet", "verbose") return cmd } func runServer(cmd *cobra.Command, args []string) error { - // Configure log level based on flags (before server starts) - if quietMode && verboseMode { - return output.Error("cannot use --quiet and --verbose together") - } + // Configure anytype-heart log level via environment variables (must be set before server starts) if quietMode { os.Setenv("ANYTYPE_LOG_LEVEL", "*=FATAL") os.Setenv("ANYTYPE_LOG_NOGELF", "1") } else if verboseMode { os.Setenv("ANYTYPE_LOG_LEVEL", "*=DEBUG") } - // Default (ERROR) is set in grpcserver/server.go if not specified + // Default log level (ERROR) is set in grpcserver/server.go if not specified svcConfig := &service.Config{ Name: "anytype", diff --git a/cmd/serve/serve_test.go b/cmd/serve/serve_test.go index 79934f6..54ae85f 100644 --- a/cmd/serve/serve_test.go +++ b/cmd/serve/serve_test.go @@ -92,11 +92,11 @@ func TestServeCmd_QuietAndVerboseMutuallyExclusive(t *testing.T) { err := cmd.Execute() if err == nil { - t.Error("expected error when using --quiet and --verbose together, got nil") + t.Fatal("expected error when using --quiet and --verbose together, got nil") } - expectedMsg := "cannot use --quiet and --verbose together" + expectedMsg := "if any flags in the group [quiet verbose] are set none of the others can be; [quiet verbose] were all set" if err.Error() != expectedMsg { - t.Errorf("error message = %v, want %v", err.Error(), expectedMsg) + t.Errorf("error message = %q, want %q", err.Error(), expectedMsg) } } From 172b0835f82af649e990fb4aa8766ed6dee400fc Mon Sep 17 00:00:00 2001 From: Jannis Metrikat <120120832+jmetrikat@users.noreply.github.com> Date: Tue, 3 Feb 2026 00:23:00 +0100 Subject: [PATCH 4/4] Refactor error handling for mutually exclusive flags --- cmd/serve/serve_test.go | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/cmd/serve/serve_test.go b/cmd/serve/serve_test.go index 54ae85f..b9eb457 100644 --- a/cmd/serve/serve_test.go +++ b/cmd/serve/serve_test.go @@ -1,6 +1,7 @@ package serve import ( + "strings" "testing" "github.com/anyproto/anytype-cli/core/config" @@ -92,11 +93,14 @@ func TestServeCmd_QuietAndVerboseMutuallyExclusive(t *testing.T) { err := cmd.Execute() if err == nil { - t.Fatal("expected error when using --quiet and --verbose together, got nil") + t.Fatal("expected error when using --quiet and --verbose together") } - expectedMsg := "if any flags in the group [quiet verbose] are set none of the others can be; [quiet verbose] were all set" - if err.Error() != expectedMsg { - t.Errorf("error message = %q, want %q", err.Error(), expectedMsg) + errMsg := err.Error() + if !strings.Contains(errMsg, "quiet") { + t.Errorf("error message should mention 'quiet' flag, got: %q", errMsg) + } + if !strings.Contains(errMsg, "verbose") { + t.Errorf("error message should mention 'verbose' flag, got: %q", errMsg) } }