DEV Community

arctic_hen7
arctic_hen7

Posted on

Command Aliases with Superpowers to Replace Make (Announcing Bonnie v0.3.0)

GitHub logo arctic-hen7 / bonnie

Simple, cross-platform, and fast command aliases with superpowers.

Bonnie

Contributor Covenant Test Build and Release Join the chat at https://gitter.im/bonnie-cli/community

Simple, cross-platform, and fast command aliases with superpowers.

Documentation β€’ Releases β€’ Contributing

Bonnie is a command aliasing tool that allows you to quickly and efficiently define short aliases for long commands that you have to repeatedly run. Here's a quick feature overview:

  • Supports simple key-value aliasing
  • Supports inserting custom arguments into commands
  • Supports interpolating environment variables
  • Supports adding any and all arguments given into a single place
  • Supports using different commands on different operating systems
  • Supports specifying custom shells for individual commands
  • Supports specifying default shells for different operating systems on a per-file basis
  • Supports infinitely nestable subcommands
  • Supports subcommands executed in a certain order based on their exit codes
  • Supports caching large config files after they've been parsed for performance
  • Supports initializing new config files from templates

Basically, if you have commands that you routinely run in a project, Bonnie is for you. Bonnie has support for…

Let's talk about command aliases, making short commands to reference longer ones. What tool springs to mind for you? If you're a JavaScript developer, probably NPM or Yarn scripts, which have such features inbuilt. If you use any other language, Make is probably at the top of the list.

For a very long time, there have been very few dedicated command aliasing tools, and yet build commands get more and more complex! Make was designed as a full build tool, though it's regularly used for simple command aliasing, which is absolute overkill! Not only is Make old and clunky, using it for command aliasing is like using a sledgehammer to crack an egg!

Make works well for command aliasing, but we can do better. Make is great for what it was designed for, don't get me wrong, but that was not simple command aliasing. And yet without Make, we have basically no real solutions though to command aliasing on a per-project basis (sure you can define global aliases in ~/.bash_aliases, but they don't help for multiple different projects).

Enter Bonnie, a tool I built a while ago while I was learning Rust. Since then, I've used Bonnie every day to manage my own command aliases, and it's recently undergone significant changes.

Now, Bonnie supports everything from simple key-value command aliasing to nested subcommands, it has a miniature programming language inbuilt that allows you to specify control flow between commands, and it even supports running different commands on different operating systems, the holy grail of cross-platform collaboration.

Bonnie also has extensive documentation and pre-built binaries on its releases page for Linux, MacOS, Windows, and even musl (for Alpine Linux and the like).

The rest of this post will be a brief tutorial on how to use Bonnie to make command aliasing dead simple in your projects.

Installation

  1. Head over to the releases page and download the latest binary for your OS.
  2. Move that binary to somewhere from which you can execute it easily (e.g. /usr/local/bin on Linux).
  3. Run bonnie -v as a sanity check in the terminal.

Setup

  1. Go into a project that needs command aliasing.
  2. Run bonnie -i.

Congratulations! You now have a super-basic Bonnie configuration in that directory in bonnie.toml. It's written in TOML, which is designed to be a human-readable version of JSON and YAML that doesn't sacrifice features.

Alias time

Let's say you have a really long build command. But, it's the same every time you run it, and it works on every OS. Easy.

version = "0.3.0"

[scripts]
build = "long command here"
Enter fullscreen mode Exit fullscreen mode

How about a multistage command for deploying to a platform like Netlify? Easy.

version = "0.3.0"

[scripts]
deploy = [
    "stage 1",
    "stage 2"
]
Enter fullscreen mode Exit fullscreen mode

Well what about an execution command that needs to do different things on different OSes? Still easy.

version = "0.3.0"

[scripts]
run.generic = "generic fallback here"
run.targets.windows = "windows command here"
run.targets.macos = "macos command here"
run.targets.linux = "linux command here"
# iOS, Android, OpenBSD, FreeBSD, NetBSD, Dragonfly...
Enter fullscreen mode Exit fullscreen mode

Need to depend on some environment variables and user-given arguments? Still easy.

version = "0.3.0"

[scripts]
run.cmd = "execution command here with %ENV_VAR and %arg1"
run.args = [ "arg1" ]
run.env_vars = [ "ENV_VAR" ]
Enter fullscreen mode Exit fullscreen mode

How about adding all the arguments a user gives into one place? Even easier, just use %%.

version = "0.3.0"

[scripts]
run = "execution command here with %%"
Enter fullscreen mode Exit fullscreen mode

What if you've got multiple subprojects to build and you want to do it in a certain order with fallbacks? Bit long, but still easy.

version = "0.3.0"

[scripts]
build.subcommands.frontend = "build command here"
build.subcommands.backend = "build command here"
build.subcommands.update = "recovery command here"
build.order = """
frontend {
    Success => backend {
        Failure => update {
            Success => backend
        }
    },
    Failure => update {
        Success => frontend {
            Success => backend {
                Failure => update {
                    Success => backend
                }
            }
        }
    }
}
"""
Enter fullscreen mode Exit fullscreen mode

Yeah, you can do that. Take a look at the docs for more, like taking user arguments, inserting environment variables, and using custom execution shells! All the examples above can be combined in just about any way you can think of!

Closing words

Bonnie is a command aliasing tool with straight-up superpowers, and I honestly think it can replace just about every use-case of Make for command aliasing. I strongly encourage you to try it out! Any suggestions are more than welcome, and please open an issue if you find any bugs or want to suggest some more features!

Top comments (2)

Collapse
 
pandademic profile image
Pandademic

nice job!

Collapse
 
arctic_hen7 profile image
arctic_hen7

Thanks!