TUN-3963: Repoint urfave/cli/v2 library at patched branch at github.com/ipostelnik/cli/v2@fixed which correctly handles reading flags declared at multiple levels of subcommands.
This commit is contained in:
parent
792520d313
commit
6db934853d
42
CHANGES.md
42
CHANGES.md
|
@ -1,29 +1,59 @@
|
||||||
**Experimental**: This is a new format for release notes. The format and availability is subject to change.
|
**Experimental**: This is a new format for release notes. The format and availability is subject to change.
|
||||||
|
|
||||||
|
## UNRELEASED
|
||||||
|
|
||||||
|
### Backward Incompatible Changes
|
||||||
|
|
||||||
|
- none
|
||||||
|
|
||||||
|
### New Features
|
||||||
|
|
||||||
|
- none
|
||||||
|
|
||||||
|
### Improvements
|
||||||
|
|
||||||
|
- Nested commands, such as `cloudflared tunnel run`, now consider CLI arguments even if they appear earlier on the
|
||||||
|
command. For instance, `cloudflared --config config.yaml tunnel run` will now behave the same as
|
||||||
|
`cloudflared tunnel --config config.yaml run`
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
- none
|
||||||
|
|
||||||
## 2021.2.5
|
## 2021.2.5
|
||||||
|
|
||||||
### New Features
|
### New Features
|
||||||
- We introduce [Cloudflare One Routing](https://developers.cloudflare.com/cloudflare-one/tutorials/warp-to-tunnel) in beta mode, where users can create private networks with RFC 1918 IP addresses on Cloudflare's network. Clients running Cloudflare WARP client in the same organization can then connect to services made available by Argo Tunnel. Please share your feedback in the GitHub issue opened.
|
|
||||||
|
|
||||||
|
- We introduce [Cloudflare One Routing](https://developers.cloudflare.com/cloudflare-one/tutorials/warp-to-tunnel) in
|
||||||
|
beta mode. Cloudflare customer can now connect users and private networks with RFC 1918 IP addresses via the
|
||||||
|
Cloudflare edge network. Users running Cloudflare WARP client in the same organization can connect to the services
|
||||||
|
made available by Argo Tunnel IP routes. Please share your feedback in the GitHub issue tracker.
|
||||||
|
|
||||||
## 2021.2.4
|
## 2021.2.4
|
||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
- Reverts the Improvement released in 2021.2.3 for CLI arguments as it introduced a regression where cloudflared failed to read URLs in configuration files.
|
|
||||||
- Cloudflared now logs the reason for failed connections if the error is recoverable.
|
|
||||||
|
|
||||||
|
- Reverts the Improvement released in 2021.2.3 for CLI arguments as it introduced a regression where cloudflared failed
|
||||||
|
to read URLs in configuration files.
|
||||||
|
- cloudflared now logs the reason for failed connections if the error is recoverable.
|
||||||
|
|
||||||
## 2021.2.3
|
## 2021.2.3
|
||||||
|
|
||||||
### Backward Incompatible Changes
|
### Backward Incompatible Changes
|
||||||
- Removes db-connect. The Cloudflare Workers product will continue to support db-connect implementations with versions of cloudflared that predate this release and include support for db-connect.
|
|
||||||
|
- Removes db-connect. The Cloudflare Workers product will continue to support db-connect implementations with versions
|
||||||
|
of cloudflared that predate this release and include support for db-connect.
|
||||||
|
|
||||||
### New Features
|
### New Features
|
||||||
|
|
||||||
- Introduces support for proxy configurations with websockets in arbitrary TCP connections (#318).
|
- Introduces support for proxy configurations with websockets in arbitrary TCP connections (#318).
|
||||||
|
|
||||||
### Improvements
|
### Improvements
|
||||||
- Nested command line arguments (such as `cloudflared tunnel run`) now consider CLI arguments even if they appear earlier in the command. E.g. `cloudflared --config config.yaml tunnel run` will now behave similarly to `cloudflared tunnel --config config.yaml run`
|
|
||||||
|
- (reverted) Nested command line argument handling.
|
||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
- The maximum number of upstream connections is now limited by default which should fix reported issues of cloudflared exhausting CPU usage when faced with connectivity issues.
|
|
||||||
|
- The maximum number of upstream connections is now limited by default which should fix reported issues of cloudflared
|
||||||
|
exhausting CPU usage when faced with connectivity issues.
|
||||||
|
|
||||||
|
|
2
go.mod
2
go.mod
|
@ -57,3 +57,5 @@ require (
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 // indirect
|
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 // indirect
|
||||||
zombiezen.com/go/capnproto2 v2.18.0+incompatible
|
zombiezen.com/go/capnproto2 v2.18.0+incompatible
|
||||||
)
|
)
|
||||||
|
|
||||||
|
replace github.com/urfave/cli/v2 => github.com/ipostelnik/cli/v2 v2.3.1-0.20210223162147-c8b4f97735e4
|
||||||
|
|
11
go.sum
11
go.sum
|
@ -144,6 +144,8 @@ github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfc
|
||||||
github.com/cpu/goacmedns v0.0.1/go.mod h1:sesf/pNnCYwUevQEQfEwY0Y3DydlQWSGZbaMElOWxok=
|
github.com/cpu/goacmedns v0.0.1/go.mod h1:sesf/pNnCYwUevQEQfEwY0Y3DydlQWSGZbaMElOWxok=
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY=
|
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY=
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||||
|
github.com/cpuguy83/go-md2man/v2 v2.0.0 h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng4PGlyM=
|
||||||
|
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||||
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
|
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
|
||||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
@ -350,6 +352,10 @@ github.com/imdario/mergo v0.3.9/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJ
|
||||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||||
github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo=
|
github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo=
|
||||||
github.com/infobloxopen/go-trees v0.0.0-20190313150506-2af4e13f9062/go.mod h1:PcNJqIlcX/dj3DTG/+QQnRvSgTMG6CLpRMjWcv4+J6w=
|
github.com/infobloxopen/go-trees v0.0.0-20190313150506-2af4e13f9062/go.mod h1:PcNJqIlcX/dj3DTG/+QQnRvSgTMG6CLpRMjWcv4+J6w=
|
||||||
|
github.com/ipostelnik/cli/v2 v2.3.1-0.20210212191405-2b6ed1f5ef69 h1:TuZfNu8oRuQr6Y8UIvQlpXq+G+SzytMUGx8NrBt+2jg=
|
||||||
|
github.com/ipostelnik/cli/v2 v2.3.1-0.20210212191405-2b6ed1f5ef69/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI=
|
||||||
|
github.com/ipostelnik/cli/v2 v2.3.1-0.20210223162147-c8b4f97735e4 h1:U2OxGKZHC5puhKZnGo6wWWjuWusJCM6J/S1eF7Vt+Uk=
|
||||||
|
github.com/ipostelnik/cli/v2 v2.3.1-0.20210223162147-c8b4f97735e4/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI=
|
||||||
github.com/jimstudt/http-authentication v0.0.0-20140401203705-3eca13d6893a/go.mod h1:wK6yTYYcgjHE1Z1QtXACPDjcFJyBskHEdagmnq3vsP8=
|
github.com/jimstudt/http-authentication v0.0.0-20140401203705-3eca13d6893a/go.mod h1:wK6yTYYcgjHE1Z1QtXACPDjcFJyBskHEdagmnq3vsP8=
|
||||||
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
|
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
|
||||||
github.com/jmespath/go-jmespath v0.3.0 h1:OS12ieG61fsCg5+qLJ+SsW9NicxNkg3b25OyT2yCeUc=
|
github.com/jmespath/go-jmespath v0.3.0 h1:OS12ieG61fsCg5+qLJ+SsW9NicxNkg3b25OyT2yCeUc=
|
||||||
|
@ -549,6 +555,8 @@ github.com/russross/blackfriday v0.0.0-20170610170232-067529f716f4 h1:S9YlS71UNJ
|
||||||
github.com/russross/blackfriday v0.0.0-20170610170232-067529f716f4/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
github.com/russross/blackfriday v0.0.0-20170610170232-067529f716f4/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
||||||
github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q=
|
github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q=
|
||||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||||
|
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
|
||||||
|
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||||
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
|
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
|
||||||
github.com/sacloud/libsacloud v1.26.1/go.mod h1:79ZwATmHLIFZIMd7sxA3LwzVy/B77uj3LDoToVTxDoQ=
|
github.com/sacloud/libsacloud v1.26.1/go.mod h1:79ZwATmHLIFZIMd7sxA3LwzVy/B77uj3LDoToVTxDoQ=
|
||||||
github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E=
|
github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E=
|
||||||
|
@ -590,6 +598,8 @@ github.com/uber-go/atomic v1.3.2/go.mod h1:/Ct5t2lcmbJ4OSe/waGBoaVvVqtO0bmtfVNex
|
||||||
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
|
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
|
||||||
github.com/urfave/cli v1.22.1 h1:+mkCCcOFKPnCmVYVcURKps1Xe+3zP90gSYGNfRkjoIY=
|
github.com/urfave/cli v1.22.1 h1:+mkCCcOFKPnCmVYVcURKps1Xe+3zP90gSYGNfRkjoIY=
|
||||||
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||||
|
github.com/urfave/cli v1.22.5 h1:lNq9sAHXK2qfdI8W+GRItjCEkI+2oR4d+MEHy1CKXoU=
|
||||||
|
github.com/urfave/cli v1.22.5/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||||
github.com/urfave/cli/v2 v2.2.0 h1:JTTnM6wKzdA0Jqodd966MVj4vWbbquZykeX1sKbe2C4=
|
github.com/urfave/cli/v2 v2.2.0 h1:JTTnM6wKzdA0Jqodd966MVj4vWbbquZykeX1sKbe2C4=
|
||||||
github.com/urfave/cli/v2 v2.2.0/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ=
|
github.com/urfave/cli/v2 v2.2.0/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ=
|
||||||
github.com/vultr/govultr v0.1.4/go.mod h1:9H008Uxr/C4vFNGLqKx232C206GL0PBHzOP0809bGNA=
|
github.com/vultr/govultr v0.1.4/go.mod h1:9H008Uxr/C4vFNGLqKx232C206GL0PBHzOP0809bGNA=
|
||||||
|
@ -978,6 +988,7 @@ gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRN
|
||||||
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
|
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
|
||||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
|
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
module github.com/rs/zerolog
|
module github.com/rs/zerolog
|
||||||
|
|
||||||
go 1.15
|
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e
|
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e
|
||||||
github.com/pkg/errors v0.8.1
|
github.com/pkg/errors v0.8.1
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
cli
|
cli
|
||||||
===
|
===
|
||||||
|
|
||||||
[![GoDoc](https://godoc.org/github.com/urfave/cli?status.svg)](https://godoc.org/github.com/urfave/cli)
|
[![GoDoc](https://godoc.org/github.com/urfave/cli?status.svg)](https://pkg.go.dev/github.com/urfave/cli/v2)
|
||||||
[![codebeat](https://codebeat.co/badges/0a8f30aa-f975-404b-b878-5fab3ae1cc5f)](https://codebeat.co/projects/github-com-urfave-cli)
|
[![codebeat](https://codebeat.co/badges/0a8f30aa-f975-404b-b878-5fab3ae1cc5f)](https://codebeat.co/projects/github-com-urfave-cli)
|
||||||
[![Go Report Card](https://goreportcard.com/badge/urfave/cli)](https://goreportcard.com/report/urfave/cli)
|
[![Go Report Card](https://goreportcard.com/badge/urfave/cli)](https://goreportcard.com/report/urfave/cli)
|
||||||
[![codecov](https://codecov.io/gh/urfave/cli/branch/master/graph/badge.svg)](https://codecov.io/gh/urfave/cli)
|
[![codecov](https://codecov.io/gh/urfave/cli/branch/master/graph/badge.svg)](https://codecov.io/gh/urfave/cli)
|
||||||
|
@ -17,11 +17,15 @@ Usage documentation exists for each major version. Don't know what version you'r
|
||||||
- `v2` - [./docs/v2/manual.md](./docs/v2/manual.md)
|
- `v2` - [./docs/v2/manual.md](./docs/v2/manual.md)
|
||||||
- `v1` - [./docs/v1/manual.md](./docs/v1/manual.md)
|
- `v1` - [./docs/v1/manual.md](./docs/v1/manual.md)
|
||||||
|
|
||||||
|
Guides for migrating to newer versions:
|
||||||
|
|
||||||
|
- `v1-to-v2` - [./docs/migrate-v1-to-v2.md](./docs/migrate-v1-to-v2.md)
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
Make sure you have a working Go environment. Go version 1.11+ is supported. [See the install instructions for Go](http://golang.org/doc/install.html).
|
Using this package requires a working Go environment. [See the install instructions for Go](http://golang.org/doc/install.html).
|
||||||
|
|
||||||
Go Modules are strongly recommended when using this package. [See the go blog guide on using Go Modules](https://blog.golang.org/using-go-modules).
|
Go Modules are required when using this package. [See the go blog guide on using Go Modules](https://blog.golang.org/using-go-modules).
|
||||||
|
|
||||||
### Using `v2` releases
|
### Using `v2` releases
|
||||||
|
|
||||||
|
@ -63,4 +67,4 @@ export PATH=$PATH:$GOPATH/bin
|
||||||
|
|
||||||
cli is tested against multiple versions of Go on Linux, and against the latest
|
cli is tested against multiple versions of Go on Linux, and against the latest
|
||||||
released version of Go on OS X and Windows. This project uses Github Actions for
|
released version of Go on OS X and Windows. This project uses Github Actions for
|
||||||
builds. For more build info, please look at the [./.github/workflows/cli.yml](https://github.com/urfave/cli/blob/master/.github/workflows/cli.yml).
|
builds. To see our currently supported go versions and platforms, look at the [./.github/workflows/cli.yml](https://github.com/urfave/cli/blob/master/.github/workflows/cli.yml).
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
package altsrc
|
||||||
|
|
||||||
|
// defaultInputSource creates a default InputSourceContext.
|
||||||
|
func defaultInputSource() (InputSourceContext, error) {
|
||||||
|
return &MapInputSource{file: "", valueMap: map[interface{}]interface{}{}}, nil
|
||||||
|
}
|
|
@ -0,0 +1,45 @@
|
||||||
|
# Only types that provide implementation of FlagInputSourceExtension can be listed here
|
||||||
|
# please keep list sorted alphabetically
|
||||||
|
flag_types = [
|
||||||
|
"Bool",
|
||||||
|
"Duration",
|
||||||
|
"Float64",
|
||||||
|
"Generic",
|
||||||
|
"Int",
|
||||||
|
"IntSlice",
|
||||||
|
"Path",
|
||||||
|
"String",
|
||||||
|
"StringSlice",
|
||||||
|
]
|
||||||
|
|
||||||
|
print('''// Code generated by fg.py; DO NOT EDIT.
|
||||||
|
|
||||||
|
package altsrc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"flag"
|
||||||
|
|
||||||
|
"github.com/urfave/cli/v2"
|
||||||
|
)''')
|
||||||
|
|
||||||
|
for t in flag_types:
|
||||||
|
print(f'''
|
||||||
|
// {t}Flag is the flag type that wraps cli.{t}Flag to allow
|
||||||
|
// for other values to be specified
|
||||||
|
type {t}Flag struct {{
|
||||||
|
*cli.{t}Flag
|
||||||
|
set *flag.FlagSet
|
||||||
|
}}
|
||||||
|
var _ FlagInputSourceExtension = (*{t}Flag)(nil)
|
||||||
|
|
||||||
|
// New{t}Flag creates a new {t}Flag
|
||||||
|
func New{t}Flag(fl *cli.{t}Flag) *{t}Flag {{
|
||||||
|
return &{t}Flag{{{t}Flag: fl, set: nil}}
|
||||||
|
}}
|
||||||
|
|
||||||
|
// Apply saves the flagSet for later usage calls, then calls
|
||||||
|
// the wrapped {t}Flag.Apply
|
||||||
|
func (f *{t}Flag) Apply(set *flag.FlagSet) error {{
|
||||||
|
f.set = set
|
||||||
|
return f.{t}Flag.Apply(set)
|
||||||
|
}}''')
|
|
@ -64,7 +64,7 @@ func InitInputSourceWithContext(flags []cli.Flag, createInputSource func(context
|
||||||
|
|
||||||
// ApplyInputSourceValue applies a generic value to the flagSet if required
|
// ApplyInputSourceValue applies a generic value to the flagSet if required
|
||||||
func (f *GenericFlag) ApplyInputSourceValue(context *cli.Context, isc InputSourceContext) error {
|
func (f *GenericFlag) ApplyInputSourceValue(context *cli.Context, isc InputSourceContext) error {
|
||||||
if f.set != nil {
|
if context != nil {
|
||||||
if !context.IsSet(f.Name) && !isEnvVarSet(f.EnvVars) {
|
if !context.IsSet(f.Name) && !isEnvVarSet(f.EnvVars) {
|
||||||
value, err := isc.Generic(f.GenericFlag.Name)
|
value, err := isc.Generic(f.GenericFlag.Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -72,7 +72,7 @@ func (f *GenericFlag) ApplyInputSourceValue(context *cli.Context, isc InputSourc
|
||||||
}
|
}
|
||||||
if value != nil {
|
if value != nil {
|
||||||
for _, name := range f.Names() {
|
for _, name := range f.Names() {
|
||||||
_ = f.set.Set(name, value.String())
|
_ = context.Set(name, value.String())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -83,7 +83,7 @@ func (f *GenericFlag) ApplyInputSourceValue(context *cli.Context, isc InputSourc
|
||||||
|
|
||||||
// ApplyInputSourceValue applies a StringSlice value to the flagSet if required
|
// ApplyInputSourceValue applies a StringSlice value to the flagSet if required
|
||||||
func (f *StringSliceFlag) ApplyInputSourceValue(context *cli.Context, isc InputSourceContext) error {
|
func (f *StringSliceFlag) ApplyInputSourceValue(context *cli.Context, isc InputSourceContext) error {
|
||||||
if f.set != nil {
|
if context != nil {
|
||||||
if !context.IsSet(f.Name) && !isEnvVarSet(f.EnvVars) {
|
if !context.IsSet(f.Name) && !isEnvVarSet(f.EnvVars) {
|
||||||
value, err := isc.StringSlice(f.StringSliceFlag.Name)
|
value, err := isc.StringSlice(f.StringSliceFlag.Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -94,6 +94,7 @@ func (f *StringSliceFlag) ApplyInputSourceValue(context *cli.Context, isc InputS
|
||||||
for _, name := range f.Names() {
|
for _, name := range f.Names() {
|
||||||
underlyingFlag := f.set.Lookup(name)
|
underlyingFlag := f.set.Lookup(name)
|
||||||
if underlyingFlag != nil {
|
if underlyingFlag != nil {
|
||||||
|
context.Set(name, sliceValue.Serialize())
|
||||||
underlyingFlag.Value = &sliceValue
|
underlyingFlag.Value = &sliceValue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -105,7 +106,7 @@ func (f *StringSliceFlag) ApplyInputSourceValue(context *cli.Context, isc InputS
|
||||||
|
|
||||||
// ApplyInputSourceValue applies a IntSlice value if required
|
// ApplyInputSourceValue applies a IntSlice value if required
|
||||||
func (f *IntSliceFlag) ApplyInputSourceValue(context *cli.Context, isc InputSourceContext) error {
|
func (f *IntSliceFlag) ApplyInputSourceValue(context *cli.Context, isc InputSourceContext) error {
|
||||||
if f.set != nil {
|
if context != nil {
|
||||||
if !context.IsSet(f.Name) && !isEnvVarSet(f.EnvVars) {
|
if !context.IsSet(f.Name) && !isEnvVarSet(f.EnvVars) {
|
||||||
value, err := isc.IntSlice(f.IntSliceFlag.Name)
|
value, err := isc.IntSlice(f.IntSliceFlag.Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -116,6 +117,7 @@ func (f *IntSliceFlag) ApplyInputSourceValue(context *cli.Context, isc InputSour
|
||||||
for _, name := range f.Names() {
|
for _, name := range f.Names() {
|
||||||
underlyingFlag := f.set.Lookup(name)
|
underlyingFlag := f.set.Lookup(name)
|
||||||
if underlyingFlag != nil {
|
if underlyingFlag != nil {
|
||||||
|
context.Set(name, sliceValue.Serialize())
|
||||||
underlyingFlag.Value = &sliceValue
|
underlyingFlag.Value = &sliceValue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -127,7 +129,7 @@ func (f *IntSliceFlag) ApplyInputSourceValue(context *cli.Context, isc InputSour
|
||||||
|
|
||||||
// ApplyInputSourceValue applies a Bool value to the flagSet if required
|
// ApplyInputSourceValue applies a Bool value to the flagSet if required
|
||||||
func (f *BoolFlag) ApplyInputSourceValue(context *cli.Context, isc InputSourceContext) error {
|
func (f *BoolFlag) ApplyInputSourceValue(context *cli.Context, isc InputSourceContext) error {
|
||||||
if f.set != nil {
|
if context != nil {
|
||||||
if !context.IsSet(f.Name) && !isEnvVarSet(f.EnvVars) {
|
if !context.IsSet(f.Name) && !isEnvVarSet(f.EnvVars) {
|
||||||
value, err := isc.Bool(f.BoolFlag.Name)
|
value, err := isc.Bool(f.BoolFlag.Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -135,7 +137,7 @@ func (f *BoolFlag) ApplyInputSourceValue(context *cli.Context, isc InputSourceCo
|
||||||
}
|
}
|
||||||
if value {
|
if value {
|
||||||
for _, name := range f.Names() {
|
for _, name := range f.Names() {
|
||||||
_ = f.set.Set(name, strconv.FormatBool(value))
|
_ = context.Set(name, strconv.FormatBool(value))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -145,7 +147,7 @@ func (f *BoolFlag) ApplyInputSourceValue(context *cli.Context, isc InputSourceCo
|
||||||
|
|
||||||
// ApplyInputSourceValue applies a String value to the flagSet if required
|
// ApplyInputSourceValue applies a String value to the flagSet if required
|
||||||
func (f *StringFlag) ApplyInputSourceValue(context *cli.Context, isc InputSourceContext) error {
|
func (f *StringFlag) ApplyInputSourceValue(context *cli.Context, isc InputSourceContext) error {
|
||||||
if f.set != nil {
|
if context != nil {
|
||||||
if !(context.IsSet(f.Name) || isEnvVarSet(f.EnvVars)) {
|
if !(context.IsSet(f.Name) || isEnvVarSet(f.EnvVars)) {
|
||||||
value, err := isc.String(f.StringFlag.Name)
|
value, err := isc.String(f.StringFlag.Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -153,7 +155,7 @@ func (f *StringFlag) ApplyInputSourceValue(context *cli.Context, isc InputSource
|
||||||
}
|
}
|
||||||
if value != "" {
|
if value != "" {
|
||||||
for _, name := range f.Names() {
|
for _, name := range f.Names() {
|
||||||
_ = f.set.Set(name, value)
|
_ = context.Set(name, value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -163,7 +165,7 @@ func (f *StringFlag) ApplyInputSourceValue(context *cli.Context, isc InputSource
|
||||||
|
|
||||||
// ApplyInputSourceValue applies a Path value to the flagSet if required
|
// ApplyInputSourceValue applies a Path value to the flagSet if required
|
||||||
func (f *PathFlag) ApplyInputSourceValue(context *cli.Context, isc InputSourceContext) error {
|
func (f *PathFlag) ApplyInputSourceValue(context *cli.Context, isc InputSourceContext) error {
|
||||||
if f.set != nil {
|
if context != nil {
|
||||||
if !(context.IsSet(f.Name) || isEnvVarSet(f.EnvVars)) {
|
if !(context.IsSet(f.Name) || isEnvVarSet(f.EnvVars)) {
|
||||||
value, err := isc.String(f.PathFlag.Name)
|
value, err := isc.String(f.PathFlag.Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -181,7 +183,7 @@ func (f *PathFlag) ApplyInputSourceValue(context *cli.Context, isc InputSourceCo
|
||||||
value = filepath.Join(filepath.Dir(basePathAbs), value)
|
value = filepath.Join(filepath.Dir(basePathAbs), value)
|
||||||
}
|
}
|
||||||
|
|
||||||
_ = f.set.Set(name, value)
|
_ = context.Set(name, value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -191,7 +193,7 @@ func (f *PathFlag) ApplyInputSourceValue(context *cli.Context, isc InputSourceCo
|
||||||
|
|
||||||
// ApplyInputSourceValue applies a int value to the flagSet if required
|
// ApplyInputSourceValue applies a int value to the flagSet if required
|
||||||
func (f *IntFlag) ApplyInputSourceValue(context *cli.Context, isc InputSourceContext) error {
|
func (f *IntFlag) ApplyInputSourceValue(context *cli.Context, isc InputSourceContext) error {
|
||||||
if f.set != nil {
|
if context != nil {
|
||||||
if !(context.IsSet(f.Name) || isEnvVarSet(f.EnvVars)) {
|
if !(context.IsSet(f.Name) || isEnvVarSet(f.EnvVars)) {
|
||||||
value, err := isc.Int(f.IntFlag.Name)
|
value, err := isc.Int(f.IntFlag.Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -199,7 +201,7 @@ func (f *IntFlag) ApplyInputSourceValue(context *cli.Context, isc InputSourceCon
|
||||||
}
|
}
|
||||||
if value > 0 {
|
if value > 0 {
|
||||||
for _, name := range f.Names() {
|
for _, name := range f.Names() {
|
||||||
_ = f.set.Set(name, strconv.FormatInt(int64(value), 10))
|
_ = context.Set(name, strconv.FormatInt(int64(value), 10))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -209,7 +211,7 @@ func (f *IntFlag) ApplyInputSourceValue(context *cli.Context, isc InputSourceCon
|
||||||
|
|
||||||
// ApplyInputSourceValue applies a Duration value to the flagSet if required
|
// ApplyInputSourceValue applies a Duration value to the flagSet if required
|
||||||
func (f *DurationFlag) ApplyInputSourceValue(context *cli.Context, isc InputSourceContext) error {
|
func (f *DurationFlag) ApplyInputSourceValue(context *cli.Context, isc InputSourceContext) error {
|
||||||
if f.set != nil {
|
if context != nil {
|
||||||
if !(context.IsSet(f.Name) || isEnvVarSet(f.EnvVars)) {
|
if !(context.IsSet(f.Name) || isEnvVarSet(f.EnvVars)) {
|
||||||
value, err := isc.Duration(f.DurationFlag.Name)
|
value, err := isc.Duration(f.DurationFlag.Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -217,7 +219,7 @@ func (f *DurationFlag) ApplyInputSourceValue(context *cli.Context, isc InputSour
|
||||||
}
|
}
|
||||||
if value > 0 {
|
if value > 0 {
|
||||||
for _, name := range f.Names() {
|
for _, name := range f.Names() {
|
||||||
_ = f.set.Set(name, value.String())
|
_ = context.Set(name, value.String())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -227,7 +229,7 @@ func (f *DurationFlag) ApplyInputSourceValue(context *cli.Context, isc InputSour
|
||||||
|
|
||||||
// ApplyInputSourceValue applies a Float64 value to the flagSet if required
|
// ApplyInputSourceValue applies a Float64 value to the flagSet if required
|
||||||
func (f *Float64Flag) ApplyInputSourceValue(context *cli.Context, isc InputSourceContext) error {
|
func (f *Float64Flag) ApplyInputSourceValue(context *cli.Context, isc InputSourceContext) error {
|
||||||
if f.set != nil {
|
if context != nil {
|
||||||
if !(context.IsSet(f.Name) || isEnvVarSet(f.EnvVars)) {
|
if !(context.IsSet(f.Name) || isEnvVarSet(f.EnvVars)) {
|
||||||
value, err := isc.Float64(f.Float64Flag.Name)
|
value, err := isc.Float64(f.Float64Flag.Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -236,7 +238,7 @@ func (f *Float64Flag) ApplyInputSourceValue(context *cli.Context, isc InputSourc
|
||||||
if value > 0 {
|
if value > 0 {
|
||||||
floatStr := float64ToString(value)
|
floatStr := float64ToString(value)
|
||||||
for _, name := range f.Names() {
|
for _, name := range f.Names() {
|
||||||
_ = f.set.Set(name, floatStr)
|
_ = context.Set(name, floatStr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Code generated by fg; DO NOT EDIT.
|
// Code generated by fg.py; DO NOT EDIT.
|
||||||
|
|
||||||
package altsrc
|
package altsrc
|
||||||
|
|
||||||
|
@ -14,6 +14,7 @@ type BoolFlag struct {
|
||||||
*cli.BoolFlag
|
*cli.BoolFlag
|
||||||
set *flag.FlagSet
|
set *flag.FlagSet
|
||||||
}
|
}
|
||||||
|
var _ FlagInputSourceExtension = (*BoolFlag)(nil)
|
||||||
|
|
||||||
// NewBoolFlag creates a new BoolFlag
|
// NewBoolFlag creates a new BoolFlag
|
||||||
func NewBoolFlag(fl *cli.BoolFlag) *BoolFlag {
|
func NewBoolFlag(fl *cli.BoolFlag) *BoolFlag {
|
||||||
|
@ -33,6 +34,7 @@ type DurationFlag struct {
|
||||||
*cli.DurationFlag
|
*cli.DurationFlag
|
||||||
set *flag.FlagSet
|
set *flag.FlagSet
|
||||||
}
|
}
|
||||||
|
var _ FlagInputSourceExtension = (*DurationFlag)(nil)
|
||||||
|
|
||||||
// NewDurationFlag creates a new DurationFlag
|
// NewDurationFlag creates a new DurationFlag
|
||||||
func NewDurationFlag(fl *cli.DurationFlag) *DurationFlag {
|
func NewDurationFlag(fl *cli.DurationFlag) *DurationFlag {
|
||||||
|
@ -52,6 +54,7 @@ type Float64Flag struct {
|
||||||
*cli.Float64Flag
|
*cli.Float64Flag
|
||||||
set *flag.FlagSet
|
set *flag.FlagSet
|
||||||
}
|
}
|
||||||
|
var _ FlagInputSourceExtension = (*Float64Flag)(nil)
|
||||||
|
|
||||||
// NewFloat64Flag creates a new Float64Flag
|
// NewFloat64Flag creates a new Float64Flag
|
||||||
func NewFloat64Flag(fl *cli.Float64Flag) *Float64Flag {
|
func NewFloat64Flag(fl *cli.Float64Flag) *Float64Flag {
|
||||||
|
@ -71,6 +74,7 @@ type GenericFlag struct {
|
||||||
*cli.GenericFlag
|
*cli.GenericFlag
|
||||||
set *flag.FlagSet
|
set *flag.FlagSet
|
||||||
}
|
}
|
||||||
|
var _ FlagInputSourceExtension = (*GenericFlag)(nil)
|
||||||
|
|
||||||
// NewGenericFlag creates a new GenericFlag
|
// NewGenericFlag creates a new GenericFlag
|
||||||
func NewGenericFlag(fl *cli.GenericFlag) *GenericFlag {
|
func NewGenericFlag(fl *cli.GenericFlag) *GenericFlag {
|
||||||
|
@ -84,31 +88,13 @@ func (f *GenericFlag) Apply(set *flag.FlagSet) error {
|
||||||
return f.GenericFlag.Apply(set)
|
return f.GenericFlag.Apply(set)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Int64Flag is the flag type that wraps cli.Int64Flag to allow
|
|
||||||
// for other values to be specified
|
|
||||||
type Int64Flag struct {
|
|
||||||
*cli.Int64Flag
|
|
||||||
set *flag.FlagSet
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewInt64Flag creates a new Int64Flag
|
|
||||||
func NewInt64Flag(fl *cli.Int64Flag) *Int64Flag {
|
|
||||||
return &Int64Flag{Int64Flag: fl, set: nil}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Apply saves the flagSet for later usage calls, then calls
|
|
||||||
// the wrapped Int64Flag.Apply
|
|
||||||
func (f *Int64Flag) Apply(set *flag.FlagSet) error {
|
|
||||||
f.set = set
|
|
||||||
return f.Int64Flag.Apply(set)
|
|
||||||
}
|
|
||||||
|
|
||||||
// IntFlag is the flag type that wraps cli.IntFlag to allow
|
// IntFlag is the flag type that wraps cli.IntFlag to allow
|
||||||
// for other values to be specified
|
// for other values to be specified
|
||||||
type IntFlag struct {
|
type IntFlag struct {
|
||||||
*cli.IntFlag
|
*cli.IntFlag
|
||||||
set *flag.FlagSet
|
set *flag.FlagSet
|
||||||
}
|
}
|
||||||
|
var _ FlagInputSourceExtension = (*IntFlag)(nil)
|
||||||
|
|
||||||
// NewIntFlag creates a new IntFlag
|
// NewIntFlag creates a new IntFlag
|
||||||
func NewIntFlag(fl *cli.IntFlag) *IntFlag {
|
func NewIntFlag(fl *cli.IntFlag) *IntFlag {
|
||||||
|
@ -128,6 +114,7 @@ type IntSliceFlag struct {
|
||||||
*cli.IntSliceFlag
|
*cli.IntSliceFlag
|
||||||
set *flag.FlagSet
|
set *flag.FlagSet
|
||||||
}
|
}
|
||||||
|
var _ FlagInputSourceExtension = (*IntSliceFlag)(nil)
|
||||||
|
|
||||||
// NewIntSliceFlag creates a new IntSliceFlag
|
// NewIntSliceFlag creates a new IntSliceFlag
|
||||||
func NewIntSliceFlag(fl *cli.IntSliceFlag) *IntSliceFlag {
|
func NewIntSliceFlag(fl *cli.IntSliceFlag) *IntSliceFlag {
|
||||||
|
@ -141,42 +128,24 @@ func (f *IntSliceFlag) Apply(set *flag.FlagSet) error {
|
||||||
return f.IntSliceFlag.Apply(set)
|
return f.IntSliceFlag.Apply(set)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Int64SliceFlag is the flag type that wraps cli.Int64SliceFlag to allow
|
// PathFlag is the flag type that wraps cli.PathFlag to allow
|
||||||
// for other values to be specified
|
// for other values to be specified
|
||||||
type Int64SliceFlag struct {
|
type PathFlag struct {
|
||||||
*cli.Int64SliceFlag
|
*cli.PathFlag
|
||||||
set *flag.FlagSet
|
set *flag.FlagSet
|
||||||
}
|
}
|
||||||
|
var _ FlagInputSourceExtension = (*PathFlag)(nil)
|
||||||
|
|
||||||
// NewInt64SliceFlag creates a new Int64SliceFlag
|
// NewPathFlag creates a new PathFlag
|
||||||
func NewInt64SliceFlag(fl *cli.Int64SliceFlag) *Int64SliceFlag {
|
func NewPathFlag(fl *cli.PathFlag) *PathFlag {
|
||||||
return &Int64SliceFlag{Int64SliceFlag: fl, set: nil}
|
return &PathFlag{PathFlag: fl, set: nil}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply saves the flagSet for later usage calls, then calls
|
// Apply saves the flagSet for later usage calls, then calls
|
||||||
// the wrapped Int64SliceFlag.Apply
|
// the wrapped PathFlag.Apply
|
||||||
func (f *Int64SliceFlag) Apply(set *flag.FlagSet) error {
|
func (f *PathFlag) Apply(set *flag.FlagSet) error {
|
||||||
f.set = set
|
f.set = set
|
||||||
return f.Int64SliceFlag.Apply(set)
|
return f.PathFlag.Apply(set)
|
||||||
}
|
|
||||||
|
|
||||||
// Float64SliceFlag is the flag type that wraps cli.Float64SliceFlag to allow
|
|
||||||
// for other values to be specified
|
|
||||||
type Float64SliceFlag struct {
|
|
||||||
*cli.Float64SliceFlag
|
|
||||||
set *flag.FlagSet
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewFloat64SliceFlag creates a new Float64SliceFlag
|
|
||||||
func NewFloat64SliceFlag(fl *cli.Float64SliceFlag) *Float64SliceFlag {
|
|
||||||
return &Float64SliceFlag{Float64SliceFlag: fl, set: nil}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Apply saves the flagSet for later usage calls, then calls the
|
|
||||||
// wrapped Float64SliceFlag.Apply
|
|
||||||
func (f *Float64SliceFlag) Apply(set *flag.FlagSet) error {
|
|
||||||
f.set = set
|
|
||||||
return f.Float64SliceFlag.Apply(set)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// StringFlag is the flag type that wraps cli.StringFlag to allow
|
// StringFlag is the flag type that wraps cli.StringFlag to allow
|
||||||
|
@ -185,6 +154,7 @@ type StringFlag struct {
|
||||||
*cli.StringFlag
|
*cli.StringFlag
|
||||||
set *flag.FlagSet
|
set *flag.FlagSet
|
||||||
}
|
}
|
||||||
|
var _ FlagInputSourceExtension = (*StringFlag)(nil)
|
||||||
|
|
||||||
// NewStringFlag creates a new StringFlag
|
// NewStringFlag creates a new StringFlag
|
||||||
func NewStringFlag(fl *cli.StringFlag) *StringFlag {
|
func NewStringFlag(fl *cli.StringFlag) *StringFlag {
|
||||||
|
@ -198,31 +168,13 @@ func (f *StringFlag) Apply(set *flag.FlagSet) error {
|
||||||
return f.StringFlag.Apply(set)
|
return f.StringFlag.Apply(set)
|
||||||
}
|
}
|
||||||
|
|
||||||
// PathFlag is the flag type that wraps cli.PathFlag to allow
|
|
||||||
// for other values to be specified
|
|
||||||
type PathFlag struct {
|
|
||||||
*cli.PathFlag
|
|
||||||
set *flag.FlagSet
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewPathFlag creates a new PathFlag
|
|
||||||
func NewPathFlag(fl *cli.PathFlag) *PathFlag {
|
|
||||||
return &PathFlag{PathFlag: fl, set: nil}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Apply saves the flagSet for later usage calls, then calls the
|
|
||||||
// wrapped PathFlag.Apply
|
|
||||||
func (f *PathFlag) Apply(set *flag.FlagSet) error {
|
|
||||||
f.set = set
|
|
||||||
return f.PathFlag.Apply(set)
|
|
||||||
}
|
|
||||||
|
|
||||||
// StringSliceFlag is the flag type that wraps cli.StringSliceFlag to allow
|
// StringSliceFlag is the flag type that wraps cli.StringSliceFlag to allow
|
||||||
// for other values to be specified
|
// for other values to be specified
|
||||||
type StringSliceFlag struct {
|
type StringSliceFlag struct {
|
||||||
*cli.StringSliceFlag
|
*cli.StringSliceFlag
|
||||||
set *flag.FlagSet
|
set *flag.FlagSet
|
||||||
}
|
}
|
||||||
|
var _ FlagInputSourceExtension = (*StringSliceFlag)(nil)
|
||||||
|
|
||||||
// NewStringSliceFlag creates a new StringSliceFlag
|
// NewStringSliceFlag creates a new StringSliceFlag
|
||||||
func NewStringSliceFlag(fl *cli.StringSliceFlag) *StringSliceFlag {
|
func NewStringSliceFlag(fl *cli.StringSliceFlag) *StringSliceFlag {
|
||||||
|
@ -235,41 +187,3 @@ func (f *StringSliceFlag) Apply(set *flag.FlagSet) error {
|
||||||
f.set = set
|
f.set = set
|
||||||
return f.StringSliceFlag.Apply(set)
|
return f.StringSliceFlag.Apply(set)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Uint64Flag is the flag type that wraps cli.Uint64Flag to allow
|
|
||||||
// for other values to be specified
|
|
||||||
type Uint64Flag struct {
|
|
||||||
*cli.Uint64Flag
|
|
||||||
set *flag.FlagSet
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewUint64Flag creates a new Uint64Flag
|
|
||||||
func NewUint64Flag(fl *cli.Uint64Flag) *Uint64Flag {
|
|
||||||
return &Uint64Flag{Uint64Flag: fl, set: nil}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Apply saves the flagSet for later usage calls, then calls
|
|
||||||
// the wrapped Uint64Flag.Apply
|
|
||||||
func (f *Uint64Flag) Apply(set *flag.FlagSet) error {
|
|
||||||
f.set = set
|
|
||||||
return f.Uint64Flag.Apply(set)
|
|
||||||
}
|
|
||||||
|
|
||||||
// UintFlag is the flag type that wraps cli.UintFlag to allow
|
|
||||||
// for other values to be specified
|
|
||||||
type UintFlag struct {
|
|
||||||
*cli.UintFlag
|
|
||||||
set *flag.FlagSet
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewUintFlag creates a new UintFlag
|
|
||||||
func NewUintFlag(fl *cli.UintFlag) *UintFlag {
|
|
||||||
return &UintFlag{UintFlag: fl, set: nil}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Apply saves the flagSet for later usage calls, then calls
|
|
||||||
// the wrapped UintFlag.Apply
|
|
||||||
func (f *UintFlag) Apply(set *flag.FlagSet) error {
|
|
||||||
f.set = set
|
|
||||||
return f.UintFlag.Apply(set)
|
|
||||||
}
|
|
||||||
|
|
|
@ -17,7 +17,11 @@ import (
|
||||||
// by the given flag.
|
// by the given flag.
|
||||||
func NewJSONSourceFromFlagFunc(flag string) func(c *cli.Context) (InputSourceContext, error) {
|
func NewJSONSourceFromFlagFunc(flag string) func(c *cli.Context) (InputSourceContext, error) {
|
||||||
return func(context *cli.Context) (InputSourceContext, error) {
|
return func(context *cli.Context) (InputSourceContext, error) {
|
||||||
return NewJSONSourceFromFile(context.String(flag))
|
if context.IsSet(flag) {
|
||||||
|
return NewJSONSourceFromFile(context.String(flag))
|
||||||
|
}
|
||||||
|
|
||||||
|
return defaultInputSource()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,11 @@ type MapInputSource struct {
|
||||||
valueMap map[interface{}]interface{}
|
valueMap map[interface{}]interface{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewMapInputSource creates a new MapInputSource for implementing custom input sources.
|
||||||
|
func NewMapInputSource(file string, valueMap map[interface{}]interface{}) *MapInputSource {
|
||||||
|
return &MapInputSource{file: file, valueMap: valueMap}
|
||||||
|
}
|
||||||
|
|
||||||
// nestedVal checks if the name has '.' delimiters.
|
// nestedVal checks if the name has '.' delimiters.
|
||||||
// If so, it tries to traverse the tree by the '.' delimited sections to find
|
// If so, it tries to traverse the tree by the '.' delimited sections to find
|
||||||
// a nested value for the key.
|
// a nested value for the key.
|
||||||
|
|
|
@ -87,8 +87,12 @@ func NewTomlSourceFromFile(file string) (InputSourceContext, error) {
|
||||||
// NewTomlSourceFromFlagFunc creates a new TOML InputSourceContext from a provided flag name and source context.
|
// NewTomlSourceFromFlagFunc creates a new TOML InputSourceContext from a provided flag name and source context.
|
||||||
func NewTomlSourceFromFlagFunc(flagFileName string) func(context *cli.Context) (InputSourceContext, error) {
|
func NewTomlSourceFromFlagFunc(flagFileName string) func(context *cli.Context) (InputSourceContext, error) {
|
||||||
return func(context *cli.Context) (InputSourceContext, error) {
|
return func(context *cli.Context) (InputSourceContext, error) {
|
||||||
filePath := context.String(flagFileName)
|
if context.IsSet(flagFileName) {
|
||||||
return NewTomlSourceFromFile(filePath)
|
filePath := context.String(flagFileName)
|
||||||
|
return NewTomlSourceFromFile(filePath)
|
||||||
|
}
|
||||||
|
|
||||||
|
return defaultInputSource()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,8 +33,12 @@ func NewYamlSourceFromFile(file string) (InputSourceContext, error) {
|
||||||
// NewYamlSourceFromFlagFunc creates a new Yaml InputSourceContext from a provided flag name and source context.
|
// NewYamlSourceFromFlagFunc creates a new Yaml InputSourceContext from a provided flag name and source context.
|
||||||
func NewYamlSourceFromFlagFunc(flagFileName string) func(context *cli.Context) (InputSourceContext, error) {
|
func NewYamlSourceFromFlagFunc(flagFileName string) func(context *cli.Context) (InputSourceContext, error) {
|
||||||
return func(context *cli.Context) (InputSourceContext, error) {
|
return func(context *cli.Context) (InputSourceContext, error) {
|
||||||
filePath := context.String(flagFileName)
|
if context.IsSet(flagFileName) {
|
||||||
return NewYamlSourceFromFile(filePath)
|
filePath := context.String(flagFileName)
|
||||||
|
return NewYamlSourceFromFile(filePath)
|
||||||
|
}
|
||||||
|
|
||||||
|
return defaultInputSource()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -64,7 +64,7 @@ type App struct {
|
||||||
Action ActionFunc
|
Action ActionFunc
|
||||||
// Execute this function if the proper command cannot be found
|
// Execute this function if the proper command cannot be found
|
||||||
CommandNotFound CommandNotFoundFunc
|
CommandNotFound CommandNotFoundFunc
|
||||||
// Execute this function if an usage error occurs
|
// Execute this function if a usage error occurs
|
||||||
OnUsageError OnUsageErrorFunc
|
OnUsageError OnUsageErrorFunc
|
||||||
// Compilation date
|
// Compilation date
|
||||||
Compiled time.Time
|
Compiled time.Time
|
||||||
|
@ -72,12 +72,15 @@ type App struct {
|
||||||
Authors []*Author
|
Authors []*Author
|
||||||
// Copyright of the binary if any
|
// Copyright of the binary if any
|
||||||
Copyright string
|
Copyright string
|
||||||
|
// Reader reader to write input to (useful for tests)
|
||||||
|
Reader io.Reader
|
||||||
// Writer writer to write output to
|
// Writer writer to write output to
|
||||||
Writer io.Writer
|
Writer io.Writer
|
||||||
// ErrWriter writes error output
|
// ErrWriter writes error output
|
||||||
ErrWriter io.Writer
|
ErrWriter io.Writer
|
||||||
// Execute this function to handle ExitErrors. If not provided, HandleExitCoder is provided to
|
// ExitErrHandler processes any error encountered while running an App before
|
||||||
// function as a default, so this is optional.
|
// it is returned to the caller. If no function is provided, HandleExitCoder
|
||||||
|
// is used as the default behavior.
|
||||||
ExitErrHandler ExitErrHandlerFunc
|
ExitErrHandler ExitErrHandlerFunc
|
||||||
// Other custom info
|
// Other custom info
|
||||||
Metadata map[string]interface{}
|
Metadata map[string]interface{}
|
||||||
|
@ -116,7 +119,9 @@ func NewApp() *App {
|
||||||
BashComplete: DefaultAppComplete,
|
BashComplete: DefaultAppComplete,
|
||||||
Action: helpCommand.Action,
|
Action: helpCommand.Action,
|
||||||
Compiled: compileTime(),
|
Compiled: compileTime(),
|
||||||
|
Reader: os.Stdin,
|
||||||
Writer: os.Stdout,
|
Writer: os.Stdout,
|
||||||
|
ErrWriter: os.Stderr,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -135,7 +140,7 @@ func (a *App) Setup() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if a.HelpName == "" {
|
if a.HelpName == "" {
|
||||||
a.HelpName = filepath.Base(os.Args[0])
|
a.HelpName = a.Name
|
||||||
}
|
}
|
||||||
|
|
||||||
if a.Usage == "" {
|
if a.Usage == "" {
|
||||||
|
@ -158,10 +163,18 @@ func (a *App) Setup() {
|
||||||
a.Compiled = compileTime()
|
a.Compiled = compileTime()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if a.Reader == nil {
|
||||||
|
a.Reader = os.Stdin
|
||||||
|
}
|
||||||
|
|
||||||
if a.Writer == nil {
|
if a.Writer == nil {
|
||||||
a.Writer = os.Stdout
|
a.Writer = os.Stdout
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if a.ErrWriter == nil {
|
||||||
|
a.ErrWriter = os.Stderr
|
||||||
|
}
|
||||||
|
|
||||||
var newCommands []*Command
|
var newCommands []*Command
|
||||||
|
|
||||||
for _, c := range a.Commands {
|
for _, c := range a.Commands {
|
||||||
|
@ -195,10 +208,6 @@ func (a *App) Setup() {
|
||||||
if a.Metadata == nil {
|
if a.Metadata == nil {
|
||||||
a.Metadata = make(map[string]interface{})
|
a.Metadata = make(map[string]interface{})
|
||||||
}
|
}
|
||||||
|
|
||||||
if a.Writer == nil {
|
|
||||||
a.Writer = os.Stdout
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *App) newFlagSet() (*flag.FlagSet, error) {
|
func (a *App) newFlagSet() (*flag.FlagSet, error) {
|
||||||
|
@ -290,8 +299,6 @@ func (a *App) RunContext(ctx context.Context, arguments []string) (err error) {
|
||||||
if a.Before != nil {
|
if a.Before != nil {
|
||||||
beforeErr := a.Before(context)
|
beforeErr := a.Before(context)
|
||||||
if beforeErr != nil {
|
if beforeErr != nil {
|
||||||
_, _ = fmt.Fprintf(a.Writer, "%v\n\n", beforeErr)
|
|
||||||
_ = ShowAppHelp(context)
|
|
||||||
a.handleExitCoder(context, beforeErr)
|
a.handleExitCoder(context, beforeErr)
|
||||||
err = beforeErr
|
err = beforeErr
|
||||||
return err
|
return err
|
||||||
|
@ -321,11 +328,11 @@ func (a *App) RunContext(ctx context.Context, arguments []string) (err error) {
|
||||||
// RunAndExitOnError calls .Run() and exits non-zero if an error was returned
|
// RunAndExitOnError calls .Run() and exits non-zero if an error was returned
|
||||||
//
|
//
|
||||||
// Deprecated: instead you should return an error that fulfills cli.ExitCoder
|
// Deprecated: instead you should return an error that fulfills cli.ExitCoder
|
||||||
// to cli.App.Run. This will cause the application to exit with the given eror
|
// to cli.App.Run. This will cause the application to exit with the given error
|
||||||
// code in the cli.ExitCoder
|
// code in the cli.ExitCoder
|
||||||
func (a *App) RunAndExitOnError() {
|
func (a *App) RunAndExitOnError() {
|
||||||
if err := a.Run(os.Args); err != nil {
|
if err := a.Run(os.Args); err != nil {
|
||||||
_, _ = fmt.Fprintln(a.errWriter(), err)
|
_, _ = fmt.Fprintln(a.ErrWriter, err)
|
||||||
OsExiter(1)
|
OsExiter(1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -479,15 +486,6 @@ func (a *App) VisibleFlags() []Flag {
|
||||||
return visibleFlags(a.Flags)
|
return visibleFlags(a.Flags)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *App) errWriter() io.Writer {
|
|
||||||
// When the app ErrWriter is nil use the package level one.
|
|
||||||
if a.ErrWriter == nil {
|
|
||||||
return ErrWriter
|
|
||||||
}
|
|
||||||
|
|
||||||
return a.ErrWriter
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *App) appendFlag(fl Flag) {
|
func (a *App) appendFlag(fl Flag) {
|
||||||
if !hasFlag(a.Flags, fl) {
|
if !hasFlag(a.Flags, fl) {
|
||||||
a.Flags = append(a.Flags, fl)
|
a.Flags = append(a.Flags, fl)
|
||||||
|
|
|
@ -150,7 +150,6 @@ func (c *Command) Run(ctx *Context) (err error) {
|
||||||
if c.Before != nil {
|
if c.Before != nil {
|
||||||
err = c.Before(context)
|
err = c.Before(context)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
_ = ShowCommandHelp(context, c.Name)
|
|
||||||
context.App.handleExitCoder(context, err)
|
context.App.handleExitCoder(context, err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -242,8 +241,9 @@ func (c *Command) startApp(ctx *Context) error {
|
||||||
app.HideHelpCommand = c.HideHelpCommand
|
app.HideHelpCommand = c.HideHelpCommand
|
||||||
|
|
||||||
app.Version = ctx.App.Version
|
app.Version = ctx.App.Version
|
||||||
app.HideVersion = ctx.App.HideVersion
|
app.HideVersion = true
|
||||||
app.Compiled = ctx.App.Compiled
|
app.Compiled = ctx.App.Compiled
|
||||||
|
app.Reader = ctx.App.Reader
|
||||||
app.Writer = ctx.App.Writer
|
app.Writer = ctx.App.Writer
|
||||||
app.ErrWriter = ctx.App.ErrWriter
|
app.ErrWriter = ctx.App.ErrWriter
|
||||||
app.ExitErrHandler = ctx.App.ExitErrHandler
|
app.ExitErrHandler = ctx.App.ExitErrHandler
|
||||||
|
|
|
@ -18,6 +18,7 @@ type Context struct {
|
||||||
Command *Command
|
Command *Command
|
||||||
shellComplete bool
|
shellComplete bool
|
||||||
flagSet *flag.FlagSet
|
flagSet *flag.FlagSet
|
||||||
|
fromFlagSet map[string]bool
|
||||||
parentContext *Context
|
parentContext *Context
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,6 +33,14 @@ func NewContext(app *App, set *flag.FlagSet, parentCtx *Context) *Context {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// pre-compute flag seen on the command line at this context
|
||||||
|
c.fromFlagSet = make(map[string]bool)
|
||||||
|
if set != nil {
|
||||||
|
set.Visit(func(f *flag.Flag) {
|
||||||
|
c.fromFlagSet[f.Name] = true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
c.Command = &Command{}
|
c.Command = &Command{}
|
||||||
|
|
||||||
if c.Context == nil {
|
if c.Context == nil {
|
||||||
|
@ -48,35 +57,50 @@ func (c *Context) NumFlags() int {
|
||||||
|
|
||||||
// Set sets a context flag to a value.
|
// Set sets a context flag to a value.
|
||||||
func (c *Context) Set(name, value string) error {
|
func (c *Context) Set(name, value string) error {
|
||||||
return c.flagSet.Set(name, value)
|
err := c.flagSet.Set(name, value)
|
||||||
|
if err == nil {
|
||||||
|
c.fromFlagSet[name] = true
|
||||||
|
}
|
||||||
|
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsSet determines if the flag was actually set
|
// IsSet determines if the flag was actually set
|
||||||
func (c *Context) IsSet(name string) bool {
|
func (c *Context) IsSet(name string) bool {
|
||||||
if fs := lookupFlagSet(name, c); fs != nil {
|
for ctx := c; ctx != nil; ctx = ctx.parentContext {
|
||||||
if fs := lookupFlagSet(name, c); fs != nil {
|
// try flags parsed from command line first
|
||||||
isSet := false
|
if ctx.flagSet.Lookup(name) == nil {
|
||||||
fs.Visit(func(f *flag.Flag) {
|
// flag not defined in this context
|
||||||
if f.Name == name {
|
continue
|
||||||
isSet = true
|
}
|
||||||
|
if ctx.flagOnCommandLine(name) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// now see if value was set externally via environment
|
||||||
|
definedFlags := ctx.Command.Flags
|
||||||
|
if ctx.Command.Name == "" && ctx.App != nil {
|
||||||
|
definedFlags = ctx.App.Flags
|
||||||
|
}
|
||||||
|
for _, ff := range definedFlags {
|
||||||
|
for _, fn := range ff.Names() {
|
||||||
|
if fn == name {
|
||||||
|
if ff.IsSet() {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
break
|
||||||
}
|
}
|
||||||
})
|
|
||||||
if isSet {
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
f := lookupFlag(name, c)
|
|
||||||
if f == nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
return f.IsSet()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Context) flagOnCommandLine(name string) bool {
|
||||||
|
return c.fromFlagSet[name]
|
||||||
|
}
|
||||||
|
|
||||||
// LocalFlagNames returns a slice of flag names used in this context.
|
// LocalFlagNames returns a slice of flag names used in this context.
|
||||||
func (c *Context) LocalFlagNames() []string {
|
func (c *Context) LocalFlagNames() []string {
|
||||||
var names []string
|
var names []string
|
||||||
|
@ -108,7 +132,10 @@ func (c *Context) Lineage() []*Context {
|
||||||
|
|
||||||
// Value returns the value of the flag corresponding to `name`
|
// Value returns the value of the flag corresponding to `name`
|
||||||
func (c *Context) Value(name string) interface{} {
|
func (c *Context) Value(name string) interface{} {
|
||||||
return c.flagSet.Lookup(name).Value.(flag.Getter).Get()
|
if fs := lookupFlagSet(name, c); fs != nil {
|
||||||
|
return fs.Lookup(name).Value.(flag.Getter).Get()
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Args returns the command line arguments associated with the context.
|
// Args returns the command line arguments associated with the context.
|
||||||
|
@ -150,6 +177,25 @@ func lookupFlag(name string, ctx *Context) Flag {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Context) resolveFlagDeep(name string) *flag.Flag {
|
||||||
|
var src *flag.Flag
|
||||||
|
for cur := c; cur != nil; cur = cur.parentContext {
|
||||||
|
if f := cur.flagSet.Lookup(name); f != nil {
|
||||||
|
if cur.flagOnCommandLine(name) {
|
||||||
|
// we've found most specific instance on command line, use it
|
||||||
|
src = f
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if src == nil {
|
||||||
|
// flag was defined, but value is not present among flags of the current context
|
||||||
|
// remember the most specific instance of the flag not from command line as fallback
|
||||||
|
src = f
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return src
|
||||||
|
}
|
||||||
|
|
||||||
func lookupFlagSet(name string, ctx *Context) *flag.FlagSet {
|
func lookupFlagSet(name string, ctx *Context) *flag.FlagSet {
|
||||||
for _, c := range ctx.Lineage() {
|
for _, c := range ctx.Lineage() {
|
||||||
if f := c.flagSet.Lookup(name); f != nil {
|
if f := c.flagSet.Lookup(name); f != nil {
|
||||||
|
|
|
@ -15,31 +15,39 @@ import (
|
||||||
// The function errors if either parsing or writing of the string fails.
|
// The function errors if either parsing or writing of the string fails.
|
||||||
func (a *App) ToMarkdown() (string, error) {
|
func (a *App) ToMarkdown() (string, error) {
|
||||||
var w bytes.Buffer
|
var w bytes.Buffer
|
||||||
if err := a.writeDocTemplate(&w); err != nil {
|
if err := a.writeDocTemplate(&w, 8); err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
return w.String(), nil
|
return w.String(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ToMan creates a man page string for the `*App`
|
// ToMan creates a man page string with section number for the `*App`
|
||||||
// The function errors if either parsing or writing of the string fails.
|
// The function errors if either parsing or writing of the string fails.
|
||||||
func (a *App) ToMan() (string, error) {
|
func (a *App) ToManWithSection(sectionNumber int) (string, error) {
|
||||||
var w bytes.Buffer
|
var w bytes.Buffer
|
||||||
if err := a.writeDocTemplate(&w); err != nil {
|
if err := a.writeDocTemplate(&w, sectionNumber); err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
man := md2man.Render(w.Bytes())
|
man := md2man.Render(w.Bytes())
|
||||||
return string(man), nil
|
return string(man), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ToMan creates a man page string for the `*App`
|
||||||
|
// The function errors if either parsing or writing of the string fails.
|
||||||
|
func (a *App) ToMan() (string, error) {
|
||||||
|
man, err := a.ToManWithSection(8)
|
||||||
|
return man, err
|
||||||
|
}
|
||||||
|
|
||||||
type cliTemplate struct {
|
type cliTemplate struct {
|
||||||
App *App
|
App *App
|
||||||
|
SectionNum int
|
||||||
Commands []string
|
Commands []string
|
||||||
GlobalArgs []string
|
GlobalArgs []string
|
||||||
SynopsisArgs []string
|
SynopsisArgs []string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *App) writeDocTemplate(w io.Writer) error {
|
func (a *App) writeDocTemplate(w io.Writer, sectionNum int) error {
|
||||||
const name = "cli"
|
const name = "cli"
|
||||||
t, err := template.New(name).Parse(MarkdownDocTemplate)
|
t, err := template.New(name).Parse(MarkdownDocTemplate)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -47,6 +55,7 @@ func (a *App) writeDocTemplate(w io.Writer) error {
|
||||||
}
|
}
|
||||||
return t.ExecuteTemplate(w, name, &cliTemplate{
|
return t.ExecuteTemplate(w, name, &cliTemplate{
|
||||||
App: a,
|
App: a,
|
||||||
|
SectionNum: sectionNum,
|
||||||
Commands: prepareCommands(a.Commands, 0),
|
Commands: prepareCommands(a.Commands, 0),
|
||||||
GlobalArgs: prepareArgsWithValues(a.VisibleFlags()),
|
GlobalArgs: prepareArgsWithValues(a.VisibleFlags()),
|
||||||
SynopsisArgs: prepareArgsSynopsis(a.VisibleFlags()),
|
SynopsisArgs: prepareArgsSynopsis(a.VisibleFlags()),
|
||||||
|
|
|
@ -17,11 +17,10 @@ var ErrWriter io.Writer = os.Stderr
|
||||||
// MultiError is an error that wraps multiple errors.
|
// MultiError is an error that wraps multiple errors.
|
||||||
type MultiError interface {
|
type MultiError interface {
|
||||||
error
|
error
|
||||||
// Errors returns a copy of the errors slice
|
|
||||||
Errors() []error
|
Errors() []error
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewMultiError creates a new MultiError. Pass in one or more errors.
|
// newMultiError creates a new MultiError. Pass in one or more errors.
|
||||||
func newMultiError(err ...error) MultiError {
|
func newMultiError(err ...error) MultiError {
|
||||||
ret := multiError(err)
|
ret := multiError(err)
|
||||||
return &ret
|
return &ret
|
||||||
|
@ -65,13 +64,20 @@ type exitError struct {
|
||||||
message interface{}
|
message interface{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewExitError makes a new *exitError
|
// NewExitError calls Exit to create a new ExitCoder.
|
||||||
|
//
|
||||||
|
// Deprecated: This function is a duplicate of Exit and will eventually be removed.
|
||||||
func NewExitError(message interface{}, exitCode int) ExitCoder {
|
func NewExitError(message interface{}, exitCode int) ExitCoder {
|
||||||
return Exit(message, exitCode)
|
return Exit(message, exitCode)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Exit wraps a message and exit code into an ExitCoder suitable for handling by
|
// Exit wraps a message and exit code into an error, which by default is
|
||||||
// HandleExitCoder
|
// handled with a call to os.Exit during default error handling.
|
||||||
|
//
|
||||||
|
// This is the simplest way to trigger a non-zero exit code for an App without
|
||||||
|
// having to call os.Exit manually. During testing, this behavior can be avoided
|
||||||
|
// by overiding the ExitErrHandler function on an App or the package-global
|
||||||
|
// OsExiter function.
|
||||||
func Exit(message interface{}, exitCode int) ExitCoder {
|
func Exit(message interface{}, exitCode int) ExitCoder {
|
||||||
return &exitError{
|
return &exitError{
|
||||||
message: message,
|
message: message,
|
||||||
|
@ -87,10 +93,14 @@ func (ee *exitError) ExitCode() int {
|
||||||
return ee.exitCode
|
return ee.exitCode
|
||||||
}
|
}
|
||||||
|
|
||||||
// HandleExitCoder checks if the error fulfills the ExitCoder interface, and if
|
// HandleExitCoder handles errors implementing ExitCoder by printing their
|
||||||
// so prints the error to stderr (if it is non-empty) and calls OsExiter with the
|
// message and calling OsExiter with the given exit code.
|
||||||
// given exit code. If the given error is a MultiError, then this func is
|
//
|
||||||
// called on all members of the Errors slice and calls OsExiter with the last exit code.
|
// If the given error instead implements MultiError, each error will be checked
|
||||||
|
// for the ExitCoder interface, and OsExiter will be called with the last exit
|
||||||
|
// code found, or exit code 1 if no ExitCoder is found.
|
||||||
|
//
|
||||||
|
// This function is the default error-handling behavior for an App.
|
||||||
func HandleExitCoder(err error) {
|
func HandleExitCoder(err error) {
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return
|
return
|
||||||
|
|
|
@ -171,6 +171,10 @@ func fishAddFileFlag(flag Flag, completion *strings.Builder) {
|
||||||
if f.TakesFile {
|
if f.TakesFile {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
case *PathFlag:
|
||||||
|
if f.TakesFile {
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
completion.WriteString(" -f")
|
completion.WriteString(" -f")
|
||||||
}
|
}
|
||||||
|
|
|
@ -359,7 +359,11 @@ func stringifySliceFlag(usage string, names, defaultVals []string) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
usageWithDefault := strings.TrimSpace(fmt.Sprintf("%s%s", usage, defaultVal))
|
usageWithDefault := strings.TrimSpace(fmt.Sprintf("%s%s", usage, defaultVal))
|
||||||
return fmt.Sprintf("%s\t%s", prefixedNames(names, placeholder), usageWithDefault)
|
multiInputString := "(accepts multiple inputs)"
|
||||||
|
if usageWithDefault != "" {
|
||||||
|
multiInputString = "\t" + multiInputString
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("%s\t%s%s", prefixedNames(names, placeholder), usageWithDefault, multiInputString)
|
||||||
}
|
}
|
||||||
|
|
||||||
func hasFlag(flags []Flag, fl Flag) bool {
|
func hasFlag(flags []Flag, fl Flag) bool {
|
||||||
|
|
|
@ -87,14 +87,10 @@ func (f *BoolFlag) Apply(set *flag.FlagSet) error {
|
||||||
// Bool looks up the value of a local BoolFlag, returns
|
// Bool looks up the value of a local BoolFlag, returns
|
||||||
// false if not found
|
// false if not found
|
||||||
func (c *Context) Bool(name string) bool {
|
func (c *Context) Bool(name string) bool {
|
||||||
if fs := lookupFlagSet(name, c); fs != nil {
|
return lookupBool(c.resolveFlagDeep(name))
|
||||||
return lookupBool(name, fs)
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func lookupBool(name string, set *flag.FlagSet) bool {
|
func lookupBool(f *flag.Flag) bool {
|
||||||
f := set.Lookup(name)
|
|
||||||
if f != nil {
|
if f != nil {
|
||||||
parsed, err := strconv.ParseBool(f.Value.String())
|
parsed, err := strconv.ParseBool(f.Value.String())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -86,14 +86,10 @@ func (f *DurationFlag) Apply(set *flag.FlagSet) error {
|
||||||
// Duration looks up the value of a local DurationFlag, returns
|
// Duration looks up the value of a local DurationFlag, returns
|
||||||
// 0 if not found
|
// 0 if not found
|
||||||
func (c *Context) Duration(name string) time.Duration {
|
func (c *Context) Duration(name string) time.Duration {
|
||||||
if fs := lookupFlagSet(name, c); fs != nil {
|
return lookupDuration(c.resolveFlagDeep(name))
|
||||||
return lookupDuration(name, fs)
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func lookupDuration(name string, set *flag.FlagSet) time.Duration {
|
func lookupDuration(f *flag.Flag) time.Duration {
|
||||||
f := set.Lookup(name)
|
|
||||||
if f != nil {
|
if f != nil {
|
||||||
parsed, err := time.ParseDuration(f.Value.String())
|
parsed, err := time.ParseDuration(f.Value.String())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -87,14 +87,10 @@ func (f *Float64Flag) Apply(set *flag.FlagSet) error {
|
||||||
// Float64 looks up the value of a local Float64Flag, returns
|
// Float64 looks up the value of a local Float64Flag, returns
|
||||||
// 0 if not found
|
// 0 if not found
|
||||||
func (c *Context) Float64(name string) float64 {
|
func (c *Context) Float64(name string) float64 {
|
||||||
if fs := lookupFlagSet(name, c); fs != nil {
|
return lookupFloat64(c.resolveFlagDeep(name))
|
||||||
return lookupFloat64(name, fs)
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func lookupFloat64(name string, set *flag.FlagSet) float64 {
|
func lookupFloat64(f *flag.Flag) float64 {
|
||||||
f := set.Lookup(name)
|
|
||||||
if f != nil {
|
if f != nil {
|
||||||
parsed, err := strconv.ParseFloat(f.Value.String(), 64)
|
parsed, err := strconv.ParseFloat(f.Value.String(), 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -146,14 +146,10 @@ func (f *Float64SliceFlag) Apply(set *flag.FlagSet) error {
|
||||||
// Float64Slice looks up the value of a local Float64SliceFlag, returns
|
// Float64Slice looks up the value of a local Float64SliceFlag, returns
|
||||||
// nil if not found
|
// nil if not found
|
||||||
func (c *Context) Float64Slice(name string) []float64 {
|
func (c *Context) Float64Slice(name string) []float64 {
|
||||||
if fs := lookupFlagSet(name, c); fs != nil {
|
return lookupFloat64Slice(c.resolveFlagDeep(name))
|
||||||
return lookupFloat64Slice(name, fs)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func lookupFloat64Slice(name string, set *flag.FlagSet) []float64 {
|
func lookupFloat64Slice(f *flag.Flag) []float64 {
|
||||||
f := set.Lookup(name)
|
|
||||||
if f != nil {
|
if f != nil {
|
||||||
if slice, ok := f.Value.(*Float64Slice); ok {
|
if slice, ok := f.Value.(*Float64Slice); ok {
|
||||||
return slice.Value()
|
return slice.Value()
|
||||||
|
|
|
@ -68,7 +68,7 @@ func (f *GenericFlag) GetValue() string {
|
||||||
|
|
||||||
// Apply takes the flagset and calls Set on the generic flag with the value
|
// Apply takes the flagset and calls Set on the generic flag with the value
|
||||||
// provided by the user for parsing by the flag
|
// provided by the user for parsing by the flag
|
||||||
func (f GenericFlag) Apply(set *flag.FlagSet) error {
|
func (f *GenericFlag) Apply(set *flag.FlagSet) error {
|
||||||
if val, ok := flagFromEnvOrFile(f.EnvVars, f.FilePath); ok {
|
if val, ok := flagFromEnvOrFile(f.EnvVars, f.FilePath); ok {
|
||||||
if val != "" {
|
if val != "" {
|
||||||
if err := f.Value.Set(val); err != nil {
|
if err := f.Value.Set(val); err != nil {
|
||||||
|
@ -89,14 +89,10 @@ func (f GenericFlag) Apply(set *flag.FlagSet) error {
|
||||||
// Generic looks up the value of a local GenericFlag, returns
|
// Generic looks up the value of a local GenericFlag, returns
|
||||||
// nil if not found
|
// nil if not found
|
||||||
func (c *Context) Generic(name string) interface{} {
|
func (c *Context) Generic(name string) interface{} {
|
||||||
if fs := lookupFlagSet(name, c); fs != nil {
|
return lookupGeneric(c.resolveFlagDeep(name))
|
||||||
return lookupGeneric(name, fs)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func lookupGeneric(name string, set *flag.FlagSet) interface{} {
|
func lookupGeneric(f *flag.Flag) interface{} {
|
||||||
f := set.Lookup(name)
|
|
||||||
if f != nil {
|
if f != nil {
|
||||||
parsed, err := f.Value, error(nil)
|
parsed, err := f.Value, error(nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -87,14 +87,10 @@ func (f *IntFlag) Apply(set *flag.FlagSet) error {
|
||||||
// Int looks up the value of a local IntFlag, returns
|
// Int looks up the value of a local IntFlag, returns
|
||||||
// 0 if not found
|
// 0 if not found
|
||||||
func (c *Context) Int(name string) int {
|
func (c *Context) Int(name string) int {
|
||||||
if fs := lookupFlagSet(name, c); fs != nil {
|
return lookupInt(c.resolveFlagDeep(name))
|
||||||
return lookupInt(name, fs)
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func lookupInt(name string, set *flag.FlagSet) int {
|
func lookupInt(f *flag.Flag) int {
|
||||||
f := set.Lookup(name)
|
|
||||||
if f != nil {
|
if f != nil {
|
||||||
parsed, err := strconv.ParseInt(f.Value.String(), 0, 64)
|
parsed, err := strconv.ParseInt(f.Value.String(), 0, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -86,14 +86,10 @@ func (f *Int64Flag) Apply(set *flag.FlagSet) error {
|
||||||
// Int64 looks up the value of a local Int64Flag, returns
|
// Int64 looks up the value of a local Int64Flag, returns
|
||||||
// 0 if not found
|
// 0 if not found
|
||||||
func (c *Context) Int64(name string) int64 {
|
func (c *Context) Int64(name string) int64 {
|
||||||
if fs := lookupFlagSet(name, c); fs != nil {
|
return lookupInt64(c.resolveFlagDeep(name))
|
||||||
return lookupInt64(name, fs)
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func lookupInt64(name string, set *flag.FlagSet) int64 {
|
func lookupInt64(f *flag.Flag) int64 {
|
||||||
f := set.Lookup(name)
|
|
||||||
if f != nil {
|
if f != nil {
|
||||||
parsed, err := strconv.ParseInt(f.Value.String(), 0, 64)
|
parsed, err := strconv.ParseInt(f.Value.String(), 0, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -145,11 +145,10 @@ func (f *Int64SliceFlag) Apply(set *flag.FlagSet) error {
|
||||||
// Int64Slice looks up the value of a local Int64SliceFlag, returns
|
// Int64Slice looks up the value of a local Int64SliceFlag, returns
|
||||||
// nil if not found
|
// nil if not found
|
||||||
func (c *Context) Int64Slice(name string) []int64 {
|
func (c *Context) Int64Slice(name string) []int64 {
|
||||||
return lookupInt64Slice(name, c.flagSet)
|
return lookupInt64Slice(c.resolveFlagDeep(name))
|
||||||
}
|
}
|
||||||
|
|
||||||
func lookupInt64Slice(name string, set *flag.FlagSet) []int64 {
|
func lookupInt64Slice(f *flag.Flag) []int64 {
|
||||||
f := set.Lookup(name)
|
|
||||||
if f != nil {
|
if f != nil {
|
||||||
if slice, ok := f.Value.(*Int64Slice); ok {
|
if slice, ok := f.Value.(*Int64Slice); ok {
|
||||||
return slice.Value()
|
return slice.Value()
|
||||||
|
|
|
@ -156,14 +156,10 @@ func (f *IntSliceFlag) Apply(set *flag.FlagSet) error {
|
||||||
// IntSlice looks up the value of a local IntSliceFlag, returns
|
// IntSlice looks up the value of a local IntSliceFlag, returns
|
||||||
// nil if not found
|
// nil if not found
|
||||||
func (c *Context) IntSlice(name string) []int {
|
func (c *Context) IntSlice(name string) []int {
|
||||||
if fs := lookupFlagSet(name, c); fs != nil {
|
return lookupIntSlice(c.resolveFlagDeep(name))
|
||||||
return lookupIntSlice(name, c.flagSet)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func lookupIntSlice(name string, set *flag.FlagSet) []int {
|
func lookupIntSlice(f *flag.Flag) []int {
|
||||||
f := set.Lookup(name)
|
|
||||||
if f != nil {
|
if f != nil {
|
||||||
if slice, ok := f.Value.(*IntSlice); ok {
|
if slice, ok := f.Value.(*IntSlice); ok {
|
||||||
return slice.Value()
|
return slice.Value()
|
||||||
|
|
|
@ -75,15 +75,10 @@ func (f *PathFlag) Apply(set *flag.FlagSet) error {
|
||||||
// Path looks up the value of a local PathFlag, returns
|
// Path looks up the value of a local PathFlag, returns
|
||||||
// "" if not found
|
// "" if not found
|
||||||
func (c *Context) Path(name string) string {
|
func (c *Context) Path(name string) string {
|
||||||
if fs := lookupFlagSet(name, c); fs != nil {
|
return lookupPath(c.resolveFlagDeep(name))
|
||||||
return lookupPath(name, fs)
|
|
||||||
}
|
|
||||||
|
|
||||||
return ""
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func lookupPath(name string, set *flag.FlagSet) string {
|
func lookupPath(f *flag.Flag) string {
|
||||||
f := set.Lookup(name)
|
|
||||||
if f != nil {
|
if f != nil {
|
||||||
parsed, err := f.Value.String(), error(nil)
|
parsed, err := f.Value.String(), error(nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -76,14 +76,10 @@ func (f *StringFlag) Apply(set *flag.FlagSet) error {
|
||||||
// String looks up the value of a local StringFlag, returns
|
// String looks up the value of a local StringFlag, returns
|
||||||
// "" if not found
|
// "" if not found
|
||||||
func (c *Context) String(name string) string {
|
func (c *Context) String(name string) string {
|
||||||
if fs := lookupFlagSet(name, c); fs != nil {
|
return lookupString(c.resolveFlagDeep(name))
|
||||||
return lookupString(name, fs)
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func lookupString(name string, set *flag.FlagSet) string {
|
func lookupString(f *flag.Flag) string {
|
||||||
f := set.Lookup(name)
|
|
||||||
if f != nil {
|
if f != nil {
|
||||||
parsed, err := f.Value.String(), error(nil)
|
parsed, err := f.Value.String(), error(nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -116,8 +116,17 @@ func (f *StringSliceFlag) GetValue() string {
|
||||||
|
|
||||||
// Apply populates the flag given the flag set and environment
|
// Apply populates the flag given the flag set and environment
|
||||||
func (f *StringSliceFlag) Apply(set *flag.FlagSet) error {
|
func (f *StringSliceFlag) Apply(set *flag.FlagSet) error {
|
||||||
|
|
||||||
|
if f.Destination != nil && f.Value != nil {
|
||||||
|
f.Destination.slice = make([]string, len(f.Value.slice))
|
||||||
|
copy(f.Destination.slice, f.Value.slice)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
if val, ok := flagFromEnvOrFile(f.EnvVars, f.FilePath); ok {
|
if val, ok := flagFromEnvOrFile(f.EnvVars, f.FilePath); ok {
|
||||||
f.Value = &StringSlice{}
|
if f.Value == nil {
|
||||||
|
f.Value = &StringSlice{}
|
||||||
|
}
|
||||||
destination := f.Value
|
destination := f.Value
|
||||||
if f.Destination != nil {
|
if f.Destination != nil {
|
||||||
destination = f.Destination
|
destination = f.Destination
|
||||||
|
@ -154,14 +163,10 @@ func (f *StringSliceFlag) Apply(set *flag.FlagSet) error {
|
||||||
// StringSlice looks up the value of a local StringSliceFlag, returns
|
// StringSlice looks up the value of a local StringSliceFlag, returns
|
||||||
// nil if not found
|
// nil if not found
|
||||||
func (c *Context) StringSlice(name string) []string {
|
func (c *Context) StringSlice(name string) []string {
|
||||||
if fs := lookupFlagSet(name, c); fs != nil {
|
return lookupStringSlice(c.resolveFlagDeep(name))
|
||||||
return lookupStringSlice(name, fs)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func lookupStringSlice(name string, set *flag.FlagSet) []string {
|
func lookupStringSlice(f *flag.Flag) []string {
|
||||||
f := set.Lookup(name)
|
|
||||||
if f != nil {
|
if f != nil {
|
||||||
if slice, ok := f.Value.(*StringSlice); ok {
|
if slice, ok := f.Value.(*StringSlice); ok {
|
||||||
return slice.Value()
|
return slice.Value()
|
||||||
|
|
|
@ -118,7 +118,9 @@ func (f *TimestampFlag) Apply(set *flag.FlagSet) error {
|
||||||
if f.Layout == "" {
|
if f.Layout == "" {
|
||||||
return fmt.Errorf("timestamp Layout is required")
|
return fmt.Errorf("timestamp Layout is required")
|
||||||
}
|
}
|
||||||
f.Value = &Timestamp{}
|
if f.Value == nil {
|
||||||
|
f.Value = &Timestamp{}
|
||||||
|
}
|
||||||
f.Value.SetLayout(f.Layout)
|
f.Value.SetLayout(f.Layout)
|
||||||
|
|
||||||
if val, ok := flagFromEnvOrFile(f.EnvVars, f.FilePath); ok {
|
if val, ok := flagFromEnvOrFile(f.EnvVars, f.FilePath); ok {
|
||||||
|
@ -136,15 +138,11 @@ func (f *TimestampFlag) Apply(set *flag.FlagSet) error {
|
||||||
|
|
||||||
// Timestamp gets the timestamp from a flag name
|
// Timestamp gets the timestamp from a flag name
|
||||||
func (c *Context) Timestamp(name string) *time.Time {
|
func (c *Context) Timestamp(name string) *time.Time {
|
||||||
if fs := lookupFlagSet(name, c); fs != nil {
|
return lookupTimestamp(c.resolveFlagDeep(name))
|
||||||
return lookupTimestamp(name, fs)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fetches the timestamp value from the local timestampWrap
|
// Fetches the timestamp value from the local timestampWrap
|
||||||
func lookupTimestamp(name string, set *flag.FlagSet) *time.Time {
|
func lookupTimestamp(f *flag.Flag) *time.Time {
|
||||||
f := set.Lookup(name)
|
|
||||||
if f != nil {
|
if f != nil {
|
||||||
return (f.Value.(*Timestamp)).Value()
|
return (f.Value.(*Timestamp)).Value()
|
||||||
}
|
}
|
||||||
|
|
|
@ -86,14 +86,10 @@ func (f *UintFlag) GetValue() string {
|
||||||
// Uint looks up the value of a local UintFlag, returns
|
// Uint looks up the value of a local UintFlag, returns
|
||||||
// 0 if not found
|
// 0 if not found
|
||||||
func (c *Context) Uint(name string) uint {
|
func (c *Context) Uint(name string) uint {
|
||||||
if fs := lookupFlagSet(name, c); fs != nil {
|
return lookupUint(c.resolveFlagDeep(name))
|
||||||
return lookupUint(name, fs)
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func lookupUint(name string, set *flag.FlagSet) uint {
|
func lookupUint(f *flag.Flag) uint {
|
||||||
f := set.Lookup(name)
|
|
||||||
if f != nil {
|
if f != nil {
|
||||||
parsed, err := strconv.ParseUint(f.Value.String(), 0, 64)
|
parsed, err := strconv.ParseUint(f.Value.String(), 0, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -86,14 +86,10 @@ func (f *Uint64Flag) GetValue() string {
|
||||||
// Uint64 looks up the value of a local Uint64Flag, returns
|
// Uint64 looks up the value of a local Uint64Flag, returns
|
||||||
// 0 if not found
|
// 0 if not found
|
||||||
func (c *Context) Uint64(name string) uint64 {
|
func (c *Context) Uint64(name string) uint64 {
|
||||||
if fs := lookupFlagSet(name, c); fs != nil {
|
return lookupUint64(c.resolveFlagDeep(name))
|
||||||
return lookupUint64(name, fs)
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func lookupUint64(name string, set *flag.FlagSet) uint64 {
|
func lookupUint64(f *flag.Flag) uint64 {
|
||||||
f := set.Lookup(name)
|
|
||||||
if f != nil {
|
if f != nil {
|
||||||
parsed, err := strconv.ParseUint(f.Value.String(), 0, 64)
|
parsed, err := strconv.ParseUint(f.Value.String(), 0, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -5,5 +5,5 @@ go 1.11
|
||||||
require (
|
require (
|
||||||
github.com/BurntSushi/toml v0.3.1
|
github.com/BurntSushi/toml v0.3.1
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d
|
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d
|
||||||
gopkg.in/yaml.v2 v2.2.2
|
gopkg.in/yaml.v2 v2.2.3
|
||||||
)
|
)
|
||||||
|
|
|
@ -10,5 +10,5 @@ github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5I
|
||||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
|
gopkg.in/yaml.v2 v2.2.3 h1:fvjTMHxHEw/mxHbtzPi3JCcKXQRAnQTBRo6YCJSVHKI=
|
||||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
|
|
|
@ -72,13 +72,13 @@ func ShowAppHelpAndExit(c *Context, exitCode int) {
|
||||||
|
|
||||||
// ShowAppHelp is an action that displays the help.
|
// ShowAppHelp is an action that displays the help.
|
||||||
func ShowAppHelp(c *Context) error {
|
func ShowAppHelp(c *Context) error {
|
||||||
template := c.App.CustomAppHelpTemplate
|
tpl := c.App.CustomAppHelpTemplate
|
||||||
if template == "" {
|
if tpl == "" {
|
||||||
template = AppHelpTemplate
|
tpl = AppHelpTemplate
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.App.ExtraInfo == nil {
|
if c.App.ExtraInfo == nil {
|
||||||
HelpPrinter(c.App.Writer, template, c.App)
|
HelpPrinter(c.App.Writer, tpl, c.App)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,7 +87,7 @@ func ShowAppHelp(c *Context) error {
|
||||||
"ExtraInfo": c.App.ExtraInfo,
|
"ExtraInfo": c.App.ExtraInfo,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
HelpPrinterCustom(c.App.Writer, template, c.App, customAppData())
|
HelpPrinterCustom(c.App.Writer, tpl, c.App, customAppData())
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -214,6 +214,12 @@ func ShowCommandHelp(ctx *Context, command string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ShowSubcommandHelpAndExit - Prints help for the given subcommand and exits with exit code.
|
||||||
|
func ShowSubcommandHelpAndExit(c *Context, exitCode int) {
|
||||||
|
_ = ShowSubcommandHelp(c)
|
||||||
|
os.Exit(exitCode)
|
||||||
|
}
|
||||||
|
|
||||||
// ShowSubcommandHelp prints help for the given subcommand
|
// ShowSubcommandHelp prints help for the given subcommand
|
||||||
func ShowSubcommandHelp(c *Context) error {
|
func ShowSubcommandHelp(c *Context) error {
|
||||||
if c == nil {
|
if c == nil {
|
||||||
|
@ -263,7 +269,10 @@ func ShowCommandCompletions(ctx *Context, command string) {
|
||||||
// allow using arbitrary functions in template rendering.
|
// allow using arbitrary functions in template rendering.
|
||||||
func printHelpCustom(out io.Writer, templ string, data interface{}, customFuncs map[string]interface{}) {
|
func printHelpCustom(out io.Writer, templ string, data interface{}, customFuncs map[string]interface{}) {
|
||||||
funcMap := template.FuncMap{
|
funcMap := template.FuncMap{
|
||||||
"join": strings.Join,
|
"join": strings.Join,
|
||||||
|
"indent": indent,
|
||||||
|
"nindent": nindent,
|
||||||
|
"trim": strings.TrimSpace,
|
||||||
}
|
}
|
||||||
for key, value := range customFuncs {
|
for key, value := range customFuncs {
|
||||||
funcMap[key] = value
|
funcMap[key] = value
|
||||||
|
@ -366,3 +375,12 @@ func checkCommandCompletions(c *Context, name string) bool {
|
||||||
ShowCommandCompletions(c, name)
|
ShowCommandCompletions(c, name)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func indent(spaces int, v string) string {
|
||||||
|
pad := strings.Repeat(" ", spaces)
|
||||||
|
return pad + strings.Replace(v, "\n", "\n"+pad, -1)
|
||||||
|
}
|
||||||
|
|
||||||
|
func nindent(spaces int, v string) string {
|
||||||
|
return "\n" + indent(spaces, v)
|
||||||
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@ VERSION:
|
||||||
{{.Version}}{{end}}{{end}}{{if .Description}}
|
{{.Version}}{{end}}{{end}}{{if .Description}}
|
||||||
|
|
||||||
DESCRIPTION:
|
DESCRIPTION:
|
||||||
{{.Description}}{{end}}{{if len .Authors}}
|
{{.Description | nindent 3 | trim}}{{end}}{{if len .Authors}}
|
||||||
|
|
||||||
AUTHOR{{with $length := len .Authors}}{{if ne 1 $length}}S{{end}}{{end}}:
|
AUTHOR{{with $length := len .Authors}}{{if ne 1 $length}}S{{end}}{{end}}:
|
||||||
{{range $index, $author := .Authors}}{{if $index}}
|
{{range $index, $author := .Authors}}{{if $index}}
|
||||||
|
@ -45,7 +45,7 @@ CATEGORY:
|
||||||
{{.Category}}{{end}}{{if .Description}}
|
{{.Category}}{{end}}{{if .Description}}
|
||||||
|
|
||||||
DESCRIPTION:
|
DESCRIPTION:
|
||||||
{{.Description}}{{end}}{{if .VisibleFlags}}
|
{{.Description | nindent 3 | trim}}{{end}}{{if .VisibleFlags}}
|
||||||
|
|
||||||
OPTIONS:
|
OPTIONS:
|
||||||
{{range .VisibleFlags}}{{.}}
|
{{range .VisibleFlags}}{{.}}
|
||||||
|
@ -62,7 +62,7 @@ USAGE:
|
||||||
{{if .UsageText}}{{.UsageText}}{{else}}{{.HelpName}} command{{if .VisibleFlags}} [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{end}}{{if .Description}}
|
{{if .UsageText}}{{.UsageText}}{{else}}{{.HelpName}} command{{if .VisibleFlags}} [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{end}}{{if .Description}}
|
||||||
|
|
||||||
DESCRIPTION:
|
DESCRIPTION:
|
||||||
{{.Description}}{{end}}
|
{{.Description | nindent 3 | trim}}{{end}}
|
||||||
|
|
||||||
COMMANDS:{{range .VisibleCategories}}{{if .Name}}
|
COMMANDS:{{range .VisibleCategories}}{{if .Name}}
|
||||||
{{.Name}}:{{range .VisibleCommands}}
|
{{.Name}}:{{range .VisibleCommands}}
|
||||||
|
@ -74,7 +74,7 @@ OPTIONS:
|
||||||
{{end}}{{end}}
|
{{end}}{{end}}
|
||||||
`
|
`
|
||||||
|
|
||||||
var MarkdownDocTemplate = `% {{ .App.Name }} 8
|
var MarkdownDocTemplate = `% {{ .App.Name }} {{ .SectionNum }}
|
||||||
|
|
||||||
# NAME
|
# NAME
|
||||||
|
|
||||||
|
|
|
@ -246,7 +246,7 @@ github.com/shurcooL/sanitized_anchor_name
|
||||||
## explicit
|
## explicit
|
||||||
github.com/stretchr/testify/assert
|
github.com/stretchr/testify/assert
|
||||||
github.com/stretchr/testify/require
|
github.com/stretchr/testify/require
|
||||||
# github.com/urfave/cli/v2 v2.2.0
|
# github.com/urfave/cli/v2 v2.2.0 => github.com/ipostelnik/cli/v2 v2.3.1-0.20210223162147-c8b4f97735e4
|
||||||
## explicit
|
## explicit
|
||||||
github.com/urfave/cli/v2
|
github.com/urfave/cli/v2
|
||||||
github.com/urfave/cli/v2/altsrc
|
github.com/urfave/cli/v2/altsrc
|
||||||
|
@ -431,3 +431,4 @@ zombiezen.com/go/capnproto2/rpc/internal/refcount
|
||||||
zombiezen.com/go/capnproto2/schemas
|
zombiezen.com/go/capnproto2/schemas
|
||||||
zombiezen.com/go/capnproto2/server
|
zombiezen.com/go/capnproto2/server
|
||||||
zombiezen.com/go/capnproto2/std/capnp/rpc
|
zombiezen.com/go/capnproto2/std/capnp/rpc
|
||||||
|
# github.com/urfave/cli/v2 => github.com/ipostelnik/cli/v2 v2.3.1-0.20210223162147-c8b4f97735e4
|
||||||
|
|
Loading…
Reference in New Issue