Update to golang 1.18, update all vendored libraries
This commit is contained in:
parent
6ede82b418
commit
ddcdad2c0f
76 changed files with 9296 additions and 1474 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
rpaste
|
14
README.md
14
README.md
|
@ -1,3 +1,17 @@
|
|||
# rpaste
|
||||
|
||||
rpaste utility written in go.
|
||||
|
||||
This repository is hosted at the [RESF Git Service](https://git.resf.org) with a mirror to [Github](https://github.com/rocky-linux/rpaste).
|
||||
|
||||
## Installation
|
||||
|
||||
If you are running Rocky Linux, it is available in the extras repository.
|
||||
|
||||
```
|
||||
# dnf install rpaste
|
||||
```
|
||||
|
||||
## Building
|
||||
|
||||
If you are wanting to build this utility yourself, minimum golang 1.18 is required. Rocky Linux 8.7 and 9.1 should have this.
|
||||
|
|
9
go.mod
9
go.mod
|
@ -1,8 +1,11 @@
|
|||
module github.com/rocky-linux/rpaste
|
||||
|
||||
go 1.16
|
||||
go 1.18
|
||||
|
||||
require github.com/urfave/cli/v2 v2.19.2
|
||||
|
||||
require (
|
||||
github.com/urfave/cli/v2 v2.3.0
|
||||
gopkg.in/ini.v1 v1.66.2 // indirect
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
|
||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
|
||||
)
|
||||
|
|
22
go.sum
22
go.sum
|
@ -1,14 +1,8 @@
|
|||
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/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/urfave/cli/v2 v2.3.0 h1:qph92Y649prgesehzOrQjdWyxFOp/QVM+6imKHad91M=
|
||||
github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/ini.v1 v1.66.2 h1:XfR1dOYubytKy4Shzc2LHrrGhU0lDCfDGG1yLPmpgsI=
|
||||
gopkg.in/ini.v1 v1.66.2/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.2/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=
|
||||
github.com/urfave/cli/v2 v2.19.2 h1:eXu5089gqqiDQKSnFW+H/FhjrxRGztwSxlTsVK7IuqQ=
|
||||
github.com/urfave/cli/v2 v2.19.2/go.mod h1:1CNUng3PtjQMtRzJO4FMXBQvkGtuYRxxiR9xMa7jMwI=
|
||||
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU=
|
||||
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8=
|
||||
|
|
|
@ -17,7 +17,7 @@ import (
|
|||
// Sane defaults and basic info
|
||||
var (
|
||||
AppName = "rpaste"
|
||||
Version = "0.2.0"
|
||||
Version = "0.3.0"
|
||||
DefaultConf = "/etc/rpaste/rpaste.conf"
|
||||
DefaultLexer = "text"
|
||||
DefaultLifeTime = "1hour"
|
||||
|
|
105
vendor/github.com/cpuguy83/go-md2man/v2/md2man/roff.go
generated
vendored
105
vendor/github.com/cpuguy83/go-md2man/v2/md2man/roff.go
generated
vendored
|
@ -15,7 +15,7 @@ type roffRenderer struct {
|
|||
extensions blackfriday.Extensions
|
||||
listCounters []int
|
||||
firstHeader bool
|
||||
defineTerm bool
|
||||
firstDD bool
|
||||
listDepth int
|
||||
}
|
||||
|
||||
|
@ -42,7 +42,8 @@ const (
|
|||
quoteCloseTag = "\n.RE\n"
|
||||
listTag = "\n.RS\n"
|
||||
listCloseTag = "\n.RE\n"
|
||||
arglistTag = "\n.TP\n"
|
||||
dtTag = "\n.TP\n"
|
||||
dd2Tag = "\n"
|
||||
tableStart = "\n.TS\nallbox;\n"
|
||||
tableEnd = ".TE\n"
|
||||
tableCellStart = "T{\n"
|
||||
|
@ -90,7 +91,7 @@ func (r *roffRenderer) RenderNode(w io.Writer, node *blackfriday.Node, entering
|
|||
|
||||
switch node.Type {
|
||||
case blackfriday.Text:
|
||||
r.handleText(w, node, entering)
|
||||
escapeSpecialChars(w, node.Literal)
|
||||
case blackfriday.Softbreak:
|
||||
out(w, crTag)
|
||||
case blackfriday.Hardbreak:
|
||||
|
@ -150,40 +151,21 @@ func (r *roffRenderer) RenderNode(w io.Writer, node *blackfriday.Node, entering
|
|||
out(w, codeCloseTag)
|
||||
case blackfriday.Table:
|
||||
r.handleTable(w, node, entering)
|
||||
case blackfriday.TableCell:
|
||||
r.handleTableCell(w, node, entering)
|
||||
case blackfriday.TableHead:
|
||||
case blackfriday.TableBody:
|
||||
case blackfriday.TableRow:
|
||||
// no action as cell entries do all the nroff formatting
|
||||
return blackfriday.GoToNext
|
||||
case blackfriday.TableCell:
|
||||
r.handleTableCell(w, node, entering)
|
||||
case blackfriday.HTMLSpan:
|
||||
// ignore other HTML tags
|
||||
default:
|
||||
fmt.Fprintln(os.Stderr, "WARNING: go-md2man does not handle node type "+node.Type.String())
|
||||
}
|
||||
return walkAction
|
||||
}
|
||||
|
||||
func (r *roffRenderer) handleText(w io.Writer, node *blackfriday.Node, entering bool) {
|
||||
var (
|
||||
start, end string
|
||||
)
|
||||
// handle special roff table cell text encapsulation
|
||||
if node.Parent.Type == blackfriday.TableCell {
|
||||
if len(node.Literal) > 30 {
|
||||
start = tableCellStart
|
||||
end = tableCellEnd
|
||||
} else {
|
||||
// end rows that aren't terminated by "tableCellEnd" with a cr if end of row
|
||||
if node.Parent.Next == nil && !node.Parent.IsHeader {
|
||||
end = crTag
|
||||
}
|
||||
}
|
||||
}
|
||||
out(w, start)
|
||||
escapeSpecialChars(w, node.Literal)
|
||||
out(w, end)
|
||||
}
|
||||
|
||||
func (r *roffRenderer) handleHeading(w io.Writer, node *blackfriday.Node, entering bool) {
|
||||
if entering {
|
||||
switch node.Level {
|
||||
|
@ -230,15 +212,20 @@ func (r *roffRenderer) handleItem(w io.Writer, node *blackfriday.Node, entering
|
|||
if node.ListFlags&blackfriday.ListTypeOrdered != 0 {
|
||||
out(w, fmt.Sprintf(".IP \"%3d.\" 5\n", r.listCounters[len(r.listCounters)-1]))
|
||||
r.listCounters[len(r.listCounters)-1]++
|
||||
} else if node.ListFlags&blackfriday.ListTypeTerm != 0 {
|
||||
// DT (definition term): line just before DD (see below).
|
||||
out(w, dtTag)
|
||||
r.firstDD = true
|
||||
} else if node.ListFlags&blackfriday.ListTypeDefinition != 0 {
|
||||
// state machine for handling terms and following definitions
|
||||
// since blackfriday does not distinguish them properly, nor
|
||||
// does it seperate them into separate lists as it should
|
||||
if !r.defineTerm {
|
||||
out(w, arglistTag)
|
||||
r.defineTerm = true
|
||||
// DD (definition description): line that starts with ": ".
|
||||
//
|
||||
// We have to distinguish between the first DD and the
|
||||
// subsequent ones, as there should be no vertical
|
||||
// whitespace between the DT and the first DD.
|
||||
if r.firstDD {
|
||||
r.firstDD = false
|
||||
} else {
|
||||
r.defineTerm = false
|
||||
out(w, dd2Tag)
|
||||
}
|
||||
} else {
|
||||
out(w, ".IP \\(bu 2\n")
|
||||
|
@ -251,7 +238,7 @@ func (r *roffRenderer) handleItem(w io.Writer, node *blackfriday.Node, entering
|
|||
func (r *roffRenderer) handleTable(w io.Writer, node *blackfriday.Node, entering bool) {
|
||||
if entering {
|
||||
out(w, tableStart)
|
||||
//call walker to count cells (and rows?) so format section can be produced
|
||||
// call walker to count cells (and rows?) so format section can be produced
|
||||
columns := countColumns(node)
|
||||
out(w, strings.Repeat("l ", columns)+"\n")
|
||||
out(w, strings.Repeat("l ", columns)+".\n")
|
||||
|
@ -261,28 +248,41 @@ func (r *roffRenderer) handleTable(w io.Writer, node *blackfriday.Node, entering
|
|||
}
|
||||
|
||||
func (r *roffRenderer) handleTableCell(w io.Writer, node *blackfriday.Node, entering bool) {
|
||||
var (
|
||||
start, end string
|
||||
)
|
||||
if node.IsHeader {
|
||||
start = codespanTag
|
||||
end = codespanCloseTag
|
||||
}
|
||||
if entering {
|
||||
var start string
|
||||
if node.Prev != nil && node.Prev.Type == blackfriday.TableCell {
|
||||
out(w, "\t"+start)
|
||||
} else {
|
||||
out(w, start)
|
||||
start = "\t"
|
||||
}
|
||||
if node.IsHeader {
|
||||
start += codespanTag
|
||||
} else if nodeLiteralSize(node) > 30 {
|
||||
start += tableCellStart
|
||||
}
|
||||
out(w, start)
|
||||
} else {
|
||||
// need to carriage return if we are at the end of the header row
|
||||
if node.IsHeader && node.Next == nil {
|
||||
end = end + crTag
|
||||
var end string
|
||||
if node.IsHeader {
|
||||
end = codespanCloseTag
|
||||
} else if nodeLiteralSize(node) > 30 {
|
||||
end = tableCellEnd
|
||||
}
|
||||
if node.Next == nil && end != tableCellEnd {
|
||||
// Last cell: need to carriage return if we are at the end of the
|
||||
// header row and content isn't wrapped in a "tablecell"
|
||||
end += crTag
|
||||
}
|
||||
out(w, end)
|
||||
}
|
||||
}
|
||||
|
||||
func nodeLiteralSize(node *blackfriday.Node) int {
|
||||
total := 0
|
||||
for n := node.FirstChild; n != nil; n = n.FirstChild {
|
||||
total += len(n.Literal)
|
||||
}
|
||||
return total
|
||||
}
|
||||
|
||||
// because roff format requires knowing the column count before outputting any table
|
||||
// data we need to walk a table tree and count the columns
|
||||
func countColumns(node *blackfriday.Node) int {
|
||||
|
@ -309,15 +309,6 @@ func out(w io.Writer, output string) {
|
|||
io.WriteString(w, output) // nolint: errcheck
|
||||
}
|
||||
|
||||
func needsBackslash(c byte) bool {
|
||||
for _, r := range []byte("-_&\\~") {
|
||||
if c == r {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func escapeSpecialChars(w io.Writer, text []byte) {
|
||||
for i := 0; i < len(text); i++ {
|
||||
// escape initial apostrophe or period
|
||||
|
@ -328,7 +319,7 @@ func escapeSpecialChars(w io.Writer, text []byte) {
|
|||
// directly copy normal characters
|
||||
org := i
|
||||
|
||||
for i < len(text) && !needsBackslash(text[i]) {
|
||||
for i < len(text) && text[i] != '\\' {
|
||||
i++
|
||||
}
|
||||
if i > org {
|
||||
|
|
90
vendor/github.com/russross/blackfriday/v2/README.md
generated
vendored
90
vendor/github.com/russross/blackfriday/v2/README.md
generated
vendored
|
@ -1,4 +1,6 @@
|
|||
Blackfriday [![Build Status](https://travis-ci.org/russross/blackfriday.svg?branch=master)](https://travis-ci.org/russross/blackfriday)
|
||||
Blackfriday
|
||||
[![Build Status][BuildV2SVG]][BuildV2URL]
|
||||
[![PkgGoDev][PkgGoDevV2SVG]][PkgGoDevV2URL]
|
||||
===========
|
||||
|
||||
Blackfriday is a [Markdown][1] processor implemented in [Go][2]. It
|
||||
|
@ -16,19 +18,21 @@ It started as a translation from C of [Sundown][3].
|
|||
Installation
|
||||
------------
|
||||
|
||||
Blackfriday is compatible with any modern Go release. With Go 1.7 and git
|
||||
installed:
|
||||
Blackfriday is compatible with modern Go releases in module mode.
|
||||
With Go installed:
|
||||
|
||||
go get gopkg.in/russross/blackfriday.v2
|
||||
go get github.com/russross/blackfriday/v2
|
||||
|
||||
will download, compile, and install the package into your `$GOPATH`
|
||||
directory hierarchy. Alternatively, you can achieve the same if you
|
||||
import it into a project:
|
||||
will resolve and add the package to the current development module,
|
||||
then build and install it. Alternatively, you can achieve the same
|
||||
if you import it in a package:
|
||||
|
||||
import "gopkg.in/russross/blackfriday.v2"
|
||||
import "github.com/russross/blackfriday/v2"
|
||||
|
||||
and `go get` without parameters.
|
||||
|
||||
Legacy GOPATH mode is unsupported.
|
||||
|
||||
|
||||
Versions
|
||||
--------
|
||||
|
@ -36,13 +40,9 @@ Versions
|
|||
Currently maintained and recommended version of Blackfriday is `v2`. It's being
|
||||
developed on its own branch: https://github.com/russross/blackfriday/tree/v2 and the
|
||||
documentation is available at
|
||||
https://godoc.org/gopkg.in/russross/blackfriday.v2.
|
||||
https://pkg.go.dev/github.com/russross/blackfriday/v2.
|
||||
|
||||
It is `go get`-able via via [gopkg.in][6] at `gopkg.in/russross/blackfriday.v2`,
|
||||
but we highly recommend using package management tool like [dep][7] or
|
||||
[Glide][8] and make use of semantic versioning. With package management you
|
||||
should import `github.com/russross/blackfriday` and specify that you're using
|
||||
version 2.0.0.
|
||||
It is `go get`-able in module mode at `github.com/russross/blackfriday/v2`.
|
||||
|
||||
Version 2 offers a number of improvements over v1:
|
||||
|
||||
|
@ -62,6 +62,11 @@ Potential drawbacks:
|
|||
v2. See issue [#348](https://github.com/russross/blackfriday/issues/348) for
|
||||
tracking.
|
||||
|
||||
If you are still interested in the legacy `v1`, you can import it from
|
||||
`github.com/russross/blackfriday`. Documentation for the legacy v1 can be found
|
||||
here: https://pkg.go.dev/github.com/russross/blackfriday.
|
||||
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
|
@ -91,7 +96,7 @@ Here's an example of simple usage of Blackfriday together with Bluemonday:
|
|||
```go
|
||||
import (
|
||||
"github.com/microcosm-cc/bluemonday"
|
||||
"github.com/russross/blackfriday"
|
||||
"github.com/russross/blackfriday/v2"
|
||||
)
|
||||
|
||||
// ...
|
||||
|
@ -104,6 +109,8 @@ html := bluemonday.UGCPolicy().SanitizeBytes(unsafe)
|
|||
If you want to customize the set of options, use `blackfriday.WithExtensions`,
|
||||
`blackfriday.WithRenderer` and `blackfriday.WithRefOverride`.
|
||||
|
||||
### `blackfriday-tool`
|
||||
|
||||
You can also check out `blackfriday-tool` for a more complete example
|
||||
of how to use it. Download and install it using:
|
||||
|
||||
|
@ -114,7 +121,7 @@ markdown file using a standalone program. You can also browse the
|
|||
source directly on github if you are just looking for some example
|
||||
code:
|
||||
|
||||
* <http://github.com/russross/blackfriday-tool>
|
||||
* <https://github.com/russross/blackfriday-tool>
|
||||
|
||||
Note that if you have not already done so, installing
|
||||
`blackfriday-tool` will be sufficient to download and install
|
||||
|
@ -123,6 +130,22 @@ installed in `$GOPATH/bin`. This is a statically-linked binary that
|
|||
can be copied to wherever you need it without worrying about
|
||||
dependencies and library versions.
|
||||
|
||||
### Sanitized anchor names
|
||||
|
||||
Blackfriday includes an algorithm for creating sanitized anchor names
|
||||
corresponding to a given input text. This algorithm is used to create
|
||||
anchors for headings when `AutoHeadingIDs` extension is enabled. The
|
||||
algorithm has a specification, so that other packages can create
|
||||
compatible anchor names and links to those anchors.
|
||||
|
||||
The specification is located at https://pkg.go.dev/github.com/russross/blackfriday/v2#hdr-Sanitized_Anchor_Names.
|
||||
|
||||
[`SanitizedAnchorName`](https://pkg.go.dev/github.com/russross/blackfriday/v2#SanitizedAnchorName) exposes this functionality, and can be used to
|
||||
create compatible links to the anchor names generated by blackfriday.
|
||||
This algorithm is also implemented in a small standalone package at
|
||||
[`github.com/shurcooL/sanitized_anchor_name`](https://pkg.go.dev/github.com/shurcooL/sanitized_anchor_name). It can be useful for clients
|
||||
that want a small package and don't need full functionality of blackfriday.
|
||||
|
||||
|
||||
Features
|
||||
--------
|
||||
|
@ -199,6 +222,15 @@ implements the following extensions:
|
|||
You can use 3 or more backticks to mark the beginning of the
|
||||
block, and the same number to mark the end of the block.
|
||||
|
||||
To preserve classes of fenced code blocks while using the bluemonday
|
||||
HTML sanitizer, use the following policy:
|
||||
|
||||
```go
|
||||
p := bluemonday.UGCPolicy()
|
||||
p.AllowAttrs("class").Matching(regexp.MustCompile("^language-[a-zA-Z0-9]+$")).OnElements("code")
|
||||
html := p.SanitizeBytes(unsafe)
|
||||
```
|
||||
|
||||
* **Definition lists**. A simple definition list is made of a single-line
|
||||
term followed by a colon and the definition for that term.
|
||||
|
||||
|
@ -250,7 +282,7 @@ Other renderers
|
|||
Blackfriday is structured to allow alternative rendering engines. Here
|
||||
are a few of note:
|
||||
|
||||
* [github_flavored_markdown](https://godoc.org/github.com/shurcooL/github_flavored_markdown):
|
||||
* [github_flavored_markdown](https://pkg.go.dev/github.com/shurcooL/github_flavored_markdown):
|
||||
provides a GitHub Flavored Markdown renderer with fenced code block
|
||||
highlighting, clickable heading anchor links.
|
||||
|
||||
|
@ -261,20 +293,28 @@ are a few of note:
|
|||
* [markdownfmt](https://github.com/shurcooL/markdownfmt): like gofmt,
|
||||
but for markdown.
|
||||
|
||||
* [LaTeX output](https://github.com/Ambrevar/Blackfriday-LaTeX):
|
||||
* [LaTeX output](https://gitlab.com/ambrevar/blackfriday-latex):
|
||||
renders output as LaTeX.
|
||||
|
||||
* [bfchroma](https://github.com/Depado/bfchroma/): provides convenience
|
||||
integration with the [Chroma](https://github.com/alecthomas/chroma) code
|
||||
highlighting library. bfchroma is only compatible with v2 of Blackfriday and
|
||||
provides a drop-in renderer ready to use with Blackfriday, as well as
|
||||
options and means for further customization.
|
||||
|
||||
* [Blackfriday-Confluence](https://github.com/kentaro-m/blackfriday-confluence): provides a [Confluence Wiki Markup](https://confluence.atlassian.com/doc/confluence-wiki-markup-251003035.html) renderer.
|
||||
|
||||
* [Blackfriday-Slack](https://github.com/karriereat/blackfriday-slack): converts markdown to slack message style
|
||||
|
||||
Todo
|
||||
|
||||
TODO
|
||||
----
|
||||
|
||||
* More unit testing
|
||||
* Improve unicode support. It does not understand all unicode
|
||||
* Improve Unicode support. It does not understand all Unicode
|
||||
rules (about what constitutes a letter, a punctuation symbol,
|
||||
etc.), so it may fail to detect word boundaries correctly in
|
||||
some instances. It is safe on all utf-8 input.
|
||||
some instances. It is safe on all UTF-8 input.
|
||||
|
||||
|
||||
License
|
||||
|
@ -286,6 +326,10 @@ License
|
|||
[1]: https://daringfireball.net/projects/markdown/ "Markdown"
|
||||
[2]: https://golang.org/ "Go Language"
|
||||
[3]: https://github.com/vmg/sundown "Sundown"
|
||||
[4]: https://godoc.org/gopkg.in/russross/blackfriday.v2#Parse "Parse func"
|
||||
[4]: https://pkg.go.dev/github.com/russross/blackfriday/v2#Parse "Parse func"
|
||||
[5]: https://github.com/microcosm-cc/bluemonday "Bluemonday"
|
||||
[6]: https://labix.org/gopkg.in "gopkg.in"
|
||||
|
||||
[BuildV2SVG]: https://travis-ci.org/russross/blackfriday.svg?branch=v2
|
||||
[BuildV2URL]: https://travis-ci.org/russross/blackfriday
|
||||
[PkgGoDevV2SVG]: https://pkg.go.dev/badge/github.com/russross/blackfriday/v2
|
||||
[PkgGoDevV2URL]: https://pkg.go.dev/github.com/russross/blackfriday/v2
|
||||
|
|
30
vendor/github.com/russross/blackfriday/v2/block.go
generated
vendored
30
vendor/github.com/russross/blackfriday/v2/block.go
generated
vendored
|
@ -18,8 +18,7 @@ import (
|
|||
"html"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/shurcooL/sanitized_anchor_name"
|
||||
"unicode"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -259,7 +258,7 @@ func (p *Markdown) prefixHeading(data []byte) int {
|
|||
}
|
||||
if end > i {
|
||||
if id == "" && p.extensions&AutoHeadingIDs != 0 {
|
||||
id = sanitized_anchor_name.Create(string(data[i:end]))
|
||||
id = SanitizedAnchorName(string(data[i:end]))
|
||||
}
|
||||
block := p.addBlock(Heading, data[i:end])
|
||||
block.HeadingID = id
|
||||
|
@ -673,6 +672,7 @@ func (p *Markdown) fencedCodeBlock(data []byte, doRender bool) int {
|
|||
if beg == 0 || beg >= len(data) {
|
||||
return 0
|
||||
}
|
||||
fenceLength := beg - 1
|
||||
|
||||
var work bytes.Buffer
|
||||
work.Write([]byte(info))
|
||||
|
@ -706,6 +706,7 @@ func (p *Markdown) fencedCodeBlock(data []byte, doRender bool) int {
|
|||
if doRender {
|
||||
block := p.addBlock(CodeBlock, work.Bytes()) // TODO: get rid of temp buffer
|
||||
block.IsFenced = true
|
||||
block.FenceLength = fenceLength
|
||||
finalizeCodeBlock(block)
|
||||
}
|
||||
|
||||
|
@ -1503,7 +1504,7 @@ func (p *Markdown) paragraph(data []byte) int {
|
|||
|
||||
id := ""
|
||||
if p.extensions&AutoHeadingIDs != 0 {
|
||||
id = sanitized_anchor_name.Create(string(data[prev:eol]))
|
||||
id = SanitizedAnchorName(string(data[prev:eol]))
|
||||
}
|
||||
|
||||
block := p.addBlock(Heading, data[prev:eol])
|
||||
|
@ -1588,3 +1589,24 @@ func skipUntilChar(text []byte, start int, char byte) int {
|
|||
}
|
||||
return i
|
||||
}
|
||||
|
||||
// SanitizedAnchorName returns a sanitized anchor name for the given text.
|
||||
//
|
||||
// It implements the algorithm specified in the package comment.
|
||||
func SanitizedAnchorName(text string) string {
|
||||
var anchorName []rune
|
||||
futureDash := false
|
||||
for _, r := range text {
|
||||
switch {
|
||||
case unicode.IsLetter(r) || unicode.IsNumber(r):
|
||||
if futureDash && len(anchorName) > 0 {
|
||||
anchorName = append(anchorName, '-')
|
||||
}
|
||||
futureDash = false
|
||||
anchorName = append(anchorName, unicode.ToLower(r))
|
||||
default:
|
||||
futureDash = true
|
||||
}
|
||||
}
|
||||
return string(anchorName)
|
||||
}
|
||||
|
|
28
vendor/github.com/russross/blackfriday/v2/doc.go
generated
vendored
28
vendor/github.com/russross/blackfriday/v2/doc.go
generated
vendored
|
@ -15,4 +15,32 @@
|
|||
//
|
||||
// If you're interested in calling Blackfriday from command line, see
|
||||
// https://github.com/russross/blackfriday-tool.
|
||||
//
|
||||
// Sanitized Anchor Names
|
||||
//
|
||||
// Blackfriday includes an algorithm for creating sanitized anchor names
|
||||
// corresponding to a given input text. This algorithm is used to create
|
||||
// anchors for headings when AutoHeadingIDs extension is enabled. The
|
||||
// algorithm is specified below, so that other packages can create
|
||||
// compatible anchor names and links to those anchors.
|
||||
//
|
||||
// The algorithm iterates over the input text, interpreted as UTF-8,
|
||||
// one Unicode code point (rune) at a time. All runes that are letters (category L)
|
||||
// or numbers (category N) are considered valid characters. They are mapped to
|
||||
// lower case, and included in the output. All other runes are considered
|
||||
// invalid characters. Invalid characters that precede the first valid character,
|
||||
// as well as invalid character that follow the last valid character
|
||||
// are dropped completely. All other sequences of invalid characters
|
||||
// between two valid characters are replaced with a single dash character '-'.
|
||||
//
|
||||
// SanitizedAnchorName exposes this functionality, and can be used to
|
||||
// create compatible links to the anchor names generated by blackfriday.
|
||||
// This algorithm is also implemented in a small standalone package at
|
||||
// github.com/shurcooL/sanitized_anchor_name. It can be useful for clients
|
||||
// that want a small package and don't need full functionality of blackfriday.
|
||||
package blackfriday
|
||||
|
||||
// NOTE: Keep Sanitized Anchor Name algorithm in sync with package
|
||||
// github.com/shurcooL/sanitized_anchor_name.
|
||||
// Otherwise, users of sanitized_anchor_name will get anchor names
|
||||
// that are incompatible with those generated by blackfriday.
|
||||
|
|
2236
vendor/github.com/russross/blackfriday/v2/entities.go
generated
vendored
Normal file
2236
vendor/github.com/russross/blackfriday/v2/entities.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
42
vendor/github.com/russross/blackfriday/v2/esc.go
generated
vendored
42
vendor/github.com/russross/blackfriday/v2/esc.go
generated
vendored
|
@ -13,13 +13,27 @@ var htmlEscaper = [256][]byte{
|
|||
}
|
||||
|
||||
func escapeHTML(w io.Writer, s []byte) {
|
||||
escapeEntities(w, s, false)
|
||||
}
|
||||
|
||||
func escapeAllHTML(w io.Writer, s []byte) {
|
||||
escapeEntities(w, s, true)
|
||||
}
|
||||
|
||||
func escapeEntities(w io.Writer, s []byte, escapeValidEntities bool) {
|
||||
var start, end int
|
||||
for end < len(s) {
|
||||
escSeq := htmlEscaper[s[end]]
|
||||
if escSeq != nil {
|
||||
w.Write(s[start:end])
|
||||
w.Write(escSeq)
|
||||
start = end + 1
|
||||
isEntity, entityEnd := nodeIsEntity(s, end)
|
||||
if isEntity && !escapeValidEntities {
|
||||
w.Write(s[start : entityEnd+1])
|
||||
start = entityEnd + 1
|
||||
} else {
|
||||
w.Write(s[start:end])
|
||||
w.Write(escSeq)
|
||||
start = end + 1
|
||||
}
|
||||
}
|
||||
end++
|
||||
}
|
||||
|
@ -28,6 +42,28 @@ func escapeHTML(w io.Writer, s []byte) {
|
|||
}
|
||||
}
|
||||
|
||||
func nodeIsEntity(s []byte, end int) (isEntity bool, endEntityPos int) {
|
||||
isEntity = false
|
||||
endEntityPos = end + 1
|
||||
|
||||
if s[end] == '&' {
|
||||
for endEntityPos < len(s) {
|
||||
if s[endEntityPos] == ';' {
|
||||
if entities[string(s[end:endEntityPos+1])] {
|
||||
isEntity = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !isalnum(s[endEntityPos]) && s[endEntityPos] != '&' && s[endEntityPos] != '#' {
|
||||
break
|
||||
}
|
||||
endEntityPos++
|
||||
}
|
||||
}
|
||||
|
||||
return isEntity, endEntityPos
|
||||
}
|
||||
|
||||
func escLink(w io.Writer, text []byte) {
|
||||
unesc := html.UnescapeString(string(text))
|
||||
escapeHTML(w, []byte(unesc))
|
||||
|
|
1
vendor/github.com/russross/blackfriday/v2/go.mod
generated
vendored
1
vendor/github.com/russross/blackfriday/v2/go.mod
generated
vendored
|
@ -1 +0,0 @@
|
|||
module github.com/russross/blackfriday/v2
|
9
vendor/github.com/russross/blackfriday/v2/html.go
generated
vendored
9
vendor/github.com/russross/blackfriday/v2/html.go
generated
vendored
|
@ -132,7 +132,10 @@ func NewHTMLRenderer(params HTMLRendererParameters) *HTMLRenderer {
|
|||
}
|
||||
|
||||
if params.FootnoteReturnLinkContents == "" {
|
||||
params.FootnoteReturnLinkContents = `<sup>[return]</sup>`
|
||||
// U+FE0E is VARIATION SELECTOR-15.
|
||||
// It suppresses automatic emoji presentation of the preceding
|
||||
// U+21A9 LEFTWARDS ARROW WITH HOOK on iOS and iPadOS.
|
||||
params.FootnoteReturnLinkContents = "<span aria-label='Return'>↩\ufe0e</span>"
|
||||
}
|
||||
|
||||
return &HTMLRenderer{
|
||||
|
@ -616,7 +619,7 @@ func (r *HTMLRenderer) RenderNode(w io.Writer, node *Node, entering bool) WalkSt
|
|||
}
|
||||
case Code:
|
||||
r.out(w, codeTag)
|
||||
escapeHTML(w, node.Literal)
|
||||
escapeAllHTML(w, node.Literal)
|
||||
r.out(w, codeCloseTag)
|
||||
case Document:
|
||||
break
|
||||
|
@ -762,7 +765,7 @@ func (r *HTMLRenderer) RenderNode(w io.Writer, node *Node, entering bool) WalkSt
|
|||
r.cr(w)
|
||||
r.out(w, preTag)
|
||||
r.tag(w, codeTag[:len(codeTag)-1], attrs)
|
||||
escapeHTML(w, node.Literal)
|
||||
escapeAllHTML(w, node.Literal)
|
||||
r.out(w, codeCloseTag)
|
||||
r.out(w, preCloseTag)
|
||||
if node.Parent.Type != Item {
|
||||
|
|
2
vendor/github.com/russross/blackfriday/v2/inline.go
generated
vendored
2
vendor/github.com/russross/blackfriday/v2/inline.go
generated
vendored
|
@ -278,7 +278,7 @@ func link(p *Markdown, data []byte, offset int) (int, *Node) {
|
|||
case data[i] == '\n':
|
||||
textHasNl = true
|
||||
|
||||
case data[i-1] == '\\':
|
||||
case isBackslashEscaped(data, i):
|
||||
continue
|
||||
|
||||
case data[i] == '[':
|
||||
|
|
12
vendor/github.com/russross/blackfriday/v2/node.go
generated
vendored
12
vendor/github.com/russross/blackfriday/v2/node.go
generated
vendored
|
@ -199,7 +199,8 @@ func (n *Node) InsertBefore(sibling *Node) {
|
|||
}
|
||||
}
|
||||
|
||||
func (n *Node) isContainer() bool {
|
||||
// IsContainer returns true if 'n' can contain children.
|
||||
func (n *Node) IsContainer() bool {
|
||||
switch n.Type {
|
||||
case Document:
|
||||
fallthrough
|
||||
|
@ -238,6 +239,11 @@ func (n *Node) isContainer() bool {
|
|||
}
|
||||
}
|
||||
|
||||
// IsLeaf returns true if 'n' is a leaf node.
|
||||
func (n *Node) IsLeaf() bool {
|
||||
return !n.IsContainer()
|
||||
}
|
||||
|
||||
func (n *Node) canContain(t NodeType) bool {
|
||||
if n.Type == List {
|
||||
return t == Item
|
||||
|
@ -309,11 +315,11 @@ func newNodeWalker(root *Node) *nodeWalker {
|
|||
}
|
||||
|
||||
func (nw *nodeWalker) next() {
|
||||
if (!nw.current.isContainer() || !nw.entering) && nw.current == nw.root {
|
||||
if (!nw.current.IsContainer() || !nw.entering) && nw.current == nw.root {
|
||||
nw.current = nil
|
||||
return
|
||||
}
|
||||
if nw.entering && nw.current.isContainer() {
|
||||
if nw.entering && nw.current.IsContainer() {
|
||||
if nw.current.FirstChild != nil {
|
||||
nw.current = nw.current.FirstChild
|
||||
nw.entering = true
|
||||
|
|
16
vendor/github.com/shurcooL/sanitized_anchor_name/.travis.yml
generated
vendored
16
vendor/github.com/shurcooL/sanitized_anchor_name/.travis.yml
generated
vendored
|
@ -1,16 +0,0 @@
|
|||
sudo: false
|
||||
language: go
|
||||
go:
|
||||
- 1.x
|
||||
- master
|
||||
matrix:
|
||||
allow_failures:
|
||||
- go: master
|
||||
fast_finish: true
|
||||
install:
|
||||
- # Do nothing. This is needed to prevent default install action "go get -t -v ./..." from happening here (we want it to happen inside script step).
|
||||
script:
|
||||
- go get -t -v ./...
|
||||
- diff -u <(echo -n) <(gofmt -d -s .)
|
||||
- go tool vet .
|
||||
- go test -v -race ./...
|
21
vendor/github.com/shurcooL/sanitized_anchor_name/LICENSE
generated
vendored
21
vendor/github.com/shurcooL/sanitized_anchor_name/LICENSE
generated
vendored
|
@ -1,21 +0,0 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2015 Dmitri Shuralyov
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
36
vendor/github.com/shurcooL/sanitized_anchor_name/README.md
generated
vendored
36
vendor/github.com/shurcooL/sanitized_anchor_name/README.md
generated
vendored
|
@ -1,36 +0,0 @@
|
|||
sanitized_anchor_name
|
||||
=====================
|
||||
|
||||
[![Build Status](https://travis-ci.org/shurcooL/sanitized_anchor_name.svg?branch=master)](https://travis-ci.org/shurcooL/sanitized_anchor_name) [![GoDoc](https://godoc.org/github.com/shurcooL/sanitized_anchor_name?status.svg)](https://godoc.org/github.com/shurcooL/sanitized_anchor_name)
|
||||
|
||||
Package sanitized_anchor_name provides a func to create sanitized anchor names.
|
||||
|
||||
Its logic can be reused by multiple packages to create interoperable anchor names
|
||||
and links to those anchors.
|
||||
|
||||
At this time, it does not try to ensure that generated anchor names
|
||||
are unique, that responsibility falls on the caller.
|
||||
|
||||
Installation
|
||||
------------
|
||||
|
||||
```bash
|
||||
go get -u github.com/shurcooL/sanitized_anchor_name
|
||||
```
|
||||
|
||||
Example
|
||||
-------
|
||||
|
||||
```Go
|
||||
anchorName := sanitized_anchor_name.Create("This is a header")
|
||||
|
||||
fmt.Println(anchorName)
|
||||
|
||||
// Output:
|
||||
// this-is-a-header
|
||||
```
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
- [MIT License](LICENSE)
|
1
vendor/github.com/shurcooL/sanitized_anchor_name/go.mod
generated
vendored
1
vendor/github.com/shurcooL/sanitized_anchor_name/go.mod
generated
vendored
|
@ -1 +0,0 @@
|
|||
module github.com/shurcooL/sanitized_anchor_name
|
29
vendor/github.com/shurcooL/sanitized_anchor_name/main.go
generated
vendored
29
vendor/github.com/shurcooL/sanitized_anchor_name/main.go
generated
vendored
|
@ -1,29 +0,0 @@
|
|||
// Package sanitized_anchor_name provides a func to create sanitized anchor names.
|
||||
//
|
||||
// Its logic can be reused by multiple packages to create interoperable anchor names
|
||||
// and links to those anchors.
|
||||
//
|
||||
// At this time, it does not try to ensure that generated anchor names
|
||||
// are unique, that responsibility falls on the caller.
|
||||
package sanitized_anchor_name // import "github.com/shurcooL/sanitized_anchor_name"
|
||||
|
||||
import "unicode"
|
||||
|
||||
// Create returns a sanitized anchor name for the given text.
|
||||
func Create(text string) string {
|
||||
var anchorName []rune
|
||||
var futureDash = false
|
||||
for _, r := range text {
|
||||
switch {
|
||||
case unicode.IsLetter(r) || unicode.IsNumber(r):
|
||||
if futureDash && len(anchorName) > 0 {
|
||||
anchorName = append(anchorName, '-')
|
||||
}
|
||||
futureDash = false
|
||||
anchorName = append(anchorName, unicode.ToLower(r))
|
||||
default:
|
||||
futureDash = true
|
||||
}
|
||||
}
|
||||
return string(anchorName)
|
||||
}
|
12
vendor/github.com/urfave/cli/v2/.gitignore
generated
vendored
12
vendor/github.com/urfave/cli/v2/.gitignore
generated
vendored
|
@ -1,7 +1,13 @@
|
|||
*.coverprofile
|
||||
*.exe
|
||||
*.orig
|
||||
node_modules/
|
||||
vendor
|
||||
.*envrc
|
||||
.envrc
|
||||
.idea
|
||||
internal/*/built-example
|
||||
/.local/
|
||||
/site/
|
||||
coverage.txt
|
||||
internal/*/built-example
|
||||
vendor
|
||||
/cmd/urfave-cli-genflags/urfave-cli-genflags
|
||||
*.exe
|
||||
|
|
11
vendor/github.com/urfave/cli/v2/CODE_OF_CONDUCT.md
generated
vendored
11
vendor/github.com/urfave/cli/v2/CODE_OF_CONDUCT.md
generated
vendored
|
@ -55,11 +55,12 @@ further defined and clarified by project maintainers.
|
|||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||
reported by contacting Dan Buch at dan@meatballhat.com. All complaints will be
|
||||
reviewed and investigated and will result in a response that is deemed necessary
|
||||
and appropriate to the circumstances. The project team is obligated to maintain
|
||||
confidentiality with regard to the reporter of an incident. Further details of
|
||||
specific enforcement policies may be posted separately.
|
||||
reported by contacting urfave-governance@googlegroups.com, a members-only group
|
||||
that is world-postable. All complaints will be reviewed and investigated and
|
||||
will result in a response that is deemed necessary and appropriate to the
|
||||
circumstances. The project team is obligated to maintain confidentiality with
|
||||
regard to the reporter of an incident. Further details of specific enforcement
|
||||
policies may be posted separately.
|
||||
|
||||
Project maintainers who do not follow or enforce the Code of Conduct in good
|
||||
faith may face temporary or permanent repercussions as determined by other
|
||||
|
|
2
vendor/github.com/urfave/cli/v2/LICENSE
generated
vendored
2
vendor/github.com/urfave/cli/v2/LICENSE
generated
vendored
|
@ -1,6 +1,6 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2016 Jeremy Saenz & Contributors
|
||||
Copyright (c) 2022 urfave/cli maintainers
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
|
26
vendor/github.com/urfave/cli/v2/Makefile
generated
vendored
Normal file
26
vendor/github.com/urfave/cli/v2/Makefile
generated
vendored
Normal file
|
@ -0,0 +1,26 @@
|
|||
# NOTE: this Makefile is meant to provide a simplified entry point for humans to
|
||||
# run all of the critical steps to verify one's changes are harmonious in
|
||||
# nature. Keeping target bodies to one line each and abstaining from make magic
|
||||
# are very important so that maintainers and contributors can focus their
|
||||
# attention on files that are primarily Go.
|
||||
|
||||
GO_RUN_BUILD := go run internal/build/build.go
|
||||
|
||||
.PHONY: all
|
||||
all: generate vet test check-binary-size gfmrun yamlfmt v2diff
|
||||
|
||||
# NOTE: this is a special catch-all rule to run any of the commands
|
||||
# defined in internal/build/build.go with optional arguments passed
|
||||
# via GFLAGS (global flags) and FLAGS (command-specific flags), e.g.:
|
||||
#
|
||||
# $ make test GFLAGS='--packages cli'
|
||||
%:
|
||||
$(GO_RUN_BUILD) $(GFLAGS) $* $(FLAGS)
|
||||
|
||||
.PHONY: docs
|
||||
docs:
|
||||
mkdocs build
|
||||
|
||||
.PHONY: serve-docs
|
||||
serve-docs:
|
||||
mkdocs serve
|
67
vendor/github.com/urfave/cli/v2/README.md
generated
vendored
67
vendor/github.com/urfave/cli/v2/README.md
generated
vendored
|
@ -1,70 +1,19 @@
|
|||
cli
|
||||
===
|
||||
# cli
|
||||
|
||||
[![GoDoc](https://godoc.org/github.com/urfave/cli?status.svg)](https://godoc.org/github.com/urfave/cli)
|
||||
[![GoDoc](https://godoc.org/github.com/urfave/cli?status.svg)](https://pkg.go.dev/github.com/urfave/cli/v2)
|
||||
[![codebeat](https://codebeat.co/badges/0a8f30aa-f975-404b-b878-5fab3ae1cc5f)](https://codebeat.co/projects/github-com-urfave-cli)
|
||||
[![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
|
||||
applications in an expressive way.
|
||||
|
||||
## Usage Documentation
|
||||
## 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`.
|
||||
More documentation is available in [`./docs`](./docs) or the hosted
|
||||
documentation site at <https://cli.urfave.org>.
|
||||
|
||||
- `v2` - [./docs/v2/manual.md](./docs/v2/manual.md)
|
||||
- `v1` - [./docs/v1/manual.md](./docs/v1/manual.md)
|
||||
## License
|
||||
|
||||
Guides for migrating to newer versions:
|
||||
|
||||
- `v1-to-v2` - [./docs/migrate-v1-to-v2.md](./docs/migrate-v1-to-v2.md)
|
||||
|
||||
## Installation
|
||||
|
||||
Using this package requires a working Go environment. [See the install instructions for Go](http://golang.org/doc/install.html).
|
||||
|
||||
Go Modules are required when using this package. [See the go blog guide on using Go Modules](https://blog.golang.org/using-go-modules).
|
||||
|
||||
### Using `v2` releases
|
||||
|
||||
```
|
||||
$ GO111MODULE=on go get github.com/urfave/cli/v2
|
||||
```
|
||||
|
||||
```go
|
||||
...
|
||||
import (
|
||||
"github.com/urfave/cli/v2" // imports as package "cli"
|
||||
)
|
||||
...
|
||||
```
|
||||
|
||||
### Using `v1` releases
|
||||
|
||||
```
|
||||
$ GO111MODULE=on go get github.com/urfave/cli
|
||||
```
|
||||
|
||||
```go
|
||||
...
|
||||
import (
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
...
|
||||
```
|
||||
|
||||
### GOPATH
|
||||
|
||||
Make sure your `PATH` includes the `$GOPATH/bin` directory so your commands can
|
||||
be easily used:
|
||||
```
|
||||
export PATH=$PATH:$GOPATH/bin
|
||||
```
|
||||
|
||||
### Supported platforms
|
||||
|
||||
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).
|
||||
See [`LICENSE`](./LICENSE)
|
||||
|
|
312
vendor/github.com/urfave/cli/v2/app.go
generated
vendored
312
vendor/github.com/urfave/cli/v2/app.go
generated
vendored
|
@ -7,17 +7,24 @@ import (
|
|||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"sort"
|
||||
"time"
|
||||
)
|
||||
|
||||
const suggestDidYouMeanTemplate = "Did you mean %q?"
|
||||
|
||||
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. "+
|
||||
fmt.Sprintf("Must be `func(*Context`)` or `func(*Context) error). %s", contactSysadmin)+
|
||||
fmt.Sprintf("See %s", appActionDeprecationURL), 2)
|
||||
|
||||
SuggestFlag SuggestFlagFunc = suggestFlag
|
||||
SuggestCommand SuggestCommandFunc = suggestCommand
|
||||
SuggestDidYouMeanTemplate string = suggestDidYouMeanTemplate
|
||||
)
|
||||
|
||||
// App is the main structure of a cli application. It is recommended that
|
||||
|
@ -37,6 +44,9 @@ type App struct {
|
|||
Version string
|
||||
// Description of the program
|
||||
Description string
|
||||
// DefaultCommand is the (optional) name of a command
|
||||
// to run if no command names are passed as CLI arguments.
|
||||
DefaultCommand string
|
||||
// List of commands to execute
|
||||
Commands []*Command
|
||||
// List of flags to parse
|
||||
|
@ -52,6 +62,8 @@ type App struct {
|
|||
HideVersion bool
|
||||
// categories contains the categorized commands and is populated on app startup
|
||||
categories CommandCategories
|
||||
// flagCategories contains the categorized flags and is populated on app startup
|
||||
flagCategories FlagCategories
|
||||
// An action to execute when the shell completion flag is set
|
||||
BashComplete BashCompleteFunc
|
||||
// An action to execute before any subcommands are run, but after the context is ready
|
||||
|
@ -66,6 +78,8 @@ type App struct {
|
|||
CommandNotFound CommandNotFoundFunc
|
||||
// Execute this function if a usage error occurs
|
||||
OnUsageError OnUsageErrorFunc
|
||||
// Execute this function when an invalid flag is accessed from the context
|
||||
InvalidFlagAccessHandler InvalidFlagAccessFunc
|
||||
// Compilation date
|
||||
Compiled time.Time
|
||||
// List of all authors who contributed
|
||||
|
@ -94,10 +108,16 @@ type App struct {
|
|||
// single-character bool arguments into one
|
||||
// i.e. foobar -o -v -> foobar -ov
|
||||
UseShortOptionHandling bool
|
||||
// Enable suggestions for commands and flags
|
||||
Suggest bool
|
||||
|
||||
didSetup bool
|
||||
}
|
||||
|
||||
type SuggestFlagFunc func(flags []Flag, provided string, hideHelp bool) string
|
||||
|
||||
type SuggestCommandFunc func(commands []*Command, provided string) string
|
||||
|
||||
// Tries to find out when this binary was compiled.
|
||||
// Returns the current time if it fails to find it.
|
||||
func compileTime() time.Time {
|
||||
|
@ -113,7 +133,6 @@ func compileTime() time.Time {
|
|||
func NewApp() *App {
|
||||
return &App{
|
||||
Name: filepath.Base(os.Args[0]),
|
||||
HelpName: filepath.Base(os.Args[0]),
|
||||
Usage: "A new cli application",
|
||||
UsageText: "",
|
||||
BashComplete: DefaultAppComplete,
|
||||
|
@ -140,7 +159,7 @@ func (a *App) Setup() {
|
|||
}
|
||||
|
||||
if a.HelpName == "" {
|
||||
a.HelpName = filepath.Base(os.Args[0])
|
||||
a.HelpName = a.Name
|
||||
}
|
||||
|
||||
if a.Usage == "" {
|
||||
|
@ -181,6 +200,8 @@ func (a *App) Setup() {
|
|||
if c.HelpName == "" {
|
||||
c.HelpName = fmt.Sprintf("%s %s", a.HelpName, c.Name)
|
||||
}
|
||||
|
||||
c.flagCategories = newFlagCategoriesFromFlags(c.Flags)
|
||||
newCommands = append(newCommands, c)
|
||||
}
|
||||
a.Commands = newCommands
|
||||
|
@ -205,6 +226,15 @@ func (a *App) Setup() {
|
|||
}
|
||||
sort.Sort(a.categories.(*commandCategories))
|
||||
|
||||
a.flagCategories = newFlagCategories()
|
||||
for _, fl := range a.Flags {
|
||||
if cf, ok := fl.(CategorizableFlag); ok {
|
||||
if cf.GetCategory() != "" {
|
||||
a.flagCategories.AddFlag(cf.GetCategory(), cf)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if a.Metadata == nil {
|
||||
a.Metadata = make(map[string]interface{})
|
||||
}
|
||||
|
@ -245,48 +275,41 @@ func (a *App) RunContext(ctx context.Context, arguments []string) (err error) {
|
|||
|
||||
err = parseIter(set, a, arguments[1:], shellComplete)
|
||||
nerr := normalizeFlags(a.Flags, set)
|
||||
context := NewContext(a, set, &Context{Context: ctx})
|
||||
cCtx := NewContext(a, set, &Context{Context: ctx})
|
||||
if nerr != nil {
|
||||
_, _ = fmt.Fprintln(a.Writer, nerr)
|
||||
_ = ShowAppHelp(context)
|
||||
if !a.HideHelp {
|
||||
_ = ShowAppHelp(cCtx)
|
||||
}
|
||||
return nerr
|
||||
}
|
||||
context.shellComplete = shellComplete
|
||||
cCtx.shellComplete = shellComplete
|
||||
|
||||
if checkCompletions(context) {
|
||||
if checkCompletions(cCtx) {
|
||||
return nil
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
if a.OnUsageError != nil {
|
||||
err := a.OnUsageError(context, err, false)
|
||||
a.handleExitCoder(context, err)
|
||||
err := a.OnUsageError(cCtx, err, false)
|
||||
a.handleExitCoder(cCtx, err)
|
||||
return err
|
||||
}
|
||||
_, _ = fmt.Fprintf(a.Writer, "%s %s\n\n", "Incorrect Usage.", err.Error())
|
||||
_ = ShowAppHelp(context)
|
||||
if a.Suggest {
|
||||
if suggestion, err := a.suggestFlagFromError(err, ""); err == nil {
|
||||
fmt.Fprintf(a.Writer, suggestion)
|
||||
}
|
||||
}
|
||||
if !a.HideHelp {
|
||||
_ = ShowAppHelp(cCtx)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
if !a.HideHelp && checkHelp(context) {
|
||||
_ = ShowAppHelp(context)
|
||||
return nil
|
||||
}
|
||||
|
||||
if !a.HideVersion && checkVersion(context) {
|
||||
ShowVersion(context)
|
||||
return nil
|
||||
}
|
||||
|
||||
cerr := checkRequiredFlags(a.Flags, context)
|
||||
if cerr != nil {
|
||||
_ = ShowAppHelp(context)
|
||||
return cerr
|
||||
}
|
||||
|
||||
if a.After != nil {
|
||||
if a.After != nil && !cCtx.shellComplete {
|
||||
defer func() {
|
||||
if afterErr := a.After(context); afterErr != nil {
|
||||
if afterErr := a.After(cCtx); afterErr != nil {
|
||||
if err != nil {
|
||||
err = newMultiError(err, afterErr)
|
||||
} else {
|
||||
|
@ -296,22 +319,74 @@ func (a *App) RunContext(ctx context.Context, arguments []string) (err error) {
|
|||
}()
|
||||
}
|
||||
|
||||
if a.Before != nil {
|
||||
beforeErr := a.Before(context)
|
||||
if !a.HideHelp && checkHelp(cCtx) {
|
||||
_ = ShowAppHelp(cCtx)
|
||||
return nil
|
||||
}
|
||||
|
||||
if !a.HideVersion && checkVersion(cCtx) {
|
||||
ShowVersion(cCtx)
|
||||
return nil
|
||||
}
|
||||
|
||||
cerr := cCtx.checkRequiredFlags(a.Flags)
|
||||
if cerr != nil {
|
||||
_ = ShowAppHelp(cCtx)
|
||||
return cerr
|
||||
}
|
||||
|
||||
if a.Before != nil && !cCtx.shellComplete {
|
||||
beforeErr := a.Before(cCtx)
|
||||
if beforeErr != nil {
|
||||
a.handleExitCoder(context, beforeErr)
|
||||
a.handleExitCoder(cCtx, beforeErr)
|
||||
err = beforeErr
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
args := context.Args()
|
||||
if err = runFlagActions(cCtx, a.Flags); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var c *Command
|
||||
args := cCtx.Args()
|
||||
if args.Present() {
|
||||
name := args.First()
|
||||
c := a.Command(name)
|
||||
if c != nil {
|
||||
return c.Run(context)
|
||||
if a.validCommandName(name) {
|
||||
c = a.Command(name)
|
||||
} else {
|
||||
hasDefault := a.DefaultCommand != ""
|
||||
isFlagName := checkStringSliceIncludes(name, cCtx.FlagNames())
|
||||
|
||||
var (
|
||||
isDefaultSubcommand = false
|
||||
defaultHasSubcommands = false
|
||||
)
|
||||
|
||||
if hasDefault {
|
||||
dc := a.Command(a.DefaultCommand)
|
||||
defaultHasSubcommands = len(dc.Subcommands) > 0
|
||||
for _, dcSub := range dc.Subcommands {
|
||||
if checkStringSliceIncludes(name, dcSub.Names()) {
|
||||
isDefaultSubcommand = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if isFlagName || (hasDefault && (defaultHasSubcommands && isDefaultSubcommand)) {
|
||||
argsWithDefault := a.argsWithDefaultCommand(args)
|
||||
if !reflect.DeepEqual(args, argsWithDefault) {
|
||||
c = a.Command(argsWithDefault.First())
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if a.DefaultCommand != "" {
|
||||
c = a.Command(a.DefaultCommand)
|
||||
}
|
||||
|
||||
if c != nil {
|
||||
return c.Run(cCtx)
|
||||
}
|
||||
|
||||
if a.Action == nil {
|
||||
|
@ -319,16 +394,39 @@ func (a *App) RunContext(ctx context.Context, arguments []string) (err error) {
|
|||
}
|
||||
|
||||
// Run default Action
|
||||
err = a.Action(context)
|
||||
err = a.Action(cCtx)
|
||||
|
||||
a.handleExitCoder(context, err)
|
||||
a.handleExitCoder(cCtx, err)
|
||||
return err
|
||||
}
|
||||
|
||||
func (a *App) suggestFlagFromError(err error, command string) (string, error) {
|
||||
flag, parseErr := flagFromError(err)
|
||||
if parseErr != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
flags := a.Flags
|
||||
if command != "" {
|
||||
cmd := a.Command(command)
|
||||
if cmd == nil {
|
||||
return "", err
|
||||
}
|
||||
flags = cmd.Flags
|
||||
}
|
||||
|
||||
suggestion := SuggestFlag(flags, flag, a.HideHelp)
|
||||
if len(suggestion) == 0 {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return fmt.Sprintf(SuggestDidYouMeanTemplate+"\n\n", suggestion), nil
|
||||
}
|
||||
|
||||
// RunAndExitOnError calls .Run() and exits non-zero if an error was returned
|
||||
//
|
||||
// Deprecated: instead you should return an error that fulfills cli.ExitCoder
|
||||
// to cli.App.Run. This will cause the application to exit with the given eror
|
||||
// to cli.App.Run. This will cause the application to exit with the given error
|
||||
// code in the cli.ExitCoder
|
||||
func (a *App) RunAndExitOnError() {
|
||||
if err := a.Run(os.Args); err != nil {
|
||||
|
@ -359,55 +457,60 @@ func (a *App) RunAsSubcommand(ctx *Context) (err error) {
|
|||
|
||||
err = parseIter(set, a, ctx.Args().Tail(), ctx.shellComplete)
|
||||
nerr := normalizeFlags(a.Flags, set)
|
||||
context := NewContext(a, set, ctx)
|
||||
cCtx := NewContext(a, set, ctx)
|
||||
|
||||
if nerr != nil {
|
||||
_, _ = fmt.Fprintln(a.Writer, nerr)
|
||||
_, _ = fmt.Fprintln(a.Writer)
|
||||
if len(a.Commands) > 0 {
|
||||
_ = ShowSubcommandHelp(context)
|
||||
_ = ShowSubcommandHelp(cCtx)
|
||||
} else {
|
||||
_ = ShowCommandHelp(ctx, context.Args().First())
|
||||
_ = ShowCommandHelp(ctx, cCtx.Args().First())
|
||||
}
|
||||
return nerr
|
||||
}
|
||||
|
||||
if checkCompletions(context) {
|
||||
if checkCompletions(cCtx) {
|
||||
return nil
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
if a.OnUsageError != nil {
|
||||
err = a.OnUsageError(context, err, true)
|
||||
a.handleExitCoder(context, err)
|
||||
err = a.OnUsageError(cCtx, err, true)
|
||||
a.handleExitCoder(cCtx, err)
|
||||
return err
|
||||
}
|
||||
_, _ = fmt.Fprintf(a.Writer, "%s %s\n\n", "Incorrect Usage.", err.Error())
|
||||
_ = ShowSubcommandHelp(context)
|
||||
if a.Suggest {
|
||||
if suggestion, err := a.suggestFlagFromError(err, cCtx.Command.Name); err == nil {
|
||||
fmt.Fprintf(a.Writer, suggestion)
|
||||
}
|
||||
}
|
||||
_ = ShowSubcommandHelp(cCtx)
|
||||
return err
|
||||
}
|
||||
|
||||
if len(a.Commands) > 0 {
|
||||
if checkSubcommandHelp(context) {
|
||||
if checkSubcommandHelp(cCtx) {
|
||||
return nil
|
||||
}
|
||||
} else {
|
||||
if checkCommandHelp(ctx, context.Args().First()) {
|
||||
if checkCommandHelp(ctx, cCtx.Args().First()) {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
cerr := checkRequiredFlags(a.Flags, context)
|
||||
cerr := cCtx.checkRequiredFlags(a.Flags)
|
||||
if cerr != nil {
|
||||
_ = ShowSubcommandHelp(context)
|
||||
_ = ShowSubcommandHelp(cCtx)
|
||||
return cerr
|
||||
}
|
||||
|
||||
if a.After != nil {
|
||||
if a.After != nil && !cCtx.shellComplete {
|
||||
defer func() {
|
||||
afterErr := a.After(context)
|
||||
afterErr := a.After(cCtx)
|
||||
if afterErr != nil {
|
||||
a.handleExitCoder(context, err)
|
||||
a.handleExitCoder(cCtx, err)
|
||||
if err != nil {
|
||||
err = newMultiError(err, afterErr)
|
||||
} else {
|
||||
|
@ -417,28 +520,32 @@ func (a *App) RunAsSubcommand(ctx *Context) (err error) {
|
|||
}()
|
||||
}
|
||||
|
||||
if a.Before != nil {
|
||||
beforeErr := a.Before(context)
|
||||
if a.Before != nil && !cCtx.shellComplete {
|
||||
beforeErr := a.Before(cCtx)
|
||||
if beforeErr != nil {
|
||||
a.handleExitCoder(context, beforeErr)
|
||||
a.handleExitCoder(cCtx, beforeErr)
|
||||
err = beforeErr
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
args := context.Args()
|
||||
if err = runFlagActions(cCtx, a.Flags); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
args := cCtx.Args()
|
||||
if args.Present() {
|
||||
name := args.First()
|
||||
c := a.Command(name)
|
||||
if c != nil {
|
||||
return c.Run(context)
|
||||
return c.Run(cCtx)
|
||||
}
|
||||
}
|
||||
|
||||
// Run default Action
|
||||
err = a.Action(context)
|
||||
err = a.Action(cCtx)
|
||||
|
||||
a.handleExitCoder(context, err)
|
||||
a.handleExitCoder(cCtx, err)
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -481,6 +588,14 @@ func (a *App) VisibleCommands() []*Command {
|
|||
return ret
|
||||
}
|
||||
|
||||
// VisibleFlagCategories returns a slice containing all the categories with the flags they contain
|
||||
func (a *App) VisibleFlagCategories() []VisibleFlagCategory {
|
||||
if a.flagCategories == nil {
|
||||
return []VisibleFlagCategory{}
|
||||
}
|
||||
return a.flagCategories.VisibleCategories()
|
||||
}
|
||||
|
||||
// VisibleFlags returns a slice of the Flags with Hidden=false
|
||||
func (a *App) VisibleFlags() []Flag {
|
||||
return visibleFlags(a.Flags)
|
||||
|
@ -498,14 +613,69 @@ func (a *App) appendCommand(c *Command) {
|
|||
}
|
||||
}
|
||||
|
||||
func (a *App) handleExitCoder(context *Context, err error) {
|
||||
func (a *App) handleExitCoder(cCtx *Context, err error) {
|
||||
if a.ExitErrHandler != nil {
|
||||
a.ExitErrHandler(context, err)
|
||||
a.ExitErrHandler(cCtx, err)
|
||||
} else {
|
||||
HandleExitCoder(err)
|
||||
}
|
||||
}
|
||||
|
||||
func (a *App) commandNames() []string {
|
||||
var cmdNames []string
|
||||
|
||||
for _, cmd := range a.Commands {
|
||||
cmdNames = append(cmdNames, cmd.Names()...)
|
||||
}
|
||||
|
||||
return cmdNames
|
||||
}
|
||||
|
||||
func (a *App) validCommandName(checkCmdName string) bool {
|
||||
valid := false
|
||||
allCommandNames := a.commandNames()
|
||||
|
||||
for _, cmdName := range allCommandNames {
|
||||
if checkCmdName == cmdName {
|
||||
valid = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return valid
|
||||
}
|
||||
|
||||
func (a *App) argsWithDefaultCommand(oldArgs Args) Args {
|
||||
if a.DefaultCommand != "" {
|
||||
rawArgs := append([]string{a.DefaultCommand}, oldArgs.Slice()...)
|
||||
newArgs := args(rawArgs)
|
||||
|
||||
return &newArgs
|
||||
}
|
||||
|
||||
return oldArgs
|
||||
}
|
||||
|
||||
func runFlagActions(c *Context, fs []Flag) error {
|
||||
for _, f := range fs {
|
||||
isSet := false
|
||||
for _, name := range f.Names() {
|
||||
if c.IsSet(name) {
|
||||
isSet = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if isSet {
|
||||
if af, ok := f.(ActionableFlag); ok {
|
||||
if err := af.RunAction(c); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Author represents someone who has contributed to a cli project.
|
||||
type Author struct {
|
||||
Name string // The Authors name
|
||||
|
@ -525,16 +695,28 @@ func (a *Author) String() string {
|
|||
// HandleAction attempts to figure out which Action signature was used. If
|
||||
// it's an ActionFunc or a func with the legacy signature for Action, the func
|
||||
// is run!
|
||||
func HandleAction(action interface{}, context *Context) (err error) {
|
||||
func HandleAction(action interface{}, cCtx *Context) (err error) {
|
||||
switch a := action.(type) {
|
||||
case ActionFunc:
|
||||
return a(context)
|
||||
return a(cCtx)
|
||||
case func(*Context) error:
|
||||
return a(context)
|
||||
return a(cCtx)
|
||||
case func(*Context): // deprecated function signature
|
||||
a(context)
|
||||
a(cCtx)
|
||||
return nil
|
||||
}
|
||||
|
||||
return errInvalidActionType
|
||||
}
|
||||
|
||||
func checkStringSliceIncludes(want string, sSlice []string) bool {
|
||||
found := false
|
||||
for _, s := range sSlice {
|
||||
if want == s {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return found
|
||||
}
|
||||
|
|
96
vendor/github.com/urfave/cli/v2/category.go
generated
vendored
96
vendor/github.com/urfave/cli/v2/category.go
generated
vendored
|
@ -1,10 +1,12 @@
|
|||
package cli
|
||||
|
||||
import "sort"
|
||||
|
||||
// CommandCategories interface allows for category manipulation
|
||||
type CommandCategories interface {
|
||||
// AddCommand adds a command to a category, creating a new category if necessary.
|
||||
AddCommand(category string, command *Command)
|
||||
// categories returns a copy of the category slice
|
||||
// Categories returns a slice of categories sorted by name
|
||||
Categories() []CommandCategory
|
||||
}
|
||||
|
||||
|
@ -77,3 +79,95 @@ func (c *commandCategory) VisibleCommands() []*Command {
|
|||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
// FlagCategories interface allows for category manipulation
|
||||
type FlagCategories interface {
|
||||
// AddFlags adds a flag to a category, creating a new category if necessary.
|
||||
AddFlag(category string, fl Flag)
|
||||
// VisibleCategories returns a slice of visible flag categories sorted by name
|
||||
VisibleCategories() []VisibleFlagCategory
|
||||
}
|
||||
|
||||
type defaultFlagCategories struct {
|
||||
m map[string]*defaultVisibleFlagCategory
|
||||
}
|
||||
|
||||
func newFlagCategories() FlagCategories {
|
||||
return &defaultFlagCategories{
|
||||
m: map[string]*defaultVisibleFlagCategory{},
|
||||
}
|
||||
}
|
||||
|
||||
func newFlagCategoriesFromFlags(fs []Flag) FlagCategories {
|
||||
fc := newFlagCategories()
|
||||
for _, fl := range fs {
|
||||
if cf, ok := fl.(CategorizableFlag); ok {
|
||||
if cf.GetCategory() != "" {
|
||||
fc.AddFlag(cf.GetCategory(), cf)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return fc
|
||||
}
|
||||
|
||||
func (f *defaultFlagCategories) AddFlag(category string, fl Flag) {
|
||||
if _, ok := f.m[category]; !ok {
|
||||
f.m[category] = &defaultVisibleFlagCategory{name: category, m: map[string]Flag{}}
|
||||
}
|
||||
|
||||
f.m[category].m[fl.String()] = fl
|
||||
}
|
||||
|
||||
func (f *defaultFlagCategories) VisibleCategories() []VisibleFlagCategory {
|
||||
catNames := []string{}
|
||||
for name := range f.m {
|
||||
catNames = append(catNames, name)
|
||||
}
|
||||
|
||||
sort.Strings(catNames)
|
||||
|
||||
ret := make([]VisibleFlagCategory, len(catNames))
|
||||
for i, name := range catNames {
|
||||
ret[i] = f.m[name]
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
// VisibleFlagCategory is a category containing flags.
|
||||
type VisibleFlagCategory interface {
|
||||
// Name returns the category name string
|
||||
Name() string
|
||||
// Flags returns a slice of VisibleFlag sorted by name
|
||||
Flags() []VisibleFlag
|
||||
}
|
||||
|
||||
type defaultVisibleFlagCategory struct {
|
||||
name string
|
||||
m map[string]Flag
|
||||
}
|
||||
|
||||
func (fc *defaultVisibleFlagCategory) Name() string {
|
||||
return fc.name
|
||||
}
|
||||
|
||||
func (fc *defaultVisibleFlagCategory) Flags() []VisibleFlag {
|
||||
vfNames := []string{}
|
||||
for flName, fl := range fc.m {
|
||||
if vf, ok := fl.(VisibleFlag); ok {
|
||||
if vf.IsVisible() {
|
||||
vfNames = append(vfNames, flName)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sort.Strings(vfNames)
|
||||
|
||||
ret := make([]VisibleFlag, len(vfNames))
|
||||
for i, flName := range vfNames {
|
||||
ret[i] = fc.m[flName].(VisibleFlag)
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
|
32
vendor/github.com/urfave/cli/v2/cli.go
generated
vendored
32
vendor/github.com/urfave/cli/v2/cli.go
generated
vendored
|
@ -1,23 +1,25 @@
|
|||
// Package cli provides a minimal framework for creating and organizing command line
|
||||
// Go applications. cli is designed to be easy to understand and write, the most simple
|
||||
// cli application can be written as follows:
|
||||
// func main() {
|
||||
// (&cli.App{}).Run(os.Args)
|
||||
// }
|
||||
//
|
||||
// func main() {
|
||||
// (&cli.App{}).Run(os.Args)
|
||||
// }
|
||||
//
|
||||
// Of course this application does not do much, so let's make this an actual application:
|
||||
// func main() {
|
||||
// app := &cli.App{
|
||||
// Name: "greet",
|
||||
// Usage: "say a greeting",
|
||||
// Action: func(c *cli.Context) error {
|
||||
// fmt.Println("Greetings")
|
||||
// return nil
|
||||
// },
|
||||
// }
|
||||
//
|
||||
// app.Run(os.Args)
|
||||
// }
|
||||
// func main() {
|
||||
// app := &cli.App{
|
||||
// Name: "greet",
|
||||
// Usage: "say a greeting",
|
||||
// Action: func(c *cli.Context) error {
|
||||
// fmt.Println("Greetings")
|
||||
// return nil
|
||||
// },
|
||||
// }
|
||||
//
|
||||
// app.Run(os.Args)
|
||||
// }
|
||||
package cli
|
||||
|
||||
//go:generate go run flag-gen/main.go flag-gen/assets_vfsdata.go
|
||||
//go:generate go run cmd/urfave-cli-genflags/main.go
|
||||
|
|
80
vendor/github.com/urfave/cli/v2/command.go
generated
vendored
80
vendor/github.com/urfave/cli/v2/command.go
generated
vendored
|
@ -38,7 +38,8 @@ type Command struct {
|
|||
// List of child commands
|
||||
Subcommands []*Command
|
||||
// List of flags to parse
|
||||
Flags []Flag
|
||||
Flags []Flag
|
||||
flagCategories FlagCategories
|
||||
// Treat all flags as normal arguments if true
|
||||
SkipFlagParsing bool
|
||||
// Boolean to hide built-in help command and help flag
|
||||
|
@ -105,39 +106,48 @@ func (c *Command) Run(ctx *Context) (err error) {
|
|||
|
||||
set, err := c.parseFlags(ctx.Args(), ctx.shellComplete)
|
||||
|
||||
context := NewContext(ctx.App, set, ctx)
|
||||
context.Command = c
|
||||
if checkCommandCompletions(context, c.Name) {
|
||||
cCtx := NewContext(ctx.App, set, ctx)
|
||||
cCtx.Command = c
|
||||
if checkCommandCompletions(cCtx, c.Name) {
|
||||
return nil
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
if c.OnUsageError != nil {
|
||||
err = c.OnUsageError(context, err, false)
|
||||
context.App.handleExitCoder(context, err)
|
||||
err = c.OnUsageError(cCtx, err, false)
|
||||
cCtx.App.handleExitCoder(cCtx, err)
|
||||
return err
|
||||
}
|
||||
_, _ = fmt.Fprintln(context.App.Writer, "Incorrect Usage:", err.Error())
|
||||
_, _ = fmt.Fprintln(context.App.Writer)
|
||||
_ = ShowCommandHelp(context, c.Name)
|
||||
_, _ = fmt.Fprintln(cCtx.App.Writer, "Incorrect Usage:", err.Error())
|
||||
_, _ = fmt.Fprintln(cCtx.App.Writer)
|
||||
if ctx.App.Suggest {
|
||||
if suggestion, err := ctx.App.suggestFlagFromError(err, c.Name); err == nil {
|
||||
fmt.Fprintf(cCtx.App.Writer, suggestion)
|
||||
}
|
||||
}
|
||||
if !c.HideHelp {
|
||||
_ = ShowCommandHelp(cCtx, c.Name)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
if checkCommandHelp(context, c.Name) {
|
||||
if checkCommandHelp(cCtx, c.Name) {
|
||||
return nil
|
||||
}
|
||||
|
||||
cerr := checkRequiredFlags(c.Flags, context)
|
||||
cerr := cCtx.checkRequiredFlags(c.Flags)
|
||||
if cerr != nil {
|
||||
_ = ShowCommandHelp(context, c.Name)
|
||||
if !c.HideHelp {
|
||||
_ = ShowCommandHelp(cCtx, c.Name)
|
||||
}
|
||||
return cerr
|
||||
}
|
||||
|
||||
if c.After != nil {
|
||||
defer func() {
|
||||
afterErr := c.After(context)
|
||||
afterErr := c.After(cCtx)
|
||||
if afterErr != nil {
|
||||
context.App.handleExitCoder(context, err)
|
||||
cCtx.App.handleExitCoder(cCtx, err)
|
||||
if err != nil {
|
||||
err = newMultiError(err, afterErr)
|
||||
} else {
|
||||
|
@ -148,22 +158,26 @@ func (c *Command) Run(ctx *Context) (err error) {
|
|||
}
|
||||
|
||||
if c.Before != nil {
|
||||
err = c.Before(context)
|
||||
err = c.Before(cCtx)
|
||||
if err != nil {
|
||||
context.App.handleExitCoder(context, err)
|
||||
cCtx.App.handleExitCoder(cCtx, err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if c.Action == nil {
|
||||
c.Action = helpSubcommand.Action
|
||||
if err = runFlagActions(cCtx, c.Flags); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
context.Command = c
|
||||
err = c.Action(context)
|
||||
if c.Action == nil {
|
||||
c.Action = helpCommand.Action
|
||||
}
|
||||
|
||||
cCtx.Command = c
|
||||
err = c.Action(cCtx)
|
||||
|
||||
if err != nil {
|
||||
context.App.handleExitCoder(context, err)
|
||||
cCtx.App.handleExitCoder(cCtx, err)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
@ -227,6 +241,7 @@ func (c *Command) startApp(ctx *Context) error {
|
|||
}
|
||||
|
||||
app.Usage = c.Usage
|
||||
app.UsageText = c.UsageText
|
||||
app.Description = c.Description
|
||||
app.ArgsUsage = c.ArgsUsage
|
||||
|
||||
|
@ -243,10 +258,12 @@ func (c *Command) startApp(ctx *Context) error {
|
|||
app.Version = ctx.App.Version
|
||||
app.HideVersion = true
|
||||
app.Compiled = ctx.App.Compiled
|
||||
app.Reader = ctx.App.Reader
|
||||
app.Writer = ctx.App.Writer
|
||||
app.ErrWriter = ctx.App.ErrWriter
|
||||
app.ExitErrHandler = ctx.App.ExitErrHandler
|
||||
app.UseShortOptionHandling = ctx.App.UseShortOptionHandling
|
||||
app.Suggest = ctx.App.Suggest
|
||||
|
||||
app.categories = newCommandCategories()
|
||||
for _, command := range c.Subcommands {
|
||||
|
@ -267,7 +284,7 @@ func (c *Command) startApp(ctx *Context) error {
|
|||
if c.Action != nil {
|
||||
app.Action = c.Action
|
||||
} else {
|
||||
app.Action = helpSubcommand.Action
|
||||
app.Action = helpCommand.Action
|
||||
}
|
||||
app.OnUsageError = c.OnUsageError
|
||||
|
||||
|
@ -278,6 +295,25 @@ func (c *Command) startApp(ctx *Context) error {
|
|||
return app.RunAsSubcommand(ctx)
|
||||
}
|
||||
|
||||
// VisibleCommands returns a slice of the Commands with Hidden=false
|
||||
func (c *Command) VisibleCommands() []*Command {
|
||||
var ret []*Command
|
||||
for _, command := range c.Subcommands {
|
||||
if !command.Hidden {
|
||||
ret = append(ret, command)
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
// VisibleFlagCategories returns a slice containing all the visible flag categories with the flags they contain
|
||||
func (c *Command) VisibleFlagCategories() []VisibleFlagCategory {
|
||||
if c.flagCategories == nil {
|
||||
c.flagCategories = newFlagCategoriesFromFlags(c.Flags)
|
||||
}
|
||||
return c.flagCategories.VisibleCategories()
|
||||
}
|
||||
|
||||
// VisibleFlags returns a slice of the Flags with Hidden=false
|
||||
func (c *Command) VisibleFlags() []Flag {
|
||||
return visibleFlags(c.Flags)
|
||||
|
|
205
vendor/github.com/urfave/cli/v2/context.go
generated
vendored
205
vendor/github.com/urfave/cli/v2/context.go
generated
vendored
|
@ -2,7 +2,6 @@ package cli
|
|||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"flag"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
@ -42,31 +41,33 @@ func NewContext(app *App, set *flag.FlagSet, parentCtx *Context) *Context {
|
|||
}
|
||||
|
||||
// NumFlags returns the number of flags set
|
||||
func (c *Context) NumFlags() int {
|
||||
return c.flagSet.NFlag()
|
||||
func (cCtx *Context) NumFlags() int {
|
||||
return cCtx.flagSet.NFlag()
|
||||
}
|
||||
|
||||
// Set sets a context flag to a value.
|
||||
func (c *Context) Set(name, value string) error {
|
||||
return c.flagSet.Set(name, value)
|
||||
func (cCtx *Context) Set(name, value string) error {
|
||||
if fs := cCtx.lookupFlagSet(name); fs != nil {
|
||||
return fs.Set(name, value)
|
||||
}
|
||||
|
||||
return fmt.Errorf("no such flag -%s", name)
|
||||
}
|
||||
|
||||
// IsSet determines if the flag was actually set
|
||||
func (c *Context) IsSet(name string) bool {
|
||||
if fs := lookupFlagSet(name, c); fs != nil {
|
||||
if fs := lookupFlagSet(name, c); fs != nil {
|
||||
isSet := false
|
||||
fs.Visit(func(f *flag.Flag) {
|
||||
if f.Name == name {
|
||||
isSet = true
|
||||
}
|
||||
})
|
||||
if isSet {
|
||||
return true
|
||||
func (cCtx *Context) IsSet(name string) bool {
|
||||
if fs := cCtx.lookupFlagSet(name); fs != nil {
|
||||
isSet := false
|
||||
fs.Visit(func(f *flag.Flag) {
|
||||
if f.Name == name {
|
||||
isSet = true
|
||||
}
|
||||
})
|
||||
if isSet {
|
||||
return true
|
||||
}
|
||||
|
||||
f := lookupFlag(name, c)
|
||||
f := cCtx.lookupFlag(name)
|
||||
if f == nil {
|
||||
return false
|
||||
}
|
||||
|
@ -78,52 +79,65 @@ func (c *Context) IsSet(name string) bool {
|
|||
}
|
||||
|
||||
// LocalFlagNames returns a slice of flag names used in this context.
|
||||
func (c *Context) LocalFlagNames() []string {
|
||||
func (cCtx *Context) LocalFlagNames() []string {
|
||||
var names []string
|
||||
c.flagSet.Visit(makeFlagNameVisitor(&names))
|
||||
cCtx.flagSet.Visit(makeFlagNameVisitor(&names))
|
||||
return names
|
||||
}
|
||||
|
||||
// FlagNames returns a slice of flag names used by the this context and all of
|
||||
// its parent contexts.
|
||||
func (c *Context) FlagNames() []string {
|
||||
func (cCtx *Context) FlagNames() []string {
|
||||
var names []string
|
||||
for _, ctx := range c.Lineage() {
|
||||
ctx.flagSet.Visit(makeFlagNameVisitor(&names))
|
||||
for _, pCtx := range cCtx.Lineage() {
|
||||
pCtx.flagSet.Visit(makeFlagNameVisitor(&names))
|
||||
}
|
||||
return names
|
||||
}
|
||||
|
||||
// Lineage returns *this* context and all of its ancestor contexts in order from
|
||||
// child to parent
|
||||
func (c *Context) Lineage() []*Context {
|
||||
func (cCtx *Context) Lineage() []*Context {
|
||||
var lineage []*Context
|
||||
|
||||
for cur := c; cur != nil; cur = cur.parentContext {
|
||||
for cur := cCtx; cur != nil; cur = cur.parentContext {
|
||||
lineage = append(lineage, cur)
|
||||
}
|
||||
|
||||
return lineage
|
||||
}
|
||||
|
||||
// Count returns the num of occurences of this flag
|
||||
func (cCtx *Context) Count(name string) int {
|
||||
if fs := cCtx.lookupFlagSet(name); fs != nil {
|
||||
if cf, ok := fs.Lookup(name).Value.(Countable); ok {
|
||||
return cf.Count()
|
||||
}
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// Value returns the value of the flag corresponding to `name`
|
||||
func (c *Context) Value(name string) interface{} {
|
||||
return c.flagSet.Lookup(name).Value.(flag.Getter).Get()
|
||||
func (cCtx *Context) Value(name string) interface{} {
|
||||
if fs := cCtx.lookupFlagSet(name); fs != nil {
|
||||
return fs.Lookup(name).Value.(flag.Getter).Get()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Args returns the command line arguments associated with the context.
|
||||
func (c *Context) Args() Args {
|
||||
ret := args(c.flagSet.Args())
|
||||
func (cCtx *Context) Args() Args {
|
||||
ret := args(cCtx.flagSet.Args())
|
||||
return &ret
|
||||
}
|
||||
|
||||
// NArg returns the number of the command line arguments.
|
||||
func (c *Context) NArg() int {
|
||||
return c.Args().Len()
|
||||
func (cCtx *Context) NArg() int {
|
||||
return cCtx.Args().Len()
|
||||
}
|
||||
|
||||
func lookupFlag(name string, ctx *Context) Flag {
|
||||
for _, c := range ctx.Lineage() {
|
||||
func (cCtx *Context) lookupFlag(name string) Flag {
|
||||
for _, c := range cCtx.Lineage() {
|
||||
if c.Command == nil {
|
||||
continue
|
||||
}
|
||||
|
@ -137,8 +151,8 @@ func lookupFlag(name string, ctx *Context) Flag {
|
|||
}
|
||||
}
|
||||
|
||||
if ctx.App != nil {
|
||||
for _, f := range ctx.App.Flags {
|
||||
if cCtx.App != nil {
|
||||
for _, f := range cCtx.App.Flags {
|
||||
for _, n := range f.Names() {
|
||||
if n == name {
|
||||
return f
|
||||
|
@ -150,58 +164,57 @@ func lookupFlag(name string, ctx *Context) Flag {
|
|||
return nil
|
||||
}
|
||||
|
||||
func lookupFlagSet(name string, ctx *Context) *flag.FlagSet {
|
||||
for _, c := range ctx.Lineage() {
|
||||
func (cCtx *Context) lookupFlagSet(name string) *flag.FlagSet {
|
||||
for _, c := range cCtx.Lineage() {
|
||||
if c.flagSet == nil {
|
||||
continue
|
||||
}
|
||||
if f := c.flagSet.Lookup(name); f != nil {
|
||||
return c.flagSet
|
||||
}
|
||||
}
|
||||
|
||||
cCtx.onInvalidFlag(name)
|
||||
return nil
|
||||
}
|
||||
|
||||
func copyFlag(name string, ff *flag.Flag, set *flag.FlagSet) {
|
||||
switch ff.Value.(type) {
|
||||
case Serializer:
|
||||
_ = set.Set(name, ff.Value.(Serializer).Serialize())
|
||||
default:
|
||||
_ = set.Set(name, ff.Value.String())
|
||||
}
|
||||
}
|
||||
|
||||
func normalizeFlags(flags []Flag, set *flag.FlagSet) error {
|
||||
visited := make(map[string]bool)
|
||||
set.Visit(func(f *flag.Flag) {
|
||||
visited[f.Name] = true
|
||||
})
|
||||
func (cCtx *Context) checkRequiredFlags(flags []Flag) requiredFlagsErr {
|
||||
var missingFlags []string
|
||||
for _, f := range flags {
|
||||
parts := f.Names()
|
||||
if len(parts) == 1 {
|
||||
continue
|
||||
}
|
||||
var ff *flag.Flag
|
||||
for _, name := range parts {
|
||||
name = strings.Trim(name, " ")
|
||||
if visited[name] {
|
||||
if ff != nil {
|
||||
return errors.New("Cannot use two forms of the same flag: " + name + " " + ff.Name)
|
||||
if rf, ok := f.(RequiredFlag); ok && rf.IsRequired() {
|
||||
var flagPresent bool
|
||||
var flagName string
|
||||
|
||||
for _, key := range f.Names() {
|
||||
flagName = key
|
||||
|
||||
if cCtx.IsSet(strings.TrimSpace(key)) {
|
||||
flagPresent = true
|
||||
}
|
||||
ff = set.Lookup(name)
|
||||
}
|
||||
}
|
||||
if ff == nil {
|
||||
continue
|
||||
}
|
||||
for _, name := range parts {
|
||||
name = strings.Trim(name, " ")
|
||||
if !visited[name] {
|
||||
copyFlag(name, ff, set)
|
||||
|
||||
if !flagPresent && flagName != "" {
|
||||
missingFlags = append(missingFlags, flagName)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(missingFlags) != 0 {
|
||||
return &errRequiredFlags{missingFlags: missingFlags}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cCtx *Context) onInvalidFlag(name string) {
|
||||
for cCtx != nil {
|
||||
if cCtx.App != nil && cCtx.App.InvalidFlagAccessHandler != nil {
|
||||
cCtx.App.InvalidFlagAccessHandler(cCtx, name)
|
||||
break
|
||||
}
|
||||
cCtx = cCtx.parentContext
|
||||
}
|
||||
}
|
||||
|
||||
func makeFlagNameVisitor(names *[]string) func(*flag.Flag) {
|
||||
return func(f *flag.Flag) {
|
||||
nameParts := strings.Split(f.Name, ",")
|
||||
|
@ -219,55 +232,3 @@ func makeFlagNameVisitor(names *[]string) func(*flag.Flag) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
type requiredFlagsErr interface {
|
||||
error
|
||||
getMissingFlags() []string
|
||||
}
|
||||
|
||||
type errRequiredFlags struct {
|
||||
missingFlags []string
|
||||
}
|
||||
|
||||
func (e *errRequiredFlags) Error() string {
|
||||
numberOfMissingFlags := len(e.missingFlags)
|
||||
if numberOfMissingFlags == 1 {
|
||||
return fmt.Sprintf("Required flag %q not set", e.missingFlags[0])
|
||||
}
|
||||
joinedMissingFlags := strings.Join(e.missingFlags, ", ")
|
||||
return fmt.Sprintf("Required flags %q not set", joinedMissingFlags)
|
||||
}
|
||||
|
||||
func (e *errRequiredFlags) getMissingFlags() []string {
|
||||
return e.missingFlags
|
||||
}
|
||||
|
||||
func checkRequiredFlags(flags []Flag, context *Context) requiredFlagsErr {
|
||||
var missingFlags []string
|
||||
for _, f := range flags {
|
||||
if rf, ok := f.(RequiredFlag); ok && rf.IsRequired() {
|
||||
var flagPresent bool
|
||||
var flagName string
|
||||
|
||||
for _, key := range f.Names() {
|
||||
if len(key) > 1 {
|
||||
flagName = key
|
||||
}
|
||||
|
||||
if context.IsSet(strings.TrimSpace(key)) {
|
||||
flagPresent = true
|
||||
}
|
||||
}
|
||||
|
||||
if !flagPresent && flagName != "" {
|
||||
missingFlags = append(missingFlags, flagName)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(missingFlags) != 0 {
|
||||
return &errRequiredFlags{missingFlags: missingFlags}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
74
vendor/github.com/urfave/cli/v2/docs.go
generated
vendored
74
vendor/github.com/urfave/cli/v2/docs.go
generated
vendored
|
@ -1,3 +1,6 @@
|
|||
//go:build !urfave_cli_no_docs
|
||||
// +build !urfave_cli_no_docs
|
||||
|
||||
package cli
|
||||
|
||||
import (
|
||||
|
@ -15,31 +18,39 @@ 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); err != nil {
|
||||
if err := a.writeDocTemplate(&w, 0); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return w.String(), nil
|
||||
}
|
||||
|
||||
// ToMan creates a man page string for the `*App`
|
||||
// ToMan creates a man page string with section number for the `*App`
|
||||
// The function errors if either parsing or writing of the string fails.
|
||||
func (a *App) ToMan() (string, error) {
|
||||
func (a *App) ToManWithSection(sectionNumber int) (string, error) {
|
||||
var w bytes.Buffer
|
||||
if err := a.writeDocTemplate(&w); err != nil {
|
||||
if err := a.writeDocTemplate(&w, sectionNumber); err != nil {
|
||||
return "", err
|
||||
}
|
||||
man := md2man.Render(w.Bytes())
|
||||
return string(man), nil
|
||||
}
|
||||
|
||||
// ToMan creates a man page string for the `*App`
|
||||
// The function errors if either parsing or writing of the string fails.
|
||||
func (a *App) ToMan() (string, error) {
|
||||
man, err := a.ToManWithSection(8)
|
||||
return man, err
|
||||
}
|
||||
|
||||
type cliTemplate struct {
|
||||
App *App
|
||||
SectionNum int
|
||||
Commands []string
|
||||
GlobalArgs []string
|
||||
SynopsisArgs []string
|
||||
}
|
||||
|
||||
func (a *App) writeDocTemplate(w io.Writer) error {
|
||||
func (a *App) writeDocTemplate(w io.Writer, sectionNum int) error {
|
||||
const name = "cli"
|
||||
t, err := template.New(name).Parse(MarkdownDocTemplate)
|
||||
if err != nil {
|
||||
|
@ -47,6 +58,7 @@ func (a *App) writeDocTemplate(w io.Writer) error {
|
|||
}
|
||||
return t.ExecuteTemplate(w, name, &cliTemplate{
|
||||
App: a,
|
||||
SectionNum: sectionNum,
|
||||
Commands: prepareCommands(a.Commands, 0),
|
||||
GlobalArgs: prepareArgsWithValues(a.VisibleFlags()),
|
||||
SynopsisArgs: prepareArgsSynopsis(a.VisibleFlags()),
|
||||
|
@ -59,25 +71,26 @@ 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)
|
||||
flags := prepareArgsWithValues(command.VisibleFlags())
|
||||
if len(flags) > 0 {
|
||||
prepared += fmt.Sprintf("\n%s", strings.Join(flags, "\n"))
|
||||
}
|
||||
|
||||
coms = append(coms, prepared)
|
||||
|
||||
// recursevly iterate subcommands
|
||||
// recursively iterate subcommands
|
||||
if len(command.Subcommands) > 0 {
|
||||
coms = append(
|
||||
coms,
|
||||
|
@ -146,3 +159,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
|
||||
}
|
||||
|
|
22
vendor/github.com/urfave/cli/v2/errors.go
generated
vendored
22
vendor/github.com/urfave/cli/v2/errors.go
generated
vendored
|
@ -47,6 +47,28 @@ func (m *multiError) Errors() []error {
|
|||
return errs
|
||||
}
|
||||
|
||||
type requiredFlagsErr interface {
|
||||
error
|
||||
getMissingFlags() []string
|
||||
}
|
||||
|
||||
type errRequiredFlags struct {
|
||||
missingFlags []string
|
||||
}
|
||||
|
||||
func (e *errRequiredFlags) Error() string {
|
||||
numberOfMissingFlags := len(e.missingFlags)
|
||||
if numberOfMissingFlags == 1 {
|
||||
return fmt.Sprintf("Required flag %q not set", e.missingFlags[0])
|
||||
}
|
||||
joinedMissingFlags := strings.Join(e.missingFlags, ", ")
|
||||
return fmt.Sprintf("Required flags %q not set", joinedMissingFlags)
|
||||
}
|
||||
|
||||
func (e *errRequiredFlags) getMissingFlags() []string {
|
||||
return e.missingFlags
|
||||
}
|
||||
|
||||
// ErrorFormatter is the interface that will suitably format the error output
|
||||
type ErrorFormatter interface {
|
||||
Format(s fmt.State, verb rune)
|
||||
|
|
2
vendor/github.com/urfave/cli/v2/fish.go
generated
vendored
2
vendor/github.com/urfave/cli/v2/fish.go
generated
vendored
|
@ -95,7 +95,7 @@ func (a *App) prepareFishCommands(commands []*Command, allCommands *[]string, pr
|
|||
completions = append(completions, completion.String())
|
||||
completions = append(
|
||||
completions,
|
||||
a.prepareFishFlags(command.Flags, command.Names())...,
|
||||
a.prepareFishFlags(command.VisibleFlags(), command.Names())...,
|
||||
)
|
||||
|
||||
// recursevly iterate subcommands
|
||||
|
|
115
vendor/github.com/urfave/cli/v2/flag-spec.yaml
generated
vendored
Normal file
115
vendor/github.com/urfave/cli/v2/flag-spec.yaml
generated
vendored
Normal file
|
@ -0,0 +1,115 @@
|
|||
# NOTE: this file is used by the tool defined in
|
||||
# ./cmd/urfave-cli-genflags/main.go which uses the
|
||||
# `Spec` type that maps to this file structure.
|
||||
flag_types:
|
||||
bool:
|
||||
struct_fields:
|
||||
- name: Count
|
||||
type: int
|
||||
pointer: true
|
||||
- name: Action
|
||||
type: "func(*Context, bool) error"
|
||||
float64:
|
||||
struct_fields:
|
||||
- name: Action
|
||||
type: "func(*Context, float64) error"
|
||||
Float64Slice:
|
||||
value_pointer: true
|
||||
skip_interfaces:
|
||||
- fmt.Stringer
|
||||
struct_fields:
|
||||
- name: Action
|
||||
type: "func(*Context, []float64) error"
|
||||
int:
|
||||
struct_fields:
|
||||
- name: Base
|
||||
type: int
|
||||
- name: Action
|
||||
type: "func(*Context, int) error"
|
||||
IntSlice:
|
||||
value_pointer: true
|
||||
skip_interfaces:
|
||||
- fmt.Stringer
|
||||
struct_fields:
|
||||
- name: Action
|
||||
type: "func(*Context, []int) error"
|
||||
int64:
|
||||
struct_fields:
|
||||
- name: Base
|
||||
type: int
|
||||
- name: Action
|
||||
type: "func(*Context, int64) error"
|
||||
Int64Slice:
|
||||
value_pointer: true
|
||||
skip_interfaces:
|
||||
- fmt.Stringer
|
||||
struct_fields:
|
||||
- name: Action
|
||||
type: "func(*Context, []int64) error"
|
||||
uint:
|
||||
struct_fields:
|
||||
- name: Base
|
||||
type: int
|
||||
- name: Action
|
||||
type: "func(*Context, uint) error"
|
||||
UintSlice:
|
||||
value_pointer: true
|
||||
skip_interfaces:
|
||||
- fmt.Stringer
|
||||
struct_fields:
|
||||
- name: Action
|
||||
type: "func(*Context, []uint) error"
|
||||
uint64:
|
||||
struct_fields:
|
||||
- name: Base
|
||||
type: int
|
||||
- name: Action
|
||||
type: "func(*Context, uint64) error"
|
||||
Uint64Slice:
|
||||
value_pointer: true
|
||||
skip_interfaces:
|
||||
- fmt.Stringer
|
||||
struct_fields:
|
||||
- name: Action
|
||||
type: "func(*Context, []uint64) error"
|
||||
string:
|
||||
struct_fields:
|
||||
- name: TakesFile
|
||||
type: bool
|
||||
- name: Action
|
||||
type: "func(*Context, string) error"
|
||||
StringSlice:
|
||||
value_pointer: true
|
||||
skip_interfaces:
|
||||
- fmt.Stringer
|
||||
struct_fields:
|
||||
- name: TakesFile
|
||||
type: bool
|
||||
- name: Action
|
||||
type: "func(*Context, []string) error"
|
||||
time.Duration:
|
||||
struct_fields:
|
||||
- name: Action
|
||||
type: "func(*Context, time.Duration) error"
|
||||
Timestamp:
|
||||
value_pointer: true
|
||||
struct_fields:
|
||||
- name: Layout
|
||||
type: string
|
||||
- name: Timezone
|
||||
type: "*time.Location"
|
||||
- name: Action
|
||||
type: "func(*Context, *time.Time) error"
|
||||
Generic:
|
||||
no_destination_pointer: true
|
||||
struct_fields:
|
||||
- name: TakesFile
|
||||
type: bool
|
||||
- name: Action
|
||||
type: "func(*Context, interface{}) error"
|
||||
Path:
|
||||
struct_fields:
|
||||
- name: TakesFile
|
||||
type: bool
|
||||
- name: Action
|
||||
type: "func(*Context, Path) error"
|
251
vendor/github.com/urfave/cli/v2/flag.go
generated
vendored
251
vendor/github.com/urfave/cli/v2/flag.go
generated
vendored
|
@ -1,13 +1,12 @@
|
|||
package cli
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
|
@ -84,6 +83,12 @@ func (f FlagsByName) Swap(i, j int) {
|
|||
f[i], f[j] = f[j], f[i]
|
||||
}
|
||||
|
||||
// ActionableFlag is an interface that wraps Flag interface and RunAction operation.
|
||||
type ActionableFlag interface {
|
||||
Flag
|
||||
RunAction(*Context) error
|
||||
}
|
||||
|
||||
// Flag is a common interface related to parsing flags in cli.
|
||||
// For more advanced flag parsing techniques, it is recommended that
|
||||
// this interface be implemented.
|
||||
|
@ -116,6 +121,42 @@ type DocGenerationFlag interface {
|
|||
// GetValue returns the flags value as string representation and an empty
|
||||
// string if the flag takes no value at all.
|
||||
GetValue() string
|
||||
|
||||
// GetDefaultText returns the default text for this flag
|
||||
GetDefaultText() string
|
||||
|
||||
// GetEnvVars returns the env vars for this flag
|
||||
GetEnvVars() []string
|
||||
}
|
||||
|
||||
// DocGenerationSliceFlag extends DocGenerationFlag for slice-based flags.
|
||||
type DocGenerationSliceFlag interface {
|
||||
DocGenerationFlag
|
||||
|
||||
// IsSliceFlag returns true for flags that can be given multiple times.
|
||||
IsSliceFlag() bool
|
||||
}
|
||||
|
||||
// VisibleFlag is an interface that allows to check if a flag is visible
|
||||
type VisibleFlag interface {
|
||||
Flag
|
||||
|
||||
// IsVisible returns true if the flag is not hidden, otherwise false
|
||||
IsVisible() bool
|
||||
}
|
||||
|
||||
// CategorizableFlag is an interface that allows us to potentially
|
||||
// use a flag in a categorized representation.
|
||||
type CategorizableFlag interface {
|
||||
VisibleFlag
|
||||
|
||||
GetCategory() string
|
||||
}
|
||||
|
||||
// Countable is an interface to enable detection of flag values which support
|
||||
// repetitive flags
|
||||
type Countable interface {
|
||||
Count() int
|
||||
}
|
||||
|
||||
func flagSet(name string, flags []Flag) (*flag.FlagSet, error) {
|
||||
|
@ -130,11 +171,52 @@ func flagSet(name string, flags []Flag) (*flag.FlagSet, error) {
|
|||
return set, nil
|
||||
}
|
||||
|
||||
func copyFlag(name string, ff *flag.Flag, set *flag.FlagSet) {
|
||||
switch ff.Value.(type) {
|
||||
case Serializer:
|
||||
_ = set.Set(name, ff.Value.(Serializer).Serialize())
|
||||
default:
|
||||
_ = set.Set(name, ff.Value.String())
|
||||
}
|
||||
}
|
||||
|
||||
func normalizeFlags(flags []Flag, set *flag.FlagSet) error {
|
||||
visited := make(map[string]bool)
|
||||
set.Visit(func(f *flag.Flag) {
|
||||
visited[f.Name] = true
|
||||
})
|
||||
for _, f := range flags {
|
||||
parts := f.Names()
|
||||
if len(parts) == 1 {
|
||||
continue
|
||||
}
|
||||
var ff *flag.Flag
|
||||
for _, name := range parts {
|
||||
name = strings.Trim(name, " ")
|
||||
if visited[name] {
|
||||
if ff != nil {
|
||||
return errors.New("Cannot use two forms of the same flag: " + name + " " + ff.Name)
|
||||
}
|
||||
ff = set.Lookup(name)
|
||||
}
|
||||
}
|
||||
if ff == nil {
|
||||
continue
|
||||
}
|
||||
for _, name := range parts {
|
||||
name = strings.Trim(name, " ")
|
||||
if !visited[name] {
|
||||
copyFlag(name, ff, set)
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func visibleFlags(fl []Flag) []Flag {
|
||||
var visible []Flag
|
||||
for _, f := range fl {
|
||||
field := flagValue(f).FieldByName("Hidden")
|
||||
if !field.IsValid() || !field.Bool() {
|
||||
if vf, ok := f.(VisibleFlag); ok && vf.IsVisible() {
|
||||
visible = append(visible, f)
|
||||
}
|
||||
}
|
||||
|
@ -188,7 +270,7 @@ func prefixedNames(names []string, placeholder string) string {
|
|||
|
||||
func withEnvHint(envVars []string, str string) string {
|
||||
envText := ""
|
||||
if envVars != nil && len(envVars) > 0 {
|
||||
if len(envVars) > 0 {
|
||||
prefix := "$"
|
||||
suffix := ""
|
||||
sep := ", $"
|
||||
|
@ -203,7 +285,7 @@ func withEnvHint(envVars []string, str string) string {
|
|||
return str + envText
|
||||
}
|
||||
|
||||
func flagNames(name string, aliases []string) []string {
|
||||
func FlagNames(name string, aliases []string) []string {
|
||||
var ret []string
|
||||
|
||||
for _, part := range append([]string{name}, aliases...) {
|
||||
|
@ -217,17 +299,6 @@ func flagNames(name string, aliases []string) []string {
|
|||
return ret
|
||||
}
|
||||
|
||||
func flagStringSliceField(f Flag, name string) []string {
|
||||
fv := flagValue(f)
|
||||
field := fv.FieldByName(name)
|
||||
|
||||
if field.IsValid() {
|
||||
return field.Interface().([]string)
|
||||
}
|
||||
|
||||
return []string{}
|
||||
}
|
||||
|
||||
func withFileHint(filePath, str string) string {
|
||||
fileText := ""
|
||||
if filePath != "" {
|
||||
|
@ -236,130 +307,39 @@ func withFileHint(filePath, str string) string {
|
|||
return str + fileText
|
||||
}
|
||||
|
||||
func flagValue(f Flag) reflect.Value {
|
||||
fv := reflect.ValueOf(f)
|
||||
for fv.Kind() == reflect.Ptr {
|
||||
fv = reflect.Indirect(fv)
|
||||
}
|
||||
return fv
|
||||
}
|
||||
|
||||
func formatDefault(format string) string {
|
||||
return " (default: " + format + ")"
|
||||
}
|
||||
|
||||
func stringifyFlag(f Flag) string {
|
||||
fv := flagValue(f)
|
||||
|
||||
switch f := f.(type) {
|
||||
case *IntSliceFlag:
|
||||
return withEnvHint(flagStringSliceField(f, "EnvVars"),
|
||||
stringifyIntSliceFlag(f))
|
||||
case *Int64SliceFlag:
|
||||
return withEnvHint(flagStringSliceField(f, "EnvVars"),
|
||||
stringifyInt64SliceFlag(f))
|
||||
case *Float64SliceFlag:
|
||||
return withEnvHint(flagStringSliceField(f, "EnvVars"),
|
||||
stringifyFloat64SliceFlag(f))
|
||||
case *StringSliceFlag:
|
||||
return withEnvHint(flagStringSliceField(f, "EnvVars"),
|
||||
stringifyStringSliceFlag(f))
|
||||
// enforce DocGeneration interface on flags to avoid reflection
|
||||
df, ok := f.(DocGenerationFlag)
|
||||
if !ok {
|
||||
return ""
|
||||
}
|
||||
|
||||
placeholder, usage := unquoteUsage(fv.FieldByName("Usage").String())
|
||||
|
||||
needsPlaceholder := false
|
||||
defaultValueString := ""
|
||||
val := fv.FieldByName("Value")
|
||||
if val.IsValid() {
|
||||
needsPlaceholder = val.Kind() != reflect.Bool
|
||||
defaultValueString = fmt.Sprintf(formatDefault("%v"), val.Interface())
|
||||
|
||||
if val.Kind() == reflect.String && val.String() != "" {
|
||||
defaultValueString = fmt.Sprintf(formatDefault("%q"), val.String())
|
||||
}
|
||||
}
|
||||
|
||||
helpText := fv.FieldByName("DefaultText")
|
||||
if helpText.IsValid() && helpText.String() != "" {
|
||||
needsPlaceholder = val.Kind() != reflect.Bool
|
||||
defaultValueString = fmt.Sprintf(formatDefault("%s"), helpText.String())
|
||||
}
|
||||
|
||||
if defaultValueString == formatDefault("") {
|
||||
defaultValueString = ""
|
||||
}
|
||||
placeholder, usage := unquoteUsage(df.GetUsage())
|
||||
needsPlaceholder := df.TakesValue()
|
||||
|
||||
if needsPlaceholder && placeholder == "" {
|
||||
placeholder = defaultPlaceholder
|
||||
}
|
||||
|
||||
defaultValueString := ""
|
||||
|
||||
if s := df.GetDefaultText(); s != "" {
|
||||
defaultValueString = fmt.Sprintf(formatDefault("%s"), s)
|
||||
}
|
||||
|
||||
usageWithDefault := strings.TrimSpace(usage + defaultValueString)
|
||||
|
||||
return withEnvHint(flagStringSliceField(f, "EnvVars"),
|
||||
fmt.Sprintf("%s\t%s", prefixedNames(f.Names(), placeholder), usageWithDefault))
|
||||
}
|
||||
|
||||
func stringifyIntSliceFlag(f *IntSliceFlag) string {
|
||||
var defaultVals []string
|
||||
if f.Value != nil && len(f.Value.Value()) > 0 {
|
||||
for _, i := range f.Value.Value() {
|
||||
defaultVals = append(defaultVals, strconv.Itoa(i))
|
||||
}
|
||||
pn := prefixedNames(df.Names(), placeholder)
|
||||
sliceFlag, ok := f.(DocGenerationSliceFlag)
|
||||
if ok && sliceFlag.IsSliceFlag() {
|
||||
pn = pn + " [ " + pn + " ]"
|
||||
}
|
||||
|
||||
return stringifySliceFlag(f.Usage, f.Names(), defaultVals)
|
||||
}
|
||||
|
||||
func stringifyInt64SliceFlag(f *Int64SliceFlag) string {
|
||||
var defaultVals []string
|
||||
if f.Value != nil && len(f.Value.Value()) > 0 {
|
||||
for _, i := range f.Value.Value() {
|
||||
defaultVals = append(defaultVals, strconv.FormatInt(i, 10))
|
||||
}
|
||||
}
|
||||
|
||||
return stringifySliceFlag(f.Usage, f.Names(), defaultVals)
|
||||
}
|
||||
|
||||
func stringifyFloat64SliceFlag(f *Float64SliceFlag) string {
|
||||
var defaultVals []string
|
||||
|
||||
if f.Value != nil && len(f.Value.Value()) > 0 {
|
||||
for _, i := range f.Value.Value() {
|
||||
defaultVals = append(defaultVals, strings.TrimRight(strings.TrimRight(fmt.Sprintf("%f", i), "0"), "."))
|
||||
}
|
||||
}
|
||||
|
||||
return stringifySliceFlag(f.Usage, f.Names(), defaultVals)
|
||||
}
|
||||
|
||||
func stringifyStringSliceFlag(f *StringSliceFlag) string {
|
||||
var defaultVals []string
|
||||
if f.Value != nil && len(f.Value.Value()) > 0 {
|
||||
for _, s := range f.Value.Value() {
|
||||
if len(s) > 0 {
|
||||
defaultVals = append(defaultVals, strconv.Quote(s))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return stringifySliceFlag(f.Usage, f.Names(), defaultVals)
|
||||
}
|
||||
|
||||
func stringifySliceFlag(usage string, names, defaultVals []string) string {
|
||||
placeholder, usage := unquoteUsage(usage)
|
||||
if placeholder == "" {
|
||||
placeholder = defaultPlaceholder
|
||||
}
|
||||
|
||||
defaultVal := ""
|
||||
if len(defaultVals) > 0 {
|
||||
defaultVal = fmt.Sprintf(formatDefault("%s"), strings.Join(defaultVals, ", "))
|
||||
}
|
||||
|
||||
usageWithDefault := strings.TrimSpace(fmt.Sprintf("%s%s", usage, defaultVal))
|
||||
return fmt.Sprintf("%s\t%s", prefixedNames(names, placeholder), usageWithDefault)
|
||||
return withEnvHint(df.GetEnvVars(), fmt.Sprintf("%s\t%s", pn, usageWithDefault))
|
||||
}
|
||||
|
||||
func hasFlag(flags []Flag, fl Flag) bool {
|
||||
|
@ -372,17 +352,26 @@ func hasFlag(flags []Flag, fl Flag) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
func flagFromEnvOrFile(envVars []string, filePath string) (val string, ok bool) {
|
||||
// Return the first value from a list of environment variables and files
|
||||
// (which may or may not exist), a description of where the value was found,
|
||||
// and a boolean which is true if a value was found.
|
||||
func flagFromEnvOrFile(envVars []string, filePath string) (value string, fromWhere string, found bool) {
|
||||
for _, envVar := range envVars {
|
||||
envVar = strings.TrimSpace(envVar)
|
||||
if val, ok := syscall.Getenv(envVar); ok {
|
||||
return val, true
|
||||
if value, found := syscall.Getenv(envVar); found {
|
||||
return value, fmt.Sprintf("environment variable %q", envVar), true
|
||||
}
|
||||
}
|
||||
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), fmt.Sprintf("file %q", filePath), true
|
||||
}
|
||||
}
|
||||
}
|
||||
return "", false
|
||||
return "", "", false
|
||||
}
|
||||
|
||||
func flagSplitMultiValues(val string) []string {
|
||||
return strings.Split(val, ",")
|
||||
}
|
||||
|
|
154
vendor/github.com/urfave/cli/v2/flag_bool.go
generated
vendored
154
vendor/github.com/urfave/cli/v2/flag_bool.go
generated
vendored
|
@ -1,45 +1,61 @@
|
|||
package cli
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"flag"
|
||||
"fmt"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// BoolFlag is a flag with type bool
|
||||
type BoolFlag struct {
|
||||
Name string
|
||||
Aliases []string
|
||||
Usage string
|
||||
EnvVars []string
|
||||
FilePath string
|
||||
Required bool
|
||||
Hidden bool
|
||||
Value bool
|
||||
DefaultText string
|
||||
Destination *bool
|
||||
HasBeenSet bool
|
||||
// boolValue needs to implement the boolFlag internal interface in flag
|
||||
// to be able to capture bool fields and values
|
||||
//
|
||||
// type boolFlag interface {
|
||||
// Value
|
||||
// IsBoolFlag() bool
|
||||
// }
|
||||
type boolValue struct {
|
||||
destination *bool
|
||||
count *int
|
||||
}
|
||||
|
||||
// IsSet returns whether or not the flag has been set through env or file
|
||||
func (f *BoolFlag) IsSet() bool {
|
||||
return f.HasBeenSet
|
||||
func newBoolValue(val bool, p *bool, count *int) *boolValue {
|
||||
*p = val
|
||||
return &boolValue{
|
||||
destination: p,
|
||||
count: count,
|
||||
}
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value
|
||||
// (for usage defaults)
|
||||
func (f *BoolFlag) String() string {
|
||||
return FlagStringer(f)
|
||||
func (b *boolValue) Set(s string) error {
|
||||
v, err := strconv.ParseBool(s)
|
||||
if err != nil {
|
||||
err = errors.New("parse error")
|
||||
return err
|
||||
}
|
||||
*b.destination = v
|
||||
if b.count != nil {
|
||||
*b.count = *b.count + 1
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// Names returns the names of the flag
|
||||
func (f *BoolFlag) Names() []string {
|
||||
return flagNames(f.Name, f.Aliases)
|
||||
func (b *boolValue) Get() interface{} { return *b.destination }
|
||||
|
||||
func (b *boolValue) String() string {
|
||||
if b.destination != nil {
|
||||
return strconv.FormatBool(*b.destination)
|
||||
}
|
||||
return strconv.FormatBool(false)
|
||||
}
|
||||
|
||||
// IsRequired returns whether or not the flag is required
|
||||
func (f *BoolFlag) IsRequired() bool {
|
||||
return f.Required
|
||||
func (b *boolValue) IsBoolFlag() bool { return true }
|
||||
|
||||
func (b *boolValue) Count() int {
|
||||
if b.count != nil {
|
||||
return *b.count
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// TakesValue returns true of the flag takes a value, otherwise false
|
||||
|
@ -52,42 +68,86 @@ func (f *BoolFlag) GetUsage() string {
|
|||
return f.Usage
|
||||
}
|
||||
|
||||
// GetCategory returns the category for the flag
|
||||
func (f *BoolFlag) GetCategory() string {
|
||||
return f.Category
|
||||
}
|
||||
|
||||
// GetValue returns the flags value as string representation and an empty
|
||||
// string if the flag takes no value at all.
|
||||
func (f *BoolFlag) GetValue() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
// Apply populates the flag given the flag set and environment
|
||||
func (f *BoolFlag) Apply(set *flag.FlagSet) error {
|
||||
if val, ok := flagFromEnvOrFile(f.EnvVars, f.FilePath); ok {
|
||||
if val != "" {
|
||||
valBool, err := strconv.ParseBool(val)
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not parse %q as bool value for flag %s: %s", val, f.Name, err)
|
||||
}
|
||||
|
||||
f.Value = valBool
|
||||
f.HasBeenSet = true
|
||||
}
|
||||
// GetDefaultText returns the default text for this flag
|
||||
func (f *BoolFlag) GetDefaultText() string {
|
||||
if f.DefaultText != "" {
|
||||
return f.DefaultText
|
||||
}
|
||||
return fmt.Sprintf("%v", f.Value)
|
||||
}
|
||||
|
||||
for _, name := range f.Names() {
|
||||
if f.Destination != nil {
|
||||
set.BoolVar(f.Destination, name, f.Value, f.Usage)
|
||||
continue
|
||||
}
|
||||
set.Bool(name, f.Value, f.Usage)
|
||||
// GetEnvVars returns the env vars for this flag
|
||||
func (f *BoolFlag) GetEnvVars() []string {
|
||||
return f.EnvVars
|
||||
}
|
||||
|
||||
// RunAction executes flag action if set
|
||||
func (f *BoolFlag) RunAction(c *Context) error {
|
||||
if f.Action != nil {
|
||||
return f.Action(c, c.Bool(f.Name))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Apply populates the flag given the flag set and environment
|
||||
func (f *BoolFlag) Apply(set *flag.FlagSet) error {
|
||||
if val, source, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found {
|
||||
if val != "" {
|
||||
valBool, err := strconv.ParseBool(val)
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not parse %q as bool value from %s for flag %s: %s", val, source, f.Name, err)
|
||||
}
|
||||
|
||||
f.Value = valBool
|
||||
} else {
|
||||
// empty value implies that the env is defined but set to empty string, we have to assume that this is
|
||||
// what the user wants. If user doesnt want this then the env needs to be deleted or the flag removed from
|
||||
// file
|
||||
f.Value = false
|
||||
}
|
||||
f.HasBeenSet = true
|
||||
}
|
||||
|
||||
count := f.Count
|
||||
dest := f.Destination
|
||||
|
||||
if count == nil {
|
||||
count = new(int)
|
||||
}
|
||||
if dest == nil {
|
||||
dest = new(bool)
|
||||
}
|
||||
|
||||
for _, name := range f.Names() {
|
||||
value := newBoolValue(f.Value, dest, count)
|
||||
set.Var(value, name, f.Usage)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Get returns the flag’s value in the given Context.
|
||||
func (f *BoolFlag) Get(ctx *Context) bool {
|
||||
return ctx.Bool(f.Name)
|
||||
}
|
||||
|
||||
// Bool looks up the value of a local BoolFlag, returns
|
||||
// false if not found
|
||||
func (c *Context) Bool(name string) bool {
|
||||
if fs := lookupFlagSet(name, c); fs != nil {
|
||||
func (cCtx *Context) Bool(name string) bool {
|
||||
if fs := cCtx.lookupFlagSet(name); fs != nil {
|
||||
return lookupBool(name, fs)
|
||||
}
|
||||
return false
|
||||
|
|
76
vendor/github.com/urfave/cli/v2/flag_duration.go
generated
vendored
76
vendor/github.com/urfave/cli/v2/flag_duration.go
generated
vendored
|
@ -6,42 +6,6 @@ import (
|
|||
"time"
|
||||
)
|
||||
|
||||
// DurationFlag is a flag with type time.Duration (see https://golang.org/pkg/time/#ParseDuration)
|
||||
type DurationFlag struct {
|
||||
Name string
|
||||
Aliases []string
|
||||
Usage string
|
||||
EnvVars []string
|
||||
FilePath string
|
||||
Required bool
|
||||
Hidden bool
|
||||
Value time.Duration
|
||||
DefaultText string
|
||||
Destination *time.Duration
|
||||
HasBeenSet bool
|
||||
}
|
||||
|
||||
// IsSet returns whether or not the flag has been set through env or file
|
||||
func (f *DurationFlag) IsSet() bool {
|
||||
return f.HasBeenSet
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value
|
||||
// (for usage defaults)
|
||||
func (f *DurationFlag) String() string {
|
||||
return FlagStringer(f)
|
||||
}
|
||||
|
||||
// Names returns the names of the flag
|
||||
func (f *DurationFlag) Names() []string {
|
||||
return flagNames(f.Name, f.Aliases)
|
||||
}
|
||||
|
||||
// IsRequired returns whether or not the flag is required
|
||||
func (f *DurationFlag) IsRequired() bool {
|
||||
return f.Required
|
||||
}
|
||||
|
||||
// TakesValue returns true of the flag takes a value, otherwise false
|
||||
func (f *DurationFlag) TakesValue() bool {
|
||||
return true
|
||||
|
@ -52,20 +16,38 @@ func (f *DurationFlag) GetUsage() string {
|
|||
return f.Usage
|
||||
}
|
||||
|
||||
// GetCategory returns the category for the flag
|
||||
func (f *DurationFlag) GetCategory() string {
|
||||
return f.Category
|
||||
}
|
||||
|
||||
// GetValue returns the flags value as string representation and an empty
|
||||
// string if the flag takes no value at all.
|
||||
func (f *DurationFlag) GetValue() string {
|
||||
return f.Value.String()
|
||||
}
|
||||
|
||||
// GetDefaultText returns the default text for this flag
|
||||
func (f *DurationFlag) GetDefaultText() string {
|
||||
if f.DefaultText != "" {
|
||||
return f.DefaultText
|
||||
}
|
||||
return f.GetValue()
|
||||
}
|
||||
|
||||
// GetEnvVars returns the env vars for this flag
|
||||
func (f *DurationFlag) GetEnvVars() []string {
|
||||
return f.EnvVars
|
||||
}
|
||||
|
||||
// Apply populates the flag given the flag set and environment
|
||||
func (f *DurationFlag) Apply(set *flag.FlagSet) error {
|
||||
if val, ok := flagFromEnvOrFile(f.EnvVars, f.FilePath); ok {
|
||||
if val, source, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found {
|
||||
if val != "" {
|
||||
valDuration, err := time.ParseDuration(val)
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not parse %q as duration value for flag %s: %s", val, f.Name, err)
|
||||
return fmt.Errorf("could not parse %q as duration value from %s for flag %s: %s", val, source, f.Name, err)
|
||||
}
|
||||
|
||||
f.Value = valDuration
|
||||
|
@ -83,10 +65,24 @@ func (f *DurationFlag) Apply(set *flag.FlagSet) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// Get returns the flag’s value in the given Context.
|
||||
func (f *DurationFlag) Get(ctx *Context) time.Duration {
|
||||
return ctx.Duration(f.Name)
|
||||
}
|
||||
|
||||
// RunAction executes flag action if set
|
||||
func (f *DurationFlag) RunAction(c *Context) error {
|
||||
if f.Action != nil {
|
||||
return f.Action(c, c.Duration(f.Name))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Duration looks up the value of a local DurationFlag, returns
|
||||
// 0 if not found
|
||||
func (c *Context) Duration(name string) time.Duration {
|
||||
if fs := lookupFlagSet(name, c); fs != nil {
|
||||
func (cCtx *Context) Duration(name string) time.Duration {
|
||||
if fs := cCtx.lookupFlagSet(name); fs != nil {
|
||||
return lookupDuration(name, fs)
|
||||
}
|
||||
return 0
|
||||
|
|
81
vendor/github.com/urfave/cli/v2/flag_float64.go
generated
vendored
81
vendor/github.com/urfave/cli/v2/flag_float64.go
generated
vendored
|
@ -6,42 +6,6 @@ import (
|
|||
"strconv"
|
||||
)
|
||||
|
||||
// Float64Flag is a flag with type float64
|
||||
type Float64Flag struct {
|
||||
Name string
|
||||
Aliases []string
|
||||
Usage string
|
||||
EnvVars []string
|
||||
FilePath string
|
||||
Required bool
|
||||
Hidden bool
|
||||
Value float64
|
||||
DefaultText string
|
||||
Destination *float64
|
||||
HasBeenSet bool
|
||||
}
|
||||
|
||||
// IsSet returns whether or not the flag has been set through env or file
|
||||
func (f *Float64Flag) IsSet() bool {
|
||||
return f.HasBeenSet
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value
|
||||
// (for usage defaults)
|
||||
func (f *Float64Flag) String() string {
|
||||
return FlagStringer(f)
|
||||
}
|
||||
|
||||
// Names returns the names of the flag
|
||||
func (f *Float64Flag) Names() []string {
|
||||
return flagNames(f.Name, f.Aliases)
|
||||
}
|
||||
|
||||
// IsRequired returns whether or not the flag is required
|
||||
func (f *Float64Flag) IsRequired() bool {
|
||||
return f.Required
|
||||
}
|
||||
|
||||
// TakesValue returns true of the flag takes a value, otherwise false
|
||||
func (f *Float64Flag) TakesValue() bool {
|
||||
return true
|
||||
|
@ -52,20 +16,37 @@ func (f *Float64Flag) GetUsage() string {
|
|||
return f.Usage
|
||||
}
|
||||
|
||||
// GetCategory returns the category for the flag
|
||||
func (f *Float64Flag) GetCategory() string {
|
||||
return f.Category
|
||||
}
|
||||
|
||||
// GetValue returns the flags value as string representation and an empty
|
||||
// string if the flag takes no value at all.
|
||||
func (f *Float64Flag) GetValue() string {
|
||||
return fmt.Sprintf("%f", f.Value)
|
||||
return fmt.Sprintf("%v", f.Value)
|
||||
}
|
||||
|
||||
// GetDefaultText returns the default text for this flag
|
||||
func (f *Float64Flag) GetDefaultText() string {
|
||||
if f.DefaultText != "" {
|
||||
return f.DefaultText
|
||||
}
|
||||
return f.GetValue()
|
||||
}
|
||||
|
||||
// GetEnvVars returns the env vars for this flag
|
||||
func (f *Float64Flag) GetEnvVars() []string {
|
||||
return f.EnvVars
|
||||
}
|
||||
|
||||
// Apply populates the flag given the flag set and environment
|
||||
func (f *Float64Flag) Apply(set *flag.FlagSet) error {
|
||||
if val, ok := flagFromEnvOrFile(f.EnvVars, f.FilePath); ok {
|
||||
if val, source, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found {
|
||||
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)
|
||||
return fmt.Errorf("could not parse %q as float64 value from %s for flag %s: %s", val, source, f.Name, err)
|
||||
}
|
||||
|
||||
f.Value = valFloat
|
||||
|
@ -84,10 +65,24 @@ func (f *Float64Flag) Apply(set *flag.FlagSet) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// Get returns the flag’s value in the given Context.
|
||||
func (f *Float64Flag) Get(ctx *Context) float64 {
|
||||
return ctx.Float64(f.Name)
|
||||
}
|
||||
|
||||
// RunAction executes flag action if set
|
||||
func (f *Float64Flag) RunAction(c *Context) error {
|
||||
if f.Action != nil {
|
||||
return f.Action(c, c.Float64(f.Name))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Float64 looks up the value of a local Float64Flag, returns
|
||||
// 0 if not found
|
||||
func (c *Context) Float64(name string) float64 {
|
||||
if fs := lookupFlagSet(name, c); fs != nil {
|
||||
func (cCtx *Context) Float64(name string) float64 {
|
||||
if fs := cCtx.lookupFlagSet(name); fs != nil {
|
||||
return lookupFloat64(name, fs)
|
||||
}
|
||||
return 0
|
||||
|
|
145
vendor/github.com/urfave/cli/v2/flag_float64_slice.go
generated
vendored
145
vendor/github.com/urfave/cli/v2/flag_float64_slice.go
generated
vendored
|
@ -19,6 +19,16 @@ func NewFloat64Slice(defaults ...float64) *Float64Slice {
|
|||
return &Float64Slice{slice: append([]float64{}, defaults...)}
|
||||
}
|
||||
|
||||
// clone allocate a copy of self object
|
||||
func (f *Float64Slice) clone() *Float64Slice {
|
||||
n := &Float64Slice{
|
||||
slice: make([]float64, len(f.slice)),
|
||||
hasBeenSet: f.hasBeenSet,
|
||||
}
|
||||
copy(n.slice, f.slice)
|
||||
return n
|
||||
}
|
||||
|
||||
// Set parses the value into a float64 and appends it to the list of values
|
||||
func (f *Float64Slice) Set(value string) error {
|
||||
if !f.hasBeenSet {
|
||||
|
@ -33,18 +43,25 @@ func (f *Float64Slice) Set(value string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
tmp, err := strconv.ParseFloat(value, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, s := range flagSplitMultiValues(value) {
|
||||
tmp, err := strconv.ParseFloat(strings.TrimSpace(s), 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
f.slice = append(f.slice, tmp)
|
||||
f.slice = append(f.slice, tmp)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value (for usage defaults)
|
||||
func (f *Float64Slice) String() string {
|
||||
return fmt.Sprintf("%#v", f.slice)
|
||||
v := f.slice
|
||||
if v == nil {
|
||||
// treat nil the same as zero length non-nil
|
||||
v = make([]float64, 0)
|
||||
}
|
||||
return fmt.Sprintf("%#v", v)
|
||||
}
|
||||
|
||||
// Serialize allows Float64Slice to fulfill Serializer
|
||||
|
@ -63,41 +80,12 @@ func (f *Float64Slice) Get() interface{} {
|
|||
return *f
|
||||
}
|
||||
|
||||
// Float64SliceFlag is a flag with type *Float64Slice
|
||||
type Float64SliceFlag struct {
|
||||
Name string
|
||||
Aliases []string
|
||||
Usage string
|
||||
EnvVars []string
|
||||
FilePath string
|
||||
Required bool
|
||||
Hidden bool
|
||||
Value *Float64Slice
|
||||
DefaultText string
|
||||
HasBeenSet bool
|
||||
}
|
||||
|
||||
// IsSet returns whether or not the flag has been set through env or file
|
||||
func (f *Float64SliceFlag) IsSet() bool {
|
||||
return f.HasBeenSet
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value
|
||||
// (for usage defaults)
|
||||
func (f *Float64SliceFlag) String() string {
|
||||
return FlagStringer(f)
|
||||
}
|
||||
|
||||
// Names returns the names of the flag
|
||||
func (f *Float64SliceFlag) Names() []string {
|
||||
return flagNames(f.Name, f.Aliases)
|
||||
}
|
||||
|
||||
// IsRequired returns whether or not the flag is required
|
||||
func (f *Float64SliceFlag) IsRequired() bool {
|
||||
return f.Required
|
||||
}
|
||||
|
||||
// TakesValue returns true if the flag takes a value, otherwise false
|
||||
func (f *Float64SliceFlag) TakesValue() bool {
|
||||
return true
|
||||
|
@ -108,36 +96,91 @@ func (f *Float64SliceFlag) GetUsage() string {
|
|||
return f.Usage
|
||||
}
|
||||
|
||||
// GetCategory returns the category for the flag
|
||||
func (f *Float64SliceFlag) GetCategory() string {
|
||||
return f.Category
|
||||
}
|
||||
|
||||
// GetValue returns the flags value as string representation and an empty
|
||||
// string if the flag takes no value at all.
|
||||
func (f *Float64SliceFlag) GetValue() string {
|
||||
if f.Value != nil {
|
||||
return f.Value.String()
|
||||
var defaultVals []string
|
||||
if f.Value != nil && len(f.Value.Value()) > 0 {
|
||||
for _, i := range f.Value.Value() {
|
||||
defaultVals = append(defaultVals, strings.TrimRight(strings.TrimRight(fmt.Sprintf("%f", i), "0"), "."))
|
||||
}
|
||||
}
|
||||
return ""
|
||||
return strings.Join(defaultVals, ", ")
|
||||
}
|
||||
|
||||
// GetDefaultText returns the default text for this flag
|
||||
func (f *Float64SliceFlag) GetDefaultText() string {
|
||||
if f.DefaultText != "" {
|
||||
return f.DefaultText
|
||||
}
|
||||
return f.GetValue()
|
||||
}
|
||||
|
||||
// GetEnvVars returns the env vars for this flag
|
||||
func (f *Float64SliceFlag) GetEnvVars() []string {
|
||||
return f.EnvVars
|
||||
}
|
||||
|
||||
// IsSliceFlag implements DocGenerationSliceFlag.
|
||||
func (f *Float64SliceFlag) IsSliceFlag() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// Apply populates the flag given the flag set and environment
|
||||
func (f *Float64SliceFlag) Apply(set *flag.FlagSet) error {
|
||||
if val, ok := flagFromEnvOrFile(f.EnvVars, f.FilePath); ok {
|
||||
if val != "" {
|
||||
f.Value = &Float64Slice{}
|
||||
// apply any default
|
||||
if f.Destination != nil && f.Value != nil {
|
||||
f.Destination.slice = make([]float64, len(f.Value.slice))
|
||||
copy(f.Destination.slice, f.Value.slice)
|
||||
}
|
||||
|
||||
for _, s := range strings.Split(val, ",") {
|
||||
if err := f.Value.Set(strings.TrimSpace(s)); err != nil {
|
||||
return fmt.Errorf("could not parse %q as float64 slice value for flag %s: %s", f.Value, f.Name, err)
|
||||
// resolve setValue (what we will assign to the set)
|
||||
var setValue *Float64Slice
|
||||
switch {
|
||||
case f.Destination != nil:
|
||||
setValue = f.Destination
|
||||
case f.Value != nil:
|
||||
setValue = f.Value.clone()
|
||||
default:
|
||||
setValue = new(Float64Slice)
|
||||
}
|
||||
|
||||
if val, source, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found {
|
||||
if val != "" {
|
||||
for _, s := range flagSplitMultiValues(val) {
|
||||
if err := setValue.Set(strings.TrimSpace(s)); err != nil {
|
||||
return fmt.Errorf("could not parse %q as float64 slice value from %s for flag %s: %s", val, source, f.Name, err)
|
||||
}
|
||||
}
|
||||
|
||||
// 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.
|
||||
setValue.hasBeenSet = false
|
||||
f.HasBeenSet = true
|
||||
}
|
||||
}
|
||||
|
||||
for _, name := range f.Names() {
|
||||
if f.Value == nil {
|
||||
f.Value = &Float64Slice{}
|
||||
}
|
||||
set.Var(f.Value, name, f.Usage)
|
||||
set.Var(setValue, name, f.Usage)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Get returns the flag’s value in the given Context.
|
||||
func (f *Float64SliceFlag) Get(ctx *Context) []float64 {
|
||||
return ctx.Float64Slice(f.Name)
|
||||
}
|
||||
|
||||
// RunAction executes flag action if set
|
||||
func (f *Float64SliceFlag) RunAction(c *Context) error {
|
||||
if f.Action != nil {
|
||||
return f.Action(c, c.Float64Slice(f.Name))
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -145,8 +188,8 @@ func (f *Float64SliceFlag) Apply(set *flag.FlagSet) error {
|
|||
|
||||
// Float64Slice looks up the value of a local Float64SliceFlag, returns
|
||||
// nil if not found
|
||||
func (c *Context) Float64Slice(name string) []float64 {
|
||||
if fs := lookupFlagSet(name, c); fs != nil {
|
||||
func (cCtx *Context) Float64Slice(name string) []float64 {
|
||||
if fs := cCtx.lookupFlagSet(name); fs != nil {
|
||||
return lookupFloat64Slice(name, fs)
|
||||
}
|
||||
return nil
|
||||
|
@ -155,7 +198,7 @@ func (c *Context) Float64Slice(name string) []float64 {
|
|||
func lookupFloat64Slice(name string, set *flag.FlagSet) []float64 {
|
||||
f := set.Lookup(name)
|
||||
if f != nil {
|
||||
if slice, ok := f.Value.(*Float64Slice); ok {
|
||||
if slice, ok := unwrapFlagValue(f.Value).(*Float64Slice); ok {
|
||||
return slice.Value()
|
||||
}
|
||||
}
|
||||
|
|
82
vendor/github.com/urfave/cli/v2/flag_generic.go
generated
vendored
82
vendor/github.com/urfave/cli/v2/flag_generic.go
generated
vendored
|
@ -11,42 +11,6 @@ type Generic interface {
|
|||
String() string
|
||||
}
|
||||
|
||||
// GenericFlag is a flag with type Generic
|
||||
type GenericFlag struct {
|
||||
Name string
|
||||
Aliases []string
|
||||
Usage string
|
||||
EnvVars []string
|
||||
FilePath string
|
||||
Required bool
|
||||
Hidden bool
|
||||
TakesFile bool
|
||||
Value Generic
|
||||
DefaultText string
|
||||
HasBeenSet bool
|
||||
}
|
||||
|
||||
// IsSet returns whether or not the flag has been set through env or file
|
||||
func (f *GenericFlag) IsSet() bool {
|
||||
return f.HasBeenSet
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value
|
||||
// (for usage defaults)
|
||||
func (f *GenericFlag) String() string {
|
||||
return FlagStringer(f)
|
||||
}
|
||||
|
||||
// Names returns the names of the flag
|
||||
func (f *GenericFlag) Names() []string {
|
||||
return flagNames(f.Name, f.Aliases)
|
||||
}
|
||||
|
||||
// IsRequired returns whether or not the flag is required
|
||||
func (f *GenericFlag) IsRequired() bool {
|
||||
return f.Required
|
||||
}
|
||||
|
||||
// TakesValue returns true of the flag takes a value, otherwise false
|
||||
func (f *GenericFlag) TakesValue() bool {
|
||||
return true
|
||||
|
@ -57,6 +21,11 @@ func (f *GenericFlag) GetUsage() string {
|
|||
return f.Usage
|
||||
}
|
||||
|
||||
// GetCategory returns the category for the flag
|
||||
func (f *GenericFlag) GetCategory() string {
|
||||
return f.Category
|
||||
}
|
||||
|
||||
// GetValue returns the flags value as string representation and an empty
|
||||
// string if the flag takes no value at all.
|
||||
func (f *GenericFlag) GetValue() string {
|
||||
|
@ -66,13 +35,26 @@ func (f *GenericFlag) GetValue() string {
|
|||
return ""
|
||||
}
|
||||
|
||||
// GetDefaultText returns the default text for this flag
|
||||
func (f *GenericFlag) GetDefaultText() string {
|
||||
if f.DefaultText != "" {
|
||||
return f.DefaultText
|
||||
}
|
||||
return f.GetValue()
|
||||
}
|
||||
|
||||
// GetEnvVars returns the env vars for this flag
|
||||
func (f *GenericFlag) GetEnvVars() []string {
|
||||
return f.EnvVars
|
||||
}
|
||||
|
||||
// Apply takes the flagset and calls Set on the generic flag with the value
|
||||
// provided by the user for parsing by the flag
|
||||
func (f GenericFlag) Apply(set *flag.FlagSet) error {
|
||||
if val, ok := flagFromEnvOrFile(f.EnvVars, f.FilePath); ok {
|
||||
func (f *GenericFlag) Apply(set *flag.FlagSet) error {
|
||||
if val, source, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found {
|
||||
if val != "" {
|
||||
if err := f.Value.Set(val); err != nil {
|
||||
return fmt.Errorf("could not parse %q as value for flag %s: %s", val, f.Name, err)
|
||||
return fmt.Errorf("could not parse %q from %s as value for flag %s: %s", val, source, f.Name, err)
|
||||
}
|
||||
|
||||
f.HasBeenSet = true
|
||||
|
@ -80,16 +62,34 @@ func (f GenericFlag) Apply(set *flag.FlagSet) error {
|
|||
}
|
||||
|
||||
for _, name := range f.Names() {
|
||||
if f.Destination != nil {
|
||||
set.Var(f.Destination, name, f.Usage)
|
||||
continue
|
||||
}
|
||||
set.Var(f.Value, name, f.Usage)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Get returns the flag’s value in the given Context.
|
||||
func (f *GenericFlag) Get(ctx *Context) interface{} {
|
||||
return ctx.Generic(f.Name)
|
||||
}
|
||||
|
||||
// RunAction executes flag action if set
|
||||
func (f *GenericFlag) RunAction(c *Context) error {
|
||||
if f.Action != nil {
|
||||
return f.Action(c, c.Generic(f.Name))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Generic looks up the value of a local GenericFlag, returns
|
||||
// nil if not found
|
||||
func (c *Context) Generic(name string) interface{} {
|
||||
if fs := lookupFlagSet(name, c); fs != nil {
|
||||
func (cCtx *Context) Generic(name string) interface{} {
|
||||
if fs := cCtx.lookupFlagSet(name); fs != nil {
|
||||
return lookupGeneric(name, fs)
|
||||
}
|
||||
return nil
|
||||
|
|
78
vendor/github.com/urfave/cli/v2/flag_int.go
generated
vendored
78
vendor/github.com/urfave/cli/v2/flag_int.go
generated
vendored
|
@ -6,42 +6,6 @@ import (
|
|||
"strconv"
|
||||
)
|
||||
|
||||
// IntFlag is a flag with type int
|
||||
type IntFlag struct {
|
||||
Name string
|
||||
Aliases []string
|
||||
Usage string
|
||||
EnvVars []string
|
||||
FilePath string
|
||||
Required bool
|
||||
Hidden bool
|
||||
Value int
|
||||
DefaultText string
|
||||
Destination *int
|
||||
HasBeenSet bool
|
||||
}
|
||||
|
||||
// IsSet returns whether or not the flag has been set through env or file
|
||||
func (f *IntFlag) IsSet() bool {
|
||||
return f.HasBeenSet
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value
|
||||
// (for usage defaults)
|
||||
func (f *IntFlag) String() string {
|
||||
return FlagStringer(f)
|
||||
}
|
||||
|
||||
// Names returns the names of the flag
|
||||
func (f *IntFlag) Names() []string {
|
||||
return flagNames(f.Name, f.Aliases)
|
||||
}
|
||||
|
||||
// IsRequired returns whether or not the flag is required
|
||||
func (f *IntFlag) IsRequired() bool {
|
||||
return f.Required
|
||||
}
|
||||
|
||||
// TakesValue returns true of the flag takes a value, otherwise false
|
||||
func (f *IntFlag) TakesValue() bool {
|
||||
return true
|
||||
|
@ -52,20 +16,38 @@ func (f *IntFlag) GetUsage() string {
|
|||
return f.Usage
|
||||
}
|
||||
|
||||
// GetCategory returns the category for the flag
|
||||
func (f *IntFlag) GetCategory() string {
|
||||
return f.Category
|
||||
}
|
||||
|
||||
// GetValue returns the flags value as string representation and an empty
|
||||
// string if the flag takes no value at all.
|
||||
func (f *IntFlag) GetValue() string {
|
||||
return fmt.Sprintf("%d", f.Value)
|
||||
}
|
||||
|
||||
// GetDefaultText returns the default text for this flag
|
||||
func (f *IntFlag) GetDefaultText() string {
|
||||
if f.DefaultText != "" {
|
||||
return f.DefaultText
|
||||
}
|
||||
return f.GetValue()
|
||||
}
|
||||
|
||||
// GetEnvVars returns the env vars for this flag
|
||||
func (f *IntFlag) GetEnvVars() []string {
|
||||
return f.EnvVars
|
||||
}
|
||||
|
||||
// Apply populates the flag given the flag set and environment
|
||||
func (f *IntFlag) Apply(set *flag.FlagSet) error {
|
||||
if val, ok := flagFromEnvOrFile(f.EnvVars, f.FilePath); ok {
|
||||
if val, source, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found {
|
||||
if val != "" {
|
||||
valInt, err := strconv.ParseInt(val, 0, 64)
|
||||
valInt, err := strconv.ParseInt(val, f.Base, 64)
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not parse %q as int value for flag %s: %s", val, f.Name, err)
|
||||
return fmt.Errorf("could not parse %q as int value from %s for flag %s: %s", val, source, f.Name, err)
|
||||
}
|
||||
|
||||
f.Value = int(valInt)
|
||||
|
@ -84,10 +66,24 @@ func (f *IntFlag) Apply(set *flag.FlagSet) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// Get returns the flag’s value in the given Context.
|
||||
func (f *IntFlag) Get(ctx *Context) int {
|
||||
return ctx.Int(f.Name)
|
||||
}
|
||||
|
||||
// RunAction executes flag action if set
|
||||
func (f *IntFlag) RunAction(c *Context) error {
|
||||
if f.Action != nil {
|
||||
return f.Action(c, c.Int(f.Name))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Int looks up the value of a local IntFlag, returns
|
||||
// 0 if not found
|
||||
func (c *Context) Int(name string) int {
|
||||
if fs := lookupFlagSet(name, c); fs != nil {
|
||||
func (cCtx *Context) Int(name string) int {
|
||||
if fs := cCtx.lookupFlagSet(name); fs != nil {
|
||||
return lookupInt(name, fs)
|
||||
}
|
||||
return 0
|
||||
|
|
78
vendor/github.com/urfave/cli/v2/flag_int64.go
generated
vendored
78
vendor/github.com/urfave/cli/v2/flag_int64.go
generated
vendored
|
@ -6,42 +6,6 @@ import (
|
|||
"strconv"
|
||||
)
|
||||
|
||||
// Int64Flag is a flag with type int64
|
||||
type Int64Flag struct {
|
||||
Name string
|
||||
Aliases []string
|
||||
Usage string
|
||||
EnvVars []string
|
||||
FilePath string
|
||||
Required bool
|
||||
Hidden bool
|
||||
Value int64
|
||||
DefaultText string
|
||||
Destination *int64
|
||||
HasBeenSet bool
|
||||
}
|
||||
|
||||
// IsSet returns whether or not the flag has been set through env or file
|
||||
func (f *Int64Flag) IsSet() bool {
|
||||
return f.HasBeenSet
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value
|
||||
// (for usage defaults)
|
||||
func (f *Int64Flag) String() string {
|
||||
return FlagStringer(f)
|
||||
}
|
||||
|
||||
// Names returns the names of the flag
|
||||
func (f *Int64Flag) Names() []string {
|
||||
return flagNames(f.Name, f.Aliases)
|
||||
}
|
||||
|
||||
// IsRequired returns whether or not the flag is required
|
||||
func (f *Int64Flag) IsRequired() bool {
|
||||
return f.Required
|
||||
}
|
||||
|
||||
// TakesValue returns true of the flag takes a value, otherwise false
|
||||
func (f *Int64Flag) TakesValue() bool {
|
||||
return true
|
||||
|
@ -52,20 +16,38 @@ func (f *Int64Flag) GetUsage() string {
|
|||
return f.Usage
|
||||
}
|
||||
|
||||
// GetCategory returns the category for the flag
|
||||
func (f *Int64Flag) GetCategory() string {
|
||||
return f.Category
|
||||
}
|
||||
|
||||
// GetValue returns the flags value as string representation and an empty
|
||||
// string if the flag takes no value at all.
|
||||
func (f *Int64Flag) GetValue() string {
|
||||
return fmt.Sprintf("%d", f.Value)
|
||||
}
|
||||
|
||||
// GetDefaultText returns the default text for this flag
|
||||
func (f *Int64Flag) GetDefaultText() string {
|
||||
if f.DefaultText != "" {
|
||||
return f.DefaultText
|
||||
}
|
||||
return f.GetValue()
|
||||
}
|
||||
|
||||
// GetEnvVars returns the env vars for this flag
|
||||
func (f *Int64Flag) GetEnvVars() []string {
|
||||
return f.EnvVars
|
||||
}
|
||||
|
||||
// Apply populates the flag given the flag set and environment
|
||||
func (f *Int64Flag) Apply(set *flag.FlagSet) error {
|
||||
if val, ok := flagFromEnvOrFile(f.EnvVars, f.FilePath); ok {
|
||||
if val, source, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found {
|
||||
if val != "" {
|
||||
valInt, err := strconv.ParseInt(val, 0, 64)
|
||||
valInt, err := strconv.ParseInt(val, f.Base, 64)
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not parse %q as int value for flag %s: %s", val, f.Name, err)
|
||||
return fmt.Errorf("could not parse %q as int value from %s for flag %s: %s", val, source, f.Name, err)
|
||||
}
|
||||
|
||||
f.Value = valInt
|
||||
|
@ -83,10 +65,24 @@ func (f *Int64Flag) Apply(set *flag.FlagSet) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// Get returns the flag’s value in the given Context.
|
||||
func (f *Int64Flag) Get(ctx *Context) int64 {
|
||||
return ctx.Int64(f.Name)
|
||||
}
|
||||
|
||||
// RunAction executes flag action if set
|
||||
func (f *Int64Flag) RunAction(c *Context) error {
|
||||
if f.Action != nil {
|
||||
return f.Action(c, c.Int64(f.Name))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Int64 looks up the value of a local Int64Flag, returns
|
||||
// 0 if not found
|
||||
func (c *Context) Int64(name string) int64 {
|
||||
if fs := lookupFlagSet(name, c); fs != nil {
|
||||
func (cCtx *Context) Int64(name string) int64 {
|
||||
if fs := cCtx.lookupFlagSet(name); fs != nil {
|
||||
return lookupInt64(name, fs)
|
||||
}
|
||||
return 0
|
||||
|
|
148
vendor/github.com/urfave/cli/v2/flag_int64_slice.go
generated
vendored
148
vendor/github.com/urfave/cli/v2/flag_int64_slice.go
generated
vendored
|
@ -19,6 +19,16 @@ func NewInt64Slice(defaults ...int64) *Int64Slice {
|
|||
return &Int64Slice{slice: append([]int64{}, defaults...)}
|
||||
}
|
||||
|
||||
// clone allocate a copy of self object
|
||||
func (i *Int64Slice) clone() *Int64Slice {
|
||||
n := &Int64Slice{
|
||||
slice: make([]int64, len(i.slice)),
|
||||
hasBeenSet: i.hasBeenSet,
|
||||
}
|
||||
copy(n.slice, i.slice)
|
||||
return n
|
||||
}
|
||||
|
||||
// Set parses the value into an integer and appends it to the list of values
|
||||
func (i *Int64Slice) Set(value string) error {
|
||||
if !i.hasBeenSet {
|
||||
|
@ -33,19 +43,26 @@ func (i *Int64Slice) Set(value string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
tmp, err := strconv.ParseInt(value, 0, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, s := range flagSplitMultiValues(value) {
|
||||
tmp, err := strconv.ParseInt(strings.TrimSpace(s), 0, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
i.slice = append(i.slice, tmp)
|
||||
i.slice = append(i.slice, tmp)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value (for usage defaults)
|
||||
func (i *Int64Slice) String() string {
|
||||
return fmt.Sprintf("%#v", i.slice)
|
||||
v := i.slice
|
||||
if v == nil {
|
||||
// treat nil the same as zero length non-nil
|
||||
v = make([]int64, 0)
|
||||
}
|
||||
return fmt.Sprintf("%#v", v)
|
||||
}
|
||||
|
||||
// Serialize allows Int64Slice to fulfill Serializer
|
||||
|
@ -64,79 +81,105 @@ func (i *Int64Slice) Get() interface{} {
|
|||
return *i
|
||||
}
|
||||
|
||||
// Int64SliceFlag is a flag with type *Int64Slice
|
||||
type Int64SliceFlag struct {
|
||||
Name string
|
||||
Aliases []string
|
||||
Usage string
|
||||
EnvVars []string
|
||||
FilePath string
|
||||
Required bool
|
||||
Hidden bool
|
||||
Value *Int64Slice
|
||||
DefaultText string
|
||||
HasBeenSet bool
|
||||
}
|
||||
|
||||
// IsSet returns whether or not the flag has been set through env or file
|
||||
func (f *Int64SliceFlag) IsSet() bool {
|
||||
return f.HasBeenSet
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value
|
||||
// (for usage defaults)
|
||||
func (f *Int64SliceFlag) String() string {
|
||||
return FlagStringer(f)
|
||||
}
|
||||
|
||||
// Names returns the names of the flag
|
||||
func (f *Int64SliceFlag) Names() []string {
|
||||
return flagNames(f.Name, f.Aliases)
|
||||
}
|
||||
|
||||
// IsRequired returns whether or not the flag is required
|
||||
func (f *Int64SliceFlag) IsRequired() bool {
|
||||
return f.Required
|
||||
}
|
||||
|
||||
// TakesValue returns true of the flag takes a value, otherwise false
|
||||
func (f *Int64SliceFlag) TakesValue() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// GetUsage returns the usage string for the flag
|
||||
func (f Int64SliceFlag) GetUsage() string {
|
||||
func (f *Int64SliceFlag) GetUsage() string {
|
||||
return f.Usage
|
||||
}
|
||||
|
||||
// GetCategory returns the category for the flag
|
||||
func (f *Int64SliceFlag) GetCategory() string {
|
||||
return f.Category
|
||||
}
|
||||
|
||||
// GetValue returns the flags value as string representation and an empty
|
||||
// string if the flag takes no value at all.
|
||||
func (f *Int64SliceFlag) GetValue() string {
|
||||
if f.Value != nil {
|
||||
return f.Value.String()
|
||||
var defaultVals []string
|
||||
if f.Value != nil && len(f.Value.Value()) > 0 {
|
||||
for _, i := range f.Value.Value() {
|
||||
defaultVals = append(defaultVals, strconv.FormatInt(i, 10))
|
||||
}
|
||||
}
|
||||
return ""
|
||||
return strings.Join(defaultVals, ", ")
|
||||
}
|
||||
|
||||
// GetDefaultText returns the default text for this flag
|
||||
func (f *Int64SliceFlag) GetDefaultText() string {
|
||||
if f.DefaultText != "" {
|
||||
return f.DefaultText
|
||||
}
|
||||
return f.GetValue()
|
||||
}
|
||||
|
||||
// GetEnvVars returns the env vars for this flag
|
||||
func (f *Int64SliceFlag) GetEnvVars() []string {
|
||||
return f.EnvVars
|
||||
}
|
||||
|
||||
// IsSliceFlag implements DocGenerationSliceFlag.
|
||||
func (f *Int64SliceFlag) IsSliceFlag() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// Apply populates the flag given the flag set and environment
|
||||
func (f *Int64SliceFlag) Apply(set *flag.FlagSet) error {
|
||||
if val, ok := flagFromEnvOrFile(f.EnvVars, f.FilePath); ok {
|
||||
f.Value = &Int64Slice{}
|
||||
// apply any default
|
||||
if f.Destination != nil && f.Value != nil {
|
||||
f.Destination.slice = make([]int64, len(f.Value.slice))
|
||||
copy(f.Destination.slice, f.Value.slice)
|
||||
}
|
||||
|
||||
for _, s := range strings.Split(val, ",") {
|
||||
if err := f.Value.Set(strings.TrimSpace(s)); err != nil {
|
||||
return fmt.Errorf("could not parse %q as int64 slice value for flag %s: %s", val, f.Name, err)
|
||||
// resolve setValue (what we will assign to the set)
|
||||
var setValue *Int64Slice
|
||||
switch {
|
||||
case f.Destination != nil:
|
||||
setValue = f.Destination
|
||||
case f.Value != nil:
|
||||
setValue = f.Value.clone()
|
||||
default:
|
||||
setValue = new(Int64Slice)
|
||||
}
|
||||
|
||||
if val, source, ok := flagFromEnvOrFile(f.EnvVars, f.FilePath); ok && val != "" {
|
||||
for _, s := range flagSplitMultiValues(val) {
|
||||
if err := setValue.Set(strings.TrimSpace(s)); err != nil {
|
||||
return fmt.Errorf("could not parse %q as int64 slice value from %s for flag %s: %s", val, source, f.Name, err)
|
||||
}
|
||||
}
|
||||
|
||||
// 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.
|
||||
setValue.hasBeenSet = false
|
||||
f.HasBeenSet = true
|
||||
}
|
||||
|
||||
for _, name := range f.Names() {
|
||||
if f.Value == nil {
|
||||
f.Value = &Int64Slice{}
|
||||
}
|
||||
set.Var(f.Value, name, f.Usage)
|
||||
set.Var(setValue, name, f.Usage)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Get returns the flag’s value in the given Context.
|
||||
func (f *Int64SliceFlag) Get(ctx *Context) []int64 {
|
||||
return ctx.Int64Slice(f.Name)
|
||||
}
|
||||
|
||||
// RunAction executes flag action if set
|
||||
func (f *Int64SliceFlag) RunAction(c *Context) error {
|
||||
if f.Action != nil {
|
||||
return f.Action(c, c.Int64Slice(f.Name))
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -144,14 +187,17 @@ func (f *Int64SliceFlag) Apply(set *flag.FlagSet) error {
|
|||
|
||||
// Int64Slice looks up the value of a local Int64SliceFlag, returns
|
||||
// nil if not found
|
||||
func (c *Context) Int64Slice(name string) []int64 {
|
||||
return lookupInt64Slice(name, c.flagSet)
|
||||
func (cCtx *Context) Int64Slice(name string) []int64 {
|
||||
if fs := cCtx.lookupFlagSet(name); fs != nil {
|
||||
return lookupInt64Slice(name, fs)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func lookupInt64Slice(name string, set *flag.FlagSet) []int64 {
|
||||
f := set.Lookup(name)
|
||||
if f != nil {
|
||||
if slice, ok := f.Value.(*Int64Slice); ok {
|
||||
if slice, ok := unwrapFlagValue(f.Value).(*Int64Slice); ok {
|
||||
return slice.Value()
|
||||
}
|
||||
}
|
||||
|
|
147
vendor/github.com/urfave/cli/v2/flag_int_slice.go
generated
vendored
147
vendor/github.com/urfave/cli/v2/flag_int_slice.go
generated
vendored
|
@ -19,6 +19,16 @@ func NewIntSlice(defaults ...int) *IntSlice {
|
|||
return &IntSlice{slice: append([]int{}, defaults...)}
|
||||
}
|
||||
|
||||
// clone allocate a copy of self object
|
||||
func (i *IntSlice) clone() *IntSlice {
|
||||
n := &IntSlice{
|
||||
slice: make([]int, len(i.slice)),
|
||||
hasBeenSet: i.hasBeenSet,
|
||||
}
|
||||
copy(n.slice, i.slice)
|
||||
return n
|
||||
}
|
||||
|
||||
// TODO: Consistently have specific Set function for Int64 and Float64 ?
|
||||
// SetInt directly adds an integer to the list of values
|
||||
func (i *IntSlice) SetInt(value int) {
|
||||
|
@ -44,19 +54,26 @@ func (i *IntSlice) Set(value string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
tmp, err := strconv.ParseInt(value, 0, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, s := range flagSplitMultiValues(value) {
|
||||
tmp, err := strconv.ParseInt(strings.TrimSpace(s), 0, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
i.slice = append(i.slice, int(tmp))
|
||||
i.slice = append(i.slice, int(tmp))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value (for usage defaults)
|
||||
func (i *IntSlice) String() string {
|
||||
return fmt.Sprintf("%#v", i.slice)
|
||||
v := i.slice
|
||||
if v == nil {
|
||||
// treat nil the same as zero length non-nil
|
||||
v = make([]int, 0)
|
||||
}
|
||||
return fmt.Sprintf("%#v", v)
|
||||
}
|
||||
|
||||
// Serialize allows IntSlice to fulfill Serializer
|
||||
|
@ -75,79 +92,105 @@ func (i *IntSlice) Get() interface{} {
|
|||
return *i
|
||||
}
|
||||
|
||||
// IntSliceFlag is a flag with type *IntSlice
|
||||
type IntSliceFlag struct {
|
||||
Name string
|
||||
Aliases []string
|
||||
Usage string
|
||||
EnvVars []string
|
||||
FilePath string
|
||||
Required bool
|
||||
Hidden bool
|
||||
Value *IntSlice
|
||||
DefaultText string
|
||||
HasBeenSet bool
|
||||
}
|
||||
|
||||
// IsSet returns whether or not the flag has been set through env or file
|
||||
func (f *IntSliceFlag) IsSet() bool {
|
||||
return f.HasBeenSet
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value
|
||||
// (for usage defaults)
|
||||
func (f *IntSliceFlag) String() string {
|
||||
return FlagStringer(f)
|
||||
}
|
||||
|
||||
// Names returns the names of the flag
|
||||
func (f *IntSliceFlag) Names() []string {
|
||||
return flagNames(f.Name, f.Aliases)
|
||||
}
|
||||
|
||||
// IsRequired returns whether or not the flag is required
|
||||
func (f *IntSliceFlag) IsRequired() bool {
|
||||
return f.Required
|
||||
}
|
||||
|
||||
// TakesValue returns true of the flag takes a value, otherwise false
|
||||
func (f *IntSliceFlag) TakesValue() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// GetUsage returns the usage string for the flag
|
||||
func (f IntSliceFlag) GetUsage() string {
|
||||
func (f *IntSliceFlag) GetUsage() string {
|
||||
return f.Usage
|
||||
}
|
||||
|
||||
// GetCategory returns the category for the flag
|
||||
func (f *IntSliceFlag) GetCategory() string {
|
||||
return f.Category
|
||||
}
|
||||
|
||||
// GetValue returns the flags value as string representation and an empty
|
||||
// string if the flag takes no value at all.
|
||||
func (f *IntSliceFlag) GetValue() string {
|
||||
if f.Value != nil {
|
||||
return f.Value.String()
|
||||
var defaultVals []string
|
||||
if f.Value != nil && len(f.Value.Value()) > 0 {
|
||||
for _, i := range f.Value.Value() {
|
||||
defaultVals = append(defaultVals, strconv.Itoa(i))
|
||||
}
|
||||
}
|
||||
return ""
|
||||
return strings.Join(defaultVals, ", ")
|
||||
}
|
||||
|
||||
// GetDefaultText returns the default text for this flag
|
||||
func (f *IntSliceFlag) GetDefaultText() string {
|
||||
if f.DefaultText != "" {
|
||||
return f.DefaultText
|
||||
}
|
||||
return f.GetValue()
|
||||
}
|
||||
|
||||
// GetEnvVars returns the env vars for this flag
|
||||
func (f *IntSliceFlag) GetEnvVars() []string {
|
||||
return f.EnvVars
|
||||
}
|
||||
|
||||
// IsSliceFlag implements DocGenerationSliceFlag.
|
||||
func (f *IntSliceFlag) IsSliceFlag() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// Apply populates the flag given the flag set and environment
|
||||
func (f *IntSliceFlag) Apply(set *flag.FlagSet) error {
|
||||
if val, ok := flagFromEnvOrFile(f.EnvVars, f.FilePath); ok {
|
||||
f.Value = &IntSlice{}
|
||||
// apply any default
|
||||
if f.Destination != nil && f.Value != nil {
|
||||
f.Destination.slice = make([]int, len(f.Value.slice))
|
||||
copy(f.Destination.slice, f.Value.slice)
|
||||
}
|
||||
|
||||
for _, s := range strings.Split(val, ",") {
|
||||
if err := f.Value.Set(strings.TrimSpace(s)); err != nil {
|
||||
return fmt.Errorf("could not parse %q as int slice value for flag %s: %s", val, f.Name, err)
|
||||
// resolve setValue (what we will assign to the set)
|
||||
var setValue *IntSlice
|
||||
switch {
|
||||
case f.Destination != nil:
|
||||
setValue = f.Destination
|
||||
case f.Value != nil:
|
||||
setValue = f.Value.clone()
|
||||
default:
|
||||
setValue = new(IntSlice)
|
||||
}
|
||||
|
||||
if val, source, ok := flagFromEnvOrFile(f.EnvVars, f.FilePath); ok && val != "" {
|
||||
for _, s := range flagSplitMultiValues(val) {
|
||||
if err := setValue.Set(strings.TrimSpace(s)); err != nil {
|
||||
return fmt.Errorf("could not parse %q as int slice value from %s for flag %s: %s", val, source, f.Name, err)
|
||||
}
|
||||
}
|
||||
|
||||
// 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.
|
||||
setValue.hasBeenSet = false
|
||||
f.HasBeenSet = true
|
||||
}
|
||||
|
||||
for _, name := range f.Names() {
|
||||
if f.Value == nil {
|
||||
f.Value = &IntSlice{}
|
||||
}
|
||||
set.Var(f.Value, name, f.Usage)
|
||||
set.Var(setValue, name, f.Usage)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Get returns the flag’s value in the given Context.
|
||||
func (f *IntSliceFlag) Get(ctx *Context) []int {
|
||||
return ctx.IntSlice(f.Name)
|
||||
}
|
||||
|
||||
// RunAction executes flag action if set
|
||||
func (f *IntSliceFlag) RunAction(c *Context) error {
|
||||
if f.Action != nil {
|
||||
return f.Action(c, c.IntSlice(f.Name))
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -155,9 +198,9 @@ func (f *IntSliceFlag) Apply(set *flag.FlagSet) error {
|
|||
|
||||
// IntSlice looks up the value of a local IntSliceFlag, returns
|
||||
// nil if not found
|
||||
func (c *Context) IntSlice(name string) []int {
|
||||
if fs := lookupFlagSet(name, c); fs != nil {
|
||||
return lookupIntSlice(name, c.flagSet)
|
||||
func (cCtx *Context) IntSlice(name string) []int {
|
||||
if fs := cCtx.lookupFlagSet(name); fs != nil {
|
||||
return lookupIntSlice(name, fs)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -165,7 +208,7 @@ func (c *Context) IntSlice(name string) []int {
|
|||
func lookupIntSlice(name string, set *flag.FlagSet) []int {
|
||||
f := set.Lookup(name)
|
||||
if f != nil {
|
||||
if slice, ok := f.Value.(*IntSlice); ok {
|
||||
if slice, ok := unwrapFlagValue(f.Value).(*IntSlice); ok {
|
||||
return slice.Value()
|
||||
}
|
||||
}
|
||||
|
|
82
vendor/github.com/urfave/cli/v2/flag_path.go
generated
vendored
82
vendor/github.com/urfave/cli/v2/flag_path.go
generated
vendored
|
@ -1,42 +1,11 @@
|
|||
package cli
|
||||
|
||||
import "flag"
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type PathFlag struct {
|
||||
Name string
|
||||
Aliases []string
|
||||
Usage string
|
||||
EnvVars []string
|
||||
FilePath string
|
||||
Required bool
|
||||
Hidden bool
|
||||
TakesFile bool
|
||||
Value string
|
||||
DefaultText string
|
||||
Destination *string
|
||||
HasBeenSet bool
|
||||
}
|
||||
|
||||
// IsSet returns whether or not the flag has been set through env or file
|
||||
func (f *PathFlag) IsSet() bool {
|
||||
return f.HasBeenSet
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value
|
||||
// (for usage defaults)
|
||||
func (f *PathFlag) String() string {
|
||||
return FlagStringer(f)
|
||||
}
|
||||
|
||||
// Names returns the names of the flag
|
||||
func (f *PathFlag) Names() []string {
|
||||
return flagNames(f.Name, f.Aliases)
|
||||
}
|
||||
|
||||
// IsRequired returns whether or not the flag is required
|
||||
func (f *PathFlag) IsRequired() bool {
|
||||
return f.Required
|
||||
}
|
||||
type Path = string
|
||||
|
||||
// TakesValue returns true of the flag takes a value, otherwise false
|
||||
func (f *PathFlag) TakesValue() bool {
|
||||
|
@ -48,15 +17,36 @@ func (f *PathFlag) GetUsage() string {
|
|||
return f.Usage
|
||||
}
|
||||
|
||||
// GetCategory returns the category for the flag
|
||||
func (f *PathFlag) GetCategory() string {
|
||||
return f.Category
|
||||
}
|
||||
|
||||
// GetValue returns the flags value as string representation and an empty
|
||||
// string if the flag takes no value at all.
|
||||
func (f *PathFlag) GetValue() string {
|
||||
return f.Value
|
||||
}
|
||||
|
||||
// GetDefaultText returns the default text for this flag
|
||||
func (f *PathFlag) GetDefaultText() string {
|
||||
if f.DefaultText != "" {
|
||||
return f.DefaultText
|
||||
}
|
||||
if f.Value == "" {
|
||||
return f.Value
|
||||
}
|
||||
return fmt.Sprintf("%q", f.Value)
|
||||
}
|
||||
|
||||
// GetEnvVars returns the env vars for this flag
|
||||
func (f *PathFlag) GetEnvVars() []string {
|
||||
return f.EnvVars
|
||||
}
|
||||
|
||||
// Apply populates the flag given the flag set and environment
|
||||
func (f *PathFlag) Apply(set *flag.FlagSet) error {
|
||||
if val, ok := flagFromEnvOrFile(f.EnvVars, f.FilePath); ok {
|
||||
if val, _, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found {
|
||||
f.Value = val
|
||||
f.HasBeenSet = true
|
||||
}
|
||||
|
@ -72,10 +62,24 @@ func (f *PathFlag) Apply(set *flag.FlagSet) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// Get returns the flag’s value in the given Context.
|
||||
func (f *PathFlag) Get(ctx *Context) string {
|
||||
return ctx.Path(f.Name)
|
||||
}
|
||||
|
||||
// RunAction executes flag action if set
|
||||
func (f *PathFlag) RunAction(c *Context) error {
|
||||
if f.Action != nil {
|
||||
return f.Action(c, c.Path(f.Name))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Path looks up the value of a local PathFlag, returns
|
||||
// "" if not found
|
||||
func (c *Context) Path(name string) string {
|
||||
if fs := lookupFlagSet(name, c); fs != nil {
|
||||
func (cCtx *Context) Path(name string) string {
|
||||
if fs := cCtx.lookupFlagSet(name); fs != nil {
|
||||
return lookupPath(name, fs)
|
||||
}
|
||||
|
||||
|
|
88
vendor/github.com/urfave/cli/v2/flag_string.go
generated
vendored
88
vendor/github.com/urfave/cli/v2/flag_string.go
generated
vendored
|
@ -1,43 +1,9 @@
|
|||
package cli
|
||||
|
||||
import "flag"
|
||||
|
||||
// StringFlag is a flag with type string
|
||||
type StringFlag struct {
|
||||
Name string
|
||||
Aliases []string
|
||||
Usage string
|
||||
EnvVars []string
|
||||
FilePath string
|
||||
Required bool
|
||||
Hidden bool
|
||||
TakesFile bool
|
||||
Value string
|
||||
DefaultText string
|
||||
Destination *string
|
||||
HasBeenSet bool
|
||||
}
|
||||
|
||||
// IsSet returns whether or not the flag has been set through env or file
|
||||
func (f *StringFlag) IsSet() bool {
|
||||
return f.HasBeenSet
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value
|
||||
// (for usage defaults)
|
||||
func (f *StringFlag) String() string {
|
||||
return FlagStringer(f)
|
||||
}
|
||||
|
||||
// Names returns the names of the flag
|
||||
func (f *StringFlag) Names() []string {
|
||||
return flagNames(f.Name, f.Aliases)
|
||||
}
|
||||
|
||||
// IsRequired returns whether or not the flag is required
|
||||
func (f *StringFlag) IsRequired() bool {
|
||||
return f.Required
|
||||
}
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// TakesValue returns true of the flag takes a value, otherwise false
|
||||
func (f *StringFlag) TakesValue() bool {
|
||||
|
@ -49,15 +15,36 @@ func (f *StringFlag) GetUsage() string {
|
|||
return f.Usage
|
||||
}
|
||||
|
||||
// GetCategory returns the category for the flag
|
||||
func (f *StringFlag) GetCategory() string {
|
||||
return f.Category
|
||||
}
|
||||
|
||||
// GetValue returns the flags value as string representation and an empty
|
||||
// string if the flag takes no value at all.
|
||||
func (f *StringFlag) GetValue() string {
|
||||
return f.Value
|
||||
}
|
||||
|
||||
// GetDefaultText returns the default text for this flag
|
||||
func (f *StringFlag) GetDefaultText() string {
|
||||
if f.DefaultText != "" {
|
||||
return f.DefaultText
|
||||
}
|
||||
if f.Value == "" {
|
||||
return f.Value
|
||||
}
|
||||
return fmt.Sprintf("%q", f.Value)
|
||||
}
|
||||
|
||||
// GetEnvVars returns the env vars for this flag
|
||||
func (f *StringFlag) GetEnvVars() []string {
|
||||
return f.EnvVars
|
||||
}
|
||||
|
||||
// Apply populates the flag given the flag set and environment
|
||||
func (f *StringFlag) Apply(set *flag.FlagSet) error {
|
||||
if val, ok := flagFromEnvOrFile(f.EnvVars, f.FilePath); ok {
|
||||
if val, _, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found {
|
||||
f.Value = val
|
||||
f.HasBeenSet = true
|
||||
}
|
||||
|
@ -73,10 +60,24 @@ func (f *StringFlag) Apply(set *flag.FlagSet) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// Get returns the flag’s value in the given Context.
|
||||
func (f *StringFlag) Get(ctx *Context) string {
|
||||
return ctx.String(f.Name)
|
||||
}
|
||||
|
||||
// RunAction executes flag action if set
|
||||
func (f *StringFlag) RunAction(c *Context) error {
|
||||
if f.Action != nil {
|
||||
return f.Action(c, c.String(f.Name))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// String looks up the value of a local StringFlag, returns
|
||||
// "" if not found
|
||||
func (c *Context) String(name string) string {
|
||||
if fs := lookupFlagSet(name, c); fs != nil {
|
||||
func (cCtx *Context) String(name string) string {
|
||||
if fs := cCtx.lookupFlagSet(name); fs != nil {
|
||||
return lookupString(name, fs)
|
||||
}
|
||||
return ""
|
||||
|
@ -85,10 +86,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 ""
|
||||
|
|
137
vendor/github.com/urfave/cli/v2/flag_string_slice.go
generated
vendored
137
vendor/github.com/urfave/cli/v2/flag_string_slice.go
generated
vendored
|
@ -4,6 +4,7 @@ import (
|
|||
"encoding/json"
|
||||
"flag"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
|
@ -18,6 +19,16 @@ func NewStringSlice(defaults ...string) *StringSlice {
|
|||
return &StringSlice{slice: append([]string{}, defaults...)}
|
||||
}
|
||||
|
||||
// clone allocate a copy of self object
|
||||
func (s *StringSlice) clone() *StringSlice {
|
||||
n := &StringSlice{
|
||||
slice: make([]string, len(s.slice)),
|
||||
hasBeenSet: s.hasBeenSet,
|
||||
}
|
||||
copy(n.slice, s.slice)
|
||||
return n
|
||||
}
|
||||
|
||||
// Set appends the string value to the list of values
|
||||
func (s *StringSlice) Set(value string) error {
|
||||
if !s.hasBeenSet {
|
||||
|
@ -32,7 +43,9 @@ func (s *StringSlice) Set(value string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
s.slice = append(s.slice, value)
|
||||
for _, t := range flagSplitMultiValues(value) {
|
||||
s.slice = append(s.slice, strings.TrimSpace(t))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
@ -58,43 +71,12 @@ func (s *StringSlice) Get() interface{} {
|
|||
return *s
|
||||
}
|
||||
|
||||
// StringSliceFlag is a flag with type *StringSlice
|
||||
type StringSliceFlag struct {
|
||||
Name string
|
||||
Aliases []string
|
||||
Usage string
|
||||
EnvVars []string
|
||||
FilePath string
|
||||
Required bool
|
||||
Hidden bool
|
||||
TakesFile bool
|
||||
Value *StringSlice
|
||||
DefaultText string
|
||||
HasBeenSet bool
|
||||
Destination *StringSlice
|
||||
}
|
||||
|
||||
// IsSet returns whether or not the flag has been set through env or file
|
||||
func (f *StringSliceFlag) IsSet() bool {
|
||||
return f.HasBeenSet
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value
|
||||
// (for usage defaults)
|
||||
func (f *StringSliceFlag) String() string {
|
||||
return FlagStringer(f)
|
||||
}
|
||||
|
||||
// Names returns the names of the flag
|
||||
func (f *StringSliceFlag) Names() []string {
|
||||
return flagNames(f.Name, f.Aliases)
|
||||
}
|
||||
|
||||
// IsRequired returns whether or not the flag is required
|
||||
func (f *StringSliceFlag) IsRequired() bool {
|
||||
return f.Required
|
||||
}
|
||||
|
||||
// TakesValue returns true of the flag takes a value, otherwise false
|
||||
func (f *StringSliceFlag) TakesValue() bool {
|
||||
return true
|
||||
|
@ -105,56 +87,91 @@ func (f *StringSliceFlag) GetUsage() string {
|
|||
return f.Usage
|
||||
}
|
||||
|
||||
// GetCategory returns the category for the flag
|
||||
func (f *StringSliceFlag) GetCategory() string {
|
||||
return f.Category
|
||||
}
|
||||
|
||||
// GetValue returns the flags value as string representation and an empty
|
||||
// string if the flag takes no value at all.
|
||||
func (f *StringSliceFlag) GetValue() string {
|
||||
if f.Value != nil {
|
||||
return f.Value.String()
|
||||
var defaultVals []string
|
||||
if f.Value != nil && len(f.Value.Value()) > 0 {
|
||||
for _, s := range f.Value.Value() {
|
||||
if len(s) > 0 {
|
||||
defaultVals = append(defaultVals, strconv.Quote(s))
|
||||
}
|
||||
}
|
||||
}
|
||||
return ""
|
||||
return strings.Join(defaultVals, ", ")
|
||||
}
|
||||
|
||||
// GetDefaultText returns the default text for this flag
|
||||
func (f *StringSliceFlag) GetDefaultText() string {
|
||||
if f.DefaultText != "" {
|
||||
return f.DefaultText
|
||||
}
|
||||
return f.GetValue()
|
||||
}
|
||||
|
||||
// GetEnvVars returns the env vars for this flag
|
||||
func (f *StringSliceFlag) GetEnvVars() []string {
|
||||
return f.EnvVars
|
||||
}
|
||||
|
||||
// IsSliceFlag implements DocGenerationSliceFlag.
|
||||
func (f *StringSliceFlag) IsSliceFlag() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// Apply populates the flag given the flag set and environment
|
||||
func (f *StringSliceFlag) Apply(set *flag.FlagSet) error {
|
||||
|
||||
// apply any default
|
||||
if f.Destination != nil && f.Value != nil {
|
||||
f.Destination.slice = make([]string, len(f.Value.slice))
|
||||
copy(f.Destination.slice, f.Value.slice)
|
||||
|
||||
}
|
||||
|
||||
if val, ok := flagFromEnvOrFile(f.EnvVars, f.FilePath); ok {
|
||||
if f.Value == nil {
|
||||
f.Value = &StringSlice{}
|
||||
}
|
||||
destination := f.Value
|
||||
if f.Destination != nil {
|
||||
destination = f.Destination
|
||||
}
|
||||
// resolve setValue (what we will assign to the set)
|
||||
var setValue *StringSlice
|
||||
switch {
|
||||
case f.Destination != nil:
|
||||
setValue = f.Destination
|
||||
case f.Value != nil:
|
||||
setValue = f.Value.clone()
|
||||
default:
|
||||
setValue = new(StringSlice)
|
||||
}
|
||||
|
||||
for _, s := range strings.Split(val, ",") {
|
||||
if err := destination.Set(strings.TrimSpace(s)); err != nil {
|
||||
return fmt.Errorf("could not parse %q as string value for flag %s: %s", val, f.Name, err)
|
||||
if val, source, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found {
|
||||
for _, s := range flagSplitMultiValues(val) {
|
||||
if err := setValue.Set(strings.TrimSpace(s)); err != nil {
|
||||
return fmt.Errorf("could not parse %q as string value from %s for flag %s: %s", val, source, f.Name, err)
|
||||
}
|
||||
}
|
||||
|
||||
// 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.
|
||||
destination.hasBeenSet = false
|
||||
setValue.hasBeenSet = false
|
||||
f.HasBeenSet = true
|
||||
}
|
||||
|
||||
for _, name := range f.Names() {
|
||||
if f.Value == nil {
|
||||
f.Value = &StringSlice{}
|
||||
}
|
||||
set.Var(setValue, name, f.Usage)
|
||||
}
|
||||
|
||||
if f.Destination != nil {
|
||||
set.Var(f.Destination, name, f.Usage)
|
||||
continue
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
set.Var(f.Value, name, f.Usage)
|
||||
// Get returns the flag’s value in the given Context.
|
||||
func (f *StringSliceFlag) Get(ctx *Context) []string {
|
||||
return ctx.StringSlice(f.Name)
|
||||
}
|
||||
|
||||
// RunAction executes flag action if set
|
||||
func (f *StringSliceFlag) RunAction(c *Context) error {
|
||||
if f.Action != nil {
|
||||
return f.Action(c, c.StringSlice(f.Name))
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -162,8 +179,8 @@ func (f *StringSliceFlag) Apply(set *flag.FlagSet) error {
|
|||
|
||||
// StringSlice looks up the value of a local StringSliceFlag, returns
|
||||
// nil if not found
|
||||
func (c *Context) StringSlice(name string) []string {
|
||||
if fs := lookupFlagSet(name, c); fs != nil {
|
||||
func (cCtx *Context) StringSlice(name string) []string {
|
||||
if fs := cCtx.lookupFlagSet(name); fs != nil {
|
||||
return lookupStringSlice(name, fs)
|
||||
}
|
||||
return nil
|
||||
|
@ -172,7 +189,7 @@ func (c *Context) StringSlice(name string) []string {
|
|||
func lookupStringSlice(name string, set *flag.FlagSet) []string {
|
||||
f := set.Lookup(name)
|
||||
if f != nil {
|
||||
if slice, ok := f.Value.(*StringSlice); ok {
|
||||
if slice, ok := unwrapFlagValue(f.Value).(*StringSlice); ok {
|
||||
return slice.Value()
|
||||
}
|
||||
}
|
||||
|
|
105
vendor/github.com/urfave/cli/v2/flag_timestamp.go
generated
vendored
105
vendor/github.com/urfave/cli/v2/flag_timestamp.go
generated
vendored
|
@ -11,6 +11,7 @@ type Timestamp struct {
|
|||
timestamp *time.Time
|
||||
hasBeenSet bool
|
||||
layout string
|
||||
location *time.Location
|
||||
}
|
||||
|
||||
// Timestamp constructor
|
||||
|
@ -31,9 +32,22 @@ func (t *Timestamp) SetLayout(layout string) {
|
|||
t.layout = layout
|
||||
}
|
||||
|
||||
// Set perceived timezone of the to-be parsed time string
|
||||
func (t *Timestamp) SetLocation(loc *time.Location) {
|
||||
t.location = loc
|
||||
}
|
||||
|
||||
// Parses the string value to timestamp
|
||||
func (t *Timestamp) Set(value string) error {
|
||||
timestamp, err := time.Parse(t.layout, value)
|
||||
var timestamp time.Time
|
||||
var err error
|
||||
|
||||
if t.location != nil {
|
||||
timestamp, err = time.ParseInLocation(t.layout, value, t.location)
|
||||
} else {
|
||||
timestamp, err = time.Parse(t.layout, value)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -58,42 +72,6 @@ func (t *Timestamp) Get() interface{} {
|
|||
return *t
|
||||
}
|
||||
|
||||
// TimestampFlag is a flag with type time
|
||||
type TimestampFlag struct {
|
||||
Name string
|
||||
Aliases []string
|
||||
Usage string
|
||||
EnvVars []string
|
||||
FilePath string
|
||||
Required bool
|
||||
Hidden bool
|
||||
Layout string
|
||||
Value *Timestamp
|
||||
DefaultText string
|
||||
HasBeenSet bool
|
||||
}
|
||||
|
||||
// IsSet returns whether or not the flag has been set through env or file
|
||||
func (f *TimestampFlag) IsSet() bool {
|
||||
return f.HasBeenSet
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value
|
||||
// (for usage defaults)
|
||||
func (f *TimestampFlag) String() string {
|
||||
return FlagStringer(f)
|
||||
}
|
||||
|
||||
// Names returns the names of the flag
|
||||
func (f *TimestampFlag) Names() []string {
|
||||
return flagNames(f.Name, f.Aliases)
|
||||
}
|
||||
|
||||
// IsRequired returns whether or not the flag is required
|
||||
func (f *TimestampFlag) IsRequired() bool {
|
||||
return f.Required
|
||||
}
|
||||
|
||||
// TakesValue returns true of the flag takes a value, otherwise false
|
||||
func (f *TimestampFlag) TakesValue() bool {
|
||||
return true
|
||||
|
@ -104,15 +82,33 @@ func (f *TimestampFlag) GetUsage() string {
|
|||
return f.Usage
|
||||
}
|
||||
|
||||
// GetCategory returns the category for the flag
|
||||
func (f *TimestampFlag) GetCategory() string {
|
||||
return f.Category
|
||||
}
|
||||
|
||||
// GetValue returns the flags value as string representation and an empty
|
||||
// string if the flag takes no value at all.
|
||||
func (f *TimestampFlag) GetValue() string {
|
||||
if f.Value != nil {
|
||||
if f.Value != nil && f.Value.timestamp != nil {
|
||||
return f.Value.timestamp.String()
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// GetDefaultText returns the default text for this flag
|
||||
func (f *TimestampFlag) GetDefaultText() string {
|
||||
if f.DefaultText != "" {
|
||||
return f.DefaultText
|
||||
}
|
||||
return f.GetValue()
|
||||
}
|
||||
|
||||
// GetEnvVars returns the env vars for this flag
|
||||
func (f *TimestampFlag) GetEnvVars() []string {
|
||||
return f.EnvVars
|
||||
}
|
||||
|
||||
// Apply populates the flag given the flag set and environment
|
||||
func (f *TimestampFlag) Apply(set *flag.FlagSet) error {
|
||||
if f.Layout == "" {
|
||||
|
@ -122,23 +118,48 @@ func (f *TimestampFlag) Apply(set *flag.FlagSet) error {
|
|||
f.Value = &Timestamp{}
|
||||
}
|
||||
f.Value.SetLayout(f.Layout)
|
||||
f.Value.SetLocation(f.Timezone)
|
||||
|
||||
if val, ok := flagFromEnvOrFile(f.EnvVars, f.FilePath); ok {
|
||||
if f.Destination != nil {
|
||||
f.Destination.SetLayout(f.Layout)
|
||||
f.Destination.SetLocation(f.Timezone)
|
||||
}
|
||||
|
||||
if val, source, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found {
|
||||
if err := f.Value.Set(val); err != nil {
|
||||
return fmt.Errorf("could not parse %q as timestamp value for flag %s: %s", val, f.Name, err)
|
||||
return fmt.Errorf("could not parse %q as timestamp value from %s for flag %s: %s", val, source, f.Name, err)
|
||||
}
|
||||
f.HasBeenSet = true
|
||||
}
|
||||
|
||||
for _, name := range f.Names() {
|
||||
if f.Destination != nil {
|
||||
set.Var(f.Destination, name, f.Usage)
|
||||
continue
|
||||
}
|
||||
|
||||
set.Var(f.Value, name, f.Usage)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Get returns the flag’s value in the given Context.
|
||||
func (f *TimestampFlag) Get(ctx *Context) *time.Time {
|
||||
return ctx.Timestamp(f.Name)
|
||||
}
|
||||
|
||||
// RunAction executes flag action if set
|
||||
func (f *TimestampFlag) RunAction(c *Context) error {
|
||||
if f.Action != nil {
|
||||
return f.Action(c, c.Timestamp(f.Name))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Timestamp gets the timestamp from a flag name
|
||||
func (c *Context) Timestamp(name string) *time.Time {
|
||||
if fs := lookupFlagSet(name, c); fs != nil {
|
||||
func (cCtx *Context) Timestamp(name string) *time.Time {
|
||||
if fs := cCtx.lookupFlagSet(name); fs != nil {
|
||||
return lookupTimestamp(name, fs)
|
||||
}
|
||||
return nil
|
||||
|
|
78
vendor/github.com/urfave/cli/v2/flag_uint.go
generated
vendored
78
vendor/github.com/urfave/cli/v2/flag_uint.go
generated
vendored
|
@ -6,42 +6,6 @@ import (
|
|||
"strconv"
|
||||
)
|
||||
|
||||
// UintFlag is a flag with type uint
|
||||
type UintFlag struct {
|
||||
Name string
|
||||
Aliases []string
|
||||
Usage string
|
||||
EnvVars []string
|
||||
FilePath string
|
||||
Required bool
|
||||
Hidden bool
|
||||
Value uint
|
||||
DefaultText string
|
||||
Destination *uint
|
||||
HasBeenSet bool
|
||||
}
|
||||
|
||||
// IsSet returns whether or not the flag has been set through env or file
|
||||
func (f *UintFlag) IsSet() bool {
|
||||
return f.HasBeenSet
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value
|
||||
// (for usage defaults)
|
||||
func (f *UintFlag) String() string {
|
||||
return FlagStringer(f)
|
||||
}
|
||||
|
||||
// Names returns the names of the flag
|
||||
func (f *UintFlag) Names() []string {
|
||||
return flagNames(f.Name, f.Aliases)
|
||||
}
|
||||
|
||||
// IsRequired returns whether or not the flag is required
|
||||
func (f *UintFlag) IsRequired() bool {
|
||||
return f.Required
|
||||
}
|
||||
|
||||
// TakesValue returns true of the flag takes a value, otherwise false
|
||||
func (f *UintFlag) TakesValue() bool {
|
||||
return true
|
||||
|
@ -52,13 +16,18 @@ func (f *UintFlag) GetUsage() string {
|
|||
return f.Usage
|
||||
}
|
||||
|
||||
// GetCategory returns the category for the flag
|
||||
func (f *UintFlag) GetCategory() string {
|
||||
return f.Category
|
||||
}
|
||||
|
||||
// Apply populates the flag given the flag set and environment
|
||||
func (f *UintFlag) Apply(set *flag.FlagSet) error {
|
||||
if val, ok := flagFromEnvOrFile(f.EnvVars, f.FilePath); ok {
|
||||
if val, source, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found {
|
||||
if val != "" {
|
||||
valInt, err := strconv.ParseUint(val, 0, 64)
|
||||
valInt, err := strconv.ParseUint(val, f.Base, 64)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not parse %q as uint value for flag %s: %s", val, f.Name, err)
|
||||
return fmt.Errorf("could not parse %q as uint value from %s for flag %s: %s", val, source, f.Name, err)
|
||||
}
|
||||
|
||||
f.Value = uint(valInt)
|
||||
|
@ -77,16 +46,43 @@ func (f *UintFlag) Apply(set *flag.FlagSet) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// RunAction executes flag action if set
|
||||
func (f *UintFlag) RunAction(c *Context) error {
|
||||
if f.Action != nil {
|
||||
return f.Action(c, c.Uint(f.Name))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetValue returns the flags value as string representation and an empty
|
||||
// string if the flag takes no value at all.
|
||||
func (f *UintFlag) GetValue() string {
|
||||
return fmt.Sprintf("%d", f.Value)
|
||||
}
|
||||
|
||||
// GetDefaultText returns the default text for this flag
|
||||
func (f *UintFlag) GetDefaultText() string {
|
||||
if f.DefaultText != "" {
|
||||
return f.DefaultText
|
||||
}
|
||||
return f.GetValue()
|
||||
}
|
||||
|
||||
// GetEnvVars returns the env vars for this flag
|
||||
func (f *UintFlag) GetEnvVars() []string {
|
||||
return f.EnvVars
|
||||
}
|
||||
|
||||
// Get returns the flag’s value in the given Context.
|
||||
func (f *UintFlag) Get(ctx *Context) uint {
|
||||
return ctx.Uint(f.Name)
|
||||
}
|
||||
|
||||
// Uint looks up the value of a local UintFlag, returns
|
||||
// 0 if not found
|
||||
func (c *Context) Uint(name string) uint {
|
||||
if fs := lookupFlagSet(name, c); fs != nil {
|
||||
func (cCtx *Context) Uint(name string) uint {
|
||||
if fs := cCtx.lookupFlagSet(name); fs != nil {
|
||||
return lookupUint(name, fs)
|
||||
}
|
||||
return 0
|
||||
|
|
78
vendor/github.com/urfave/cli/v2/flag_uint64.go
generated
vendored
78
vendor/github.com/urfave/cli/v2/flag_uint64.go
generated
vendored
|
@ -6,42 +6,6 @@ import (
|
|||
"strconv"
|
||||
)
|
||||
|
||||
// Uint64Flag is a flag with type uint64
|
||||
type Uint64Flag struct {
|
||||
Name string
|
||||
Aliases []string
|
||||
Usage string
|
||||
EnvVars []string
|
||||
FilePath string
|
||||
Required bool
|
||||
Hidden bool
|
||||
Value uint64
|
||||
DefaultText string
|
||||
Destination *uint64
|
||||
HasBeenSet bool
|
||||
}
|
||||
|
||||
// IsSet returns whether or not the flag has been set through env or file
|
||||
func (f *Uint64Flag) IsSet() bool {
|
||||
return f.HasBeenSet
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value
|
||||
// (for usage defaults)
|
||||
func (f *Uint64Flag) String() string {
|
||||
return FlagStringer(f)
|
||||
}
|
||||
|
||||
// Names returns the names of the flag
|
||||
func (f *Uint64Flag) Names() []string {
|
||||
return flagNames(f.Name, f.Aliases)
|
||||
}
|
||||
|
||||
// IsRequired returns whether or not the flag is required
|
||||
func (f *Uint64Flag) IsRequired() bool {
|
||||
return f.Required
|
||||
}
|
||||
|
||||
// TakesValue returns true of the flag takes a value, otherwise false
|
||||
func (f *Uint64Flag) TakesValue() bool {
|
||||
return true
|
||||
|
@ -52,13 +16,18 @@ func (f *Uint64Flag) GetUsage() string {
|
|||
return f.Usage
|
||||
}
|
||||
|
||||
// GetCategory returns the category for the flag
|
||||
func (f *Uint64Flag) GetCategory() string {
|
||||
return f.Category
|
||||
}
|
||||
|
||||
// Apply populates the flag given the flag set and environment
|
||||
func (f *Uint64Flag) Apply(set *flag.FlagSet) error {
|
||||
if val, ok := flagFromEnvOrFile(f.EnvVars, f.FilePath); ok {
|
||||
if val, source, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found {
|
||||
if val != "" {
|
||||
valInt, err := strconv.ParseUint(val, 0, 64)
|
||||
valInt, err := strconv.ParseUint(val, f.Base, 64)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not parse %q as uint64 value for flag %s: %s", val, f.Name, err)
|
||||
return fmt.Errorf("could not parse %q as uint64 value from %s for flag %s: %s", val, source, f.Name, err)
|
||||
}
|
||||
|
||||
f.Value = valInt
|
||||
|
@ -77,16 +46,43 @@ func (f *Uint64Flag) Apply(set *flag.FlagSet) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// RunAction executes flag action if set
|
||||
func (f *Uint64Flag) RunAction(c *Context) error {
|
||||
if f.Action != nil {
|
||||
return f.Action(c, c.Uint64(f.Name))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetValue returns the flags value as string representation and an empty
|
||||
// string if the flag takes no value at all.
|
||||
func (f *Uint64Flag) GetValue() string {
|
||||
return fmt.Sprintf("%d", f.Value)
|
||||
}
|
||||
|
||||
// GetDefaultText returns the default text for this flag
|
||||
func (f *Uint64Flag) GetDefaultText() string {
|
||||
if f.DefaultText != "" {
|
||||
return f.DefaultText
|
||||
}
|
||||
return f.GetValue()
|
||||
}
|
||||
|
||||
// GetEnvVars returns the env vars for this flag
|
||||
func (f *Uint64Flag) GetEnvVars() []string {
|
||||
return f.EnvVars
|
||||
}
|
||||
|
||||
// Get returns the flag’s value in the given Context.
|
||||
func (f *Uint64Flag) Get(ctx *Context) uint64 {
|
||||
return ctx.Uint64(f.Name)
|
||||
}
|
||||
|
||||
// Uint64 looks up the value of a local Uint64Flag, returns
|
||||
// 0 if not found
|
||||
func (c *Context) Uint64(name string) uint64 {
|
||||
if fs := lookupFlagSet(name, c); fs != nil {
|
||||
func (cCtx *Context) Uint64(name string) uint64 {
|
||||
if fs := cCtx.lookupFlagSet(name); fs != nil {
|
||||
return lookupUint64(name, fs)
|
||||
}
|
||||
return 0
|
||||
|
|
200
vendor/github.com/urfave/cli/v2/flag_uint64_slice.go
generated
vendored
Normal file
200
vendor/github.com/urfave/cli/v2/flag_uint64_slice.go
generated
vendored
Normal file
|
@ -0,0 +1,200 @@
|
|||
package cli
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Uint64Slice wraps []int64 to satisfy flag.Value
|
||||
type Uint64Slice struct {
|
||||
slice []uint64
|
||||
hasBeenSet bool
|
||||
}
|
||||
|
||||
// NewUint64Slice makes an *Uint64Slice with default values
|
||||
func NewUint64Slice(defaults ...uint64) *Uint64Slice {
|
||||
return &Uint64Slice{slice: append([]uint64{}, defaults...)}
|
||||
}
|
||||
|
||||
// clone allocate a copy of self object
|
||||
func (i *Uint64Slice) clone() *Uint64Slice {
|
||||
n := &Uint64Slice{
|
||||
slice: make([]uint64, len(i.slice)),
|
||||
hasBeenSet: i.hasBeenSet,
|
||||
}
|
||||
copy(n.slice, i.slice)
|
||||
return n
|
||||
}
|
||||
|
||||
// Set parses the value into an integer and appends it to the list of values
|
||||
func (i *Uint64Slice) Set(value string) error {
|
||||
if !i.hasBeenSet {
|
||||
i.slice = []uint64{}
|
||||
i.hasBeenSet = true
|
||||
}
|
||||
|
||||
if strings.HasPrefix(value, slPfx) {
|
||||
// Deserializing assumes overwrite
|
||||
_ = json.Unmarshal([]byte(strings.Replace(value, slPfx, "", 1)), &i.slice)
|
||||
i.hasBeenSet = true
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, s := range flagSplitMultiValues(value) {
|
||||
tmp, err := strconv.ParseUint(strings.TrimSpace(s), 0, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
i.slice = append(i.slice, tmp)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value (for usage defaults)
|
||||
func (i *Uint64Slice) String() string {
|
||||
v := i.slice
|
||||
if v == nil {
|
||||
// treat nil the same as zero length non-nil
|
||||
v = make([]uint64, 0)
|
||||
}
|
||||
str := fmt.Sprintf("%d", v)
|
||||
str = strings.Replace(str, " ", ", ", -1)
|
||||
str = strings.Replace(str, "[", "{", -1)
|
||||
str = strings.Replace(str, "]", "}", -1)
|
||||
return fmt.Sprintf("[]uint64%s", str)
|
||||
}
|
||||
|
||||
// Serialize allows Uint64Slice to fulfill Serializer
|
||||
func (i *Uint64Slice) Serialize() string {
|
||||
jsonBytes, _ := json.Marshal(i.slice)
|
||||
return fmt.Sprintf("%s%s", slPfx, string(jsonBytes))
|
||||
}
|
||||
|
||||
// Value returns the slice of ints set by this flag
|
||||
func (i *Uint64Slice) Value() []uint64 {
|
||||
return i.slice
|
||||
}
|
||||
|
||||
// Get returns the slice of ints set by this flag
|
||||
func (i *Uint64Slice) Get() interface{} {
|
||||
return *i
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value
|
||||
// (for usage defaults)
|
||||
func (f *Uint64SliceFlag) String() string {
|
||||
return FlagStringer(f)
|
||||
}
|
||||
|
||||
// TakesValue returns true of the flag takes a value, otherwise false
|
||||
func (f *Uint64SliceFlag) TakesValue() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// GetUsage returns the usage string for the flag
|
||||
func (f *Uint64SliceFlag) GetUsage() string {
|
||||
return f.Usage
|
||||
}
|
||||
|
||||
// GetCategory returns the category for the flag
|
||||
func (f *Uint64SliceFlag) GetCategory() string {
|
||||
return f.Category
|
||||
}
|
||||
|
||||
// GetValue returns the flags value as string representation and an empty
|
||||
// string if the flag takes no value at all.
|
||||
func (f *Uint64SliceFlag) GetValue() string {
|
||||
var defaultVals []string
|
||||
if f.Value != nil && len(f.Value.Value()) > 0 {
|
||||
for _, i := range f.Value.Value() {
|
||||
defaultVals = append(defaultVals, strconv.FormatUint(i, 10))
|
||||
}
|
||||
}
|
||||
return strings.Join(defaultVals, ", ")
|
||||
}
|
||||
|
||||
// GetDefaultText returns the default text for this flag
|
||||
func (f *Uint64SliceFlag) GetDefaultText() string {
|
||||
if f.DefaultText != "" {
|
||||
return f.DefaultText
|
||||
}
|
||||
return f.GetValue()
|
||||
}
|
||||
|
||||
// GetEnvVars returns the env vars for this flag
|
||||
func (f *Uint64SliceFlag) GetEnvVars() []string {
|
||||
return f.EnvVars
|
||||
}
|
||||
|
||||
// IsSliceFlag implements DocGenerationSliceFlag.
|
||||
func (f *Uint64SliceFlag) IsSliceFlag() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// Apply populates the flag given the flag set and environment
|
||||
func (f *Uint64SliceFlag) Apply(set *flag.FlagSet) error {
|
||||
// apply any default
|
||||
if f.Destination != nil && f.Value != nil {
|
||||
f.Destination.slice = make([]uint64, len(f.Value.slice))
|
||||
copy(f.Destination.slice, f.Value.slice)
|
||||
}
|
||||
|
||||
// resolve setValue (what we will assign to the set)
|
||||
var setValue *Uint64Slice
|
||||
switch {
|
||||
case f.Destination != nil:
|
||||
setValue = f.Destination
|
||||
case f.Value != nil:
|
||||
setValue = f.Value.clone()
|
||||
default:
|
||||
setValue = new(Uint64Slice)
|
||||
}
|
||||
|
||||
if val, source, ok := flagFromEnvOrFile(f.EnvVars, f.FilePath); ok && val != "" {
|
||||
for _, s := range flagSplitMultiValues(val) {
|
||||
if err := setValue.Set(strings.TrimSpace(s)); err != nil {
|
||||
return fmt.Errorf("could not parse %q as uint64 slice value from %s for flag %s: %s", val, source, f.Name, err)
|
||||
}
|
||||
}
|
||||
|
||||
// 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.
|
||||
setValue.hasBeenSet = false
|
||||
f.HasBeenSet = true
|
||||
}
|
||||
|
||||
for _, name := range f.Names() {
|
||||
set.Var(setValue, name, f.Usage)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Get returns the flag’s value in the given Context.
|
||||
func (f *Uint64SliceFlag) Get(ctx *Context) []uint64 {
|
||||
return ctx.Uint64Slice(f.Name)
|
||||
}
|
||||
|
||||
// Uint64Slice looks up the value of a local Uint64SliceFlag, returns
|
||||
// nil if not found
|
||||
func (cCtx *Context) Uint64Slice(name string) []uint64 {
|
||||
if fs := cCtx.lookupFlagSet(name); fs != nil {
|
||||
return lookupUint64Slice(name, fs)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func lookupUint64Slice(name string, set *flag.FlagSet) []uint64 {
|
||||
f := set.Lookup(name)
|
||||
if f != nil {
|
||||
if slice, ok := unwrapFlagValue(f.Value).(*Uint64Slice); ok {
|
||||
return slice.Value()
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
211
vendor/github.com/urfave/cli/v2/flag_uint_slice.go
generated
vendored
Normal file
211
vendor/github.com/urfave/cli/v2/flag_uint_slice.go
generated
vendored
Normal file
|
@ -0,0 +1,211 @@
|
|||
package cli
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// UintSlice wraps []int to satisfy flag.Value
|
||||
type UintSlice struct {
|
||||
slice []uint
|
||||
hasBeenSet bool
|
||||
}
|
||||
|
||||
// NewUintSlice makes an *UintSlice with default values
|
||||
func NewUintSlice(defaults ...uint) *UintSlice {
|
||||
return &UintSlice{slice: append([]uint{}, defaults...)}
|
||||
}
|
||||
|
||||
// clone allocate a copy of self object
|
||||
func (i *UintSlice) clone() *UintSlice {
|
||||
n := &UintSlice{
|
||||
slice: make([]uint, len(i.slice)),
|
||||
hasBeenSet: i.hasBeenSet,
|
||||
}
|
||||
copy(n.slice, i.slice)
|
||||
return n
|
||||
}
|
||||
|
||||
// TODO: Consistently have specific Set function for Int64 and Float64 ?
|
||||
// SetInt directly adds an integer to the list of values
|
||||
func (i *UintSlice) SetUint(value uint) {
|
||||
if !i.hasBeenSet {
|
||||
i.slice = []uint{}
|
||||
i.hasBeenSet = true
|
||||
}
|
||||
|
||||
i.slice = append(i.slice, value)
|
||||
}
|
||||
|
||||
// Set parses the value into an integer and appends it to the list of values
|
||||
func (i *UintSlice) Set(value string) error {
|
||||
if !i.hasBeenSet {
|
||||
i.slice = []uint{}
|
||||
i.hasBeenSet = true
|
||||
}
|
||||
|
||||
if strings.HasPrefix(value, slPfx) {
|
||||
// Deserializing assumes overwrite
|
||||
_ = json.Unmarshal([]byte(strings.Replace(value, slPfx, "", 1)), &i.slice)
|
||||
i.hasBeenSet = true
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, s := range flagSplitMultiValues(value) {
|
||||
tmp, err := strconv.ParseUint(strings.TrimSpace(s), 0, 32)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
i.slice = append(i.slice, uint(tmp))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value (for usage defaults)
|
||||
func (i *UintSlice) String() string {
|
||||
v := i.slice
|
||||
if v == nil {
|
||||
// treat nil the same as zero length non-nil
|
||||
v = make([]uint, 0)
|
||||
}
|
||||
str := fmt.Sprintf("%d", v)
|
||||
str = strings.Replace(str, " ", ", ", -1)
|
||||
str = strings.Replace(str, "[", "{", -1)
|
||||
str = strings.Replace(str, "]", "}", -1)
|
||||
return fmt.Sprintf("[]uint%s", str)
|
||||
}
|
||||
|
||||
// Serialize allows UintSlice to fulfill Serializer
|
||||
func (i *UintSlice) Serialize() string {
|
||||
jsonBytes, _ := json.Marshal(i.slice)
|
||||
return fmt.Sprintf("%s%s", slPfx, string(jsonBytes))
|
||||
}
|
||||
|
||||
// Value returns the slice of ints set by this flag
|
||||
func (i *UintSlice) Value() []uint {
|
||||
return i.slice
|
||||
}
|
||||
|
||||
// Get returns the slice of ints set by this flag
|
||||
func (i *UintSlice) Get() interface{} {
|
||||
return *i
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value
|
||||
// (for usage defaults)
|
||||
func (f *UintSliceFlag) String() string {
|
||||
return FlagStringer(f)
|
||||
}
|
||||
|
||||
// TakesValue returns true of the flag takes a value, otherwise false
|
||||
func (f *UintSliceFlag) TakesValue() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// GetUsage returns the usage string for the flag
|
||||
func (f *UintSliceFlag) GetUsage() string {
|
||||
return f.Usage
|
||||
}
|
||||
|
||||
// GetCategory returns the category for the flag
|
||||
func (f *UintSliceFlag) GetCategory() string {
|
||||
return f.Category
|
||||
}
|
||||
|
||||
// GetValue returns the flags value as string representation and an empty
|
||||
// string if the flag takes no value at all.
|
||||
func (f *UintSliceFlag) GetValue() string {
|
||||
var defaultVals []string
|
||||
if f.Value != nil && len(f.Value.Value()) > 0 {
|
||||
for _, i := range f.Value.Value() {
|
||||
defaultVals = append(defaultVals, strconv.FormatUint(uint64(i), 10))
|
||||
}
|
||||
}
|
||||
return strings.Join(defaultVals, ", ")
|
||||
}
|
||||
|
||||
// GetDefaultText returns the default text for this flag
|
||||
func (f *UintSliceFlag) GetDefaultText() string {
|
||||
if f.DefaultText != "" {
|
||||
return f.DefaultText
|
||||
}
|
||||
return f.GetValue()
|
||||
}
|
||||
|
||||
// GetEnvVars returns the env vars for this flag
|
||||
func (f *UintSliceFlag) GetEnvVars() []string {
|
||||
return f.EnvVars
|
||||
}
|
||||
|
||||
// IsSliceFlag implements DocGenerationSliceFlag.
|
||||
func (f *UintSliceFlag) IsSliceFlag() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// Apply populates the flag given the flag set and environment
|
||||
func (f *UintSliceFlag) Apply(set *flag.FlagSet) error {
|
||||
// apply any default
|
||||
if f.Destination != nil && f.Value != nil {
|
||||
f.Destination.slice = make([]uint, len(f.Value.slice))
|
||||
copy(f.Destination.slice, f.Value.slice)
|
||||
}
|
||||
|
||||
// resolve setValue (what we will assign to the set)
|
||||
var setValue *UintSlice
|
||||
switch {
|
||||
case f.Destination != nil:
|
||||
setValue = f.Destination
|
||||
case f.Value != nil:
|
||||
setValue = f.Value.clone()
|
||||
default:
|
||||
setValue = new(UintSlice)
|
||||
}
|
||||
|
||||
if val, source, ok := flagFromEnvOrFile(f.EnvVars, f.FilePath); ok && val != "" {
|
||||
for _, s := range flagSplitMultiValues(val) {
|
||||
if err := setValue.Set(strings.TrimSpace(s)); err != nil {
|
||||
return fmt.Errorf("could not parse %q as uint slice value from %s for flag %s: %s", val, source, f.Name, err)
|
||||
}
|
||||
}
|
||||
|
||||
// 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.
|
||||
setValue.hasBeenSet = false
|
||||
f.HasBeenSet = true
|
||||
}
|
||||
|
||||
for _, name := range f.Names() {
|
||||
set.Var(setValue, name, f.Usage)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Get returns the flag’s value in the given Context.
|
||||
func (f *UintSliceFlag) Get(ctx *Context) []uint {
|
||||
return ctx.UintSlice(f.Name)
|
||||
}
|
||||
|
||||
// UintSlice looks up the value of a local UintSliceFlag, returns
|
||||
// nil if not found
|
||||
func (cCtx *Context) UintSlice(name string) []uint {
|
||||
if fs := cCtx.lookupFlagSet(name); fs != nil {
|
||||
return lookupUintSlice(name, fs)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func lookupUintSlice(name string, set *flag.FlagSet) []uint {
|
||||
f := set.Lookup(name)
|
||||
if f != nil {
|
||||
if slice, ok := unwrapFlagValue(f.Value).(*UintSlice); ok {
|
||||
return slice.Value()
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
9
vendor/github.com/urfave/cli/v2/funcs.go
generated
vendored
9
vendor/github.com/urfave/cli/v2/funcs.go
generated
vendored
|
@ -17,15 +17,18 @@ 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.
|
||||
type OnUsageErrorFunc func(context *Context, err error, isSubcommand bool) error
|
||||
type OnUsageErrorFunc func(cCtx *Context, err error, isSubcommand bool) error
|
||||
|
||||
// InvalidFlagAccessFunc is executed when an invalid flag is accessed from the context.
|
||||
type InvalidFlagAccessFunc func(*Context, string)
|
||||
|
||||
// ExitErrHandlerFunc is executed if provided in order to handle exitError values
|
||||
// returned by Actions and Before/After functions.
|
||||
type ExitErrHandlerFunc func(context *Context, err error)
|
||||
type ExitErrHandlerFunc func(cCtx *Context, err error)
|
||||
|
||||
// FlagStringFunc is used by the help generation to display a flag, which is
|
||||
// expected to be a single line.
|
||||
|
|
9
vendor/github.com/urfave/cli/v2/go.mod
generated
vendored
9
vendor/github.com/urfave/cli/v2/go.mod
generated
vendored
|
@ -1,9 +0,0 @@
|
|||
module github.com/urfave/cli/v2
|
||||
|
||||
go 1.11
|
||||
|
||||
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
|
||||
)
|
14
vendor/github.com/urfave/cli/v2/go.sum
generated
vendored
14
vendor/github.com/urfave/cli/v2/go.sum
generated
vendored
|
@ -1,14 +0,0 @@
|
|||
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=
|
||||
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=
|
2619
vendor/github.com/urfave/cli/v2/godoc-current.txt
generated
vendored
Normal file
2619
vendor/github.com/urfave/cli/v2/godoc-current.txt
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
305
vendor/github.com/urfave/cli/v2/help.go
generated
vendored
305
vendor/github.com/urfave/cli/v2/help.go
generated
vendored
|
@ -10,34 +10,65 @@ import (
|
|||
"unicode/utf8"
|
||||
)
|
||||
|
||||
var helpCommand = &Command{
|
||||
Name: "help",
|
||||
Aliases: []string{"h"},
|
||||
const (
|
||||
helpName = "help"
|
||||
helpAlias = "h"
|
||||
)
|
||||
|
||||
// this instance is to avoid recursion in the ShowCommandHelp which can
|
||||
// add a help command again
|
||||
var helpCommandDontUse = &Command{
|
||||
Name: helpName,
|
||||
Aliases: []string{helpAlias},
|
||||
Usage: "Shows a list of commands or help for one command",
|
||||
ArgsUsage: "[command]",
|
||||
Action: func(c *Context) error {
|
||||
args := c.Args()
|
||||
if args.Present() {
|
||||
return ShowCommandHelp(c, args.First())
|
||||
}
|
||||
|
||||
_ = ShowAppHelp(c)
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
var helpSubcommand = &Command{
|
||||
Name: "help",
|
||||
Aliases: []string{"h"},
|
||||
var helpCommand = &Command{
|
||||
Name: helpName,
|
||||
Aliases: []string{helpAlias},
|
||||
Usage: "Shows a list of commands or help for one command",
|
||||
ArgsUsage: "[command]",
|
||||
Action: func(c *Context) error {
|
||||
args := c.Args()
|
||||
if args.Present() {
|
||||
return ShowCommandHelp(c, args.First())
|
||||
Action: func(cCtx *Context) error {
|
||||
args := cCtx.Args()
|
||||
argsPresent := args.First() != ""
|
||||
firstArg := args.First()
|
||||
|
||||
// This action can be triggered by a "default" action of a command
|
||||
// or via cmd.Run when cmd == helpCmd. So we have following possibilities
|
||||
//
|
||||
// 1 $ app
|
||||
// 2 $ app help
|
||||
// 3 $ app foo
|
||||
// 4 $ app help foo
|
||||
// 5 $ app foo help
|
||||
|
||||
// Case 4. when executing a help command set the context to parent
|
||||
// to allow resolution of subsequent args. This will transform
|
||||
// $ app help foo
|
||||
// to
|
||||
// $ app foo
|
||||
// which will then be handled as case 3
|
||||
if cCtx.Command.Name == helpName || cCtx.Command.Name == helpAlias {
|
||||
cCtx = cCtx.parentContext
|
||||
}
|
||||
|
||||
return ShowSubcommandHelp(c)
|
||||
// Case 4. $ app hello foo
|
||||
// foo is the command for which help needs to be shown
|
||||
if argsPresent {
|
||||
return ShowCommandHelp(cCtx, firstArg)
|
||||
}
|
||||
|
||||
// Case 1 & 2
|
||||
// Special case when running help on main app itself as opposed to indivdual
|
||||
// commands/subcommands
|
||||
if cCtx.parentContext.App == nil {
|
||||
_ = ShowAppHelp(cCtx)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Case 3, 5
|
||||
return ShowSubcommandHelp(cCtx)
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -59,6 +90,11 @@ var HelpPrinter helpPrinter = printHelp
|
|||
// HelpPrinterCustom is a function that writes the help output. It is used as
|
||||
// the default implementation of HelpPrinter, and may be called directly if
|
||||
// the ExtraInfo field is set on an App.
|
||||
//
|
||||
// In the default implementation, if the customFuncs argument contains a
|
||||
// "wrapAt" key, which is a function which takes no arguments and returns
|
||||
// an int, this int value will be used to produce a "wrap" function used
|
||||
// by the default template to wrap long lines.
|
||||
var HelpPrinterCustom helpPrinterCustom = printHelpCustom
|
||||
|
||||
// VersionPrinter prints the version for the App
|
||||
|
@ -71,30 +107,30 @@ func ShowAppHelpAndExit(c *Context, exitCode int) {
|
|||
}
|
||||
|
||||
// ShowAppHelp is an action that displays the help.
|
||||
func ShowAppHelp(c *Context) error {
|
||||
tpl := c.App.CustomAppHelpTemplate
|
||||
func ShowAppHelp(cCtx *Context) error {
|
||||
tpl := cCtx.App.CustomAppHelpTemplate
|
||||
if tpl == "" {
|
||||
tpl = AppHelpTemplate
|
||||
}
|
||||
|
||||
if c.App.ExtraInfo == nil {
|
||||
HelpPrinter(c.App.Writer, tpl, c.App)
|
||||
if cCtx.App.ExtraInfo == nil {
|
||||
HelpPrinter(cCtx.App.Writer, tpl, cCtx.App)
|
||||
return nil
|
||||
}
|
||||
|
||||
customAppData := func() map[string]interface{} {
|
||||
return map[string]interface{}{
|
||||
"ExtraInfo": c.App.ExtraInfo,
|
||||
"ExtraInfo": cCtx.App.ExtraInfo,
|
||||
}
|
||||
}
|
||||
HelpPrinterCustom(c.App.Writer, tpl, c.App, customAppData())
|
||||
HelpPrinterCustom(cCtx.App.Writer, tpl, cCtx.App, customAppData())
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// DefaultAppComplete prints the list of subcommands as the default app completion method
|
||||
func DefaultAppComplete(c *Context) {
|
||||
DefaultCompleteWithFlags(nil)(c)
|
||||
func DefaultAppComplete(cCtx *Context) {
|
||||
DefaultCompleteWithFlags(nil)(cCtx)
|
||||
}
|
||||
|
||||
func printCommandSuggestions(commands []*Command, writer io.Writer) {
|
||||
|
@ -102,7 +138,7 @@ func printCommandSuggestions(commands []*Command, writer io.Writer) {
|
|||
if command.Hidden {
|
||||
continue
|
||||
}
|
||||
if os.Getenv("_CLI_ZSH_AUTOCOMPLETE_HACK") == "1" {
|
||||
if strings.HasSuffix(os.Getenv("SHELL"), "zsh") {
|
||||
for _, name := range command.Names() {
|
||||
_, _ = fmt.Fprintf(writer, "%s:%s\n", name, command.Usage)
|
||||
}
|
||||
|
@ -159,23 +195,30 @@ func printFlagSuggestions(lastArg string, flags []Flag, writer io.Writer) {
|
|||
}
|
||||
}
|
||||
|
||||
func DefaultCompleteWithFlags(cmd *Command) func(c *Context) {
|
||||
return func(c *Context) {
|
||||
func DefaultCompleteWithFlags(cmd *Command) func(cCtx *Context) {
|
||||
return func(cCtx *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)
|
||||
printFlagSuggestions(lastArg, cmd.Flags, cCtx.App.Writer)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
printFlagSuggestions(lastArg, cCtx.App.Flags, cCtx.App.Writer)
|
||||
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if cmd != nil {
|
||||
printCommandSuggestions(cmd.Subcommands, c.App.Writer)
|
||||
} else {
|
||||
printCommandSuggestions(c.App.Commands, c.App.Writer)
|
||||
printCommandSuggestions(cmd.Subcommands, cCtx.App.Writer)
|
||||
return
|
||||
}
|
||||
|
||||
printCommandSuggestions(cCtx.App.Commands, cCtx.App.Writer)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -195,9 +238,19 @@ func ShowCommandHelp(ctx *Context, command string) error {
|
|||
|
||||
for _, c := range ctx.App.Commands {
|
||||
if c.HasName(command) {
|
||||
if !ctx.App.HideHelpCommand && !c.HasName(helpName) && len(c.Subcommands) != 0 {
|
||||
c.Subcommands = append(c.Subcommands, helpCommandDontUse)
|
||||
}
|
||||
if !ctx.App.HideHelp && HelpFlag != nil {
|
||||
c.appendFlag(HelpFlag)
|
||||
}
|
||||
templ := c.CustomHelpTemplate
|
||||
if templ == "" {
|
||||
templ = CommandHelpTemplate
|
||||
if len(c.Subcommands) == 0 {
|
||||
templ = CommandHelpTemplate
|
||||
} else {
|
||||
templ = SubcommandHelpTemplate
|
||||
}
|
||||
}
|
||||
|
||||
HelpPrinter(ctx.App.Writer, templ, c)
|
||||
|
@ -207,7 +260,13 @@ func ShowCommandHelp(ctx *Context, command string) error {
|
|||
}
|
||||
|
||||
if ctx.App.CommandNotFound == nil {
|
||||
return Exit(fmt.Sprintf("No help topic for '%v'", command), 3)
|
||||
errMsg := fmt.Sprintf("No help topic for '%v'", command)
|
||||
if ctx.App.Suggest {
|
||||
if suggestion := SuggestCommand(ctx.App.Commands, command); suggestion != "" {
|
||||
errMsg += ". " + suggestion
|
||||
}
|
||||
}
|
||||
return Exit(errMsg, 3)
|
||||
}
|
||||
|
||||
ctx.App.CommandNotFound(ctx, command)
|
||||
|
@ -221,32 +280,32 @@ func ShowSubcommandHelpAndExit(c *Context, exitCode int) {
|
|||
}
|
||||
|
||||
// ShowSubcommandHelp prints help for the given subcommand
|
||||
func ShowSubcommandHelp(c *Context) error {
|
||||
if c == nil {
|
||||
func ShowSubcommandHelp(cCtx *Context) error {
|
||||
if cCtx == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
if c.Command != nil {
|
||||
return ShowCommandHelp(c, c.Command.Name)
|
||||
if cCtx.Command != nil {
|
||||
return ShowCommandHelp(cCtx, cCtx.Command.Name)
|
||||
}
|
||||
|
||||
return ShowCommandHelp(c, "")
|
||||
return ShowCommandHelp(cCtx, "")
|
||||
}
|
||||
|
||||
// ShowVersion prints the version number of the App
|
||||
func ShowVersion(c *Context) {
|
||||
VersionPrinter(c)
|
||||
func ShowVersion(cCtx *Context) {
|
||||
VersionPrinter(cCtx)
|
||||
}
|
||||
|
||||
func printVersion(c *Context) {
|
||||
_, _ = fmt.Fprintf(c.App.Writer, "%v version %v\n", c.App.Name, c.App.Version)
|
||||
func printVersion(cCtx *Context) {
|
||||
_, _ = fmt.Fprintf(cCtx.App.Writer, "%v version %v\n", cCtx.App.Name, cCtx.App.Version)
|
||||
}
|
||||
|
||||
// ShowCompletions prints the lists of commands within a given context
|
||||
func ShowCompletions(c *Context) {
|
||||
a := c.App
|
||||
func ShowCompletions(cCtx *Context) {
|
||||
a := cCtx.App
|
||||
if a != nil && a.BashComplete != nil {
|
||||
a.BashComplete(c)
|
||||
a.BashComplete(cCtx)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -268,18 +327,48 @@ func ShowCommandCompletions(ctx *Context, command string) {
|
|||
// The customFuncs map will be combined with a default template.FuncMap to
|
||||
// allow using arbitrary functions in template rendering.
|
||||
func printHelpCustom(out io.Writer, templ string, data interface{}, customFuncs map[string]interface{}) {
|
||||
|
||||
const maxLineLength = 10000
|
||||
|
||||
funcMap := template.FuncMap{
|
||||
"join": strings.Join,
|
||||
"indent": indent,
|
||||
"nindent": nindent,
|
||||
"trim": strings.TrimSpace,
|
||||
"join": strings.Join,
|
||||
"subtract": subtract,
|
||||
"indent": indent,
|
||||
"nindent": nindent,
|
||||
"trim": strings.TrimSpace,
|
||||
"wrap": func(input string, offset int) string { return wrap(input, offset, maxLineLength) },
|
||||
"offset": offset,
|
||||
"offsetCommands": offsetCommands,
|
||||
}
|
||||
|
||||
if customFuncs["wrapAt"] != nil {
|
||||
if wa, ok := customFuncs["wrapAt"]; ok {
|
||||
if waf, ok := wa.(func() int); ok {
|
||||
wrapAt := waf()
|
||||
customFuncs["wrap"] = func(input string, offset int) string {
|
||||
return wrap(input, offset, wrapAt)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for key, value := range customFuncs {
|
||||
funcMap[key] = value
|
||||
}
|
||||
|
||||
w := tabwriter.NewWriter(out, 1, 8, 2, ' ', 0)
|
||||
t := template.Must(template.New("help").Funcs(funcMap).Parse(templ))
|
||||
t.New("helpNameTemplate").Parse(helpNameTemplate)
|
||||
t.New("usageTemplate").Parse(usageTemplate)
|
||||
t.New("descriptionTemplate").Parse(descriptionTemplate)
|
||||
t.New("visibleCommandTemplate").Parse(visibleCommandTemplate)
|
||||
t.New("copyrightTemplate").Parse(copyrightTemplate)
|
||||
t.New("versionTemplate").Parse(versionTemplate)
|
||||
t.New("visibleFlagCategoryTemplate").Parse(visibleFlagCategoryTemplate)
|
||||
t.New("visibleFlagTemplate").Parse(visibleFlagTemplate)
|
||||
t.New("visibleGlobalFlagCategoryTemplate").Parse(strings.Replace(visibleFlagCategoryTemplate, "OPTIONS", "GLOBAL OPTIONS", -1))
|
||||
t.New("authorsTemplate").Parse(authorsTemplate)
|
||||
t.New("visibleCommandCategoryTemplate").Parse(visibleCommandCategoryTemplate)
|
||||
|
||||
err := t.Execute(w, data)
|
||||
if err != nil {
|
||||
|
@ -297,20 +386,20 @@ func printHelp(out io.Writer, templ string, data interface{}) {
|
|||
HelpPrinterCustom(out, templ, data, nil)
|
||||
}
|
||||
|
||||
func checkVersion(c *Context) bool {
|
||||
func checkVersion(cCtx *Context) bool {
|
||||
found := false
|
||||
for _, name := range VersionFlag.Names() {
|
||||
if c.Bool(name) {
|
||||
if cCtx.Bool(name) {
|
||||
found = true
|
||||
}
|
||||
}
|
||||
return found
|
||||
}
|
||||
|
||||
func checkHelp(c *Context) bool {
|
||||
func checkHelp(cCtx *Context) bool {
|
||||
found := false
|
||||
for _, name := range HelpFlag.Names() {
|
||||
if c.Bool(name) {
|
||||
if cCtx.Bool(name) {
|
||||
found = true
|
||||
}
|
||||
}
|
||||
|
@ -326,9 +415,9 @@ func checkCommandHelp(c *Context, name string) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
func checkSubcommandHelp(c *Context) bool {
|
||||
if c.Bool("h") || c.Bool("help") {
|
||||
_ = ShowSubcommandHelp(c)
|
||||
func checkSubcommandHelp(cCtx *Context) bool {
|
||||
if cCtx.Bool("h") || cCtx.Bool("help") {
|
||||
_ = ShowSubcommandHelp(cCtx)
|
||||
return true
|
||||
}
|
||||
|
||||
|
@ -350,20 +439,20 @@ func checkShellCompleteFlag(a *App, arguments []string) (bool, []string) {
|
|||
return true, arguments[:pos]
|
||||
}
|
||||
|
||||
func checkCompletions(c *Context) bool {
|
||||
if !c.shellComplete {
|
||||
func checkCompletions(cCtx *Context) bool {
|
||||
if !cCtx.shellComplete {
|
||||
return false
|
||||
}
|
||||
|
||||
if args := c.Args(); args.Present() {
|
||||
if args := cCtx.Args(); args.Present() {
|
||||
name := args.First()
|
||||
if cmd := c.App.Command(name); cmd != nil {
|
||||
if cmd := cCtx.App.Command(name); cmd != nil {
|
||||
// let the command handle the completion
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
ShowCompletions(c)
|
||||
ShowCompletions(cCtx)
|
||||
return true
|
||||
}
|
||||
|
||||
|
@ -376,6 +465,10 @@ func checkCommandCompletions(c *Context, name string) bool {
|
|||
return true
|
||||
}
|
||||
|
||||
func subtract(a, b int) int {
|
||||
return a - b
|
||||
}
|
||||
|
||||
func indent(spaces int, v string) string {
|
||||
pad := strings.Repeat(" ", spaces)
|
||||
return pad + strings.Replace(v, "\n", "\n"+pad, -1)
|
||||
|
@ -384,3 +477,83 @@ func indent(spaces int, v string) string {
|
|||
func nindent(spaces int, v string) string {
|
||||
return "\n" + indent(spaces, v)
|
||||
}
|
||||
|
||||
func wrap(input string, offset int, wrapAt int) string {
|
||||
var ss []string
|
||||
|
||||
lines := strings.Split(input, "\n")
|
||||
|
||||
padding := strings.Repeat(" ", offset)
|
||||
|
||||
for i, line := range lines {
|
||||
if line == "" {
|
||||
ss = append(ss, line)
|
||||
} else {
|
||||
wrapped := wrapLine(line, offset, wrapAt, padding)
|
||||
if i == 0 {
|
||||
ss = append(ss, wrapped)
|
||||
} else {
|
||||
ss = append(ss, padding+wrapped)
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return strings.Join(ss, "\n")
|
||||
}
|
||||
|
||||
func wrapLine(input string, offset int, wrapAt int, padding string) string {
|
||||
if wrapAt <= offset || len(input) <= wrapAt-offset {
|
||||
return input
|
||||
}
|
||||
|
||||
lineWidth := wrapAt - offset
|
||||
words := strings.Fields(input)
|
||||
if len(words) == 0 {
|
||||
return input
|
||||
}
|
||||
|
||||
wrapped := words[0]
|
||||
spaceLeft := lineWidth - len(wrapped)
|
||||
for _, word := range words[1:] {
|
||||
if len(word)+1 > spaceLeft {
|
||||
wrapped += "\n" + padding + word
|
||||
spaceLeft = lineWidth - len(word)
|
||||
} else {
|
||||
wrapped += " " + word
|
||||
spaceLeft -= 1 + len(word)
|
||||
}
|
||||
}
|
||||
|
||||
return wrapped
|
||||
}
|
||||
|
||||
func offset(input string, fixed int) int {
|
||||
return len(input) + fixed
|
||||
}
|
||||
|
||||
// this function tries to find the max width of the names column
|
||||
// so say we have the following rows for help
|
||||
//
|
||||
// foo1, foo2, foo3 some string here
|
||||
// bar1, b2 some other string here
|
||||
//
|
||||
// We want to offset the 2nd row usage by some amount so that everything
|
||||
// is aligned
|
||||
//
|
||||
// foo1, foo2, foo3 some string here
|
||||
// bar1, b2 some other string here
|
||||
//
|
||||
// to find that offset we find the length of all the rows and use the max
|
||||
// to calculate the offset
|
||||
func offsetCommands(cmds []*Command, fixed int) int {
|
||||
var max int = 0
|
||||
for _, cmd := range cmds {
|
||||
s := strings.Join(cmd.Names(), ", ")
|
||||
if len(s) > max {
|
||||
max = len(s)
|
||||
}
|
||||
}
|
||||
return max + fixed
|
||||
}
|
||||
|
|
5
vendor/github.com/urfave/cli/v2/mkdocs-requirements.txt
generated
vendored
Normal file
5
vendor/github.com/urfave/cli/v2/mkdocs-requirements.txt
generated
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
mkdocs-git-revision-date-localized-plugin~=1.0
|
||||
mkdocs-material-extensions~=1.0
|
||||
mkdocs-material~=8.2
|
||||
mkdocs~=1.3
|
||||
pygments~=2.12
|
107
vendor/github.com/urfave/cli/v2/mkdocs.yml
generated
vendored
Normal file
107
vendor/github.com/urfave/cli/v2/mkdocs.yml
generated
vendored
Normal file
|
@ -0,0 +1,107 @@
|
|||
# NOTE: the mkdocs dependencies will need to be installed out of
|
||||
# band until this whole thing gets more automated:
|
||||
#
|
||||
# pip install -r mkdocs-requirements.txt
|
||||
#
|
||||
|
||||
site_name: urfave/cli
|
||||
site_url: https://cli.urfave.org/
|
||||
repo_url: https://github.com/urfave/cli
|
||||
edit_uri: edit/main/docs/
|
||||
nav:
|
||||
- Home:
|
||||
- Welcome: index.md
|
||||
- Contributing: CONTRIBUTING.md
|
||||
- Code of Conduct: CODE_OF_CONDUCT.md
|
||||
- Releasing: RELEASING.md
|
||||
- Security: SECURITY.md
|
||||
- Migrate v1 to v2: migrate-v1-to-v2.md
|
||||
- v2 Manual:
|
||||
- Getting Started: v2/getting-started.md
|
||||
- Migrating From Older Releases: v2/migrating-from-older-releases.md
|
||||
- Examples:
|
||||
- Greet: v2/examples/greet.md
|
||||
- Arguments: v2/examples/arguments.md
|
||||
- Flags: v2/examples/flags.md
|
||||
- Subcommands: v2/examples/subcommands.md
|
||||
- Subcommands Categories: v2/examples/subcommands-categories.md
|
||||
- Exit Codes: v2/examples/exit-codes.md
|
||||
- Combining Short Options: v2/examples/combining-short-options.md
|
||||
- Bash Completions: v2/examples/bash-completions.md
|
||||
- Generated Help Text: v2/examples/generated-help-text.md
|
||||
- Version Flag: v2/examples/version-flag.md
|
||||
- Timestamp Flag: v2/examples/timestamp-flag.md
|
||||
- Suggestions: v2/examples/suggestions.md
|
||||
- Full API Example: v2/examples/full-api-example.md
|
||||
- v1 Manual:
|
||||
- Getting Started: v1/getting-started.md
|
||||
- Migrating to v2: v1/migrating-to-v2.md
|
||||
- Examples:
|
||||
- Greet: v1/examples/greet.md
|
||||
- Arguments: v1/examples/arguments.md
|
||||
- Flags: v1/examples/flags.md
|
||||
- Subcommands: v1/examples/subcommands.md
|
||||
- Subcommands (Categories): v1/examples/subcommands-categories.md
|
||||
- Exit Codes: v1/examples/exit-codes.md
|
||||
- Combining Short Options: v1/examples/combining-short-options.md
|
||||
- Bash Completions: v1/examples/bash-completions.md
|
||||
- Generated Help Text: v1/examples/generated-help-text.md
|
||||
- Version Flag: v1/examples/version-flag.md
|
||||
|
||||
theme:
|
||||
name: material
|
||||
palette:
|
||||
- media: "(prefers-color-scheme: light)"
|
||||
scheme: default
|
||||
toggle:
|
||||
icon: material/brightness-4
|
||||
name: dark mode
|
||||
- media: "(prefers-color-scheme: dark)"
|
||||
scheme: slate
|
||||
toggle:
|
||||
icon: material/brightness-7
|
||||
name: light mode
|
||||
features:
|
||||
- content.code.annotate
|
||||
- navigation.top
|
||||
- navigation.instant
|
||||
- navigation.expand
|
||||
- navigation.sections
|
||||
- navigation.tabs
|
||||
- navigation.tabs.sticky
|
||||
plugins:
|
||||
- git-revision-date-localized
|
||||
- search
|
||||
- tags
|
||||
# NOTE: this is the recommended configuration from
|
||||
# https://squidfunk.github.io/mkdocs-material/setup/extensions/#recommended-configuration
|
||||
markdown_extensions:
|
||||
- abbr
|
||||
- admonition
|
||||
- attr_list
|
||||
- def_list
|
||||
- footnotes
|
||||
- meta
|
||||
- md_in_html
|
||||
- toc:
|
||||
permalink: true
|
||||
- pymdownx.arithmatex:
|
||||
generic: true
|
||||
- pymdownx.betterem:
|
||||
smart_enable: all
|
||||
- pymdownx.caret
|
||||
- pymdownx.details
|
||||
- pymdownx.emoji:
|
||||
emoji_index: !!python/name:materialx.emoji.twemoji
|
||||
emoji_generator: !!python/name:materialx.emoji.to_svg
|
||||
- pymdownx.highlight
|
||||
- pymdownx.inlinehilite
|
||||
- pymdownx.keys
|
||||
- pymdownx.mark
|
||||
- pymdownx.smartsymbols
|
||||
- pymdownx.superfences
|
||||
- pymdownx.tabbed:
|
||||
alternate_style: true
|
||||
- pymdownx.tasklist:
|
||||
custom_checkbox: true
|
||||
- pymdownx.tilde
|
30
vendor/github.com/urfave/cli/v2/parse.go
generated
vendored
30
vendor/github.com/urfave/cli/v2/parse.go
generated
vendored
|
@ -26,9 +26,8 @@ func parseIter(set *flag.FlagSet, ip iterativeParser, args []string, shellComple
|
|||
return err
|
||||
}
|
||||
|
||||
errStr := err.Error()
|
||||
trimmed := strings.TrimPrefix(errStr, "flag provided but not defined: -")
|
||||
if errStr == trimmed {
|
||||
trimmed, trimErr := flagFromError(err)
|
||||
if trimErr != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -47,7 +46,10 @@ func parseIter(set *flag.FlagSet, ip iterativeParser, args []string, shellComple
|
|||
}
|
||||
|
||||
// swap current argument with the split version
|
||||
args = append(args[:i], append(shortOpts, args[i+1:]...)...)
|
||||
// do not include args that parsed correctly so far as it would
|
||||
// trigger Value.Set() on those args and would result in
|
||||
// duplicates for slice type flags
|
||||
args = append(shortOpts, args[i+1:]...)
|
||||
argsWereSplit = true
|
||||
break
|
||||
}
|
||||
|
@ -57,16 +59,22 @@ func parseIter(set *flag.FlagSet, ip iterativeParser, args []string, shellComple
|
|||
if !argsWereSplit {
|
||||
return err
|
||||
}
|
||||
|
||||
// Since custom parsing failed, replace the flag set before retrying
|
||||
newSet, err := ip.newFlagSet()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*set = *newSet
|
||||
}
|
||||
}
|
||||
|
||||
const providedButNotDefinedErrMsg = "flag provided but not defined: -"
|
||||
|
||||
// flagFromError tries to parse a provided flag from an error message. If the
|
||||
// parsing fials, it returns the input error and an empty string
|
||||
func flagFromError(err error) (string, error) {
|
||||
errStr := err.Error()
|
||||
trimmed := strings.TrimPrefix(errStr, providedButNotDefinedErrMsg)
|
||||
if errStr == trimmed {
|
||||
return "", err
|
||||
}
|
||||
return trimmed, nil
|
||||
}
|
||||
|
||||
func splitShortOptions(set *flag.FlagSet, arg string) []string {
|
||||
shortFlagsExist := func(s string) bool {
|
||||
for _, c := range s[1:] {
|
||||
|
|
293
vendor/github.com/urfave/cli/v2/sliceflag.go
generated
vendored
Normal file
293
vendor/github.com/urfave/cli/v2/sliceflag.go
generated
vendored
Normal file
|
@ -0,0 +1,293 @@
|
|||
//go:build go1.18
|
||||
// +build go1.18
|
||||
|
||||
package cli
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
type (
|
||||
// SliceFlag extends implementations like StringSliceFlag and IntSliceFlag with support for using slices directly,
|
||||
// as Value and/or Destination.
|
||||
// See also SliceFlagTarget, MultiStringFlag, MultiFloat64Flag, MultiInt64Flag, MultiIntFlag.
|
||||
SliceFlag[T SliceFlagTarget[E], S ~[]E, E any] struct {
|
||||
Target T
|
||||
Value S
|
||||
Destination *S
|
||||
}
|
||||
|
||||
// SliceFlagTarget models a target implementation for use with SliceFlag.
|
||||
// The three methods, SetValue, SetDestination, and GetDestination, are necessary to propagate Value and
|
||||
// Destination, where Value is propagated inwards (initially), and Destination is propagated outwards (on every
|
||||
// update).
|
||||
SliceFlagTarget[E any] interface {
|
||||
Flag
|
||||
RequiredFlag
|
||||
DocGenerationFlag
|
||||
VisibleFlag
|
||||
CategorizableFlag
|
||||
|
||||
// SetValue should propagate the given slice to the target, ideally as a new value.
|
||||
// Note that a nil slice should nil/clear any existing value (modelled as ~[]E).
|
||||
SetValue(slice []E)
|
||||
// SetDestination should propagate the given slice to the target, ideally as a new value.
|
||||
// Note that a nil slice should nil/clear any existing value (modelled as ~*[]E).
|
||||
SetDestination(slice []E)
|
||||
// GetDestination should return the current value referenced by any destination, or nil if nil/unset.
|
||||
GetDestination() []E
|
||||
}
|
||||
|
||||
// MultiStringFlag extends StringSliceFlag with support for using slices directly, as Value and/or Destination.
|
||||
// See also SliceFlag.
|
||||
MultiStringFlag = SliceFlag[*StringSliceFlag, []string, string]
|
||||
|
||||
// MultiFloat64Flag extends Float64SliceFlag with support for using slices directly, as Value and/or Destination.
|
||||
// See also SliceFlag.
|
||||
MultiFloat64Flag = SliceFlag[*Float64SliceFlag, []float64, float64]
|
||||
|
||||
// MultiInt64Flag extends Int64SliceFlag with support for using slices directly, as Value and/or Destination.
|
||||
// See also SliceFlag.
|
||||
MultiInt64Flag = SliceFlag[*Int64SliceFlag, []int64, int64]
|
||||
|
||||
// MultiIntFlag extends IntSliceFlag with support for using slices directly, as Value and/or Destination.
|
||||
// See also SliceFlag.
|
||||
MultiIntFlag = SliceFlag[*IntSliceFlag, []int, int]
|
||||
|
||||
flagValueHook struct {
|
||||
value Generic
|
||||
hook func()
|
||||
}
|
||||
)
|
||||
|
||||
var (
|
||||
// compile time assertions
|
||||
|
||||
_ SliceFlagTarget[string] = (*StringSliceFlag)(nil)
|
||||
_ SliceFlagTarget[string] = (*SliceFlag[*StringSliceFlag, []string, string])(nil)
|
||||
_ SliceFlagTarget[string] = (*MultiStringFlag)(nil)
|
||||
_ SliceFlagTarget[float64] = (*MultiFloat64Flag)(nil)
|
||||
_ SliceFlagTarget[int64] = (*MultiInt64Flag)(nil)
|
||||
_ SliceFlagTarget[int] = (*MultiIntFlag)(nil)
|
||||
|
||||
_ Generic = (*flagValueHook)(nil)
|
||||
_ Serializer = (*flagValueHook)(nil)
|
||||
)
|
||||
|
||||
func (x *SliceFlag[T, S, E]) Apply(set *flag.FlagSet) error {
|
||||
x.Target.SetValue(x.convertSlice(x.Value))
|
||||
|
||||
destination := x.Destination
|
||||
if destination == nil {
|
||||
x.Target.SetDestination(nil)
|
||||
|
||||
return x.Target.Apply(set)
|
||||
}
|
||||
|
||||
x.Target.SetDestination(x.convertSlice(*destination))
|
||||
|
||||
return applyFlagValueHook(set, x.Target.Apply, func() {
|
||||
*destination = x.Target.GetDestination()
|
||||
})
|
||||
}
|
||||
|
||||
func (x *SliceFlag[T, S, E]) convertSlice(slice S) []E {
|
||||
result := make([]E, len(slice))
|
||||
copy(result, slice)
|
||||
return result
|
||||
}
|
||||
|
||||
func (x *SliceFlag[T, S, E]) SetValue(slice S) {
|
||||
x.Value = slice
|
||||
}
|
||||
|
||||
func (x *SliceFlag[T, S, E]) SetDestination(slice S) {
|
||||
if slice != nil {
|
||||
x.Destination = &slice
|
||||
} else {
|
||||
x.Destination = nil
|
||||
}
|
||||
}
|
||||
|
||||
func (x *SliceFlag[T, S, E]) GetDestination() S {
|
||||
if destination := x.Destination; destination != nil {
|
||||
return *destination
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *SliceFlag[T, S, E]) String() string { return x.Target.String() }
|
||||
func (x *SliceFlag[T, S, E]) Names() []string { return x.Target.Names() }
|
||||
func (x *SliceFlag[T, S, E]) IsSet() bool { return x.Target.IsSet() }
|
||||
func (x *SliceFlag[T, S, E]) IsRequired() bool { return x.Target.IsRequired() }
|
||||
func (x *SliceFlag[T, S, E]) TakesValue() bool { return x.Target.TakesValue() }
|
||||
func (x *SliceFlag[T, S, E]) GetUsage() string { return x.Target.GetUsage() }
|
||||
func (x *SliceFlag[T, S, E]) GetValue() string { return x.Target.GetValue() }
|
||||
func (x *SliceFlag[T, S, E]) GetDefaultText() string { return x.Target.GetDefaultText() }
|
||||
func (x *SliceFlag[T, S, E]) GetEnvVars() []string { return x.Target.GetEnvVars() }
|
||||
func (x *SliceFlag[T, S, E]) IsVisible() bool { return x.Target.IsVisible() }
|
||||
func (x *SliceFlag[T, S, E]) GetCategory() string { return x.Target.GetCategory() }
|
||||
|
||||
func (x *flagValueHook) Set(value string) error {
|
||||
if err := x.value.Set(value); err != nil {
|
||||
return err
|
||||
}
|
||||
x.hook()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *flagValueHook) String() string {
|
||||
// note: this is necessary due to the way Go's flag package handles defaults
|
||||
isZeroValue := func(f flag.Value, v string) bool {
|
||||
/*
|
||||
https://cs.opensource.google/go/go/+/refs/tags/go1.18.3:src/flag/flag.go;drc=2580d0e08d5e9f979b943758d3c49877fb2324cb;l=453
|
||||
|
||||
Copyright (c) 2009 The Go Authors. All rights reserved.
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following disclaimer
|
||||
in the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
* Neither the name of Google Inc. nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
// Build a zero value of the flag's Value type, and see if the
|
||||
// result of calling its String method equals the value passed in.
|
||||
// This works unless the Value type is itself an interface type.
|
||||
typ := reflect.TypeOf(f)
|
||||
var z reflect.Value
|
||||
if typ.Kind() == reflect.Pointer {
|
||||
z = reflect.New(typ.Elem())
|
||||
} else {
|
||||
z = reflect.Zero(typ)
|
||||
}
|
||||
return v == z.Interface().(flag.Value).String()
|
||||
}
|
||||
if x.value != nil {
|
||||
// only return non-empty if not the same string as returned by the zero value
|
||||
if s := x.value.String(); !isZeroValue(x.value, s) {
|
||||
return s
|
||||
}
|
||||
}
|
||||
return ``
|
||||
}
|
||||
|
||||
func (x *flagValueHook) Serialize() string {
|
||||
if value, ok := x.value.(Serializer); ok {
|
||||
return value.Serialize()
|
||||
}
|
||||
return x.String()
|
||||
}
|
||||
|
||||
// applyFlagValueHook wraps calls apply then wraps flags to call a hook function on update and after initial apply.
|
||||
func applyFlagValueHook(set *flag.FlagSet, apply func(set *flag.FlagSet) error, hook func()) error {
|
||||
if apply == nil || set == nil || hook == nil {
|
||||
panic(`invalid input`)
|
||||
}
|
||||
var tmp flag.FlagSet
|
||||
if err := apply(&tmp); err != nil {
|
||||
return err
|
||||
}
|
||||
tmp.VisitAll(func(f *flag.Flag) { set.Var(&flagValueHook{value: f.Value, hook: hook}, f.Name, f.Usage) })
|
||||
hook()
|
||||
return nil
|
||||
}
|
||||
|
||||
// newSliceFlagValue is for implementing SliceFlagTarget.SetValue and SliceFlagTarget.SetDestination.
|
||||
// It's e.g. as part of StringSliceFlag.SetValue, using the factory NewStringSlice.
|
||||
func newSliceFlagValue[R any, S ~[]E, E any](factory func(defaults ...E) *R, defaults S) *R {
|
||||
if defaults == nil {
|
||||
return nil
|
||||
}
|
||||
return factory(defaults...)
|
||||
}
|
||||
|
||||
// unwrapFlagValue strips any/all *flagValueHook wrappers.
|
||||
func unwrapFlagValue(v flag.Value) flag.Value {
|
||||
for {
|
||||
h, ok := v.(*flagValueHook)
|
||||
if !ok {
|
||||
return v
|
||||
}
|
||||
v = h.value
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: the methods below are in this file to make use of the build constraint
|
||||
|
||||
func (f *Float64SliceFlag) SetValue(slice []float64) {
|
||||
f.Value = newSliceFlagValue(NewFloat64Slice, slice)
|
||||
}
|
||||
|
||||
func (f *Float64SliceFlag) SetDestination(slice []float64) {
|
||||
f.Destination = newSliceFlagValue(NewFloat64Slice, slice)
|
||||
}
|
||||
|
||||
func (f *Float64SliceFlag) GetDestination() []float64 {
|
||||
if destination := f.Destination; destination != nil {
|
||||
return destination.Value()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *Int64SliceFlag) SetValue(slice []int64) {
|
||||
f.Value = newSliceFlagValue(NewInt64Slice, slice)
|
||||
}
|
||||
|
||||
func (f *Int64SliceFlag) SetDestination(slice []int64) {
|
||||
f.Destination = newSliceFlagValue(NewInt64Slice, slice)
|
||||
}
|
||||
|
||||
func (f *Int64SliceFlag) GetDestination() []int64 {
|
||||
if destination := f.Destination; destination != nil {
|
||||
return destination.Value()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *IntSliceFlag) SetValue(slice []int) {
|
||||
f.Value = newSliceFlagValue(NewIntSlice, slice)
|
||||
}
|
||||
|
||||
func (f *IntSliceFlag) SetDestination(slice []int) {
|
||||
f.Destination = newSliceFlagValue(NewIntSlice, slice)
|
||||
}
|
||||
|
||||
func (f *IntSliceFlag) GetDestination() []int {
|
||||
if destination := f.Destination; destination != nil {
|
||||
return destination.Value()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *StringSliceFlag) SetValue(slice []string) {
|
||||
f.Value = newSliceFlagValue(NewStringSlice, slice)
|
||||
}
|
||||
|
||||
func (f *StringSliceFlag) SetDestination(slice []string) {
|
||||
f.Destination = newSliceFlagValue(NewStringSlice, slice)
|
||||
}
|
||||
|
||||
func (f *StringSliceFlag) GetDestination() []string {
|
||||
if destination := f.Destination; destination != nil {
|
||||
return destination.Value()
|
||||
}
|
||||
return nil
|
||||
}
|
10
vendor/github.com/urfave/cli/v2/sliceflag_pre18.go
generated
vendored
Normal file
10
vendor/github.com/urfave/cli/v2/sliceflag_pre18.go
generated
vendored
Normal file
|
@ -0,0 +1,10 @@
|
|||
//go:build !go1.18
|
||||
// +build !go1.18
|
||||
|
||||
package cli
|
||||
|
||||
import (
|
||||
"flag"
|
||||
)
|
||||
|
||||
func unwrapFlagValue(v flag.Value) flag.Value { return v }
|
60
vendor/github.com/urfave/cli/v2/suggestions.go
generated
vendored
Normal file
60
vendor/github.com/urfave/cli/v2/suggestions.go
generated
vendored
Normal file
|
@ -0,0 +1,60 @@
|
|||
package cli
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/xrash/smetrics"
|
||||
)
|
||||
|
||||
func jaroWinkler(a, b string) float64 {
|
||||
// magic values are from https://github.com/xrash/smetrics/blob/039620a656736e6ad994090895784a7af15e0b80/jaro-winkler.go#L8
|
||||
const (
|
||||
boostThreshold = 0.7
|
||||
prefixSize = 4
|
||||
)
|
||||
return smetrics.JaroWinkler(a, b, boostThreshold, prefixSize)
|
||||
}
|
||||
|
||||
func suggestFlag(flags []Flag, provided string, hideHelp bool) string {
|
||||
distance := 0.0
|
||||
suggestion := ""
|
||||
|
||||
for _, flag := range flags {
|
||||
flagNames := flag.Names()
|
||||
if !hideHelp {
|
||||
flagNames = append(flagNames, HelpFlag.Names()...)
|
||||
}
|
||||
for _, name := range flagNames {
|
||||
newDistance := jaroWinkler(name, provided)
|
||||
if newDistance > distance {
|
||||
distance = newDistance
|
||||
suggestion = name
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(suggestion) == 1 {
|
||||
suggestion = "-" + suggestion
|
||||
} else if len(suggestion) > 1 {
|
||||
suggestion = "--" + suggestion
|
||||
}
|
||||
|
||||
return suggestion
|
||||
}
|
||||
|
||||
// suggestCommand takes a list of commands and a provided string to suggest a
|
||||
// command name
|
||||
func suggestCommand(commands []*Command, provided string) (suggestion string) {
|
||||
distance := 0.0
|
||||
for _, command := range commands {
|
||||
for _, name := range append(command.Names(), helpName, helpAlias) {
|
||||
newDistance := jaroWinkler(name, provided)
|
||||
if newDistance > distance {
|
||||
distance = newDistance
|
||||
suggestion = name
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return fmt.Sprintf(SuggestDidYouMeanTemplate, suggestion)
|
||||
}
|
95
vendor/github.com/urfave/cli/v2/template.go
generated
vendored
95
vendor/github.com/urfave/cli/v2/template.go
generated
vendored
|
@ -1,82 +1,103 @@
|
|||
package cli
|
||||
|
||||
var helpNameTemplate = `{{$v := offset .HelpName 6}}{{wrap .HelpName 3}}{{if .Usage}} - {{wrap .Usage $v}}{{end}}`
|
||||
var usageTemplate = `{{if .UsageText}}{{wrap .UsageText 3}}{{else}}{{.HelpName}}{{if .VisibleFlags}} [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{end}}`
|
||||
var descriptionTemplate = `{{wrap .Description 3}}`
|
||||
var authorsTemplate = `{{with $length := len .Authors}}{{if ne 1 $length}}S{{end}}{{end}}:
|
||||
{{range $index, $author := .Authors}}{{if $index}}
|
||||
{{end}}{{$author}}{{end}}`
|
||||
var visibleCommandTemplate = `{{ $cv := offsetCommands .VisibleCommands 5}}{{range .VisibleCommands}}
|
||||
{{$s := join .Names ", "}}{{$s}}{{ $sp := subtract $cv (offset $s 3) }}{{ indent $sp ""}}{{wrap .Usage $cv}}{{end}}`
|
||||
var visibleCommandCategoryTemplate = `{{range .VisibleCategories}}{{if .Name}}
|
||||
{{.Name}}:{{range .VisibleCommands}}
|
||||
{{join .Names ", "}}{{"\t"}}{{.Usage}}{{end}}{{else}}{{template "visibleCommandTemplate" .}}{{end}}{{end}}`
|
||||
var visibleFlagCategoryTemplate = `{{range .VisibleFlagCategories}}
|
||||
{{if .Name}}{{.Name}}
|
||||
|
||||
{{end}}{{$flglen := len .Flags}}{{range $i, $e := .Flags}}{{if eq (subtract $flglen $i) 1}}{{$e}}
|
||||
{{else}}{{$e}}
|
||||
{{end}}{{end}}{{end}}`
|
||||
|
||||
var visibleFlagTemplate = `{{range $i, $e := .VisibleFlags}}
|
||||
{{wrap $e.String 6}}{{end}}`
|
||||
|
||||
var versionTemplate = `{{if .Version}}{{if not .HideVersion}}
|
||||
|
||||
VERSION:
|
||||
{{.Version}}{{end}}{{end}}`
|
||||
|
||||
var copyrightTemplate = `{{wrap .Copyright 3}}`
|
||||
|
||||
// AppHelpTemplate is the text template for the Default help topic.
|
||||
// cli.go uses text/template to render templates. You can
|
||||
// render custom help text by setting this variable.
|
||||
var AppHelpTemplate = `NAME:
|
||||
{{.Name}}{{if .Usage}} - {{.Usage}}{{end}}
|
||||
{{template "helpNameTemplate" .}}
|
||||
|
||||
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}}{{wrap .UsageText 3}}{{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}}
|
||||
|
||||
DESCRIPTION:
|
||||
{{.Description | nindent 3 | trim}}{{end}}{{if len .Authors}}
|
||||
{{template "descriptionTemplate" .}}{{end}}
|
||||
{{- if len .Authors}}
|
||||
|
||||
AUTHOR{{with $length := len .Authors}}{{if ne 1 $length}}S{{end}}{{end}}:
|
||||
{{range $index, $author := .Authors}}{{if $index}}
|
||||
{{end}}{{$author}}{{end}}{{end}}{{if .VisibleCommands}}
|
||||
AUTHOR{{template "authorsTemplate" .}}{{end}}{{if .VisibleCommands}}
|
||||
|
||||
COMMANDS:{{range .VisibleCategories}}{{if .Name}}
|
||||
{{.Name}}:{{range .VisibleCommands}}
|
||||
{{join .Names ", "}}{{"\t"}}{{.Usage}}{{end}}{{else}}{{range .VisibleCommands}}
|
||||
{{join .Names ", "}}{{"\t"}}{{.Usage}}{{end}}{{end}}{{end}}{{end}}{{if .VisibleFlags}}
|
||||
COMMANDS:{{template "visibleCommandCategoryTemplate" .}}{{end}}{{if .VisibleFlagCategories}}
|
||||
|
||||
GLOBAL OPTIONS:
|
||||
{{range $index, $option := .VisibleFlags}}{{if $index}}
|
||||
{{end}}{{$option}}{{end}}{{end}}{{if .Copyright}}
|
||||
GLOBAL OPTIONS:{{template "visibleFlagCategoryTemplate" .}}{{else if .VisibleFlags}}
|
||||
|
||||
GLOBAL OPTIONS:{{template "visibleFlagTemplate" .}}{{end}}{{if .Copyright}}
|
||||
|
||||
COPYRIGHT:
|
||||
{{.Copyright}}{{end}}
|
||||
{{template "copyrightTemplate" .}}{{end}}
|
||||
`
|
||||
|
||||
// CommandHelpTemplate is the text template for the command help topic.
|
||||
// cli.go uses text/template to render templates. You can
|
||||
// render custom help text by setting this variable.
|
||||
var CommandHelpTemplate = `NAME:
|
||||
{{.HelpName}} - {{.Usage}}
|
||||
{{template "helpNameTemplate" .}}
|
||||
|
||||
USAGE:
|
||||
{{if .UsageText}}{{.UsageText}}{{else}}{{.HelpName}}{{if .VisibleFlags}} [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{end}}{{if .Category}}
|
||||
{{template "usageTemplate" .}}{{if .Category}}
|
||||
|
||||
CATEGORY:
|
||||
{{.Category}}{{end}}{{if .Description}}
|
||||
|
||||
DESCRIPTION:
|
||||
{{.Description | nindent 3 | trim}}{{end}}{{if .VisibleFlags}}
|
||||
{{template "descriptionTemplate" .}}{{end}}{{if .VisibleFlagCategories}}
|
||||
|
||||
OPTIONS:
|
||||
{{range .VisibleFlags}}{{.}}
|
||||
{{end}}{{end}}
|
||||
OPTIONS:{{template "visibleFlagCategoryTemplate" .}}{{else if .VisibleFlags}}
|
||||
|
||||
OPTIONS:{{template "visibleFlagTemplate" .}}{{end}}
|
||||
`
|
||||
|
||||
// SubcommandHelpTemplate is the text template for the subcommand help topic.
|
||||
// cli.go uses text/template to render templates. You can
|
||||
// render custom help text by setting this variable.
|
||||
var SubcommandHelpTemplate = `NAME:
|
||||
{{.HelpName}} - {{.Usage}}
|
||||
{{template "helpNameTemplate" .}}
|
||||
|
||||
USAGE:
|
||||
{{if .UsageText}}{{.UsageText}}{{else}}{{.HelpName}} command{{if .VisibleFlags}} [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{end}}{{if .Description}}
|
||||
{{if .UsageText}}{{wrap .UsageText 3}}{{else}}{{.HelpName}} command{{if .VisibleFlags}} [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{end}}{{if .Description}}
|
||||
|
||||
DESCRIPTION:
|
||||
{{.Description | nindent 3 | trim}}{{end}}
|
||||
{{template "descriptionTemplate" .}}{{end}}{{if .VisibleCommands}}
|
||||
|
||||
COMMANDS:{{range .VisibleCategories}}{{if .Name}}
|
||||
{{.Name}}:{{range .VisibleCommands}}
|
||||
{{join .Names ", "}}{{"\t"}}{{.Usage}}{{end}}{{else}}{{range .VisibleCommands}}
|
||||
{{join .Names ", "}}{{"\t"}}{{.Usage}}{{end}}{{end}}{{end}}{{if .VisibleFlags}}
|
||||
COMMANDS:{{template "visibleCommandTemplate" .}}{{end}}{{if .VisibleFlagCategories}}
|
||||
|
||||
OPTIONS:
|
||||
{{range .VisibleFlags}}{{.}}
|
||||
{{end}}{{end}}
|
||||
OPTIONS:{{template "visibleFlagCategoryTemplate" .}}{{else if .VisibleFlags}}
|
||||
|
||||
OPTIONS:{{template "visibleFlagTemplate" .}}{{end}}
|
||||
`
|
||||
|
||||
var MarkdownDocTemplate = `% {{ .App.Name }} 8
|
||||
var MarkdownDocTemplate = `{{if gt .SectionNum 0}}% {{ .App.Name }} {{ .SectionNum }}
|
||||
|
||||
# NAME
|
||||
{{end}}# NAME
|
||||
|
||||
{{ .App.Name }}{{ if .App.Usage }} - {{ .App.Usage }}{{ end }}
|
||||
|
||||
|
@ -86,16 +107,18 @@ var MarkdownDocTemplate = `% {{ .App.Name }} 8
|
|||
{{ 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 }}
|
||||
|
|
798
vendor/github.com/urfave/cli/v2/zz_generated.flags.go
generated
vendored
Normal file
798
vendor/github.com/urfave/cli/v2/zz_generated.flags.go
generated
vendored
Normal file
|
@ -0,0 +1,798 @@
|
|||
// WARNING: this file is generated. DO NOT EDIT
|
||||
|
||||
package cli
|
||||
|
||||
import "time"
|
||||
|
||||
// Float64SliceFlag is a flag with type *Float64Slice
|
||||
type Float64SliceFlag struct {
|
||||
Name string
|
||||
|
||||
Category string
|
||||
DefaultText string
|
||||
FilePath string
|
||||
Usage string
|
||||
|
||||
Required bool
|
||||
Hidden bool
|
||||
HasBeenSet bool
|
||||
|
||||
Value *Float64Slice
|
||||
Destination *Float64Slice
|
||||
|
||||
Aliases []string
|
||||
EnvVars []string
|
||||
|
||||
Action func(*Context, []float64) error
|
||||
}
|
||||
|
||||
// IsSet returns whether or not the flag has been set through env or file
|
||||
func (f *Float64SliceFlag) IsSet() bool {
|
||||
return f.HasBeenSet
|
||||
}
|
||||
|
||||
// Names returns the names of the flag
|
||||
func (f *Float64SliceFlag) Names() []string {
|
||||
return FlagNames(f.Name, f.Aliases)
|
||||
}
|
||||
|
||||
// IsRequired returns whether or not the flag is required
|
||||
func (f *Float64SliceFlag) IsRequired() bool {
|
||||
return f.Required
|
||||
}
|
||||
|
||||
// IsVisible returns true if the flag is not hidden, otherwise false
|
||||
func (f *Float64SliceFlag) IsVisible() bool {
|
||||
return !f.Hidden
|
||||
}
|
||||
|
||||
// GenericFlag is a flag with type Generic
|
||||
type GenericFlag struct {
|
||||
Name string
|
||||
|
||||
Category string
|
||||
DefaultText string
|
||||
FilePath string
|
||||
Usage string
|
||||
|
||||
Required bool
|
||||
Hidden bool
|
||||
HasBeenSet bool
|
||||
|
||||
Value Generic
|
||||
Destination Generic
|
||||
|
||||
Aliases []string
|
||||
EnvVars []string
|
||||
|
||||
TakesFile bool
|
||||
|
||||
Action func(*Context, interface{}) error
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value (for usage defaults)
|
||||
func (f *GenericFlag) String() string {
|
||||
return FlagStringer(f)
|
||||
}
|
||||
|
||||
// IsSet returns whether or not the flag has been set through env or file
|
||||
func (f *GenericFlag) IsSet() bool {
|
||||
return f.HasBeenSet
|
||||
}
|
||||
|
||||
// Names returns the names of the flag
|
||||
func (f *GenericFlag) Names() []string {
|
||||
return FlagNames(f.Name, f.Aliases)
|
||||
}
|
||||
|
||||
// IsRequired returns whether or not the flag is required
|
||||
func (f *GenericFlag) IsRequired() bool {
|
||||
return f.Required
|
||||
}
|
||||
|
||||
// IsVisible returns true if the flag is not hidden, otherwise false
|
||||
func (f *GenericFlag) IsVisible() bool {
|
||||
return !f.Hidden
|
||||
}
|
||||
|
||||
// Int64SliceFlag is a flag with type *Int64Slice
|
||||
type Int64SliceFlag struct {
|
||||
Name string
|
||||
|
||||
Category string
|
||||
DefaultText string
|
||||
FilePath string
|
||||
Usage string
|
||||
|
||||
Required bool
|
||||
Hidden bool
|
||||
HasBeenSet bool
|
||||
|
||||
Value *Int64Slice
|
||||
Destination *Int64Slice
|
||||
|
||||
Aliases []string
|
||||
EnvVars []string
|
||||
|
||||
Action func(*Context, []int64) error
|
||||
}
|
||||
|
||||
// IsSet returns whether or not the flag has been set through env or file
|
||||
func (f *Int64SliceFlag) IsSet() bool {
|
||||
return f.HasBeenSet
|
||||
}
|
||||
|
||||
// Names returns the names of the flag
|
||||
func (f *Int64SliceFlag) Names() []string {
|
||||
return FlagNames(f.Name, f.Aliases)
|
||||
}
|
||||
|
||||
// IsRequired returns whether or not the flag is required
|
||||
func (f *Int64SliceFlag) IsRequired() bool {
|
||||
return f.Required
|
||||
}
|
||||
|
||||
// IsVisible returns true if the flag is not hidden, otherwise false
|
||||
func (f *Int64SliceFlag) IsVisible() bool {
|
||||
return !f.Hidden
|
||||
}
|
||||
|
||||
// IntSliceFlag is a flag with type *IntSlice
|
||||
type IntSliceFlag struct {
|
||||
Name string
|
||||
|
||||
Category string
|
||||
DefaultText string
|
||||
FilePath string
|
||||
Usage string
|
||||
|
||||
Required bool
|
||||
Hidden bool
|
||||
HasBeenSet bool
|
||||
|
||||
Value *IntSlice
|
||||
Destination *IntSlice
|
||||
|
||||
Aliases []string
|
||||
EnvVars []string
|
||||
|
||||
Action func(*Context, []int) error
|
||||
}
|
||||
|
||||
// IsSet returns whether or not the flag has been set through env or file
|
||||
func (f *IntSliceFlag) IsSet() bool {
|
||||
return f.HasBeenSet
|
||||
}
|
||||
|
||||
// Names returns the names of the flag
|
||||
func (f *IntSliceFlag) Names() []string {
|
||||
return FlagNames(f.Name, f.Aliases)
|
||||
}
|
||||
|
||||
// IsRequired returns whether or not the flag is required
|
||||
func (f *IntSliceFlag) IsRequired() bool {
|
||||
return f.Required
|
||||
}
|
||||
|
||||
// IsVisible returns true if the flag is not hidden, otherwise false
|
||||
func (f *IntSliceFlag) IsVisible() bool {
|
||||
return !f.Hidden
|
||||
}
|
||||
|
||||
// PathFlag is a flag with type Path
|
||||
type PathFlag struct {
|
||||
Name string
|
||||
|
||||
Category string
|
||||
DefaultText string
|
||||
FilePath string
|
||||
Usage string
|
||||
|
||||
Required bool
|
||||
Hidden bool
|
||||
HasBeenSet bool
|
||||
|
||||
Value Path
|
||||
Destination *Path
|
||||
|
||||
Aliases []string
|
||||
EnvVars []string
|
||||
|
||||
TakesFile bool
|
||||
|
||||
Action func(*Context, Path) error
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value (for usage defaults)
|
||||
func (f *PathFlag) String() string {
|
||||
return FlagStringer(f)
|
||||
}
|
||||
|
||||
// IsSet returns whether or not the flag has been set through env or file
|
||||
func (f *PathFlag) IsSet() bool {
|
||||
return f.HasBeenSet
|
||||
}
|
||||
|
||||
// Names returns the names of the flag
|
||||
func (f *PathFlag) Names() []string {
|
||||
return FlagNames(f.Name, f.Aliases)
|
||||
}
|
||||
|
||||
// IsRequired returns whether or not the flag is required
|
||||
func (f *PathFlag) IsRequired() bool {
|
||||
return f.Required
|
||||
}
|
||||
|
||||
// IsVisible returns true if the flag is not hidden, otherwise false
|
||||
func (f *PathFlag) IsVisible() bool {
|
||||
return !f.Hidden
|
||||
}
|
||||
|
||||
// StringSliceFlag is a flag with type *StringSlice
|
||||
type StringSliceFlag struct {
|
||||
Name string
|
||||
|
||||
Category string
|
||||
DefaultText string
|
||||
FilePath string
|
||||
Usage string
|
||||
|
||||
Required bool
|
||||
Hidden bool
|
||||
HasBeenSet bool
|
||||
|
||||
Value *StringSlice
|
||||
Destination *StringSlice
|
||||
|
||||
Aliases []string
|
||||
EnvVars []string
|
||||
|
||||
TakesFile bool
|
||||
|
||||
Action func(*Context, []string) error
|
||||
}
|
||||
|
||||
// IsSet returns whether or not the flag has been set through env or file
|
||||
func (f *StringSliceFlag) IsSet() bool {
|
||||
return f.HasBeenSet
|
||||
}
|
||||
|
||||
// Names returns the names of the flag
|
||||
func (f *StringSliceFlag) Names() []string {
|
||||
return FlagNames(f.Name, f.Aliases)
|
||||
}
|
||||
|
||||
// IsRequired returns whether or not the flag is required
|
||||
func (f *StringSliceFlag) IsRequired() bool {
|
||||
return f.Required
|
||||
}
|
||||
|
||||
// IsVisible returns true if the flag is not hidden, otherwise false
|
||||
func (f *StringSliceFlag) IsVisible() bool {
|
||||
return !f.Hidden
|
||||
}
|
||||
|
||||
// TimestampFlag is a flag with type *Timestamp
|
||||
type TimestampFlag struct {
|
||||
Name string
|
||||
|
||||
Category string
|
||||
DefaultText string
|
||||
FilePath string
|
||||
Usage string
|
||||
|
||||
Required bool
|
||||
Hidden bool
|
||||
HasBeenSet bool
|
||||
|
||||
Value *Timestamp
|
||||
Destination *Timestamp
|
||||
|
||||
Aliases []string
|
||||
EnvVars []string
|
||||
|
||||
Layout string
|
||||
|
||||
Timezone *time.Location
|
||||
|
||||
Action func(*Context, *time.Time) error
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value (for usage defaults)
|
||||
func (f *TimestampFlag) String() string {
|
||||
return FlagStringer(f)
|
||||
}
|
||||
|
||||
// IsSet returns whether or not the flag has been set through env or file
|
||||
func (f *TimestampFlag) IsSet() bool {
|
||||
return f.HasBeenSet
|
||||
}
|
||||
|
||||
// Names returns the names of the flag
|
||||
func (f *TimestampFlag) Names() []string {
|
||||
return FlagNames(f.Name, f.Aliases)
|
||||
}
|
||||
|
||||
// IsRequired returns whether or not the flag is required
|
||||
func (f *TimestampFlag) IsRequired() bool {
|
||||
return f.Required
|
||||
}
|
||||
|
||||
// IsVisible returns true if the flag is not hidden, otherwise false
|
||||
func (f *TimestampFlag) IsVisible() bool {
|
||||
return !f.Hidden
|
||||
}
|
||||
|
||||
// Uint64SliceFlag is a flag with type *Uint64Slice
|
||||
type Uint64SliceFlag struct {
|
||||
Name string
|
||||
|
||||
Category string
|
||||
DefaultText string
|
||||
FilePath string
|
||||
Usage string
|
||||
|
||||
Required bool
|
||||
Hidden bool
|
||||
HasBeenSet bool
|
||||
|
||||
Value *Uint64Slice
|
||||
Destination *Uint64Slice
|
||||
|
||||
Aliases []string
|
||||
EnvVars []string
|
||||
|
||||
Action func(*Context, []uint64) error
|
||||
}
|
||||
|
||||
// IsSet returns whether or not the flag has been set through env or file
|
||||
func (f *Uint64SliceFlag) IsSet() bool {
|
||||
return f.HasBeenSet
|
||||
}
|
||||
|
||||
// Names returns the names of the flag
|
||||
func (f *Uint64SliceFlag) Names() []string {
|
||||
return FlagNames(f.Name, f.Aliases)
|
||||
}
|
||||
|
||||
// IsRequired returns whether or not the flag is required
|
||||
func (f *Uint64SliceFlag) IsRequired() bool {
|
||||
return f.Required
|
||||
}
|
||||
|
||||
// IsVisible returns true if the flag is not hidden, otherwise false
|
||||
func (f *Uint64SliceFlag) IsVisible() bool {
|
||||
return !f.Hidden
|
||||
}
|
||||
|
||||
// UintSliceFlag is a flag with type *UintSlice
|
||||
type UintSliceFlag struct {
|
||||
Name string
|
||||
|
||||
Category string
|
||||
DefaultText string
|
||||
FilePath string
|
||||
Usage string
|
||||
|
||||
Required bool
|
||||
Hidden bool
|
||||
HasBeenSet bool
|
||||
|
||||
Value *UintSlice
|
||||
Destination *UintSlice
|
||||
|
||||
Aliases []string
|
||||
EnvVars []string
|
||||
|
||||
Action func(*Context, []uint) error
|
||||
}
|
||||
|
||||
// IsSet returns whether or not the flag has been set through env or file
|
||||
func (f *UintSliceFlag) IsSet() bool {
|
||||
return f.HasBeenSet
|
||||
}
|
||||
|
||||
// Names returns the names of the flag
|
||||
func (f *UintSliceFlag) Names() []string {
|
||||
return FlagNames(f.Name, f.Aliases)
|
||||
}
|
||||
|
||||
// IsRequired returns whether or not the flag is required
|
||||
func (f *UintSliceFlag) IsRequired() bool {
|
||||
return f.Required
|
||||
}
|
||||
|
||||
// IsVisible returns true if the flag is not hidden, otherwise false
|
||||
func (f *UintSliceFlag) IsVisible() bool {
|
||||
return !f.Hidden
|
||||
}
|
||||
|
||||
// BoolFlag is a flag with type bool
|
||||
type BoolFlag struct {
|
||||
Name string
|
||||
|
||||
Category string
|
||||
DefaultText string
|
||||
FilePath string
|
||||
Usage string
|
||||
|
||||
Required bool
|
||||
Hidden bool
|
||||
HasBeenSet bool
|
||||
|
||||
Value bool
|
||||
Destination *bool
|
||||
|
||||
Aliases []string
|
||||
EnvVars []string
|
||||
|
||||
Count *int
|
||||
|
||||
Action func(*Context, bool) error
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value (for usage defaults)
|
||||
func (f *BoolFlag) String() string {
|
||||
return FlagStringer(f)
|
||||
}
|
||||
|
||||
// IsSet returns whether or not the flag has been set through env or file
|
||||
func (f *BoolFlag) IsSet() bool {
|
||||
return f.HasBeenSet
|
||||
}
|
||||
|
||||
// Names returns the names of the flag
|
||||
func (f *BoolFlag) Names() []string {
|
||||
return FlagNames(f.Name, f.Aliases)
|
||||
}
|
||||
|
||||
// IsRequired returns whether or not the flag is required
|
||||
func (f *BoolFlag) IsRequired() bool {
|
||||
return f.Required
|
||||
}
|
||||
|
||||
// IsVisible returns true if the flag is not hidden, otherwise false
|
||||
func (f *BoolFlag) IsVisible() bool {
|
||||
return !f.Hidden
|
||||
}
|
||||
|
||||
// Float64Flag is a flag with type float64
|
||||
type Float64Flag struct {
|
||||
Name string
|
||||
|
||||
Category string
|
||||
DefaultText string
|
||||
FilePath string
|
||||
Usage string
|
||||
|
||||
Required bool
|
||||
Hidden bool
|
||||
HasBeenSet bool
|
||||
|
||||
Value float64
|
||||
Destination *float64
|
||||
|
||||
Aliases []string
|
||||
EnvVars []string
|
||||
|
||||
Action func(*Context, float64) error
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value (for usage defaults)
|
||||
func (f *Float64Flag) String() string {
|
||||
return FlagStringer(f)
|
||||
}
|
||||
|
||||
// IsSet returns whether or not the flag has been set through env or file
|
||||
func (f *Float64Flag) IsSet() bool {
|
||||
return f.HasBeenSet
|
||||
}
|
||||
|
||||
// Names returns the names of the flag
|
||||
func (f *Float64Flag) Names() []string {
|
||||
return FlagNames(f.Name, f.Aliases)
|
||||
}
|
||||
|
||||
// IsRequired returns whether or not the flag is required
|
||||
func (f *Float64Flag) IsRequired() bool {
|
||||
return f.Required
|
||||
}
|
||||
|
||||
// IsVisible returns true if the flag is not hidden, otherwise false
|
||||
func (f *Float64Flag) IsVisible() bool {
|
||||
return !f.Hidden
|
||||
}
|
||||
|
||||
// IntFlag is a flag with type int
|
||||
type IntFlag struct {
|
||||
Name string
|
||||
|
||||
Category string
|
||||
DefaultText string
|
||||
FilePath string
|
||||
Usage string
|
||||
|
||||
Required bool
|
||||
Hidden bool
|
||||
HasBeenSet bool
|
||||
|
||||
Value int
|
||||
Destination *int
|
||||
|
||||
Aliases []string
|
||||
EnvVars []string
|
||||
|
||||
Base int
|
||||
|
||||
Action func(*Context, int) error
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value (for usage defaults)
|
||||
func (f *IntFlag) String() string {
|
||||
return FlagStringer(f)
|
||||
}
|
||||
|
||||
// IsSet returns whether or not the flag has been set through env or file
|
||||
func (f *IntFlag) IsSet() bool {
|
||||
return f.HasBeenSet
|
||||
}
|
||||
|
||||
// Names returns the names of the flag
|
||||
func (f *IntFlag) Names() []string {
|
||||
return FlagNames(f.Name, f.Aliases)
|
||||
}
|
||||
|
||||
// IsRequired returns whether or not the flag is required
|
||||
func (f *IntFlag) IsRequired() bool {
|
||||
return f.Required
|
||||
}
|
||||
|
||||
// IsVisible returns true if the flag is not hidden, otherwise false
|
||||
func (f *IntFlag) IsVisible() bool {
|
||||
return !f.Hidden
|
||||
}
|
||||
|
||||
// Int64Flag is a flag with type int64
|
||||
type Int64Flag struct {
|
||||
Name string
|
||||
|
||||
Category string
|
||||
DefaultText string
|
||||
FilePath string
|
||||
Usage string
|
||||
|
||||
Required bool
|
||||
Hidden bool
|
||||
HasBeenSet bool
|
||||
|
||||
Value int64
|
||||
Destination *int64
|
||||
|
||||
Aliases []string
|
||||
EnvVars []string
|
||||
|
||||
Base int
|
||||
|
||||
Action func(*Context, int64) error
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value (for usage defaults)
|
||||
func (f *Int64Flag) String() string {
|
||||
return FlagStringer(f)
|
||||
}
|
||||
|
||||
// IsSet returns whether or not the flag has been set through env or file
|
||||
func (f *Int64Flag) IsSet() bool {
|
||||
return f.HasBeenSet
|
||||
}
|
||||
|
||||
// Names returns the names of the flag
|
||||
func (f *Int64Flag) Names() []string {
|
||||
return FlagNames(f.Name, f.Aliases)
|
||||
}
|
||||
|
||||
// IsRequired returns whether or not the flag is required
|
||||
func (f *Int64Flag) IsRequired() bool {
|
||||
return f.Required
|
||||
}
|
||||
|
||||
// IsVisible returns true if the flag is not hidden, otherwise false
|
||||
func (f *Int64Flag) IsVisible() bool {
|
||||
return !f.Hidden
|
||||
}
|
||||
|
||||
// StringFlag is a flag with type string
|
||||
type StringFlag struct {
|
||||
Name string
|
||||
|
||||
Category string
|
||||
DefaultText string
|
||||
FilePath string
|
||||
Usage string
|
||||
|
||||
Required bool
|
||||
Hidden bool
|
||||
HasBeenSet bool
|
||||
|
||||
Value string
|
||||
Destination *string
|
||||
|
||||
Aliases []string
|
||||
EnvVars []string
|
||||
|
||||
TakesFile bool
|
||||
|
||||
Action func(*Context, string) error
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value (for usage defaults)
|
||||
func (f *StringFlag) String() string {
|
||||
return FlagStringer(f)
|
||||
}
|
||||
|
||||
// IsSet returns whether or not the flag has been set through env or file
|
||||
func (f *StringFlag) IsSet() bool {
|
||||
return f.HasBeenSet
|
||||
}
|
||||
|
||||
// Names returns the names of the flag
|
||||
func (f *StringFlag) Names() []string {
|
||||
return FlagNames(f.Name, f.Aliases)
|
||||
}
|
||||
|
||||
// IsRequired returns whether or not the flag is required
|
||||
func (f *StringFlag) IsRequired() bool {
|
||||
return f.Required
|
||||
}
|
||||
|
||||
// IsVisible returns true if the flag is not hidden, otherwise false
|
||||
func (f *StringFlag) IsVisible() bool {
|
||||
return !f.Hidden
|
||||
}
|
||||
|
||||
// DurationFlag is a flag with type time.Duration
|
||||
type DurationFlag struct {
|
||||
Name string
|
||||
|
||||
Category string
|
||||
DefaultText string
|
||||
FilePath string
|
||||
Usage string
|
||||
|
||||
Required bool
|
||||
Hidden bool
|
||||
HasBeenSet bool
|
||||
|
||||
Value time.Duration
|
||||
Destination *time.Duration
|
||||
|
||||
Aliases []string
|
||||
EnvVars []string
|
||||
|
||||
Action func(*Context, time.Duration) error
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value (for usage defaults)
|
||||
func (f *DurationFlag) String() string {
|
||||
return FlagStringer(f)
|
||||
}
|
||||
|
||||
// IsSet returns whether or not the flag has been set through env or file
|
||||
func (f *DurationFlag) IsSet() bool {
|
||||
return f.HasBeenSet
|
||||
}
|
||||
|
||||
// Names returns the names of the flag
|
||||
func (f *DurationFlag) Names() []string {
|
||||
return FlagNames(f.Name, f.Aliases)
|
||||
}
|
||||
|
||||
// IsRequired returns whether or not the flag is required
|
||||
func (f *DurationFlag) IsRequired() bool {
|
||||
return f.Required
|
||||
}
|
||||
|
||||
// IsVisible returns true if the flag is not hidden, otherwise false
|
||||
func (f *DurationFlag) IsVisible() bool {
|
||||
return !f.Hidden
|
||||
}
|
||||
|
||||
// UintFlag is a flag with type uint
|
||||
type UintFlag struct {
|
||||
Name string
|
||||
|
||||
Category string
|
||||
DefaultText string
|
||||
FilePath string
|
||||
Usage string
|
||||
|
||||
Required bool
|
||||
Hidden bool
|
||||
HasBeenSet bool
|
||||
|
||||
Value uint
|
||||
Destination *uint
|
||||
|
||||
Aliases []string
|
||||
EnvVars []string
|
||||
|
||||
Base int
|
||||
|
||||
Action func(*Context, uint) error
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value (for usage defaults)
|
||||
func (f *UintFlag) String() string {
|
||||
return FlagStringer(f)
|
||||
}
|
||||
|
||||
// IsSet returns whether or not the flag has been set through env or file
|
||||
func (f *UintFlag) IsSet() bool {
|
||||
return f.HasBeenSet
|
||||
}
|
||||
|
||||
// Names returns the names of the flag
|
||||
func (f *UintFlag) Names() []string {
|
||||
return FlagNames(f.Name, f.Aliases)
|
||||
}
|
||||
|
||||
// IsRequired returns whether or not the flag is required
|
||||
func (f *UintFlag) IsRequired() bool {
|
||||
return f.Required
|
||||
}
|
||||
|
||||
// IsVisible returns true if the flag is not hidden, otherwise false
|
||||
func (f *UintFlag) IsVisible() bool {
|
||||
return !f.Hidden
|
||||
}
|
||||
|
||||
// Uint64Flag is a flag with type uint64
|
||||
type Uint64Flag struct {
|
||||
Name string
|
||||
|
||||
Category string
|
||||
DefaultText string
|
||||
FilePath string
|
||||
Usage string
|
||||
|
||||
Required bool
|
||||
Hidden bool
|
||||
HasBeenSet bool
|
||||
|
||||
Value uint64
|
||||
Destination *uint64
|
||||
|
||||
Aliases []string
|
||||
EnvVars []string
|
||||
|
||||
Base int
|
||||
|
||||
Action func(*Context, uint64) error
|
||||
}
|
||||
|
||||
// String returns a readable representation of this value (for usage defaults)
|
||||
func (f *Uint64Flag) String() string {
|
||||
return FlagStringer(f)
|
||||
}
|
||||
|
||||
// IsSet returns whether or not the flag has been set through env or file
|
||||
func (f *Uint64Flag) IsSet() bool {
|
||||
return f.HasBeenSet
|
||||
}
|
||||
|
||||
// Names returns the names of the flag
|
||||
func (f *Uint64Flag) Names() []string {
|
||||
return FlagNames(f.Name, f.Aliases)
|
||||
}
|
||||
|
||||
// IsRequired returns whether or not the flag is required
|
||||
func (f *Uint64Flag) IsRequired() bool {
|
||||
return f.Required
|
||||
}
|
||||
|
||||
// IsVisible returns true if the flag is not hidden, otherwise false
|
||||
func (f *Uint64Flag) IsVisible() bool {
|
||||
return !f.Hidden
|
||||
}
|
||||
|
||||
// vim:ro
|
9
vendor/github.com/xrash/smetrics/.travis.yml
generated
vendored
Normal file
9
vendor/github.com/xrash/smetrics/.travis.yml
generated
vendored
Normal file
|
@ -0,0 +1,9 @@
|
|||
language: go
|
||||
go:
|
||||
- 1.11
|
||||
- 1.12
|
||||
- 1.13
|
||||
- 1.14.x
|
||||
- master
|
||||
script:
|
||||
- cd tests && make
|
21
vendor/github.com/xrash/smetrics/LICENSE
generated
vendored
Normal file
21
vendor/github.com/xrash/smetrics/LICENSE
generated
vendored
Normal file
|
@ -0,0 +1,21 @@
|
|||
Copyright (C) 2016 Felipe da Cunha Gonçalves
|
||||
All Rights Reserved.
|
||||
|
||||
MIT LICENSE
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
49
vendor/github.com/xrash/smetrics/README.md
generated
vendored
Normal file
49
vendor/github.com/xrash/smetrics/README.md
generated
vendored
Normal file
|
@ -0,0 +1,49 @@
|
|||
[![Build Status](https://travis-ci.org/xrash/smetrics.svg?branch=master)](http://travis-ci.org/xrash/smetrics)
|
||||
|
||||
# smetrics
|
||||
|
||||
`smetrics` is "string metrics".
|
||||
|
||||
Package smetrics provides a bunch of algorithms for calculating the distance between strings.
|
||||
|
||||
There are implementations for calculating the popular Levenshtein distance (aka Edit Distance or Wagner-Fischer), as well as the Jaro distance, the Jaro-Winkler distance, and more.
|
||||
|
||||
# How to import
|
||||
|
||||
```go
|
||||
import "github.com/xrash/smetrics"
|
||||
```
|
||||
|
||||
# Documentation
|
||||
|
||||
Go to [https://pkg.go.dev/github.com/xrash/smetrics](https://pkg.go.dev/github.com/xrash/smetrics) for complete documentation.
|
||||
|
||||
# Example
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/xrash/smetrics"
|
||||
)
|
||||
|
||||
func main() {
|
||||
smetrics.WagnerFischer("POTATO", "POTATTO", 1, 1, 2)
|
||||
smetrics.WagnerFischer("MOUSE", "HOUSE", 2, 2, 4)
|
||||
|
||||
smetrics.Ukkonen("POTATO", "POTATTO", 1, 1, 2)
|
||||
smetrics.Ukkonen("MOUSE", "HOUSE", 2, 2, 4)
|
||||
|
||||
smetrics.Jaro("AL", "AL")
|
||||
smetrics.Jaro("MARTHA", "MARHTA")
|
||||
|
||||
smetrics.JaroWinkler("AL", "AL", 0.7, 4)
|
||||
smetrics.JaroWinkler("MARTHA", "MARHTA", 0.7, 4)
|
||||
|
||||
smetrics.Soundex("Euler")
|
||||
smetrics.Soundex("Ellery")
|
||||
|
||||
smetrics.Hamming("aaa", "aaa")
|
||||
smetrics.Hamming("aaa", "aab")
|
||||
}
|
||||
```
|
19
vendor/github.com/xrash/smetrics/doc.go
generated
vendored
Normal file
19
vendor/github.com/xrash/smetrics/doc.go
generated
vendored
Normal file
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
Package smetrics provides a bunch of algorithms for calculating
|
||||
the distance between strings.
|
||||
|
||||
There are implementations for calculating the popular Levenshtein
|
||||
distance (aka Edit Distance or Wagner-Fischer), as well as the Jaro
|
||||
distance, the Jaro-Winkler distance, and more.
|
||||
|
||||
For the Levenshtein distance, you can use the functions WagnerFischer()
|
||||
and Ukkonen(). Read the documentation on these functions.
|
||||
|
||||
For the Jaro and Jaro-Winkler algorithms, check the functions
|
||||
Jaro() and JaroWinkler(). Read the documentation on these functions.
|
||||
|
||||
For the Soundex algorithm, check the function Soundex().
|
||||
|
||||
For the Hamming distance algorithm, check the function Hamming().
|
||||
*/
|
||||
package smetrics
|
25
vendor/github.com/xrash/smetrics/hamming.go
generated
vendored
Normal file
25
vendor/github.com/xrash/smetrics/hamming.go
generated
vendored
Normal file
|
@ -0,0 +1,25 @@
|
|||
package smetrics
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// The Hamming distance is the minimum number of substitutions required to change string A into string B. Both strings must have the same size. If the strings have different sizes, the function returns an error.
|
||||
func Hamming(a, b string) (int, error) {
|
||||
al := len(a)
|
||||
bl := len(b)
|
||||
|
||||
if al != bl {
|
||||
return -1, fmt.Errorf("strings are not equal (len(a)=%d, len(b)=%d)", al, bl)
|
||||
}
|
||||
|
||||
var difference = 0
|
||||
|
||||
for i := range a {
|
||||
if a[i] != b[i] {
|
||||
difference = difference + 1
|
||||
}
|
||||
}
|
||||
|
||||
return difference, nil
|
||||
}
|
28
vendor/github.com/xrash/smetrics/jaro-winkler.go
generated
vendored
Normal file
28
vendor/github.com/xrash/smetrics/jaro-winkler.go
generated
vendored
Normal file
|
@ -0,0 +1,28 @@
|
|||
package smetrics
|
||||
|
||||
import (
|
||||
"math"
|
||||
)
|
||||
|
||||
// The Jaro-Winkler distance. The result is 1 for equal strings, and 0 for completely different strings. It is commonly used on Record Linkage stuff, thus it tries to be accurate for common typos when writing real names such as person names and street names.
|
||||
// Jaro-Winkler is a modification of the Jaro algorithm. It works by first running Jaro, then boosting the score of exact matches at the beginning of the strings. Because of that, it introduces two more parameters: the boostThreshold and the prefixSize. These are commonly set to 0.7 and 4, respectively.
|
||||
func JaroWinkler(a, b string, boostThreshold float64, prefixSize int) float64 {
|
||||
j := Jaro(a, b)
|
||||
|
||||
if j <= boostThreshold {
|
||||
return j
|
||||
}
|
||||
|
||||
prefixSize = int(math.Min(float64(len(a)), math.Min(float64(prefixSize), float64(len(b)))))
|
||||
|
||||
var prefixMatch float64
|
||||
for i := 0; i < prefixSize; i++ {
|
||||
if a[i] == b[i] {
|
||||
prefixMatch++
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return j + 0.1*prefixMatch*(1.0-j)
|
||||
}
|
86
vendor/github.com/xrash/smetrics/jaro.go
generated
vendored
Normal file
86
vendor/github.com/xrash/smetrics/jaro.go
generated
vendored
Normal file
|
@ -0,0 +1,86 @@
|
|||
package smetrics
|
||||
|
||||
import (
|
||||
"math"
|
||||
)
|
||||
|
||||
// The Jaro distance. The result is 1 for equal strings, and 0 for completely different strings.
|
||||
func Jaro(a, b string) float64 {
|
||||
// If both strings are zero-length, they are completely equal,
|
||||
// therefore return 1.
|
||||
if len(a) == 0 && len(b) == 0 {
|
||||
return 1
|
||||
}
|
||||
|
||||
// If one string is zero-length, strings are completely different,
|
||||
// therefore return 0.
|
||||
if len(a) == 0 || len(b) == 0 {
|
||||
return 0
|
||||
}
|
||||
|
||||
// Define the necessary variables for the algorithm.
|
||||
la := float64(len(a))
|
||||
lb := float64(len(b))
|
||||
matchRange := int(math.Max(0, math.Floor(math.Max(la, lb)/2.0)-1))
|
||||
matchesA := make([]bool, len(a))
|
||||
matchesB := make([]bool, len(b))
|
||||
var matches float64 = 0
|
||||
|
||||
// Step 1: Matches
|
||||
// Loop through each character of the first string,
|
||||
// looking for a matching character in the second string.
|
||||
for i := 0; i < len(a); i++ {
|
||||
start := int(math.Max(0, float64(i-matchRange)))
|
||||
end := int(math.Min(lb-1, float64(i+matchRange)))
|
||||
|
||||
for j := start; j <= end; j++ {
|
||||
if matchesB[j] {
|
||||
continue
|
||||
}
|
||||
|
||||
if a[i] == b[j] {
|
||||
matchesA[i] = true
|
||||
matchesB[j] = true
|
||||
matches++
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If there are no matches, strings are completely different,
|
||||
// therefore return 0.
|
||||
if matches == 0 {
|
||||
return 0
|
||||
}
|
||||
|
||||
// Step 2: Transpositions
|
||||
// Loop through the matches' arrays, looking for
|
||||
// unaligned matches. Count the number of unaligned matches.
|
||||
unaligned := 0
|
||||
j := 0
|
||||
for i := 0; i < len(a); i++ {
|
||||
if !matchesA[i] {
|
||||
continue
|
||||
}
|
||||
|
||||
for !matchesB[j] {
|
||||
j++
|
||||
}
|
||||
|
||||
if a[i] != b[j] {
|
||||
unaligned++
|
||||
}
|
||||
|
||||
j++
|
||||
}
|
||||
|
||||
// The number of unaligned matches divided by two, is the number of _transpositions_.
|
||||
transpositions := math.Floor(float64(unaligned / 2))
|
||||
|
||||
// Jaro distance is the average between these three numbers:
|
||||
// 1. matches / length of string A
|
||||
// 2. matches / length of string B
|
||||
// 3. (matches - transpositions/matches)
|
||||
// So, all that divided by three is the final result.
|
||||
return ((matches / la) + (matches / lb) + ((matches - transpositions) / matches)) / 3.0
|
||||
}
|
41
vendor/github.com/xrash/smetrics/soundex.go
generated
vendored
Normal file
41
vendor/github.com/xrash/smetrics/soundex.go
generated
vendored
Normal file
|
@ -0,0 +1,41 @@
|
|||
package smetrics
|
||||
|
||||
import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
// The Soundex encoding. It is a phonetic algorithm that considers how the words sound in English. Soundex maps a string to a 4-byte code consisting of the first letter of the original string and three numbers. Strings that sound similar should map to the same code.
|
||||
func Soundex(s string) string {
|
||||
m := map[byte]string{
|
||||
'B': "1", 'P': "1", 'F': "1", 'V': "1",
|
||||
'C': "2", 'S': "2", 'K': "2", 'G': "2", 'J': "2", 'Q': "2", 'X': "2", 'Z': "2",
|
||||
'D': "3", 'T': "3",
|
||||
'L': "4",
|
||||
'M': "5", 'N': "5",
|
||||
'R': "6",
|
||||
}
|
||||
|
||||
s = strings.ToUpper(s)
|
||||
|
||||
r := string(s[0])
|
||||
p := s[0]
|
||||
for i := 1; i < len(s) && len(r) < 4; i++ {
|
||||
c := s[i]
|
||||
|
||||
if (c < 'A' || c > 'Z') || (c == p) {
|
||||
continue
|
||||
}
|
||||
|
||||
p = c
|
||||
|
||||
if n, ok := m[c]; ok {
|
||||
r += n
|
||||
}
|
||||
}
|
||||
|
||||
for i := len(r); i < 4; i++ {
|
||||
r += "0"
|
||||
}
|
||||
|
||||
return r
|
||||
}
|
94
vendor/github.com/xrash/smetrics/ukkonen.go
generated
vendored
Normal file
94
vendor/github.com/xrash/smetrics/ukkonen.go
generated
vendored
Normal file
|
@ -0,0 +1,94 @@
|
|||
package smetrics
|
||||
|
||||
import (
|
||||
"math"
|
||||
)
|
||||
|
||||
// The Ukkonen algorithm for calculating the Levenshtein distance. The algorithm is described in http://www.cs.helsinki.fi/u/ukkonen/InfCont85.PDF, or in docs/InfCont85.PDF. It runs on O(t . min(m, n)) where t is the actual distance between strings a and b. It needs O(min(t, m, n)) space. This function might be preferred over WagnerFischer() for *very* similar strings. But test it out yourself.
|
||||
// The first two parameters are the two strings to be compared. The last three parameters are the insertion cost, the deletion cost and the substitution cost. These are normally defined as 1, 1 and 2 respectively.
|
||||
func Ukkonen(a, b string, icost, dcost, scost int) int {
|
||||
var lowerCost int
|
||||
|
||||
if icost < dcost && icost < scost {
|
||||
lowerCost = icost
|
||||
} else if dcost < scost {
|
||||
lowerCost = dcost
|
||||
} else {
|
||||
lowerCost = scost
|
||||
}
|
||||
|
||||
infinite := math.MaxInt32 / 2
|
||||
|
||||
var r []int
|
||||
var k, kprime, p, t int
|
||||
var ins, del, sub int
|
||||
|
||||
if len(a) > len(b) {
|
||||
t = (len(a) - len(b) + 1) * lowerCost
|
||||
} else {
|
||||
t = (len(b) - len(a) + 1) * lowerCost
|
||||
}
|
||||
|
||||
for {
|
||||
if (t / lowerCost) < (len(b) - len(a)) {
|
||||
continue
|
||||
}
|
||||
|
||||
// This is the right damn thing since the original Ukkonen
|
||||
// paper minimizes the expression result only, but the uncommented version
|
||||
// doesn't need to deal with floats so it's faster.
|
||||
// p = int(math.Floor(0.5*((float64(t)/float64(lowerCost)) - float64(len(b) - len(a)))))
|
||||
p = ((t / lowerCost) - (len(b) - len(a))) / 2
|
||||
|
||||
k = -p
|
||||
kprime = k
|
||||
|
||||
rowlength := (len(b) - len(a)) + (2 * p)
|
||||
|
||||
r = make([]int, rowlength+2)
|
||||
|
||||
for i := 0; i < rowlength+2; i++ {
|
||||
r[i] = infinite
|
||||
}
|
||||
|
||||
for i := 0; i <= len(a); i++ {
|
||||
for j := 0; j <= rowlength; j++ {
|
||||
if i == j+k && i == 0 {
|
||||
r[j] = 0
|
||||
} else {
|
||||
if j-1 < 0 {
|
||||
ins = infinite
|
||||
} else {
|
||||
ins = r[j-1] + icost
|
||||
}
|
||||
|
||||
del = r[j+1] + dcost
|
||||
sub = r[j] + scost
|
||||
|
||||
if i-1 < 0 || i-1 >= len(a) || j+k-1 >= len(b) || j+k-1 < 0 {
|
||||
sub = infinite
|
||||
} else if a[i-1] == b[j+k-1] {
|
||||
sub = r[j]
|
||||
}
|
||||
|
||||
if ins < del && ins < sub {
|
||||
r[j] = ins
|
||||
} else if del < sub {
|
||||
r[j] = del
|
||||
} else {
|
||||
r[j] = sub
|
||||
}
|
||||
}
|
||||
}
|
||||
k++
|
||||
}
|
||||
|
||||
if r[(len(b)-len(a))+(2*p)+kprime] <= t {
|
||||
break
|
||||
} else {
|
||||
t *= 2
|
||||
}
|
||||
}
|
||||
|
||||
return r[(len(b)-len(a))+(2*p)+kprime]
|
||||
}
|
48
vendor/github.com/xrash/smetrics/wagner-fischer.go
generated
vendored
Normal file
48
vendor/github.com/xrash/smetrics/wagner-fischer.go
generated
vendored
Normal file
|
@ -0,0 +1,48 @@
|
|||
package smetrics
|
||||
|
||||
// The Wagner-Fischer algorithm for calculating the Levenshtein distance.
|
||||
// The first two parameters are the two strings to be compared. The last three parameters are the insertion cost, the deletion cost and the substitution cost. These are normally defined as 1, 1 and 2 respectively.
|
||||
func WagnerFischer(a, b string, icost, dcost, scost int) int {
|
||||
|
||||
// Allocate both rows.
|
||||
row1 := make([]int, len(b)+1)
|
||||
row2 := make([]int, len(b)+1)
|
||||
var tmp []int
|
||||
|
||||
// Initialize the first row.
|
||||
for i := 1; i <= len(b); i++ {
|
||||
row1[i] = i * icost
|
||||
}
|
||||
|
||||
// For each row...
|
||||
for i := 1; i <= len(a); i++ {
|
||||
row2[0] = i * dcost
|
||||
|
||||
// For each column...
|
||||
for j := 1; j <= len(b); j++ {
|
||||
if a[i-1] == b[j-1] {
|
||||
row2[j] = row1[j-1]
|
||||
} else {
|
||||
ins := row2[j-1] + icost
|
||||
del := row1[j] + dcost
|
||||
sub := row1[j-1] + scost
|
||||
|
||||
if ins < del && ins < sub {
|
||||
row2[j] = ins
|
||||
} else if del < sub {
|
||||
row2[j] = del
|
||||
} else {
|
||||
row2[j] = sub
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Swap the rows at the end of each row.
|
||||
tmp = row1
|
||||
row1 = row2
|
||||
row2 = tmp
|
||||
}
|
||||
|
||||
// Because we swapped the rows, the final result is in row1 instead of row2.
|
||||
return row1[len(row1)-1]
|
||||
}
|
15
vendor/modules.txt
vendored
15
vendor/modules.txt
vendored
|
@ -1,11 +1,12 @@
|
|||
# github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d
|
||||
# github.com/cpuguy83/go-md2man/v2 v2.0.2
|
||||
## explicit; go 1.11
|
||||
github.com/cpuguy83/go-md2man/v2/md2man
|
||||
# github.com/russross/blackfriday/v2 v2.0.1
|
||||
# github.com/russross/blackfriday/v2 v2.1.0
|
||||
## explicit
|
||||
github.com/russross/blackfriday/v2
|
||||
# github.com/shurcooL/sanitized_anchor_name v1.0.0
|
||||
github.com/shurcooL/sanitized_anchor_name
|
||||
# github.com/urfave/cli/v2 v2.3.0
|
||||
## explicit
|
||||
# github.com/urfave/cli/v2 v2.19.2
|
||||
## explicit; go 1.18
|
||||
github.com/urfave/cli/v2
|
||||
# gopkg.in/ini.v1 v1.66.2
|
||||
# github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673
|
||||
## explicit
|
||||
github.com/xrash/smetrics
|
||||
|
|
Loading…
Reference in a new issue