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
|
name: ask a question
|
||||||
about: ask us question - assume stackoverflow's guidelines apply here
|
about: ask a question - assume stackoverflow's guidelines apply here
|
||||||
title: 'q: ( your question title goes here )'
|
title: your question title goes here
|
||||||
labels: 'kind/question, status/triage, area/v2'
|
labels: 'kind/question, status/triage, area/v2'
|
||||||
assignees: ''
|
assignees: ''
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## my question is...
|
my question is...
|
||||||
|
|
||||||
_**( Put the question text here )**_
|
|
||||||
|
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
|
name: v1 bug report
|
||||||
about: Create a report to help us fix v1 bugs
|
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'
|
labels: 'kind/bug, status/triage, area/v1'
|
||||||
assignees: ''
|
assignees: ''
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## my urfave/cli version is
|
## My urfave/cli version is
|
||||||
|
|
||||||
_**( Put the version of urfave/cli that you are using here )**_
|
_**( Put the version of urfave/cli that you are using here )**_
|
||||||
|
|
||||||
## Checklist
|
## Checklist
|
||||||
|
|
||||||
* [ ] Are you running the latest v1 release? The list of releases is [here](https://github.com/urfave/cli/releases).
|
- [ ] 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 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.
|
- [ ] 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
|
## Dependency Management
|
||||||
|
|
||||||
- [ ] My project is using go modules.
|
<!--
|
||||||
- [ ] My project is using vendoring.
|
Delete any of the following that do not apply:
|
||||||
- [ ] My project is automatically downloading the latest version.
|
-->
|
||||||
- [ ] I am unsure of what my dependency management setup is.
|
|
||||||
|
- 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
|
## Describe the bug
|
||||||
|
|
||||||
@ -34,23 +38,30 @@ Describe the steps or code required to reproduce the behavior
|
|||||||
|
|
||||||
## Observed 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
|
## 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
|
## Additional context
|
||||||
|
|
||||||
Add any other context about the problem here.
|
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?
|
## 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
|
## 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
|
name: v2 bug report
|
||||||
about: Create a report to help us fix v2 bugs
|
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'
|
labels: 'kind/bug, area/v2, status/triage'
|
||||||
assignees: ''
|
assignees: ''
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## my urfave/cli version is
|
## My urfave/cli version is
|
||||||
|
|
||||||
_**( Put the version of urfave/cli that you are using here )**_
|
_**( Put the version of urfave/cli that you are using here )**_
|
||||||
|
|
||||||
## Checklist
|
## Checklist
|
||||||
|
|
||||||
* [ ] Are you running the latest v2 release? The list of releases is [here](https://github.com/urfave/cli/releases).
|
- [ ] 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 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.
|
- [ ] 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
|
## Dependency Management
|
||||||
|
|
||||||
- [ ] My project is using go modules.
|
<!--
|
||||||
- [ ] My project is using vendoring.
|
Delete any of the following that do not apply:
|
||||||
- [ ] My project is automatically downloading the latest version.
|
-->
|
||||||
- [ ] I am unsure of what my dependency management setup is.
|
|
||||||
|
- 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
|
## Describe the bug
|
||||||
|
|
||||||
@ -34,23 +38,30 @@ Describe the steps or code required to reproduce the behavior
|
|||||||
|
|
||||||
## Observed 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
|
## 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
|
## Additional context
|
||||||
|
|
||||||
Add any other context about the problem here.
|
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?
|
## 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
|
## 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
|
name: v2 feature request
|
||||||
about: Suggest an improvement for v2
|
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'
|
labels: 'type/feature, area/v2, status/triage'
|
||||||
assignees: ''
|
assignees: ''
|
||||||
|
|
||||||
@ -10,16 +10,19 @@ assignees: ''
|
|||||||
## Checklist
|
## Checklist
|
||||||
|
|
||||||
* [ ] Are you running the latest v2 release? The list of releases is [here](https://github.com/urfave/cli/releases).
|
* [ ] 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.
|
* [ ] 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?
|
## What problem does this solve?
|
||||||
|
|
||||||
A clear and concise description of what problem this feature would solve. For example:
|
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
|
- needing to type out the full flag name takes a long time, so I
|
||||||
- I use (osx, windows, linux) and would like support for (some existing feature) to be extended to my platform
|
would like to suggest adding auto-complete
|
||||||
- the terminal output for a particular error case is confusing, and I think it could be improved
|
- 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
|
## Solution description
|
||||||
|
|
||||||
@ -27,4 +30,5 @@ A detailed description of what you want to happen.
|
|||||||
|
|
||||||
## Describe alternatives you've considered
|
## 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)_
|
_(REQUIRED)_
|
||||||
|
|
||||||
- [ ] bug
|
<!--
|
||||||
- [ ] cleanup
|
Delete any of the following that do not apply:
|
||||||
- [ ] documentation
|
-->
|
||||||
- [ ] feature
|
|
||||||
|
- bug
|
||||||
|
- cleanup
|
||||||
|
- documentation
|
||||||
|
- feature
|
||||||
|
|
||||||
## What this PR does / why we need it:
|
## What this PR does / why we need it:
|
||||||
|
|
||||||
@ -28,6 +32,7 @@ _(REQUIRED)_
|
|||||||
## Which issue(s) this PR fixes:
|
## Which issue(s) this PR fixes:
|
||||||
|
|
||||||
_(REQUIRED)_
|
_(REQUIRED)_
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
If this PR fixes one of more issues, list them here.
|
If this PR fixes one of more issues, list them here.
|
||||||
One line each, like so:
|
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 becomes stale
|
||||||
|
daysUntilStale: 365
|
||||||
# Number of days of inactivity before an Issue or Pull Request becomes stale
|
# Number of days of inactivity before a stale issue is closed
|
||||||
daysUntilStale: 90
|
daysUntilClose: 90
|
||||||
|
# Issues with these labels will never be considered stale
|
||||||
# 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
|
|
||||||
exemptLabels:
|
exemptLabels:
|
||||||
- pinned
|
- pinned
|
||||||
- security
|
- security
|
||||||
- "help wanted"
|
# Label to use when marking an issue as stale
|
||||||
- "kind/maintenance"
|
staleLabel: wontfix
|
||||||
|
# Comment to post when marking an issue as stale. Set to `false` to disable
|
||||||
# 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
|
|
||||||
markComment: >
|
markComment: >
|
||||||
This issue or PR has been automatically marked as stale because it has not had
|
This issue has been automatically marked as stale because it has not had
|
||||||
recent activity. Please add a comment bumping this if you're still
|
recent activity. It will be closed if no further activity occurs. Thank you
|
||||||
interested in it's resolution! Thanks for your help, please let us know
|
for your contributions.
|
||||||
if you need anything else.
|
# Comment to post when closing a stale issue. Set to `false` to disable
|
||||||
|
closeComment: false
|
||||||
# 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
|
|
||||||
|
77
.github/workflows/cli.yml
vendored
77
.github/workflows/cli.yml
vendored
@ -3,42 +3,35 @@ name: Run Tests
|
|||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- master
|
- main
|
||||||
- v1
|
tags:
|
||||||
|
- v2.*
|
||||||
pull_request:
|
pull_request:
|
||||||
branches:
|
branches:
|
||||||
- master
|
- main
|
||||||
- v1
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
test:
|
test:
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
os: [ubuntu-latest, macos-latest, windows-latest]
|
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 }}
|
name: ${{ matrix.os }} @ Go ${{ matrix.go }}
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
steps:
|
steps:
|
||||||
- name: Set up Go ${{ matrix.go }}
|
- name: Set up Go ${{ matrix.go }}
|
||||||
uses: actions/setup-go@v1
|
uses: actions/setup-go@v3
|
||||||
with:
|
with:
|
||||||
go-version: ${{ matrix.go }}
|
go-version: ${{ matrix.go }}
|
||||||
|
|
||||||
- name: Set GOPATH, PATH and ENV
|
- name: Set PATH
|
||||||
run: |
|
run: echo "${GITHUB_WORKSPACE}/.local/bin" >>"${GITHUB_PATH}"
|
||||||
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: Checkout Code
|
- name: Checkout Code
|
||||||
uses: actions/checkout@v1
|
uses: actions/checkout@v3
|
||||||
with:
|
|
||||||
ref: ${{ github.ref }}
|
|
||||||
|
|
||||||
- name: GOFMT Check
|
- 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 .)
|
run: test -z $(gofmt -l .)
|
||||||
|
|
||||||
- name: vet
|
- name: vet
|
||||||
@ -51,8 +44,8 @@ jobs:
|
|||||||
run: go run internal/build/build.go check-binary-size
|
run: go run internal/build/build.go check-binary-size
|
||||||
|
|
||||||
- name: Upload coverage to Codecov
|
- name: Upload coverage to Codecov
|
||||||
if: success() && matrix.go == 1.16 && matrix.os == 'ubuntu-latest'
|
if: success() && matrix.go == '1.18.x' && matrix.os == 'ubuntu-latest'
|
||||||
uses: codecov/codecov-action@v1
|
uses: codecov/codecov-action@v2
|
||||||
with:
|
with:
|
||||||
fail_ci_if_error: true
|
fail_ci_if_error: true
|
||||||
|
|
||||||
@ -61,44 +54,30 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Set up Go
|
- name: Set up Go
|
||||||
uses: actions/setup-go@v1
|
uses: actions/setup-go@v3
|
||||||
with:
|
with:
|
||||||
# Currently fails on 1.16
|
go-version: 1.18.x
|
||||||
go-version: 1.15
|
|
||||||
|
|
||||||
- name: Use Node.js 12.x
|
- name: Use Node.js 16
|
||||||
uses: actions/setup-node@v1
|
uses: actions/setup-node@v3
|
||||||
with:
|
with:
|
||||||
node-version: 12.x
|
node-version: '16'
|
||||||
|
|
||||||
- name: Set GOPATH, PATH and ENV
|
- name: Set PATH
|
||||||
run: |
|
run: echo "${GITHUB_WORKSPACE}/.local/bin" >>"${GITHUB_PATH}"
|
||||||
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: Checkout Code
|
- name: Checkout Code
|
||||||
uses: actions/checkout@v1
|
uses: actions/checkout@v3
|
||||||
with:
|
|
||||||
ref: ${{ github.ref }}
|
|
||||||
|
|
||||||
- name: Install Dependencies
|
- name: Install Dependencies
|
||||||
run: |
|
run:
|
||||||
mkdir -p $GOPATH/bin
|
mkdir -p "${GITHUB_WORKSPACE}/.local/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"
|
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 $GOPATH/bin/gfmrun
|
chmod +x "${GITHUB_WORKSPACE}/.local/bin/gfmrun" &&
|
||||||
npm install -g markdown-toc@1.2.0
|
npm install -g markdown-toc@1.2.0
|
||||||
|
|
||||||
- name: Run Tests (v1)
|
- name: gfmrun
|
||||||
if: contains(github.base_ref, 'v1')
|
run: go run internal/build/build.go gfmrun docs/v2/manual.md
|
||||||
run: |
|
|
||||||
go run internal/build/build.go gfmrun docs/v1/manual.md
|
|
||||||
go run internal/build/build.go toc docs/v1/manual.md
|
|
||||||
|
|
||||||
- name: Run Tests (v2)
|
- name: toc
|
||||||
if: contains(github.base_ref, 'master')
|
run: go run internal/build/build.go toc docs/v2/manual.md
|
||||||
run: |
|
|
||||||
go run internal/build/build.go gfmrun docs/v2/manual.md
|
|
||||||
go run internal/build/build.go toc docs/v2/manual.md
|
|
||||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -5,5 +5,6 @@ vendor
|
|||||||
.idea
|
.idea
|
||||||
internal/*/built-example
|
internal/*/built-example
|
||||||
coverage.txt
|
coverage.txt
|
||||||
|
/.local/
|
||||||
|
|
||||||
*.exe
|
*.exe
|
||||||
|
10
README.md
10
README.md
@ -4,7 +4,7 @@ cli
|
|||||||
[](https://pkg.go.dev/github.com/urfave/cli/v2)
|
[](https://pkg.go.dev/github.com/urfave/cli/v2)
|
||||||
[](https://codebeat.co/projects/github-com-urfave-cli)
|
[](https://codebeat.co/projects/github-com-urfave-cli)
|
||||||
[](https://goreportcard.com/report/urfave/cli)
|
[](https://goreportcard.com/report/urfave/cli)
|
||||||
[](https://codecov.io/gh/urfave/cli)
|
[](https://codecov.io/gh/urfave/cli)
|
||||||
|
|
||||||
cli is a simple, fast, and fun package for building command line apps in Go. The
|
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
|
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
|
||||||
|
|
||||||
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)
|
- `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)
|
||||||
@ -30,7 +30,7 @@ Go Modules are required when using this package. [See the go blog guide on using
|
|||||||
### Using `v2` releases
|
### Using `v2` releases
|
||||||
|
|
||||||
```
|
```
|
||||||
$ GO111MODULE=on go get github.com/urfave/cli/v2
|
$ go get github.com/urfave/cli/v2
|
||||||
```
|
```
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@ -44,7 +44,7 @@ import (
|
|||||||
### Using `v1` releases
|
### Using `v1` releases
|
||||||
|
|
||||||
```
|
```
|
||||||
$ GO111MODULE=on go get github.com/urfave/cli
|
$ go get github.com/urfave/cli
|
||||||
```
|
```
|
||||||
|
|
||||||
```go
|
```go
|
||||||
@ -67,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. 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 (
|
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)
|
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."
|
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. "+
|
errInvalidActionType = NewExitError("ERROR invalid Action type. "+
|
||||||
|
@ -476,18 +476,18 @@ func TestApp_RunAsSubCommandIncorrectUsage(t *testing.T) {
|
|||||||
a := App{
|
a := App{
|
||||||
Name: "cmd",
|
Name: "cmd",
|
||||||
Flags: []Flag{
|
Flags: []Flag{
|
||||||
&StringFlag{Name: "--foo"},
|
&StringFlag{Name: "foo"},
|
||||||
},
|
},
|
||||||
Writer: bytes.NewBufferString(""),
|
Writer: bytes.NewBufferString(""),
|
||||||
}
|
}
|
||||||
|
|
||||||
set := flag.NewFlagSet("", flag.ContinueOnError)
|
set := flag.NewFlagSet("", flag.ContinueOnError)
|
||||||
_ = set.Parse([]string{"", "---foo"})
|
_ = set.Parse([]string{"", "-bar"})
|
||||||
c := &Context{flagSet: set}
|
c := &Context{flagSet: set}
|
||||||
|
|
||||||
err := a.RunAsSubcommand(c)
|
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) {
|
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 {
|
func (ctx *Context) lookupFlagSet(name string) *flag.FlagSet {
|
||||||
for _, c := range ctx.Lineage() {
|
for _, c := range ctx.Lineage() {
|
||||||
|
if c.flagSet == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
if f := c.flagSet.Lookup(name); f != nil {
|
if f := c.flagSet.Lookup(name); f != nil {
|
||||||
return c.flagSet
|
return c.flagSet
|
||||||
}
|
}
|
||||||
|
@ -112,6 +112,8 @@ func TestContext_String(t *testing.T) {
|
|||||||
c := NewContext(nil, set, parentCtx)
|
c := NewContext(nil, set, parentCtx)
|
||||||
expect(t, c.String("myflag"), "hello world")
|
expect(t, c.String("myflag"), "hello world")
|
||||||
expect(t, c.String("top-flag"), "hai veld")
|
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) {
|
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.
|
// 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, 8); err != nil {
|
if err := a.writeDocTemplate(&w, 0); err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
return w.String(), nil
|
return w.String(), nil
|
||||||
@ -68,15 +68,16 @@ func prepareCommands(commands []*Command, level int) []string {
|
|||||||
if command.Hidden {
|
if command.Hidden {
|
||||||
continue
|
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.Repeat("#", level+2),
|
||||||
strings.Join(command.Names(), ", "),
|
strings.Join(command.Names(), ", "),
|
||||||
usage,
|
usage,
|
||||||
|
usageText,
|
||||||
)
|
)
|
||||||
|
|
||||||
flags := prepareArgsWithValues(command.Flags)
|
flags := prepareArgsWithValues(command.Flags)
|
||||||
@ -155,3 +156,40 @@ func flagDetails(flag DocGenerationFlag) string {
|
|||||||
}
|
}
|
||||||
return ": " + description
|
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
|
give it a code review and make sure that it does not break backwards
|
||||||
compatibility. If collaborators agree that it is in line with
|
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
|
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
|
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
|
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)
|
* [Flags before args](#flags-before-args)
|
||||||
* [Import string changed](#import-string-changed)
|
* [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)
|
* [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)
|
* [Commands are now lists of pointers](#commands-are-now-lists-of-pointers)
|
||||||
* [Lists of commands should be pointers](#lists-of-commands-should-be-pointers)
|
* [Lists of commands should be pointers](#lists-of-commands-should-be-pointers)
|
||||||
* [cli.Flag changed](#cliflag-changed)
|
|
||||||
* [Appending Commands](#appending-commands)
|
* [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)
|
* [Everything else](#everything-else)
|
||||||
* [Full API Example](#full-api-example)
|
|
||||||
|
|
||||||
<!-- tocstop -->
|
<!-- 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 *`
|
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"}`
|
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
|
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
|
# Everything else
|
||||||
|
|
||||||
Compile the code and work through any errors. Most should
|
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
|
If `EnvVars` contains more than one string, the first environment variable that
|
||||||
resolves is used as the default.
|
resolves is used.
|
||||||
|
|
||||||
<!-- {
|
<!-- {
|
||||||
"args": ["--help"],
|
"args": ["--help"],
|
||||||
@ -674,8 +674,10 @@ Take for example this app that requires the `lang` flag:
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
166
docs_test.go
166
docs_test.go
@ -67,8 +67,50 @@ func testApp() *App {
|
|||||||
}, {
|
}, {
|
||||||
Name: "hidden-command",
|
Name: "hidden-command",
|
||||||
Hidden: true,
|
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.UsageText = "app [first_arg] [second_arg]"
|
||||||
|
app.Description = `Description of the application.`
|
||||||
app.Usage = "Some app"
|
app.Usage = "Some app"
|
||||||
app.Authors = []*Author{
|
app.Authors = []*Author{
|
||||||
{Name: "Harrison", Email: "harrison@lolwut.com"},
|
{Name: "Harrison", Email: "harrison@lolwut.com"},
|
||||||
@ -77,13 +119,13 @@ func testApp() *App {
|
|||||||
return app
|
return app
|
||||||
}
|
}
|
||||||
|
|
||||||
func expectFileContent(t *testing.T, file, expected string) {
|
func expectFileContent(t *testing.T, file, got string) {
|
||||||
data, err := ioutil.ReadFile(file)
|
data, err := ioutil.ReadFile(file)
|
||||||
// Ignore windows line endings
|
// Ignore windows line endings
|
||||||
// TODO: Replace with bytes.ReplaceAll when support for Go 1.11 is dropped
|
// TODO: Replace with bytes.ReplaceAll when support for Go 1.11 is dropped
|
||||||
data = bytes.Replace(data, []byte("\r\n"), []byte("\n"), -1)
|
data = bytes.Replace(data, []byte("\r\n"), []byte("\n"), -1)
|
||||||
expect(t, err, nil)
|
expect(t, err, nil)
|
||||||
expect(t, string(data), expected)
|
expect(t, got, string(data))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestToMarkdownFull(t *testing.T) {
|
func TestToMarkdownFull(t *testing.T) {
|
||||||
@ -137,6 +179,19 @@ func TestToMarkdownNoAuthors(t *testing.T) {
|
|||||||
expectFileContent(t, "testdata/expected-doc-no-authors.md", res)
|
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) {
|
func TestToMan(t *testing.T) {
|
||||||
// Given
|
// Given
|
||||||
app := testApp()
|
app := testApp()
|
||||||
@ -175,3 +230,110 @@ func TestToManWithSection(t *testing.T) {
|
|||||||
expect(t, err, nil)
|
expect(t, err, nil)
|
||||||
expectFileContent(t, "testdata/expected-doc-full.man", res)
|
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, ",") {
|
for _, fileVar := range strings.Split(filePath, ",") {
|
||||||
if data, err := ioutil.ReadFile(fileVar); err == nil {
|
if fileVar != "" {
|
||||||
return string(data), true
|
if data, err := ioutil.ReadFile(fileVar); err == nil {
|
||||||
|
return string(data), true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return "", false
|
return "", false
|
||||||
|
@ -80,8 +80,7 @@ func (f *Float64Flag) IsVisible() bool {
|
|||||||
func (f *Float64Flag) Apply(set *flag.FlagSet) error {
|
func (f *Float64Flag) 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 != "" {
|
||||||
valFloat, err := strconv.ParseFloat(val, 10)
|
valFloat, err := strconv.ParseFloat(val, 64)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("could not parse %q as float64 value for flag %s: %s", val, f.Name, err)
|
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
|
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
|
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
|
f.HasBeenSet = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -109,10 +109,7 @@ func (c *Context) String(name string) string {
|
|||||||
func lookupString(name string, set *flag.FlagSet) string {
|
func lookupString(name string, set *flag.FlagSet) string {
|
||||||
f := set.Lookup(name)
|
f := set.Lookup(name)
|
||||||
if f != nil {
|
if f != nil {
|
||||||
parsed, err := f.Value.String(), error(nil)
|
parsed := f.Value.String()
|
||||||
if err != nil {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
return parsed
|
return parsed
|
||||||
}
|
}
|
||||||
return ""
|
return ""
|
||||||
|
13
flag_test.go
13
flag_test.go
@ -52,15 +52,21 @@ func TestBoolFlagApply_SetsAllNames(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestFlagsFromEnv(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 {
|
newSetIntSlice := func(defaults ...int) IntSlice {
|
||||||
s := NewIntSlice(defaults...)
|
s := NewIntSlice(defaults...)
|
||||||
s.hasBeenSet = true
|
s.hasBeenSet = false
|
||||||
return *s
|
return *s
|
||||||
}
|
}
|
||||||
|
|
||||||
newSetInt64Slice := func(defaults ...int64) Int64Slice {
|
newSetInt64Slice := func(defaults ...int64) Int64Slice {
|
||||||
s := NewInt64Slice(defaults...)
|
s := NewInt64Slice(defaults...)
|
||||||
s.hasBeenSet = true
|
s.hasBeenSet = false
|
||||||
return *s
|
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: .*`},
|
{"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: .*`},
|
{"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", 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: .*`},
|
{"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: .*`},
|
{"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
|
// CommandNotFoundFunc is executed if the proper command cannot be found
|
||||||
type CommandNotFoundFunc func(*Context, string)
|
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
|
// customized usage error messages. This function is able to replace the
|
||||||
// original error messages. If this function is not set, the "Incorrect usage"
|
// original error messages. If this function is not set, the "Incorrect usage"
|
||||||
// is displayed and the execution is interrupted.
|
// is displayed and the execution is interrupted.
|
||||||
|
10
go.mod
10
go.mod
@ -1,9 +1,11 @@
|
|||||||
module github.com/urfave/cli/v2
|
module github.com/urfave/cli/v2
|
||||||
|
|
||||||
go 1.11
|
go 1.18
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/BurntSushi/toml v0.3.1
|
github.com/BurntSushi/toml v1.1.0
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d
|
github.com/cpuguy83/go-md2man/v2 v2.0.1
|
||||||
gopkg.in/yaml.v2 v2.2.3
|
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 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
|
||||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
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/BurntSushi/toml v1.1.0 h1:ksErzDEI1khOiGPgpwuI7x2ebx/uXQNw7xJpn9Eq1+I=
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
github.com/BurntSushi/toml v1.1.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/cpuguy83/go-md2man/v2 v2.0.1 h1:r/myEWzV9lfsM1tFLgDyu0atFtJ1fXn261LKYj/3DxU=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||||
github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q=
|
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
|
||||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
github.com/russross/blackfriday/v2 v2.1.0/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=
|
|
||||||
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.3 h1:fvjTMHxHEw/mxHbtzPi3JCcKXQRAnQTBRo6YCJSVHKI=
|
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||||
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
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) {
|
return func(c *Context) {
|
||||||
if len(os.Args) > 2 {
|
if len(os.Args) > 2 {
|
||||||
lastArg := os.Args[len(os.Args)-2]
|
lastArg := os.Args[len(os.Args)-2]
|
||||||
|
|
||||||
if strings.HasPrefix(lastArg, "-") {
|
if strings.HasPrefix(lastArg, "-") {
|
||||||
printFlagSuggestions(lastArg, c.App.Flags, c.App.Writer)
|
|
||||||
if cmd != nil {
|
if cmd != nil {
|
||||||
printFlagSuggestions(lastArg, cmd.Flags, c.App.Writer)
|
printFlagSuggestions(lastArg, cmd.Flags, c.App.Writer)
|
||||||
|
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
printFlagSuggestions(lastArg, c.App.Flags, c.App.Writer)
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if cmd != nil {
|
if cmd != nil {
|
||||||
printCommandSuggestions(cmd.Subcommands, c.App.Writer)
|
printCommandSuggestions(cmd.Subcommands, c.App.Writer)
|
||||||
} else {
|
return
|
||||||
printCommandSuggestions(c.App.Commands, c.App.Writer)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
printCommandSuggestions(c.App.Commands, c.App.Writer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
197
help_test.go
197
help_test.go
@ -6,6 +6,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"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) {
|
func TestShowSubcommandHelp_SubcommandUsageText(t *testing.T) {
|
||||||
app := &App{
|
app := &App{
|
||||||
Commands: []*Command{
|
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) {
|
func TestShowAppHelp_HiddenCommand(t *testing.T) {
|
||||||
app := &App{
|
app := &App{
|
||||||
Commands: []*Command{
|
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) {
|
func TestHideHelpCommand(t *testing.T) {
|
||||||
app := &App{
|
app := &App{
|
||||||
HideHelpCommand: true,
|
HideHelpCommand: true,
|
||||||
@ -923,3 +1038,85 @@ func TestHideHelpCommand_WithSubcommands(t *testing.T) {
|
|||||||
t.Errorf("Run returned unexpected error: %v", err)
|
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"
|
cliBuiltFilePath = "./internal/example-cli/built-example"
|
||||||
helloSourceFilePath = "./internal/example-hello-world/example-hello-world.go"
|
helloSourceFilePath = "./internal/example-hello-world/example-hello-world.go"
|
||||||
helloBuiltFilePath = "./internal/example-hello-world/built-example"
|
helloBuiltFilePath = "./internal/example-hello-world/built-example"
|
||||||
desiredMinBinarySize = 1.8
|
desiredMinBinarySize = 1.9
|
||||||
desiredMaxBinarySize = 2.1
|
desiredMaxBinarySize = 2.2
|
||||||
badNewsEmoji = "🚨"
|
badNewsEmoji = "🚨"
|
||||||
goodNewsEmoji = "✨"
|
goodNewsEmoji = "✨"
|
||||||
checksPassedEmoji = "✅"
|
checksPassedEmoji = "✅"
|
||||||
|
20
template.go
20
template.go
@ -7,7 +7,7 @@ var AppHelpTemplate = `NAME:
|
|||||||
{{.Name}}{{if .Usage}} - {{.Usage}}{{end}}
|
{{.Name}}{{if .Usage}} - {{.Usage}}{{end}}
|
||||||
|
|
||||||
USAGE:
|
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:
|
||||||
{{.Version}}{{end}}{{end}}{{if .Description}}
|
{{.Version}}{{end}}{{end}}{{if .Description}}
|
||||||
@ -39,7 +39,7 @@ var CommandHelpTemplate = `NAME:
|
|||||||
{{.HelpName}} - {{.Usage}}
|
{{.HelpName}} - {{.Usage}}
|
||||||
|
|
||||||
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:
|
||||||
{{.Category}}{{end}}{{if .Description}}
|
{{.Category}}{{end}}{{if .Description}}
|
||||||
@ -59,7 +59,7 @@ var SubcommandHelpTemplate = `NAME:
|
|||||||
{{.HelpName}} - {{.Usage}}
|
{{.HelpName}} - {{.Usage}}
|
||||||
|
|
||||||
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:
|
||||||
{{.Description | nindent 3 | trim}}{{end}}
|
{{.Description | nindent 3 | trim}}{{end}}
|
||||||
@ -74,9 +74,9 @@ OPTIONS:
|
|||||||
{{end}}{{end}}
|
{{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 }}
|
{{ .App.Name }}{{ if .App.Usage }} - {{ .App.Usage }}{{ end }}
|
||||||
|
|
||||||
@ -86,16 +86,18 @@ var MarkdownDocTemplate = `% {{ .App.Name }} {{ .SectionNum }}
|
|||||||
{{ if .SynopsisArgs }}
|
{{ if .SynopsisArgs }}
|
||||||
` + "```" + `
|
` + "```" + `
|
||||||
{{ range $v := .SynopsisArgs }}{{ $v }}{{ end }}` + "```" + `
|
{{ range $v := .SynopsisArgs }}{{ $v }}{{ end }}` + "```" + `
|
||||||
{{ end }}{{ if .App.UsageText }}
|
{{ end }}{{ if .App.Description }}
|
||||||
# DESCRIPTION
|
# DESCRIPTION
|
||||||
|
|
||||||
{{ .App.UsageText }}
|
{{ .App.Description }}
|
||||||
{{ end }}
|
{{ end }}
|
||||||
**Usage**:
|
**Usage**:
|
||||||
|
|
||||||
` + "```" + `
|
` + "```" + `{{ if .App.UsageText }}
|
||||||
|
{{ .App.UsageText }}
|
||||||
|
{{ else }}
|
||||||
{{ .App.Name }} [GLOBAL OPTIONS] command [COMMAND OPTIONS] [ARGUMENTS...]
|
{{ .App.Name }} [GLOBAL OPTIONS] command [COMMAND OPTIONS] [ARGUMENTS...]
|
||||||
` + "```" + `
|
{{ end }}` + "```" + `
|
||||||
{{ if .GlobalArgs }}
|
{{ if .GlobalArgs }}
|
||||||
# GLOBAL OPTIONS
|
# GLOBAL OPTIONS
|
||||||
{{ range $v := .GlobalArgs }}
|
{{ range $v := .GlobalArgs }}
|
||||||
|
72
testdata/expected-doc-full.man
vendored
72
testdata/expected-doc-full.man
vendored
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
.SH NAME
|
.SH NAME
|
||||||
.PP
|
.PP
|
||||||
greet \- Some app
|
greet - Some app
|
||||||
|
|
||||||
|
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
@ -14,9 +14,9 @@ greet
|
|||||||
.RS
|
.RS
|
||||||
|
|
||||||
.nf
|
.nf
|
||||||
[\-\-another\-flag|\-b]
|
[--another-flag|-b]
|
||||||
[\-\-flag|\-\-fl|\-f]=[value]
|
[--flag|--fl|-f]=[value]
|
||||||
[\-\-socket|\-s]=[value]
|
[--socket|-s]=[value]
|
||||||
|
|
||||||
.fi
|
.fi
|
||||||
.RE
|
.RE
|
||||||
@ -24,7 +24,7 @@ greet
|
|||||||
|
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
.PP
|
.PP
|
||||||
app [first\_arg] [second\_arg]
|
Description of the application.
|
||||||
|
|
||||||
.PP
|
.PP
|
||||||
\fBUsage\fP:
|
\fBUsage\fP:
|
||||||
@ -33,7 +33,7 @@ app [first\_arg] [second\_arg]
|
|||||||
.RS
|
.RS
|
||||||
|
|
||||||
.nf
|
.nf
|
||||||
greet [GLOBAL OPTIONS] command [COMMAND OPTIONS] [ARGUMENTS...]
|
app [first_arg] [second_arg]
|
||||||
|
|
||||||
.fi
|
.fi
|
||||||
.RE
|
.RE
|
||||||
@ -41,13 +41,13 @@ greet [GLOBAL OPTIONS] command [COMMAND OPTIONS] [ARGUMENTS...]
|
|||||||
|
|
||||||
.SH GLOBAL OPTIONS
|
.SH GLOBAL OPTIONS
|
||||||
.PP
|
.PP
|
||||||
\fB\-\-another\-flag, \-b\fP: another usage text
|
\fB--another-flag, -b\fP: another usage text
|
||||||
|
|
||||||
.PP
|
.PP
|
||||||
\fB\-\-flag, \-\-fl, \-f\fP="":
|
\fB--flag, --fl, -f\fP="":
|
||||||
|
|
||||||
.PP
|
.PP
|
||||||
\fB\-\-socket, \-s\fP="": some 'usage' text (default: value)
|
\fB--socket, -s\fP="": some 'usage' text (default: value)
|
||||||
|
|
||||||
|
|
||||||
.SH COMMANDS
|
.SH COMMANDS
|
||||||
@ -56,23 +56,65 @@ greet [GLOBAL OPTIONS] command [COMMAND OPTIONS] [ARGUMENTS...]
|
|||||||
another usage test
|
another usage test
|
||||||
|
|
||||||
.PP
|
.PP
|
||||||
\fB\-\-another\-flag, \-b\fP: another usage text
|
\fB--another-flag, -b\fP: another usage text
|
||||||
|
|
||||||
.PP
|
.PP
|
||||||
\fB\-\-flag, \-\-fl, \-f\fP="":
|
\fB--flag, --fl, -f\fP="":
|
||||||
|
|
||||||
.SS sub\-config, s, ss
|
.SS sub-config, s, ss
|
||||||
.PP
|
.PP
|
||||||
another usage test
|
another usage test
|
||||||
|
|
||||||
.PP
|
.PP
|
||||||
\fB\-\-sub\-command\-flag, \-s\fP: some usage text
|
\fB--sub-command-flag, -s\fP: some usage text
|
||||||
|
|
||||||
.PP
|
.PP
|
||||||
\fB\-\-sub\-flag, \-\-sub\-fl, \-s\fP="":
|
\fB--sub-flag, --sub-fl, -s\fP="":
|
||||||
|
|
||||||
.SH info, i, in
|
.SH info, i, in
|
||||||
.PP
|
.PP
|
||||||
retrieve generic information
|
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
|
# NAME
|
||||||
|
|
||||||
greet - Some app
|
greet - Some app
|
||||||
@ -16,12 +14,12 @@ greet
|
|||||||
|
|
||||||
# DESCRIPTION
|
# DESCRIPTION
|
||||||
|
|
||||||
app [first_arg] [second_arg]
|
Description of the application.
|
||||||
|
|
||||||
**Usage**:
|
**Usage**:
|
||||||
|
|
||||||
```
|
```
|
||||||
greet [GLOBAL OPTIONS] command [COMMAND OPTIONS] [ARGUMENTS...]
|
app [first_arg] [second_arg]
|
||||||
```
|
```
|
||||||
|
|
||||||
# GLOBAL OPTIONS
|
# GLOBAL OPTIONS
|
||||||
@ -58,3 +56,29 @@ retrieve generic information
|
|||||||
## some-command
|
## 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
|
# NAME
|
||||||
|
|
||||||
greet - Some app
|
greet - Some app
|
||||||
@ -16,12 +14,12 @@ greet
|
|||||||
|
|
||||||
# DESCRIPTION
|
# DESCRIPTION
|
||||||
|
|
||||||
app [first_arg] [second_arg]
|
Description of the application.
|
||||||
|
|
||||||
**Usage**:
|
**Usage**:
|
||||||
|
|
||||||
```
|
```
|
||||||
greet [GLOBAL OPTIONS] command [COMMAND OPTIONS] [ARGUMENTS...]
|
app [first_arg] [second_arg]
|
||||||
```
|
```
|
||||||
|
|
||||||
# GLOBAL OPTIONS
|
# GLOBAL OPTIONS
|
||||||
@ -58,3 +56,29 @@ retrieve generic information
|
|||||||
## some-command
|
## 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
|
# NAME
|
||||||
|
|
||||||
greet - Some app
|
greet - Some app
|
||||||
@ -16,12 +14,12 @@ greet
|
|||||||
|
|
||||||
# DESCRIPTION
|
# DESCRIPTION
|
||||||
|
|
||||||
app [first_arg] [second_arg]
|
Description of the application.
|
||||||
|
|
||||||
**Usage**:
|
**Usage**:
|
||||||
|
|
||||||
```
|
```
|
||||||
greet [GLOBAL OPTIONS] command [COMMAND OPTIONS] [ARGUMENTS...]
|
app [first_arg] [second_arg]
|
||||||
```
|
```
|
||||||
|
|
||||||
# GLOBAL OPTIONS
|
# 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
|
# NAME
|
||||||
|
|
||||||
greet - Some app
|
greet - Some app
|
||||||
@ -10,12 +8,12 @@ greet
|
|||||||
|
|
||||||
# DESCRIPTION
|
# DESCRIPTION
|
||||||
|
|
||||||
app [first_arg] [second_arg]
|
Description of the application.
|
||||||
|
|
||||||
**Usage**:
|
**Usage**:
|
||||||
|
|
||||||
```
|
```
|
||||||
greet [GLOBAL OPTIONS] command [COMMAND OPTIONS] [ARGUMENTS...]
|
app [first_arg] [second_arg]
|
||||||
```
|
```
|
||||||
|
|
||||||
# COMMANDS
|
# COMMANDS
|
||||||
@ -43,3 +41,29 @@ retrieve generic information
|
|||||||
## some-command
|
## 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'
|
function __fish_greet_no_subcommand --description 'Test if there has been any subcommand yet'
|
||||||
for i in (commandline -opc)
|
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
|
return 1
|
||||||
end
|
end
|
||||||
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 -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 -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 -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…
x
Reference in New Issue
Block a user