Bashly Framework Documentation
repository·master·Indexed 25 days ago
https://github.com/bashly-framework/bashlyA CLI framework and generator for creating sophisticated bash scripts using YAML configuration. Bashly automates argument parsing, help text generation, and command routing. Key features include support for catch-all arguments, argfile default loading, command aliases, and a built-in colors library for colorized output.
What's inside Bashly
- Bashly is a command line application written in Ruby that acts as a generator for feature-rich bash command line tools. Instead of manually writing complex argument parsing logic, error handling, and help text, you define your CLI structure in a YAML configuration file. Bashly then generates a standalone, shellcheck-compliant, and shfmt-compliant bash script that handles the heavy lifting of command-line interface management.
Configure hooks in `bashly.yml`
masterHooks are managed via thebashly.ymlconfiguration file. While the specific implementation of the hook logic resides in the generatedsrc/root_command.sh(which you can edit freely and regenerate without loss), the hook component must be added to the project structure using thebashly add hookscommand.Use custom properties in the Markdown renderer
masterThe Bashly Markdown renderer supports custom properties prefixed with
x_markdown_to inject additional content into the generated documentation.One available property is
x_markdown_footer, which allows you to append a custom section (like an issue tracker or contact info) to the end of the generated Markdown file.To see all supported custom properties, run:
bashly render :markdown --aboutx_markdown_footer: |- # ISSUE TRACKER Report issues at <https://github.com/lanalang/smallville>Delegate unknown commands to an external executable
masterBashly allows you to create extensible CLI applications that can delegate commands not explicitly defined in the framework to an external executable. In this pattern, if a user invokes a command that the primary CLI (e.g.,mygit) does not recognize, the application intercepts the call and passes the arguments to a secondary executable (e.g.,git).How to implement custom validation functions
masterBashly allows you to define custom validation logic by creating functions in your script.
To register a custom validator, name your function starting with the prefix
validate_. For example, if you specifyvalidate: my_custom_rulein yourbashly.yml, Bashly will look for a function namedvalidate_my_custom_rulein your script.Function Return Contract:
- On Success: Return an empty string (
""). - On Failure: Return a string containing the error message to be displayed to the user.
- On Success: Return an empty string (
Accessing flags in generated shell scripts
masterWhen you define flags in
bashly.yml, Bashly generates a shell script where the logic for the root command is located insrc/root_command.sh. The code you write in this file is wrapped in a function namedcli_command().You can access the values of passed flags using the
${args[--flag-name]}syntax. For boolean flags (flags without anargdefined), the value is typically set to1when present.# Inside src/root_command.sh args: - ${args[--verbose]} = 1 - ${args[--host]} = localhostHow the initialize hook works
masterThesrc/initialize.shfile contains theinitialize()function. Any code placed in this file is executed inside this function and is called before any other part of the CLI runs. This is the ideal place for global setup, such as enabling features like stack traces or setting environment variables.How default commands behave in the CLI
masterWhen a command is set as
default: true, Bashly modifies the CLI usage patterns:- Implicit Execution: If the user runs
./app something, anduploadis the default command, Bashly executes theuploadcommand logic usingsomethingas the arguments. - Explicit Execution: Running
./app upload somethingremains valid and performs the same action. - Help Text: The default command is typically identified in the help output with a
(default)label next to its description.
- Implicit Execution: If the user runs
Use the docker image command alias
masterThedocker imagecommand supports the short aliasifor more concise command execution.Enable catch_all for arbitrary arguments
masterThe
catch_alloption allows a command to receive an arbitrary list of arguments that are not explicitly defined in theargssection ofbashly.yml. Whencatch_all: trueis set, any extra arguments provided by the user are captured in a special array calledother_args.To use this feature:
- Set
catch_all: trueat the command level in yourbashly.yml. - Access the captured arguments using the
${other_args[*]}(all arguments) or${other_args[index]}(specific argument by index) syntax within your command implementation files.
Note that if a user provides flags that are not defined in your
flagslist, they will also be captured in theother_argsarray.name: download help: Catch All Example version: 0.1.0 # Enable catch_all for the root command catch_all: true args: - name: message required: true help: Message flags: - long: --debug short: -d- Set
Implement a command in a generated `.sh` file
masterWhen you generate a Bashly project, each command is assigned a corresponding shell script file in the
src/directory (e.g.,src/all_command.sh).Your implementation code is automatically wrapped inside a function named after the command following the pattern
[app_name]_[command_name]_command().For example, if your application is named
testerand your command isall, your code goes intosrc/all_command.shand will be executed within thetester_all_command()function. Changes made to these files will persist across subsequentbashly generatecalls.Implement command logic in command shell files
masterFor every command defined in
bashly.yml, Bashly generates a corresponding shell script in thesrc/directory (e.g.,src/status_command.shfor a command namedstatus).Your logic must be written inside a function that Bashly automatically wraps. For a command named
status, the function name will begit_status_command().To access flags and arguments passed to the command, use the
${args[<flag_name>]}syntax. For example, if a flag--allis used, its value can be accessed via${args[--all]}.