Change import name to Z from bonzai

pull/53/head v0.0.40
rwxrob 2 years ago
parent d2bf3d6342
commit 2e15af3bf4
No known key found for this signature in database
GPG Key ID: 2B9111F33082AE77

@ -10,8 +10,6 @@ sense of how it's coming along and how to use until the 1.0 release.
> Or, you can get started right away by cloning/forking [the sample
`foo` template repo](https://github.com/rwxrob/foo)
🚧 *under construction* 🚧
[![Go Version](https://img.shields.io/github/go-mod/go-version/rwxrob/bonzai)](https://tip.golang.org/doc/go1.18)
[![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)
@ -24,7 +22,7 @@ Card](https://goreportcard.com/badge/github.com/rwxrob/bonzai)](https://goreport
1. Install Go 1.18 and the tooling your require for it
1. `go install github.com/rwxrob/bonzai@latest`
1. `import "github.com/rwxrob/bonzai"`
1. `import Z "github.com/rwxrob/bonzai"`
1. Consider using the [template][] to get started
[template]: <https://github.com/rwxrob/bonzai-template>
@ -49,7 +47,7 @@ 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.
needed.
## Contributors/PRs Welcome
@ -70,22 +68,26 @@ 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 commands). And
Buckaroo Banzai was always a favorite. We like to think he would use
Bonzai today to make amazing things.
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.
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.
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 makes short work of creating
offensive and defensive tool kits all wrapping into one nice Go binary,
popular for building single-binary Linux container distros (like BusyBox
and Alpine, watch for Bonzai Linux soon), as well as root kits, and
other security tools
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?"
@ -93,58 +95,75 @@ 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.
Cobra requires wasteful and error-prone sourcing of thousands of lines
of shell code every time you create 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.
Corba is also not designed to be a command compositor at all, which is
really unfortunate because they missed a golden opportunity there.
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 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 buys into the broken boomer "getopt" view of the world requiring
people to remember all sorts of ungodly different combinations of dashes
and equals signs hoping things will just work. Bonzai takes a no-dashes
approach promoting much cleaner 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 for
most humans without much need to look up the documentation, which, by
the way, is embedded in the Bonzai command tree.
Cobra provides minimal, unappealing command documentation that 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. 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. And the source containing the
documentation is as easy to read as the documentation itself.
In short, Cobra got us a long way, but has proved to be so laden with
crushing technical debt from failed base design decisions that it simply
is not sustainable given current modern expectations for good user
interfaces and documentation. Bonzai is a fresh, extensible,
sustainable, human-friendly command compositor to take us into the
future of command line interfaces, for everyone.
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.
* **Corba 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
@ -156,9 +175,10 @@ future of command line interfaces, for everyone.
> various Go modules. Individual commands are isolated and unaware of
> each other and possibly maintained by other people." (tadasv123)
## Example GitHub Template
## Examples
<https://github.com/rwxrob/foo>
* <https://github.com/rwxrob/foo> - clone-able GitHub template
* <https://github.com/rwxrob/z> - first Bonzai command tree ever made
## Design Considerations
@ -180,7 +200,7 @@ future of command line interfaces, for everyone.
undesirable tight coupling --- even with channels --- between
specific commands.
* **Cmds should be very light.**
* **Cmds should be very light.**
Most Cmds should assign their first-class Call function to one that
lightly wraps a similar function signature in a callable, high-level
@ -201,7 +221,7 @@ future of command line interfaces, for everyone.
completers and composable commands that carry their own completion
logic. This one objective fact alone should give everyone pause before
opting to use one of these inferior shells for their command line
interactions.
interactions.
Bonzai commands leverage this best-of-breed completion functionality
of bash to provide an unlimited number of completion methods and
@ -214,11 +234,11 @@ future of command line interfaces, for everyone.
shortcut aliases when completion is not available (h|help, for
example).
* **Bonzai commands may default to `shell.Cmd` or `help.Cmd`**
* **Bonzai commands may default to `shell.Cmd` or `help.Cmd`**
These provide help information and optional interactive assistance
including tab completion in runtime environments that do not have
`complete -C foo foo` enabled.
`complete -C foo foo` enabled.
*shell.Cmd is still under development and likely will be for a while*
@ -248,6 +268,28 @@ future of command line interfaces, for everyone.
alias the packages as needed using Go's excellent package import
design.
* **Use capital "Z" import name.**
People can easily change the default "Z" import name to whatever else
if they don't like it (or worse, if has conflicts). But, we actually
want naming conflicts even though this seems counter-intuitive.
Developers should be putting most of their code into their own `pkg`
libraries and calling into them from their wrapping Bonzai trees and
branches that import Z. If someone is importing Z into their package
library they are likely doing something they shouldn't. Bonzai should
*only* be imported into the composable branch or standalone command
(`main`). This is a reminder as well to Bonzai developers not to stuff
things into the Z package that would never be used outside a Bonzai
command, tree or `main.go` standalone.
* **Promote lower "z" personal Bonzai trees.**
Just as "dotfiles" has become a convention, use of the simple "z"
GitHub repo should be promoted as a common, "ez" way to find people's
personal monoliths. Obviously, people can use what they want. This is
also consistent with the capital "Z" import name of the `bonzai`
package.
## Style Guidelines
* Everything through `go fmt` or equiv, no exceptions
@ -258,6 +300,7 @@ future of command line interfaces, for everyone.
* Package globals that will be used a lot can be single capital
* Must be good reason to use more than 4 character pkg name
* Avoid unnecessary comments
* Use "deciduous tree" emoji 🌳 to mark Bonzai branches and commands
## Acknowledgements
@ -279,3 +322,19 @@ can be used freely to refer to the Bonzai™ 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.
## TODO
Here is a list of major things that are still needed before a v1.0
release:
* Complete default `help.Cmd`
* Complete `bonzai` helper command
* Initialize new branch including optional GitHub repo creation
* Vet a branch repo for orphan commands, etc.
* Cache/search list of package depending on `bonzai` as registry
* Complete final art
* Large logo for landing page
* Small logo for lists
* Animated emote suitable for Twitch
* Create a Bonzai™ merch outlet

@ -2,7 +2,7 @@
// SPDX-License-Identifier: Apache-2.0
/*
Package bonzai provides a rooted node tree of commands and singular
Package Z (bonzai) provides a rooted node tree of commands and singular
parameters making tab completion a breeze and complicated applications
much easier to intuit without reading all the docs. Documentation is
embedded with each command removing the need for separate man pages and
@ -18,7 +18,7 @@ following types of nodes:
* Parameters, single words that are passed to a leaf command
*/
package bonzai
package Z
import (
"fmt"
@ -28,6 +28,7 @@ import (
"strings"
config "github.com/rwxrob/config/pkg"
"github.com/rwxrob/fn"
"github.com/rwxrob/fs/file"
"github.com/rwxrob/term"
)
@ -243,3 +244,26 @@ func ArgsOrIn(args []string) string {
// strings.Fields) to ensure that hard-coded arguments containing
// whitespace are properly handled.
var Aliases = make(map[string][]string)
// EscThese is set to the default UNIX shell characters which require
// escaping to be used safely on the terminal. It can be changed to suit
// the needs of different host shell environments.
var EscThese = " \r\t\n|&;()<>![]"
// Esc returns a shell-escaped version of the string s. The returned value
// is a string that can safely be used as one token in a shell command line.
func Esc(s string) string {
var buf []rune
for _, r := range s {
for _, esc := range EscThese {
if r == esc {
buf = append(buf, '\\')
}
}
buf = append(buf, r)
}
return string(buf)
}
// EscAll calls Esc on all passed strings.
func EscAll(args []string) []string { return fn.Map(args, Esc) }

@ -1,18 +1,18 @@
// Copyright 2022 Robert S. Muhlestein.
// SPDX-License-Identifier: Apache-2.0
package bonzai_test
package Z_test
import (
"fmt"
"os"
"github.com/rwxrob/bonzai"
Z "github.com/rwxrob/bonzai"
)
func ExampleArgsFrom() {
fmt.Printf("%q\n", bonzai.ArgsFrom(`greet hi french`))
fmt.Printf("%q\n", bonzai.ArgsFrom(`greet hi french `))
fmt.Printf("%q\n", Z.ArgsFrom(`greet hi french`))
fmt.Printf("%q\n", Z.ArgsFrom(`greet hi french `))
// Output:
// ["greet" "hi" "french"]
// ["greet" "hi" "french" ""]
@ -24,7 +24,7 @@ func ExampleArgsOrIn_read_Nil() {
defer func() { os.Stdin = orig }()
os.Stdin, _ = os.Open(`testdata/in`)
fmt.Println(bonzai.ArgsOrIn(nil))
fmt.Println(Z.ArgsOrIn(nil))
// Output:
// some thing
@ -36,7 +36,7 @@ func ExampleArgsOrIn_read_Zero_Args() {
defer func() { os.Stdin = orig }()
os.Stdin, _ = os.Open(`testdata/in`)
fmt.Println(bonzai.ArgsOrIn([]string{}))
fmt.Println(Z.ArgsOrIn([]string{}))
// Output:
// some thing
@ -44,8 +44,23 @@ func ExampleArgsOrIn_read_Zero_Args() {
func ExampleArgsOrIn_args_Joined() {
fmt.Println(bonzai.ArgsOrIn([]string{"some", "thing"}))
fmt.Println(Z.ArgsOrIn([]string{"some", "thing"}))
// Output:
// some thing
}
func ExampleEsc() {
fmt.Println(Z.Esc("|&;()<>![]"))
fmt.Printf("%q", Z.Esc(" \n\r"))
// Output:
// \|\&\;\(\)\<\>\!\[\]
// "\\ \\\n\\\r"
}
func ExampleEscAll() {
list := []string{"so!me", "<here>", "other&"}
fmt.Println(Z.EscAll(list))
// Output:
// [so\!me \<here\> other\&]
}

@ -1,7 +1,7 @@
// Copyright 2022 Robert S. Muhlestein.
// SPDX-License-Identifier: Apache-2.0
package bonzai
package Z
import (
"fmt"
@ -75,7 +75,7 @@ func (x *Cmd) Run() {
x.cacheAliases()
// resolve bonzai.Aliases (if completion didn't replace them)
// resolve Z.Aliases (if completion didn't replace them)
if len(os.Args) > 1 {
args := []string{os.Args[0]}
alias := Aliases[os.Args[1]]

@ -1,22 +1,22 @@
// Copyright 2022 Robert S. Muhlestein.
// SPDX-License-Identifier: Apache-2.0
package bonzai_test
package Z_test
import (
"fmt"
"os"
"github.com/rwxrob/bonzai"
Z "github.com/rwxrob/bonzai"
"github.com/rwxrob/bonzai/inc/help"
)
func ExampleCmd_Seek() {
hello := &bonzai.Cmd{
hello := &Z.Cmd{
Name: `hello`,
Params: []string{"there"},
Call: func(_ *bonzai.Cmd, args ...string) error {
Call: func(_ *Z.Cmd, args ...string) error {
if len(args) > 0 {
fmt.Printf("hello %v\n", args[0])
return nil
@ -26,10 +26,10 @@ func ExampleCmd_Seek() {
},
}
hi := &bonzai.Cmd{
hi := &Z.Cmd{
Name: `hi`,
Params: []string{"there", "ya"},
Call: func(_ *bonzai.Cmd, args ...string) error {
Call: func(_ *Z.Cmd, args ...string) error {
if len(args) > 0 {
fmt.Printf("hi %v\n", args[0])
return nil
@ -39,18 +39,18 @@ func ExampleCmd_Seek() {
},
}
yo := &bonzai.Cmd{
yo := &Z.Cmd{
Name: `yo`,
Call: func(x *bonzai.Cmd, args ...string) error {
Call: func(x *Z.Cmd, args ...string) error {
fmt.Println("yo")
return nil
},
}
salut := &bonzai.Cmd{
salut := &Z.Cmd{
Name: `salut`,
Params: []string{"la"},
Call: func(_ *bonzai.Cmd, args ...string) error {
Call: func(_ *Z.Cmd, args ...string) error {
if len(args) > 0 {
fmt.Printf("salut %v\n", args[0])
return nil
@ -60,30 +60,30 @@ func ExampleCmd_Seek() {
},
}
french := &bonzai.Cmd{
french := &Z.Cmd{
Name: `french`,
Aliases: []string{"fr"},
Commands: []*bonzai.Cmd{help.Cmd, salut},
Commands: []*Z.Cmd{help.Cmd, salut},
}
greet := &bonzai.Cmd{
greet := &Z.Cmd{
Name: `greet`,
Commands: []*bonzai.Cmd{help.Cmd, yo, hi, hello, french},
Commands: []*Z.Cmd{help.Cmd, yo, hi, hello, french},
}
cmd, args := greet.Seek(bonzai.ArgsFrom(`hi there`))
cmd, args := greet.Seek(Z.ArgsFrom(`hi there`))
fmt.Printf("%v %q\n", cmd.Name, args)
cmd, args = greet.Seek(bonzai.ArgsFrom(`french salut`))
cmd, args = greet.Seek(Z.ArgsFrom(`french salut`))
fmt.Printf("%v %q\n", cmd.Name, args)
cmd, args = greet.Seek(bonzai.ArgsFrom(`french salut `))
cmd, args = greet.Seek(Z.ArgsFrom(`french salut `))
fmt.Printf("%v %q\n", cmd.Name, args)
cmd, args = greet.Seek(bonzai.ArgsFrom(`french h`))
cmd, args = greet.Seek(Z.ArgsFrom(`french h`))
fmt.Printf("%v %q\n", cmd.Name, args)
cmd, args = greet.Seek(bonzai.ArgsFrom(`french help`))
cmd, args = greet.Seek(Z.ArgsFrom(`french help`))
fmt.Printf("%v %q\n", cmd.Name, args)
// Output:
@ -95,7 +95,7 @@ func ExampleCmd_Seek() {
}
func ExampleCmd_CmdNames() {
foo := new(bonzai.Cmd)
foo := new(Z.Cmd)
foo.Add("bar")
foo.Add("blah")
foo.Add("other")
@ -105,7 +105,7 @@ func ExampleCmd_CmdNames() {
}
func ExampleCmd_GetCommands() {
foo := new(bonzai.Cmd)
foo := new(Z.Cmd)
foo.Add("bar")
foo.Add("blah")
foo.Add("other")
@ -115,7 +115,7 @@ func ExampleCmd_GetCommands() {
}
func ExampleCmd_GetParams() {
foo := new(bonzai.Cmd)
foo := new(Z.Cmd)
foo.Params = []string{"box", "bing", "and"}
fmt.Println(foo.GetParams())
// Output:
@ -123,9 +123,9 @@ func ExampleCmd_GetParams() {
}
func ExampleCmd_Branch() {
bonzai.ExitOff()
Z.ExitOff()
z := new(bonzai.Cmd)
z := new(Z.Cmd)
c := z.Add("some")
//fmt.Print(z.Commands[0].Name)
c = c.Add("thing")
@ -133,7 +133,7 @@ func ExampleCmd_Branch() {
c = c.Add("deep")
//fmt.Print(z.Commands[0].Commands[0].Commands[0].Name)
c.Call = func(x *bonzai.Cmd, _ ...string) error {
c.Call = func(x *Z.Cmd, _ ...string) error {
fmt.Println(x.Branch())
return nil
}

@ -6,13 +6,13 @@ package comp_test
import (
"fmt"
"github.com/rwxrob/bonzai"
Z "github.com/rwxrob/bonzai"
"github.com/rwxrob/bonzai/comp"
"github.com/rwxrob/fn/filt"
)
func ExampleStandard() {
foo := new(bonzai.Cmd)
foo := new(Z.Cmd)
foo.Params = []string{"box"}
foo.Add("bar")
foo.Add("blah")

@ -1,7 +1,7 @@
// Copyright 2022 Robert S. Muhlestein.
// SPDX-License-Identifier: Apache-2.0
package bonzai
package Z
import (
"fmt"

@ -1,7 +1,7 @@
// Copyright 2022 Robert S. Muhlestein.
// SPDX-License-Identifier: Apache-2.0
package bonzai
package Z
import (
"os"

@ -1,14 +1,15 @@
module github.com/rwxrob/bonzai
module github.com/rwxrob/Z
go 1.18
require (
github.com/rwxrob/bonzai v0.0.39
github.com/rwxrob/config v0.3.1
github.com/rwxrob/fn v0.3.0
github.com/rwxrob/fs v0.4.2
github.com/rwxrob/fs v0.4.3
github.com/rwxrob/json v0.4.1
github.com/rwxrob/structs v0.5.0
github.com/rwxrob/term v0.1.4
github.com/rwxrob/term v0.1.5
golang.org/x/mod v0.5.1
)
@ -16,8 +17,8 @@ require (
github.com/rogpeppe/go-internal v1.8.1 // indirect
github.com/rwxrob/to v0.2.1 // indirect
github.com/rwxrob/y2j v0.3.1 // indirect
golang.org/x/crypto v0.0.0-20220321153916-2c7772ba3064 // indirect
golang.org/x/sys v0.0.0-20220328115105-d36c6a25d886 // indirect
golang.org/x/crypto v0.0.0-20220331220935-ae2d96664a29 // indirect
golang.org/x/sys v0.0.0-20220330033206-e17cdc41300f // indirect
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
)

@ -4,28 +4,30 @@ github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
github.com/rogpeppe/go-internal v1.8.1 h1:geMPLpDpQOgVyCg5z5GoRwLHepNdb71NXb67XFkP+Eg=
github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o=
github.com/rwxrob/bonzai v0.0.39 h1:EJ1aVVVwnm4mdPKJEeCLI3wVttgbD8ulggXKZiwEO4w=
github.com/rwxrob/bonzai v0.0.39/go.mod h1:PyKG44H68o3DZ2Xh6ouViGW9IAbYZVw0OYqLMdCM1RI=
github.com/rwxrob/config v0.3.1 h1:YwnPEuEFDZz7gD5ZJwYkYEF/oSjvM9ryXV6oK+aDvJc=
github.com/rwxrob/config v0.3.1/go.mod h1:aqV/tWGH+Tz2ciADZDDYoodAniZ2iQTm8WZNM0wRyCA=
github.com/rwxrob/fn v0.3.0 h1:R4kcZhInEc9Fn3lsWbn3O6ZOoZ/D43Y1l3SS5Nxm1wc=
github.com/rwxrob/fn v0.3.0/go.mod h1:omPqOqEB+dDna09z5pi5YFxq4IZqDvv3wFPUCES5LvY=
github.com/rwxrob/fs v0.4.2 h1:KXBs48us7rwkIAT05IMpKJ2AQNHLGBqHaqaCpXjrys0=
github.com/rwxrob/fs v0.4.2/go.mod h1:vO8AeluD7rnrO7zC54745xTEBFgHPUpHL0hbp1NnsVo=
github.com/rwxrob/fs v0.4.3 h1:ntu9TZnk7NHd1Yen+p4+xruBmkQMugKtFU0OLfAMa+M=
github.com/rwxrob/fs v0.4.3/go.mod h1:vO8AeluD7rnrO7zC54745xTEBFgHPUpHL0hbp1NnsVo=
github.com/rwxrob/json v0.4.1 h1:b4ToZe4mrQO8rRL/kRFglzZszyZZnGv6JRHj6jrI3f4=
github.com/rwxrob/json v0.4.1/go.mod h1:DU3TQKCWY4bK7sQ0wu80cRmTs96b6M//OYvT7Eg2mJA=
github.com/rwxrob/structs v0.5.0 h1:pjLsfyYHS+gB1CtzRj3H39wRYL4lI5pTpFf8kl91guw=
github.com/rwxrob/structs v0.5.0/go.mod h1:2gIte2ZI9zUok6q6F3v3l41ZXo7Zg5Kf1GUTP2+pXyQ=
github.com/rwxrob/term v0.1.4 h1:E49nmDAd7rwfjhled17RapP6RJP6T3a0NGIdW44WVAU=
github.com/rwxrob/term v0.1.4/go.mod h1:IVE7hG+VQlM4R+kS4pY6uhfMHoG0QECrZF7d7bKcdsk=
github.com/rwxrob/term v0.1.5 h1:jKvNgEYlsT6sLRqIuR9ITcNNh4woGkWxcAe71pPJReQ=
github.com/rwxrob/term v0.1.5/go.mod h1:IVE7hG+VQlM4R+kS4pY6uhfMHoG0QECrZF7d7bKcdsk=
github.com/rwxrob/to v0.2.1 h1:ZYBNEa8LJT5VDQUHm2wSwiRf61xSqU87UqbYvitV3eY=
github.com/rwxrob/to v0.2.1/go.mod h1:8qdgCWkh50Avs8sRpV6/P7lAQgVf3KLRSKMZahV/W48=
github.com/rwxrob/y2j v0.3.1 h1:qOCU7J6g0Q/7KlLAabCMLx6/wG1/NelG6QTOVpESAQg=
github.com/rwxrob/y2j v0.3.1/go.mod h1:/3eS+LPnOF1F2VfoqZr3Upkr8q4ByziAi3eB6FIgzoE=
golang.org/x/crypto v0.0.0-20220321153916-2c7772ba3064 h1:S25/rfnfsMVgORT4/J61MJ7rdyseOZOyvLIrZEZ7s6s=
golang.org/x/crypto v0.0.0-20220321153916-2c7772ba3064/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.0.0-20220331220935-ae2d96664a29 h1:tkVvjkPTB7pnW3jnid7kNyAMPVWllTNOf/qKDze4p9o=
golang.org/x/crypto v0.0.0-20220331220935-ae2d96664a29/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/mod v0.5.1 h1:OJxoQ/rynoF0dcCdI7cLPktw/hR2cueqYfjm43oqK38=
golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
golang.org/x/sys v0.0.0-20220328115105-d36c6a25d886 h1:eJv7u3ksNXoLbGSKuv2s/SIO4tJVxc/A+MTpzxDgz/Q=
golang.org/x/sys v0.0.0-20220328115105-d36c6a25d886/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220330033206-e17cdc41300f h1:rlezHXNlxYWvBCzNses9Dlc7nGFaNMJeqLolcmQSSZY=
golang.org/x/sys v0.0.0-20220330033206-e17cdc41300f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=

@ -6,7 +6,7 @@ package help
import (
"log"
"github.com/rwxrob/bonzai"
Z "github.com/rwxrob/bonzai"
"github.com/rwxrob/bonzai/comp"
"github.com/rwxrob/fn/filt"
"github.com/rwxrob/fn/maps"
@ -18,14 +18,14 @@ var CBracketed = term.Reset
// Cmd provides help documentation for the caller allowing the specific
// section of help wanted to be passed as a tab-completable parameter.
var Cmd = &bonzai.Cmd{
var Cmd = &Z.Cmd{
Name: `help`,
Params: []string{
"name", "title", "summary", "params", "commands", "description",
"examples", "legal", "copyright", "license", "version",
},
Completer: helpCompleter,
Call: func(caller *bonzai.Cmd, args ...string) error {
Call: func(caller *Z.Cmd, args ...string) error {
section := "all"
if len(args) > 0 {
section = args[0]

@ -1,28 +0,0 @@
package bonzai
import (
"github.com/rwxrob/fn"
)
// EscThese is set to the default UNIX shell characters which require
// escaping to be used safely on the terminal. It can be changed to suit
// the needs of different host shell environments.
var EscThese = " \r\t\n|&;()<>![]"
// Esc returns a shell-escaped version of the string s. The returned value
// is a string that can safely be used as one token in a shell command line.
func Esc(s string) string {
var buf []rune
for _, r := range s {
for _, esc := range EscThese {
if r == esc {
buf = append(buf, '\\')
}
}
buf = append(buf, r)
}
return string(buf)
}
// EscAll calls Esc on all passed strings.
func EscAll(args []string) []string { return fn.Map(args, Esc) }

@ -1,22 +0,0 @@
package bonzai_test
import (
"fmt"
"github.com/rwxrob/bonzai"
)
func ExampleEsc() {
fmt.Println(bonzai.Esc("|&;()<>![]"))
fmt.Printf("%q", bonzai.Esc(" \n\r"))
// Output:
// \|\&\;\(\)\<\>\!\[\]
// "\\ \\\n\\\r"
}
func ExampleEscAll() {
list := []string{"so!me", "<here>", "other&"}
fmt.Println(bonzai.EscAll(list))
// Output:
// [so\!me \<here\> other\&]
}

@ -1,4 +1,4 @@
package bonzai
package Z
import (
"log"

@ -1,11 +1,11 @@
package bonzai_test
package Z_test
import (
"fmt"
"net/http"
ht "net/http/httptest"
"github.com/rwxrob/bonzai"
Z "github.com/rwxrob/bonzai"
)
func ExampleCompareUpdated() {
@ -31,10 +31,10 @@ func ExampleCompareUpdated() {
same := ht.NewServer(handler)
defer same.Close()
fmt.Println(bonzai.CompareUpdated(20220322080542, older.URL))
fmt.Println(bonzai.CompareUpdated(20220322080542, newer.URL))
fmt.Println(bonzai.CompareUpdated(20220322080542, same.URL))
fmt.Println(bonzai.CompareUpdated(20220322080542, "foobar"))
fmt.Println(Z.CompareUpdated(20220322080542, older.URL))
fmt.Println(Z.CompareUpdated(20220322080542, newer.URL))
fmt.Println(Z.CompareUpdated(20220322080542, same.URL))
fmt.Println(Z.CompareUpdated(20220322080542, "foobar"))
// Output:
// -1
@ -66,10 +66,10 @@ func ExampleCompareVersions() {
same := ht.NewServer(handler)
defer same.Close()
fmt.Println(bonzai.CompareVersions(`v0.0.2`, older.URL))
fmt.Println(bonzai.CompareVersions(`v0.0.2`, newer.URL))
fmt.Println(bonzai.CompareVersions(`v0.0.2`, same.URL))
fmt.Println(bonzai.CompareVersions(`v0.0.2`, "foobar"))
fmt.Println(Z.CompareVersions(`v0.0.2`, older.URL))
fmt.Println(Z.CompareVersions(`v0.0.2`, newer.URL))
fmt.Println(Z.CompareVersions(`v0.0.2`, same.URL))
fmt.Println(Z.CompareVersions(`v0.0.2`, "foobar"))
// Output:
// 1

Loading…
Cancel
Save