Remove Z.Shortcuts

pull/97/head
rwxrob 2 years ago
parent a29bdb8c54
commit 1198faaa5d
No known key found for this signature in database
GPG Key ID: 2B9111F33082AE77

@ -1,194 +1,4 @@
# 🌳 Go Bonzai™ Command Compositor
[![GoDoc](https://godoc.org/github.com/rwxrob/bonzai?status.svg)](https://godoc.org/github.com/rwxrob/bonzai)
[![License](https://img.shields.io/badge/license-Apache2-brightgreen.svg)](LICENSE)
[![Go Report
Card](https://goreportcard.com/badge/github.com/rwxrob/bonzai)](https://goreportcard.com/report/github.com/rwxrob/bonzai)
Meticulously manicured monolith and multicall binaries, built from
imported composite commands, on *any* device, with recursive,
light-weight tab completion, and colorful, rendered-templated
documentation from terminal or local web browser. Replace messy
collections of shell scripts ported to clean Go code and compiled into a
single, portable command.
## 🤚 TL;DR; 🛑
Check/clone sample `foo` template:
👆 <https://github.com/rwxrob/bonzai-example>
Study the `z` monolith/multicall that started it all:
👆 <https://github.com/rwxrob/z>
![logo](logo.png)
## Installation
🎉 ***Bonzai shamelessly requires Go 1.18+*** 💋
1. Install Go 1.18 and the tooling your require for it
1. `go install github.com/rwxrob/bonzai@latest`
1. `import Z "github.com/rwxrob/bonzai"`
1. Consider using the [template][] to get started
[template]: <https://github.com/rwxrob/bonzai-example>
😎 *Yes, we use the wonderful new generics all [over](fn).* 👍
## Welcome to Bonzai
Yes, "banzai" is something people yell going into battle. But isn't
that what making command line utilities in Go (instead of your favorite
shell script) actually is?
And yes, "bonsai" trees are well-manicured, meticulously crafted,
miniature trees that rival their larger cousins, just like Bonzai
command and data node trees. They 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.
But wait, there's more! What about all those other tasks you need to do
to make a command line application honorable in anyone's eyes? Tools are
needed.
## Contributors/PRs Welcome
*... especially for "Completers", included popular commands, 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](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.
If you must know, the primary motivator was the similarity to a
well-manicured tree (since it is for creating trees of composite
commands).
The misunderstood word "banzai" is 'a traditional Japanese idiom
meaning "ten thousand years" of long life,' a cheer used in
celebrations like "Hurrah" or "Viva".' So combining the notion of a
happy, well-manicured, beautiful tree and "ten thousand years of
long life" works out just fine for us.
And, yes, Buckaroo Banzai was always a favorite. We like to think he
would use Bonzai today to make amazing things and last for a long time
to defeat evil aliens and save the world.
It turns out that the "call to war" associated with Bonzai is not
entirely without merit as well. Bonzai is excellent for unorthodox,
rapid applications development (instead of writing scripts) and makes
short work of creating offensive and defensive tool kits all wrapping
into one nice Go multicall binary, popular for building single-binary
Linux container distros like BusyBox and Alpine, as well as root kits,
and other security tools
## "Why not just use Cobra?"
Just because something is popular (or first) doesn't mean it was well
designed. In fact, often inferior designs are rushed to market just to
gain adoption. Cobra seems to suffer from this. Discerning developers
and engineers have been not-so-quietly complaining about Cobra's
horrible design for years. It's time for something new. Read on if you
want the specific reasons.
* **Cobra tab completion is wasteful and error-prone.**
Cobra often requires sourcing thousands of lines of shell code every
time you run a new shell that needs to use a Cobra command with shell
tab completion (`kubectl` requires 12637). It is not uncommon for
operations people to be sourcing 100s of thousands of lines of shell
code just to enable basic completion that could have been enabled
easily with `complete -C` instead. Bonzai manages all completion in Go
instead of shell and therefore allows the modular addition of any
number of Completers including the standard file completion as well as
calculators, dates, and anything anyone can conceive of completing.
Completion is not dependent on any underlying operating system. Any
Bonzai command can provide its own completion algorithm or use one of
the many already provided. Cobra can never do this.
* **Cobra is not designed to be a command compositor at all.**
This is really unfortunate because the designers missed a golden
opportunity. Bonzai branches can be imported and composed into other
branches and monoliths with just a few lines of Go. Registries of
Bonzai commands can be easily inferred from dependencies on the
`bonzai` package and creators are free to compose their monoliths or
multicall binaries from a rich eco-system of Bonzai branches and
commands. Bonzai allows creation of Go multicall binary monoliths
(like BusyBox) to be made easily, and from a diverse, modular,
importable, composable sources. Such is simply not possible with Cobra
and never will be.
* **Cobra suffers from broken boomer "getopt" design.**
The world if finally realizing how bad dashed arguments and options
have always been for *good* human-computer interactions from the
command line, perhaps because more people are using chat interfaces as
their command line. People simply cannot remember all sorts of ungodly
combinations of dashes and equals signs hoping things will
just work. Bonzai takes a no-dashes approach with aliases promoting
cleaner, understandable command lines with context and promotion of
domain specific languages (created with PEGN, scan.X, or others) that
easily translate directly to chat and other command-line interfaces
that most humans can use without even looking up the documentation,
which, by the way, is embedded in any Bonzai command tree.
* **Cobra provides bad, brittle, command documentation.**
Cobra documentation is virtually unreadable in source form. And Cobra
provides no means of markup or use of color and doesn't even promote
the same look and feel of manual page documentation. In contrast,
Bonzai has its own subset of Markdown, BonzaiMark, respects the well
established readability of manual pages, and allows for the creation
of elegant documentation that can be viewed from the command line or
easily from a local browser on the same computer running the command.
Bonzai command documentation is as easy to read in source form as the
documentation itself.
* **Cobra suffers from crushing technical debt.**
The problems listed (and more) are never going to come out of Cobra.
Because it is filled with bad design decisions and was rushed to
market without serious consideration for its API, it is now doomed to
never lose its warts (kinda like JavaScript). There is no possible way
it can ever upgrade to address the very reasonable modern expectations
for good command line user experiences. No wonder you never see people
using Cobra for their replace-my-shell-scripts utilities. Cobra is
simply horrible for this. Thankfully, Bonzai is a fresh, extensible,
sustainable, human-friendly command compositor to take us into the
future of command line interfaces.
## 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)
## Examples
* <https://github.com/rwxrob/bonzai-example> - clone-able GitHub template
* <https://github.com/rwxrob/z> - first Bonzai command tree ever made
## Design Considerations
# Design Considerations
* **Promote high-level package library API calls over Cmd bloat**
@ -442,6 +252,13 @@ want the specific reasons.
why the full `v1.0` is not expected until December 25th 2022, some
months after things should feel settled and finished).
* **Move package global Aliases/Shortcuts into Cmd**
In Cmd they can be documented. They also tend to be long and eat up
too much of the command line when using them with completion. Better
to just have them in the help docs to lookup when the full path is
wanted.
## Style Guidelines
* Use "deciduous tree" emoji 🌳 to mark Bonzai stuff

@ -291,8 +291,8 @@ func ArgsOrIn(args []string) string {
}
// ArgMap is a map keyed to individual arguments that should be
// expanded by being replaced with the slice of strings. Z.Aliases and
// Cmd.Shortcuts are both ArgMaps.
// expanded by being replaced with the slice of strings. See
// Cmd.Shortcuts.
type ArgMap map[string][]string
// Keys returns only the key names.
@ -304,15 +304,6 @@ func (m ArgMap) Keys() []string {
return list
}
// Shortcuts allows Bonzai tree developers to create single-word
// shortcuts (similar to shell aliases) that are directly translated
// into arguments to the Bonzai tree executable by overriding the
// os.Args in a controlled way. The value of a shortcut is always a slice
// of strings that will replace the os.Args[2:]. A slice is used
// (instead of a string parsed with strings.Fields) to ensure that
// hard-coded arguments containing whitespace are properly handled.
var Shortcuts = make(ArgMap)
// AllowPanic disables TrapPanic stopping it from cleaning panic errors.
var AllowPanic = false

@ -244,17 +244,6 @@ func (x *Cmd) Run() {
x.cacheSections()
// resolve Z.Shortcuts (if completion didn't replace them)
if len(os.Args) > 1 {
args := []string{os.Args[0]}
alias := Shortcuts[os.Args[1]]
if alias != nil {
args = append(args, alias...)
args = append(args, os.Args[2:]...)
os.Args = args
}
}
// COMPLETION
line := os.Getenv("COMP_LINE")
@ -263,9 +252,6 @@ func (x *Cmd) Run() {
// find the leaf command
lineargs := ArgsFrom(line)
if len(lineargs) == 2 {
list = append(list, maps.KeysWithPrefix(Shortcuts, lineargs[1])...)
}
cmd, args := x.Seek(lineargs[1:])
// default completer or package aliases, always exits
@ -273,13 +259,6 @@ func (x *Cmd) Run() {
if Comp != nil {
list = append(list, Comp.Complete(cmd, args...)...)
}
if len(list) == 1 && len(lineargs) == 2 {
if v, has := Shortcuts[list[0]]; has {
fmt.Println(strings.Join(EscAll(v), " "))
Exit()
return
}
}
each.Println(list)
Exit()
return
@ -503,7 +482,7 @@ func (x *Cmd) Seek(args []string) (*Cmd, []string) {
if v, has := cur.Shortcuts[args[n]]; has {
nargs := v
nargs = append(nargs, args[n+1:]...)
return cur.Seek(EscAll(nargs))
return cur.Seek(nargs)
}
}
return cur, args[n:]

Loading…
Cancel
Save