diff --git a/cmd/gcp_search.go b/cmd/gcp_search.go index 3c6e74d..ef4dfc7 100644 --- a/cmd/gcp_search.go +++ b/cmd/gcp_search.go @@ -10,6 +10,7 @@ import ( "github.com/kedare/compass/internal/gcp" "github.com/kedare/compass/internal/gcp/search" "github.com/kedare/compass/internal/logger" + "github.com/kedare/compass/internal/output" "github.com/pterm/pterm" "github.com/spf13/cobra" ) @@ -294,7 +295,6 @@ When both --type and --no-type are used, --no-type is applied to the --type filt } displaySearchResults(searchOutput.Results) - displaySearchWarnings(searchOutput.Warnings) return nil }, @@ -364,34 +364,8 @@ func resolveSearchProjects(searchTerm string, resourceTypes []string) ([]string, return trimmed, nil } -// displaySearchWarnings shows any warnings from providers that failed during search. -func displaySearchWarnings(warnings []search.SearchWarning) { - if len(warnings) == 0 { - return - } - - // Group warnings by provider to avoid repeating the same API error for every project - providerErrors := make(map[search.ResourceKind]int) - for _, w := range warnings { - providerErrors[w.Provider]++ - } - - pterm.Println() - pterm.Warning.Printf("Some providers encountered errors (%d total):\n", len(warnings)) - for provider, count := range providerErrors { - // Find a sample error for this provider - var sampleErr error - for _, w := range warnings { - if w.Provider == provider { - sampleErr = w.Err - break - } - } - pterm.Warning.Printf(" - %s: %d project(s) failed - %v\n", provider, count, sampleErr) - } -} - -// displaySearchResults renders the search matches to stdout using pterm tables. +// displaySearchResults renders the search matches to stdout. +// It uses a full table when the terminal is wide enough, otherwise falls back to a compact card layout. func displaySearchResults(results []search.Result) { if len(results) == 0 { pterm.Info.Println("No resources matched your query.") @@ -412,10 +386,28 @@ func displaySearchResults(results []search.Result) { }) } - if err := pterm.DefaultTable.WithBoxed(true).WithHasHeader().WithData(rows).Render(); err != nil { - logger.Log.Warnf("Failed to render search results table: %v", err) - for _, row := range rows[1:] { - pterm.Println(strings.Join(row, "\t")) + // Try rendering as a table first, then check if it fits + rendered, err := pterm.DefaultTable.WithBoxed(true).WithHasHeader().WithData(rows).Srender() + if err == nil && output.FitsTerminalWidth(rendered) { + pterm.Println(rendered) + return + } + + // Fall back to compact card layout for narrow terminals + displaySearchResultsCompact(results) +} + +// displaySearchResultsCompact renders search results in a compact card layout suitable for narrow terminals. +func displaySearchResultsCompact(results []search.Result) { + for i, result := range results { + if i > 0 { + pterm.Println() + } + pterm.Printf("[%s] %s\n", pterm.Bold.Sprint(string(result.Type)), pterm.Bold.Sprint(result.Name)) + pterm.Printf(" %-10s %s\n", "Project:", result.Project) + pterm.Printf(" %-10s %s\n", "Location:", result.Location) + if details := formatResultDetails(result.Details); details != "" { + pterm.Printf(" %-10s %s\n", "Details:", details) } } } diff --git a/internal/output/connectivity.go b/internal/output/connectivity.go index 1d36370..df57521 100644 --- a/internal/output/connectivity.go +++ b/internal/output/connectivity.go @@ -15,8 +15,8 @@ import ( "golang.org/x/term" ) -// detectTerminalWidth returns the width of the current terminal when available. -func detectTerminalWidth() (int, bool) { +// DetectTerminalWidth returns the width of the current terminal when available. +func DetectTerminalWidth() (int, bool) { if raw, ok := os.LookupEnv("COLUMNS"); ok { if width, err := strconv.Atoi(raw); err == nil && width > 0 { return width, true @@ -406,7 +406,7 @@ func displayForwardAndReturnPaths(forwardTraces []*gcp.Trace, returnTraces []*gc return false } - if fitsTerminalWidth(combined) { + if FitsTerminalWidth(combined) { fmt.Print(combined) return true @@ -554,9 +554,9 @@ func traceStepCells(trace *gcp.Trace, index int) [5]string { return [5]string{stepNum, getStepIcon(index, len(trace.Steps), step.CausesDrop), stepType, resource, status} } -// fitsTerminalWidth reports whether the rendered block fits within the current terminal width. -func fitsTerminalWidth(block string) bool { - width, ok := detectTerminalWidth() +// FitsTerminalWidth reports whether the rendered block fits within the current terminal width. +func FitsTerminalWidth(block string) bool { + width, ok := DetectTerminalWidth() return fitsTerminalWidthWithLimit(block, width, ok) } diff --git a/internal/output/connectivity_test.go b/internal/output/connectivity_test.go index 2ba9b3d..2591810 100644 --- a/internal/output/connectivity_test.go +++ b/internal/output/connectivity_test.go @@ -91,7 +91,7 @@ func TestDisplayForwardAndReturnPaths_RespectsTerminalWidth(t *testing.T) { wide := required + 10 t.Setenv("COLUMNS", strconv.Itoa(wide)) - width, ok := detectTerminalWidth() + width, ok := DetectTerminalWidth() require.True(t, ok) require.Equal(t, wide, width)