• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

astronomer / astro-cli / d8c087d9-3e34-4a26-9912-4e9425408752

04 Feb 2026 08:31PM UTC coverage: 32.799% (+0.005%) from 32.794%
d8c087d9-3e34-4a26-9912-4e9425408752

push

circleci

jeremybeard
Fix linting

18 of 95 new or added lines in 9 files covered. (18.95%)

5 existing lines in 1 file now uncovered.

21211 of 64670 relevant lines covered (32.8%)

8.33 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/cmd/api/list.go
1
package api
2

3
import (
4
        "fmt"
5
        "io"
6
        "strings"
7
        "text/tabwriter"
8

9
        "github.com/astronomer/astro-cli/pkg/openapi"
10
        "github.com/fatih/color"
11
        "github.com/spf13/cobra"
12
)
13

14
// ListOptions holds options for the list command.
15
type ListOptions struct {
16
        Out       io.Writer
17
        specCache *openapi.Cache
18
        Filter    string
19
        Verbose   bool
20
        Refresh   bool
21
}
22

23
// NewListCmd creates the 'astro api cloud ls' command.
24
func NewListCmd(out io.Writer, specCache *openapi.Cache) *cobra.Command {
×
25
        opts := &ListOptions{
×
26
                Out:       out,
×
27
                specCache: specCache,
×
28
        }
×
29

×
30
        cmd := &cobra.Command{
×
31
                Use:     "ls [filter]",
×
32
                Aliases: []string{"list"},
×
33
                Short:   "List available Astro Cloud API endpoints",
×
34
                Long: `List all available endpoints from the Astro Cloud API.
×
35

×
36
You can optionally provide a filter to search for specific endpoints.
×
37
The filter matches against endpoint paths, methods, operation IDs, summaries, and tags.`,
×
38
                Example: `  # List all endpoints
×
39
  astro api cloud ls
×
40

×
41
  # List endpoints related to deployments
×
42
  astro api cloud ls deployments
×
43

×
44
  # List endpoints related to organizations
×
45
  astro api cloud ls organization
×
46

×
47
  # List POST endpoints
×
48
  astro api cloud ls POST
×
49

×
50
  # Show verbose output with descriptions
×
51
  astro api cloud ls --verbose`,
×
52
                Args: cobra.MaximumNArgs(1),
×
53
                RunE: func(cmd *cobra.Command, args []string) error {
×
54
                        if len(args) > 0 {
×
55
                                opts.Filter = args[0]
×
56
                        }
×
57
                        return runList(opts)
×
58
                },
59
        }
60

61
        cmd.Flags().BoolVarP(&opts.Verbose, "verbose", "v", false, "Show additional details like summaries and tags")
×
62
        cmd.Flags().BoolVar(&opts.Refresh, "refresh", false, "Force refresh of the OpenAPI specification cache")
×
63

×
64
        return cmd
×
65
}
66

67
// runList executes the list command.
68
func runList(opts *ListOptions) error {
×
69
        // Load OpenAPI spec
×
70
        if err := opts.specCache.Load(opts.Refresh); err != nil {
×
71
                return fmt.Errorf("loading OpenAPI spec: %w", err)
×
72
        }
×
73

74
        endpoints := opts.specCache.GetEndpoints()
×
75
        if len(endpoints) == 0 {
×
76
                return fmt.Errorf("no endpoints found in API specification")
×
77
        }
×
78

79
        // Filter endpoints if a filter was provided
80
        if opts.Filter != "" {
×
81
                endpoints = openapi.FilterEndpoints(endpoints, opts.Filter)
×
82
                if len(endpoints) == 0 {
×
83
                        fmt.Fprintf(opts.Out, "No endpoints found matching '%s'\n", opts.Filter)
×
84
                        return nil
×
85
                }
×
86
        }
87

88
        // Print endpoints
89
        if opts.Verbose {
×
90
                printEndpointsVerbose(opts.Out, endpoints)
×
91
        } else {
×
92
                printEndpointsTable(opts.Out, endpoints)
×
93
        }
×
94

95
        fmt.Fprintf(opts.Out, "\nFound %d endpoint(s)\n", len(endpoints))
×
96
        return nil
×
97
}
98

99
// printEndpointsTable prints endpoints in a simple table format.
100
func printEndpointsTable(out io.Writer, endpoints []openapi.Endpoint) {
×
101
        // Use tabwriter for proper column alignment
×
102
        // The tabwriter doesn't handle ANSI codes well, so we print method without colors
×
103
        // and use a fixed-width format for the method column
×
104
        w := tabwriter.NewWriter(out, 0, 0, 2, ' ', 0)
×
105

×
106
        // Print header
×
107
        fmt.Fprintf(w, "%-8s\t%s\t%s\n", "METHOD", "PATH", "OPERATION ID")
×
108

×
NEW
109
        for i := range endpoints {
×
110
                deprecated := ""
×
NEW
111
                if endpoints[i].Deprecated {
×
112
                        deprecated = " " + color.YellowString("(deprecated)")
×
113
                }
×
114

115
                // Print with fixed-width method column to avoid ANSI code issues
NEW
116
                fmt.Fprintf(w, "%-8s\t%s\t%s%s\n", colorizeMethod(endpoints[i].Method), endpoints[i].Path, endpoints[i].OperationID, deprecated)
×
117
        }
118

119
        w.Flush()
×
120
}
121

122
// printEndpointsVerbose prints endpoints with full details.
123
func printEndpointsVerbose(out io.Writer, endpoints []openapi.Endpoint) {
×
NEW
124
        for i := range endpoints {
×
125
                if i > 0 {
×
126
                        fmt.Fprintln(out, "---")
×
127
                }
×
128

NEW
129
                method := colorizeMethod(endpoints[i].Method)
×
NEW
130
                fmt.Fprintf(out, "%s %s\n", method, endpoints[i].Path)
×
131

×
NEW
132
                if endpoints[i].OperationID != "" {
×
NEW
133
                        fmt.Fprintf(out, "  Operation ID: %s\n", endpoints[i].OperationID)
×
134
                }
×
NEW
135
                if endpoints[i].Summary != "" {
×
NEW
136
                        fmt.Fprintf(out, "  Summary: %s\n", endpoints[i].Summary)
×
137
                }
×
NEW
138
                if len(endpoints[i].Tags) > 0 {
×
NEW
139
                        fmt.Fprintf(out, "  Tags: %s\n", strings.Join(endpoints[i].Tags, ", "))
×
140
                }
×
NEW
141
                if endpoints[i].Deprecated {
×
142
                        fmt.Fprintf(out, "  %s\n", color.YellowString("DEPRECATED"))
×
143
                }
×
144

145
                // Show path parameters
NEW
146
                pathParams := openapi.GetPathParameters(endpoints[i].Path)
×
147
                if len(pathParams) > 0 {
×
148
                        fmt.Fprintf(out, "  Path Parameters: %s\n", strings.Join(pathParams, ", "))
×
149
                }
×
150
        }
151
}
152

153
// colorizeMethod returns the method with appropriate coloring.
154
func colorizeMethod(method string) string {
×
155
        switch method {
×
156
        case "GET":
×
157
                return color.GreenString(method)
×
158
        case "POST":
×
159
                return color.BlueString(method)
×
160
        case "PUT":
×
161
                return color.YellowString(method)
×
162
        case "PATCH":
×
163
                return color.CyanString(method)
×
164
        case "DELETE":
×
165
                return color.RedString(method)
×
166
        default:
×
167
                return method
×
168
        }
169
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc