pvolok/mprocs

[Feature] Configurable process status display

legobeat opened this issue · 2 comments

Description

mprocs is very promising as a lightweight "framework" for certain CLI apps. Thank you for working on it and sharing, pvolok!

Current behavior

As I understand it:

  • Process running: UP (green)
  • Process exited: DOWN ($EXIT_CODE) (red)

Desired behavior

Allow recognizing multiple process states, and allow users to introduce their own semantics and represent them in an intuitive and pleasing way in UI (similar to #127)

So instead of:

### mprocs.yml
procs:
  foo:
    shell: "run-job foo"
  boo:
    shell: "run-job boo"
  baz:
    shell: "run-job baz"
  yay:
    shell: "run-job yay"
  zzz:
    shell: "run-job zzz"

## statuses
foo   UP            // green
boo   DOWN (1)      // red
bar   DOWN (123)    // red
yay   DOWN (0)      // red
zzz   DOWN          // red

We might want something like

## statuses
foo   Processing... // gray
boo   Failed! (1)   // red, bold
bar   Fixed!        // green
yay   Clean         // blue
zzz                 // empty

Solution

There is more than one approach to this.
The following aspects would be nice:

  • Dynamic enough to express bespoke error code semantics like above example
  • Keep the simple pipes-and-exit-codes only interface of communicating between mprocs and its processes (no unix sockets, temporary files, or other fanciness)

Option 1

  foo:
    shell: "run-job foo"
    statuses: *default_statuses
      '0':
        label: Processing...
        fg_color: lightgreen
        bold: false
      '123':
        label: Clean
        fg_color: blue
      # default/fallback for not explicitly defined codes
      '*': 
        label: 'Failed! (%s)'  # I guess the templating here would be a stretch-goal
        fg_color: lightred
      # For processes not yet started
      '':
        label: ''
      # ...
  bar:
    shell: "run-job bar"
    statuses: &default_statuses
  # ...

If going this approach, seems sensible to just pass through existing options and names for ratatui::style::Style.

Option 2

Some form of more dynamic templating language in process labels (and names?). If this were a golang project the obvious choice would be go-template - not sure if there's something similar that would be suitable for this project. Other things to imagine would be some subset of markdown/html or printf formatting. If going down this route could be worth looking at if there's some similar enough application (like a statusline implementation) with community mind-share to borrow from.

Arbitrary example:

  foo:
    shell: "run-job foo"
    statuses: *default_statuses
      '0': '[fg=lightgreen]Processing[/fg]...'

Could even imagine splitting the separation of "name" and "status" (would require #135 , I guess, and take some consideration to allow reuse of templates):

  foo:
    shell: "run-job foo"
    label: '${name}%t<fg=lightgreen>Processing</fg>...'

Option 3

Keep current main approach of hardcoded states but introduce more granularity.

#127 (comment)


Option 1 would be my proposed approach, as it's simpler and doesn't open pandora's box of introducing a DSL (maybe it does make sense to do something like this at a later point but seems overkill here), while being generic enough to remove the urge for certain follow-up PRs with associate reconsiderations of whether certain conventions should be considered in display or not (as option 3).

Related

  • This is a more general version of #127

Thank you for kind feedback and a very detailed proposal. I think we can have two layers of configurability.

Layer 1 would be your option 1. But I think an array would give us more flexibility. First element that matches would be used. And we can provide a few popular filters.

  foo:
    shell: "run-job foo"
    statuses: *default_statuses
      - exit_code: 0
        label: Processing...
        fg_color: lightgreen
        bold: false
      - exit_code: 123
        label: Clean
        fg_color: blue
      # default/fallback for not explicitly defined codes
      - exit_code: [ [1, 255] ] # Array of ranges
        label: 'Failed! (%s)'  # I guess the templating here would be a stretch-goal
        fg_color: lightred
      # For processes not yet started
      - never_started: true
        label: ''
      # ...
  bar:
    shell: "run-job bar"
    statuses: &default_statuses
  # ...

Layer 2 would be Lua customization. My current plan is to deprecate mprocs.lua config and instead have yaml configs that allow using code to customize some parts. This way we can reload configs without losing state. Also ui for editing yaml configs will be possible. And in Lua controller we can define dynamic and complex markup for rendering status. And more advanced checks will be possible via Lua controller: health checks, analyzing process output, etc.

Cheers!

Agreed list looks nicer and I like the filter-based approach allowing for ranges etc.

Another thought I had for process names would be to open up a third output pipe aside from stdout/stderr and use that as a feed for process title. Should be straightforward to implement. The lua approach is obviously a lot more powerful and sounds like it could be used to implement basically that if desired, anyway.