Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/runware_serverless_apps_list.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ runware serverless apps list [flags]
-h, --help help for list
--limit int Maximum number of applications to return (1-100)
--query string Filter by substring on name or ID
--sort string Sort order (createdAt (default), name, activity, or errorRate)
--sort string Sort order (createdAt (default) or name)
--status string Filter by status (active, initializing, stopped, …)
```

Expand Down
5 changes: 5 additions & 0 deletions internal/api/serverless/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,11 @@ const (
// AppSort is a listApps ordering.
type AppSort = gen.AppSort

const (
AppSortCreatedAt AppSort = gen.CreatedAt
AppSortName AppSort = gen.Name
)

// WorkerStatus is a worker lifecycle status.
type WorkerStatus = gen.WorkerStatus

Expand Down
21 changes: 19 additions & 2 deletions internal/cmd/serverless/apps.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ func newAppsListCmd(logger *log.Logger) *cobra.Command {
cmd.Flags().StringVar(&status, "status", "", "Filter by status (active, initializing, stopped, …)")
cmd.Flags().StringVar(&query, "query", "", "Filter by substring on name or ID")
cmd.Flags().StringVar(&gpuType, "gpu-type", "", "Filter by GPU type (see 'serverless gpus')")
cmd.Flags().StringVar(&sort, "sort", "", "Sort order (createdAt (default), name, activity, or errorRate)")
cmd.Flags().StringVar(&sort, "sort", "", "Sort order ("+appListSortsHelp+")")

return cmd
}
Expand Down Expand Up @@ -438,8 +438,25 @@ func parseValidFlag[T validListFlag](flag, value, want string) (*T, error) {
return &v, nil
}

// appListSorts are the listApps orderings this CLI offers. activity and
// errorRate stay in the API enum, but they rank on traffic metrics that are
// not collected yet, so the server answers 422. They are omitted until that lands.
var appListSorts = map[serverlessapi.AppSort]struct{}{
serverlessapi.AppSortCreatedAt: {},
serverlessapi.AppSortName: {},
}

const appListSortsHelp = "createdAt (default) or name"

func parseAppSort(sort string) (*serverlessapi.AppSort, error) {
return parseValidFlag[serverlessapi.AppSort]("--sort", sort, "createdAt, name, activity, or errorRate")
if sort == "" {
return nil, nil
}
v := serverlessapi.AppSort(sort)
if _, ok := appListSorts[v]; !ok {
return nil, fmt.Errorf("invalid --sort %q (want %s)", sort, appListSortsHelp)
}
return &v, nil
}

func parseAppStatus(status string) (*serverlessapi.AppStatus, error) {
Expand Down
23 changes: 11 additions & 12 deletions internal/cmd/serverless/display_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,25 +66,24 @@ func TestParseAppSort(t *testing.T) {
t.Fatalf("unset sort: got=%v err=%v", got, err)
}

got, err = parseAppSort("activity")
if err != nil {
t.Fatalf("activity: %v", err)
}
if got == nil || *got != "activity" {
t.Fatalf("activity: got %+v", got)
got, err = parseAppSort("name")
if err != nil || got == nil || *got != "name" {
t.Fatalf("name: got=%v err=%v", got, err)
}

got, err = parseAppSort("createdAt")
if err != nil || got == nil || *got != "createdAt" {
t.Fatalf("createdAt: got=%v err=%v", got, err)
}

_, err = parseAppSort("nope")
if err == nil {
t.Fatal("expected error for sort nope")
}
if !strings.Contains(err.Error(), "invalid --sort") {
t.Fatalf("error %q should mention invalid --sort", err)
for _, sort := range []string{"activity", "errorRate", "nope"} {
_, err = parseAppSort(sort)
if err == nil {
t.Fatalf("expected error for sort %q", sort)
}
if !strings.Contains(err.Error(), "invalid --sort") || !strings.Contains(err.Error(), appListSortsHelp) {
t.Fatalf("error %q should name the allowed sorts", err)
}
}
}

Expand Down
Loading