Skip to content

Commit

Permalink
Move code to README
Browse files Browse the repository at this point in the history
  • Loading branch information
artemklevtsov committed Sep 16, 2023
1 parent 67c19b4 commit 684934e
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 91 deletions.
117 changes: 70 additions & 47 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,45 +2,48 @@
<p align="center"><img width="90%" src="kong.png" /></p>

# Kong is a command-line parser for Go

[![](https://godoc.org/github.com/alecthomas/kong?status.svg)](http://godoc.org/github.com/alecthomas/kong) [![CircleCI](https://img.shields.io/circleci/project/github/alecthomas/kong.svg)](https://circleci.com/gh/alecthomas/kong) [![Go Report Card](https://goreportcard.com/badge/github.com/alecthomas/kong)](https://goreportcard.com/report/github.com/alecthomas/kong) [![Slack chat](https://img.shields.io/static/v1?logo=slack&style=flat&label=slack&color=green&message=gophers)](https://gophers.slack.com/messages/CN9DS8YF3)

<!-- https://github.com/naokazuterada/MarkdownTOC -->

<!-- MarkdownTOC autolink="true" style="ordered" indent=" " -->

1. [Introduction](#introduction)
1. [Help](#help)
1. [Help as a user of a Kong application](#help-as-a-user-of-a-kong-application)
1. [Defining help in Kong](#defining-help-in-kong)
1. [Showing the _command_'s detailed help](#showing-the-_command_s-detailed-help)
1. [Showing an _argument_'s detailed help](#showing-an-_argument_s-detailed-help)
1. [Command handling](#command-handling)
1. [Switch on the command string](#switch-on-the-command-string)
1. [Attach a `Run(...) error` method to each command](#attach-a-run-error-method-to-each-command)
1. [Hooks: BeforeReset\(\), BeforeResolve\(\), BeforeApply\(\), AfterApply\(\) and the Bind\(\) option](#hooks-beforereset-beforeresolve-beforeapply-afterapply-and-the-bind-option)
1. [Flags](#flags)
1. [Commands and sub-commands](#commands-and-sub-commands)
1. [Branching positional arguments](#branching-positional-arguments)
1. [Positional arguments](#positional-arguments)
1. [Slices](#slices)
1. [Maps](#maps)
1. [Nested data structure](#nested-data-structure)
1. [Custom named decoders](#custom-named-decoders)
1. [Supported field types](#supported-field-types)
1. [Custom decoders \(mappers\)](#custom-decoders-mappers)
1. [Supported tags](#supported-tags)
1. [Plugins](#plugins)
1. [Dynamic Commands](#dynamic-commands)
1. [Variable interpolation](#variable-interpolation)
1. [Validation](#validation)
1. [Modifying Kong's behaviour](#modifying-kongs-behaviour)
1. [`Name(help)` and `Description(help)` - set the application name description](#namehelp-and-descriptionhelp---set-the-application-name-description)
1. [`Configuration(loader, paths...)` - load defaults from configuration files](#configurationloader-paths---load-defaults-from-configuration-files)
1. [`Resolver(...)` - support for default values from external sources](#resolver---support-for-default-values-from-external-sources)
1. [`*Mapper(...)` - customising how the command-line is mapped to Go values](#mapper---customising-how-the-command-line-is-mapped-to-go-values)
1. [`ConfigureHelp(HelpOptions)` and `Help(HelpFunc)` - customising help](#configurehelphelpoptions-and-helphelpfunc---customising-help)
1. [`Bind(...)` - bind values for callback hooks and Run\(\) methods](#bind---bind-values-for-callback-hooks-and-run-methods)
1. [Other options](#other-options)
- [Kong is a command-line parser for Go](#kong-is-a-command-line-parser-for-go)
- [Introduction](#introduction)
- [Help](#help)
- [Help as a user of a Kong application](#help-as-a-user-of-a-kong-application)
- [Defining help in Kong](#defining-help-in-kong)
- [Showing the _command_'s detailed help](#showing-the-commands-detailed-help)
- [Showing an _argument_'s detailed help](#showing-an-arguments-detailed-help)
- [Command handling](#command-handling)
- [Switch on the command string](#switch-on-the-command-string)
- [Attach a `Run(...) error` method to each command](#attach-a-run-error-method-to-each-command)
- [Hooks: BeforeReset(), BeforeResolve(), BeforeApply(), AfterApply() and the Bind() option](#hooks-beforereset-beforeresolve-beforeapply-afterapply-and-the-bind-option)
- [Flags](#flags)
- [Commands and sub-commands](#commands-and-sub-commands)
- [Branching positional arguments](#branching-positional-arguments)
- [Positional arguments](#positional-arguments)
- [Slices](#slices)
- [Maps](#maps)
- [Pointers](#pointers)
- [Nested data structure](#nested-data-structure)
- [Custom named decoders](#custom-named-decoders)
- [Supported field types](#supported-field-types)
- [Custom decoders (mappers)](#custom-decoders-mappers)
- [Supported tags](#supported-tags)
- [Plugins](#plugins)
- [Dynamic Commands](#dynamic-commands)
- [Variable interpolation](#variable-interpolation)
- [Validation](#validation)
- [Modifying Kong's behaviour](#modifying-kongs-behaviour)
- [`Name(help)` and `Description(help)` - set the application name description](#namehelp-and-descriptionhelp---set-the-application-name-description)
- [`Configuration(loader, paths...)` - load defaults from configuration files](#configurationloader-paths---load-defaults-from-configuration-files)
- [`Resolver(...)` - support for default values from external sources](#resolver---support-for-default-values-from-external-sources)
- [`*Mapper(...)` - customising how the command-line is mapped to Go values](#mapper---customising-how-the-command-line-is-mapped-to-go-values)
- [`ConfigureHelp(HelpOptions)` and `Help(HelpFunc)` - customising help](#configurehelphelpoptions-and-helphelpfunc---customising-help)
- [`Bind(...)` - bind values for callback hooks and Run() methods](#bind---bind-values-for-callback-hooks-and-run-methods)
- [Other options](#other-options)

<!-- /MarkdownTOC -->

Expand Down Expand Up @@ -137,13 +140,14 @@ also be interpolated into the help string.
Finally, any command, or argument type implementing the interface
`Help() string` will have this function called to retrieve more detail to
augment the help tag. This allows for much more descriptive text than can
fit in Go tags. [See _examples/shell/help](./_examples/shell/help)
fit in Go tags. [See \_examples/shell/help](./_examples/shell/help)

#### Showing the _command_'s detailed help

A command's additional help text is _not_ shown from top-level help, but can be displayed within contextual help:

**Top level help**

```bash
$ go run ./_examples/shell/help --help
Usage: help <command>
Expand All @@ -159,6 +163,7 @@ Commands:
```

**Contextual**

```bash
$ go run ./_examples/shell/help echo --help
Usage: help echo <msg>
Expand All @@ -180,6 +185,7 @@ Flags:
Custom help will only be shown for _positional arguments with named fields_ ([see the README section on positional arguments for more details on what that means](../../../README.md#branching-positional-arguments))

**Contextual argument help**

```bash
$ go run ./_examples/shell/help msg --help
Usage: help echo <msg>
Expand Down Expand Up @@ -337,9 +343,29 @@ func main() {
}
```

Another example of using hooks is load the env-file:

```go
import (
"github.com/joho/godotenv"
)

type EnvFlag string

// BeforeResolve loads env file.
func (c EnvFlag) BeforeReset(ctx *Context, trace *Path) error {
path := string(ctx.FlagValue(trace.Flag).(EnvFlag)) // nolint
path = ExpandPath(path)
if err := godotenv.Load(path); err != nil {
return err
}
return nil
}
```

## Flags

Any [mapped](#mapper---customising-how-the-command-line-is-mapped-to-go-values) field in the command structure *not* tagged with `cmd` or `arg` will be a flag. Flags are optional by default.
Any [mapped](#mapper---customising-how-the-command-line-is-mapped-to-go-values) field in the command structure _not_ tagged with `cmd` or `arg` will be a flag. Flags are optional by default.

eg. The command-line `app [--flag="foo"]` can be represented by the following.

Expand Down Expand Up @@ -479,25 +505,22 @@ Kong includes a number of builtin custom type mappers. These can be used by
specifying the tag `type:"<type>"`. They are registered with the option
function `NamedMapper(name, mapper)`.

| Name | Description |
| -------------- | -------------------------------------------------------------------------------------------------- |
| `path` | A path. ~ expansion is applied. `-` is accepted for stdout, and will be passed unaltered. |
| `existingfile` | An existing file. ~ expansion is applied. `-` is accepted for stdin, and will be passed unaltered. |
| `existingdir` | An existing directory. ~ expansion is applied. |
| `counter` | Increment a numeric field. Useful for `-vvv`. Can accept `-s`, `--long` or `--long=N`. |
| Name | Description |
| -------------- | ---------------------------------------------------------------------------------------------------------------------- |
| `path` | A path. ~ expansion is applied. `-` is accepted for stdout, and will be passed unaltered. |
| `existingfile` | An existing file. ~ expansion is applied. `-` is accepted for stdin, and will be passed unaltered. |
| `existingdir` | An existing directory. ~ expansion is applied. |
| `counter` | Increment a numeric field. Useful for `-vvv`. Can accept `-s`, `--long` or `--long=N`. |
| `filecontent` | Read the file at path into the field. ~ expansion is applied. `-` is accepted for stdin, and will be passed unaltered. |


Slices and maps treat type tags specially. For slices, the `type:""` tag
specifies the element type. For maps, the tag has the format
`tag:"[<key>]:[<value>]"` where either may be omitted.

## Supported field types


## Custom decoders (mappers)


Any field implementing `encoding.TextUnmarshaler` or `json.Unmarshaler` will use those interfaces
for decoding values. Kong also includes builtin support for many common Go types:

Expand All @@ -522,7 +545,7 @@ Tags can be in two forms:
Both can coexist with standard Tag parsing.

| Tag | Description |
|----------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `cmd:""` | If present, struct is a command. |
| `arg:""` | If present, field is an argument. Required by default. |
| `env:"X,Y,..."` | Specify envars to use for default value. The envs are resolved in the declared order. The first value found is used. |
Expand Down Expand Up @@ -629,7 +652,7 @@ interface:
type Validatable interface {
Validate() error
}
```
```

If one of these nodes is in the active command-line it will be called during
normal validation.
Expand Down Expand Up @@ -704,4 +727,4 @@ See the [section on hooks](#hooks-beforeresolve-beforeapply-afterapply-and-the-b

### Other options

The full set of options can be found [here](https://godoc.org/github.com/alecthomas/kong#Option).
The full set of options can be found [here](https://godoc.org/github.com/alecthomas/kong#Option).
5 changes: 2 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
module github.com/alecthomas/kong

require (
github.com/alecthomas/assert/v2 v2.1.0
github.com/alecthomas/repr v0.1.0
github.com/joho/godotenv v1.5.1
github.com/alecthomas/assert/v2 v2.3.0
github.com/alecthomas/repr v0.2.0
)

require github.com/hexops/gotextdiff v1.0.3 // indirect
Expand Down
10 changes: 4 additions & 6 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
github.com/alecthomas/assert/v2 v2.1.0 h1:tbredtNcQnoSd3QBhQWI7QZ3XHOVkw1Moklp2ojoH/0=
github.com/alecthomas/assert/v2 v2.1.0/go.mod h1:b/+1DI2Q6NckYi+3mXyH3wFb8qG37K/DuK80n7WefXA=
github.com/alecthomas/repr v0.1.0 h1:ENn2e1+J3k09gyj2shc0dHr/yjaWSHRlrJ4DPMevDqE=
github.com/alecthomas/repr v0.1.0/go.mod h1:2kn6fqh/zIyPLmm3ugklbEi5hg5wS435eygvNfaDQL8=
github.com/alecthomas/assert/v2 v2.3.0 h1:mAsH2wmvjsuvyBvAmCtm7zFsBlb8mIHx5ySLVdDZXL0=
github.com/alecthomas/assert/v2 v2.3.0/go.mod h1:pXcQ2Asjp247dahGEmsZ6ru0UVwnkhktn7S0bBDLxvQ=
github.com/alecthomas/repr v0.2.0 h1:HAzS41CIzNW5syS8Mf9UwXhNH1J9aix/BvDRf1Ml2Yk=
github.com/alecthomas/repr v0.2.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4=
github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM=
github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg=
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
17 changes: 0 additions & 17 deletions util.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ import (
"fmt"
"os"
"reflect"

"github.com/joho/godotenv"
)

// ConfigFlag uses the configured (via kong.Configuration(loader)) configuration loader to load configuration
Expand All @@ -28,21 +26,6 @@ func (c ConfigFlag) BeforeResolve(kong *Kong, ctx *Context, trace *Path) error {
return nil
}

// EnvFlag loads environment variables from a file specified by a flag.
//
// Use this as a flag value to support loading of environment variables from a file.
type EnvFlag string

// BeforeResolve loads env file.
func (c EnvFlag) BeforeReset(ctx *Context, trace *Path) error {
path := string(ctx.FlagValue(trace.Flag).(EnvFlag)) // nolint
path = ExpandPath(path)
if err := godotenv.Load(path); err != nil {
return err
}
return nil
}

// VersionFlag is a flag type that can be used to display a version number, stored in the "version" variable.
type VersionFlag bool

Expand Down
18 changes: 0 additions & 18 deletions util_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,24 +29,6 @@ func TestConfigFlag(t *testing.T) {
assert.Equal(t, "hello world", cli.Flag)
}

func TestEnvFlag(t *testing.T) {
var cli struct {
EnvFile EnvFlag
Flag string `env:"FLAG"`
}

w, err := ioutil.TempFile("", "")
assert.NoError(t, err)
defer os.Remove(w.Name())
w.WriteString(`FLAG=hello world`) // nolint: errcheck
w.Close()

p := Must(&cli)
_, err = p.Parse([]string{"--env-file", w.Name()})
assert.NoError(t, err)
assert.Equal(t, "hello world", cli.Flag)
}

func TestVersionFlag(t *testing.T) {
var cli struct {
Version VersionFlag
Expand Down

0 comments on commit 684934e

Please sign in to comment.