Bashly Framework Documentation

repository·master·Indexed 25 days ago

https://github.com/bashly-framework/bashly

A 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.

Tokens
38.2K
Snippets
166
Records
244
Agent score
74%

What's inside Bashly

  1. Overview of Bashly

    master
    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.
  2. Configure hooks in `bashly.yml`

    master
    Hooks are managed via the bashly.yml configuration file. While the specific implementation of the hook logic resides in the generated src/root_command.sh (which you can edit freely and regenerate without loss), the hook component must be added to the project structure using the bashly add hooks command.
  3. Use custom properties in the Markdown renderer

    master

    The 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 --about
    x_markdown_footer: |-
      # ISSUE TRACKER
      Report issues at <https://github.com/lanalang/smallville>
  4. Delegate unknown commands to an external executable

    master
    Bashly 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).
  5. How to implement custom validation functions

    master

    Bashly 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 specify validate: my_custom_rule in your bashly.yml, Bashly will look for a function named validate_my_custom_rule in 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.
  6. Accessing flags in generated shell scripts

    master

    When you define flags in bashly.yml, Bashly generates a shell script where the logic for the root command is located in src/root_command.sh. The code you write in this file is wrapped in a function named cli_command().

    You can access the values of passed flags using the ${args[--flag-name]} syntax. For boolean flags (flags without an arg defined), the value is typically set to 1 when present.

    # Inside src/root_command.sh
    args:
    - ${args[--verbose]} = 1
    - ${args[--host]} = localhost
  7. How default commands behave in the CLI

    master

    When a command is set as default: true, Bashly modifies the CLI usage patterns:

    1. Implicit Execution: If the user runs ./app something, and upload is the default command, Bashly executes the upload command logic using something as the arguments.
    2. Explicit Execution: Running ./app upload something remains valid and performs the same action.
    3. Help Text: The default command is typically identified in the help output with a (default) label next to its description.
  8. Enable catch_all for arbitrary arguments

    master

    The catch_all option allows a command to receive an arbitrary list of arguments that are not explicitly defined in the args section of bashly.yml. When catch_all: true is set, any extra arguments provided by the user are captured in a special array called other_args.

    To use this feature:

    1. Set catch_all: true at the command level in your bashly.yml.
    2. 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 flags list, they will also be captured in the other_args array.

    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
  9. Implement a command in a generated `.sh` file

    master

    When 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 tester and your command is all, your code goes into src/all_command.sh and will be executed within the tester_all_command() function. Changes made to these files will persist across subsequent bashly generate calls.

  10. Implement command logic in command shell files

    master

    For every command defined in bashly.yml, Bashly generates a corresponding shell script in the src/ directory (e.g., src/status_command.sh for a command named status).

    Your logic must be written inside a function that Bashly automatically wraps. For a command named status, the function name will be git_status_command().

    To access flags and arguments passed to the command, use the ${args[<flag_name>]} syntax. For example, if a flag --all is used, its value can be accessed via ${args[--all]}.