mirror of
https://github.com/coder/coder.git
synced 2026-06-04 13:38:21 +00:00
6f82ad09c8
This makes the english consistent on flags, and improves the contrast for the placeholder color on dark themes.
125 lines
3.8 KiB
Go
125 lines
3.8 KiB
Go
package cli
|
|
|
|
import (
|
|
"fmt"
|
|
"time"
|
|
|
|
"github.com/google/uuid"
|
|
"github.com/spf13/cobra"
|
|
|
|
"github.com/coder/coder/cli/cliui"
|
|
"github.com/coder/coder/coderd/autobuild/schedule"
|
|
"github.com/coder/coder/coderd/util/ptr"
|
|
"github.com/coder/coder/codersdk"
|
|
)
|
|
|
|
type workspaceListRow struct {
|
|
Workspace string `table:"workspace"`
|
|
Template string `table:"template"`
|
|
Status string `table:"status"`
|
|
LastBuilt string `table:"last built"`
|
|
Outdated bool `table:"outdated"`
|
|
StartsAt string `table:"starts at"`
|
|
StopsAfter string `table:"stops after"`
|
|
}
|
|
|
|
func workspaceListRowFromWorkspace(now time.Time, usersByID map[uuid.UUID]codersdk.User, workspace codersdk.Workspace) workspaceListRow {
|
|
status := codersdk.WorkspaceDisplayStatus(workspace.LatestBuild.Job.Status, workspace.LatestBuild.Transition)
|
|
|
|
lastBuilt := now.UTC().Sub(workspace.LatestBuild.Job.CreatedAt).Truncate(time.Second)
|
|
autostartDisplay := "-"
|
|
if !ptr.NilOrEmpty(workspace.AutostartSchedule) {
|
|
if sched, err := schedule.Weekly(*workspace.AutostartSchedule); err == nil {
|
|
autostartDisplay = fmt.Sprintf("%s %s (%s)", sched.Time(), sched.DaysOfWeek(), sched.Location())
|
|
}
|
|
}
|
|
|
|
autostopDisplay := "-"
|
|
if !ptr.NilOrZero(workspace.TTLMillis) {
|
|
dur := time.Duration(*workspace.TTLMillis) * time.Millisecond
|
|
autostopDisplay = durationDisplay(dur)
|
|
if !workspace.LatestBuild.Deadline.IsZero() && workspace.LatestBuild.Deadline.Time.After(now) && status == "Running" {
|
|
remaining := time.Until(workspace.LatestBuild.Deadline.Time)
|
|
autostopDisplay = fmt.Sprintf("%s (%s)", autostopDisplay, relative(remaining))
|
|
}
|
|
}
|
|
|
|
user := usersByID[workspace.OwnerID]
|
|
return workspaceListRow{
|
|
Workspace: user.Username + "/" + workspace.Name,
|
|
Template: workspace.TemplateName,
|
|
Status: status,
|
|
LastBuilt: durationDisplay(lastBuilt),
|
|
Outdated: workspace.Outdated,
|
|
StartsAt: autostartDisplay,
|
|
StopsAfter: autostopDisplay,
|
|
}
|
|
}
|
|
|
|
func list() *cobra.Command {
|
|
var (
|
|
all bool
|
|
columns []string
|
|
defaultQuery = "owner:me"
|
|
searchQuery string
|
|
)
|
|
cmd := &cobra.Command{
|
|
Annotations: workspaceCommand,
|
|
Use: "list",
|
|
Short: "List workspaces",
|
|
Aliases: []string{"ls"},
|
|
Args: cobra.ExactArgs(0),
|
|
RunE: func(cmd *cobra.Command, args []string) error {
|
|
client, err := CreateClient(cmd)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
filter := codersdk.WorkspaceFilter{
|
|
FilterQuery: searchQuery,
|
|
}
|
|
if all && searchQuery == defaultQuery {
|
|
filter.FilterQuery = ""
|
|
}
|
|
workspaces, err := client.Workspaces(cmd.Context(), filter)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if len(workspaces) == 0 {
|
|
_, _ = fmt.Fprintln(cmd.ErrOrStderr(), cliui.Styles.Prompt.String()+"No workspaces found! Create one:")
|
|
_, _ = fmt.Fprintln(cmd.ErrOrStderr())
|
|
_, _ = fmt.Fprintln(cmd.ErrOrStderr(), " "+cliui.Styles.Code.Render("coder create <name>"))
|
|
_, _ = fmt.Fprintln(cmd.ErrOrStderr())
|
|
return nil
|
|
}
|
|
users, err := client.Users(cmd.Context(), codersdk.UsersRequest{})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
usersByID := map[uuid.UUID]codersdk.User{}
|
|
for _, user := range users {
|
|
usersByID[user.ID] = user
|
|
}
|
|
|
|
now := time.Now()
|
|
displayWorkspaces := make([]workspaceListRow, len(workspaces))
|
|
for i, workspace := range workspaces {
|
|
displayWorkspaces[i] = workspaceListRowFromWorkspace(now, usersByID, workspace)
|
|
}
|
|
|
|
out, err := cliui.DisplayTable(displayWorkspaces, "workspace", columns)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
_, err = fmt.Fprintln(cmd.OutOrStdout(), out)
|
|
return err
|
|
},
|
|
}
|
|
cmd.Flags().BoolVarP(&all, "all", "a", false,
|
|
"Specifies whether all workspaces will be listed or not.")
|
|
cmd.Flags().StringArrayVarP(&columns, "column", "c", nil,
|
|
"Specify a column to filter in the table.")
|
|
cmd.Flags().StringVar(&searchQuery, "search", defaultQuery, "Search for a workspace with a query.")
|
|
return cmd
|
|
}
|