Bonzai - Bonzai! Simple CLI Command Trees in Go

Overview

Bonzai! Simple CLI Command Trees in Go

Go Version GoDoc License Go Report Card

Bonzai command trees are unlike anything you've probably encountered so far, no getopt dashes (we kind of hate them), no ugly commander interface to learn, no 12637 lines of shell tab completion bloat to source before your command will complete, just well manicured nested-tab-complete-with-magical-aliases-enabled commands organized into rooted node trees for your command-line enjoyment. Your right-pinky will be particularly grateful.

Installation

🎉 Bonzai shamelessly requires Go 1.18+ 💋

  1. Install Go 1.18 and the tooling your require for it
  2. go install github.com/rwxrob/[email protected]
  3. import "github.com/rwxrob/bonzai"
  4. Consider using the template to get started

😎 Yes, we use the wonderful new generics within the filter subpackage.

Embedded Text or Web Docs FTW!

And, all the documentation for your command tree goes inside the binary (if you want). That's right. Portable, text or web-enabled "man" pages without the man page. You can use one of the composable interactive-color-terminal-sensing help documentation commands like cmd.Help that will easily marshal into JSON, or text, or well-styled HTML locally while enabling you to write your embedded docs in simplified CommonMark. Think "readthedocs" but without the Internet dependency. And if you don't want cmd.Help you don't need it. You can even write your own composable Bonzai command or pick from a rich ecosystem of embeddable Bonzai command trees available from anywhere on the Internet or maintained by the Bonzai project. No registries to worry about. Just use good 'ol Go module imports are all that are need to share your creations.

Contributors/PRs Welcome

... especially for "Completers" and Runtime Detection.

Speaking of sharing, why not send a PR for your addition to the ever growing collection of comp subpackage Completers for everything from days of the week, to tab-driven inline math calculations, to a list of all the listening ports running on your current system.

CONTRIBUTING

"It's spelled bonsai/banzai."

We know. The domains were taken. Plus, this makes it more unique and easier to find once you know the strange spelling we chose to use. Sorry if that triggers your OCD.

On a lighter note, it just so happens that "banzai" means 'a traditional Japanese idiom meaning "ten thousand years" of long life,' a cheer used in celebrations. So combining the notion of a happy, little, well-manicured, beautiful tree and "ten thousand years of long life" works out just fine for us.

Then, of course, there's the image of Buckaroo invoked every time we say the name. In fact, I think we have our new theme song.

What People Are Saying

"It's like a modular, multicall BusyBox builder for Go with built in completion and embedded documentation support."

"The utility here is that Bonzai lets you maintain your own personal 'toolbox' with built in auto-complete that you can assemble from various Go modules. Individual commands are isolated and unaware of each other and possibly maintained by other people." (tadasv123)

Example GitHub Template

https://github.com/rwxrob/bonzai-template

Design Considerations

  • Promote high-level package library API calls over Cmd bloat. Code belongs in package libraries, not Cmds. While Bonzai allows for rapid applications development by putting everything initially in Cmd Methods, Cmds are most designed for documentation and completion, not heavy Method implementations. Eventually, most Method implementations should be moved into their own package libraries, perhaps even in the same Go module. Cmds should never be communicating with each other directly. While the idea of adding a Channel attribute was intriguing, it quickly became clear that doing so would promote too much code and tight coupling --- even with channels --- between specific commands. Cmds should be very light. In fact, most Cmds should assign their Method directly from one matching the Method function signature in a callable, high-level library.

Acknowledgements

The https://twitch.tv/rwxrob community has been constantly involved with the development of this project, making suggestions about everything from my use of init, to the name "bonzai". While all their contributions are too numerous to name specifically, they more than deserve a huge thank you here.

Legal

Copyright 2022 Robert S. Muhlestein (mailto:[email protected])
Licensed under Apache-2.0

"Bonzai" and "bonzai" are legal trademarks of Robert S. Muhlestein but can be used freely to refer to the cmdbox project https://github.com/rwxrob/bonzai without limitation. To avoid potential developer confusion, intentionally using these trademarks to refer to other projects --- free or proprietary --- is prohibited.

Comments
  • Add support for embedded Description

    Add support for embedded Description

    Now that embed is fully supported and rather mature it makes sense to begin maintaining the documentation that goes into the Description fields in its own text/template. As such, breaking out the Other sections makes less sense. I propose adding support for double-hashtag Markdown headings that signal the creation of a new headings (forced to upper case when rendered). We should also deprecate use of Other in general because it is only supported when displaying main help, and not itemized.

    Note that this is a change to the help.Cmd and the bonzai/z.Mark* stuff together.

    opened by rwxrob 1
  • Add Cmd.AutoUpdate

    Add Cmd.AutoUpdate

    Should look at Version detect an VERSION file within the Source URL location making intelligent decisions about the Source URL expansion required by the hosting service (github.com, for example). If not VERSION file is found and the service is github.com use the GitHub API to determine the latest release. It is important that there be no dependency on Git for checking for a latest version allowing distribution of binaries to take place on a simple web server with a VERSION file next to the binaries.

    opened by rwxrob 1
  • Bonzai Always Returns a Runtime Error

    Bonzai Always Returns a Runtime Error

    Hello Rob

    There seems to be a problem with the newest version of Bonsai where 2022/11/27 23:43:52 runtime error: index out of range [1] with length 1 is always reported by the runtime.

    Steps to reproduce:

    1. Create new Bonsai tree like so
    package main
    
    import (
    	Z "github.com/rwxrob/bonzai/z"
    	"log"
    )
    
    var Cmd = &Z.Cmd {
    	Name: `j`,
    	Description: `
    		Blank
    		`,
    
    	Commands: []*Z.Cmd {
    		HelloCmd,
    	},
    }
    
    var HelloCmd = &Z.Cmd {
    	Name: `hello`,
    
    	Call: func(_ *Z.Cmd, args ...string) error {
    		name := args[0]
    		log.Printf("Hello, %v!\n", name)
    		return nil
    	},
    
    }
    
    
    func main() {
    
    
    	Cmd.Run()
    }
    
    
    1. Build using go build .
    2. Get Error

    I was hoping you could solve this, because it is very annoying

    Regards, foehammer

    opened by foehammer127 0
  • Move arg count checks (NoArgs, etc.) *after* default command

    Move arg count checks (NoArgs, etc.) *after* default command

    Since help accepts arguments having NoArgs on the base command that composes in help.Cmd doesn't allow those args to be picked up my help.Cmd.

    z version  (breaks and should not with NoArgs set)
    
    opened by rwxrob 0
  • Change Z.Aliases to Z.Shortcuts, add Cmd.Shortcuts

    Change Z.Aliases to Z.Shortcuts, add Cmd.Shortcuts

    Z.Aliases is a misnomer. They are shortcuts. Plus, by changing this we can move them into Cmd.Shortcuts so that they are relative to a given command. Keeping the two allows the developer creating the composite tree to add their own shortcuts as well as allowing branch developers to provide alternatives (foo var set <name> <value -> foo set <name> <value>).

    Note that shortcuts are different than aliases, which are simply other names for the current command itself. Shortcuts relate to all the commands under that command.

    opened by rwxrob 0
  • Add Z.Dynamic package global

    Add Z.Dynamic package global

    Need to be able to expand the template language of anything in a given Bonzai branch (Z package scope) rather than just for a given command. This way the following will overwrite in layers with the last one winning:

    1. Z builtins (indent, cmd, pre, exename, etc.)
    2. Z.Dynamic
    3. Cmd.Dynamic
    opened by rwxrob 0
  • Add

    Add "into" (`--`) operator

    The -- "into" operator (end of options in other shells) is the equivalent of a pipe in BonzaiShell. It signifies that one command has ended and that any output to os.Stdout should be redirected into a buffer and set as the last argument to the command immediately following the "into" operator. This is the exact behavior of text/template when adding FuncMap functions that take piped input and should feel normal to any Go programmer who has worked with templates.

    We cannot use the actual pipe operator (|) because it would have to be quoted or escaped constantly (like find command requires). By using -- the hosting shell (if there is one) will ignore it. And since we are doing our own argument parsing (and not using getopt) use of -- is fine. In fact, because -- does have special meaning to getopt we can purposefully ensure that no Bonzai command ever adds getopt (since technically it could be added now). This conflict, therefore, has a purpose.

    opened by rwxrob 0
  • Factor out comp.Standard and comp.File

    Factor out comp.Standard and comp.File

    These need to be their own repos:

    • https://github.com/rwxrob/comp-cmd
    • https://github.com/rwxrob/comp-file

    There should be another base template repo created for creating your own completers:

    • https://github.com/rwxrob/comp-template

    We really want to make it drop-dead easy to create your own bonzai.Completers so we can jump start the ecosystem of completions. Writing a completer is a great first Go programming experience and potentially much more entertaining than the others.

    Also, by breaking completers out into their own repos we are more likely to get people making their own FOSS contributions because they get all the credit since they made the repo.

    opened by rwxrob 0
  • Add standard FuncMap with indent, etc.

    Add standard FuncMap with indent, etc.

    The mergeFuncs function should make a number of easy to use template functions available to Bonzai developers, all of which can be overridden by whatever they assign to Cmd.Dynamic.

    opened by rwxrob 0
  • Add Cmd.Cache and bonzai.Cache interface

    Add Cmd.Cache and bonzai.Cache interface

    We need a way to set a cached variable persistence engine for the entire Bonzai binary executable (like with Conf). The https://github.com/rwxrob/cache bonzai branch and pkg lib is being created as first example implementation.

    opened by rwxrob 0
  • Change Cmd.Get* methods to render as template

    Change Cmd.Get* methods to render as template

    Since we have added the entire bonzai.Command interface might as well take advantage of all those method calls to support text/template replacements of any of the resulting values, starting with GetDescription. This would mean that the Cmd.Description (in this case) is the raw template string. And GetDescription would have the template filled in. This will require reworking the help.Cmd as well but will provide very dynamic documentation possibilities.

    opened by rwxrob 0
  • Explore use of reflection to populate `Summary` and `Description` automatically

    Explore use of reflection to populate `Summary` and `Description` automatically

    Now that embed is the conventional way to add documentation to commands, it makes sense to explore ways to put all the documentation for a given command into a single file within the desc directory. In fact, where it is stored does matter, we simply have to use Reflect to look for a string that matches the name of the command.

    //go:embed desc/foo.md
    var fooCmdDoc string
    
    var fooCmd := &Z.Cmd{
      // ...
    }
    
    

    The performance hit from using Reflect is minimal for this type of operation since it is only to display help and would not affect anything else being called dynamically from the help command itself.

    The use of docs should, however, be discouraged since it is used for other things like KEG and GitHub pages sites.

    opened by rwxrob 0
  • Add support for backticks now that embed is preferred

    Add support for backticks now that embed is preferred

    Previously, backticks in Markdown for Description would conflict with the multi-line string backticks required for Go, but now that adding such things in desc/help.md file is preferred, such is no longer needed.

    opened by rwxrob 0
  • bonzai does not work when pyenv in $PATH

    bonzai does not work when pyenv in $PATH

    Hi, thanks for your work and streams. Bonzai is an excellent idea and I am planning to move my scritps as well to it after I understand how to use it.

    I have pyenv on my environment, running any bonzai command that calls a help command fails with pyenv: no such command "tmp/hlpe-XXXXX"

    If I remove pyenv from my $PATH bonzai help command works. Why would the pyenv executable be called ? I never encountered this issue.

    Is there a way to traceback command exection ? I am willing to fix it if I can the debug the call. strace was not helpfulp.

    It should be easy to reproduce by just installing pyenv. The bug happen under any shell (bash, zsh, fish ...)

    Thanks.

    opened by blob42 2
  • Add `more` detection for Windows

    Add `more` detection for Windows

    Windows doesn't follow any of the normal pager conventions, but should be able to find more on the system for it. Detecting the pager will also cover the problem with command-line dos prompts not doing color since piping to more disables all color.

    opened by rwxrob 0
Owner
Rob Muhlestein
Infrastructure Engineer / Software Developer • Cloud Native • Professional Mentor • Streamer
Rob Muhlestein
git-xargs is a command-line tool (CLI) for making updates across multiple Github repositories with a single command.

Table of contents Introduction Reference Contributing Introduction Overview git-xargs is a command-line tool (CLI) for making updates across multiple

Gruntwork 713 Dec 31, 2022
git-xargs is a command-line tool (CLI) for making updates across multiple GitHub repositories with a single command

git-xargs is a command-line tool (CLI) for making updates across multiple GitHub repositories with a single command. You give git-xargs:

Maxar Infrastructure 1 Feb 5, 2022
Package command provide simple API to create modern command-line interface

Package command Package command provide simple API to create modern command-line interface, mainly for lightweight usage, inspired by cobra Usage pack

chenen 0 Jan 16, 2022
Watcher - A simple command line app to watch files in a directory for changes and run a command when files change!

Watcher - Develop your programs easily Watcher watches all the files present in the directory it is run from of the directory that is specified while

Geet Sethi 1 Mar 27, 2022
Soren L. Hansen 1.7k Jan 3, 2023
A simple way for CLI command to have many subcommands

subcommands This is a modified fork of google/subcommands that uses lucasepe/pflag Subcommands is a Go package that implements a simple way for a sing

Luca Sepe 0 Oct 12, 2021
cli is a simple, fast, and fun package for building command line apps in Go.

cli cli is a simple, fast, and fun package for building command line apps in Go. The goal is to enable developers to write fast and distributable comm

凹语言 2 Jul 10, 2022
A simple library to build golang command line (cli / cmd)apps

A simple library to build golang command line (cli / cmd)apps

seastart dev team 0 Jan 11, 2022
bluemonday-cli is a simple command-line interface to bluemonday

bluemonday-cli bluemonday-cli is a simple command-line interface to bluemonday. We've configured bluemonday for ROVR's specific requirements. It reads

ROVR Labs 0 Jan 24, 2022
News-parser-cli - Simple CLI which allows you to receive news depending on the parameters passed to it

news-parser-cli Simple CLI which allows you to receive news depending on the par

Maxym 0 Jan 4, 2022
An open-source GitLab command line tool bringing GitLab's cool features to your command line

GLab is an open source GitLab CLI tool bringing GitLab to your terminal next to where you are already working with git and your code without switching

Clement Sam 2.1k Dec 30, 2022
This is a command that simply prints "ok" onto your screen whenever you run the "ok" command

ok This is a command that simply prints "ok" onto your screen whenever you run the ok command Installation (Linux) Download the latest release and sud

ErrorNoInternet 7 Sep 16, 2022
Brigodier is a command parser & dispatcher, designed and developed for command lines such as for Discord bots or Minecraft chat commands. It is a complete port from Mojang's "brigadier" into Go.

brigodier Brigodier is a command parser & dispatcher, designed and developed to provide a simple and flexible command framework. It can be used in man

Minekube 16 Dec 15, 2022
A command line tool that builds and (re)starts your web application everytime you save a Go or template fileA command line tool that builds and (re)starts your web application everytime you save a Go or template file

# Fresh Fresh is a command line tool that builds and (re)starts your web application everytime you save a Go or template file. If the web framework yo

null 0 Nov 22, 2021
A command line tool for simplified docker volume command built with go

dockervol A command line tool for simplified docker volume command built with go. Features: Remove anonymous volume (beta) Remove volume by matching n

Moh Achun Armando 0 Dec 18, 2021
A command line tool to prompt for a value to be included in another command line.

readval is a command line tool which is designed for one specific purpose—to prompt for a value to be included in another command line. readval prints

Venky 0 Dec 22, 2021
Hasura-fzf - This command has a fzf-like UI that allows you to find and run the file version used by the hasura command

hasura-fzf This command has a fzf-like UI that allows you to find and run the fi

Shoki Hata 5 Sep 29, 2022
CLI - A package for building command line app with go

Command line interface Screenshot Key features Lightweight and easy to use. Defines flag by tag, e.g. flag name(short or/and long), description, defau

王仕晋 678 Dec 23, 2022
Golang library with POSIX-compliant command-line UI (CLI) and Hierarchical-configuration. Better substitute for stdlib flag.

cmdr cmdr is a POSIX-compliant, command-line UI (CLI) library in Golang. It is a getopt-like parser of command-line options, be compatible with the ge

hz 116 Oct 28, 2022