diff --git a/pkg/cmd/ls/ls.go b/pkg/cmd/ls/ls.go index 0491215a..94060732 100644 --- a/pkg/cmd/ls/ls.go +++ b/pkg/cmd/ls/ls.go @@ -24,7 +24,6 @@ import ( "github.com/brevdev/brev-cli/pkg/cmdcontext" "github.com/brevdev/brev-cli/pkg/config" "github.com/brevdev/brev-cli/pkg/entity" - "github.com/brevdev/brev-cli/pkg/entity/virtualproject" breverrors "github.com/brevdev/brev-cli/pkg/errors" "github.com/brevdev/brev-cli/pkg/featureflag" "github.com/brevdev/brev-cli/pkg/store" @@ -383,27 +382,14 @@ func (ls Ls) RunUser(_ bool) error { return nil } -func (ls Ls) ShowAllWorkspaces(org *entity.Organization, otherOrgs []entity.Organization, user *entity.User, allWorkspaces []entity.Workspace, gpuLookup map[string]string) { - userWorkspaces := store.FilterForUserWorkspaces(allWorkspaces, user.ID) - ls.displayWorkspacesAndHelp(org, otherOrgs, userWorkspaces, allWorkspaces, gpuLookup) - - projects := virtualproject.NewVirtualProjects(allWorkspaces) - - var unjoinedProjects []virtualproject.VirtualProject - for _, p := range projects { - wks := p.GetUserWorkspaces(user.ID) - if len(wks) == 0 { - unjoinedProjects = append(unjoinedProjects, p) - } - } - - displayProjects(ls.terminal, org.Name, unjoinedProjects) +func (ls Ls) ShowAllWorkspaces(org *entity.Organization, otherOrgs []entity.Organization, workspacesToShow []entity.Workspace, gpuLookup map[string]string) { + ls.displayWorkspacesAndHelp(org, otherOrgs, workspacesToShow, workspacesToShow, true, gpuLookup) } func (ls Ls) ShowUserWorkspaces(org *entity.Organization, otherOrgs []entity.Organization, user *entity.User, allWorkspaces []entity.Workspace, gpuLookup map[string]string) { userWorkspaces := store.FilterForUserWorkspaces(allWorkspaces, user.ID) - ls.displayWorkspacesAndHelp(org, otherOrgs, userWorkspaces, allWorkspaces, gpuLookup) + ls.displayWorkspacesAndHelp(org, otherOrgs, userWorkspaces, allWorkspaces, false, gpuLookup) } func (ls Ls) ShowOrgWorkspaces(org *entity.Organization, workspaces []entity.Workspace, gpuLookup map[string]string) { @@ -419,10 +405,10 @@ func (ls Ls) ShowOrgWorkspaces(org *entity.Organization, workspaces []entity.Wor displayLsResetBreadCrumb(ls.terminal, workspaces) } -func (ls Ls) displayWorkspacesAndHelp(org *entity.Organization, otherOrgs []entity.Organization, userWorkspaces []entity.Workspace, allWorkspaces []entity.Workspace, gpuLookup map[string]string) { - if len(userWorkspaces) == 0 { +func (ls Ls) displayWorkspacesAndHelp(org *entity.Organization, otherOrgs []entity.Organization, workspacesToDisplay []entity.Workspace, allWorkspaces []entity.Workspace, showAll bool, gpuLookup map[string]string) { + if len(workspacesToDisplay) == 0 { ls.terminal.Vprint(ls.terminal.Yellow("No instances in org %s\n", org.Name)) - if len(allWorkspaces) > 0 { + if !showAll && len(allWorkspaces) > 0 { ls.terminal.Vprintf("%s", ls.terminal.Green("See teammates' instances:\n")) ls.terminal.Vprintf("%s", ls.terminal.Yellow("\tbrev ls --all\n")) } else { @@ -434,13 +420,17 @@ func (ls Ls) displayWorkspacesAndHelp(org *entity.Organization, otherOrgs []enti ls.terminal.Vprintf("%s", ls.terminal.Yellow(fmt.Sprintf("\tbrev set %s\n", getOtherOrg(otherOrgs, *org).Name))) } } else { - ls.terminal.Vprintf("You have %d instances in Org %s\n", len(userWorkspaces), ls.terminal.Yellow(org.Name)) - displayWorkspacesTable(ls.terminal, userWorkspaces, gpuLookup) + if showAll { + ls.terminal.Vprintf("%d instances in Org %s\n", len(workspacesToDisplay), ls.terminal.Yellow(org.Name)) + } else { + ls.terminal.Vprintf("You have %d instances in Org %s\n", len(workspacesToDisplay), ls.terminal.Yellow(org.Name)) + } + displayWorkspacesTable(ls.terminal, workspacesToDisplay, gpuLookup) fmt.Print("\n") - displayLsResetBreadCrumb(ls.terminal, userWorkspaces) - // displayLsConnectBreadCrumb(ls.terminal, userWorkspaces) + displayLsResetBreadCrumb(ls.terminal, workspacesToDisplay) + // displayLsConnectBreadCrumb(ls.terminal, workspacesToDisplay) } } @@ -548,7 +538,7 @@ func (ls Ls) RunWorkspaces(cliAuth auth.CLIAuth, org *entity.Organization, showA return breverrors.WrapAndTrace(err) } if showAll { - ls.ShowAllWorkspaces(org, orgs, user, allWorkspaces, gpuLookup) + ls.ShowAllWorkspaces(org, orgs, workspacesToShow, gpuLookup) if len(nodes) > 0 { ls.terminal.Vprintf("\nYou have %d external node(s) in Org %s\n", len(nodes), ls.terminal.Yellow(org.Name)) displayNodesTable(ls.terminal, nodes, ls.piped) @@ -680,23 +670,6 @@ func (ls Ls) RunHosts(org *entity.Organization) error { return nil } -func displayProjects(t *terminal.Terminal, orgName string, projects []virtualproject.VirtualProject) { - if len(projects) > 0 { - fmt.Print("\n") - t.Vprintf("%d other projects in Org %s\n", len(projects), t.Yellow(orgName)) - displayProjectsTable(projects) - - fmt.Print("\n") - t.Vprintf("%s", t.Green("Join a project:\n")+ - t.Yellow(fmt.Sprintf("\tbrev start %s\n", projects[0].Name))) - } else { - t.Vprintf("no other projects in Org %s\n", t.Yellow(orgName)) - fmt.Print("\n") - t.Vprintf("%s", t.Green("Invite a teamate:\n")+ - t.Yellow("\tbrev invite")) - } -} - func getBrevTableOptions() table.Options { options := table.OptionsDefault options.DrawBorder = false @@ -793,19 +766,6 @@ func displayOrgTable(t *terminal.Terminal, orgs []entity.Organization, currentOr ta.Render() } -func displayProjectsTable(projects []virtualproject.VirtualProject) { - ta := table.NewWriter() - ta.SetOutputMirror(os.Stdout) - ta.Style().Options = getBrevTableOptions() - header := table.Row{"NAME", "MEMBERS"} - ta.AppendHeader(header) - for _, p := range projects { - workspaceRow := []table.Row{{p.Name, p.GetUniqueUserCount()}} - ta.AppendRows(workspaceRow) - } - ta.Render() -} - func getStatusColoredText(t *terminal.Terminal, status string) string { switch status { case entity.Running, entity.Ready, string(entity.Completed): diff --git a/pkg/cmd/ls/ls_test.go b/pkg/cmd/ls/ls_test.go index 0e176f8c..d94dd33a 100644 --- a/pkg/cmd/ls/ls_test.go +++ b/pkg/cmd/ls/ls_test.go @@ -401,6 +401,41 @@ func TestRunLs_OrgsJSON(t *testing.T) { } } +// TestRunLs_ShowAllTable verifies that --all lists every org instance in table output. +func TestRunLs_ShowAllTable(t *testing.T) { + s := newTestStore() + s.workspaces = []entity.Workspace{ + { + ID: "ws-mine", + Name: "my-ws", + Status: entity.Running, + VerbBuildStatus: entity.Completed, + CreatedByUserID: "u1", + }, + { + ID: "ws-other", + Name: "other-ws", + Status: entity.Running, + VerbBuildStatus: entity.Completed, + CreatedByUserID: "u2", + }, + } + term := terminal.New() + + out := captureStdout(t, func() { + err := RunLs(term, resolveTestCLIAuth(t, s), s, nil, "", true, false) + if err != nil { + t.Fatalf("RunLs --all returned error: %v", err) + } + }) + if !strings.Contains(out, "my-ws") || !strings.Contains(out, "other-ws") { + t.Fatalf("expected both workspaces in table output, got:\n%s", out) + } + if strings.Contains(out, "brev ls --all") { + t.Fatal("should not suggest brev ls --all when already using --all") + } +} + // TestRunLs_ShowAll verifies that --all includes workspaces from other users. func TestRunLs_ShowAllJSON(t *testing.T) { s := newTestStore()