matryer / xbar

Put the output from any script or program into your macOS Menu Bar (the BitBar reboot)
https://xbarapp.com
MIT License
17.52k stars 643 forks source link

Allow compiled Go plugins to use xbar variables #833

Open sprak3000 opened 2 years ago

sprak3000 commented 2 years ago

There is currently no way for xbar to pull metadata from a compiled Go plugin. A naive first thought implementation might be to output the <xbar.var> metadata as part of the plugin output. Have the parser expect those lines at the start of the output, parse them out, and set them up as variables. Tricky part would be how to then inject those variables into the already running plugin... API way for the plugin to grab the config JSON itself?

mlh78750 commented 1 year ago

Would it be possible to just look to see if there is a .vars.json and use that to identify both the possible vars and the set value for all complied plugins? I've made a rust based plugin and would love to have the ability to use variables. If you just allowed the json without the need for the commented xbar.var tags in the code it would cover all complied plugins.

leaanthony commented 1 year ago

That's a neat idea. Would that be relative to the plugin?

mlh78750 commented 1 year ago

I was thinking if you had something like plugin.5m.bin you could in the plugindir have plugin.5m.bin.vars.json. That .json file could have { "VAR_NAME": "BOB" } and that would show up in the env for the exec of the .bin.

sprak3000 commented 1 year ago

Have read over the proposal a few times and want to see if my understanding of the flow lines up. It sounds like the flow would be:

  1. You install the plugin, effectively enabling it.
  2. The plugin itself would write out its configuration file with the environment variables with potential default values in it.
  3. The xbar UI would both try to parse the script for variable metadata but also look for a configuration file for possible variables to present in the plugin browser.

If have the above correct, I think the main trade off to consider is the JSON isn't very descriptive. { "VAR_NAME": "BOB" } doesn't provide all the options the current metadata format allows -- descriptions, restricting a variable to set of values, etc. The plugin browser UI could read that in if present and no other metadata is found, but it wouldn't make for an ideal experience to a user trying to configure the plugin.

It also places a small burden on the plugin author to manage that initial startup of their plugin. "Is the config file there? No... write it out". xbar could provide some environment variables to help with that -- path, filename, etc. Still leaves the plugin author with a code path they wouldn't otherwise have to maintain.

Overall, I think I've encountered only one other plugin wanting to be compiled rather than interpreted. I'm likely an edge case. I'm also maintaining my own configuration file for my plugin already, where what I want to configure doesn't fit neatly into the xbar system.

I have larger ideas around plugins, metadata, and such, but I'm still thinking through the implications to xbar and the ecosystem before I present them. Probably worth just closing this out at this point.

mlh78750 commented 1 year ago

I get the limitation of json. You could still do something like have a file like .plugin.5m.bin.vars file or something that was just a text file with the existing format for scripts/interpreted plugins and leave the json as is.

I also don't think you'd have to have the plugin emit the file. It could be packaged as part of the plugin install. Or have a standard that on install you run the plugin with a env var called GET_VARS or something and plugin authors just write to stdout the contents of that file.

But I also understand that you might have other plans where this wouldn't fit.

mlh78750 commented 1 year ago

Trying to be more pedantic for my proposal.

A complied plugin could optionally include a file that has all of the stuff next to it in the plugin direction with a '.' pre-pended and a .vars post-pended to the plugin's original filename.

You could also optionally have plugins implement a specific flag that would output that file to stdout for xbar to run on install (creating the .plugin-filename.var file).

vars would be read from this dotfile and function just like they do in scripts.

xbar would use the .json files just like it does with scripts.

This would allow complied plugins to use the vars and have them passed into the plugin via the environment xbar executes them within.