github.com/DaAlbrecht/cf-cli@v0.0.0-20231128151943-1fe19bb400b9/integration/helpers/app_instance_table.go (about) 1 package helpers 2 3 import ( 4 "regexp" 5 "strings" 6 ) 7 8 // AppInstanceRow represents an instance of a V3 app's process, 9 // as displayed in the 'cf app' output. 10 type AppInstanceRow struct { 11 Index string 12 State string 13 Since string 14 CPU string 15 Memory string 16 Disk string 17 LogRate string 18 Details string 19 } 20 21 // AppProcessTable represents a process of a V3 app, as displayed in the 'cf 22 // app' output. 23 type AppProcessTable struct { 24 Type string 25 Sidecars string 26 InstanceCount string 27 MemUsage string 28 Instances []AppInstanceRow 29 } 30 31 // AppTable represents a V3 app as a collection of processes, 32 // as displayed in the 'cf app' output. 33 type AppTable struct { 34 Processes []AppProcessTable 35 } 36 37 // ParseV3AppProcessTable parses bytes from 'cf app' stdout into an AppTable. 38 func ParseV3AppProcessTable(input []byte) AppTable { 39 appTable := AppTable{} 40 41 rows := strings.Split(string(input), "\n") 42 foundFirstProcess := false 43 for _, row := range rows { 44 if !foundFirstProcess { 45 ok := regexp.MustCompile(`\Atype:([^:]+)\z`).Match([]byte(row)) 46 if ok { 47 foundFirstProcess = true 48 } else { 49 continue 50 } 51 } 52 53 if row == "" { 54 continue 55 } 56 57 switch { 58 case strings.HasPrefix(row, "#"): 59 const columnCount = 8 60 61 // instance row 62 columns := splitColumns(row) 63 details := "" 64 if len(columns) >= columnCount { 65 details = columns[7] 66 } 67 68 instanceRow := AppInstanceRow{ 69 Index: columns[0], 70 State: columns[1], 71 Since: columns[2], 72 CPU: columns[3], 73 Memory: columns[4], 74 Disk: columns[5], 75 LogRate: columns[6], 76 Details: details, 77 } 78 lastProcessIndex := len(appTable.Processes) - 1 79 appTable.Processes[lastProcessIndex].Instances = append( 80 appTable.Processes[lastProcessIndex].Instances, 81 instanceRow, 82 ) 83 84 case strings.HasPrefix(row, "type:"): 85 appTable.Processes = append(appTable.Processes, AppProcessTable{ 86 Type: strings.TrimSpace(strings.TrimPrefix(row, "type:")), 87 }) 88 89 case strings.HasPrefix(row, "instances:"): 90 lpi := len(appTable.Processes) - 1 91 iVal := strings.TrimSpace(strings.TrimPrefix(row, "instances:")) 92 appTable.Processes[lpi].InstanceCount = iVal 93 94 case strings.HasPrefix(row, "memory usage:"): 95 lpi := len(appTable.Processes) - 1 96 mVal := strings.TrimSpace(strings.TrimPrefix(row, "memory usage:")) 97 appTable.Processes[lpi].MemUsage = mVal 98 99 default: 100 // column headers 101 continue 102 } 103 104 } 105 106 return appTable 107 } 108 109 func splitColumns(row string) []string { 110 // uses 3 spaces between columns 111 return regexp.MustCompile(`\s{3,}`).Split(strings.TrimSpace(row), -1) 112 }