Merge branch 'main' into remove_reflect
This commit is contained in:
commit
d83bb8d85e
8
.github/ISSUE_TEMPLATE/question.md
vendored
8
.github/ISSUE_TEMPLATE/question.md
vendored
@ -1,12 +1,10 @@
|
||||
---
|
||||
name: ask a question
|
||||
about: ask us question - assume stackoverflow's guidelines apply here
|
||||
title: 'q: ( your question title goes here )'
|
||||
about: ask a question - assume stackoverflow's guidelines apply here
|
||||
title: your question title goes here
|
||||
labels: 'kind/question, status/triage, area/v2'
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
## my question is...
|
||||
|
||||
_**( Put the question text here )**_
|
||||
my question is...
|
||||
|
39
.github/ISSUE_TEMPLATE/v1-bug-report.md
vendored
39
.github/ISSUE_TEMPLATE/v1-bug-report.md
vendored
@ -1,28 +1,32 @@
|
||||
---
|
||||
name: v1 bug report
|
||||
about: Create a report to help us fix v1 bugs
|
||||
title: 'v1 bug: ( your bug title goes here )'
|
||||
title: 'your bug title goes here'
|
||||
labels: 'kind/bug, status/triage, area/v1'
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
## my urfave/cli version is
|
||||
## My urfave/cli version is
|
||||
|
||||
_**( Put the version of urfave/cli that you are using here )**_
|
||||
|
||||
## Checklist
|
||||
|
||||
* [ ] Are you running the latest v1 release? The list of releases is [here](https://github.com/urfave/cli/releases).
|
||||
* [ ] Did you check the manual for your release? The v1 manual is [here](https://github.com/urfave/cli/blob/master/docs/v1/manual.md)
|
||||
* [ ] Did you perform a search about this problem? Here's the [Github guide](https://help.github.com/en/github/managing-your-work-on-github/using-search-to-filter-issues-and-pull-requests) about searching.
|
||||
- [ ] Are you running the latest v1 release? The list of releases is [here](https://github.com/urfave/cli/releases).
|
||||
- [ ] Did you check the manual for your release? The v1 manual is [here](https://github.com/urfave/cli/blob/main/docs/v1/manual.md).
|
||||
- [ ] Did you perform a search about this problem? Here's the [Github guide](https://help.github.com/en/github/managing-your-work-on-github/using-search-to-filter-issues-and-pull-requests) about searching.
|
||||
|
||||
## Dependency Management
|
||||
|
||||
- [ ] My project is using go modules.
|
||||
- [ ] My project is using vendoring.
|
||||
- [ ] My project is automatically downloading the latest version.
|
||||
- [ ] I am unsure of what my dependency management setup is.
|
||||
<!--
|
||||
Delete any of the following that do not apply:
|
||||
-->
|
||||
|
||||
- My project is using go modules.
|
||||
- My project is using vendoring.
|
||||
- My project is automatically downloading the latest version.
|
||||
- I am unsure of what my dependency management setup is.
|
||||
|
||||
## Describe the bug
|
||||
|
||||
@ -34,23 +38,30 @@ Describe the steps or code required to reproduce the behavior
|
||||
|
||||
## Observed behavior
|
||||
|
||||
What did you see happen immediately after the reproduction steps above?
|
||||
What did you see happen immediately after the reproduction steps
|
||||
above?
|
||||
|
||||
## Expected behavior
|
||||
|
||||
What would you have expected to happen immediately after the reproduction steps above?
|
||||
What would you have expected to happen immediately after the
|
||||
reproduction steps above?
|
||||
|
||||
## Additional context
|
||||
|
||||
Add any other context about the problem here.
|
||||
|
||||
If the issue relates to a specific open source Github repo, please link that repo here.
|
||||
If the issue relates to a specific open source Github repo, please
|
||||
link that repo here.
|
||||
|
||||
If you can reproduce this issue with a public CI system, please link a failing build here.
|
||||
If you can reproduce this issue with a public CI system, please
|
||||
link a failing build here.
|
||||
|
||||
## Want to fix this yourself?
|
||||
|
||||
We'd love to have more contributors on this project! If the fix for this bug is easily explained and very small, free free to create a pull request for it. You'll want to base the PR off the `v1` branch, all `v1` bug fix releases will be made from that branch.
|
||||
We'd love to have more contributors on this project! If the fix for
|
||||
this bug is easily explained and very small, free free to create a
|
||||
pull request for it. You'll want to base the PR off the `v1`
|
||||
branch, all `v1` bug fix releases will be made from that branch.
|
||||
|
||||
## Run `go version` and paste its output here
|
||||
|
||||
|
39
.github/ISSUE_TEMPLATE/v2-bug-report.md
vendored
39
.github/ISSUE_TEMPLATE/v2-bug-report.md
vendored
@ -1,28 +1,32 @@
|
||||
---
|
||||
name: v2 bug report
|
||||
about: Create a report to help us fix v2 bugs
|
||||
title: 'v2 bug: ( your bug title goes here )'
|
||||
title: 'your bug title goes here'
|
||||
labels: 'kind/bug, area/v2, status/triage'
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
## my urfave/cli version is
|
||||
## My urfave/cli version is
|
||||
|
||||
_**( Put the version of urfave/cli that you are using here )**_
|
||||
|
||||
## Checklist
|
||||
|
||||
* [ ] Are you running the latest v2 release? The list of releases is [here](https://github.com/urfave/cli/releases).
|
||||
* [ ] Did you check the manual for your release? The v2 manual is [here](https://github.com/urfave/cli/blob/master/docs/v2/manual.md)
|
||||
* [ ] Did you perform a search about this problem? Here's the [Github guide](https://help.github.com/en/github/managing-your-work-on-github/using-search-to-filter-issues-and-pull-requests) about searching.
|
||||
- [ ] Are you running the latest v2 release? The list of releases is [here](https://github.com/urfave/cli/releases).
|
||||
- [ ] Did you check the manual for your release? The v2 manual is [here](https://github.com/urfave/cli/blob/main/docs/v2/manual.md)
|
||||
- [ ] Did you perform a search about this problem? Here's the [Github guide](https://help.github.com/en/github/managing-your-work-on-github/using-search-to-filter-issues-and-pull-requests) about searching.
|
||||
|
||||
## Dependency Management
|
||||
|
||||
- [ ] My project is using go modules.
|
||||
- [ ] My project is using vendoring.
|
||||
- [ ] My project is automatically downloading the latest version.
|
||||
- [ ] I am unsure of what my dependency management setup is.
|
||||
<!--
|
||||
Delete any of the following that do not apply:
|
||||
-->
|
||||
|
||||
- My project is using go modules.
|
||||
- My project is using vendoring.
|
||||
- My project is automatically downloading the latest version.
|
||||
- I am unsure of what my dependency management setup is.
|
||||
|
||||
## Describe the bug
|
||||
|
||||
@ -34,23 +38,30 @@ Describe the steps or code required to reproduce the behavior
|
||||
|
||||
## Observed behavior
|
||||
|
||||
What did you see happen immediately after the reproduction steps above?
|
||||
What did you see happen immediately after the reproduction steps
|
||||
above?
|
||||
|
||||
## Expected behavior
|
||||
|
||||
What would you have expected to happen immediately after the reproduction steps above?
|
||||
What would you have expected to happen immediately after the
|
||||
reproduction steps above?
|
||||
|
||||
## Additional context
|
||||
|
||||
Add any other context about the problem here.
|
||||
|
||||
If the issue relates to a specific open source Github repo, please link that repo here.
|
||||
If the issue relates to a specific open source Github repo, please
|
||||
link that repo here.
|
||||
|
||||
If you can reproduce this issue with a public CI system, please link a failing build here.
|
||||
If you can reproduce this issue with a public CI system, please
|
||||
link a failing build here.
|
||||
|
||||
## Want to fix this yourself?
|
||||
|
||||
We'd love to have more contributors on this project! If the fix for this bug is easily explained and very small, free free to create a pull request for it.
|
||||
We'd love to have more contributors on this project! If the fix for
|
||||
this bug is easily explained and very small, free free to create a
|
||||
pull request for it.
|
||||
|
||||
## Run `go version` and paste its output here
|
||||
|
||||
```
|
||||
|
16
.github/ISSUE_TEMPLATE/v2-feature-request.md
vendored
16
.github/ISSUE_TEMPLATE/v2-feature-request.md
vendored
@ -1,7 +1,7 @@
|
||||
---
|
||||
name: v2 feature request
|
||||
about: Suggest an improvement for v2
|
||||
title: 'v2 feature: ( your feature title goes here )'
|
||||
title: 'your feature title goes here'
|
||||
labels: 'type/feature, area/v2, status/triage'
|
||||
assignees: ''
|
||||
|
||||
@ -10,16 +10,19 @@ assignees: ''
|
||||
## Checklist
|
||||
|
||||
* [ ] Are you running the latest v2 release? The list of releases is [here](https://github.com/urfave/cli/releases).
|
||||
* [ ] Did you check the manual for your release? The v2 manual is [here](https://github.com/urfave/cli/blob/master/docs/v2/manual.md)
|
||||
* [ ] Did you check the manual for your release? The v2 manual is [here](https://github.com/urfave/cli/blob/main/docs/v2/manual.md).
|
||||
* [ ] Did you perform a search about this feature? Here's the [Github guide](https://help.github.com/en/github/managing-your-work-on-github/using-search-to-filter-issues-and-pull-requests) about searching.
|
||||
|
||||
## What problem does this solve?
|
||||
|
||||
A clear and concise description of what problem this feature would solve. For example:
|
||||
|
||||
- needing to type out the full flag name takes a long time, so I would like to suggest adding auto-complete
|
||||
- I use (osx, windows, linux) and would like support for (some existing feature) to be extended to my platform
|
||||
- the terminal output for a particular error case is confusing, and I think it could be improved
|
||||
- needing to type out the full flag name takes a long time, so I
|
||||
would like to suggest adding auto-complete
|
||||
- I use (osx, windows, linux) and would like support for (some
|
||||
existing feature) to be extended to my platform
|
||||
- the terminal output for a particular error case is confusing, and
|
||||
I think it could be improved
|
||||
|
||||
## Solution description
|
||||
|
||||
@ -27,4 +30,5 @@ A detailed description of what you want to happen.
|
||||
|
||||
## Describe alternatives you've considered
|
||||
|
||||
A clear and concise description of any alternative solutions or features you've considered.
|
||||
A clear and concise description of any alternative solutions or
|
||||
features you've considered.
|
||||
|
13
.github/pull_request_template.md
vendored
13
.github/pull_request_template.md
vendored
@ -8,10 +8,14 @@
|
||||
|
||||
_(REQUIRED)_
|
||||
|
||||
- [ ] bug
|
||||
- [ ] cleanup
|
||||
- [ ] documentation
|
||||
- [ ] feature
|
||||
<!--
|
||||
Delete any of the following that do not apply:
|
||||
-->
|
||||
|
||||
- bug
|
||||
- cleanup
|
||||
- documentation
|
||||
- feature
|
||||
|
||||
## What this PR does / why we need it:
|
||||
|
||||
@ -28,6 +32,7 @@ _(REQUIRED)_
|
||||
## Which issue(s) this PR fixes:
|
||||
|
||||
_(REQUIRED)_
|
||||
|
||||
<!--
|
||||
If this PR fixes one of more issues, list them here.
|
||||
One line each, like so:
|
||||
|
73
.github/stale.yml
vendored
73
.github/stale.yml
vendored
@ -1,64 +1,17 @@
|
||||
# Configuration for probot-stale - https://github.com/probot/stale
|
||||
|
||||
# Number of days of inactivity before an Issue or Pull Request becomes stale
|
||||
daysUntilStale: 90
|
||||
|
||||
# Number of days of inactivity before an Issue or Pull Request with the stale label is closed.
|
||||
# Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale.
|
||||
daysUntilClose: 30
|
||||
|
||||
# Only issues or pull requests with all of these labels are check if stale. Defaults to `[]` (disabled)
|
||||
onlyLabels: []
|
||||
|
||||
# Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable
|
||||
# Number of days of inactivity before an issue becomes stale
|
||||
daysUntilStale: 365
|
||||
# Number of days of inactivity before a stale issue is closed
|
||||
daysUntilClose: 90
|
||||
# Issues with these labels will never be considered stale
|
||||
exemptLabels:
|
||||
- pinned
|
||||
- security
|
||||
- "help wanted"
|
||||
- "kind/maintenance"
|
||||
|
||||
# Set to true to ignore issues in a project (defaults to false)
|
||||
exemptProjects: false
|
||||
|
||||
# Set to true to ignore issues in a milestone (defaults to false)
|
||||
exemptMilestones: false
|
||||
|
||||
# Set to true to ignore issues with an assignee (defaults to false)
|
||||
exemptAssignees: false
|
||||
|
||||
# Label to use when marking as stale
|
||||
staleLabel: "status/stale"
|
||||
|
||||
# Comment to post when marking as stale. Set to `false` to disable
|
||||
# Label to use when marking an issue as stale
|
||||
staleLabel: wontfix
|
||||
# Comment to post when marking an issue as stale. Set to `false` to disable
|
||||
markComment: >
|
||||
This issue or PR has been automatically marked as stale because it has not had
|
||||
recent activity. Please add a comment bumping this if you're still
|
||||
interested in it's resolution! Thanks for your help, please let us know
|
||||
if you need anything else.
|
||||
|
||||
# Comment to post when removing the stale label.
|
||||
unmarkComment: >
|
||||
This issue or PR has been bumped and is no longer marked as stale! Feel free
|
||||
to bump it again in the future, if it's still relevant.
|
||||
|
||||
# Comment to post when closing a stale Issue or Pull Request.
|
||||
closeComment: >
|
||||
Closing this as it has become stale.
|
||||
|
||||
# Limit the number of actions per hour, from 1-30. Default is 30
|
||||
limitPerRun: 30
|
||||
|
||||
# Limit to only `issues` or `pulls`
|
||||
# only: issues
|
||||
|
||||
# Optionally, specify configuration settings that are specific to just 'issues' or 'pulls':
|
||||
# pulls:
|
||||
# daysUntilStale: 30
|
||||
# markComment: >
|
||||
# This pull request has been automatically marked as stale because it has not had
|
||||
# recent activity. It will be closed if no further activity occurs. Thank you
|
||||
# for your contributions.
|
||||
|
||||
# issues:
|
||||
# exemptLabels:
|
||||
# - confirmed
|
||||
This issue has been automatically marked as stale because it has not had
|
||||
recent activity. It will be closed if no further activity occurs. Thank you
|
||||
for your contributions.
|
||||
# Comment to post when closing a stale issue. Set to `false` to disable
|
||||
closeComment: false
|
||||
|
77
.github/workflows/cli.yml
vendored
77
.github/workflows/cli.yml
vendored
@ -3,42 +3,35 @@ name: Run Tests
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- v1
|
||||
- main
|
||||
tags:
|
||||
- v2.*
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
- v1
|
||||
- main
|
||||
|
||||
jobs:
|
||||
test:
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest, macos-latest, windows-latest]
|
||||
go: [1.14, 1.15, 1.16]
|
||||
go: [1.16.x, 1.17.x, 1.18.x]
|
||||
name: ${{ matrix.os }} @ Go ${{ matrix.go }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- name: Set up Go ${{ matrix.go }}
|
||||
uses: actions/setup-go@v1
|
||||
uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: ${{ matrix.go }}
|
||||
|
||||
- name: Set GOPATH, PATH and ENV
|
||||
run: |
|
||||
echo "GOPATH=$(dirname $GITHUB_WORKSPACE)" >> $GITHUB_ENV
|
||||
echo "GO111MODULE=on" >> $GITHUB_ENV
|
||||
echo "GOPROXY=https://proxy.golang.org" >> $GITHUB_ENV
|
||||
echo "$(dirname $GITHUB_WORKSPACE)/bin" >> $GITHUB_PATH
|
||||
shell: bash
|
||||
- name: Set PATH
|
||||
run: echo "${GITHUB_WORKSPACE}/.local/bin" >>"${GITHUB_PATH}"
|
||||
|
||||
- name: Checkout Code
|
||||
uses: actions/checkout@v1
|
||||
with:
|
||||
ref: ${{ github.ref }}
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: GOFMT Check
|
||||
if: matrix.go == 1.16 && matrix.os == 'ubuntu-latest'
|
||||
if: matrix.go == '1.18.x' && matrix.os == 'ubuntu-latest'
|
||||
run: test -z $(gofmt -l .)
|
||||
|
||||
- name: vet
|
||||
@ -51,8 +44,8 @@ jobs:
|
||||
run: go run internal/build/build.go check-binary-size
|
||||
|
||||
- name: Upload coverage to Codecov
|
||||
if: success() && matrix.go == 1.16 && matrix.os == 'ubuntu-latest'
|
||||
uses: codecov/codecov-action@v1
|
||||
if: success() && matrix.go == '1.18.x' && matrix.os == 'ubuntu-latest'
|
||||
uses: codecov/codecov-action@v2
|
||||
with:
|
||||
fail_ci_if_error: true
|
||||
|
||||
@ -61,44 +54,30 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v1
|
||||
uses: actions/setup-go@v3
|
||||
with:
|
||||
# Currently fails on 1.16
|
||||
go-version: 1.15
|
||||
go-version: 1.18.x
|
||||
|
||||
- name: Use Node.js 12.x
|
||||
uses: actions/setup-node@v1
|
||||
- name: Use Node.js 16
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 12.x
|
||||
node-version: '16'
|
||||
|
||||
- name: Set GOPATH, PATH and ENV
|
||||
run: |
|
||||
echo "GOPATH=$(dirname $GITHUB_WORKSPACE)" >> $GITHUB_ENV
|
||||
echo "GO111MODULE=on" >> $GITHUB_ENV
|
||||
echo "GOPROXY=https://proxy.golang.org" >> $GITHUB_ENV
|
||||
echo "$(dirname $GITHUB_WORKSPACE)/bin" >> $GITHUB_PATH
|
||||
shell: bash
|
||||
- name: Set PATH
|
||||
run: echo "${GITHUB_WORKSPACE}/.local/bin" >>"${GITHUB_PATH}"
|
||||
|
||||
- name: Checkout Code
|
||||
uses: actions/checkout@v1
|
||||
with:
|
||||
ref: ${{ github.ref }}
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Install Dependencies
|
||||
run: |
|
||||
mkdir -p $GOPATH/bin
|
||||
curl -L -o $GOPATH/bin/gfmrun "https://github.com/urfave/gfmrun/releases/download/v1.2.14/gfmrun-$(go env GOOS)-amd64-v1.2.14"
|
||||
chmod +x $GOPATH/bin/gfmrun
|
||||
run:
|
||||
mkdir -p "${GITHUB_WORKSPACE}/.local/bin" &&
|
||||
curl -fsSL -o "${GITHUB_WORKSPACE}/.local/bin/gfmrun" "https://github.com/urfave/gfmrun/releases/download/v1.3.0/gfmrun-$(go env GOOS)-$(go env GOARCH)-v1.3.0" &&
|
||||
chmod +x "${GITHUB_WORKSPACE}/.local/bin/gfmrun" &&
|
||||
npm install -g markdown-toc@1.2.0
|
||||
|
||||
- name: Run Tests (v1)
|
||||
if: contains(github.base_ref, 'v1')
|
||||
run: |
|
||||
go run internal/build/build.go gfmrun docs/v1/manual.md
|
||||
go run internal/build/build.go toc docs/v1/manual.md
|
||||
- name: gfmrun
|
||||
run: go run internal/build/build.go gfmrun docs/v2/manual.md
|
||||
|
||||
- name: Run Tests (v2)
|
||||
if: contains(github.base_ref, 'master')
|
||||
run: |
|
||||
go run internal/build/build.go gfmrun docs/v2/manual.md
|
||||
go run internal/build/build.go toc docs/v2/manual.md
|
||||
- name: toc
|
||||
run: go run internal/build/build.go toc docs/v2/manual.md
|
||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -5,5 +5,6 @@ vendor
|
||||
.idea
|
||||
internal/*/built-example
|
||||
coverage.txt
|
||||
/.local/
|
||||
|
||||
*.exe
|
||||
|
10
README.md
10
README.md
@ -4,7 +4,7 @@ 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)
|
||||
[![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/main/graph/badge.svg)](https://codecov.io/gh/urfave/cli)
|
||||
|
||||
cli is a simple, fast, and fun package for building command line apps in Go. The
|
||||
goal is to enable developers to write fast and distributable command line
|
||||
@ -12,7 +12,7 @@ applications in an expressive way.
|
||||
|
||||
## Usage Documentation
|
||||
|
||||
Usage documentation exists for each major version. Don't know what version you're on? You're probably using the version from the `master` branch, which is currently `v2`.
|
||||
Usage documentation exists for each major version. Don't know what version you're on? You're probably using the version from the `main` branch, which is currently `v2`.
|
||||
|
||||
- `v2` - [./docs/v2/manual.md](./docs/v2/manual.md)
|
||||
- `v1` - [./docs/v1/manual.md](./docs/v1/manual.md)
|
||||
@ -30,7 +30,7 @@ Go Modules are required when using this package. [See the go blog guide on using
|
||||
### Using `v2` releases
|
||||
|
||||
```
|
||||
$ GO111MODULE=on go get github.com/urfave/cli/v2
|
||||
$ go get github.com/urfave/cli/v2
|
||||
```
|
||||
|
||||
```go
|
||||
@ -44,7 +44,7 @@ import (
|
||||
### Using `v1` releases
|
||||
|
||||
```
|
||||
$ GO111MODULE=on go get github.com/urfave/cli
|
||||
$ go get github.com/urfave/cli
|
||||
```
|
||||
|
||||
```go
|
||||
@ -67,4 +67,4 @@ export PATH=$PATH:$GOPATH/bin
|
||||
|
||||
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
|
||||
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).
|
||||
builds. To see our currently supported go versions and platforms, look at the [./.github/workflows/cli.yml](https://github.com/urfave/cli/blob/main/.github/workflows/cli.yml).
|
||||
|
2
app.go
2
app.go
@ -12,7 +12,7 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
changeLogURL = "https://github.com/urfave/cli/blob/master/docs/CHANGELOG.md"
|
||||
changeLogURL = "https://github.com/urfave/cli/blob/main/docs/CHANGELOG.md"
|
||||
appActionDeprecationURL = fmt.Sprintf("%s#deprecated-cli-app-action-signature", changeLogURL)
|
||||
contactSysadmin = "This is an error in the application. Please contact the distributor of this application if this is not you."
|
||||
errInvalidActionType = NewExitError("ERROR invalid Action type. "+
|
||||
|
@ -476,18 +476,18 @@ func TestApp_RunAsSubCommandIncorrectUsage(t *testing.T) {
|
||||
a := App{
|
||||
Name: "cmd",
|
||||
Flags: []Flag{
|
||||
&StringFlag{Name: "--foo"},
|
||||
&StringFlag{Name: "foo"},
|
||||
},
|
||||
Writer: bytes.NewBufferString(""),
|
||||
}
|
||||
|
||||
set := flag.NewFlagSet("", flag.ContinueOnError)
|
||||
_ = set.Parse([]string{"", "---foo"})
|
||||
_ = set.Parse([]string{"", "-bar"})
|
||||
c := &Context{flagSet: set}
|
||||
|
||||
err := a.RunAsSubcommand(c)
|
||||
|
||||
expect(t, err, errors.New("bad flag syntax: ---foo"))
|
||||
expect(t, err.Error(), "flag provided but not defined: -bar")
|
||||
}
|
||||
|
||||
func TestApp_CommandWithFlagBeforeTerminator(t *testing.T) {
|
||||
|
@ -151,6 +151,9 @@ func (ctx *Context) lookupFlag(name string) Flag {
|
||||
|
||||
func (ctx *Context) lookupFlagSet(name string) *flag.FlagSet {
|
||||
for _, c := range ctx.Lineage() {
|
||||
if c.flagSet == nil {
|
||||
continue
|
||||
}
|
||||
if f := c.flagSet.Lookup(name); f != nil {
|
||||
return c.flagSet
|
||||
}
|
||||
|
@ -112,6 +112,8 @@ func TestContext_String(t *testing.T) {
|
||||
c := NewContext(nil, set, parentCtx)
|
||||
expect(t, c.String("myflag"), "hello world")
|
||||
expect(t, c.String("top-flag"), "hai veld")
|
||||
c = NewContext(nil, nil, parentCtx)
|
||||
expect(t, c.String("top-flag"), "hai veld")
|
||||
}
|
||||
|
||||
func TestContext_Path(t *testing.T) {
|
||||
|
50
docs.go
50
docs.go
@ -15,7 +15,7 @@ import (
|
||||
// The function errors if either parsing or writing of the string fails.
|
||||
func (a *App) ToMarkdown() (string, error) {
|
||||
var w bytes.Buffer
|
||||
if err := a.writeDocTemplate(&w, 8); err != nil {
|
||||
if err := a.writeDocTemplate(&w, 0); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return w.String(), nil
|
||||
@ -68,15 +68,16 @@ func prepareCommands(commands []*Command, level int) []string {
|
||||
if command.Hidden {
|
||||
continue
|
||||
}
|
||||
usage := ""
|
||||
if command.Usage != "" {
|
||||
usage = command.Usage
|
||||
}
|
||||
|
||||
prepared := fmt.Sprintf("%s %s\n\n%s\n",
|
||||
usageText := prepareUsageText(command)
|
||||
|
||||
usage := prepareUsage(command, usageText)
|
||||
|
||||
prepared := fmt.Sprintf("%s %s\n\n%s%s",
|
||||
strings.Repeat("#", level+2),
|
||||
strings.Join(command.Names(), ", "),
|
||||
usage,
|
||||
usageText,
|
||||
)
|
||||
|
||||
flags := prepareArgsWithValues(command.Flags)
|
||||
@ -155,3 +156,40 @@ func flagDetails(flag DocGenerationFlag) string {
|
||||
}
|
||||
return ": " + description
|
||||
}
|
||||
|
||||
func prepareUsageText(command *Command) string {
|
||||
if command.UsageText == "" {
|
||||
return ""
|
||||
}
|
||||
|
||||
// Remove leading and trailing newlines
|
||||
preparedUsageText := strings.Trim(command.UsageText, "\n")
|
||||
|
||||
var usageText string
|
||||
if strings.Contains(preparedUsageText, "\n") {
|
||||
// Format multi-line string as a code block using the 4 space schema to allow for embedded markdown such
|
||||
// that it will not break the continuous code block.
|
||||
for _, ln := range strings.Split(preparedUsageText, "\n") {
|
||||
usageText += fmt.Sprintf(" %s\n", ln)
|
||||
}
|
||||
} else {
|
||||
// Style a single line as a note
|
||||
usageText = fmt.Sprintf(">%s\n", preparedUsageText)
|
||||
}
|
||||
|
||||
return usageText
|
||||
}
|
||||
|
||||
func prepareUsage(command *Command, usageText string) string {
|
||||
if command.Usage == "" {
|
||||
return ""
|
||||
}
|
||||
|
||||
usage := command.Usage + "\n"
|
||||
// Add a newline to the Usage IFF there is a UsageText
|
||||
if usageText != "" {
|
||||
usage += "\n"
|
||||
}
|
||||
|
||||
return usage
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ Feel free to put up a pull request to fix a bug or maybe add a feature. We will
|
||||
give it a code review and make sure that it does not break backwards
|
||||
compatibility. If collaborators agree that it is in line with
|
||||
the vision of the project, we will work with you to get the code into
|
||||
a mergeable state and merge it into the master branch.
|
||||
a mergeable state and merge it into the main branch.
|
||||
|
||||
If you have contributed something significant to the project, we will most
|
||||
likely add you as a collaborator. As a collaborator you are given the ability
|
||||
|
@ -15,15 +15,18 @@ consider sending a PR to help improve this guide.
|
||||
|
||||
* [Flags before args](#flags-before-args)
|
||||
* [Import string changed](#import-string-changed)
|
||||
* [Flag aliases are done differently.](#flag-aliases-are-done-differently)
|
||||
* [Flag aliases are done differently](#flag-aliases-are-done-differently)
|
||||
* [EnvVar is now a list (EnvVars)](#envvar-is-now-a-list-envvars)
|
||||
* [Actions returns errors](#actions-returns-errors)
|
||||
* [cli.Flag changed](#cliflag-changed)
|
||||
* [Commands are now lists of pointers](#commands-are-now-lists-of-pointers)
|
||||
* [Lists of commands should be pointers](#lists-of-commands-should-be-pointers)
|
||||
* [cli.Flag changed](#cliflag-changed)
|
||||
* [Appending Commands](#appending-commands)
|
||||
* [Actions returns errors](#actions-returns-errors)
|
||||
* [GlobalString, GlobalBool and its likes are deprecated](#globalstring-globalbool-and-its-likes-are-deprecated)
|
||||
* [BoolTFlag and BoolT are deprecated](#booltflag-and-boolt-are-deprecated)
|
||||
* [&cli.StringSlice{""} replaced with cli.NewStringSlice("")](#clistringslice-replaced-with-clinewstringslice)
|
||||
* [Replace deprecated functions](#replace-deprecated-functions)
|
||||
* [Everything else](#everything-else)
|
||||
* [Full API Example](#full-api-example)
|
||||
|
||||
<!-- tocstop -->
|
||||
|
||||
@ -53,7 +56,7 @@ Check each file for this and make the change.
|
||||
|
||||
Shell command to find them all: `fgrep -rl github.com/urfave/cli *`
|
||||
|
||||
# Flag aliases are done differently.
|
||||
# Flag aliases are done differently
|
||||
|
||||
Change `Name: "foo, f"` to `Name: "foo", Aliases: []string{"f"}`
|
||||
|
||||
@ -181,6 +184,52 @@ Compiler messages you might see:
|
||||
cannot use c (type *cli.Command) as type cli.Command in append
|
||||
```
|
||||
|
||||
# GlobalString, GlobalBool and its likes are deprecated
|
||||
|
||||
Use simply `String` instead of `GlobalString`, `Bool` instead of `GlobalBool`
|
||||
|
||||
# BoolTFlag and BoolT are deprecated
|
||||
|
||||
BoolTFlag was a Bool Flag with its default value set to true and BoolT was used to find any BoolTFlag used locally, so both are deprecated.
|
||||
|
||||
* OLD:
|
||||
|
||||
```go
|
||||
cli.BoolTFlag{
|
||||
Name: FlagName,
|
||||
Usage: FlagUsage,
|
||||
EnvVar: "FLAG_ENV_VAR",
|
||||
}
|
||||
```
|
||||
* NEW:
|
||||
```go
|
||||
cli.BoolFlag{
|
||||
Name: FlagName,
|
||||
Value: true,
|
||||
Usage: FlagUsage,
|
||||
EnvVar: "FLAG_ENV_VAR",
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
# &cli.StringSlice{""} replaced with cli.NewStringSlice("")
|
||||
|
||||
Example:
|
||||
|
||||
* OLD:
|
||||
|
||||
```go
|
||||
Value: &cli.StringSlice{""},
|
||||
```
|
||||
* NEW:
|
||||
```go
|
||||
Value: cli.NewStringSlice(""),
|
||||
}
|
||||
```
|
||||
# Replace deprecated functions
|
||||
|
||||
`cli.NewExitError()` is deprecated. Use `cli.Exit()` instead. ([Staticcheck](https://staticcheck.io/) detects this automatically and recommends replacement code.)
|
||||
|
||||
# Everything else
|
||||
|
||||
Compile the code and work through any errors. Most should
|
||||
|
@ -514,7 +514,7 @@ func main() {
|
||||
```
|
||||
|
||||
If `EnvVars` contains more than one string, the first environment variable that
|
||||
resolves is used as the default.
|
||||
resolves is used.
|
||||
|
||||
<!-- {
|
||||
"args": ["--help"],
|
||||
@ -674,8 +674,10 @@ Take for example this app that requires the `lang` flag:
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
|
166
docs_test.go
166
docs_test.go
@ -67,8 +67,50 @@ func testApp() *App {
|
||||
}, {
|
||||
Name: "hidden-command",
|
||||
Hidden: true,
|
||||
}, {
|
||||
Aliases: []string{"u"},
|
||||
Flags: []Flag{
|
||||
&StringFlag{
|
||||
Name: "flag",
|
||||
Aliases: []string{"fl", "f"},
|
||||
TakesFile: true,
|
||||
},
|
||||
&BoolFlag{
|
||||
Name: "another-flag",
|
||||
Aliases: []string{"b"},
|
||||
Usage: "another usage text",
|
||||
},
|
||||
},
|
||||
Name: "usage",
|
||||
Usage: "standard usage text",
|
||||
UsageText: `
|
||||
Usage for the usage text
|
||||
- formatted: Based on the specified ConfigMap and summon secrets.yml
|
||||
- list: Inspect the environment for a specific process running on a Pod
|
||||
- for_effect: Compare 'namespace' environment with 'local'
|
||||
|
||||
` + "```" + `
|
||||
func() { ... }
|
||||
` + "```" + `
|
||||
|
||||
Should be a part of the same code block
|
||||
`,
|
||||
Subcommands: []*Command{{
|
||||
Aliases: []string{"su"},
|
||||
Flags: []Flag{
|
||||
&BoolFlag{
|
||||
Name: "sub-command-flag",
|
||||
Aliases: []string{"s"},
|
||||
Usage: "some usage text",
|
||||
},
|
||||
},
|
||||
Name: "sub-usage",
|
||||
Usage: "standard usage text",
|
||||
UsageText: "Single line of UsageText",
|
||||
}},
|
||||
}}
|
||||
app.UsageText = "app [first_arg] [second_arg]"
|
||||
app.Description = `Description of the application.`
|
||||
app.Usage = "Some app"
|
||||
app.Authors = []*Author{
|
||||
{Name: "Harrison", Email: "harrison@lolwut.com"},
|
||||
@ -77,13 +119,13 @@ func testApp() *App {
|
||||
return app
|
||||
}
|
||||
|
||||
func expectFileContent(t *testing.T, file, expected string) {
|
||||
func expectFileContent(t *testing.T, file, got string) {
|
||||
data, err := ioutil.ReadFile(file)
|
||||
// Ignore windows line endings
|
||||
// TODO: Replace with bytes.ReplaceAll when support for Go 1.11 is dropped
|
||||
data = bytes.Replace(data, []byte("\r\n"), []byte("\n"), -1)
|
||||
expect(t, err, nil)
|
||||
expect(t, string(data), expected)
|
||||
expect(t, got, string(data))
|
||||
}
|
||||
|
||||
func TestToMarkdownFull(t *testing.T) {
|
||||
@ -137,6 +179,19 @@ func TestToMarkdownNoAuthors(t *testing.T) {
|
||||
expectFileContent(t, "testdata/expected-doc-no-authors.md", res)
|
||||
}
|
||||
|
||||
func TestToMarkdownNoUsageText(t *testing.T) {
|
||||
// Given
|
||||
app := testApp()
|
||||
app.UsageText = ""
|
||||
|
||||
// When
|
||||
res, err := app.ToMarkdown()
|
||||
|
||||
// Then
|
||||
expect(t, err, nil)
|
||||
expectFileContent(t, "testdata/expected-doc-no-usagetext.md", res)
|
||||
}
|
||||
|
||||
func TestToMan(t *testing.T) {
|
||||
// Given
|
||||
app := testApp()
|
||||
@ -175,3 +230,110 @@ func TestToManWithSection(t *testing.T) {
|
||||
expect(t, err, nil)
|
||||
expectFileContent(t, "testdata/expected-doc-full.man", res)
|
||||
}
|
||||
|
||||
func Test_prepareUsageText(t *testing.T) {
|
||||
t.Run("no UsageText provided", func(t *testing.T) {
|
||||
// Given
|
||||
cmd := Command{}
|
||||
|
||||
// When
|
||||
res := prepareUsageText(&cmd)
|
||||
|
||||
// Then
|
||||
expect(t, res, "")
|
||||
})
|
||||
|
||||
t.Run("single line UsageText", func(t *testing.T) {
|
||||
// Given
|
||||
cmd := Command{UsageText: "Single line usage text"}
|
||||
|
||||
// When
|
||||
res := prepareUsageText(&cmd)
|
||||
|
||||
// Then
|
||||
expect(t, res, ">Single line usage text\n")
|
||||
})
|
||||
|
||||
t.Run("multiline UsageText", func(t *testing.T) {
|
||||
// Given
|
||||
cmd := Command{
|
||||
UsageText: `
|
||||
Usage for the usage text
|
||||
- Should be a part of the same code block
|
||||
`,
|
||||
}
|
||||
|
||||
// When
|
||||
res := prepareUsageText(&cmd)
|
||||
|
||||
// Then
|
||||
test := ` Usage for the usage text
|
||||
- Should be a part of the same code block
|
||||
`
|
||||
expect(t, res, test)
|
||||
})
|
||||
|
||||
t.Run("multiline UsageText has formatted embedded markdown", func(t *testing.T) {
|
||||
// Given
|
||||
cmd := Command{
|
||||
UsageText: `
|
||||
Usage for the usage text
|
||||
|
||||
` + "```" + `
|
||||
func() { ... }
|
||||
` + "```" + `
|
||||
|
||||
Should be a part of the same code block
|
||||
`,
|
||||
}
|
||||
|
||||
// When
|
||||
res := prepareUsageText(&cmd)
|
||||
|
||||
// Then
|
||||
test := ` Usage for the usage text
|
||||
|
||||
` + "```" + `
|
||||
func() { ... }
|
||||
` + "```" + `
|
||||
|
||||
Should be a part of the same code block
|
||||
`
|
||||
expect(t, res, test)
|
||||
})
|
||||
}
|
||||
|
||||
func Test_prepareUsage(t *testing.T) {
|
||||
t.Run("no Usage provided", func(t *testing.T) {
|
||||
// Given
|
||||
cmd := Command{}
|
||||
|
||||
// When
|
||||
res := prepareUsage(&cmd, "")
|
||||
|
||||
// Then
|
||||
expect(t, res, "")
|
||||
})
|
||||
|
||||
t.Run("simple Usage", func(t *testing.T) {
|
||||
// Given
|
||||
cmd := Command{Usage: "simple usage text"}
|
||||
|
||||
// When
|
||||
res := prepareUsage(&cmd, "")
|
||||
|
||||
// Then
|
||||
expect(t, res, cmd.Usage+"\n")
|
||||
})
|
||||
|
||||
t.Run("simple Usage with UsageText", func(t *testing.T) {
|
||||
// Given
|
||||
cmd := Command{Usage: "simple usage text"}
|
||||
|
||||
// When
|
||||
res := prepareUsage(&cmd, "a non-empty string")
|
||||
|
||||
// Then
|
||||
expect(t, res, cmd.Usage+"\n\n")
|
||||
})
|
||||
}
|
||||
|
6
flag.go
6
flag.go
@ -414,8 +414,10 @@ func flagFromEnvOrFile(envVars []string, filePath string) (val string, ok bool)
|
||||
}
|
||||
}
|
||||
for _, fileVar := range strings.Split(filePath, ",") {
|
||||
if data, err := ioutil.ReadFile(fileVar); err == nil {
|
||||
return string(data), true
|
||||
if fileVar != "" {
|
||||
if data, err := ioutil.ReadFile(fileVar); err == nil {
|
||||
return string(data), true
|
||||
}
|
||||
}
|
||||
}
|
||||
return "", false
|
||||
|
@ -80,8 +80,7 @@ func (f *Float64Flag) IsVisible() bool {
|
||||
func (f *Float64Flag) Apply(set *flag.FlagSet) error {
|
||||
if val, ok := flagFromEnvOrFile(f.EnvVars, f.FilePath); ok {
|
||||
if val != "" {
|
||||
valFloat, err := strconv.ParseFloat(val, 10)
|
||||
|
||||
valFloat, err := strconv.ParseFloat(val, 64)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not parse %q as float64 value for flag %s: %s", val, f.Name, err)
|
||||
}
|
||||
|
@ -157,6 +157,9 @@ func (f *Float64SliceFlag) Apply(set *flag.FlagSet) error {
|
||||
}
|
||||
}
|
||||
|
||||
// Set this to false so that we reset the slice if we then set values from
|
||||
// flags that have already been set by the environment.
|
||||
f.Value.hasBeenSet = false
|
||||
f.HasBeenSet = true
|
||||
}
|
||||
}
|
||||
|
@ -157,6 +157,9 @@ func (f *Int64SliceFlag) Apply(set *flag.FlagSet) error {
|
||||
}
|
||||
}
|
||||
|
||||
// Set this to false so that we reset the slice if we then set values from
|
||||
// flags that have already been set by the environment.
|
||||
f.Value.hasBeenSet = false
|
||||
f.HasBeenSet = true
|
||||
}
|
||||
|
||||
|
@ -168,6 +168,9 @@ func (f *IntSliceFlag) Apply(set *flag.FlagSet) error {
|
||||
}
|
||||
}
|
||||
|
||||
// Set this to false so that we reset the slice if we then set values from
|
||||
// flags that have already been set by the environment.
|
||||
f.Value.hasBeenSet = false
|
||||
f.HasBeenSet = true
|
||||
}
|
||||
|
||||
|
@ -109,10 +109,7 @@ func (c *Context) String(name string) string {
|
||||
func lookupString(name string, set *flag.FlagSet) string {
|
||||
f := set.Lookup(name)
|
||||
if f != nil {
|
||||
parsed, err := f.Value.String(), error(nil)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
parsed := f.Value.String()
|
||||
return parsed
|
||||
}
|
||||
return ""
|
||||
|
13
flag_test.go
13
flag_test.go
@ -52,15 +52,21 @@ func TestBoolFlagApply_SetsAllNames(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestFlagsFromEnv(t *testing.T) {
|
||||
newSetFloat64Slice := func(defaults ...float64) Float64Slice {
|
||||
s := NewFloat64Slice(defaults...)
|
||||
s.hasBeenSet = false
|
||||
return *s
|
||||
}
|
||||
|
||||
newSetIntSlice := func(defaults ...int) IntSlice {
|
||||
s := NewIntSlice(defaults...)
|
||||
s.hasBeenSet = true
|
||||
s.hasBeenSet = false
|
||||
return *s
|
||||
}
|
||||
|
||||
newSetInt64Slice := func(defaults ...int64) Int64Slice {
|
||||
s := NewInt64Slice(defaults...)
|
||||
s.hasBeenSet = true
|
||||
s.hasBeenSet = false
|
||||
return *s
|
||||
}
|
||||
|
||||
@ -96,6 +102,9 @@ func TestFlagsFromEnv(t *testing.T) {
|
||||
{"1.2", 0, &IntFlag{Name: "seconds", EnvVars: []string{"SECONDS"}}, `could not parse "1.2" as int value for flag seconds: .*`},
|
||||
{"foobar", 0, &IntFlag{Name: "seconds", EnvVars: []string{"SECONDS"}}, `could not parse "foobar" as int value for flag seconds: .*`},
|
||||
|
||||
{"1.0,2", newSetFloat64Slice(1, 2), &Float64SliceFlag{Name: "seconds", EnvVars: []string{"SECONDS"}}, ""},
|
||||
{"foobar", newSetFloat64Slice(), &Float64SliceFlag{Name: "seconds", EnvVars: []string{"SECONDS"}}, `could not parse "\[\]float64{}" as float64 slice value for flag seconds: .*`},
|
||||
|
||||
{"1,2", newSetIntSlice(1, 2), &IntSliceFlag{Name: "seconds", EnvVars: []string{"SECONDS"}}, ""},
|
||||
{"1.2,2", newSetIntSlice(), &IntSliceFlag{Name: "seconds", EnvVars: []string{"SECONDS"}}, `could not parse "1.2,2" as int slice value for flag seconds: .*`},
|
||||
{"foobar", newSetIntSlice(), &IntSliceFlag{Name: "seconds", EnvVars: []string{"SECONDS"}}, `could not parse "foobar" as int slice value for flag seconds: .*`},
|
||||
|
2
funcs.go
2
funcs.go
@ -17,7 +17,7 @@ type ActionFunc func(*Context) error
|
||||
// CommandNotFoundFunc is executed if the proper command cannot be found
|
||||
type CommandNotFoundFunc func(*Context, string)
|
||||
|
||||
// OnUsageErrorFunc is executed if an usage error occurs. This is useful for displaying
|
||||
// OnUsageErrorFunc is executed if a usage error occurs. This is useful for displaying
|
||||
// customized usage error messages. This function is able to replace the
|
||||
// original error messages. If this function is not set, the "Incorrect usage"
|
||||
// is displayed and the execution is interrupted.
|
||||
|
10
go.mod
10
go.mod
@ -1,9 +1,11 @@
|
||||
module github.com/urfave/cli/v2
|
||||
|
||||
go 1.11
|
||||
go 1.18
|
||||
|
||||
require (
|
||||
github.com/BurntSushi/toml v0.3.1
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d
|
||||
gopkg.in/yaml.v2 v2.2.3
|
||||
github.com/BurntSushi/toml v1.1.0
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.1
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
)
|
||||
|
||||
require github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||
|
18
go.sum
18
go.sum
@ -1,14 +1,12 @@
|
||||
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
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/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
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/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
github.com/BurntSushi/toml v1.1.0 h1:ksErzDEI1khOiGPgpwuI7x2ebx/uXQNw7xJpn9Eq1+I=
|
||||
github.com/BurntSushi/toml v1.1.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.1 h1:r/myEWzV9lfsM1tFLgDyu0atFtJ1fXn261LKYj/3DxU=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
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=
|
||||
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/yaml.v2 v2.2.3 h1:fvjTMHxHEw/mxHbtzPi3JCcKXQRAnQTBRo6YCJSVHKI=
|
||||
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
|
13
help.go
13
help.go
@ -163,19 +163,26 @@ func DefaultCompleteWithFlags(cmd *Command) func(c *Context) {
|
||||
return func(c *Context) {
|
||||
if len(os.Args) > 2 {
|
||||
lastArg := os.Args[len(os.Args)-2]
|
||||
|
||||
if strings.HasPrefix(lastArg, "-") {
|
||||
printFlagSuggestions(lastArg, c.App.Flags, c.App.Writer)
|
||||
if cmd != nil {
|
||||
printFlagSuggestions(lastArg, cmd.Flags, c.App.Writer)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
printFlagSuggestions(lastArg, c.App.Flags, c.App.Writer)
|
||||
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if cmd != nil {
|
||||
printCommandSuggestions(cmd.Subcommands, c.App.Writer)
|
||||
} else {
|
||||
printCommandSuggestions(c.App.Commands, c.App.Writer)
|
||||
return
|
||||
}
|
||||
|
||||
printCommandSuggestions(c.App.Commands, c.App.Writer)
|
||||
}
|
||||
}
|
||||
|
||||
|
197
help_test.go
197
help_test.go
@ -6,6 +6,7 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"runtime"
|
||||
"strings"
|
||||
"testing"
|
||||
@ -511,6 +512,36 @@ func TestShowSubcommandHelp_CommandUsageText(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestShowSubcommandHelp_MultiLine_CommandUsageText(t *testing.T) {
|
||||
app := &App{
|
||||
Commands: []*Command{
|
||||
{
|
||||
Name: "frobbly",
|
||||
UsageText: `This is a
|
||||
multi
|
||||
line
|
||||
UsageText`,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
output := &bytes.Buffer{}
|
||||
app.Writer = output
|
||||
|
||||
_ = app.Run([]string{"foo", "frobbly", "--help"})
|
||||
|
||||
expected := `USAGE:
|
||||
This is a
|
||||
multi
|
||||
line
|
||||
UsageText
|
||||
`
|
||||
|
||||
if !strings.Contains(output.String(), expected) {
|
||||
t.Errorf("expected output to include usage text; got: %q", output.String())
|
||||
}
|
||||
}
|
||||
|
||||
func TestShowSubcommandHelp_SubcommandUsageText(t *testing.T) {
|
||||
app := &App{
|
||||
Commands: []*Command{
|
||||
@ -535,6 +566,40 @@ func TestShowSubcommandHelp_SubcommandUsageText(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestShowSubcommandHelp_MultiLine_SubcommandUsageText(t *testing.T) {
|
||||
app := &App{
|
||||
Commands: []*Command{
|
||||
{
|
||||
Name: "frobbly",
|
||||
Subcommands: []*Command{
|
||||
{
|
||||
Name: "bobbly",
|
||||
UsageText: `This is a
|
||||
multi
|
||||
line
|
||||
UsageText`,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
output := &bytes.Buffer{}
|
||||
app.Writer = output
|
||||
_ = app.Run([]string{"foo", "frobbly", "bobbly", "--help"})
|
||||
|
||||
expected := `USAGE:
|
||||
This is a
|
||||
multi
|
||||
line
|
||||
UsageText
|
||||
`
|
||||
|
||||
if !strings.Contains(output.String(), expected) {
|
||||
t.Errorf("expected output to include usage text; got: %q", output.String())
|
||||
}
|
||||
}
|
||||
|
||||
func TestShowAppHelp_HiddenCommand(t *testing.T) {
|
||||
app := &App{
|
||||
Commands: []*Command{
|
||||
@ -780,6 +845,56 @@ VERSION:
|
||||
}
|
||||
}
|
||||
|
||||
func TestShowAppHelp_UsageText(t *testing.T) {
|
||||
app := &App{
|
||||
UsageText: "This is a sinlge line of UsageText",
|
||||
Commands: []*Command{
|
||||
{
|
||||
Name: "frobbly",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
output := &bytes.Buffer{}
|
||||
app.Writer = output
|
||||
|
||||
_ = app.Run([]string{"foo"})
|
||||
|
||||
if !strings.Contains(output.String(), "This is a sinlge line of UsageText") {
|
||||
t.Errorf("expected output to include usage text; got: %q", output.String())
|
||||
}
|
||||
}
|
||||
|
||||
func TestShowAppHelp_MultiLine_UsageText(t *testing.T) {
|
||||
app := &App{
|
||||
UsageText: `This is a
|
||||
multi
|
||||
line
|
||||
App UsageText`,
|
||||
Commands: []*Command{
|
||||
{
|
||||
Name: "frobbly",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
output := &bytes.Buffer{}
|
||||
app.Writer = output
|
||||
|
||||
_ = app.Run([]string{"foo"})
|
||||
|
||||
expected := `USAGE:
|
||||
This is a
|
||||
multi
|
||||
line
|
||||
App UsageText
|
||||
`
|
||||
|
||||
if !strings.Contains(output.String(), expected) {
|
||||
t.Errorf("expected output to include usage text; got: %q", output.String())
|
||||
}
|
||||
}
|
||||
|
||||
func TestHideHelpCommand(t *testing.T) {
|
||||
app := &App{
|
||||
HideHelpCommand: true,
|
||||
@ -923,3 +1038,85 @@ func TestHideHelpCommand_WithSubcommands(t *testing.T) {
|
||||
t.Errorf("Run returned unexpected error: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDefaultCompleteWithFlags(t *testing.T) {
|
||||
origArgv := os.Args
|
||||
|
||||
t.Cleanup(func() {
|
||||
os.Args = origArgv
|
||||
})
|
||||
|
||||
for _, tc := range []struct {
|
||||
name string
|
||||
c *Context
|
||||
cmd *Command
|
||||
argv []string
|
||||
expected string
|
||||
}{
|
||||
{
|
||||
name: "empty",
|
||||
c: &Context{App: &App{}},
|
||||
cmd: &Command{},
|
||||
argv: []string{"prog", "cmd"},
|
||||
expected: "",
|
||||
},
|
||||
{
|
||||
name: "typical-flag-suggestion",
|
||||
c: &Context{App: &App{
|
||||
Name: "cmd",
|
||||
Flags: []Flag{
|
||||
&BoolFlag{Name: "happiness"},
|
||||
&Int64Flag{Name: "everybody-jump-on"},
|
||||
},
|
||||
Commands: []*Command{
|
||||
{Name: "putz"},
|
||||
},
|
||||
}},
|
||||
cmd: &Command{
|
||||
Flags: []Flag{
|
||||
&BoolFlag{Name: "excitement"},
|
||||
&StringFlag{Name: "hat-shape"},
|
||||
},
|
||||
},
|
||||
argv: []string{"cmd", "--e", "--generate-bash-completion"},
|
||||
expected: "--excitement\n",
|
||||
},
|
||||
{
|
||||
name: "typical-command-suggestion",
|
||||
c: &Context{App: &App{
|
||||
Name: "cmd",
|
||||
Flags: []Flag{
|
||||
&BoolFlag{Name: "happiness"},
|
||||
&Int64Flag{Name: "everybody-jump-on"},
|
||||
},
|
||||
}},
|
||||
cmd: &Command{
|
||||
Name: "putz",
|
||||
Subcommands: []*Command{
|
||||
{Name: "futz"},
|
||||
},
|
||||
Flags: []Flag{
|
||||
&BoolFlag{Name: "excitement"},
|
||||
&StringFlag{Name: "hat-shape"},
|
||||
},
|
||||
},
|
||||
argv: []string{"cmd", "--generate-bash-completion"},
|
||||
expected: "futz\n",
|
||||
},
|
||||
} {
|
||||
t.Run(tc.name, func(ct *testing.T) {
|
||||
writer := &bytes.Buffer{}
|
||||
tc.c.App.Writer = writer
|
||||
|
||||
os.Args = tc.argv
|
||||
f := DefaultCompleteWithFlags(tc.cmd)
|
||||
f(tc.c)
|
||||
|
||||
written := writer.String()
|
||||
|
||||
if written != tc.expected {
|
||||
ct.Errorf("written help does not match expected %q != %q", written, tc.expected)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -193,8 +193,8 @@ func checkBinarySizeActionFunc(c *cli.Context) (err error) {
|
||||
cliBuiltFilePath = "./internal/example-cli/built-example"
|
||||
helloSourceFilePath = "./internal/example-hello-world/example-hello-world.go"
|
||||
helloBuiltFilePath = "./internal/example-hello-world/built-example"
|
||||
desiredMinBinarySize = 1.8
|
||||
desiredMaxBinarySize = 2.1
|
||||
desiredMinBinarySize = 1.9
|
||||
desiredMaxBinarySize = 2.2
|
||||
badNewsEmoji = "🚨"
|
||||
goodNewsEmoji = "✨"
|
||||
checksPassedEmoji = "✅"
|
||||
|
20
template.go
20
template.go
@ -7,7 +7,7 @@ var AppHelpTemplate = `NAME:
|
||||
{{.Name}}{{if .Usage}} - {{.Usage}}{{end}}
|
||||
|
||||
USAGE:
|
||||
{{if .UsageText}}{{.UsageText}}{{else}}{{.HelpName}} {{if .VisibleFlags}}[global options]{{end}}{{if .Commands}} command [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{end}}{{if .Version}}{{if not .HideVersion}}
|
||||
{{if .UsageText}}{{.UsageText | nindent 3 | trim}}{{else}}{{.HelpName}} {{if .VisibleFlags}}[global options]{{end}}{{if .Commands}} command [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{end}}{{if .Version}}{{if not .HideVersion}}
|
||||
|
||||
VERSION:
|
||||
{{.Version}}{{end}}{{end}}{{if .Description}}
|
||||
@ -39,7 +39,7 @@ var CommandHelpTemplate = `NAME:
|
||||
{{.HelpName}} - {{.Usage}}
|
||||
|
||||
USAGE:
|
||||
{{if .UsageText}}{{.UsageText}}{{else}}{{.HelpName}}{{if .VisibleFlags}} [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{end}}{{if .Category}}
|
||||
{{if .UsageText}}{{.UsageText | nindent 3 | trim}}{{else}}{{.HelpName}}{{if .VisibleFlags}} [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{end}}{{if .Category}}
|
||||
|
||||
CATEGORY:
|
||||
{{.Category}}{{end}}{{if .Description}}
|
||||
@ -59,7 +59,7 @@ var SubcommandHelpTemplate = `NAME:
|
||||
{{.HelpName}} - {{.Usage}}
|
||||
|
||||
USAGE:
|
||||
{{if .UsageText}}{{.UsageText}}{{else}}{{.HelpName}} command{{if .VisibleFlags}} [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{end}}{{if .Description}}
|
||||
{{if .UsageText}}{{.UsageText | nindent 3 | trim}}{{else}}{{.HelpName}} command{{if .VisibleFlags}} [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{end}}{{if .Description}}
|
||||
|
||||
DESCRIPTION:
|
||||
{{.Description | nindent 3 | trim}}{{end}}
|
||||
@ -74,9 +74,9 @@ OPTIONS:
|
||||
{{end}}{{end}}
|
||||
`
|
||||
|
||||
var MarkdownDocTemplate = `% {{ .App.Name }} {{ .SectionNum }}
|
||||
var MarkdownDocTemplate = `{{if gt .SectionNum 0}}% {{ .App.Name }} {{ .SectionNum }}
|
||||
|
||||
# NAME
|
||||
{{end}}# NAME
|
||||
|
||||
{{ .App.Name }}{{ if .App.Usage }} - {{ .App.Usage }}{{ end }}
|
||||
|
||||
@ -86,16 +86,18 @@ var MarkdownDocTemplate = `% {{ .App.Name }} {{ .SectionNum }}
|
||||
{{ if .SynopsisArgs }}
|
||||
` + "```" + `
|
||||
{{ range $v := .SynopsisArgs }}{{ $v }}{{ end }}` + "```" + `
|
||||
{{ end }}{{ if .App.UsageText }}
|
||||
{{ end }}{{ if .App.Description }}
|
||||
# DESCRIPTION
|
||||
|
||||
{{ .App.UsageText }}
|
||||
{{ .App.Description }}
|
||||
{{ end }}
|
||||
**Usage**:
|
||||
|
||||
` + "```" + `
|
||||
` + "```" + `{{ if .App.UsageText }}
|
||||
{{ .App.UsageText }}
|
||||
{{ else }}
|
||||
{{ .App.Name }} [GLOBAL OPTIONS] command [COMMAND OPTIONS] [ARGUMENTS...]
|
||||
` + "```" + `
|
||||
{{ end }}` + "```" + `
|
||||
{{ if .GlobalArgs }}
|
||||
# GLOBAL OPTIONS
|
||||
{{ range $v := .GlobalArgs }}
|
||||
|
72
testdata/expected-doc-full.man
vendored
72
testdata/expected-doc-full.man
vendored
@ -3,7 +3,7 @@
|
||||
|
||||
.SH NAME
|
||||
.PP
|
||||
greet \- Some app
|
||||
greet - Some app
|
||||
|
||||
|
||||
.SH SYNOPSIS
|
||||
@ -14,9 +14,9 @@ greet
|
||||
.RS
|
||||
|
||||
.nf
|
||||
[\-\-another\-flag|\-b]
|
||||
[\-\-flag|\-\-fl|\-f]=[value]
|
||||
[\-\-socket|\-s]=[value]
|
||||
[--another-flag|-b]
|
||||
[--flag|--fl|-f]=[value]
|
||||
[--socket|-s]=[value]
|
||||
|
||||
.fi
|
||||
.RE
|
||||
@ -24,7 +24,7 @@ greet
|
||||
|
||||
.SH DESCRIPTION
|
||||
.PP
|
||||
app [first\_arg] [second\_arg]
|
||||
Description of the application.
|
||||
|
||||
.PP
|
||||
\fBUsage\fP:
|
||||
@ -33,7 +33,7 @@ app [first\_arg] [second\_arg]
|
||||
.RS
|
||||
|
||||
.nf
|
||||
greet [GLOBAL OPTIONS] command [COMMAND OPTIONS] [ARGUMENTS...]
|
||||
app [first_arg] [second_arg]
|
||||
|
||||
.fi
|
||||
.RE
|
||||
@ -41,13 +41,13 @@ greet [GLOBAL OPTIONS] command [COMMAND OPTIONS] [ARGUMENTS...]
|
||||
|
||||
.SH GLOBAL OPTIONS
|
||||
.PP
|
||||
\fB\-\-another\-flag, \-b\fP: another usage text
|
||||
\fB--another-flag, -b\fP: another usage text
|
||||
|
||||
.PP
|
||||
\fB\-\-flag, \-\-fl, \-f\fP="":
|
||||
\fB--flag, --fl, -f\fP="":
|
||||
|
||||
.PP
|
||||
\fB\-\-socket, \-s\fP="": some 'usage' text (default: value)
|
||||
\fB--socket, -s\fP="": some 'usage' text (default: value)
|
||||
|
||||
|
||||
.SH COMMANDS
|
||||
@ -56,23 +56,65 @@ greet [GLOBAL OPTIONS] command [COMMAND OPTIONS] [ARGUMENTS...]
|
||||
another usage test
|
||||
|
||||
.PP
|
||||
\fB\-\-another\-flag, \-b\fP: another usage text
|
||||
\fB--another-flag, -b\fP: another usage text
|
||||
|
||||
.PP
|
||||
\fB\-\-flag, \-\-fl, \-f\fP="":
|
||||
\fB--flag, --fl, -f\fP="":
|
||||
|
||||
.SS sub\-config, s, ss
|
||||
.SS sub-config, s, ss
|
||||
.PP
|
||||
another usage test
|
||||
|
||||
.PP
|
||||
\fB\-\-sub\-command\-flag, \-s\fP: some usage text
|
||||
\fB--sub-command-flag, -s\fP: some usage text
|
||||
|
||||
.PP
|
||||
\fB\-\-sub\-flag, \-\-sub\-fl, \-s\fP="":
|
||||
\fB--sub-flag, --sub-fl, -s\fP="":
|
||||
|
||||
.SH info, i, in
|
||||
.PP
|
||||
retrieve generic information
|
||||
|
||||
.SH some\-command
|
||||
.SH some-command
|
||||
.SH usage, u
|
||||
.PP
|
||||
standard usage text
|
||||
|
||||
.PP
|
||||
.RS
|
||||
|
||||
.nf
|
||||
Usage for the usage text
|
||||
- formatted: Based on the specified ConfigMap and summon secrets.yml
|
||||
- list: Inspect the environment for a specific process running on a Pod
|
||||
- for_effect: Compare 'namespace' environment with 'local'
|
||||
|
||||
```
|
||||
func() { ... }
|
||||
```
|
||||
|
||||
Should be a part of the same code block
|
||||
|
||||
.fi
|
||||
.RE
|
||||
|
||||
.PP
|
||||
\fB--another-flag, -b\fP: another usage text
|
||||
|
||||
.PP
|
||||
\fB--flag, --fl, -f\fP="":
|
||||
|
||||
.SS sub-usage, su
|
||||
.PP
|
||||
standard usage text
|
||||
|
||||
.PP
|
||||
.RS
|
||||
|
||||
.PP
|
||||
Single line of UsageText
|
||||
|
||||
.RE
|
||||
|
||||
.PP
|
||||
\fB--sub-command-flag, -s\fP: some usage text
|
||||
|
32
testdata/expected-doc-full.md
vendored
32
testdata/expected-doc-full.md
vendored
@ -1,5 +1,3 @@
|
||||
% greet 8
|
||||
|
||||
# NAME
|
||||
|
||||
greet - Some app
|
||||
@ -16,12 +14,12 @@ greet
|
||||
|
||||
# DESCRIPTION
|
||||
|
||||
app [first_arg] [second_arg]
|
||||
Description of the application.
|
||||
|
||||
**Usage**:
|
||||
|
||||
```
|
||||
greet [GLOBAL OPTIONS] command [COMMAND OPTIONS] [ARGUMENTS...]
|
||||
app [first_arg] [second_arg]
|
||||
```
|
||||
|
||||
# GLOBAL OPTIONS
|
||||
@ -58,3 +56,29 @@ retrieve generic information
|
||||
## some-command
|
||||
|
||||
|
||||
## usage, u
|
||||
|
||||
standard usage text
|
||||
|
||||
Usage for the usage text
|
||||
- formatted: Based on the specified ConfigMap and summon secrets.yml
|
||||
- list: Inspect the environment for a specific process running on a Pod
|
||||
- for_effect: Compare 'namespace' environment with 'local'
|
||||
|
||||
```
|
||||
func() { ... }
|
||||
```
|
||||
|
||||
Should be a part of the same code block
|
||||
|
||||
**--another-flag, -b**: another usage text
|
||||
|
||||
**--flag, --fl, -f**="":
|
||||
|
||||
### sub-usage, su
|
||||
|
||||
standard usage text
|
||||
|
||||
>Single line of UsageText
|
||||
|
||||
**--sub-command-flag, -s**: some usage text
|
||||
|
32
testdata/expected-doc-no-authors.md
vendored
32
testdata/expected-doc-no-authors.md
vendored
@ -1,5 +1,3 @@
|
||||
% greet 8
|
||||
|
||||
# NAME
|
||||
|
||||
greet - Some app
|
||||
@ -16,12 +14,12 @@ greet
|
||||
|
||||
# DESCRIPTION
|
||||
|
||||
app [first_arg] [second_arg]
|
||||
Description of the application.
|
||||
|
||||
**Usage**:
|
||||
|
||||
```
|
||||
greet [GLOBAL OPTIONS] command [COMMAND OPTIONS] [ARGUMENTS...]
|
||||
app [first_arg] [second_arg]
|
||||
```
|
||||
|
||||
# GLOBAL OPTIONS
|
||||
@ -58,3 +56,29 @@ retrieve generic information
|
||||
## some-command
|
||||
|
||||
|
||||
## usage, u
|
||||
|
||||
standard usage text
|
||||
|
||||
Usage for the usage text
|
||||
- formatted: Based on the specified ConfigMap and summon secrets.yml
|
||||
- list: Inspect the environment for a specific process running on a Pod
|
||||
- for_effect: Compare 'namespace' environment with 'local'
|
||||
|
||||
```
|
||||
func() { ... }
|
||||
```
|
||||
|
||||
Should be a part of the same code block
|
||||
|
||||
**--another-flag, -b**: another usage text
|
||||
|
||||
**--flag, --fl, -f**="":
|
||||
|
||||
### sub-usage, su
|
||||
|
||||
standard usage text
|
||||
|
||||
>Single line of UsageText
|
||||
|
||||
**--sub-command-flag, -s**: some usage text
|
||||
|
6
testdata/expected-doc-no-commands.md
vendored
6
testdata/expected-doc-no-commands.md
vendored
@ -1,5 +1,3 @@
|
||||
% greet 8
|
||||
|
||||
# NAME
|
||||
|
||||
greet - Some app
|
||||
@ -16,12 +14,12 @@ greet
|
||||
|
||||
# DESCRIPTION
|
||||
|
||||
app [first_arg] [second_arg]
|
||||
Description of the application.
|
||||
|
||||
**Usage**:
|
||||
|
||||
```
|
||||
greet [GLOBAL OPTIONS] command [COMMAND OPTIONS] [ARGUMENTS...]
|
||||
app [first_arg] [second_arg]
|
||||
```
|
||||
|
||||
# GLOBAL OPTIONS
|
||||
|
32
testdata/expected-doc-no-flags.md
vendored
32
testdata/expected-doc-no-flags.md
vendored
@ -1,5 +1,3 @@
|
||||
% greet 8
|
||||
|
||||
# NAME
|
||||
|
||||
greet - Some app
|
||||
@ -10,12 +8,12 @@ greet
|
||||
|
||||
# DESCRIPTION
|
||||
|
||||
app [first_arg] [second_arg]
|
||||
Description of the application.
|
||||
|
||||
**Usage**:
|
||||
|
||||
```
|
||||
greet [GLOBAL OPTIONS] command [COMMAND OPTIONS] [ARGUMENTS...]
|
||||
app [first_arg] [second_arg]
|
||||
```
|
||||
|
||||
# COMMANDS
|
||||
@ -43,3 +41,29 @@ retrieve generic information
|
||||
## some-command
|
||||
|
||||
|
||||
## usage, u
|
||||
|
||||
standard usage text
|
||||
|
||||
Usage for the usage text
|
||||
- formatted: Based on the specified ConfigMap and summon secrets.yml
|
||||
- list: Inspect the environment for a specific process running on a Pod
|
||||
- for_effect: Compare 'namespace' environment with 'local'
|
||||
|
||||
```
|
||||
func() { ... }
|
||||
```
|
||||
|
||||
Should be a part of the same code block
|
||||
|
||||
**--another-flag, -b**: another usage text
|
||||
|
||||
**--flag, --fl, -f**="":
|
||||
|
||||
### sub-usage, su
|
||||
|
||||
standard usage text
|
||||
|
||||
>Single line of UsageText
|
||||
|
||||
**--sub-command-flag, -s**: some usage text
|
||||
|
84
testdata/expected-doc-no-usagetext.md
vendored
Normal file
84
testdata/expected-doc-no-usagetext.md
vendored
Normal file
@ -0,0 +1,84 @@
|
||||
# NAME
|
||||
|
||||
greet - Some app
|
||||
|
||||
# SYNOPSIS
|
||||
|
||||
greet
|
||||
|
||||
```
|
||||
[--another-flag|-b]
|
||||
[--flag|--fl|-f]=[value]
|
||||
[--socket|-s]=[value]
|
||||
```
|
||||
|
||||
# DESCRIPTION
|
||||
|
||||
Description of the application.
|
||||
|
||||
**Usage**:
|
||||
|
||||
```
|
||||
greet [GLOBAL OPTIONS] command [COMMAND OPTIONS] [ARGUMENTS...]
|
||||
```
|
||||
|
||||
# GLOBAL OPTIONS
|
||||
|
||||
**--another-flag, -b**: another usage text
|
||||
|
||||
**--flag, --fl, -f**="":
|
||||
|
||||
**--socket, -s**="": some 'usage' text (default: value)
|
||||
|
||||
|
||||
# COMMANDS
|
||||
|
||||
## config, c
|
||||
|
||||
another usage test
|
||||
|
||||
**--another-flag, -b**: another usage text
|
||||
|
||||
**--flag, --fl, -f**="":
|
||||
|
||||
### sub-config, s, ss
|
||||
|
||||
another usage test
|
||||
|
||||
**--sub-command-flag, -s**: some usage text
|
||||
|
||||
**--sub-flag, --sub-fl, -s**="":
|
||||
|
||||
## info, i, in
|
||||
|
||||
retrieve generic information
|
||||
|
||||
## some-command
|
||||
|
||||
|
||||
## usage, u
|
||||
|
||||
standard usage text
|
||||
|
||||
Usage for the usage text
|
||||
- formatted: Based on the specified ConfigMap and summon secrets.yml
|
||||
- list: Inspect the environment for a specific process running on a Pod
|
||||
- for_effect: Compare 'namespace' environment with 'local'
|
||||
|
||||
```
|
||||
func() { ... }
|
||||
```
|
||||
|
||||
Should be a part of the same code block
|
||||
|
||||
**--another-flag, -b**: another usage text
|
||||
|
||||
**--flag, --fl, -f**="":
|
||||
|
||||
### sub-usage, su
|
||||
|
||||
standard usage text
|
||||
|
||||
>Single line of UsageText
|
||||
|
||||
**--sub-command-flag, -s**: some usage text
|
9
testdata/expected-fish-full.fish
vendored
9
testdata/expected-fish-full.fish
vendored
@ -2,7 +2,7 @@
|
||||
|
||||
function __fish_greet_no_subcommand --description 'Test if there has been any subcommand yet'
|
||||
for i in (commandline -opc)
|
||||
if contains -- $i config c sub-config s ss info i in some-command
|
||||
if contains -- $i config c sub-config s ss info i in some-command usage u sub-usage su
|
||||
return 1
|
||||
end
|
||||
end
|
||||
@ -27,3 +27,10 @@ complete -c greet -n '__fish_seen_subcommand_from info i in' -f -l help -s h -d
|
||||
complete -r -c greet -n '__fish_greet_no_subcommand' -a 'info i in' -d 'retrieve generic information'
|
||||
complete -c greet -n '__fish_seen_subcommand_from some-command' -f -l help -s h -d 'show help'
|
||||
complete -r -c greet -n '__fish_greet_no_subcommand' -a 'some-command'
|
||||
complete -c greet -n '__fish_seen_subcommand_from usage u' -f -l help -s h -d 'show help'
|
||||
complete -r -c greet -n '__fish_greet_no_subcommand' -a 'usage u' -d 'standard usage text'
|
||||
complete -c greet -n '__fish_seen_subcommand_from usage u' -l flag -s fl -s f -r
|
||||
complete -c greet -n '__fish_seen_subcommand_from usage u' -f -l another-flag -s b -d 'another usage text'
|
||||
complete -c greet -n '__fish_seen_subcommand_from sub-usage su' -f -l help -s h -d 'show help'
|
||||
complete -r -c greet -n '__fish_seen_subcommand_from usage u' -a 'sub-usage su' -d 'standard usage text'
|
||||
complete -c greet -n '__fish_seen_subcommand_from sub-usage su' -f -l sub-command-flag -s s -d 'some usage text'
|
||||
|
Loading…
Reference in New Issue
Block a user