github.com/lmorg/murex@v0.0.0-20240217211045-e081c89cd4ef/builtins/core/processes/fid-list.go (about) 1 package processes 2 3 import ( 4 "fmt" 5 "strings" 6 7 "github.com/lmorg/murex/config/defaults" 8 "github.com/lmorg/murex/lang" 9 "github.com/lmorg/murex/lang/state" 10 "github.com/lmorg/murex/lang/types" 11 "github.com/lmorg/murex/utils/json" 12 ) 13 14 func init() { 15 lang.DefineFunction("fid-list", cmdFidList, types.JsonLines) 16 17 defaults.AppendProfile(` 18 autocomplete set fid-list { [{ 19 "DynamicDesc": ({ fid-list --help }) 20 }] } 21 22 alias jobs=fid-list --jobs 23 method define jobs { 24 "in": "null", 25 "out": "*" 26 } 27 config eval shell safe-commands { -> append jobs }`) 28 } 29 30 func getParams(p *lang.Process) string { 31 params := p.Parameters.StringArray() 32 if len(params) == 0 && len(p.Parameters.PreParsed) > 0 { 33 params = make([]string, len(p.Parameters.PreParsed)) 34 for i := range p.Parameters.PreParsed { 35 params[i] = string(p.Parameters.PreParsed[i]) 36 } 37 } 38 39 return strings.Join(params, " ") 40 } 41 42 func cmdFidList(p *lang.Process) error { 43 flag, _ := p.Parameters.String(0) 44 switch flag { 45 case "": 46 if p.Stdout.IsTTY() { 47 return cmdFidListTTY(p) 48 } 49 return cmdFidListPipe(p) 50 51 case "--csv": 52 return cmdFidListCSV(p) 53 54 case "--jsonl": 55 return cmdFidListPipe(p) 56 57 case "--tty": 58 return cmdFidListTTY(p) 59 60 case "--jobs": 61 return cmdJobs(p) 62 63 case "--stopped": 64 return cmdJobsStopped(p) 65 66 case "--background": 67 return cmdJobsBackground(p) 68 69 case "--help": 70 fallthrough 71 72 default: 73 return cmdFidListHelp(p) 74 } 75 } 76 77 func cmdFidListHelp(p *lang.Process) error { 78 flags := map[string]string{ 79 "--csv": "Outputs as CSV table", 80 "--jsonl": "Outputs as a jsonlines (a greppable array of JSON objects). This is the default mode when `fid-list` is piped", 81 "--tty": "Outputs as a human readable table. This is the default mode when outputting to a TTY", 82 "--stopped": "JSON map of all stopped processes running under murex", 83 "--background": "JSON map of all background processes running under murex", 84 "--jobs": "List stopped or background processes (similar to POSIX jobs)", 85 "--help": "Displays a list of parameters", 86 } 87 p.Stdout.SetDataType(types.Json) 88 b, err := json.Marshal(flags, p.Stdout.IsTTY()) 89 if err != nil { 90 return err 91 } 92 93 _, err = p.Stdout.Write(b) 94 return err 95 } 96 97 func cmdFidListTTY(p *lang.Process) error { 98 p.Stdout.SetDataType(types.Generic) 99 p.Stdout.Writeln([]byte(fmt.Sprintf("%7s %7s %7s %-12s %-8s %-3s %-10s %-10s %-10s %s", 100 "FID", "Parent", "Scope", "State", "Run Mode", "BG", "Out Pipe", "Err Pipe", "Command", "Parameters"))) 101 102 procs := lang.GlobalFIDs.ListAll() 103 for _, process := range procs { 104 s := fmt.Sprintf("%7d %7d %7d %-12s %-8s %-3s %-10s %-10s %-10s %s", 105 process.Id, 106 process.Parent.Id, 107 process.Scope.Id, 108 process.State.String(), 109 process.RunMode.String(), 110 process.Background.String(), 111 process.NamedPipeOut, 112 process.NamedPipeErr, 113 process.Name.String(), 114 getParams(process), 115 ) 116 _, err := p.Stdout.Writeln([]byte(s)) 117 if err != nil { 118 return err 119 } 120 } 121 return nil 122 } 123 124 func cmdFidListCSV(p *lang.Process) error { 125 p.Stdout.SetDataType("csv") 126 p.Stdout.Writeln([]byte(fmt.Sprintf("%s,%s,%s,%s,%s,%s,%s,%s,%s,%s", 127 "FID", "Parent", "Scope", "State", "Run Mode", "BG", "Out Pipe", "Err Pipe", "Command", "Parameters"))) 128 129 procs := lang.GlobalFIDs.ListAll() 130 for _, process := range procs { 131 s := fmt.Sprintf("%d,%d,%d,%s,%s,%s,%s,%s,%s,%s", 132 process.Id, 133 process.Parent.Id, 134 process.Scope.Id, 135 process.State.String(), 136 process.RunMode.String(), 137 process.Background.String(), 138 process.NamedPipeOut, 139 process.NamedPipeErr, 140 process.Name.String(), 141 getParams(process), 142 ) 143 _, err := p.Stdout.Writeln([]byte(s)) 144 if err != nil { 145 return err 146 } 147 } 148 return nil 149 } 150 151 func cmdFidListPipe(p *lang.Process) error { 152 p.Stdout.SetDataType(types.JsonLines) 153 154 b, err := lang.MarshalData(p, types.Json, []interface{}{ 155 "FID", 156 "Parent", 157 "Scope", 158 "State", 159 "RunMode", 160 "BG", 161 "OutPipe", 162 "ErrPipe", 163 "Command", 164 "Parameters", 165 }) 166 if err != nil { 167 return err 168 } 169 _, err = p.Stdout.Writeln(b) 170 if err != nil { 171 return err 172 } 173 174 procs := lang.GlobalFIDs.ListAll() 175 for _, process := range procs { 176 b, err = lang.MarshalData(p, types.Json, []interface{}{ 177 process.Id, 178 process.Parent.Id, 179 process.Scope.Id, 180 process.State.String(), 181 process.RunMode.String(), 182 process.Background.Get(), 183 process.NamedPipeOut, 184 process.NamedPipeErr, 185 process.Name.String(), 186 getParams(process), 187 }) 188 if err != nil { 189 return err 190 } 191 _, err = p.Stdout.Writeln(b) 192 if err != nil { 193 return err 194 } 195 } 196 197 return nil 198 } 199 200 func cmdJobsStopped(p *lang.Process) error { 201 procs := lang.GlobalFIDs.ListAll() 202 m := make(map[uint32]string) 203 204 for _, process := range procs { 205 if process.State.Get() != state.Stopped { 206 continue 207 } 208 m[process.Id] = process.Name.String() + " " + getParams(process) 209 } 210 211 b, err := lang.MarshalData(p, types.Json, m) 212 if err != nil { 213 return err 214 } 215 216 p.Stdout.SetDataType(types.Json) 217 _, err = p.Stdout.Write(b) 218 return err 219 } 220 221 func cmdJobsBackground(p *lang.Process) error { 222 procs := lang.GlobalFIDs.ListAll() 223 m := make(map[uint32]string) 224 225 for _, process := range procs { 226 if !process.Background.Get() { 227 continue 228 } 229 m[process.Id] = process.Name.String() + " " + getParams(process) 230 } 231 232 b, err := lang.MarshalData(p, types.Json, m) 233 if err != nil { 234 return err 235 } 236 237 p.Stdout.SetDataType(types.Json) 238 _, err = p.Stdout.Write(b) 239 return err 240 }