bevry / dorothy

🧙🏻‍♀️ Bring your dotfile commands and configuration to any shell. Sensible defaults and hundreds of commands preloaded. Supports Bash, Zsh, Fish, Nu, Xonsh, Elvish, Dash, KornShell, macOS, Linux, Windows.
Other
333 stars 22 forks source link

Suggestion: shell-agnostic config files #173

Open balupton opened 1 year ago

balupton commented 1 year ago

Currently dorothy's config files are sourced into the shell calling them, and as most of the files that load config files are bash the config files must either be .sh or .bash

I'm thinking instead of sourcing configuration files, we could execute them, similar to what we do with setup-environment-commands

For instance, a bash config file could do:

#!/usr/bin/env dorothy-bash-env
export HELLO=world

And our helper command bash-env sources our sources/env.bash that dumps the commands to set the modified environment variables.

we'd just have to update our sources/config.* files to understand how to load these, and provide the (bash|zsh|fish|nu)-env commands.

This would also allow us to do json or toml config files.

The issue here however is that currently Dorothy can update fields within bash configuration files. If we properly endorse other formats, we'd need to move this updating ability into a proper command, and give it the intelligence to support any extension we support.

balupton commented 1 year ago

Another alternative to this would be for config files to change to commands that are invoked that output the configuration to stdout, as the format json/cson/toml/yaml or whatever specific format we adopt. This would also allow people to write dynamic config files in whatever language they want.

balupton commented 1 year ago

To summarise, existing config/file.extension files will work exactly the same, however this would add support for config/file (without extension) which would be invoked instead of sourced.

These config/file commands can be programmed in any shell language, and would be implemented via one of these proposals:

option 1: invoker

#!/usr/bin/env dorothy-bash-env
export HELLO=world

In which the dorothy-bash-env invoker would source $DOROTHY/sources/env.bash to automatically output the appropriate modifications.

option 2: manual json

#!/usr/bin/env bash
printf '%s' '{"HELLO": "world"}'
#!/usr/bin/env nu
# https://www.nushell.sh/book/types_of_data.html#records
# https://www.nushell.sh/commands/categories/filters.html
# https://www.nushell.sh/commands/docs/to_json.html
{HELLO: 'world'} | to json -r
#!/usr/bin/env node
process.stdout.write(JSON.stringify({HELLO: 'world'}))

Which would then be parsed by the config loading script.


Personally I'm leaning to option 2. Tooling can be created to make json construction easier for non-json languages. Furthermore we can even have configuration commands in any language, not just login shells, such as the Node.js example above.


The reason why we don't just support config/file.json is because we want evaluate of the configuration files, such that they can adjust the configuration based on the environment.


The limitation of config/file.extension is that their language support is limited to the language of the command that is loading them, e.g. a bash command can only load .bash and .sh` configuration files. This means that users of Nu have to write many configuration files in bash, as most of Dorothy is coded in bash.

Furthermore this change would allow more commands to be written in other languages, as any language would now be able to parse configuration files.

The big downside of this approach is that it would destroy our ability to update these configuration files programatically, as we currently do with our --configure and dorothy theme flows... however I guess we can just output a message to the user on what they need to change.