Skip to content

Commit

Permalink
outputs
Browse files Browse the repository at this point in the history
  • Loading branch information
AdheipSingh committed Nov 1, 2024
1 parent 14440bc commit a9b11d3
Show file tree
Hide file tree
Showing 3 changed files with 144 additions and 31 deletions.
33 changes: 32 additions & 1 deletion cmd/role.go
Original file line number Diff line number Diff line change
Expand Up @@ -191,14 +191,20 @@ var ListRoleCmd = &cobra.Command{
Use: "list",
Short: "List all roles",
Example: " pb role list",
RunE: func(_ *cobra.Command, _ []string) error {
RunE: func(cmd *cobra.Command, _ []string) error {
var roles []string
client := DefaultClient()
err := fetchRoles(&client, &roles)
if err != nil {
return err
}

// Get output flag value
outputFormat, err := cmd.Flags().GetString("output")
if err != nil {
return err
}

roleResponses := make([]struct {
data []RoleData
err error
Expand All @@ -217,6 +223,26 @@ var ListRoleCmd = &cobra.Command{
}

wsg.Wait()

// Output in JSON format if requested
if outputFormat == "json" {
// Collect the role data into a structured format
allRoles := map[string][]RoleData{}
for idx, roleName := range roles {
if roleResponses[idx].err == nil {
allRoles[roleName] = roleResponses[idx].data
}
}
// Marshal and print as JSON
jsonOutput, err := json.MarshalIndent(allRoles, "", " ")
if err != nil {
return fmt.Errorf("failed to marshal JSON output: %w", err)
}
fmt.Println(string(jsonOutput))
return nil
}

// Default output in text format
fmt.Println()
for idx, roleName := range roles {
fetchRes := roleResponses[idx]
Expand Down Expand Up @@ -295,3 +321,8 @@ func fetchSpecificRole(client *HTTPClient, role string) (res []RoleData, err err

return
}

func init() {
// Add the --output flag with default value "text"
ListRoleCmd.Flags().String("output", "text", "Output format: 'text' or 'json'")
}
77 changes: 53 additions & 24 deletions cmd/stream.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"errors"
"fmt"
"io"
"net/http"
"strconv"
"strings"
"time"
Expand All @@ -44,11 +45,11 @@ type StreamStatsData struct {
}

type StreamListItem struct {
name string
Name string
}

func (item *StreamListItem) Render() string {
render := StandardStyle.Render(item.name)
render := StandardStyle.Render(item.Name)
return ItemOuter.Render(render)
}

Expand Down Expand Up @@ -245,8 +246,8 @@ var RemoveStreamCmd = &cobra.Command{
var ListStreamCmd = &cobra.Command{
Use: "list",
Short: "List all streams",
Example: " pb stream list",
RunE: func(_ *cobra.Command, _ []string) error {
Example: " pb stream list",
RunE: func(cmd *cobra.Command, _ []string) error {
client := DefaultClient()
req, err := client.NewRequest("GET", "logstream", nil)
if err != nil {
Expand All @@ -257,40 +258,68 @@ var ListStreamCmd = &cobra.Command{
if err != nil {
return err
}
defer resp.Body.Close()

if resp.StatusCode == 200 {
items := []map[string]string{}
err = json.NewDecoder(resp.Body).Decode(&items)
if resp.StatusCode != http.StatusOK {
// Read response body for error message
bytes, err := io.ReadAll(resp.Body)
if err != nil {
return err
}
defer resp.Body.Close()
body := string(bytes)
fmt.Printf("Request Failed\nStatus Code: %s\nResponse: %s\n", resp.Status, body)
return nil
}

if len(items) >= 0 {
fmt.Println()
} else if len(items) == 0 {
fmt.Println("No streams found")
return nil
}
var items []map[string]string
err = json.NewDecoder(resp.Body).Decode(&items)
if err != nil {
return err
}

for _, item := range items {
item := StreamListItem{item["name"]}
fmt.Print("• ")
fmt.Println(item.Render())
// Get output flag value
outputFormat, err := cmd.Flags().GetString("output")
if err != nil {
return err
}

// Handle JSON output format
if outputFormat == "json" {
// Collect stream names for JSON output
streams := make([]string, len(items))
for i, item := range items {
streams[i] = item["name"]
}
jsonOutput, err := json.MarshalIndent(streams, "", " ")
if err != nil {
return fmt.Errorf("failed to marshal JSON output: %w", err)
}
fmt.Println()
fmt.Println(string(jsonOutput))
return nil
}
bytes, err := io.ReadAll(resp.Body)
if err != nil {
return err

// Default to text output
if len(items) == 0 {
fmt.Println("No streams found")
return nil
}
body := string(bytes)
fmt.Printf("Request Failed\nStatus Code: %s\nResponse: %s\n", resp.Status, body)

fmt.Println()
for _, item := range items {
streamItem := StreamListItem{Name: item["name"]}
fmt.Print("• ")
fmt.Println(streamItem.Render())
}
fmt.Println()
return nil
},
}

func init() {
// Add the --output flag with default value "text"
ListStreamCmd.Flags().StringP("output", "o", "text", "Output format: 'text' or 'json'")
}

func fetchStats(client *HTTPClient, name string) (data StreamStatsData, err error) {
req, err := client.NewRequest("GET", fmt.Sprintf("logstream/%s/stats", name), nil)
if err != nil {
Expand Down
65 changes: 59 additions & 6 deletions cmd/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -232,50 +232,103 @@ var ListUserCmd = &cobra.Command{
Use: "list",
Short: "List all users",
Example: " pb user list",
RunE: func(_ *cobra.Command, _ []string) error {
RunE: func(cmd *cobra.Command, _ []string) error {
client := DefaultClient()
users, err := fetchUsers(&client)
if err != nil {
return err
}

roleResponses := make([]struct {
data UserRoleData
data []string // Collects roles as strings for text output
err error
}, len(users))

wsg := sync.WaitGroup{}

for idx, user := range users {
wsg.Add(1)
out := &roleResponses[idx]
user := user.ID
userID := user.ID
client := &client
go func() {
out.data, out.err = fetchUserRoles(client, user)
var userRolesData UserRoleData
userRolesData, out.err = fetchUserRoles(client, userID)
if out.err == nil {
// Collect role names for this user
for role := range userRolesData {
out.data = append(out.data, role)
}
}
wsg.Done()
}()
}

wsg.Wait()

// Get the output format, defaulting to empty (existing behavior)
outputFormat, err := cmd.Flags().GetString("output")
if err != nil {
return err
}

// JSON output if specified
if outputFormat == "json" {
usersWithRoles := make([]map[string]interface{}, len(users))
for idx, user := range users {
usersWithRoles[idx] = map[string]interface{}{
"id": user.ID,
"roles": roleResponses[idx].data,
}
}
jsonOutput, err := json.MarshalIndent(usersWithRoles, "", " ")
if err != nil {
return fmt.Errorf("failed to marshal JSON output: %w", err)
}
fmt.Println(string(jsonOutput))
return nil
}

// Text output if specified
if outputFormat == "text" {
fmt.Println()
for idx, user := range users {
roles := roleResponses[idx]
if roles.err == nil {
roleList := strings.Join(roles.data, ", ")
fmt.Printf("%s, %s\n", user.ID, roleList)
} else {
fmt.Printf("%s, error: %v\n", user.ID, roles.err)
}
}
fmt.Println()
return nil
}

// Default output (existing layout)
fmt.Println()
for idx, user := range users {
roles := roleResponses[idx]
fmt.Print("• ")
fmt.Println(StandardStyleBold.Bold(true).Render(user.ID))
if roles.err == nil {
for role := range roles.data {
for _, role := range roles.data {
fmt.Println(lipgloss.NewStyle().PaddingLeft(3).Render(role))
}
} else {
fmt.Println(roles.err)
}
}
fmt.Println()

return nil
},
}

func init() {
// Add the --output flag with shorthand -o, defaulting to empty for default layout
ListUserCmd.Flags().StringP("output", "o", "", "Output format: 'text' or 'json'")
}

func fetchUsers(client *HTTPClient) (res []UserData, err error) {
req, err := client.NewRequest("GET", "user", nil)
if err != nil {
Expand Down

0 comments on commit a9b11d3

Please sign in to comment.