wand/readme.md

142 lines
3.2 KiB
Markdown
Raw Normal View History

2025-09-01 02:07:48 +02:00
# Wand
2026-01-07 20:12:19 +01:00
Wand is a library to wrap Go functions as executable binaries. It supports:
2026-01-07 22:21:54 +01:00
- hierarchy of subcommands
2026-01-07 20:12:19 +01:00
- binding of command line options
- binding of environment variables
- binding of configuration entries
- positional arguments
- automatically generated help and documentation from go doc
## Example:
```
package main
import (
"strings"
"code.squareroundforest.org/arpio/wand"
)
func main() {
wand.Exec(strings.Split)
}
```
## Lib docs:
- [./lib.go](./lib.go)
- [go docs html](https://godocs.io/code.squareroundforest.org/arpio/wand)
## wand tool
2026-01-07 22:21:54 +01:00
The wand tool helps with the following tasks:
2026-01-07 20:12:19 +01:00
2026-01-07 22:21:54 +01:00
- generating code from the go doc of the library that is converted into an executable binary by wand
- generating man (roff) or markdown documentation
2026-01-07 20:12:19 +01:00
- executing arbitrary Go functions in the command line addressed by their go path
Generating code with the docs of the wrapped library is particularly useful, because this way the automatically
generated help can be based on the go docs. This is an important part of the attempt to achieve that ideal
situation, where a solution to a problem is presented both as a library and a command line tool, and there is
only a single place ("source of truth") of documentation.
Executing arbitrary Go functions in the command line is only a lucky side effect of the way wand was built.
While it's not the primary function of the tool, it can be useful when just quickly trying out some Go functions
or expressions, without having to create a throwaway main.go file.
### wand tool installation
```
sudo make install
```
or in the current user's home:
```
prefix=~/.local make install
```
(See the recommended way below on how to use the locked version in the build tooling of a project.)
### wand tool usage
2026-01-07 22:21:54 +01:00
Let's consider a project hierarchy where in the root we have a library (mylib), and in the ./cmd directory we
2026-01-07 20:12:19 +01:00
have a main package, wrapping one or more functions of that library with wand as an executable binary:
```
./cmd/main.go
./lib.go
```
2026-01-07 22:21:54 +01:00
Generating the compiled docs from the go doc of a library:
2026-01-07 20:12:19 +01:00
```
wand docreflect mylib .
```
Generating a man page for the command:
```
2026-01-07 22:21:54 +01:00
wand manpages --date-string 2026-01-07 --version v1.0.0 ./cmd
2026-01-07 20:12:19 +01:00
```
### wand tool bonus usage
```
wand --import strings strings.Split 1:2:3 :
```
### wand tool docs
2026-01-07 20:13:49 +01:00
- [./cmd/wand/readme.md](./cmd/wand/readme.md)
2026-01-07 20:12:19 +01:00
When installed:
```
man wand
```
When not installed with man pages:
```
wand help
```
### wand tool usage with go.mod version
2026-01-07 22:21:54 +01:00
When generating the docs for a shared project, we may want to ensure that the same version of wand is used for
both docreflect and manpages in every environment. It is best to use the version that is defined in go.mod. This
can be achieved using some trivial scripts. The example below shows docreflect:
2026-01-07 20:12:19 +01:00
```
package main
import (
"code.squareroundforest.org/arpio/wand/tools"
"log"
"os"
)
func main() {
if len(os.Args) < 2 {
log.Fatalln("expected package name")
}
if err := tools.Docreflect(os.Stdout, os.Args[1], os.Args[2:]...); err != nil {
log.Fatalln(err)
}
}
```
and calling it, e.g. from a Makefile, with go run like:
```
go run script/gendocs.go mylib . gopath.to/me/mylib > docs.gen.go
```
---
2025-09-01 02:07:48 +02:00
*Made in Berlin, DE*