Bashly – Create beautiful bash scripts from simple YAML configuration
github.com
github.com
You provide a YAML file listing commands, subcommands, arguments, and flags, and it automatically generates a Bash script that can parse and validate them, provide help messages, and run your code for each command.
It also lets you keep the actual code for each command and subcommand in separate files, which are merged together into one distributable Bash script at generation time.
It's basically a templating system to auto-generate argument parsing so you don't have to solve that again or deal with things like optparse.
2. If you need this level of complexity, I feel like you should be reaching for Python or Go or something else that definitely isn't Bash
I also see argument 2 a lot, and I've already addressed this in other comments, but sometimes you really just need to call a couple of commands while prepping some env vars or config files for convenience.
In those cases, reaching for Python or Go ends up being a lot of boilerplate for very little advantage, especially when you want to pass control over to other applications once you're done setting things up.
No you aren't. This irritates me also. Bash is about as beautiful as perl.
> 2. If you need this level of complexity, I feel like you should be reaching for Python or Go or something else that definitely isn't Bash
This is true. Otherwise you risk [in bash] creating something very difficult to maintain for future contributors. The lengths people will go to avoid "programming" can be quite staggering.
https://ilya-sher.org/2021/03/19/running-elegant-bash-on-sim...
"Beautiful" would be in the intersection. "Modern" is popular on HN, but not so much with the ex-president.
For all its shortcomings, I find that shell scripting is still the easiest way to put together a tool that needs to interact with a lot of other commands, no matter how large it ends up being. I love Python to death, but using `subprocess` for everything is the opposite of my idea of a good time.
You would think there would be more effort supporting this since it's so tedious to have a billion libraries that are just wrappers around http apis and external utility calls.
Most shell utilities are focused on text processing or are thin wrappers around system calls. If you're using something like python's `subprocess` module to get at these, you're doing it wrong.
Interactivity is where shells have an advantage. Their syntax lends itself well to that. It's also why the syntax sucks for regular programming.
Next Generation Shell is a "real" programming language. It also has syntax for calling external programs. It handles exit codes properly. It has facility for constructing command line arguments.
Project - https://github.com/ngs-lang/ngs
Motivation related to the above - https://ilya-sher.org/2017/10/10/why-i-have-no-favorite-prog...
edit: ah, yes, NGS also supports command line arguments automatic parsing when main() is called; augmenting this facility would be the sane way to solve the problem.
However, I wanted to go back and see what was earlier or view the source input and output. So I would also like it if the contents of the gif was printed out below for easier access.
Totally understand why you would write this in Ruby instead though!
Note there is a docker image if you want to use it without having Ruby.
As an example, here's a bash alias generator, alf [0], which itself is a bash script, created using this. The bash script for alf is note really small [1]. Additionally, the output is extremely readable unlike most other bash scripts I myself have written!
Really amazing piece of software! Kudos.
[0]: https://github.com/DannyBen/alf [1]: https://raw.githubusercontent.com/DannyBen/alf/master/alf
It's probably clever, sure, but it seems like this would wind up more declarative than imperative?
1. Define your commands + flags + args in YAML (`bashly init` creates this YAML).
2. Bashly generates the standalone script and empty "placeholder" scripts for your actual bash code (`bashly generate`).
3. You plug in your bash code.
4. Bashly merges it all back to the same single final script (`bashly generate`).
5. Rinse and repeat.
What happens when I get to 5 and want to change an arg for cdm/foo? Does step 3 need to be repeated in its entirety?
I think this is a good minimal example:
https://github.com/DannyBen/bashly/tree/master/examples/mini...
Anyone know what tool is used to create that?
It was created with asciinema and svg-term-cli
Run : https://github.com/TekWizely/run
It has its own DSL for describing tasks, along with help strings and argument descriptors, and can manages generating help screens, parsing args and invoking tasks (sub-commands).
Each task can be written in its own language, one task could be Bash, one could be zsh, one could be python, etc.
If you're in the market for a flexible task runner, I hope you'll give it a chance.
At its core it's just interacting with existing software like docker-compose, git, and some internal tools, which I find is still much, much easier to do with shell scripting than "proper" languages.
I need to build things that pass the bus audit: other people also have to understand them and work on them and, for better or for worse, Bash is a very popular lowest common denominator for many devs.
There are of course other alternatives such as `doit`
When you want to create a bash script - and you choose bash for portability or for whatever reason - and still want to have a decent-looking command line interface, without investing effort in creating argument parsers and usage help.
The examples page shows real-world examples, and per-feature examples: https://bashly.dannyb.co/examples/
> ${1:?help message}
Using python more these days however
https://github.com/hofstadter-io/hofmod-cli is the same idea for generating Go CLI boilerplate.
hof uses CUE instead of Yaml, can output to any and multiple languages, and uses diff3 so you can work in both the output and the design at the same time.