https://github.com/fortio/cli
Reduce boiler plate needed on each new Golang main functions (Command Line Interface) for both tool and servers
https://github.com/fortio/cli
Last synced: 4 months ago
JSON representation
Reduce boiler plate needed on each new Golang main functions (Command Line Interface) for both tool and servers
- Host: GitHub
- URL: https://github.com/fortio/cli
- Owner: fortio
- License: apache-2.0
- Created: 2023-02-18T20:10:45.000Z (over 2 years ago)
- Default Branch: main
- Last Pushed: 2025-04-06T22:57:19.000Z (6 months ago)
- Last Synced: 2025-04-06T23:27:34.451Z (6 months ago)
- Language: Go
- Homepage:
- Size: 328 KB
- Stars: 6
- Watchers: 3
- Forks: 0
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
[](https://pkg.go.dev/fortio.org/cli)
[](https://goreportcard.com/report/fortio.org/cli)
[](https://github.com/fortio/cli/releases/)# cli
Reduce boiler plate needed on each new Golang main functions (Command Line Interface) for both tools and servers (use [fortio.org/scli ServerMain()](https://github.com/fortio/scli#scli) for server)It abstracts the repetitive parts of a `main()` command line tool, flag parsing, usage, etc...
You can see real use example in a tool like [multicurl](https://github.com/fortio/multicurl) or a server like [proxy](https://github.com/fortio/proxy).
It also supports (sub)commands style (where there is a word/command before the flags and remaining arguments, [fortio](https://github.com/fortio/fortio) uses that mode).
## Tool Example
Client/Tool example (no dynamic flag url or config) [sampleTool](sampleTool/main.go)Code as simple as
```golang
import (
"flag"
"os""fortio.org/cli"
"fortio.org/log"
)func main() {
myFlag := flag.String("myflag", "default", "my flag")
cli.MinArgs = 2
cli.MaxArgs = 4
cli.Main() // Will have either called cli.ExitFunction or everything is valid
// Next line output won't show when passed -quiet
log.Infof("Info test, -myflag is %q", *myFlag)
// This always shows
log.Printf("Hello world, version %s, args %v", cli.ShortVersion, flag.Args())
// This shows and is colorized and structured, unless loglevel is set to critical.
log.S(log.Error, "Error test",
log.Str("myflag", *myFlag),
log.Attr("num_args", len(flag.Args())),
log.Attr("args", flag.Args()))
}
``````bash
$ sampleTool a
sampleTool 1.2.0 usage:
sampleTool [flags] arg1 arg2 [arg3...arg4]
or 1 of the special arguments
sampleTool {help|version|buildinfo}
flags:
-logger-force-color
Force color output even if stderr isn't a terminal
-logger-no-color
Prevent colorized output even if stderr is a terminal
-loglevel level
log level, one of [Debug Verbose Info Warning Error Critical Fatal] (default Info)
-myflag string
my flag (default "default")
-quiet
Quiet mode, sets loglevel to Error (quietly) to reduces the output
At least 2 arguments expected, got 1
```Since v1.3, the above is colorized on a terminal and looks like this:

or normal case:

Old style, no colors:
```bash
$ sampleTool -logger-no-color a b
17:20:41 [I] Info test, -myflag is "default"
17:20:41 Hello world, version dev, args [a b]
17:20:41 [E] Error test, myflag="default", num_args="2", args="[a b]"
```## Additional builtins
### buildinfo
e.g
```bash
% go install github.com/fortio/multicurl@latest
go: downloading github.com/fortio/multicurl v1.10.1
% multicurl buildinfo
1.10.1 h1:h9yM3XplwG7JWtVaSS0eJPiDmCJfnxvj3w+yoAMWMo4= go1.19.6 arm64 darwin
go go1.19.6
path github.com/fortio/multicurl
mod github.com/fortio/multicurl v1.10.1 h1:h9yM3XplwG7JWtVaSS0eJPiDmCJfnxvj3w+yoAMWMo4=
dep fortio.org/cli v0.6.1 h1:V9L6ly4oz4fJjeQ5745FulIMsFAwFZvLPSUN+cKUrKk=
dep fortio.org/log v1.2.2 h1:vs42JjNwiqbMbacittZjJE9+oi72Za6aekML9gKmILg=
dep fortio.org/version v1.0.2 h1:8NwxdX58aoeKx7T5xAPO0xlUu1Hpk42nRz5s6e6eKZ0=
build -compiler=gc
build CGO_ENABLED=1
build CGO_CFLAGS=
build CGO_CPPFLAGS=
build CGO_CXXFLAGS=
build CGO_LDFLAGS=
build GOARCH=arm64
build GOOS=darwin
```### help
```bash
% multicurl help
Fortio multicurl 1.10.1 usage:
multicurl [flags] url
or 1 of the special arguments
multicurl {help|version|buildinfo}
flags:
[...]
-logger-force-color
Force color output even if stderr isn't a terminal
-logger-no-color
Prevent colorized output even if stderr is a terminal
-loglevel level
log level, one of [Debug Verbose Info Warning Error Critical Fatal] (default Info)
-quiet
Quiet mode, sets loglevel to Error (quietly) to reduces the output
```### version
Short 'numeric' version (v skipped, useful for docker image tags etc)
```bash
% multicurl version
1.10.1
```### https/tls in FROM scratch docker images
You should always try to use `FROM scratch` Docker images when possible,
it's one of the strength of go.Using this `fortio.org/cli` as a base makes it work for outcalls to internet valid TLS certs (e.g. https).
It does this by defaulting to the bundle provided by `golang.org/x/crypto/x509roots/fallback` automatically.See https://github.com/fortio/multicurl for a good example.
If you do not want this behavior, build using `-tags no_tls_fallback`.
### Small binaries
If you application doesn't do http request/response logging at all, use `-tags no_http` or `-tags no_net` (that one will also imply `no_tls_fallback`) and save 1.6 Mbytes in your binary's size (because the linker isn't smart enough to see net/http isn't actually used) (1.1Mbytes for log's no_http and 530k from the no_tls_fallback)
And, if you don't need any of the advanced JSON logging (which is quite likely with a cli), use `-tags no_json` the logger will still produce json structured logging just not as advanced if what you log are deep structures - this saves another 130k or so.
These tags are from [fortio.org/log](https://github.com/fortio/log) v1.14 and later
In summary: for smallest pure local cli binaries using this package:
```
CGO_ENABLE=0 go build -trimpath -ldflags="-w -s" -tags no_net,no_json .
```
saves ~1.7Mbytes in total (a basic cli dependending on this package will then only be about 300k more as an hello world yet include color help, buildinfo, version, logging etc)