github.com/streamingfast/substreams@v1.6.2/cmd/substreams/service-utils.go (about) 1 package main 2 3 import ( 4 "context" 5 "fmt" 6 "sort" 7 "strings" 8 9 "connectrpc.com/connect" 10 "github.com/spf13/cobra" 11 pbsinksvc "github.com/streamingfast/substreams/pb/sf/substreams/sink/service/v1" 12 "github.com/streamingfast/substreams/pb/sf/substreams/sink/service/v1/pbsinksvcconnect" 13 ) 14 15 var fuzzyMatchPreferredStatusOrder = []pbsinksvc.DeploymentStatus{ 16 pbsinksvc.DeploymentStatus_RUNNING, 17 pbsinksvc.DeploymentStatus_PAUSED, 18 pbsinksvc.DeploymentStatus_FAILING, 19 pbsinksvc.DeploymentStatus_STOPPED, 20 pbsinksvc.DeploymentStatus_UNKNOWN, 21 } 22 23 func fuzzyMatchDeployment(ctx context.Context, q string, cli pbsinksvcconnect.ProviderClient, cmd *cobra.Command, preferredStatusOrder []pbsinksvc.DeploymentStatus) (*pbsinksvc.DeploymentWithStatus, error) { 24 req := connect.NewRequest(&pbsinksvc.ListRequest{}) 25 if err := addHeaders(cmd, req); err != nil { 26 return nil, err 27 } 28 resp, err := cli.List(ctx, req) 29 if err != nil { 30 return nil, fmt.Errorf("error fetching existing deployments: %w", err) 31 } 32 33 matching := make(map[*pbsinksvc.DeploymentWithStatus]pbsinksvc.DeploymentStatus) 34 for _, dep := range resp.Msg.Deployments { 35 if strings.HasPrefix(dep.Id, q) { 36 matching[dep] = dep.Status 37 } 38 } 39 if len(matching) == 0 { 40 return nil, fmt.Errorf("cannot find any deployment matching %q", q) 41 } 42 if len(matching) == 1 { 43 for k := range matching { 44 return k, nil 45 } 46 } 47 // more than one match, take the best status... 48 49 for i := len(preferredStatusOrder) - 1; i >= 0; i-- { 50 for k, v := range matching { 51 if v == preferredStatusOrder[i] { 52 delete(matching, k) 53 } 54 } 55 if len(matching) == 1 { 56 for k := range matching { 57 return k, nil 58 } 59 } 60 if len(matching) == 0 { 61 break 62 } 63 } 64 return nil, fmt.Errorf("cannot determine which deployment should match %q", q) 65 } 66 67 func printServices(outputs map[string]string) { 68 fmt.Printf("Services:\n") 69 var keys []string 70 for k := range outputs { 71 keys = append(keys, k) 72 } 73 sort.Strings(keys) 74 75 for _, k := range keys { 76 lines := strings.Split(outputs[k], "\n") 77 prefixLen := len(k) + 6 78 var withMargin string 79 for i, line := range lines { 80 if i == 0 { 81 withMargin = line + "\n" 82 continue 83 } 84 withMargin += strings.Repeat(" ", prefixLen) + line + "\n" 85 } 86 fmt.Printf(" - %s: %s", k, withMargin) 87 } 88 89 } 90 91 func userConfirm() bool { 92 var resp string 93 _, err := fmt.Scan(&resp) 94 if err != nil { 95 panic(err) 96 } 97 98 switch strings.ToLower(resp) { 99 case "y", "yes": 100 return true 101 } 102 return false 103 } 104 105 func interceptConnectionError(err error) error { 106 if connectError, ok := err.(*connect.Error); ok { 107 if connectError.Code() == connect.CodeUnavailable { 108 return fmt.Errorf("cannot connect to sink service: %w. Are you running `substreams alpha service serve` ?", err) 109 } 110 } 111 return err 112 }