mirror of
				https://gitea.com/gitea/tea.git
				synced 2025-10-31 01:05:26 +01:00 
			
		
		
		
	[Vendor] Update urfave/cli v1.20.0 -> v1.22.2 (#84)
Merge branch 'master' into update-cli-lib2 [Vendor] Update stretchr/testify v1.3.0 -> v1.4.0 (#83) update github.com/stretchr/testify v1.3.0 -> v1.4.0 Co-authored-by: 6543 <6543@obermui.de> Reviewed-by: techknowlogick <techknowlogick@gitea.io> Reviewed-by: sapk <sapk@noreply.gitea.io> Reviewed-by: appleboy <appleboy.tw@gmail.com> Update urfave/cli v1.20.0 -> v1.22.2 Co-authored-by: 6543 <6543@obermui.de> Reviewed-by: mrsdizzie <info@mrsdizzie.com> Reviewed-by: Lunny Xiao <xiaolunwen@gmail.com>
This commit is contained in:
		
							
								
								
									
										3
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								go.mod
									
									
									
									
									
								
							| @@ -4,11 +4,12 @@ go 1.12 | |||||||
|  |  | ||||||
| require ( | require ( | ||||||
| 	code.gitea.io/sdk/gitea v0.0.0-20200103062250-c7686bd633c6 | 	code.gitea.io/sdk/gitea v0.0.0-20200103062250-c7686bd633c6 | ||||||
|  | 	github.com/cpuguy83/go-md2man/v2 v2.0.0 // indirect | ||||||
| 	github.com/go-gitea/yaml v0.0.0-20170812160011-eb3733d160e7 | 	github.com/go-gitea/yaml v0.0.0-20170812160011-eb3733d160e7 | ||||||
| 	github.com/mattn/go-runewidth v0.0.4 // indirect | 	github.com/mattn/go-runewidth v0.0.4 // indirect | ||||||
| 	github.com/olekukonko/tablewriter v0.0.1 | 	github.com/olekukonko/tablewriter v0.0.1 | ||||||
| 	github.com/stretchr/testify v1.4.0 | 	github.com/stretchr/testify v1.4.0 | ||||||
| 	github.com/urfave/cli v1.20.0 | 	github.com/urfave/cli v1.22.2 | ||||||
| 	gopkg.in/src-d/go-git.v4 v4.13.1 | 	gopkg.in/src-d/go-git.v4 v4.13.1 | ||||||
| 	gopkg.in/yaml.v2 v2.2.7 // indirect | 	gopkg.in/yaml.v2 v2.2.7 // indirect | ||||||
| ) | ) | ||||||
|   | |||||||
							
								
								
									
										13
									
								
								go.sum
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								go.sum
									
									
									
									
									
								
							| @@ -1,11 +1,16 @@ | |||||||
| code.gitea.io/sdk/gitea v0.0.0-20200103062250-c7686bd633c6 h1:SFCUXiw/mg8Luu6+2/X8g4a0NGaT8eClU/bWjCKjs3o= | code.gitea.io/sdk/gitea v0.0.0-20200103062250-c7686bd633c6 h1:SFCUXiw/mg8Luu6+2/X8g4a0NGaT8eClU/bWjCKjs3o= | ||||||
| code.gitea.io/sdk/gitea v0.0.0-20200103062250-c7686bd633c6/go.mod h1:8IxkM1gyiwEjfO0m47bcmr3u3foR15+LoVub43hCHd0= | code.gitea.io/sdk/gitea v0.0.0-20200103062250-c7686bd633c6/go.mod h1:8IxkM1gyiwEjfO0m47bcmr3u3foR15+LoVub43hCHd0= | ||||||
|  | github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= | ||||||
| github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7 h1:uSoVVbwJiQipAclBbw+8quDsfcvFjOpI5iCf4p/cqCs= | github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7 h1:uSoVVbwJiQipAclBbw+8quDsfcvFjOpI5iCf4p/cqCs= | ||||||
| github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs= | github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs= | ||||||
| github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo4JG6LR5AXSUEsOjtdm0kw0FtQtMJA= | github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo4JG6LR5AXSUEsOjtdm0kw0FtQtMJA= | ||||||
| github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= | github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= | ||||||
| github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= | github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= | ||||||
| github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= | github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= | ||||||
|  | github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY= | ||||||
|  | github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= | ||||||
|  | github.com/cpuguy83/go-md2man/v2 v2.0.0 h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng4PGlyM= | ||||||
|  | github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= | ||||||
| github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= | github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= | ||||||
| github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | ||||||
| github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= | ||||||
| @@ -42,8 +47,12 @@ github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= | |||||||
| github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= | github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= | ||||||
| github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= | 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/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/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ= | github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ= | ||||||
| github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= | github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= | ||||||
|  | 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/src-d/gcfg v1.4.0 h1:xXbNR5AlLSA315x2UO+fTSSAXCDf+Ar38/6oyGbDKQ4= | github.com/src-d/gcfg v1.4.0 h1:xXbNR5AlLSA315x2UO+fTSSAXCDf+Ar38/6oyGbDKQ4= | ||||||
| github.com/src-d/gcfg v1.4.0/go.mod h1:p/UMsR43ujA89BJY9duynAwIpvqEujIH/jFlfL7jWoI= | github.com/src-d/gcfg v1.4.0/go.mod h1:p/UMsR43ujA89BJY9duynAwIpvqEujIH/jFlfL7jWoI= | ||||||
| github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= | ||||||
| @@ -53,8 +62,8 @@ github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0 | |||||||
| github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= | github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= | ||||||
| github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= | github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= | ||||||
| github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= | github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= | ||||||
| github.com/urfave/cli v1.20.0 h1:fDqGv3UG/4jbVl/QkFwEdddtEDjh/5Ov6X+0B/3bPaw= | github.com/urfave/cli v1.22.2 h1:gsqYFH8bb9ekPA12kRo0hfjngWQjkJPlN9R0N78BoUo= | ||||||
| github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= | github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= | ||||||
| github.com/xanzy/ssh-agent v0.2.1 h1:TCbipTQL2JiiCprBWx9frJ2eJlCYT00NmctrHxVAr70= | github.com/xanzy/ssh-agent v0.2.1 h1:TCbipTQL2JiiCprBWx9frJ2eJlCYT00NmctrHxVAr70= | ||||||
| github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4= | github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4= | ||||||
| golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= | golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= | ||||||
|   | |||||||
							
								
								
									
										21
									
								
								vendor/github.com/cpuguy83/go-md2man/v2/LICENSE.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								vendor/github.com/cpuguy83/go-md2man/v2/LICENSE.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,21 @@ | |||||||
|  | The MIT License (MIT) | ||||||
|  |  | ||||||
|  | Copyright (c) 2014 Brian Goff | ||||||
|  |  | ||||||
|  | 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. | ||||||
							
								
								
									
										14
									
								
								vendor/github.com/cpuguy83/go-md2man/v2/md2man/md2man.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								vendor/github.com/cpuguy83/go-md2man/v2/md2man/md2man.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,14 @@ | |||||||
|  | package md2man | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"github.com/russross/blackfriday/v2" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | // Render converts a markdown document into a roff formatted document. | ||||||
|  | func Render(doc []byte) []byte { | ||||||
|  | 	renderer := NewRoffRenderer() | ||||||
|  |  | ||||||
|  | 	return blackfriday.Run(doc, | ||||||
|  | 		[]blackfriday.Option{blackfriday.WithRenderer(renderer), | ||||||
|  | 			blackfriday.WithExtensions(renderer.GetExtensions())}...) | ||||||
|  | } | ||||||
							
								
								
									
										345
									
								
								vendor/github.com/cpuguy83/go-md2man/v2/md2man/roff.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										345
									
								
								vendor/github.com/cpuguy83/go-md2man/v2/md2man/roff.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,345 @@ | |||||||
|  | package md2man | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"fmt" | ||||||
|  | 	"io" | ||||||
|  | 	"os" | ||||||
|  | 	"strings" | ||||||
|  |  | ||||||
|  | 	"github.com/russross/blackfriday/v2" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | // roffRenderer implements the blackfriday.Renderer interface for creating | ||||||
|  | // roff format (manpages) from markdown text | ||||||
|  | type roffRenderer struct { | ||||||
|  | 	extensions   blackfriday.Extensions | ||||||
|  | 	listCounters []int | ||||||
|  | 	firstHeader  bool | ||||||
|  | 	defineTerm   bool | ||||||
|  | 	listDepth    int | ||||||
|  | } | ||||||
|  |  | ||||||
|  | const ( | ||||||
|  | 	titleHeader      = ".TH " | ||||||
|  | 	topLevelHeader   = "\n\n.SH " | ||||||
|  | 	secondLevelHdr   = "\n.SH " | ||||||
|  | 	otherHeader      = "\n.SS " | ||||||
|  | 	crTag            = "\n" | ||||||
|  | 	emphTag          = "\\fI" | ||||||
|  | 	emphCloseTag     = "\\fP" | ||||||
|  | 	strongTag        = "\\fB" | ||||||
|  | 	strongCloseTag   = "\\fP" | ||||||
|  | 	breakTag         = "\n.br\n" | ||||||
|  | 	paraTag          = "\n.PP\n" | ||||||
|  | 	hruleTag         = "\n.ti 0\n\\l'\\n(.lu'\n" | ||||||
|  | 	linkTag          = "\n\\[la]" | ||||||
|  | 	linkCloseTag     = "\\[ra]" | ||||||
|  | 	codespanTag      = "\\fB\\fC" | ||||||
|  | 	codespanCloseTag = "\\fR" | ||||||
|  | 	codeTag          = "\n.PP\n.RS\n\n.nf\n" | ||||||
|  | 	codeCloseTag     = "\n.fi\n.RE\n" | ||||||
|  | 	quoteTag         = "\n.PP\n.RS\n" | ||||||
|  | 	quoteCloseTag    = "\n.RE\n" | ||||||
|  | 	listTag          = "\n.RS\n" | ||||||
|  | 	listCloseTag     = "\n.RE\n" | ||||||
|  | 	arglistTag       = "\n.TP\n" | ||||||
|  | 	tableStart       = "\n.TS\nallbox;\n" | ||||||
|  | 	tableEnd         = ".TE\n" | ||||||
|  | 	tableCellStart   = "T{\n" | ||||||
|  | 	tableCellEnd     = "\nT}\n" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | // NewRoffRenderer creates a new blackfriday Renderer for generating roff documents | ||||||
|  | // from markdown | ||||||
|  | func NewRoffRenderer() *roffRenderer { // nolint: golint | ||||||
|  | 	var extensions blackfriday.Extensions | ||||||
|  |  | ||||||
|  | 	extensions |= blackfriday.NoIntraEmphasis | ||||||
|  | 	extensions |= blackfriday.Tables | ||||||
|  | 	extensions |= blackfriday.FencedCode | ||||||
|  | 	extensions |= blackfriday.SpaceHeadings | ||||||
|  | 	extensions |= blackfriday.Footnotes | ||||||
|  | 	extensions |= blackfriday.Titleblock | ||||||
|  | 	extensions |= blackfriday.DefinitionLists | ||||||
|  | 	return &roffRenderer{ | ||||||
|  | 		extensions: extensions, | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // GetExtensions returns the list of extensions used by this renderer implementation | ||||||
|  | func (r *roffRenderer) GetExtensions() blackfriday.Extensions { | ||||||
|  | 	return r.extensions | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // RenderHeader handles outputting the header at document start | ||||||
|  | func (r *roffRenderer) RenderHeader(w io.Writer, ast *blackfriday.Node) { | ||||||
|  | 	// disable hyphenation | ||||||
|  | 	out(w, ".nh\n") | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // RenderFooter handles outputting the footer at the document end; the roff | ||||||
|  | // renderer has no footer information | ||||||
|  | func (r *roffRenderer) RenderFooter(w io.Writer, ast *blackfriday.Node) { | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // RenderNode is called for each node in a markdown document; based on the node | ||||||
|  | // type the equivalent roff output is sent to the writer | ||||||
|  | func (r *roffRenderer) RenderNode(w io.Writer, node *blackfriday.Node, entering bool) blackfriday.WalkStatus { | ||||||
|  |  | ||||||
|  | 	var walkAction = blackfriday.GoToNext | ||||||
|  |  | ||||||
|  | 	switch node.Type { | ||||||
|  | 	case blackfriday.Text: | ||||||
|  | 		r.handleText(w, node, entering) | ||||||
|  | 	case blackfriday.Softbreak: | ||||||
|  | 		out(w, crTag) | ||||||
|  | 	case blackfriday.Hardbreak: | ||||||
|  | 		out(w, breakTag) | ||||||
|  | 	case blackfriday.Emph: | ||||||
|  | 		if entering { | ||||||
|  | 			out(w, emphTag) | ||||||
|  | 		} else { | ||||||
|  | 			out(w, emphCloseTag) | ||||||
|  | 		} | ||||||
|  | 	case blackfriday.Strong: | ||||||
|  | 		if entering { | ||||||
|  | 			out(w, strongTag) | ||||||
|  | 		} else { | ||||||
|  | 			out(w, strongCloseTag) | ||||||
|  | 		} | ||||||
|  | 	case blackfriday.Link: | ||||||
|  | 		if !entering { | ||||||
|  | 			out(w, linkTag+string(node.LinkData.Destination)+linkCloseTag) | ||||||
|  | 		} | ||||||
|  | 	case blackfriday.Image: | ||||||
|  | 		// ignore images | ||||||
|  | 		walkAction = blackfriday.SkipChildren | ||||||
|  | 	case blackfriday.Code: | ||||||
|  | 		out(w, codespanTag) | ||||||
|  | 		escapeSpecialChars(w, node.Literal) | ||||||
|  | 		out(w, codespanCloseTag) | ||||||
|  | 	case blackfriday.Document: | ||||||
|  | 		break | ||||||
|  | 	case blackfriday.Paragraph: | ||||||
|  | 		// roff .PP markers break lists | ||||||
|  | 		if r.listDepth > 0 { | ||||||
|  | 			return blackfriday.GoToNext | ||||||
|  | 		} | ||||||
|  | 		if entering { | ||||||
|  | 			out(w, paraTag) | ||||||
|  | 		} else { | ||||||
|  | 			out(w, crTag) | ||||||
|  | 		} | ||||||
|  | 	case blackfriday.BlockQuote: | ||||||
|  | 		if entering { | ||||||
|  | 			out(w, quoteTag) | ||||||
|  | 		} else { | ||||||
|  | 			out(w, quoteCloseTag) | ||||||
|  | 		} | ||||||
|  | 	case blackfriday.Heading: | ||||||
|  | 		r.handleHeading(w, node, entering) | ||||||
|  | 	case blackfriday.HorizontalRule: | ||||||
|  | 		out(w, hruleTag) | ||||||
|  | 	case blackfriday.List: | ||||||
|  | 		r.handleList(w, node, entering) | ||||||
|  | 	case blackfriday.Item: | ||||||
|  | 		r.handleItem(w, node, entering) | ||||||
|  | 	case blackfriday.CodeBlock: | ||||||
|  | 		out(w, codeTag) | ||||||
|  | 		escapeSpecialChars(w, node.Literal) | ||||||
|  | 		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 | ||||||
|  | 	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 { | ||||||
|  | 		case 1: | ||||||
|  | 			if !r.firstHeader { | ||||||
|  | 				out(w, titleHeader) | ||||||
|  | 				r.firstHeader = true | ||||||
|  | 				break | ||||||
|  | 			} | ||||||
|  | 			out(w, topLevelHeader) | ||||||
|  | 		case 2: | ||||||
|  | 			out(w, secondLevelHdr) | ||||||
|  | 		default: | ||||||
|  | 			out(w, otherHeader) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (r *roffRenderer) handleList(w io.Writer, node *blackfriday.Node, entering bool) { | ||||||
|  | 	openTag := listTag | ||||||
|  | 	closeTag := listCloseTag | ||||||
|  | 	if node.ListFlags&blackfriday.ListTypeDefinition != 0 { | ||||||
|  | 		// tags for definition lists handled within Item node | ||||||
|  | 		openTag = "" | ||||||
|  | 		closeTag = "" | ||||||
|  | 	} | ||||||
|  | 	if entering { | ||||||
|  | 		r.listDepth++ | ||||||
|  | 		if node.ListFlags&blackfriday.ListTypeOrdered != 0 { | ||||||
|  | 			r.listCounters = append(r.listCounters, 1) | ||||||
|  | 		} | ||||||
|  | 		out(w, openTag) | ||||||
|  | 	} else { | ||||||
|  | 		if node.ListFlags&blackfriday.ListTypeOrdered != 0 { | ||||||
|  | 			r.listCounters = r.listCounters[:len(r.listCounters)-1] | ||||||
|  | 		} | ||||||
|  | 		out(w, closeTag) | ||||||
|  | 		r.listDepth-- | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (r *roffRenderer) handleItem(w io.Writer, node *blackfriday.Node, entering bool) { | ||||||
|  | 	if 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.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 | ||||||
|  | 			} else { | ||||||
|  | 				r.defineTerm = false | ||||||
|  | 			} | ||||||
|  | 		} else { | ||||||
|  | 			out(w, ".IP \\(bu 2\n") | ||||||
|  | 		} | ||||||
|  | 	} else { | ||||||
|  | 		out(w, "\n") | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | 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 | ||||||
|  | 		columns := countColumns(node) | ||||||
|  | 		out(w, strings.Repeat("l ", columns)+"\n") | ||||||
|  | 		out(w, strings.Repeat("l ", columns)+".\n") | ||||||
|  | 	} else { | ||||||
|  | 		out(w, tableEnd) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | 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 { | ||||||
|  | 		if node.Prev != nil && node.Prev.Type == blackfriday.TableCell { | ||||||
|  | 			out(w, "\t"+start) | ||||||
|  | 		} else { | ||||||
|  | 			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 | ||||||
|  | 		} | ||||||
|  | 		out(w, end) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // 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 { | ||||||
|  | 	var columns int | ||||||
|  |  | ||||||
|  | 	node.Walk(func(node *blackfriday.Node, entering bool) blackfriday.WalkStatus { | ||||||
|  | 		switch node.Type { | ||||||
|  | 		case blackfriday.TableRow: | ||||||
|  | 			if !entering { | ||||||
|  | 				return blackfriday.Terminate | ||||||
|  | 			} | ||||||
|  | 		case blackfriday.TableCell: | ||||||
|  | 			if entering { | ||||||
|  | 				columns++ | ||||||
|  | 			} | ||||||
|  | 		default: | ||||||
|  | 		} | ||||||
|  | 		return blackfriday.GoToNext | ||||||
|  | 	}) | ||||||
|  | 	return columns | ||||||
|  | } | ||||||
|  |  | ||||||
|  | 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 | ||||||
|  | 		if len(text) >= 1 && (text[0] == '\'' || text[0] == '.') { | ||||||
|  | 			out(w, "\\&") | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		// directly copy normal characters | ||||||
|  | 		org := i | ||||||
|  |  | ||||||
|  | 		for i < len(text) && !needsBackslash(text[i]) { | ||||||
|  | 			i++ | ||||||
|  | 		} | ||||||
|  | 		if i > org { | ||||||
|  | 			w.Write(text[org:i]) // nolint: errcheck | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		// escape a character | ||||||
|  | 		if i >= len(text) { | ||||||
|  | 			break | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		w.Write([]byte{'\\', text[i]}) // nolint: errcheck | ||||||
|  | 	} | ||||||
|  | } | ||||||
							
								
								
									
										8
									
								
								vendor/github.com/russross/blackfriday/v2/.gitignore
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								vendor/github.com/russross/blackfriday/v2/.gitignore
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,8 @@ | |||||||
|  | *.out | ||||||
|  | *.swp | ||||||
|  | *.8 | ||||||
|  | *.6 | ||||||
|  | _obj | ||||||
|  | _test* | ||||||
|  | markdown | ||||||
|  | tags | ||||||
							
								
								
									
										17
									
								
								vendor/github.com/russross/blackfriday/v2/.travis.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								vendor/github.com/russross/blackfriday/v2/.travis.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,17 @@ | |||||||
|  | sudo: false | ||||||
|  | language: go | ||||||
|  | go: | ||||||
|  |   - "1.10.x" | ||||||
|  |   - "1.11.x" | ||||||
|  |   - tip | ||||||
|  | matrix: | ||||||
|  |   fast_finish: true | ||||||
|  |   allow_failures: | ||||||
|  |     - go: tip | ||||||
|  | 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 ./... | ||||||
							
								
								
									
										29
									
								
								vendor/github.com/russross/blackfriday/v2/LICENSE.txt
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								vendor/github.com/russross/blackfriday/v2/LICENSE.txt
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,29 @@ | |||||||
|  | Blackfriday is distributed under the Simplified BSD License: | ||||||
|  |  | ||||||
|  | > Copyright © 2011 Russ Ross | ||||||
|  | > All rights reserved. | ||||||
|  | > | ||||||
|  | > Redistribution and use in source and binary forms, with or without | ||||||
|  | > modification, are permitted provided that the following conditions | ||||||
|  | > are met: | ||||||
|  | > | ||||||
|  | > 1.  Redistributions of source code must retain the above copyright | ||||||
|  | >     notice, this list of conditions and the following disclaimer. | ||||||
|  | > | ||||||
|  | > 2.  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. | ||||||
|  | > | ||||||
|  | > 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 HOLDER 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. | ||||||
							
								
								
									
										291
									
								
								vendor/github.com/russross/blackfriday/v2/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										291
									
								
								vendor/github.com/russross/blackfriday/v2/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,291 @@ | |||||||
|  | Blackfriday [](https://travis-ci.org/russross/blackfriday) | ||||||
|  | =========== | ||||||
|  |  | ||||||
|  | Blackfriday is a [Markdown][1] processor implemented in [Go][2]. It | ||||||
|  | is paranoid about its input (so you can safely feed it user-supplied | ||||||
|  | data), it is fast, it supports common extensions (tables, smart | ||||||
|  | punctuation substitutions, etc.), and it is safe for all utf-8 | ||||||
|  | (unicode) input. | ||||||
|  |  | ||||||
|  | HTML output is currently supported, along with Smartypants | ||||||
|  | extensions. | ||||||
|  |  | ||||||
|  | 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: | ||||||
|  |  | ||||||
|  |     go get gopkg.in/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: | ||||||
|  |  | ||||||
|  |     import "gopkg.in/russross/blackfriday.v2" | ||||||
|  |  | ||||||
|  | and `go get` without parameters. | ||||||
|  |  | ||||||
|  |  | ||||||
|  | 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. | ||||||
|  |  | ||||||
|  | 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. | ||||||
|  |  | ||||||
|  | Version 2 offers a number of improvements over v1: | ||||||
|  |  | ||||||
|  | * Cleaned up API | ||||||
|  | * A separate call to [`Parse`][4], which produces an abstract syntax tree for | ||||||
|  |   the document | ||||||
|  | * Latest bug fixes | ||||||
|  | * Flexibility to easily add your own rendering extensions | ||||||
|  |  | ||||||
|  | Potential drawbacks: | ||||||
|  |  | ||||||
|  | * Our benchmarks show v2 to be slightly slower than v1. Currently in the | ||||||
|  |   ballpark of around 15%. | ||||||
|  | * API breakage. If you can't afford modifying your code to adhere to the new API | ||||||
|  |   and don't care too much about the new features, v2 is probably not for you. | ||||||
|  | * Several bug fixes are trailing behind and still need to be forward-ported to | ||||||
|  |   v2. See issue [#348](https://github.com/russross/blackfriday/issues/348) for | ||||||
|  |   tracking. | ||||||
|  |  | ||||||
|  | Usage | ||||||
|  | ----- | ||||||
|  |  | ||||||
|  | For the most sensible markdown processing, it is as simple as getting your input | ||||||
|  | into a byte slice and calling: | ||||||
|  |  | ||||||
|  | ```go | ||||||
|  | output := blackfriday.Run(input) | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | Your input will be parsed and the output rendered with a set of most popular | ||||||
|  | extensions enabled. If you want the most basic feature set, corresponding with | ||||||
|  | the bare Markdown specification, use: | ||||||
|  |  | ||||||
|  | ```go | ||||||
|  | output := blackfriday.Run(input, blackfriday.WithNoExtensions()) | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | ### Sanitize untrusted content | ||||||
|  |  | ||||||
|  | Blackfriday itself does nothing to protect against malicious content. If you are | ||||||
|  | dealing with user-supplied markdown, we recommend running Blackfriday's output | ||||||
|  | through HTML sanitizer such as [Bluemonday][5]. | ||||||
|  |  | ||||||
|  | Here's an example of simple usage of Blackfriday together with Bluemonday: | ||||||
|  |  | ||||||
|  | ```go | ||||||
|  | import ( | ||||||
|  |     "github.com/microcosm-cc/bluemonday" | ||||||
|  |     "github.com/russross/blackfriday" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | // ... | ||||||
|  | unsafe := blackfriday.Run(input) | ||||||
|  | html := bluemonday.UGCPolicy().SanitizeBytes(unsafe) | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | ### Custom options | ||||||
|  |  | ||||||
|  | If you want to customize the set of options, use `blackfriday.WithExtensions`, | ||||||
|  | `blackfriday.WithRenderer` and `blackfriday.WithRefOverride`. | ||||||
|  |  | ||||||
|  | You can also check out `blackfriday-tool` for a more complete example | ||||||
|  | of how to use it. Download and install it using: | ||||||
|  |  | ||||||
|  |     go get github.com/russross/blackfriday-tool | ||||||
|  |  | ||||||
|  | This is a simple command-line tool that allows you to process a | ||||||
|  | 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> | ||||||
|  |  | ||||||
|  | Note that if you have not already done so, installing | ||||||
|  | `blackfriday-tool` will be sufficient to download and install | ||||||
|  | blackfriday in addition to the tool itself. The tool binary will be | ||||||
|  | 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. | ||||||
|  |  | ||||||
|  |  | ||||||
|  | Features | ||||||
|  | -------- | ||||||
|  |  | ||||||
|  | All features of Sundown are supported, including: | ||||||
|  |  | ||||||
|  | *   **Compatibility**. The Markdown v1.0.3 test suite passes with | ||||||
|  |     the `--tidy` option.  Without `--tidy`, the differences are | ||||||
|  |     mostly in whitespace and entity escaping, where blackfriday is | ||||||
|  |     more consistent and cleaner. | ||||||
|  |  | ||||||
|  | *   **Common extensions**, including table support, fenced code | ||||||
|  |     blocks, autolinks, strikethroughs, non-strict emphasis, etc. | ||||||
|  |  | ||||||
|  | *   **Safety**. Blackfriday is paranoid when parsing, making it safe | ||||||
|  |     to feed untrusted user input without fear of bad things | ||||||
|  |     happening. The test suite stress tests this and there are no | ||||||
|  |     known inputs that make it crash.  If you find one, please let me | ||||||
|  |     know and send me the input that does it. | ||||||
|  |  | ||||||
|  |     NOTE: "safety" in this context means *runtime safety only*. In order to | ||||||
|  |     protect yourself against JavaScript injection in untrusted content, see | ||||||
|  |     [this example](https://github.com/russross/blackfriday#sanitize-untrusted-content). | ||||||
|  |  | ||||||
|  | *   **Fast processing**. It is fast enough to render on-demand in | ||||||
|  |     most web applications without having to cache the output. | ||||||
|  |  | ||||||
|  | *   **Thread safety**. You can run multiple parsers in different | ||||||
|  |     goroutines without ill effect. There is no dependence on global | ||||||
|  |     shared state. | ||||||
|  |  | ||||||
|  | *   **Minimal dependencies**. Blackfriday only depends on standard | ||||||
|  |     library packages in Go. The source code is pretty | ||||||
|  |     self-contained, so it is easy to add to any project, including | ||||||
|  |     Google App Engine projects. | ||||||
|  |  | ||||||
|  | *   **Standards compliant**. Output successfully validates using the | ||||||
|  |     W3C validation tool for HTML 4.01 and XHTML 1.0 Transitional. | ||||||
|  |  | ||||||
|  |  | ||||||
|  | Extensions | ||||||
|  | ---------- | ||||||
|  |  | ||||||
|  | In addition to the standard markdown syntax, this package | ||||||
|  | implements the following extensions: | ||||||
|  |  | ||||||
|  | *   **Intra-word emphasis supression**. The `_` character is | ||||||
|  |     commonly used inside words when discussing code, so having | ||||||
|  |     markdown interpret it as an emphasis command is usually the | ||||||
|  |     wrong thing. Blackfriday lets you treat all emphasis markers as | ||||||
|  |     normal characters when they occur inside a word. | ||||||
|  |  | ||||||
|  | *   **Tables**. Tables can be created by drawing them in the input | ||||||
|  |     using a simple syntax: | ||||||
|  |  | ||||||
|  |     ``` | ||||||
|  |     Name    | Age | ||||||
|  |     --------|------ | ||||||
|  |     Bob     | 27 | ||||||
|  |     Alice   | 23 | ||||||
|  |     ``` | ||||||
|  |  | ||||||
|  | *   **Fenced code blocks**. In addition to the normal 4-space | ||||||
|  |     indentation to mark code blocks, you can explicitly mark them | ||||||
|  |     and supply a language (to make syntax highlighting simple). Just | ||||||
|  |     mark it like this: | ||||||
|  |  | ||||||
|  |         ```go | ||||||
|  |         func getTrue() bool { | ||||||
|  |             return true | ||||||
|  |         } | ||||||
|  |         ``` | ||||||
|  |  | ||||||
|  |     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. | ||||||
|  |  | ||||||
|  | *   **Definition lists**. A simple definition list is made of a single-line | ||||||
|  |     term followed by a colon and the definition for that term. | ||||||
|  |  | ||||||
|  |         Cat | ||||||
|  |         : Fluffy animal everyone likes | ||||||
|  |  | ||||||
|  |         Internet | ||||||
|  |         : Vector of transmission for pictures of cats | ||||||
|  |  | ||||||
|  |     Terms must be separated from the previous definition by a blank line. | ||||||
|  |  | ||||||
|  | *   **Footnotes**. A marker in the text that will become a superscript number; | ||||||
|  |     a footnote definition that will be placed in a list of footnotes at the | ||||||
|  |     end of the document. A footnote looks like this: | ||||||
|  |  | ||||||
|  |         This is a footnote.[^1] | ||||||
|  |  | ||||||
|  |         [^1]: the footnote text. | ||||||
|  |  | ||||||
|  | *   **Autolinking**. Blackfriday can find URLs that have not been | ||||||
|  |     explicitly marked as links and turn them into links. | ||||||
|  |  | ||||||
|  | *   **Strikethrough**. Use two tildes (`~~`) to mark text that | ||||||
|  |     should be crossed out. | ||||||
|  |  | ||||||
|  | *   **Hard line breaks**. With this extension enabled newlines in the input | ||||||
|  |     translate into line breaks in the output. This extension is off by default. | ||||||
|  |  | ||||||
|  | *   **Smart quotes**. Smartypants-style punctuation substitution is | ||||||
|  |     supported, turning normal double- and single-quote marks into | ||||||
|  |     curly quotes, etc. | ||||||
|  |  | ||||||
|  | *   **LaTeX-style dash parsing** is an additional option, where `--` | ||||||
|  |     is translated into `–`, and `---` is translated into | ||||||
|  |     `—`. This differs from most smartypants processors, which | ||||||
|  |     turn a single hyphen into an ndash and a double hyphen into an | ||||||
|  |     mdash. | ||||||
|  |  | ||||||
|  | *   **Smart fractions**, where anything that looks like a fraction | ||||||
|  |     is translated into suitable HTML (instead of just a few special | ||||||
|  |     cases like most smartypant processors). For example, `4/5` | ||||||
|  |     becomes `<sup>4</sup>⁄<sub>5</sub>`, which renders as | ||||||
|  |     <sup>4</sup>⁄<sub>5</sub>. | ||||||
|  |  | ||||||
|  |  | ||||||
|  | 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): | ||||||
|  |     provides a GitHub Flavored Markdown renderer with fenced code block | ||||||
|  |     highlighting, clickable heading anchor links. | ||||||
|  |  | ||||||
|  |     It's not customizable, and its goal is to produce HTML output | ||||||
|  |     equivalent to the [GitHub Markdown API endpoint](https://developer.github.com/v3/markdown/#render-a-markdown-document-in-raw-mode), | ||||||
|  |     except the rendering is performed locally. | ||||||
|  |  | ||||||
|  | *   [markdownfmt](https://github.com/shurcooL/markdownfmt): like gofmt, | ||||||
|  |     but for markdown. | ||||||
|  |  | ||||||
|  | *   [LaTeX output](https://github.com/Ambrevar/Blackfriday-LaTeX): | ||||||
|  |     renders output as LaTeX. | ||||||
|  |  | ||||||
|  | *   [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. | ||||||
|  |  | ||||||
|  |  | ||||||
|  | Todo | ||||||
|  | ---- | ||||||
|  |  | ||||||
|  | *   More unit testing | ||||||
|  | *   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. | ||||||
|  |  | ||||||
|  |  | ||||||
|  | License | ||||||
|  | ------- | ||||||
|  |  | ||||||
|  | [Blackfriday is distributed under the Simplified BSD License](LICENSE.txt) | ||||||
|  |  | ||||||
|  |  | ||||||
|  |    [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" | ||||||
|  |    [5]: https://github.com/microcosm-cc/bluemonday "Bluemonday" | ||||||
|  |    [6]: https://labix.org/gopkg.in "gopkg.in" | ||||||
							
								
								
									
										1590
									
								
								vendor/github.com/russross/blackfriday/v2/block.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1590
									
								
								vendor/github.com/russross/blackfriday/v2/block.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										18
									
								
								vendor/github.com/russross/blackfriday/v2/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								vendor/github.com/russross/blackfriday/v2/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,18 @@ | |||||||
|  | // Package blackfriday is a markdown processor. | ||||||
|  | // | ||||||
|  | // It translates plain text with simple formatting rules into an AST, which can | ||||||
|  | // then be further processed to HTML (provided by Blackfriday itself) or other | ||||||
|  | // formats (provided by the community). | ||||||
|  | // | ||||||
|  | // The simplest way to invoke Blackfriday is to call the Run function. It will | ||||||
|  | // take a text input and produce a text output in HTML (or other format). | ||||||
|  | // | ||||||
|  | // A slightly more sophisticated way to use Blackfriday is to create a Markdown | ||||||
|  | // processor and to call Parse, which returns a syntax tree for the input | ||||||
|  | // document. You can leverage Blackfriday's parsing for content extraction from | ||||||
|  | // markdown documents. You can assign a custom renderer and set various options | ||||||
|  | // to the Markdown processor. | ||||||
|  | // | ||||||
|  | // If you're interested in calling Blackfriday from command line, see | ||||||
|  | // https://github.com/russross/blackfriday-tool. | ||||||
|  | package blackfriday | ||||||
							
								
								
									
										34
									
								
								vendor/github.com/russross/blackfriday/v2/esc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								vendor/github.com/russross/blackfriday/v2/esc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,34 @@ | |||||||
|  | package blackfriday | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"html" | ||||||
|  | 	"io" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | var htmlEscaper = [256][]byte{ | ||||||
|  | 	'&': []byte("&"), | ||||||
|  | 	'<': []byte("<"), | ||||||
|  | 	'>': []byte(">"), | ||||||
|  | 	'"': []byte("""), | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func escapeHTML(w io.Writer, s []byte) { | ||||||
|  | 	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 | ||||||
|  | 		} | ||||||
|  | 		end++ | ||||||
|  | 	} | ||||||
|  | 	if start < len(s) && end <= len(s) { | ||||||
|  | 		w.Write(s[start:end]) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | 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
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								vendor/github.com/russross/blackfriday/v2/go.mod
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | |||||||
|  | module github.com/russross/blackfriday/v2 | ||||||
							
								
								
									
										949
									
								
								vendor/github.com/russross/blackfriday/v2/html.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										949
									
								
								vendor/github.com/russross/blackfriday/v2/html.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,949 @@ | |||||||
|  | // | ||||||
|  | // Blackfriday Markdown Processor | ||||||
|  | // Available at http://github.com/russross/blackfriday | ||||||
|  | // | ||||||
|  | // Copyright © 2011 Russ Ross <russ@russross.com>. | ||||||
|  | // Distributed under the Simplified BSD License. | ||||||
|  | // See README.md for details. | ||||||
|  | // | ||||||
|  |  | ||||||
|  | // | ||||||
|  | // | ||||||
|  | // HTML rendering backend | ||||||
|  | // | ||||||
|  | // | ||||||
|  |  | ||||||
|  | package blackfriday | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"bytes" | ||||||
|  | 	"fmt" | ||||||
|  | 	"io" | ||||||
|  | 	"regexp" | ||||||
|  | 	"strings" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | // HTMLFlags control optional behavior of HTML renderer. | ||||||
|  | type HTMLFlags int | ||||||
|  |  | ||||||
|  | // HTML renderer configuration options. | ||||||
|  | const ( | ||||||
|  | 	HTMLFlagsNone           HTMLFlags = 0 | ||||||
|  | 	SkipHTML                HTMLFlags = 1 << iota // Skip preformatted HTML blocks | ||||||
|  | 	SkipImages                                    // Skip embedded images | ||||||
|  | 	SkipLinks                                     // Skip all links | ||||||
|  | 	Safelink                                      // Only link to trusted protocols | ||||||
|  | 	NofollowLinks                                 // Only link with rel="nofollow" | ||||||
|  | 	NoreferrerLinks                               // Only link with rel="noreferrer" | ||||||
|  | 	NoopenerLinks                                 // Only link with rel="noopener" | ||||||
|  | 	HrefTargetBlank                               // Add a blank target | ||||||
|  | 	CompletePage                                  // Generate a complete HTML page | ||||||
|  | 	UseXHTML                                      // Generate XHTML output instead of HTML | ||||||
|  | 	FootnoteReturnLinks                           // Generate a link at the end of a footnote to return to the source | ||||||
|  | 	Smartypants                                   // Enable smart punctuation substitutions | ||||||
|  | 	SmartypantsFractions                          // Enable smart fractions (with Smartypants) | ||||||
|  | 	SmartypantsDashes                             // Enable smart dashes (with Smartypants) | ||||||
|  | 	SmartypantsLatexDashes                        // Enable LaTeX-style dashes (with Smartypants) | ||||||
|  | 	SmartypantsAngledQuotes                       // Enable angled double quotes (with Smartypants) for double quotes rendering | ||||||
|  | 	SmartypantsQuotesNBSP                         // Enable « French guillemets » (with Smartypants) | ||||||
|  | 	TOC                                           // Generate a table of contents | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | var ( | ||||||
|  | 	htmlTagRe = regexp.MustCompile("(?i)^" + htmlTag) | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | const ( | ||||||
|  | 	htmlTag = "(?:" + openTag + "|" + closeTag + "|" + htmlComment + "|" + | ||||||
|  | 		processingInstruction + "|" + declaration + "|" + cdata + ")" | ||||||
|  | 	closeTag              = "</" + tagName + "\\s*[>]" | ||||||
|  | 	openTag               = "<" + tagName + attribute + "*" + "\\s*/?>" | ||||||
|  | 	attribute             = "(?:" + "\\s+" + attributeName + attributeValueSpec + "?)" | ||||||
|  | 	attributeValue        = "(?:" + unquotedValue + "|" + singleQuotedValue + "|" + doubleQuotedValue + ")" | ||||||
|  | 	attributeValueSpec    = "(?:" + "\\s*=" + "\\s*" + attributeValue + ")" | ||||||
|  | 	attributeName         = "[a-zA-Z_:][a-zA-Z0-9:._-]*" | ||||||
|  | 	cdata                 = "<!\\[CDATA\\[[\\s\\S]*?\\]\\]>" | ||||||
|  | 	declaration           = "<![A-Z]+" + "\\s+[^>]*>" | ||||||
|  | 	doubleQuotedValue     = "\"[^\"]*\"" | ||||||
|  | 	htmlComment           = "<!---->|<!--(?:-?[^>-])(?:-?[^-])*-->" | ||||||
|  | 	processingInstruction = "[<][?].*?[?][>]" | ||||||
|  | 	singleQuotedValue     = "'[^']*'" | ||||||
|  | 	tagName               = "[A-Za-z][A-Za-z0-9-]*" | ||||||
|  | 	unquotedValue         = "[^\"'=<>`\\x00-\\x20]+" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | // HTMLRendererParameters is a collection of supplementary parameters tweaking | ||||||
|  | // the behavior of various parts of HTML renderer. | ||||||
|  | type HTMLRendererParameters struct { | ||||||
|  | 	// Prepend this text to each relative URL. | ||||||
|  | 	AbsolutePrefix string | ||||||
|  | 	// Add this text to each footnote anchor, to ensure uniqueness. | ||||||
|  | 	FootnoteAnchorPrefix string | ||||||
|  | 	// Show this text inside the <a> tag for a footnote return link, if the | ||||||
|  | 	// HTML_FOOTNOTE_RETURN_LINKS flag is enabled. If blank, the string | ||||||
|  | 	// <sup>[return]</sup> is used. | ||||||
|  | 	FootnoteReturnLinkContents string | ||||||
|  | 	// If set, add this text to the front of each Heading ID, to ensure | ||||||
|  | 	// uniqueness. | ||||||
|  | 	HeadingIDPrefix string | ||||||
|  | 	// If set, add this text to the back of each Heading ID, to ensure uniqueness. | ||||||
|  | 	HeadingIDSuffix string | ||||||
|  | 	// Increase heading levels: if the offset is 1, <h1> becomes <h2> etc. | ||||||
|  | 	// Negative offset is also valid. | ||||||
|  | 	// Resulting levels are clipped between 1 and 6. | ||||||
|  | 	HeadingLevelOffset int | ||||||
|  |  | ||||||
|  | 	Title string // Document title (used if CompletePage is set) | ||||||
|  | 	CSS   string // Optional CSS file URL (used if CompletePage is set) | ||||||
|  | 	Icon  string // Optional icon file URL (used if CompletePage is set) | ||||||
|  |  | ||||||
|  | 	Flags HTMLFlags // Flags allow customizing this renderer's behavior | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // HTMLRenderer is a type that implements the Renderer interface for HTML output. | ||||||
|  | // | ||||||
|  | // Do not create this directly, instead use the NewHTMLRenderer function. | ||||||
|  | type HTMLRenderer struct { | ||||||
|  | 	HTMLRendererParameters | ||||||
|  |  | ||||||
|  | 	closeTag string // how to end singleton tags: either " />" or ">" | ||||||
|  |  | ||||||
|  | 	// Track heading IDs to prevent ID collision in a single generation. | ||||||
|  | 	headingIDs map[string]int | ||||||
|  |  | ||||||
|  | 	lastOutputLen int | ||||||
|  | 	disableTags   int | ||||||
|  |  | ||||||
|  | 	sr *SPRenderer | ||||||
|  | } | ||||||
|  |  | ||||||
|  | const ( | ||||||
|  | 	xhtmlClose = " />" | ||||||
|  | 	htmlClose  = ">" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | // NewHTMLRenderer creates and configures an HTMLRenderer object, which | ||||||
|  | // satisfies the Renderer interface. | ||||||
|  | func NewHTMLRenderer(params HTMLRendererParameters) *HTMLRenderer { | ||||||
|  | 	// configure the rendering engine | ||||||
|  | 	closeTag := htmlClose | ||||||
|  | 	if params.Flags&UseXHTML != 0 { | ||||||
|  | 		closeTag = xhtmlClose | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if params.FootnoteReturnLinkContents == "" { | ||||||
|  | 		params.FootnoteReturnLinkContents = `<sup>[return]</sup>` | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return &HTMLRenderer{ | ||||||
|  | 		HTMLRendererParameters: params, | ||||||
|  |  | ||||||
|  | 		closeTag:   closeTag, | ||||||
|  | 		headingIDs: make(map[string]int), | ||||||
|  |  | ||||||
|  | 		sr: NewSmartypantsRenderer(params.Flags), | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func isHTMLTag(tag []byte, tagname string) bool { | ||||||
|  | 	found, _ := findHTMLTagPos(tag, tagname) | ||||||
|  | 	return found | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Look for a character, but ignore it when it's in any kind of quotes, it | ||||||
|  | // might be JavaScript | ||||||
|  | func skipUntilCharIgnoreQuotes(html []byte, start int, char byte) int { | ||||||
|  | 	inSingleQuote := false | ||||||
|  | 	inDoubleQuote := false | ||||||
|  | 	inGraveQuote := false | ||||||
|  | 	i := start | ||||||
|  | 	for i < len(html) { | ||||||
|  | 		switch { | ||||||
|  | 		case html[i] == char && !inSingleQuote && !inDoubleQuote && !inGraveQuote: | ||||||
|  | 			return i | ||||||
|  | 		case html[i] == '\'': | ||||||
|  | 			inSingleQuote = !inSingleQuote | ||||||
|  | 		case html[i] == '"': | ||||||
|  | 			inDoubleQuote = !inDoubleQuote | ||||||
|  | 		case html[i] == '`': | ||||||
|  | 			inGraveQuote = !inGraveQuote | ||||||
|  | 		} | ||||||
|  | 		i++ | ||||||
|  | 	} | ||||||
|  | 	return start | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func findHTMLTagPos(tag []byte, tagname string) (bool, int) { | ||||||
|  | 	i := 0 | ||||||
|  | 	if i < len(tag) && tag[0] != '<' { | ||||||
|  | 		return false, -1 | ||||||
|  | 	} | ||||||
|  | 	i++ | ||||||
|  | 	i = skipSpace(tag, i) | ||||||
|  |  | ||||||
|  | 	if i < len(tag) && tag[i] == '/' { | ||||||
|  | 		i++ | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	i = skipSpace(tag, i) | ||||||
|  | 	j := 0 | ||||||
|  | 	for ; i < len(tag); i, j = i+1, j+1 { | ||||||
|  | 		if j >= len(tagname) { | ||||||
|  | 			break | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		if strings.ToLower(string(tag[i]))[0] != tagname[j] { | ||||||
|  | 			return false, -1 | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if i == len(tag) { | ||||||
|  | 		return false, -1 | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	rightAngle := skipUntilCharIgnoreQuotes(tag, i, '>') | ||||||
|  | 	if rightAngle >= i { | ||||||
|  | 		return true, rightAngle | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return false, -1 | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func skipSpace(tag []byte, i int) int { | ||||||
|  | 	for i < len(tag) && isspace(tag[i]) { | ||||||
|  | 		i++ | ||||||
|  | 	} | ||||||
|  | 	return i | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func isRelativeLink(link []byte) (yes bool) { | ||||||
|  | 	// a tag begin with '#' | ||||||
|  | 	if link[0] == '#' { | ||||||
|  | 		return true | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// link begin with '/' but not '//', the second maybe a protocol relative link | ||||||
|  | 	if len(link) >= 2 && link[0] == '/' && link[1] != '/' { | ||||||
|  | 		return true | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// only the root '/' | ||||||
|  | 	if len(link) == 1 && link[0] == '/' { | ||||||
|  | 		return true | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// current directory : begin with "./" | ||||||
|  | 	if bytes.HasPrefix(link, []byte("./")) { | ||||||
|  | 		return true | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// parent directory : begin with "../" | ||||||
|  | 	if bytes.HasPrefix(link, []byte("../")) { | ||||||
|  | 		return true | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return false | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (r *HTMLRenderer) ensureUniqueHeadingID(id string) string { | ||||||
|  | 	for count, found := r.headingIDs[id]; found; count, found = r.headingIDs[id] { | ||||||
|  | 		tmp := fmt.Sprintf("%s-%d", id, count+1) | ||||||
|  |  | ||||||
|  | 		if _, tmpFound := r.headingIDs[tmp]; !tmpFound { | ||||||
|  | 			r.headingIDs[id] = count + 1 | ||||||
|  | 			id = tmp | ||||||
|  | 		} else { | ||||||
|  | 			id = id + "-1" | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if _, found := r.headingIDs[id]; !found { | ||||||
|  | 		r.headingIDs[id] = 0 | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return id | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (r *HTMLRenderer) addAbsPrefix(link []byte) []byte { | ||||||
|  | 	if r.AbsolutePrefix != "" && isRelativeLink(link) && link[0] != '.' { | ||||||
|  | 		newDest := r.AbsolutePrefix | ||||||
|  | 		if link[0] != '/' { | ||||||
|  | 			newDest += "/" | ||||||
|  | 		} | ||||||
|  | 		newDest += string(link) | ||||||
|  | 		return []byte(newDest) | ||||||
|  | 	} | ||||||
|  | 	return link | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func appendLinkAttrs(attrs []string, flags HTMLFlags, link []byte) []string { | ||||||
|  | 	if isRelativeLink(link) { | ||||||
|  | 		return attrs | ||||||
|  | 	} | ||||||
|  | 	val := []string{} | ||||||
|  | 	if flags&NofollowLinks != 0 { | ||||||
|  | 		val = append(val, "nofollow") | ||||||
|  | 	} | ||||||
|  | 	if flags&NoreferrerLinks != 0 { | ||||||
|  | 		val = append(val, "noreferrer") | ||||||
|  | 	} | ||||||
|  | 	if flags&NoopenerLinks != 0 { | ||||||
|  | 		val = append(val, "noopener") | ||||||
|  | 	} | ||||||
|  | 	if flags&HrefTargetBlank != 0 { | ||||||
|  | 		attrs = append(attrs, "target=\"_blank\"") | ||||||
|  | 	} | ||||||
|  | 	if len(val) == 0 { | ||||||
|  | 		return attrs | ||||||
|  | 	} | ||||||
|  | 	attr := fmt.Sprintf("rel=%q", strings.Join(val, " ")) | ||||||
|  | 	return append(attrs, attr) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func isMailto(link []byte) bool { | ||||||
|  | 	return bytes.HasPrefix(link, []byte("mailto:")) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func needSkipLink(flags HTMLFlags, dest []byte) bool { | ||||||
|  | 	if flags&SkipLinks != 0 { | ||||||
|  | 		return true | ||||||
|  | 	} | ||||||
|  | 	return flags&Safelink != 0 && !isSafeLink(dest) && !isMailto(dest) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func isSmartypantable(node *Node) bool { | ||||||
|  | 	pt := node.Parent.Type | ||||||
|  | 	return pt != Link && pt != CodeBlock && pt != Code | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func appendLanguageAttr(attrs []string, info []byte) []string { | ||||||
|  | 	if len(info) == 0 { | ||||||
|  | 		return attrs | ||||||
|  | 	} | ||||||
|  | 	endOfLang := bytes.IndexAny(info, "\t ") | ||||||
|  | 	if endOfLang < 0 { | ||||||
|  | 		endOfLang = len(info) | ||||||
|  | 	} | ||||||
|  | 	return append(attrs, fmt.Sprintf("class=\"language-%s\"", info[:endOfLang])) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (r *HTMLRenderer) tag(w io.Writer, name []byte, attrs []string) { | ||||||
|  | 	w.Write(name) | ||||||
|  | 	if len(attrs) > 0 { | ||||||
|  | 		w.Write(spaceBytes) | ||||||
|  | 		w.Write([]byte(strings.Join(attrs, " "))) | ||||||
|  | 	} | ||||||
|  | 	w.Write(gtBytes) | ||||||
|  | 	r.lastOutputLen = 1 | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func footnoteRef(prefix string, node *Node) []byte { | ||||||
|  | 	urlFrag := prefix + string(slugify(node.Destination)) | ||||||
|  | 	anchor := fmt.Sprintf(`<a href="#fn:%s">%d</a>`, urlFrag, node.NoteID) | ||||||
|  | 	return []byte(fmt.Sprintf(`<sup class="footnote-ref" id="fnref:%s">%s</sup>`, urlFrag, anchor)) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func footnoteItem(prefix string, slug []byte) []byte { | ||||||
|  | 	return []byte(fmt.Sprintf(`<li id="fn:%s%s">`, prefix, slug)) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func footnoteReturnLink(prefix, returnLink string, slug []byte) []byte { | ||||||
|  | 	const format = ` <a class="footnote-return" href="#fnref:%s%s">%s</a>` | ||||||
|  | 	return []byte(fmt.Sprintf(format, prefix, slug, returnLink)) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func itemOpenCR(node *Node) bool { | ||||||
|  | 	if node.Prev == nil { | ||||||
|  | 		return false | ||||||
|  | 	} | ||||||
|  | 	ld := node.Parent.ListData | ||||||
|  | 	return !ld.Tight && ld.ListFlags&ListTypeDefinition == 0 | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func skipParagraphTags(node *Node) bool { | ||||||
|  | 	grandparent := node.Parent.Parent | ||||||
|  | 	if grandparent == nil || grandparent.Type != List { | ||||||
|  | 		return false | ||||||
|  | 	} | ||||||
|  | 	tightOrTerm := grandparent.Tight || node.Parent.ListFlags&ListTypeTerm != 0 | ||||||
|  | 	return grandparent.Type == List && tightOrTerm | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func cellAlignment(align CellAlignFlags) string { | ||||||
|  | 	switch align { | ||||||
|  | 	case TableAlignmentLeft: | ||||||
|  | 		return "left" | ||||||
|  | 	case TableAlignmentRight: | ||||||
|  | 		return "right" | ||||||
|  | 	case TableAlignmentCenter: | ||||||
|  | 		return "center" | ||||||
|  | 	default: | ||||||
|  | 		return "" | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (r *HTMLRenderer) out(w io.Writer, text []byte) { | ||||||
|  | 	if r.disableTags > 0 { | ||||||
|  | 		w.Write(htmlTagRe.ReplaceAll(text, []byte{})) | ||||||
|  | 	} else { | ||||||
|  | 		w.Write(text) | ||||||
|  | 	} | ||||||
|  | 	r.lastOutputLen = len(text) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (r *HTMLRenderer) cr(w io.Writer) { | ||||||
|  | 	if r.lastOutputLen > 0 { | ||||||
|  | 		r.out(w, nlBytes) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | var ( | ||||||
|  | 	nlBytes    = []byte{'\n'} | ||||||
|  | 	gtBytes    = []byte{'>'} | ||||||
|  | 	spaceBytes = []byte{' '} | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | var ( | ||||||
|  | 	brTag              = []byte("<br>") | ||||||
|  | 	brXHTMLTag         = []byte("<br />") | ||||||
|  | 	emTag              = []byte("<em>") | ||||||
|  | 	emCloseTag         = []byte("</em>") | ||||||
|  | 	strongTag          = []byte("<strong>") | ||||||
|  | 	strongCloseTag     = []byte("</strong>") | ||||||
|  | 	delTag             = []byte("<del>") | ||||||
|  | 	delCloseTag        = []byte("</del>") | ||||||
|  | 	ttTag              = []byte("<tt>") | ||||||
|  | 	ttCloseTag         = []byte("</tt>") | ||||||
|  | 	aTag               = []byte("<a") | ||||||
|  | 	aCloseTag          = []byte("</a>") | ||||||
|  | 	preTag             = []byte("<pre>") | ||||||
|  | 	preCloseTag        = []byte("</pre>") | ||||||
|  | 	codeTag            = []byte("<code>") | ||||||
|  | 	codeCloseTag       = []byte("</code>") | ||||||
|  | 	pTag               = []byte("<p>") | ||||||
|  | 	pCloseTag          = []byte("</p>") | ||||||
|  | 	blockquoteTag      = []byte("<blockquote>") | ||||||
|  | 	blockquoteCloseTag = []byte("</blockquote>") | ||||||
|  | 	hrTag              = []byte("<hr>") | ||||||
|  | 	hrXHTMLTag         = []byte("<hr />") | ||||||
|  | 	ulTag              = []byte("<ul>") | ||||||
|  | 	ulCloseTag         = []byte("</ul>") | ||||||
|  | 	olTag              = []byte("<ol>") | ||||||
|  | 	olCloseTag         = []byte("</ol>") | ||||||
|  | 	dlTag              = []byte("<dl>") | ||||||
|  | 	dlCloseTag         = []byte("</dl>") | ||||||
|  | 	liTag              = []byte("<li>") | ||||||
|  | 	liCloseTag         = []byte("</li>") | ||||||
|  | 	ddTag              = []byte("<dd>") | ||||||
|  | 	ddCloseTag         = []byte("</dd>") | ||||||
|  | 	dtTag              = []byte("<dt>") | ||||||
|  | 	dtCloseTag         = []byte("</dt>") | ||||||
|  | 	tableTag           = []byte("<table>") | ||||||
|  | 	tableCloseTag      = []byte("</table>") | ||||||
|  | 	tdTag              = []byte("<td") | ||||||
|  | 	tdCloseTag         = []byte("</td>") | ||||||
|  | 	thTag              = []byte("<th") | ||||||
|  | 	thCloseTag         = []byte("</th>") | ||||||
|  | 	theadTag           = []byte("<thead>") | ||||||
|  | 	theadCloseTag      = []byte("</thead>") | ||||||
|  | 	tbodyTag           = []byte("<tbody>") | ||||||
|  | 	tbodyCloseTag      = []byte("</tbody>") | ||||||
|  | 	trTag              = []byte("<tr>") | ||||||
|  | 	trCloseTag         = []byte("</tr>") | ||||||
|  | 	h1Tag              = []byte("<h1") | ||||||
|  | 	h1CloseTag         = []byte("</h1>") | ||||||
|  | 	h2Tag              = []byte("<h2") | ||||||
|  | 	h2CloseTag         = []byte("</h2>") | ||||||
|  | 	h3Tag              = []byte("<h3") | ||||||
|  | 	h3CloseTag         = []byte("</h3>") | ||||||
|  | 	h4Tag              = []byte("<h4") | ||||||
|  | 	h4CloseTag         = []byte("</h4>") | ||||||
|  | 	h5Tag              = []byte("<h5") | ||||||
|  | 	h5CloseTag         = []byte("</h5>") | ||||||
|  | 	h6Tag              = []byte("<h6") | ||||||
|  | 	h6CloseTag         = []byte("</h6>") | ||||||
|  |  | ||||||
|  | 	footnotesDivBytes      = []byte("\n<div class=\"footnotes\">\n\n") | ||||||
|  | 	footnotesCloseDivBytes = []byte("\n</div>\n") | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | func headingTagsFromLevel(level int) ([]byte, []byte) { | ||||||
|  | 	if level <= 1 { | ||||||
|  | 		return h1Tag, h1CloseTag | ||||||
|  | 	} | ||||||
|  | 	switch level { | ||||||
|  | 	case 2: | ||||||
|  | 		return h2Tag, h2CloseTag | ||||||
|  | 	case 3: | ||||||
|  | 		return h3Tag, h3CloseTag | ||||||
|  | 	case 4: | ||||||
|  | 		return h4Tag, h4CloseTag | ||||||
|  | 	case 5: | ||||||
|  | 		return h5Tag, h5CloseTag | ||||||
|  | 	} | ||||||
|  | 	return h6Tag, h6CloseTag | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (r *HTMLRenderer) outHRTag(w io.Writer) { | ||||||
|  | 	if r.Flags&UseXHTML == 0 { | ||||||
|  | 		r.out(w, hrTag) | ||||||
|  | 	} else { | ||||||
|  | 		r.out(w, hrXHTMLTag) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // RenderNode is a default renderer of a single node of a syntax tree. For | ||||||
|  | // block nodes it will be called twice: first time with entering=true, second | ||||||
|  | // time with entering=false, so that it could know when it's working on an open | ||||||
|  | // tag and when on close. It writes the result to w. | ||||||
|  | // | ||||||
|  | // The return value is a way to tell the calling walker to adjust its walk | ||||||
|  | // pattern: e.g. it can terminate the traversal by returning Terminate. Or it | ||||||
|  | // can ask the walker to skip a subtree of this node by returning SkipChildren. | ||||||
|  | // The typical behavior is to return GoToNext, which asks for the usual | ||||||
|  | // traversal to the next node. | ||||||
|  | func (r *HTMLRenderer) RenderNode(w io.Writer, node *Node, entering bool) WalkStatus { | ||||||
|  | 	attrs := []string{} | ||||||
|  | 	switch node.Type { | ||||||
|  | 	case Text: | ||||||
|  | 		if r.Flags&Smartypants != 0 { | ||||||
|  | 			var tmp bytes.Buffer | ||||||
|  | 			escapeHTML(&tmp, node.Literal) | ||||||
|  | 			r.sr.Process(w, tmp.Bytes()) | ||||||
|  | 		} else { | ||||||
|  | 			if node.Parent.Type == Link { | ||||||
|  | 				escLink(w, node.Literal) | ||||||
|  | 			} else { | ||||||
|  | 				escapeHTML(w, node.Literal) | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	case Softbreak: | ||||||
|  | 		r.cr(w) | ||||||
|  | 		// TODO: make it configurable via out(renderer.softbreak) | ||||||
|  | 	case Hardbreak: | ||||||
|  | 		if r.Flags&UseXHTML == 0 { | ||||||
|  | 			r.out(w, brTag) | ||||||
|  | 		} else { | ||||||
|  | 			r.out(w, brXHTMLTag) | ||||||
|  | 		} | ||||||
|  | 		r.cr(w) | ||||||
|  | 	case Emph: | ||||||
|  | 		if entering { | ||||||
|  | 			r.out(w, emTag) | ||||||
|  | 		} else { | ||||||
|  | 			r.out(w, emCloseTag) | ||||||
|  | 		} | ||||||
|  | 	case Strong: | ||||||
|  | 		if entering { | ||||||
|  | 			r.out(w, strongTag) | ||||||
|  | 		} else { | ||||||
|  | 			r.out(w, strongCloseTag) | ||||||
|  | 		} | ||||||
|  | 	case Del: | ||||||
|  | 		if entering { | ||||||
|  | 			r.out(w, delTag) | ||||||
|  | 		} else { | ||||||
|  | 			r.out(w, delCloseTag) | ||||||
|  | 		} | ||||||
|  | 	case HTMLSpan: | ||||||
|  | 		if r.Flags&SkipHTML != 0 { | ||||||
|  | 			break | ||||||
|  | 		} | ||||||
|  | 		r.out(w, node.Literal) | ||||||
|  | 	case Link: | ||||||
|  | 		// mark it but don't link it if it is not a safe link: no smartypants | ||||||
|  | 		dest := node.LinkData.Destination | ||||||
|  | 		if needSkipLink(r.Flags, dest) { | ||||||
|  | 			if entering { | ||||||
|  | 				r.out(w, ttTag) | ||||||
|  | 			} else { | ||||||
|  | 				r.out(w, ttCloseTag) | ||||||
|  | 			} | ||||||
|  | 		} else { | ||||||
|  | 			if entering { | ||||||
|  | 				dest = r.addAbsPrefix(dest) | ||||||
|  | 				var hrefBuf bytes.Buffer | ||||||
|  | 				hrefBuf.WriteString("href=\"") | ||||||
|  | 				escLink(&hrefBuf, dest) | ||||||
|  | 				hrefBuf.WriteByte('"') | ||||||
|  | 				attrs = append(attrs, hrefBuf.String()) | ||||||
|  | 				if node.NoteID != 0 { | ||||||
|  | 					r.out(w, footnoteRef(r.FootnoteAnchorPrefix, node)) | ||||||
|  | 					break | ||||||
|  | 				} | ||||||
|  | 				attrs = appendLinkAttrs(attrs, r.Flags, dest) | ||||||
|  | 				if len(node.LinkData.Title) > 0 { | ||||||
|  | 					var titleBuff bytes.Buffer | ||||||
|  | 					titleBuff.WriteString("title=\"") | ||||||
|  | 					escapeHTML(&titleBuff, node.LinkData.Title) | ||||||
|  | 					titleBuff.WriteByte('"') | ||||||
|  | 					attrs = append(attrs, titleBuff.String()) | ||||||
|  | 				} | ||||||
|  | 				r.tag(w, aTag, attrs) | ||||||
|  | 			} else { | ||||||
|  | 				if node.NoteID != 0 { | ||||||
|  | 					break | ||||||
|  | 				} | ||||||
|  | 				r.out(w, aCloseTag) | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	case Image: | ||||||
|  | 		if r.Flags&SkipImages != 0 { | ||||||
|  | 			return SkipChildren | ||||||
|  | 		} | ||||||
|  | 		if entering { | ||||||
|  | 			dest := node.LinkData.Destination | ||||||
|  | 			dest = r.addAbsPrefix(dest) | ||||||
|  | 			if r.disableTags == 0 { | ||||||
|  | 				//if options.safe && potentiallyUnsafe(dest) { | ||||||
|  | 				//out(w, `<img src="" alt="`) | ||||||
|  | 				//} else { | ||||||
|  | 				r.out(w, []byte(`<img src="`)) | ||||||
|  | 				escLink(w, dest) | ||||||
|  | 				r.out(w, []byte(`" alt="`)) | ||||||
|  | 				//} | ||||||
|  | 			} | ||||||
|  | 			r.disableTags++ | ||||||
|  | 		} else { | ||||||
|  | 			r.disableTags-- | ||||||
|  | 			if r.disableTags == 0 { | ||||||
|  | 				if node.LinkData.Title != nil { | ||||||
|  | 					r.out(w, []byte(`" title="`)) | ||||||
|  | 					escapeHTML(w, node.LinkData.Title) | ||||||
|  | 				} | ||||||
|  | 				r.out(w, []byte(`" />`)) | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	case Code: | ||||||
|  | 		r.out(w, codeTag) | ||||||
|  | 		escapeHTML(w, node.Literal) | ||||||
|  | 		r.out(w, codeCloseTag) | ||||||
|  | 	case Document: | ||||||
|  | 		break | ||||||
|  | 	case Paragraph: | ||||||
|  | 		if skipParagraphTags(node) { | ||||||
|  | 			break | ||||||
|  | 		} | ||||||
|  | 		if entering { | ||||||
|  | 			// TODO: untangle this clusterfuck about when the newlines need | ||||||
|  | 			// to be added and when not. | ||||||
|  | 			if node.Prev != nil { | ||||||
|  | 				switch node.Prev.Type { | ||||||
|  | 				case HTMLBlock, List, Paragraph, Heading, CodeBlock, BlockQuote, HorizontalRule: | ||||||
|  | 					r.cr(w) | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 			if node.Parent.Type == BlockQuote && node.Prev == nil { | ||||||
|  | 				r.cr(w) | ||||||
|  | 			} | ||||||
|  | 			r.out(w, pTag) | ||||||
|  | 		} else { | ||||||
|  | 			r.out(w, pCloseTag) | ||||||
|  | 			if !(node.Parent.Type == Item && node.Next == nil) { | ||||||
|  | 				r.cr(w) | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	case BlockQuote: | ||||||
|  | 		if entering { | ||||||
|  | 			r.cr(w) | ||||||
|  | 			r.out(w, blockquoteTag) | ||||||
|  | 		} else { | ||||||
|  | 			r.out(w, blockquoteCloseTag) | ||||||
|  | 			r.cr(w) | ||||||
|  | 		} | ||||||
|  | 	case HTMLBlock: | ||||||
|  | 		if r.Flags&SkipHTML != 0 { | ||||||
|  | 			break | ||||||
|  | 		} | ||||||
|  | 		r.cr(w) | ||||||
|  | 		r.out(w, node.Literal) | ||||||
|  | 		r.cr(w) | ||||||
|  | 	case Heading: | ||||||
|  | 		headingLevel := r.HTMLRendererParameters.HeadingLevelOffset + node.Level | ||||||
|  | 		openTag, closeTag := headingTagsFromLevel(headingLevel) | ||||||
|  | 		if entering { | ||||||
|  | 			if node.IsTitleblock { | ||||||
|  | 				attrs = append(attrs, `class="title"`) | ||||||
|  | 			} | ||||||
|  | 			if node.HeadingID != "" { | ||||||
|  | 				id := r.ensureUniqueHeadingID(node.HeadingID) | ||||||
|  | 				if r.HeadingIDPrefix != "" { | ||||||
|  | 					id = r.HeadingIDPrefix + id | ||||||
|  | 				} | ||||||
|  | 				if r.HeadingIDSuffix != "" { | ||||||
|  | 					id = id + r.HeadingIDSuffix | ||||||
|  | 				} | ||||||
|  | 				attrs = append(attrs, fmt.Sprintf(`id="%s"`, id)) | ||||||
|  | 			} | ||||||
|  | 			r.cr(w) | ||||||
|  | 			r.tag(w, openTag, attrs) | ||||||
|  | 		} else { | ||||||
|  | 			r.out(w, closeTag) | ||||||
|  | 			if !(node.Parent.Type == Item && node.Next == nil) { | ||||||
|  | 				r.cr(w) | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	case HorizontalRule: | ||||||
|  | 		r.cr(w) | ||||||
|  | 		r.outHRTag(w) | ||||||
|  | 		r.cr(w) | ||||||
|  | 	case List: | ||||||
|  | 		openTag := ulTag | ||||||
|  | 		closeTag := ulCloseTag | ||||||
|  | 		if node.ListFlags&ListTypeOrdered != 0 { | ||||||
|  | 			openTag = olTag | ||||||
|  | 			closeTag = olCloseTag | ||||||
|  | 		} | ||||||
|  | 		if node.ListFlags&ListTypeDefinition != 0 { | ||||||
|  | 			openTag = dlTag | ||||||
|  | 			closeTag = dlCloseTag | ||||||
|  | 		} | ||||||
|  | 		if entering { | ||||||
|  | 			if node.IsFootnotesList { | ||||||
|  | 				r.out(w, footnotesDivBytes) | ||||||
|  | 				r.outHRTag(w) | ||||||
|  | 				r.cr(w) | ||||||
|  | 			} | ||||||
|  | 			r.cr(w) | ||||||
|  | 			if node.Parent.Type == Item && node.Parent.Parent.Tight { | ||||||
|  | 				r.cr(w) | ||||||
|  | 			} | ||||||
|  | 			r.tag(w, openTag[:len(openTag)-1], attrs) | ||||||
|  | 			r.cr(w) | ||||||
|  | 		} else { | ||||||
|  | 			r.out(w, closeTag) | ||||||
|  | 			//cr(w) | ||||||
|  | 			//if node.parent.Type != Item { | ||||||
|  | 			//	cr(w) | ||||||
|  | 			//} | ||||||
|  | 			if node.Parent.Type == Item && node.Next != nil { | ||||||
|  | 				r.cr(w) | ||||||
|  | 			} | ||||||
|  | 			if node.Parent.Type == Document || node.Parent.Type == BlockQuote { | ||||||
|  | 				r.cr(w) | ||||||
|  | 			} | ||||||
|  | 			if node.IsFootnotesList { | ||||||
|  | 				r.out(w, footnotesCloseDivBytes) | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	case Item: | ||||||
|  | 		openTag := liTag | ||||||
|  | 		closeTag := liCloseTag | ||||||
|  | 		if node.ListFlags&ListTypeDefinition != 0 { | ||||||
|  | 			openTag = ddTag | ||||||
|  | 			closeTag = ddCloseTag | ||||||
|  | 		} | ||||||
|  | 		if node.ListFlags&ListTypeTerm != 0 { | ||||||
|  | 			openTag = dtTag | ||||||
|  | 			closeTag = dtCloseTag | ||||||
|  | 		} | ||||||
|  | 		if entering { | ||||||
|  | 			if itemOpenCR(node) { | ||||||
|  | 				r.cr(w) | ||||||
|  | 			} | ||||||
|  | 			if node.ListData.RefLink != nil { | ||||||
|  | 				slug := slugify(node.ListData.RefLink) | ||||||
|  | 				r.out(w, footnoteItem(r.FootnoteAnchorPrefix, slug)) | ||||||
|  | 				break | ||||||
|  | 			} | ||||||
|  | 			r.out(w, openTag) | ||||||
|  | 		} else { | ||||||
|  | 			if node.ListData.RefLink != nil { | ||||||
|  | 				slug := slugify(node.ListData.RefLink) | ||||||
|  | 				if r.Flags&FootnoteReturnLinks != 0 { | ||||||
|  | 					r.out(w, footnoteReturnLink(r.FootnoteAnchorPrefix, r.FootnoteReturnLinkContents, slug)) | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 			r.out(w, closeTag) | ||||||
|  | 			r.cr(w) | ||||||
|  | 		} | ||||||
|  | 	case CodeBlock: | ||||||
|  | 		attrs = appendLanguageAttr(attrs, node.Info) | ||||||
|  | 		r.cr(w) | ||||||
|  | 		r.out(w, preTag) | ||||||
|  | 		r.tag(w, codeTag[:len(codeTag)-1], attrs) | ||||||
|  | 		escapeHTML(w, node.Literal) | ||||||
|  | 		r.out(w, codeCloseTag) | ||||||
|  | 		r.out(w, preCloseTag) | ||||||
|  | 		if node.Parent.Type != Item { | ||||||
|  | 			r.cr(w) | ||||||
|  | 		} | ||||||
|  | 	case Table: | ||||||
|  | 		if entering { | ||||||
|  | 			r.cr(w) | ||||||
|  | 			r.out(w, tableTag) | ||||||
|  | 		} else { | ||||||
|  | 			r.out(w, tableCloseTag) | ||||||
|  | 			r.cr(w) | ||||||
|  | 		} | ||||||
|  | 	case TableCell: | ||||||
|  | 		openTag := tdTag | ||||||
|  | 		closeTag := tdCloseTag | ||||||
|  | 		if node.IsHeader { | ||||||
|  | 			openTag = thTag | ||||||
|  | 			closeTag = thCloseTag | ||||||
|  | 		} | ||||||
|  | 		if entering { | ||||||
|  | 			align := cellAlignment(node.Align) | ||||||
|  | 			if align != "" { | ||||||
|  | 				attrs = append(attrs, fmt.Sprintf(`align="%s"`, align)) | ||||||
|  | 			} | ||||||
|  | 			if node.Prev == nil { | ||||||
|  | 				r.cr(w) | ||||||
|  | 			} | ||||||
|  | 			r.tag(w, openTag, attrs) | ||||||
|  | 		} else { | ||||||
|  | 			r.out(w, closeTag) | ||||||
|  | 			r.cr(w) | ||||||
|  | 		} | ||||||
|  | 	case TableHead: | ||||||
|  | 		if entering { | ||||||
|  | 			r.cr(w) | ||||||
|  | 			r.out(w, theadTag) | ||||||
|  | 		} else { | ||||||
|  | 			r.out(w, theadCloseTag) | ||||||
|  | 			r.cr(w) | ||||||
|  | 		} | ||||||
|  | 	case TableBody: | ||||||
|  | 		if entering { | ||||||
|  | 			r.cr(w) | ||||||
|  | 			r.out(w, tbodyTag) | ||||||
|  | 			// XXX: this is to adhere to a rather silly test. Should fix test. | ||||||
|  | 			if node.FirstChild == nil { | ||||||
|  | 				r.cr(w) | ||||||
|  | 			} | ||||||
|  | 		} else { | ||||||
|  | 			r.out(w, tbodyCloseTag) | ||||||
|  | 			r.cr(w) | ||||||
|  | 		} | ||||||
|  | 	case TableRow: | ||||||
|  | 		if entering { | ||||||
|  | 			r.cr(w) | ||||||
|  | 			r.out(w, trTag) | ||||||
|  | 		} else { | ||||||
|  | 			r.out(w, trCloseTag) | ||||||
|  | 			r.cr(w) | ||||||
|  | 		} | ||||||
|  | 	default: | ||||||
|  | 		panic("Unknown node type " + node.Type.String()) | ||||||
|  | 	} | ||||||
|  | 	return GoToNext | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // RenderHeader writes HTML document preamble and TOC if requested. | ||||||
|  | func (r *HTMLRenderer) RenderHeader(w io.Writer, ast *Node) { | ||||||
|  | 	r.writeDocumentHeader(w) | ||||||
|  | 	if r.Flags&TOC != 0 { | ||||||
|  | 		r.writeTOC(w, ast) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // RenderFooter writes HTML document footer. | ||||||
|  | func (r *HTMLRenderer) RenderFooter(w io.Writer, ast *Node) { | ||||||
|  | 	if r.Flags&CompletePage == 0 { | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  | 	io.WriteString(w, "\n</body>\n</html>\n") | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (r *HTMLRenderer) writeDocumentHeader(w io.Writer) { | ||||||
|  | 	if r.Flags&CompletePage == 0 { | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  | 	ending := "" | ||||||
|  | 	if r.Flags&UseXHTML != 0 { | ||||||
|  | 		io.WriteString(w, "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" ") | ||||||
|  | 		io.WriteString(w, "\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n") | ||||||
|  | 		io.WriteString(w, "<html xmlns=\"http://www.w3.org/1999/xhtml\">\n") | ||||||
|  | 		ending = " /" | ||||||
|  | 	} else { | ||||||
|  | 		io.WriteString(w, "<!DOCTYPE html>\n") | ||||||
|  | 		io.WriteString(w, "<html>\n") | ||||||
|  | 	} | ||||||
|  | 	io.WriteString(w, "<head>\n") | ||||||
|  | 	io.WriteString(w, "  <title>") | ||||||
|  | 	if r.Flags&Smartypants != 0 { | ||||||
|  | 		r.sr.Process(w, []byte(r.Title)) | ||||||
|  | 	} else { | ||||||
|  | 		escapeHTML(w, []byte(r.Title)) | ||||||
|  | 	} | ||||||
|  | 	io.WriteString(w, "</title>\n") | ||||||
|  | 	io.WriteString(w, "  <meta name=\"GENERATOR\" content=\"Blackfriday Markdown Processor v") | ||||||
|  | 	io.WriteString(w, Version) | ||||||
|  | 	io.WriteString(w, "\"") | ||||||
|  | 	io.WriteString(w, ending) | ||||||
|  | 	io.WriteString(w, ">\n") | ||||||
|  | 	io.WriteString(w, "  <meta charset=\"utf-8\"") | ||||||
|  | 	io.WriteString(w, ending) | ||||||
|  | 	io.WriteString(w, ">\n") | ||||||
|  | 	if r.CSS != "" { | ||||||
|  | 		io.WriteString(w, "  <link rel=\"stylesheet\" type=\"text/css\" href=\"") | ||||||
|  | 		escapeHTML(w, []byte(r.CSS)) | ||||||
|  | 		io.WriteString(w, "\"") | ||||||
|  | 		io.WriteString(w, ending) | ||||||
|  | 		io.WriteString(w, ">\n") | ||||||
|  | 	} | ||||||
|  | 	if r.Icon != "" { | ||||||
|  | 		io.WriteString(w, "  <link rel=\"icon\" type=\"image/x-icon\" href=\"") | ||||||
|  | 		escapeHTML(w, []byte(r.Icon)) | ||||||
|  | 		io.WriteString(w, "\"") | ||||||
|  | 		io.WriteString(w, ending) | ||||||
|  | 		io.WriteString(w, ">\n") | ||||||
|  | 	} | ||||||
|  | 	io.WriteString(w, "</head>\n") | ||||||
|  | 	io.WriteString(w, "<body>\n\n") | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (r *HTMLRenderer) writeTOC(w io.Writer, ast *Node) { | ||||||
|  | 	buf := bytes.Buffer{} | ||||||
|  |  | ||||||
|  | 	inHeading := false | ||||||
|  | 	tocLevel := 0 | ||||||
|  | 	headingCount := 0 | ||||||
|  |  | ||||||
|  | 	ast.Walk(func(node *Node, entering bool) WalkStatus { | ||||||
|  | 		if node.Type == Heading && !node.HeadingData.IsTitleblock { | ||||||
|  | 			inHeading = entering | ||||||
|  | 			if entering { | ||||||
|  | 				node.HeadingID = fmt.Sprintf("toc_%d", headingCount) | ||||||
|  | 				if node.Level == tocLevel { | ||||||
|  | 					buf.WriteString("</li>\n\n<li>") | ||||||
|  | 				} else if node.Level < tocLevel { | ||||||
|  | 					for node.Level < tocLevel { | ||||||
|  | 						tocLevel-- | ||||||
|  | 						buf.WriteString("</li>\n</ul>") | ||||||
|  | 					} | ||||||
|  | 					buf.WriteString("</li>\n\n<li>") | ||||||
|  | 				} else { | ||||||
|  | 					for node.Level > tocLevel { | ||||||
|  | 						tocLevel++ | ||||||
|  | 						buf.WriteString("\n<ul>\n<li>") | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
|  |  | ||||||
|  | 				fmt.Fprintf(&buf, `<a href="#toc_%d">`, headingCount) | ||||||
|  | 				headingCount++ | ||||||
|  | 			} else { | ||||||
|  | 				buf.WriteString("</a>") | ||||||
|  | 			} | ||||||
|  | 			return GoToNext | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		if inHeading { | ||||||
|  | 			return r.RenderNode(&buf, node, entering) | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		return GoToNext | ||||||
|  | 	}) | ||||||
|  |  | ||||||
|  | 	for ; tocLevel > 0; tocLevel-- { | ||||||
|  | 		buf.WriteString("</li>\n</ul>") | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if buf.Len() > 0 { | ||||||
|  | 		io.WriteString(w, "<nav>\n") | ||||||
|  | 		w.Write(buf.Bytes()) | ||||||
|  | 		io.WriteString(w, "\n\n</nav>\n") | ||||||
|  | 	} | ||||||
|  | 	r.lastOutputLen = buf.Len() | ||||||
|  | } | ||||||
							
								
								
									
										1228
									
								
								vendor/github.com/russross/blackfriday/v2/inline.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1228
									
								
								vendor/github.com/russross/blackfriday/v2/inline.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										950
									
								
								vendor/github.com/russross/blackfriday/v2/markdown.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										950
									
								
								vendor/github.com/russross/blackfriday/v2/markdown.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,950 @@ | |||||||
|  | // Blackfriday Markdown Processor | ||||||
|  | // Available at http://github.com/russross/blackfriday | ||||||
|  | // | ||||||
|  | // Copyright © 2011 Russ Ross <russ@russross.com>. | ||||||
|  | // Distributed under the Simplified BSD License. | ||||||
|  | // See README.md for details. | ||||||
|  |  | ||||||
|  | package blackfriday | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"bytes" | ||||||
|  | 	"fmt" | ||||||
|  | 	"io" | ||||||
|  | 	"strings" | ||||||
|  | 	"unicode/utf8" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | // | ||||||
|  | // Markdown parsing and processing | ||||||
|  | // | ||||||
|  |  | ||||||
|  | // Version string of the package. Appears in the rendered document when | ||||||
|  | // CompletePage flag is on. | ||||||
|  | const Version = "2.0" | ||||||
|  |  | ||||||
|  | // Extensions is a bitwise or'ed collection of enabled Blackfriday's | ||||||
|  | // extensions. | ||||||
|  | type Extensions int | ||||||
|  |  | ||||||
|  | // These are the supported markdown parsing extensions. | ||||||
|  | // OR these values together to select multiple extensions. | ||||||
|  | const ( | ||||||
|  | 	NoExtensions           Extensions = 0 | ||||||
|  | 	NoIntraEmphasis        Extensions = 1 << iota // Ignore emphasis markers inside words | ||||||
|  | 	Tables                                        // Render tables | ||||||
|  | 	FencedCode                                    // Render fenced code blocks | ||||||
|  | 	Autolink                                      // Detect embedded URLs that are not explicitly marked | ||||||
|  | 	Strikethrough                                 // Strikethrough text using ~~test~~ | ||||||
|  | 	LaxHTMLBlocks                                 // Loosen up HTML block parsing rules | ||||||
|  | 	SpaceHeadings                                 // Be strict about prefix heading rules | ||||||
|  | 	HardLineBreak                                 // Translate newlines into line breaks | ||||||
|  | 	TabSizeEight                                  // Expand tabs to eight spaces instead of four | ||||||
|  | 	Footnotes                                     // Pandoc-style footnotes | ||||||
|  | 	NoEmptyLineBeforeBlock                        // No need to insert an empty line to start a (code, quote, ordered list, unordered list) block | ||||||
|  | 	HeadingIDs                                    // specify heading IDs  with {#id} | ||||||
|  | 	Titleblock                                    // Titleblock ala pandoc | ||||||
|  | 	AutoHeadingIDs                                // Create the heading ID from the text | ||||||
|  | 	BackslashLineBreak                            // Translate trailing backslashes into line breaks | ||||||
|  | 	DefinitionLists                               // Render definition lists | ||||||
|  |  | ||||||
|  | 	CommonHTMLFlags HTMLFlags = UseXHTML | Smartypants | | ||||||
|  | 		SmartypantsFractions | SmartypantsDashes | SmartypantsLatexDashes | ||||||
|  |  | ||||||
|  | 	CommonExtensions Extensions = NoIntraEmphasis | Tables | FencedCode | | ||||||
|  | 		Autolink | Strikethrough | SpaceHeadings | HeadingIDs | | ||||||
|  | 		BackslashLineBreak | DefinitionLists | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | // ListType contains bitwise or'ed flags for list and list item objects. | ||||||
|  | type ListType int | ||||||
|  |  | ||||||
|  | // These are the possible flag values for the ListItem renderer. | ||||||
|  | // Multiple flag values may be ORed together. | ||||||
|  | // These are mostly of interest if you are writing a new output format. | ||||||
|  | const ( | ||||||
|  | 	ListTypeOrdered ListType = 1 << iota | ||||||
|  | 	ListTypeDefinition | ||||||
|  | 	ListTypeTerm | ||||||
|  |  | ||||||
|  | 	ListItemContainsBlock | ||||||
|  | 	ListItemBeginningOfList // TODO: figure out if this is of any use now | ||||||
|  | 	ListItemEndOfList | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | // CellAlignFlags holds a type of alignment in a table cell. | ||||||
|  | type CellAlignFlags int | ||||||
|  |  | ||||||
|  | // These are the possible flag values for the table cell renderer. | ||||||
|  | // Only a single one of these values will be used; they are not ORed together. | ||||||
|  | // These are mostly of interest if you are writing a new output format. | ||||||
|  | const ( | ||||||
|  | 	TableAlignmentLeft CellAlignFlags = 1 << iota | ||||||
|  | 	TableAlignmentRight | ||||||
|  | 	TableAlignmentCenter = (TableAlignmentLeft | TableAlignmentRight) | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | // The size of a tab stop. | ||||||
|  | const ( | ||||||
|  | 	TabSizeDefault = 4 | ||||||
|  | 	TabSizeDouble  = 8 | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | // blockTags is a set of tags that are recognized as HTML block tags. | ||||||
|  | // Any of these can be included in markdown text without special escaping. | ||||||
|  | var blockTags = map[string]struct{}{ | ||||||
|  | 	"blockquote": {}, | ||||||
|  | 	"del":        {}, | ||||||
|  | 	"div":        {}, | ||||||
|  | 	"dl":         {}, | ||||||
|  | 	"fieldset":   {}, | ||||||
|  | 	"form":       {}, | ||||||
|  | 	"h1":         {}, | ||||||
|  | 	"h2":         {}, | ||||||
|  | 	"h3":         {}, | ||||||
|  | 	"h4":         {}, | ||||||
|  | 	"h5":         {}, | ||||||
|  | 	"h6":         {}, | ||||||
|  | 	"iframe":     {}, | ||||||
|  | 	"ins":        {}, | ||||||
|  | 	"math":       {}, | ||||||
|  | 	"noscript":   {}, | ||||||
|  | 	"ol":         {}, | ||||||
|  | 	"pre":        {}, | ||||||
|  | 	"p":          {}, | ||||||
|  | 	"script":     {}, | ||||||
|  | 	"style":      {}, | ||||||
|  | 	"table":      {}, | ||||||
|  | 	"ul":         {}, | ||||||
|  |  | ||||||
|  | 	// HTML5 | ||||||
|  | 	"address":    {}, | ||||||
|  | 	"article":    {}, | ||||||
|  | 	"aside":      {}, | ||||||
|  | 	"canvas":     {}, | ||||||
|  | 	"figcaption": {}, | ||||||
|  | 	"figure":     {}, | ||||||
|  | 	"footer":     {}, | ||||||
|  | 	"header":     {}, | ||||||
|  | 	"hgroup":     {}, | ||||||
|  | 	"main":       {}, | ||||||
|  | 	"nav":        {}, | ||||||
|  | 	"output":     {}, | ||||||
|  | 	"progress":   {}, | ||||||
|  | 	"section":    {}, | ||||||
|  | 	"video":      {}, | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Renderer is the rendering interface. This is mostly of interest if you are | ||||||
|  | // implementing a new rendering format. | ||||||
|  | // | ||||||
|  | // Only an HTML implementation is provided in this repository, see the README | ||||||
|  | // for external implementations. | ||||||
|  | type Renderer interface { | ||||||
|  | 	// RenderNode is the main rendering method. It will be called once for | ||||||
|  | 	// every leaf node and twice for every non-leaf node (first with | ||||||
|  | 	// entering=true, then with entering=false). The method should write its | ||||||
|  | 	// rendition of the node to the supplied writer w. | ||||||
|  | 	RenderNode(w io.Writer, node *Node, entering bool) WalkStatus | ||||||
|  |  | ||||||
|  | 	// RenderHeader is a method that allows the renderer to produce some | ||||||
|  | 	// content preceding the main body of the output document. The header is | ||||||
|  | 	// understood in the broad sense here. For example, the default HTML | ||||||
|  | 	// renderer will write not only the HTML document preamble, but also the | ||||||
|  | 	// table of contents if it was requested. | ||||||
|  | 	// | ||||||
|  | 	// The method will be passed an entire document tree, in case a particular | ||||||
|  | 	// implementation needs to inspect it to produce output. | ||||||
|  | 	// | ||||||
|  | 	// The output should be written to the supplied writer w. If your | ||||||
|  | 	// implementation has no header to write, supply an empty implementation. | ||||||
|  | 	RenderHeader(w io.Writer, ast *Node) | ||||||
|  |  | ||||||
|  | 	// RenderFooter is a symmetric counterpart of RenderHeader. | ||||||
|  | 	RenderFooter(w io.Writer, ast *Node) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Callback functions for inline parsing. One such function is defined | ||||||
|  | // for each character that triggers a response when parsing inline data. | ||||||
|  | type inlineParser func(p *Markdown, data []byte, offset int) (int, *Node) | ||||||
|  |  | ||||||
|  | // Markdown is a type that holds extensions and the runtime state used by | ||||||
|  | // Parse, and the renderer. You can not use it directly, construct it with New. | ||||||
|  | type Markdown struct { | ||||||
|  | 	renderer          Renderer | ||||||
|  | 	referenceOverride ReferenceOverrideFunc | ||||||
|  | 	refs              map[string]*reference | ||||||
|  | 	inlineCallback    [256]inlineParser | ||||||
|  | 	extensions        Extensions | ||||||
|  | 	nesting           int | ||||||
|  | 	maxNesting        int | ||||||
|  | 	insideLink        bool | ||||||
|  |  | ||||||
|  | 	// Footnotes need to be ordered as well as available to quickly check for | ||||||
|  | 	// presence. If a ref is also a footnote, it's stored both in refs and here | ||||||
|  | 	// in notes. Slice is nil if footnotes not enabled. | ||||||
|  | 	notes []*reference | ||||||
|  |  | ||||||
|  | 	doc                  *Node | ||||||
|  | 	tip                  *Node // = doc | ||||||
|  | 	oldTip               *Node | ||||||
|  | 	lastMatchedContainer *Node // = doc | ||||||
|  | 	allClosed            bool | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (p *Markdown) getRef(refid string) (ref *reference, found bool) { | ||||||
|  | 	if p.referenceOverride != nil { | ||||||
|  | 		r, overridden := p.referenceOverride(refid) | ||||||
|  | 		if overridden { | ||||||
|  | 			if r == nil { | ||||||
|  | 				return nil, false | ||||||
|  | 			} | ||||||
|  | 			return &reference{ | ||||||
|  | 				link:     []byte(r.Link), | ||||||
|  | 				title:    []byte(r.Title), | ||||||
|  | 				noteID:   0, | ||||||
|  | 				hasBlock: false, | ||||||
|  | 				text:     []byte(r.Text)}, true | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	// refs are case insensitive | ||||||
|  | 	ref, found = p.refs[strings.ToLower(refid)] | ||||||
|  | 	return ref, found | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (p *Markdown) finalize(block *Node) { | ||||||
|  | 	above := block.Parent | ||||||
|  | 	block.open = false | ||||||
|  | 	p.tip = above | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (p *Markdown) addChild(node NodeType, offset uint32) *Node { | ||||||
|  | 	return p.addExistingChild(NewNode(node), offset) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (p *Markdown) addExistingChild(node *Node, offset uint32) *Node { | ||||||
|  | 	for !p.tip.canContain(node.Type) { | ||||||
|  | 		p.finalize(p.tip) | ||||||
|  | 	} | ||||||
|  | 	p.tip.AppendChild(node) | ||||||
|  | 	p.tip = node | ||||||
|  | 	return node | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (p *Markdown) closeUnmatchedBlocks() { | ||||||
|  | 	if !p.allClosed { | ||||||
|  | 		for p.oldTip != p.lastMatchedContainer { | ||||||
|  | 			parent := p.oldTip.Parent | ||||||
|  | 			p.finalize(p.oldTip) | ||||||
|  | 			p.oldTip = parent | ||||||
|  | 		} | ||||||
|  | 		p.allClosed = true | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // | ||||||
|  | // | ||||||
|  | // Public interface | ||||||
|  | // | ||||||
|  | // | ||||||
|  |  | ||||||
|  | // Reference represents the details of a link. | ||||||
|  | // See the documentation in Options for more details on use-case. | ||||||
|  | type Reference struct { | ||||||
|  | 	// Link is usually the URL the reference points to. | ||||||
|  | 	Link string | ||||||
|  | 	// Title is the alternate text describing the link in more detail. | ||||||
|  | 	Title string | ||||||
|  | 	// Text is the optional text to override the ref with if the syntax used was | ||||||
|  | 	// [refid][] | ||||||
|  | 	Text string | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // ReferenceOverrideFunc is expected to be called with a reference string and | ||||||
|  | // return either a valid Reference type that the reference string maps to or | ||||||
|  | // nil. If overridden is false, the default reference logic will be executed. | ||||||
|  | // See the documentation in Options for more details on use-case. | ||||||
|  | type ReferenceOverrideFunc func(reference string) (ref *Reference, overridden bool) | ||||||
|  |  | ||||||
|  | // New constructs a Markdown processor. You can use the same With* functions as | ||||||
|  | // for Run() to customize parser's behavior and the renderer. | ||||||
|  | func New(opts ...Option) *Markdown { | ||||||
|  | 	var p Markdown | ||||||
|  | 	for _, opt := range opts { | ||||||
|  | 		opt(&p) | ||||||
|  | 	} | ||||||
|  | 	p.refs = make(map[string]*reference) | ||||||
|  | 	p.maxNesting = 16 | ||||||
|  | 	p.insideLink = false | ||||||
|  | 	docNode := NewNode(Document) | ||||||
|  | 	p.doc = docNode | ||||||
|  | 	p.tip = docNode | ||||||
|  | 	p.oldTip = docNode | ||||||
|  | 	p.lastMatchedContainer = docNode | ||||||
|  | 	p.allClosed = true | ||||||
|  | 	// register inline parsers | ||||||
|  | 	p.inlineCallback[' '] = maybeLineBreak | ||||||
|  | 	p.inlineCallback['*'] = emphasis | ||||||
|  | 	p.inlineCallback['_'] = emphasis | ||||||
|  | 	if p.extensions&Strikethrough != 0 { | ||||||
|  | 		p.inlineCallback['~'] = emphasis | ||||||
|  | 	} | ||||||
|  | 	p.inlineCallback['`'] = codeSpan | ||||||
|  | 	p.inlineCallback['\n'] = lineBreak | ||||||
|  | 	p.inlineCallback['['] = link | ||||||
|  | 	p.inlineCallback['<'] = leftAngle | ||||||
|  | 	p.inlineCallback['\\'] = escape | ||||||
|  | 	p.inlineCallback['&'] = entity | ||||||
|  | 	p.inlineCallback['!'] = maybeImage | ||||||
|  | 	p.inlineCallback['^'] = maybeInlineFootnote | ||||||
|  | 	if p.extensions&Autolink != 0 { | ||||||
|  | 		p.inlineCallback['h'] = maybeAutoLink | ||||||
|  | 		p.inlineCallback['m'] = maybeAutoLink | ||||||
|  | 		p.inlineCallback['f'] = maybeAutoLink | ||||||
|  | 		p.inlineCallback['H'] = maybeAutoLink | ||||||
|  | 		p.inlineCallback['M'] = maybeAutoLink | ||||||
|  | 		p.inlineCallback['F'] = maybeAutoLink | ||||||
|  | 	} | ||||||
|  | 	if p.extensions&Footnotes != 0 { | ||||||
|  | 		p.notes = make([]*reference, 0) | ||||||
|  | 	} | ||||||
|  | 	return &p | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Option customizes the Markdown processor's default behavior. | ||||||
|  | type Option func(*Markdown) | ||||||
|  |  | ||||||
|  | // WithRenderer allows you to override the default renderer. | ||||||
|  | func WithRenderer(r Renderer) Option { | ||||||
|  | 	return func(p *Markdown) { | ||||||
|  | 		p.renderer = r | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // WithExtensions allows you to pick some of the many extensions provided by | ||||||
|  | // Blackfriday. You can bitwise OR them. | ||||||
|  | func WithExtensions(e Extensions) Option { | ||||||
|  | 	return func(p *Markdown) { | ||||||
|  | 		p.extensions = e | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // WithNoExtensions turns off all extensions and custom behavior. | ||||||
|  | func WithNoExtensions() Option { | ||||||
|  | 	return func(p *Markdown) { | ||||||
|  | 		p.extensions = NoExtensions | ||||||
|  | 		p.renderer = NewHTMLRenderer(HTMLRendererParameters{ | ||||||
|  | 			Flags: HTMLFlagsNone, | ||||||
|  | 		}) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // WithRefOverride sets an optional function callback that is called every | ||||||
|  | // time a reference is resolved. | ||||||
|  | // | ||||||
|  | // In Markdown, the link reference syntax can be made to resolve a link to | ||||||
|  | // a reference instead of an inline URL, in one of the following ways: | ||||||
|  | // | ||||||
|  | //  * [link text][refid] | ||||||
|  | //  * [refid][] | ||||||
|  | // | ||||||
|  | // Usually, the refid is defined at the bottom of the Markdown document. If | ||||||
|  | // this override function is provided, the refid is passed to the override | ||||||
|  | // function first, before consulting the defined refids at the bottom. If | ||||||
|  | // the override function indicates an override did not occur, the refids at | ||||||
|  | // the bottom will be used to fill in the link details. | ||||||
|  | func WithRefOverride(o ReferenceOverrideFunc) Option { | ||||||
|  | 	return func(p *Markdown) { | ||||||
|  | 		p.referenceOverride = o | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Run is the main entry point to Blackfriday. It parses and renders a | ||||||
|  | // block of markdown-encoded text. | ||||||
|  | // | ||||||
|  | // The simplest invocation of Run takes one argument, input: | ||||||
|  | //     output := Run(input) | ||||||
|  | // This will parse the input with CommonExtensions enabled and render it with | ||||||
|  | // the default HTMLRenderer (with CommonHTMLFlags). | ||||||
|  | // | ||||||
|  | // Variadic arguments opts can customize the default behavior. Since Markdown | ||||||
|  | // type does not contain exported fields, you can not use it directly. Instead, | ||||||
|  | // use the With* functions. For example, this will call the most basic | ||||||
|  | // functionality, with no extensions: | ||||||
|  | //     output := Run(input, WithNoExtensions()) | ||||||
|  | // | ||||||
|  | // You can use any number of With* arguments, even contradicting ones. They | ||||||
|  | // will be applied in order of appearance and the latter will override the | ||||||
|  | // former: | ||||||
|  | //     output := Run(input, WithNoExtensions(), WithExtensions(exts), | ||||||
|  | //         WithRenderer(yourRenderer)) | ||||||
|  | func Run(input []byte, opts ...Option) []byte { | ||||||
|  | 	r := NewHTMLRenderer(HTMLRendererParameters{ | ||||||
|  | 		Flags: CommonHTMLFlags, | ||||||
|  | 	}) | ||||||
|  | 	optList := []Option{WithRenderer(r), WithExtensions(CommonExtensions)} | ||||||
|  | 	optList = append(optList, opts...) | ||||||
|  | 	parser := New(optList...) | ||||||
|  | 	ast := parser.Parse(input) | ||||||
|  | 	var buf bytes.Buffer | ||||||
|  | 	parser.renderer.RenderHeader(&buf, ast) | ||||||
|  | 	ast.Walk(func(node *Node, entering bool) WalkStatus { | ||||||
|  | 		return parser.renderer.RenderNode(&buf, node, entering) | ||||||
|  | 	}) | ||||||
|  | 	parser.renderer.RenderFooter(&buf, ast) | ||||||
|  | 	return buf.Bytes() | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Parse is an entry point to the parsing part of Blackfriday. It takes an | ||||||
|  | // input markdown document and produces a syntax tree for its contents. This | ||||||
|  | // tree can then be rendered with a default or custom renderer, or | ||||||
|  | // analyzed/transformed by the caller to whatever non-standard needs they have. | ||||||
|  | // The return value is the root node of the syntax tree. | ||||||
|  | func (p *Markdown) Parse(input []byte) *Node { | ||||||
|  | 	p.block(input) | ||||||
|  | 	// Walk the tree and finish up some of unfinished blocks | ||||||
|  | 	for p.tip != nil { | ||||||
|  | 		p.finalize(p.tip) | ||||||
|  | 	} | ||||||
|  | 	// Walk the tree again and process inline markdown in each block | ||||||
|  | 	p.doc.Walk(func(node *Node, entering bool) WalkStatus { | ||||||
|  | 		if node.Type == Paragraph || node.Type == Heading || node.Type == TableCell { | ||||||
|  | 			p.inline(node, node.content) | ||||||
|  | 			node.content = nil | ||||||
|  | 		} | ||||||
|  | 		return GoToNext | ||||||
|  | 	}) | ||||||
|  | 	p.parseRefsToAST() | ||||||
|  | 	return p.doc | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (p *Markdown) parseRefsToAST() { | ||||||
|  | 	if p.extensions&Footnotes == 0 || len(p.notes) == 0 { | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  | 	p.tip = p.doc | ||||||
|  | 	block := p.addBlock(List, nil) | ||||||
|  | 	block.IsFootnotesList = true | ||||||
|  | 	block.ListFlags = ListTypeOrdered | ||||||
|  | 	flags := ListItemBeginningOfList | ||||||
|  | 	// Note: this loop is intentionally explicit, not range-form. This is | ||||||
|  | 	// because the body of the loop will append nested footnotes to p.notes and | ||||||
|  | 	// we need to process those late additions. Range form would only walk over | ||||||
|  | 	// the fixed initial set. | ||||||
|  | 	for i := 0; i < len(p.notes); i++ { | ||||||
|  | 		ref := p.notes[i] | ||||||
|  | 		p.addExistingChild(ref.footnote, 0) | ||||||
|  | 		block := ref.footnote | ||||||
|  | 		block.ListFlags = flags | ListTypeOrdered | ||||||
|  | 		block.RefLink = ref.link | ||||||
|  | 		if ref.hasBlock { | ||||||
|  | 			flags |= ListItemContainsBlock | ||||||
|  | 			p.block(ref.title) | ||||||
|  | 		} else { | ||||||
|  | 			p.inline(block, ref.title) | ||||||
|  | 		} | ||||||
|  | 		flags &^= ListItemBeginningOfList | ListItemContainsBlock | ||||||
|  | 	} | ||||||
|  | 	above := block.Parent | ||||||
|  | 	finalizeList(block) | ||||||
|  | 	p.tip = above | ||||||
|  | 	block.Walk(func(node *Node, entering bool) WalkStatus { | ||||||
|  | 		if node.Type == Paragraph || node.Type == Heading { | ||||||
|  | 			p.inline(node, node.content) | ||||||
|  | 			node.content = nil | ||||||
|  | 		} | ||||||
|  | 		return GoToNext | ||||||
|  | 	}) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // | ||||||
|  | // Link references | ||||||
|  | // | ||||||
|  | // This section implements support for references that (usually) appear | ||||||
|  | // as footnotes in a document, and can be referenced anywhere in the document. | ||||||
|  | // The basic format is: | ||||||
|  | // | ||||||
|  | //    [1]: http://www.google.com/ "Google" | ||||||
|  | //    [2]: http://www.github.com/ "Github" | ||||||
|  | // | ||||||
|  | // Anywhere in the document, the reference can be linked by referring to its | ||||||
|  | // label, i.e., 1 and 2 in this example, as in: | ||||||
|  | // | ||||||
|  | //    This library is hosted on [Github][2], a git hosting site. | ||||||
|  | // | ||||||
|  | // Actual footnotes as specified in Pandoc and supported by some other Markdown | ||||||
|  | // libraries such as php-markdown are also taken care of. They look like this: | ||||||
|  | // | ||||||
|  | //    This sentence needs a bit of further explanation.[^note] | ||||||
|  | // | ||||||
|  | //    [^note]: This is the explanation. | ||||||
|  | // | ||||||
|  | // Footnotes should be placed at the end of the document in an ordered list. | ||||||
|  | // Finally, there are inline footnotes such as: | ||||||
|  | // | ||||||
|  | //    Inline footnotes^[Also supported.] provide a quick inline explanation, | ||||||
|  | //    but are rendered at the bottom of the document. | ||||||
|  | // | ||||||
|  |  | ||||||
|  | // reference holds all information necessary for a reference-style links or | ||||||
|  | // footnotes. | ||||||
|  | // | ||||||
|  | // Consider this markdown with reference-style links: | ||||||
|  | // | ||||||
|  | //     [link][ref] | ||||||
|  | // | ||||||
|  | //     [ref]: /url/ "tooltip title" | ||||||
|  | // | ||||||
|  | // It will be ultimately converted to this HTML: | ||||||
|  | // | ||||||
|  | //     <p><a href=\"/url/\" title=\"title\">link</a></p> | ||||||
|  | // | ||||||
|  | // And a reference structure will be populated as follows: | ||||||
|  | // | ||||||
|  | //     p.refs["ref"] = &reference{ | ||||||
|  | //         link: "/url/", | ||||||
|  | //         title: "tooltip title", | ||||||
|  | //     } | ||||||
|  | // | ||||||
|  | // Alternatively, reference can contain information about a footnote. Consider | ||||||
|  | // this markdown: | ||||||
|  | // | ||||||
|  | //     Text needing a footnote.[^a] | ||||||
|  | // | ||||||
|  | //     [^a]: This is the note | ||||||
|  | // | ||||||
|  | // A reference structure will be populated as follows: | ||||||
|  | // | ||||||
|  | //     p.refs["a"] = &reference{ | ||||||
|  | //         link: "a", | ||||||
|  | //         title: "This is the note", | ||||||
|  | //         noteID: <some positive int>, | ||||||
|  | //     } | ||||||
|  | // | ||||||
|  | // TODO: As you can see, it begs for splitting into two dedicated structures | ||||||
|  | // for refs and for footnotes. | ||||||
|  | type reference struct { | ||||||
|  | 	link     []byte | ||||||
|  | 	title    []byte | ||||||
|  | 	noteID   int // 0 if not a footnote ref | ||||||
|  | 	hasBlock bool | ||||||
|  | 	footnote *Node // a link to the Item node within a list of footnotes | ||||||
|  |  | ||||||
|  | 	text []byte // only gets populated by refOverride feature with Reference.Text | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (r *reference) String() string { | ||||||
|  | 	return fmt.Sprintf("{link: %q, title: %q, text: %q, noteID: %d, hasBlock: %v}", | ||||||
|  | 		r.link, r.title, r.text, r.noteID, r.hasBlock) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Check whether or not data starts with a reference link. | ||||||
|  | // If so, it is parsed and stored in the list of references | ||||||
|  | // (in the render struct). | ||||||
|  | // Returns the number of bytes to skip to move past it, | ||||||
|  | // or zero if the first line is not a reference. | ||||||
|  | func isReference(p *Markdown, data []byte, tabSize int) int { | ||||||
|  | 	// up to 3 optional leading spaces | ||||||
|  | 	if len(data) < 4 { | ||||||
|  | 		return 0 | ||||||
|  | 	} | ||||||
|  | 	i := 0 | ||||||
|  | 	for i < 3 && data[i] == ' ' { | ||||||
|  | 		i++ | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	noteID := 0 | ||||||
|  |  | ||||||
|  | 	// id part: anything but a newline between brackets | ||||||
|  | 	if data[i] != '[' { | ||||||
|  | 		return 0 | ||||||
|  | 	} | ||||||
|  | 	i++ | ||||||
|  | 	if p.extensions&Footnotes != 0 { | ||||||
|  | 		if i < len(data) && data[i] == '^' { | ||||||
|  | 			// we can set it to anything here because the proper noteIds will | ||||||
|  | 			// be assigned later during the second pass. It just has to be != 0 | ||||||
|  | 			noteID = 1 | ||||||
|  | 			i++ | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	idOffset := i | ||||||
|  | 	for i < len(data) && data[i] != '\n' && data[i] != '\r' && data[i] != ']' { | ||||||
|  | 		i++ | ||||||
|  | 	} | ||||||
|  | 	if i >= len(data) || data[i] != ']' { | ||||||
|  | 		return 0 | ||||||
|  | 	} | ||||||
|  | 	idEnd := i | ||||||
|  | 	// footnotes can have empty ID, like this: [^], but a reference can not be | ||||||
|  | 	// empty like this: []. Break early if it's not a footnote and there's no ID | ||||||
|  | 	if noteID == 0 && idOffset == idEnd { | ||||||
|  | 		return 0 | ||||||
|  | 	} | ||||||
|  | 	// spacer: colon (space | tab)* newline? (space | tab)* | ||||||
|  | 	i++ | ||||||
|  | 	if i >= len(data) || data[i] != ':' { | ||||||
|  | 		return 0 | ||||||
|  | 	} | ||||||
|  | 	i++ | ||||||
|  | 	for i < len(data) && (data[i] == ' ' || data[i] == '\t') { | ||||||
|  | 		i++ | ||||||
|  | 	} | ||||||
|  | 	if i < len(data) && (data[i] == '\n' || data[i] == '\r') { | ||||||
|  | 		i++ | ||||||
|  | 		if i < len(data) && data[i] == '\n' && data[i-1] == '\r' { | ||||||
|  | 			i++ | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	for i < len(data) && (data[i] == ' ' || data[i] == '\t') { | ||||||
|  | 		i++ | ||||||
|  | 	} | ||||||
|  | 	if i >= len(data) { | ||||||
|  | 		return 0 | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	var ( | ||||||
|  | 		linkOffset, linkEnd   int | ||||||
|  | 		titleOffset, titleEnd int | ||||||
|  | 		lineEnd               int | ||||||
|  | 		raw                   []byte | ||||||
|  | 		hasBlock              bool | ||||||
|  | 	) | ||||||
|  |  | ||||||
|  | 	if p.extensions&Footnotes != 0 && noteID != 0 { | ||||||
|  | 		linkOffset, linkEnd, raw, hasBlock = scanFootnote(p, data, i, tabSize) | ||||||
|  | 		lineEnd = linkEnd | ||||||
|  | 	} else { | ||||||
|  | 		linkOffset, linkEnd, titleOffset, titleEnd, lineEnd = scanLinkRef(p, data, i) | ||||||
|  | 	} | ||||||
|  | 	if lineEnd == 0 { | ||||||
|  | 		return 0 | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// a valid ref has been found | ||||||
|  |  | ||||||
|  | 	ref := &reference{ | ||||||
|  | 		noteID:   noteID, | ||||||
|  | 		hasBlock: hasBlock, | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if noteID > 0 { | ||||||
|  | 		// reusing the link field for the id since footnotes don't have links | ||||||
|  | 		ref.link = data[idOffset:idEnd] | ||||||
|  | 		// if footnote, it's not really a title, it's the contained text | ||||||
|  | 		ref.title = raw | ||||||
|  | 	} else { | ||||||
|  | 		ref.link = data[linkOffset:linkEnd] | ||||||
|  | 		ref.title = data[titleOffset:titleEnd] | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// id matches are case-insensitive | ||||||
|  | 	id := string(bytes.ToLower(data[idOffset:idEnd])) | ||||||
|  |  | ||||||
|  | 	p.refs[id] = ref | ||||||
|  |  | ||||||
|  | 	return lineEnd | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func scanLinkRef(p *Markdown, data []byte, i int) (linkOffset, linkEnd, titleOffset, titleEnd, lineEnd int) { | ||||||
|  | 	// link: whitespace-free sequence, optionally between angle brackets | ||||||
|  | 	if data[i] == '<' { | ||||||
|  | 		i++ | ||||||
|  | 	} | ||||||
|  | 	linkOffset = i | ||||||
|  | 	for i < len(data) && data[i] != ' ' && data[i] != '\t' && data[i] != '\n' && data[i] != '\r' { | ||||||
|  | 		i++ | ||||||
|  | 	} | ||||||
|  | 	linkEnd = i | ||||||
|  | 	if data[linkOffset] == '<' && data[linkEnd-1] == '>' { | ||||||
|  | 		linkOffset++ | ||||||
|  | 		linkEnd-- | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// optional spacer: (space | tab)* (newline | '\'' | '"' | '(' ) | ||||||
|  | 	for i < len(data) && (data[i] == ' ' || data[i] == '\t') { | ||||||
|  | 		i++ | ||||||
|  | 	} | ||||||
|  | 	if i < len(data) && data[i] != '\n' && data[i] != '\r' && data[i] != '\'' && data[i] != '"' && data[i] != '(' { | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// compute end-of-line | ||||||
|  | 	if i >= len(data) || data[i] == '\r' || data[i] == '\n' { | ||||||
|  | 		lineEnd = i | ||||||
|  | 	} | ||||||
|  | 	if i+1 < len(data) && data[i] == '\r' && data[i+1] == '\n' { | ||||||
|  | 		lineEnd++ | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// optional (space|tab)* spacer after a newline | ||||||
|  | 	if lineEnd > 0 { | ||||||
|  | 		i = lineEnd + 1 | ||||||
|  | 		for i < len(data) && (data[i] == ' ' || data[i] == '\t') { | ||||||
|  | 			i++ | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// optional title: any non-newline sequence enclosed in '"() alone on its line | ||||||
|  | 	if i+1 < len(data) && (data[i] == '\'' || data[i] == '"' || data[i] == '(') { | ||||||
|  | 		i++ | ||||||
|  | 		titleOffset = i | ||||||
|  |  | ||||||
|  | 		// look for EOL | ||||||
|  | 		for i < len(data) && data[i] != '\n' && data[i] != '\r' { | ||||||
|  | 			i++ | ||||||
|  | 		} | ||||||
|  | 		if i+1 < len(data) && data[i] == '\n' && data[i+1] == '\r' { | ||||||
|  | 			titleEnd = i + 1 | ||||||
|  | 		} else { | ||||||
|  | 			titleEnd = i | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		// step back | ||||||
|  | 		i-- | ||||||
|  | 		for i > titleOffset && (data[i] == ' ' || data[i] == '\t') { | ||||||
|  | 			i-- | ||||||
|  | 		} | ||||||
|  | 		if i > titleOffset && (data[i] == '\'' || data[i] == '"' || data[i] == ')') { | ||||||
|  | 			lineEnd = titleEnd | ||||||
|  | 			titleEnd = i | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // The first bit of this logic is the same as Parser.listItem, but the rest | ||||||
|  | // is much simpler. This function simply finds the entire block and shifts it | ||||||
|  | // over by one tab if it is indeed a block (just returns the line if it's not). | ||||||
|  | // blockEnd is the end of the section in the input buffer, and contents is the | ||||||
|  | // extracted text that was shifted over one tab. It will need to be rendered at | ||||||
|  | // the end of the document. | ||||||
|  | func scanFootnote(p *Markdown, data []byte, i, indentSize int) (blockStart, blockEnd int, contents []byte, hasBlock bool) { | ||||||
|  | 	if i == 0 || len(data) == 0 { | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// skip leading whitespace on first line | ||||||
|  | 	for i < len(data) && data[i] == ' ' { | ||||||
|  | 		i++ | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	blockStart = i | ||||||
|  |  | ||||||
|  | 	// find the end of the line | ||||||
|  | 	blockEnd = i | ||||||
|  | 	for i < len(data) && data[i-1] != '\n' { | ||||||
|  | 		i++ | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// get working buffer | ||||||
|  | 	var raw bytes.Buffer | ||||||
|  |  | ||||||
|  | 	// put the first line into the working buffer | ||||||
|  | 	raw.Write(data[blockEnd:i]) | ||||||
|  | 	blockEnd = i | ||||||
|  |  | ||||||
|  | 	// process the following lines | ||||||
|  | 	containsBlankLine := false | ||||||
|  |  | ||||||
|  | gatherLines: | ||||||
|  | 	for blockEnd < len(data) { | ||||||
|  | 		i++ | ||||||
|  |  | ||||||
|  | 		// find the end of this line | ||||||
|  | 		for i < len(data) && data[i-1] != '\n' { | ||||||
|  | 			i++ | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		// if it is an empty line, guess that it is part of this item | ||||||
|  | 		// and move on to the next line | ||||||
|  | 		if p.isEmpty(data[blockEnd:i]) > 0 { | ||||||
|  | 			containsBlankLine = true | ||||||
|  | 			blockEnd = i | ||||||
|  | 			continue | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		n := 0 | ||||||
|  | 		if n = isIndented(data[blockEnd:i], indentSize); n == 0 { | ||||||
|  | 			// this is the end of the block. | ||||||
|  | 			// we don't want to include this last line in the index. | ||||||
|  | 			break gatherLines | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		// if there were blank lines before this one, insert a new one now | ||||||
|  | 		if containsBlankLine { | ||||||
|  | 			raw.WriteByte('\n') | ||||||
|  | 			containsBlankLine = false | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		// get rid of that first tab, write to buffer | ||||||
|  | 		raw.Write(data[blockEnd+n : i]) | ||||||
|  | 		hasBlock = true | ||||||
|  |  | ||||||
|  | 		blockEnd = i | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if data[blockEnd-1] != '\n' { | ||||||
|  | 		raw.WriteByte('\n') | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	contents = raw.Bytes() | ||||||
|  |  | ||||||
|  | 	return | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // | ||||||
|  | // | ||||||
|  | // Miscellaneous helper functions | ||||||
|  | // | ||||||
|  | // | ||||||
|  |  | ||||||
|  | // Test if a character is a punctuation symbol. | ||||||
|  | // Taken from a private function in regexp in the stdlib. | ||||||
|  | func ispunct(c byte) bool { | ||||||
|  | 	for _, r := range []byte("!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~") { | ||||||
|  | 		if c == r { | ||||||
|  | 			return true | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return false | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Test if a character is a whitespace character. | ||||||
|  | func isspace(c byte) bool { | ||||||
|  | 	return ishorizontalspace(c) || isverticalspace(c) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Test if a character is a horizontal whitespace character. | ||||||
|  | func ishorizontalspace(c byte) bool { | ||||||
|  | 	return c == ' ' || c == '\t' | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Test if a character is a vertical character. | ||||||
|  | func isverticalspace(c byte) bool { | ||||||
|  | 	return c == '\n' || c == '\r' || c == '\f' || c == '\v' | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Test if a character is letter. | ||||||
|  | func isletter(c byte) bool { | ||||||
|  | 	return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Test if a character is a letter or a digit. | ||||||
|  | // TODO: check when this is looking for ASCII alnum and when it should use unicode | ||||||
|  | func isalnum(c byte) bool { | ||||||
|  | 	return (c >= '0' && c <= '9') || isletter(c) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Replace tab characters with spaces, aligning to the next TAB_SIZE column. | ||||||
|  | // always ends output with a newline | ||||||
|  | func expandTabs(out *bytes.Buffer, line []byte, tabSize int) { | ||||||
|  | 	// first, check for common cases: no tabs, or only tabs at beginning of line | ||||||
|  | 	i, prefix := 0, 0 | ||||||
|  | 	slowcase := false | ||||||
|  | 	for i = 0; i < len(line); i++ { | ||||||
|  | 		if line[i] == '\t' { | ||||||
|  | 			if prefix == i { | ||||||
|  | 				prefix++ | ||||||
|  | 			} else { | ||||||
|  | 				slowcase = true | ||||||
|  | 				break | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// no need to decode runes if all tabs are at the beginning of the line | ||||||
|  | 	if !slowcase { | ||||||
|  | 		for i = 0; i < prefix*tabSize; i++ { | ||||||
|  | 			out.WriteByte(' ') | ||||||
|  | 		} | ||||||
|  | 		out.Write(line[prefix:]) | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// the slow case: we need to count runes to figure out how | ||||||
|  | 	// many spaces to insert for each tab | ||||||
|  | 	column := 0 | ||||||
|  | 	i = 0 | ||||||
|  | 	for i < len(line) { | ||||||
|  | 		start := i | ||||||
|  | 		for i < len(line) && line[i] != '\t' { | ||||||
|  | 			_, size := utf8.DecodeRune(line[i:]) | ||||||
|  | 			i += size | ||||||
|  | 			column++ | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		if i > start { | ||||||
|  | 			out.Write(line[start:i]) | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		if i >= len(line) { | ||||||
|  | 			break | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		for { | ||||||
|  | 			out.WriteByte(' ') | ||||||
|  | 			column++ | ||||||
|  | 			if column%tabSize == 0 { | ||||||
|  | 				break | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		i++ | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Find if a line counts as indented or not. | ||||||
|  | // Returns number of characters the indent is (0 = not indented). | ||||||
|  | func isIndented(data []byte, indentSize int) int { | ||||||
|  | 	if len(data) == 0 { | ||||||
|  | 		return 0 | ||||||
|  | 	} | ||||||
|  | 	if data[0] == '\t' { | ||||||
|  | 		return 1 | ||||||
|  | 	} | ||||||
|  | 	if len(data) < indentSize { | ||||||
|  | 		return 0 | ||||||
|  | 	} | ||||||
|  | 	for i := 0; i < indentSize; i++ { | ||||||
|  | 		if data[i] != ' ' { | ||||||
|  | 			return 0 | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return indentSize | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Create a url-safe slug for fragments | ||||||
|  | func slugify(in []byte) []byte { | ||||||
|  | 	if len(in) == 0 { | ||||||
|  | 		return in | ||||||
|  | 	} | ||||||
|  | 	out := make([]byte, 0, len(in)) | ||||||
|  | 	sym := false | ||||||
|  |  | ||||||
|  | 	for _, ch := range in { | ||||||
|  | 		if isalnum(ch) { | ||||||
|  | 			sym = false | ||||||
|  | 			out = append(out, ch) | ||||||
|  | 		} else if sym { | ||||||
|  | 			continue | ||||||
|  | 		} else { | ||||||
|  | 			out = append(out, '-') | ||||||
|  | 			sym = true | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	var a, b int | ||||||
|  | 	var ch byte | ||||||
|  | 	for a, ch = range out { | ||||||
|  | 		if ch != '-' { | ||||||
|  | 			break | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	for b = len(out) - 1; b > 0; b-- { | ||||||
|  | 		if out[b] != '-' { | ||||||
|  | 			break | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return out[a : b+1] | ||||||
|  | } | ||||||
							
								
								
									
										354
									
								
								vendor/github.com/russross/blackfriday/v2/node.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										354
									
								
								vendor/github.com/russross/blackfriday/v2/node.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,354 @@ | |||||||
|  | package blackfriday | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"bytes" | ||||||
|  | 	"fmt" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | // NodeType specifies a type of a single node of a syntax tree. Usually one | ||||||
|  | // node (and its type) corresponds to a single markdown feature, e.g. emphasis | ||||||
|  | // or code block. | ||||||
|  | type NodeType int | ||||||
|  |  | ||||||
|  | // Constants for identifying different types of nodes. See NodeType. | ||||||
|  | const ( | ||||||
|  | 	Document NodeType = iota | ||||||
|  | 	BlockQuote | ||||||
|  | 	List | ||||||
|  | 	Item | ||||||
|  | 	Paragraph | ||||||
|  | 	Heading | ||||||
|  | 	HorizontalRule | ||||||
|  | 	Emph | ||||||
|  | 	Strong | ||||||
|  | 	Del | ||||||
|  | 	Link | ||||||
|  | 	Image | ||||||
|  | 	Text | ||||||
|  | 	HTMLBlock | ||||||
|  | 	CodeBlock | ||||||
|  | 	Softbreak | ||||||
|  | 	Hardbreak | ||||||
|  | 	Code | ||||||
|  | 	HTMLSpan | ||||||
|  | 	Table | ||||||
|  | 	TableCell | ||||||
|  | 	TableHead | ||||||
|  | 	TableBody | ||||||
|  | 	TableRow | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | var nodeTypeNames = []string{ | ||||||
|  | 	Document:       "Document", | ||||||
|  | 	BlockQuote:     "BlockQuote", | ||||||
|  | 	List:           "List", | ||||||
|  | 	Item:           "Item", | ||||||
|  | 	Paragraph:      "Paragraph", | ||||||
|  | 	Heading:        "Heading", | ||||||
|  | 	HorizontalRule: "HorizontalRule", | ||||||
|  | 	Emph:           "Emph", | ||||||
|  | 	Strong:         "Strong", | ||||||
|  | 	Del:            "Del", | ||||||
|  | 	Link:           "Link", | ||||||
|  | 	Image:          "Image", | ||||||
|  | 	Text:           "Text", | ||||||
|  | 	HTMLBlock:      "HTMLBlock", | ||||||
|  | 	CodeBlock:      "CodeBlock", | ||||||
|  | 	Softbreak:      "Softbreak", | ||||||
|  | 	Hardbreak:      "Hardbreak", | ||||||
|  | 	Code:           "Code", | ||||||
|  | 	HTMLSpan:       "HTMLSpan", | ||||||
|  | 	Table:          "Table", | ||||||
|  | 	TableCell:      "TableCell", | ||||||
|  | 	TableHead:      "TableHead", | ||||||
|  | 	TableBody:      "TableBody", | ||||||
|  | 	TableRow:       "TableRow", | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (t NodeType) String() string { | ||||||
|  | 	return nodeTypeNames[t] | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // ListData contains fields relevant to a List and Item node type. | ||||||
|  | type ListData struct { | ||||||
|  | 	ListFlags       ListType | ||||||
|  | 	Tight           bool   // Skip <p>s around list item data if true | ||||||
|  | 	BulletChar      byte   // '*', '+' or '-' in bullet lists | ||||||
|  | 	Delimiter       byte   // '.' or ')' after the number in ordered lists | ||||||
|  | 	RefLink         []byte // If not nil, turns this list item into a footnote item and triggers different rendering | ||||||
|  | 	IsFootnotesList bool   // This is a list of footnotes | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // LinkData contains fields relevant to a Link node type. | ||||||
|  | type LinkData struct { | ||||||
|  | 	Destination []byte // Destination is what goes into a href | ||||||
|  | 	Title       []byte // Title is the tooltip thing that goes in a title attribute | ||||||
|  | 	NoteID      int    // NoteID contains a serial number of a footnote, zero if it's not a footnote | ||||||
|  | 	Footnote    *Node  // If it's a footnote, this is a direct link to the footnote Node. Otherwise nil. | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // CodeBlockData contains fields relevant to a CodeBlock node type. | ||||||
|  | type CodeBlockData struct { | ||||||
|  | 	IsFenced    bool   // Specifies whether it's a fenced code block or an indented one | ||||||
|  | 	Info        []byte // This holds the info string | ||||||
|  | 	FenceChar   byte | ||||||
|  | 	FenceLength int | ||||||
|  | 	FenceOffset int | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // TableCellData contains fields relevant to a TableCell node type. | ||||||
|  | type TableCellData struct { | ||||||
|  | 	IsHeader bool           // This tells if it's under the header row | ||||||
|  | 	Align    CellAlignFlags // This holds the value for align attribute | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // HeadingData contains fields relevant to a Heading node type. | ||||||
|  | type HeadingData struct { | ||||||
|  | 	Level        int    // This holds the heading level number | ||||||
|  | 	HeadingID    string // This might hold heading ID, if present | ||||||
|  | 	IsTitleblock bool   // Specifies whether it's a title block | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Node is a single element in the abstract syntax tree of the parsed document. | ||||||
|  | // It holds connections to the structurally neighboring nodes and, for certain | ||||||
|  | // types of nodes, additional information that might be needed when rendering. | ||||||
|  | type Node struct { | ||||||
|  | 	Type       NodeType // Determines the type of the node | ||||||
|  | 	Parent     *Node    // Points to the parent | ||||||
|  | 	FirstChild *Node    // Points to the first child, if any | ||||||
|  | 	LastChild  *Node    // Points to the last child, if any | ||||||
|  | 	Prev       *Node    // Previous sibling; nil if it's the first child | ||||||
|  | 	Next       *Node    // Next sibling; nil if it's the last child | ||||||
|  |  | ||||||
|  | 	Literal []byte // Text contents of the leaf nodes | ||||||
|  |  | ||||||
|  | 	HeadingData   // Populated if Type is Heading | ||||||
|  | 	ListData      // Populated if Type is List | ||||||
|  | 	CodeBlockData // Populated if Type is CodeBlock | ||||||
|  | 	LinkData      // Populated if Type is Link | ||||||
|  | 	TableCellData // Populated if Type is TableCell | ||||||
|  |  | ||||||
|  | 	content []byte // Markdown content of the block nodes | ||||||
|  | 	open    bool   // Specifies an open block node that has not been finished to process yet | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // NewNode allocates a node of a specified type. | ||||||
|  | func NewNode(typ NodeType) *Node { | ||||||
|  | 	return &Node{ | ||||||
|  | 		Type: typ, | ||||||
|  | 		open: true, | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (n *Node) String() string { | ||||||
|  | 	ellipsis := "" | ||||||
|  | 	snippet := n.Literal | ||||||
|  | 	if len(snippet) > 16 { | ||||||
|  | 		snippet = snippet[:16] | ||||||
|  | 		ellipsis = "..." | ||||||
|  | 	} | ||||||
|  | 	return fmt.Sprintf("%s: '%s%s'", n.Type, snippet, ellipsis) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Unlink removes node 'n' from the tree. | ||||||
|  | // It panics if the node is nil. | ||||||
|  | func (n *Node) Unlink() { | ||||||
|  | 	if n.Prev != nil { | ||||||
|  | 		n.Prev.Next = n.Next | ||||||
|  | 	} else if n.Parent != nil { | ||||||
|  | 		n.Parent.FirstChild = n.Next | ||||||
|  | 	} | ||||||
|  | 	if n.Next != nil { | ||||||
|  | 		n.Next.Prev = n.Prev | ||||||
|  | 	} else if n.Parent != nil { | ||||||
|  | 		n.Parent.LastChild = n.Prev | ||||||
|  | 	} | ||||||
|  | 	n.Parent = nil | ||||||
|  | 	n.Next = nil | ||||||
|  | 	n.Prev = nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // AppendChild adds a node 'child' as a child of 'n'. | ||||||
|  | // It panics if either node is nil. | ||||||
|  | func (n *Node) AppendChild(child *Node) { | ||||||
|  | 	child.Unlink() | ||||||
|  | 	child.Parent = n | ||||||
|  | 	if n.LastChild != nil { | ||||||
|  | 		n.LastChild.Next = child | ||||||
|  | 		child.Prev = n.LastChild | ||||||
|  | 		n.LastChild = child | ||||||
|  | 	} else { | ||||||
|  | 		n.FirstChild = child | ||||||
|  | 		n.LastChild = child | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // InsertBefore inserts 'sibling' immediately before 'n'. | ||||||
|  | // It panics if either node is nil. | ||||||
|  | func (n *Node) InsertBefore(sibling *Node) { | ||||||
|  | 	sibling.Unlink() | ||||||
|  | 	sibling.Prev = n.Prev | ||||||
|  | 	if sibling.Prev != nil { | ||||||
|  | 		sibling.Prev.Next = sibling | ||||||
|  | 	} | ||||||
|  | 	sibling.Next = n | ||||||
|  | 	n.Prev = sibling | ||||||
|  | 	sibling.Parent = n.Parent | ||||||
|  | 	if sibling.Prev == nil { | ||||||
|  | 		sibling.Parent.FirstChild = sibling | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (n *Node) isContainer() bool { | ||||||
|  | 	switch n.Type { | ||||||
|  | 	case Document: | ||||||
|  | 		fallthrough | ||||||
|  | 	case BlockQuote: | ||||||
|  | 		fallthrough | ||||||
|  | 	case List: | ||||||
|  | 		fallthrough | ||||||
|  | 	case Item: | ||||||
|  | 		fallthrough | ||||||
|  | 	case Paragraph: | ||||||
|  | 		fallthrough | ||||||
|  | 	case Heading: | ||||||
|  | 		fallthrough | ||||||
|  | 	case Emph: | ||||||
|  | 		fallthrough | ||||||
|  | 	case Strong: | ||||||
|  | 		fallthrough | ||||||
|  | 	case Del: | ||||||
|  | 		fallthrough | ||||||
|  | 	case Link: | ||||||
|  | 		fallthrough | ||||||
|  | 	case Image: | ||||||
|  | 		fallthrough | ||||||
|  | 	case Table: | ||||||
|  | 		fallthrough | ||||||
|  | 	case TableHead: | ||||||
|  | 		fallthrough | ||||||
|  | 	case TableBody: | ||||||
|  | 		fallthrough | ||||||
|  | 	case TableRow: | ||||||
|  | 		fallthrough | ||||||
|  | 	case TableCell: | ||||||
|  | 		return true | ||||||
|  | 	default: | ||||||
|  | 		return false | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (n *Node) canContain(t NodeType) bool { | ||||||
|  | 	if n.Type == List { | ||||||
|  | 		return t == Item | ||||||
|  | 	} | ||||||
|  | 	if n.Type == Document || n.Type == BlockQuote || n.Type == Item { | ||||||
|  | 		return t != Item | ||||||
|  | 	} | ||||||
|  | 	if n.Type == Table { | ||||||
|  | 		return t == TableHead || t == TableBody | ||||||
|  | 	} | ||||||
|  | 	if n.Type == TableHead || n.Type == TableBody { | ||||||
|  | 		return t == TableRow | ||||||
|  | 	} | ||||||
|  | 	if n.Type == TableRow { | ||||||
|  | 		return t == TableCell | ||||||
|  | 	} | ||||||
|  | 	return false | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // WalkStatus allows NodeVisitor to have some control over the tree traversal. | ||||||
|  | // It is returned from NodeVisitor and different values allow Node.Walk to | ||||||
|  | // decide which node to go to next. | ||||||
|  | type WalkStatus int | ||||||
|  |  | ||||||
|  | const ( | ||||||
|  | 	// GoToNext is the default traversal of every node. | ||||||
|  | 	GoToNext WalkStatus = iota | ||||||
|  | 	// SkipChildren tells walker to skip all children of current node. | ||||||
|  | 	SkipChildren | ||||||
|  | 	// Terminate tells walker to terminate the traversal. | ||||||
|  | 	Terminate | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | // NodeVisitor is a callback to be called when traversing the syntax tree. | ||||||
|  | // Called twice for every node: once with entering=true when the branch is | ||||||
|  | // first visited, then with entering=false after all the children are done. | ||||||
|  | type NodeVisitor func(node *Node, entering bool) WalkStatus | ||||||
|  |  | ||||||
|  | // Walk is a convenience method that instantiates a walker and starts a | ||||||
|  | // traversal of subtree rooted at n. | ||||||
|  | func (n *Node) Walk(visitor NodeVisitor) { | ||||||
|  | 	w := newNodeWalker(n) | ||||||
|  | 	for w.current != nil { | ||||||
|  | 		status := visitor(w.current, w.entering) | ||||||
|  | 		switch status { | ||||||
|  | 		case GoToNext: | ||||||
|  | 			w.next() | ||||||
|  | 		case SkipChildren: | ||||||
|  | 			w.entering = false | ||||||
|  | 			w.next() | ||||||
|  | 		case Terminate: | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | type nodeWalker struct { | ||||||
|  | 	current  *Node | ||||||
|  | 	root     *Node | ||||||
|  | 	entering bool | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func newNodeWalker(root *Node) *nodeWalker { | ||||||
|  | 	return &nodeWalker{ | ||||||
|  | 		current:  root, | ||||||
|  | 		root:     root, | ||||||
|  | 		entering: true, | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (nw *nodeWalker) next() { | ||||||
|  | 	if (!nw.current.isContainer() || !nw.entering) && nw.current == nw.root { | ||||||
|  | 		nw.current = nil | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  | 	if nw.entering && nw.current.isContainer() { | ||||||
|  | 		if nw.current.FirstChild != nil { | ||||||
|  | 			nw.current = nw.current.FirstChild | ||||||
|  | 			nw.entering = true | ||||||
|  | 		} else { | ||||||
|  | 			nw.entering = false | ||||||
|  | 		} | ||||||
|  | 	} else if nw.current.Next == nil { | ||||||
|  | 		nw.current = nw.current.Parent | ||||||
|  | 		nw.entering = false | ||||||
|  | 	} else { | ||||||
|  | 		nw.current = nw.current.Next | ||||||
|  | 		nw.entering = true | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func dump(ast *Node) { | ||||||
|  | 	fmt.Println(dumpString(ast)) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func dumpR(ast *Node, depth int) string { | ||||||
|  | 	if ast == nil { | ||||||
|  | 		return "" | ||||||
|  | 	} | ||||||
|  | 	indent := bytes.Repeat([]byte("\t"), depth) | ||||||
|  | 	content := ast.Literal | ||||||
|  | 	if content == nil { | ||||||
|  | 		content = ast.content | ||||||
|  | 	} | ||||||
|  | 	result := fmt.Sprintf("%s%s(%q)\n", indent, ast.Type, content) | ||||||
|  | 	for n := ast.FirstChild; n != nil; n = n.Next { | ||||||
|  | 		result += dumpR(n, depth+1) | ||||||
|  | 	} | ||||||
|  | 	return result | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func dumpString(ast *Node) string { | ||||||
|  | 	return dumpR(ast, 0) | ||||||
|  | } | ||||||
							
								
								
									
										457
									
								
								vendor/github.com/russross/blackfriday/v2/smartypants.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										457
									
								
								vendor/github.com/russross/blackfriday/v2/smartypants.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,457 @@ | |||||||
|  | // | ||||||
|  | // Blackfriday Markdown Processor | ||||||
|  | // Available at http://github.com/russross/blackfriday | ||||||
|  | // | ||||||
|  | // Copyright © 2011 Russ Ross <russ@russross.com>. | ||||||
|  | // Distributed under the Simplified BSD License. | ||||||
|  | // See README.md for details. | ||||||
|  | // | ||||||
|  |  | ||||||
|  | // | ||||||
|  | // | ||||||
|  | // SmartyPants rendering | ||||||
|  | // | ||||||
|  | // | ||||||
|  |  | ||||||
|  | package blackfriday | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"bytes" | ||||||
|  | 	"io" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | // SPRenderer is a struct containing state of a Smartypants renderer. | ||||||
|  | type SPRenderer struct { | ||||||
|  | 	inSingleQuote bool | ||||||
|  | 	inDoubleQuote bool | ||||||
|  | 	callbacks     [256]smartCallback | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func wordBoundary(c byte) bool { | ||||||
|  | 	return c == 0 || isspace(c) || ispunct(c) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func tolower(c byte) byte { | ||||||
|  | 	if c >= 'A' && c <= 'Z' { | ||||||
|  | 		return c - 'A' + 'a' | ||||||
|  | 	} | ||||||
|  | 	return c | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func isdigit(c byte) bool { | ||||||
|  | 	return c >= '0' && c <= '9' | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func smartQuoteHelper(out *bytes.Buffer, previousChar byte, nextChar byte, quote byte, isOpen *bool, addNBSP bool) bool { | ||||||
|  | 	// edge of the buffer is likely to be a tag that we don't get to see, | ||||||
|  | 	// so we treat it like text sometimes | ||||||
|  |  | ||||||
|  | 	// enumerate all sixteen possibilities for (previousChar, nextChar) | ||||||
|  | 	// each can be one of {0, space, punct, other} | ||||||
|  | 	switch { | ||||||
|  | 	case previousChar == 0 && nextChar == 0: | ||||||
|  | 		// context is not any help here, so toggle | ||||||
|  | 		*isOpen = !*isOpen | ||||||
|  | 	case isspace(previousChar) && nextChar == 0: | ||||||
|  | 		// [ "] might be [ "<code>foo...] | ||||||
|  | 		*isOpen = true | ||||||
|  | 	case ispunct(previousChar) && nextChar == 0: | ||||||
|  | 		// [!"] hmm... could be [Run!"] or [("<code>...] | ||||||
|  | 		*isOpen = false | ||||||
|  | 	case /* isnormal(previousChar) && */ nextChar == 0: | ||||||
|  | 		// [a"] is probably a close | ||||||
|  | 		*isOpen = false | ||||||
|  | 	case previousChar == 0 && isspace(nextChar): | ||||||
|  | 		// [" ] might be [...foo</code>" ] | ||||||
|  | 		*isOpen = false | ||||||
|  | 	case isspace(previousChar) && isspace(nextChar): | ||||||
|  | 		// [ " ] context is not any help here, so toggle | ||||||
|  | 		*isOpen = !*isOpen | ||||||
|  | 	case ispunct(previousChar) && isspace(nextChar): | ||||||
|  | 		// [!" ] is probably a close | ||||||
|  | 		*isOpen = false | ||||||
|  | 	case /* isnormal(previousChar) && */ isspace(nextChar): | ||||||
|  | 		// [a" ] this is one of the easy cases | ||||||
|  | 		*isOpen = false | ||||||
|  | 	case previousChar == 0 && ispunct(nextChar): | ||||||
|  | 		// ["!] hmm... could be ["$1.95] or [</code>"!...] | ||||||
|  | 		*isOpen = false | ||||||
|  | 	case isspace(previousChar) && ispunct(nextChar): | ||||||
|  | 		// [ "!] looks more like [ "$1.95] | ||||||
|  | 		*isOpen = true | ||||||
|  | 	case ispunct(previousChar) && ispunct(nextChar): | ||||||
|  | 		// [!"!] context is not any help here, so toggle | ||||||
|  | 		*isOpen = !*isOpen | ||||||
|  | 	case /* isnormal(previousChar) && */ ispunct(nextChar): | ||||||
|  | 		// [a"!] is probably a close | ||||||
|  | 		*isOpen = false | ||||||
|  | 	case previousChar == 0 /* && isnormal(nextChar) */ : | ||||||
|  | 		// ["a] is probably an open | ||||||
|  | 		*isOpen = true | ||||||
|  | 	case isspace(previousChar) /* && isnormal(nextChar) */ : | ||||||
|  | 		// [ "a] this is one of the easy cases | ||||||
|  | 		*isOpen = true | ||||||
|  | 	case ispunct(previousChar) /* && isnormal(nextChar) */ : | ||||||
|  | 		// [!"a] is probably an open | ||||||
|  | 		*isOpen = true | ||||||
|  | 	default: | ||||||
|  | 		// [a'b] maybe a contraction? | ||||||
|  | 		*isOpen = false | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// Note that with the limited lookahead, this non-breaking | ||||||
|  | 	// space will also be appended to single double quotes. | ||||||
|  | 	if addNBSP && !*isOpen { | ||||||
|  | 		out.WriteString(" ") | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	out.WriteByte('&') | ||||||
|  | 	if *isOpen { | ||||||
|  | 		out.WriteByte('l') | ||||||
|  | 	} else { | ||||||
|  | 		out.WriteByte('r') | ||||||
|  | 	} | ||||||
|  | 	out.WriteByte(quote) | ||||||
|  | 	out.WriteString("quo;") | ||||||
|  |  | ||||||
|  | 	if addNBSP && *isOpen { | ||||||
|  | 		out.WriteString(" ") | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return true | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (r *SPRenderer) smartSingleQuote(out *bytes.Buffer, previousChar byte, text []byte) int { | ||||||
|  | 	if len(text) >= 2 { | ||||||
|  | 		t1 := tolower(text[1]) | ||||||
|  |  | ||||||
|  | 		if t1 == '\'' { | ||||||
|  | 			nextChar := byte(0) | ||||||
|  | 			if len(text) >= 3 { | ||||||
|  | 				nextChar = text[2] | ||||||
|  | 			} | ||||||
|  | 			if smartQuoteHelper(out, previousChar, nextChar, 'd', &r.inDoubleQuote, false) { | ||||||
|  | 				return 1 | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		if (t1 == 's' || t1 == 't' || t1 == 'm' || t1 == 'd') && (len(text) < 3 || wordBoundary(text[2])) { | ||||||
|  | 			out.WriteString("’") | ||||||
|  | 			return 0 | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		if len(text) >= 3 { | ||||||
|  | 			t2 := tolower(text[2]) | ||||||
|  |  | ||||||
|  | 			if ((t1 == 'r' && t2 == 'e') || (t1 == 'l' && t2 == 'l') || (t1 == 'v' && t2 == 'e')) && | ||||||
|  | 				(len(text) < 4 || wordBoundary(text[3])) { | ||||||
|  | 				out.WriteString("’") | ||||||
|  | 				return 0 | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	nextChar := byte(0) | ||||||
|  | 	if len(text) > 1 { | ||||||
|  | 		nextChar = text[1] | ||||||
|  | 	} | ||||||
|  | 	if smartQuoteHelper(out, previousChar, nextChar, 's', &r.inSingleQuote, false) { | ||||||
|  | 		return 0 | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	out.WriteByte(text[0]) | ||||||
|  | 	return 0 | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (r *SPRenderer) smartParens(out *bytes.Buffer, previousChar byte, text []byte) int { | ||||||
|  | 	if len(text) >= 3 { | ||||||
|  | 		t1 := tolower(text[1]) | ||||||
|  | 		t2 := tolower(text[2]) | ||||||
|  |  | ||||||
|  | 		if t1 == 'c' && t2 == ')' { | ||||||
|  | 			out.WriteString("©") | ||||||
|  | 			return 2 | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		if t1 == 'r' && t2 == ')' { | ||||||
|  | 			out.WriteString("®") | ||||||
|  | 			return 2 | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		if len(text) >= 4 && t1 == 't' && t2 == 'm' && text[3] == ')' { | ||||||
|  | 			out.WriteString("™") | ||||||
|  | 			return 3 | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	out.WriteByte(text[0]) | ||||||
|  | 	return 0 | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (r *SPRenderer) smartDash(out *bytes.Buffer, previousChar byte, text []byte) int { | ||||||
|  | 	if len(text) >= 2 { | ||||||
|  | 		if text[1] == '-' { | ||||||
|  | 			out.WriteString("—") | ||||||
|  | 			return 1 | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		if wordBoundary(previousChar) && wordBoundary(text[1]) { | ||||||
|  | 			out.WriteString("–") | ||||||
|  | 			return 0 | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	out.WriteByte(text[0]) | ||||||
|  | 	return 0 | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (r *SPRenderer) smartDashLatex(out *bytes.Buffer, previousChar byte, text []byte) int { | ||||||
|  | 	if len(text) >= 3 && text[1] == '-' && text[2] == '-' { | ||||||
|  | 		out.WriteString("—") | ||||||
|  | 		return 2 | ||||||
|  | 	} | ||||||
|  | 	if len(text) >= 2 && text[1] == '-' { | ||||||
|  | 		out.WriteString("–") | ||||||
|  | 		return 1 | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	out.WriteByte(text[0]) | ||||||
|  | 	return 0 | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (r *SPRenderer) smartAmpVariant(out *bytes.Buffer, previousChar byte, text []byte, quote byte, addNBSP bool) int { | ||||||
|  | 	if bytes.HasPrefix(text, []byte(""")) { | ||||||
|  | 		nextChar := byte(0) | ||||||
|  | 		if len(text) >= 7 { | ||||||
|  | 			nextChar = text[6] | ||||||
|  | 		} | ||||||
|  | 		if smartQuoteHelper(out, previousChar, nextChar, quote, &r.inDoubleQuote, addNBSP) { | ||||||
|  | 			return 5 | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if bytes.HasPrefix(text, []byte("�")) { | ||||||
|  | 		return 3 | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	out.WriteByte('&') | ||||||
|  | 	return 0 | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (r *SPRenderer) smartAmp(angledQuotes, addNBSP bool) func(*bytes.Buffer, byte, []byte) int { | ||||||
|  | 	var quote byte = 'd' | ||||||
|  | 	if angledQuotes { | ||||||
|  | 		quote = 'a' | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return func(out *bytes.Buffer, previousChar byte, text []byte) int { | ||||||
|  | 		return r.smartAmpVariant(out, previousChar, text, quote, addNBSP) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (r *SPRenderer) smartPeriod(out *bytes.Buffer, previousChar byte, text []byte) int { | ||||||
|  | 	if len(text) >= 3 && text[1] == '.' && text[2] == '.' { | ||||||
|  | 		out.WriteString("…") | ||||||
|  | 		return 2 | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if len(text) >= 5 && text[1] == ' ' && text[2] == '.' && text[3] == ' ' && text[4] == '.' { | ||||||
|  | 		out.WriteString("…") | ||||||
|  | 		return 4 | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	out.WriteByte(text[0]) | ||||||
|  | 	return 0 | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (r *SPRenderer) smartBacktick(out *bytes.Buffer, previousChar byte, text []byte) int { | ||||||
|  | 	if len(text) >= 2 && text[1] == '`' { | ||||||
|  | 		nextChar := byte(0) | ||||||
|  | 		if len(text) >= 3 { | ||||||
|  | 			nextChar = text[2] | ||||||
|  | 		} | ||||||
|  | 		if smartQuoteHelper(out, previousChar, nextChar, 'd', &r.inDoubleQuote, false) { | ||||||
|  | 			return 1 | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	out.WriteByte(text[0]) | ||||||
|  | 	return 0 | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (r *SPRenderer) smartNumberGeneric(out *bytes.Buffer, previousChar byte, text []byte) int { | ||||||
|  | 	if wordBoundary(previousChar) && previousChar != '/' && len(text) >= 3 { | ||||||
|  | 		// is it of the form digits/digits(word boundary)?, i.e., \d+/\d+\b | ||||||
|  | 		// note: check for regular slash (/) or fraction slash (⁄, 0x2044, or 0xe2 81 84 in utf-8) | ||||||
|  | 		//       and avoid changing dates like 1/23/2005 into fractions. | ||||||
|  | 		numEnd := 0 | ||||||
|  | 		for len(text) > numEnd && isdigit(text[numEnd]) { | ||||||
|  | 			numEnd++ | ||||||
|  | 		} | ||||||
|  | 		if numEnd == 0 { | ||||||
|  | 			out.WriteByte(text[0]) | ||||||
|  | 			return 0 | ||||||
|  | 		} | ||||||
|  | 		denStart := numEnd + 1 | ||||||
|  | 		if len(text) > numEnd+3 && text[numEnd] == 0xe2 && text[numEnd+1] == 0x81 && text[numEnd+2] == 0x84 { | ||||||
|  | 			denStart = numEnd + 3 | ||||||
|  | 		} else if len(text) < numEnd+2 || text[numEnd] != '/' { | ||||||
|  | 			out.WriteByte(text[0]) | ||||||
|  | 			return 0 | ||||||
|  | 		} | ||||||
|  | 		denEnd := denStart | ||||||
|  | 		for len(text) > denEnd && isdigit(text[denEnd]) { | ||||||
|  | 			denEnd++ | ||||||
|  | 		} | ||||||
|  | 		if denEnd == denStart { | ||||||
|  | 			out.WriteByte(text[0]) | ||||||
|  | 			return 0 | ||||||
|  | 		} | ||||||
|  | 		if len(text) == denEnd || wordBoundary(text[denEnd]) && text[denEnd] != '/' { | ||||||
|  | 			out.WriteString("<sup>") | ||||||
|  | 			out.Write(text[:numEnd]) | ||||||
|  | 			out.WriteString("</sup>⁄<sub>") | ||||||
|  | 			out.Write(text[denStart:denEnd]) | ||||||
|  | 			out.WriteString("</sub>") | ||||||
|  | 			return denEnd - 1 | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	out.WriteByte(text[0]) | ||||||
|  | 	return 0 | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (r *SPRenderer) smartNumber(out *bytes.Buffer, previousChar byte, text []byte) int { | ||||||
|  | 	if wordBoundary(previousChar) && previousChar != '/' && len(text) >= 3 { | ||||||
|  | 		if text[0] == '1' && text[1] == '/' && text[2] == '2' { | ||||||
|  | 			if len(text) < 4 || wordBoundary(text[3]) && text[3] != '/' { | ||||||
|  | 				out.WriteString("½") | ||||||
|  | 				return 2 | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		if text[0] == '1' && text[1] == '/' && text[2] == '4' { | ||||||
|  | 			if len(text) < 4 || wordBoundary(text[3]) && text[3] != '/' || (len(text) >= 5 && tolower(text[3]) == 't' && tolower(text[4]) == 'h') { | ||||||
|  | 				out.WriteString("¼") | ||||||
|  | 				return 2 | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		if text[0] == '3' && text[1] == '/' && text[2] == '4' { | ||||||
|  | 			if len(text) < 4 || wordBoundary(text[3]) && text[3] != '/' || (len(text) >= 6 && tolower(text[3]) == 't' && tolower(text[4]) == 'h' && tolower(text[5]) == 's') { | ||||||
|  | 				out.WriteString("¾") | ||||||
|  | 				return 2 | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	out.WriteByte(text[0]) | ||||||
|  | 	return 0 | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (r *SPRenderer) smartDoubleQuoteVariant(out *bytes.Buffer, previousChar byte, text []byte, quote byte) int { | ||||||
|  | 	nextChar := byte(0) | ||||||
|  | 	if len(text) > 1 { | ||||||
|  | 		nextChar = text[1] | ||||||
|  | 	} | ||||||
|  | 	if !smartQuoteHelper(out, previousChar, nextChar, quote, &r.inDoubleQuote, false) { | ||||||
|  | 		out.WriteString(""") | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return 0 | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (r *SPRenderer) smartDoubleQuote(out *bytes.Buffer, previousChar byte, text []byte) int { | ||||||
|  | 	return r.smartDoubleQuoteVariant(out, previousChar, text, 'd') | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (r *SPRenderer) smartAngledDoubleQuote(out *bytes.Buffer, previousChar byte, text []byte) int { | ||||||
|  | 	return r.smartDoubleQuoteVariant(out, previousChar, text, 'a') | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (r *SPRenderer) smartLeftAngle(out *bytes.Buffer, previousChar byte, text []byte) int { | ||||||
|  | 	i := 0 | ||||||
|  |  | ||||||
|  | 	for i < len(text) && text[i] != '>' { | ||||||
|  | 		i++ | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	out.Write(text[:i+1]) | ||||||
|  | 	return i | ||||||
|  | } | ||||||
|  |  | ||||||
|  | type smartCallback func(out *bytes.Buffer, previousChar byte, text []byte) int | ||||||
|  |  | ||||||
|  | // NewSmartypantsRenderer constructs a Smartypants renderer object. | ||||||
|  | func NewSmartypantsRenderer(flags HTMLFlags) *SPRenderer { | ||||||
|  | 	var ( | ||||||
|  | 		r SPRenderer | ||||||
|  |  | ||||||
|  | 		smartAmpAngled      = r.smartAmp(true, false) | ||||||
|  | 		smartAmpAngledNBSP  = r.smartAmp(true, true) | ||||||
|  | 		smartAmpRegular     = r.smartAmp(false, false) | ||||||
|  | 		smartAmpRegularNBSP = r.smartAmp(false, true) | ||||||
|  |  | ||||||
|  | 		addNBSP = flags&SmartypantsQuotesNBSP != 0 | ||||||
|  | 	) | ||||||
|  |  | ||||||
|  | 	if flags&SmartypantsAngledQuotes == 0 { | ||||||
|  | 		r.callbacks['"'] = r.smartDoubleQuote | ||||||
|  | 		if !addNBSP { | ||||||
|  | 			r.callbacks['&'] = smartAmpRegular | ||||||
|  | 		} else { | ||||||
|  | 			r.callbacks['&'] = smartAmpRegularNBSP | ||||||
|  | 		} | ||||||
|  | 	} else { | ||||||
|  | 		r.callbacks['"'] = r.smartAngledDoubleQuote | ||||||
|  | 		if !addNBSP { | ||||||
|  | 			r.callbacks['&'] = smartAmpAngled | ||||||
|  | 		} else { | ||||||
|  | 			r.callbacks['&'] = smartAmpAngledNBSP | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	r.callbacks['\''] = r.smartSingleQuote | ||||||
|  | 	r.callbacks['('] = r.smartParens | ||||||
|  | 	if flags&SmartypantsDashes != 0 { | ||||||
|  | 		if flags&SmartypantsLatexDashes == 0 { | ||||||
|  | 			r.callbacks['-'] = r.smartDash | ||||||
|  | 		} else { | ||||||
|  | 			r.callbacks['-'] = r.smartDashLatex | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	r.callbacks['.'] = r.smartPeriod | ||||||
|  | 	if flags&SmartypantsFractions == 0 { | ||||||
|  | 		r.callbacks['1'] = r.smartNumber | ||||||
|  | 		r.callbacks['3'] = r.smartNumber | ||||||
|  | 	} else { | ||||||
|  | 		for ch := '1'; ch <= '9'; ch++ { | ||||||
|  | 			r.callbacks[ch] = r.smartNumberGeneric | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	r.callbacks['<'] = r.smartLeftAngle | ||||||
|  | 	r.callbacks['`'] = r.smartBacktick | ||||||
|  | 	return &r | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Process is the entry point of the Smartypants renderer. | ||||||
|  | func (r *SPRenderer) Process(w io.Writer, text []byte) { | ||||||
|  | 	mark := 0 | ||||||
|  | 	for i := 0; i < len(text); i++ { | ||||||
|  | 		if action := r.callbacks[text[i]]; action != nil { | ||||||
|  | 			if i > mark { | ||||||
|  | 				w.Write(text[mark:i]) | ||||||
|  | 			} | ||||||
|  | 			previousChar := byte(0) | ||||||
|  | 			if i > 0 { | ||||||
|  | 				previousChar = text[i-1] | ||||||
|  | 			} | ||||||
|  | 			var tmp bytes.Buffer | ||||||
|  | 			i += action(&tmp, previousChar, text[i:]) | ||||||
|  | 			w.Write(tmp.Bytes()) | ||||||
|  | 			mark = i + 1 | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	if mark < len(text) { | ||||||
|  | 		w.Write(text[mark:]) | ||||||
|  | 	} | ||||||
|  | } | ||||||
							
								
								
									
										16
									
								
								vendor/github.com/shurcooL/sanitized_anchor_name/.travis.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								vendor/github.com/shurcooL/sanitized_anchor_name/.travis.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,16 @@ | |||||||
|  | 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
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								vendor/github.com/shurcooL/sanitized_anchor_name/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,21 @@ | |||||||
|  | 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
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								vendor/github.com/shurcooL/sanitized_anchor_name/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,36 @@ | |||||||
|  | sanitized_anchor_name | ||||||
|  | ===================== | ||||||
|  |  | ||||||
|  | [](https://travis-ci.org/shurcooL/sanitized_anchor_name) [](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
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								vendor/github.com/shurcooL/sanitized_anchor_name/go.mod
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | |||||||
|  | module github.com/shurcooL/sanitized_anchor_name | ||||||
							
								
								
									
										29
									
								
								vendor/github.com/shurcooL/sanitized_anchor_name/main.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								vendor/github.com/shurcooL/sanitized_anchor_name/main.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,29 @@ | |||||||
|  | // 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) | ||||||
|  | } | ||||||
							
								
								
									
										1
									
								
								vendor/github.com/urfave/cli/.gitignore
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								vendor/github.com/urfave/cli/.gitignore
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,2 +1,3 @@ | |||||||
| *.coverprofile | *.coverprofile | ||||||
| node_modules/ | node_modules/ | ||||||
|  | vendor | ||||||
							
								
								
									
										38
									
								
								vendor/github.com/urfave/cli/.travis.yml
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										38
									
								
								vendor/github.com/urfave/cli/.travis.yml
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,27 +1,35 @@ | |||||||
| language: go | language: go | ||||||
| sudo: false | sudo: false | ||||||
| dist: trusty | dist: bionic | ||||||
| osx_image: xcode8.3 | osx_image: xcode10 | ||||||
| go: 1.8.x | go: | ||||||
|  |   - 1.11.x | ||||||
|  |   - 1.12.x | ||||||
|  |   - 1.13.x | ||||||
|  |  | ||||||
| os: | os: | ||||||
| - linux |   - linux | ||||||
| - osx |   - osx | ||||||
|  |  | ||||||
|  | env: | ||||||
|  |   GO111MODULE=on | ||||||
|  |   GOPROXY=https://proxy.golang.org | ||||||
|  |  | ||||||
| cache: | cache: | ||||||
|   directories: |   directories: | ||||||
|     - node_modules |     - node_modules | ||||||
|  |  | ||||||
| before_script: | before_script: | ||||||
| - go get github.com/urfave/gfmrun/... || true |   - go get github.com/urfave/gfmrun/cmd/gfmrun | ||||||
| - go get golang.org/x/tools/cmd/goimports |   - go get golang.org/x/tools/cmd/goimports | ||||||
| - if [ ! -f node_modules/.bin/markdown-toc ] ; then |   - npm install markdown-toc | ||||||
|     npm install markdown-toc ; |   - go mod tidy | ||||||
|   fi |  | ||||||
|  |  | ||||||
| script: | script: | ||||||
| - ./runtests gen |   - go run build.go vet | ||||||
| - ./runtests vet |   - go run build.go test | ||||||
| - ./runtests test |   - go run build.go gfmrun docs/v1/manual.md | ||||||
| - ./runtests gfmrun |   - go run build.go toc docs/v1/manual.md | ||||||
| - ./runtests toc |  | ||||||
|  | after_success: | ||||||
|  |   - bash <(curl -s https://codecov.io/bash) | ||||||
|   | |||||||
							
								
								
									
										435
									
								
								vendor/github.com/urfave/cli/CHANGELOG.md
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										435
									
								
								vendor/github.com/urfave/cli/CHANGELOG.md
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,435 +0,0 @@ | |||||||
| # Change Log |  | ||||||
|  |  | ||||||
| **ATTN**: This project uses [semantic versioning](http://semver.org/). |  | ||||||
|  |  | ||||||
| ## [Unreleased] |  | ||||||
|  |  | ||||||
| ## 1.20.0 - 2017-08-10 |  | ||||||
|  |  | ||||||
| ### Fixed |  | ||||||
|  |  | ||||||
| * `HandleExitCoder` is now correctly iterates over all errors in |  | ||||||
|   a `MultiError`. The exit code is the exit code of the last error or `1` if |  | ||||||
|   there are no `ExitCoder`s in the `MultiError`. |  | ||||||
| * Fixed YAML file loading on Windows (previously would fail validate the file path) |  | ||||||
| * Subcommand `Usage`, `Description`, `ArgsUsage`, `OnUsageError` correctly |  | ||||||
|   propogated |  | ||||||
| * `ErrWriter` is now passed downwards through command structure to avoid the |  | ||||||
|   need to redefine it |  | ||||||
| * Pass `Command` context into `OnUsageError` rather than parent context so that |  | ||||||
|   all fields are avaiable |  | ||||||
| * Errors occuring in `Before` funcs are no longer double printed |  | ||||||
| * Use `UsageText` in the help templates for commands and subcommands if |  | ||||||
|   defined; otherwise build the usage as before (was previously ignoring this |  | ||||||
|   field) |  | ||||||
| * `IsSet` and `GlobalIsSet` now correctly return whether a flag is set if |  | ||||||
|   a program calls `Set` or `GlobalSet` directly after flag parsing (would |  | ||||||
|   previously only return `true` if the flag was set during parsing) |  | ||||||
|  |  | ||||||
| ### Changed |  | ||||||
|  |  | ||||||
| * No longer exit the program on command/subcommand error if the error raised is |  | ||||||
|   not an `OsExiter`. This exiting behavior was introduced in 1.19.0, but was |  | ||||||
|   determined to be a regression in functionality. See [the |  | ||||||
|   PR](https://github.com/urfave/cli/pull/595) for discussion. |  | ||||||
|  |  | ||||||
| ### Added |  | ||||||
|  |  | ||||||
| * `CommandsByName` type was added to make it easy to sort `Command`s by name, |  | ||||||
|   alphabetically |  | ||||||
| * `altsrc` now handles loading of string and int arrays from TOML |  | ||||||
| * Support for definition of custom help templates for `App` via |  | ||||||
|   `CustomAppHelpTemplate` |  | ||||||
| * Support for arbitrary key/value fields on `App` to be used with |  | ||||||
|   `CustomAppHelpTemplate` via `ExtraInfo` |  | ||||||
| * `HelpFlag`, `VersionFlag`, and `BashCompletionFlag` changed to explictly be |  | ||||||
|   `cli.Flag`s allowing for the use of custom flags satisfying the `cli.Flag` |  | ||||||
|   interface to be used. |  | ||||||
|  |  | ||||||
|  |  | ||||||
| ## [1.19.1] - 2016-11-21 |  | ||||||
|  |  | ||||||
| ### Fixed |  | ||||||
|  |  | ||||||
| - Fixes regression introduced in 1.19.0 where using an `ActionFunc` as |  | ||||||
|   the `Action` for a command would cause it to error rather than calling the |  | ||||||
|   function. Should not have a affected declarative cases using `func(c |  | ||||||
|   *cli.Context) err)`. |  | ||||||
| - Shell completion now handles the case where the user specifies |  | ||||||
|   `--generate-bash-completion` immediately after a flag that takes an argument. |  | ||||||
|   Previously it call the application with `--generate-bash-completion` as the |  | ||||||
|   flag value. |  | ||||||
|  |  | ||||||
| ## [1.19.0] - 2016-11-19 |  | ||||||
| ### Added |  | ||||||
| - `FlagsByName` was added to make it easy to sort flags (e.g. `sort.Sort(cli.FlagsByName(app.Flags))`) |  | ||||||
| - A `Description` field was added to `App` for a more detailed description of |  | ||||||
|   the application (similar to the existing `Description` field on `Command`) |  | ||||||
| - Flag type code generation via `go generate` |  | ||||||
| - Write to stderr and exit 1 if action returns non-nil error |  | ||||||
| - Added support for TOML to the `altsrc` loader |  | ||||||
| - `SkipArgReorder` was added to allow users to skip the argument reordering. |  | ||||||
|   This is useful if you want to consider all "flags" after an argument as |  | ||||||
|   arguments rather than flags (the default behavior of the stdlib `flag` |  | ||||||
|   library). This is backported functionality from the [removal of the flag |  | ||||||
|   reordering](https://github.com/urfave/cli/pull/398) in the unreleased version |  | ||||||
|   2 |  | ||||||
| - For formatted errors (those implementing `ErrorFormatter`), the errors will |  | ||||||
|   be formatted during output. Compatible with `pkg/errors`. |  | ||||||
|  |  | ||||||
| ### Changed |  | ||||||
| - Raise minimum tested/supported Go version to 1.2+ |  | ||||||
|  |  | ||||||
| ### Fixed |  | ||||||
| - Consider empty environment variables as set (previously environment variables |  | ||||||
|   with the equivalent of `""` would be skipped rather than their value used). |  | ||||||
| - Return an error if the value in a given environment variable cannot be parsed |  | ||||||
|   as the flag type. Previously these errors were silently swallowed. |  | ||||||
| - Print full error when an invalid flag is specified (which includes the invalid flag) |  | ||||||
| - `App.Writer` defaults to `stdout` when `nil` |  | ||||||
| - If no action is specified on a command or app, the help is now printed instead of `panic`ing |  | ||||||
| - `App.Metadata` is initialized automatically now (previously was `nil` unless initialized) |  | ||||||
| - Correctly show help message if `-h` is provided to a subcommand |  | ||||||
| - `context.(Global)IsSet` now respects environment variables. Previously it |  | ||||||
|   would return `false` if a flag was specified in the environment rather than |  | ||||||
|   as an argument |  | ||||||
| - Removed deprecation warnings to STDERR to avoid them leaking to the end-user |  | ||||||
| - `altsrc`s import paths were updated to use `gopkg.in/urfave/cli.v1`. This |  | ||||||
|   fixes issues that occurred when `gopkg.in/urfave/cli.v1` was imported as well |  | ||||||
|   as `altsrc` where Go would complain that the types didn't match |  | ||||||
|  |  | ||||||
| ## [1.18.1] - 2016-08-28 |  | ||||||
| ### Fixed |  | ||||||
| - Removed deprecation warnings to STDERR to avoid them leaking to the end-user (backported) |  | ||||||
|  |  | ||||||
| ## [1.18.0] - 2016-06-27 |  | ||||||
| ### Added |  | ||||||
| - `./runtests` test runner with coverage tracking by default |  | ||||||
| - testing on OS X |  | ||||||
| - testing on Windows |  | ||||||
| - `UintFlag`, `Uint64Flag`, and `Int64Flag` types and supporting code |  | ||||||
|  |  | ||||||
| ### Changed |  | ||||||
| - Use spaces for alignment in help/usage output instead of tabs, making the |  | ||||||
|   output alignment consistent regardless of tab width |  | ||||||
|  |  | ||||||
| ### Fixed |  | ||||||
| - Printing of command aliases in help text |  | ||||||
| - Printing of visible flags for both struct and struct pointer flags |  | ||||||
| - Display the `help` subcommand when using `CommandCategories` |  | ||||||
| - No longer swallows `panic`s that occur within the `Action`s themselves when |  | ||||||
|   detecting the signature of the `Action` field |  | ||||||
|  |  | ||||||
| ## [1.17.1] - 2016-08-28 |  | ||||||
| ### Fixed |  | ||||||
| - Removed deprecation warnings to STDERR to avoid them leaking to the end-user |  | ||||||
|  |  | ||||||
| ## [1.17.0] - 2016-05-09 |  | ||||||
| ### Added |  | ||||||
| - Pluggable flag-level help text rendering via `cli.DefaultFlagStringFunc` |  | ||||||
| - `context.GlobalBoolT` was added as an analogue to `context.GlobalBool` |  | ||||||
| - Support for hiding commands by setting `Hidden: true` -- this will hide the |  | ||||||
|   commands in help output |  | ||||||
|  |  | ||||||
| ### Changed |  | ||||||
| - `Float64Flag`, `IntFlag`, and `DurationFlag` default values are no longer |  | ||||||
|   quoted in help text output. |  | ||||||
| - All flag types now include `(default: {value})` strings following usage when a |  | ||||||
|   default value can be (reasonably) detected. |  | ||||||
| - `IntSliceFlag` and `StringSliceFlag` usage strings are now more consistent |  | ||||||
|   with non-slice flag types |  | ||||||
| - Apps now exit with a code of 3 if an unknown subcommand is specified |  | ||||||
|   (previously they printed "No help topic for...", but still exited 0. This |  | ||||||
|   makes it easier to script around apps built using `cli` since they can trust |  | ||||||
|   that a 0 exit code indicated a successful execution. |  | ||||||
| - cleanups based on [Go Report Card |  | ||||||
|   feedback](https://goreportcard.com/report/github.com/urfave/cli) |  | ||||||
|  |  | ||||||
| ## [1.16.1] - 2016-08-28 |  | ||||||
| ### Fixed |  | ||||||
| - Removed deprecation warnings to STDERR to avoid them leaking to the end-user |  | ||||||
|  |  | ||||||
| ## [1.16.0] - 2016-05-02 |  | ||||||
| ### Added |  | ||||||
| - `Hidden` field on all flag struct types to omit from generated help text |  | ||||||
|  |  | ||||||
| ### Changed |  | ||||||
| - `BashCompletionFlag` (`--enable-bash-completion`) is now omitted from |  | ||||||
| generated help text via the `Hidden` field |  | ||||||
|  |  | ||||||
| ### Fixed |  | ||||||
| - handling of error values in `HandleAction` and `HandleExitCoder` |  | ||||||
|  |  | ||||||
| ## [1.15.0] - 2016-04-30 |  | ||||||
| ### Added |  | ||||||
| - This file! |  | ||||||
| - Support for placeholders in flag usage strings |  | ||||||
| - `App.Metadata` map for arbitrary data/state management |  | ||||||
| - `Set` and `GlobalSet` methods on `*cli.Context` for altering values after |  | ||||||
| parsing. |  | ||||||
| - Support for nested lookup of dot-delimited keys in structures loaded from |  | ||||||
| YAML. |  | ||||||
|  |  | ||||||
| ### Changed |  | ||||||
| - The `App.Action` and `Command.Action` now prefer a return signature of |  | ||||||
| `func(*cli.Context) error`, as defined by `cli.ActionFunc`.  If a non-nil |  | ||||||
| `error` is returned, there may be two outcomes: |  | ||||||
|     - If the error fulfills `cli.ExitCoder`, then `os.Exit` will be called |  | ||||||
|     automatically |  | ||||||
|     - Else the error is bubbled up and returned from `App.Run` |  | ||||||
| - Specifying an `Action` with the legacy return signature of |  | ||||||
| `func(*cli.Context)` will produce a deprecation message to stderr |  | ||||||
| - Specifying an `Action` that is not a `func` type will produce a non-zero exit |  | ||||||
| from `App.Run` |  | ||||||
| - Specifying an `Action` func that has an invalid (input) signature will |  | ||||||
| produce a non-zero exit from `App.Run` |  | ||||||
|  |  | ||||||
| ### Deprecated |  | ||||||
| - <a name="deprecated-cli-app-runandexitonerror"></a> |  | ||||||
| `cli.App.RunAndExitOnError`, which should now be done by returning an error |  | ||||||
| that fulfills `cli.ExitCoder` to `cli.App.Run`. |  | ||||||
| - <a name="deprecated-cli-app-action-signature"></a> the legacy signature for |  | ||||||
| `cli.App.Action` of `func(*cli.Context)`, which should now have a return |  | ||||||
| signature of `func(*cli.Context) error`, as defined by `cli.ActionFunc`. |  | ||||||
|  |  | ||||||
| ### Fixed |  | ||||||
| - Added missing `*cli.Context.GlobalFloat64` method |  | ||||||
|  |  | ||||||
| ## [1.14.0] - 2016-04-03 (backfilled 2016-04-25) |  | ||||||
| ### Added |  | ||||||
| - Codebeat badge |  | ||||||
| - Support for categorization via `CategorizedHelp` and `Categories` on app. |  | ||||||
|  |  | ||||||
| ### Changed |  | ||||||
| - Use `filepath.Base` instead of `path.Base` in `Name` and `HelpName`. |  | ||||||
|  |  | ||||||
| ### Fixed |  | ||||||
| - Ensure version is not shown in help text when `HideVersion` set. |  | ||||||
|  |  | ||||||
| ## [1.13.0] - 2016-03-06 (backfilled 2016-04-25) |  | ||||||
| ### Added |  | ||||||
| - YAML file input support. |  | ||||||
| - `NArg` method on context. |  | ||||||
|  |  | ||||||
| ## [1.12.0] - 2016-02-17 (backfilled 2016-04-25) |  | ||||||
| ### Added |  | ||||||
| - Custom usage error handling. |  | ||||||
| - Custom text support in `USAGE` section of help output. |  | ||||||
| - Improved help messages for empty strings. |  | ||||||
| - AppVeyor CI configuration. |  | ||||||
|  |  | ||||||
| ### Changed |  | ||||||
| - Removed `panic` from default help printer func. |  | ||||||
| - De-duping and optimizations. |  | ||||||
|  |  | ||||||
| ### Fixed |  | ||||||
| - Correctly handle `Before`/`After` at command level when no subcommands. |  | ||||||
| - Case of literal `-` argument causing flag reordering. |  | ||||||
| - Environment variable hints on Windows. |  | ||||||
| - Docs updates. |  | ||||||
|  |  | ||||||
| ## [1.11.1] - 2015-12-21 (backfilled 2016-04-25) |  | ||||||
| ### Changed |  | ||||||
| - Use `path.Base` in `Name` and `HelpName` |  | ||||||
| - Export `GetName` on flag types. |  | ||||||
|  |  | ||||||
| ### Fixed |  | ||||||
| - Flag parsing when skipping is enabled. |  | ||||||
| - Test output cleanup. |  | ||||||
| - Move completion check to account for empty input case. |  | ||||||
|  |  | ||||||
| ## [1.11.0] - 2015-11-15 (backfilled 2016-04-25) |  | ||||||
| ### Added |  | ||||||
| - Destination scan support for flags. |  | ||||||
| - Testing against `tip` in Travis CI config. |  | ||||||
|  |  | ||||||
| ### Changed |  | ||||||
| - Go version in Travis CI config. |  | ||||||
|  |  | ||||||
| ### Fixed |  | ||||||
| - Removed redundant tests. |  | ||||||
| - Use correct example naming in tests. |  | ||||||
|  |  | ||||||
| ## [1.10.2] - 2015-10-29 (backfilled 2016-04-25) |  | ||||||
| ### Fixed |  | ||||||
| - Remove unused var in bash completion. |  | ||||||
|  |  | ||||||
| ## [1.10.1] - 2015-10-21 (backfilled 2016-04-25) |  | ||||||
| ### Added |  | ||||||
| - Coverage and reference logos in README. |  | ||||||
|  |  | ||||||
| ### Fixed |  | ||||||
| - Use specified values in help and version parsing. |  | ||||||
| - Only display app version and help message once. |  | ||||||
|  |  | ||||||
| ## [1.10.0] - 2015-10-06 (backfilled 2016-04-25) |  | ||||||
| ### Added |  | ||||||
| - More tests for existing functionality. |  | ||||||
| - `ArgsUsage` at app and command level for help text flexibility. |  | ||||||
|  |  | ||||||
| ### Fixed |  | ||||||
| - Honor `HideHelp` and `HideVersion` in `App.Run`. |  | ||||||
| - Remove juvenile word from README. |  | ||||||
|  |  | ||||||
| ## [1.9.0] - 2015-09-08 (backfilled 2016-04-25) |  | ||||||
| ### Added |  | ||||||
| - `FullName` on command with accompanying help output update. |  | ||||||
| - Set default `$PROG` in bash completion. |  | ||||||
|  |  | ||||||
| ### Changed |  | ||||||
| - Docs formatting. |  | ||||||
|  |  | ||||||
| ### Fixed |  | ||||||
| - Removed self-referential imports in tests. |  | ||||||
|  |  | ||||||
| ## [1.8.0] - 2015-06-30 (backfilled 2016-04-25) |  | ||||||
| ### Added |  | ||||||
| - Support for `Copyright` at app level. |  | ||||||
| - `Parent` func at context level to walk up context lineage. |  | ||||||
|  |  | ||||||
| ### Fixed |  | ||||||
| - Global flag processing at top level. |  | ||||||
|  |  | ||||||
| ## [1.7.1] - 2015-06-11 (backfilled 2016-04-25) |  | ||||||
| ### Added |  | ||||||
| - Aggregate errors from `Before`/`After` funcs. |  | ||||||
| - Doc comments on flag structs. |  | ||||||
| - Include non-global flags when checking version and help. |  | ||||||
| - Travis CI config updates. |  | ||||||
|  |  | ||||||
| ### Fixed |  | ||||||
| - Ensure slice type flags have non-nil values. |  | ||||||
| - Collect global flags from the full command hierarchy. |  | ||||||
| - Docs prose. |  | ||||||
|  |  | ||||||
| ## [1.7.0] - 2015-05-03 (backfilled 2016-04-25) |  | ||||||
| ### Changed |  | ||||||
| - `HelpPrinter` signature includes output writer. |  | ||||||
|  |  | ||||||
| ### Fixed |  | ||||||
| - Specify go 1.1+ in docs. |  | ||||||
| - Set `Writer` when running command as app. |  | ||||||
|  |  | ||||||
| ## [1.6.0] - 2015-03-23 (backfilled 2016-04-25) |  | ||||||
| ### Added |  | ||||||
| - Multiple author support. |  | ||||||
| - `NumFlags` at context level. |  | ||||||
| - `Aliases` at command level. |  | ||||||
|  |  | ||||||
| ### Deprecated |  | ||||||
| - `ShortName` at command level. |  | ||||||
|  |  | ||||||
| ### Fixed |  | ||||||
| - Subcommand help output. |  | ||||||
| - Backward compatible support for deprecated `Author` and `Email` fields. |  | ||||||
| - Docs regarding `Names`/`Aliases`. |  | ||||||
|  |  | ||||||
| ## [1.5.0] - 2015-02-20 (backfilled 2016-04-25) |  | ||||||
| ### Added |  | ||||||
| - `After` hook func support at app and command level. |  | ||||||
|  |  | ||||||
| ### Fixed |  | ||||||
| - Use parsed context when running command as subcommand. |  | ||||||
| - Docs prose. |  | ||||||
|  |  | ||||||
| ## [1.4.1] - 2015-01-09 (backfilled 2016-04-25) |  | ||||||
| ### Added |  | ||||||
| - Support for hiding `-h / --help` flags, but not `help` subcommand. |  | ||||||
| - Stop flag parsing after `--`. |  | ||||||
|  |  | ||||||
| ### Fixed |  | ||||||
| - Help text for generic flags to specify single value. |  | ||||||
| - Use double quotes in output for defaults. |  | ||||||
| - Use `ParseInt` instead of `ParseUint` for int environment var values. |  | ||||||
| - Use `0` as base when parsing int environment var values. |  | ||||||
|  |  | ||||||
| ## [1.4.0] - 2014-12-12 (backfilled 2016-04-25) |  | ||||||
| ### Added |  | ||||||
| - Support for environment variable lookup "cascade". |  | ||||||
| - Support for `Stdout` on app for output redirection. |  | ||||||
|  |  | ||||||
| ### Fixed |  | ||||||
| - Print command help instead of app help in `ShowCommandHelp`. |  | ||||||
|  |  | ||||||
| ## [1.3.1] - 2014-11-13 (backfilled 2016-04-25) |  | ||||||
| ### Added |  | ||||||
| - Docs and example code updates. |  | ||||||
|  |  | ||||||
| ### Changed |  | ||||||
| - Default `-v / --version` flag made optional. |  | ||||||
|  |  | ||||||
| ## [1.3.0] - 2014-08-10 (backfilled 2016-04-25) |  | ||||||
| ### Added |  | ||||||
| - `FlagNames` at context level. |  | ||||||
| - Exposed `VersionPrinter` var for more control over version output. |  | ||||||
| - Zsh completion hook. |  | ||||||
| - `AUTHOR` section in default app help template. |  | ||||||
| - Contribution guidelines. |  | ||||||
| - `DurationFlag` type. |  | ||||||
|  |  | ||||||
| ## [1.2.0] - 2014-08-02 |  | ||||||
| ### Added |  | ||||||
| - Support for environment variable defaults on flags plus tests. |  | ||||||
|  |  | ||||||
| ## [1.1.0] - 2014-07-15 |  | ||||||
| ### Added |  | ||||||
| - Bash completion. |  | ||||||
| - Optional hiding of built-in help command. |  | ||||||
| - Optional skipping of flag parsing at command level. |  | ||||||
| - `Author`, `Email`, and `Compiled` metadata on app. |  | ||||||
| - `Before` hook func support at app and command level. |  | ||||||
| - `CommandNotFound` func support at app level. |  | ||||||
| - Command reference available on context. |  | ||||||
| - `GenericFlag` type. |  | ||||||
| - `Float64Flag` type. |  | ||||||
| - `BoolTFlag` type. |  | ||||||
| - `IsSet` flag helper on context. |  | ||||||
| - More flag lookup funcs at context level. |  | ||||||
| - More tests & docs. |  | ||||||
|  |  | ||||||
| ### Changed |  | ||||||
| - Help template updates to account for presence/absence of flags. |  | ||||||
| - Separated subcommand help template. |  | ||||||
| - Exposed `HelpPrinter` var for more control over help output. |  | ||||||
|  |  | ||||||
| ## [1.0.0] - 2013-11-01 |  | ||||||
| ### Added |  | ||||||
| - `help` flag in default app flag set and each command flag set. |  | ||||||
| - Custom handling of argument parsing errors. |  | ||||||
| - Command lookup by name at app level. |  | ||||||
| - `StringSliceFlag` type and supporting `StringSlice` type. |  | ||||||
| - `IntSliceFlag` type and supporting `IntSlice` type. |  | ||||||
| - Slice type flag lookups by name at context level. |  | ||||||
| - Export of app and command help functions. |  | ||||||
| - More tests & docs. |  | ||||||
|  |  | ||||||
| ## 0.1.0 - 2013-07-22 |  | ||||||
| ### Added |  | ||||||
| - Initial implementation. |  | ||||||
|  |  | ||||||
| [Unreleased]: https://github.com/urfave/cli/compare/v1.18.0...HEAD |  | ||||||
| [1.18.0]: https://github.com/urfave/cli/compare/v1.17.0...v1.18.0 |  | ||||||
| [1.17.0]: https://github.com/urfave/cli/compare/v1.16.0...v1.17.0 |  | ||||||
| [1.16.0]: https://github.com/urfave/cli/compare/v1.15.0...v1.16.0 |  | ||||||
| [1.15.0]: https://github.com/urfave/cli/compare/v1.14.0...v1.15.0 |  | ||||||
| [1.14.0]: https://github.com/urfave/cli/compare/v1.13.0...v1.14.0 |  | ||||||
| [1.13.0]: https://github.com/urfave/cli/compare/v1.12.0...v1.13.0 |  | ||||||
| [1.12.0]: https://github.com/urfave/cli/compare/v1.11.1...v1.12.0 |  | ||||||
| [1.11.1]: https://github.com/urfave/cli/compare/v1.11.0...v1.11.1 |  | ||||||
| [1.11.0]: https://github.com/urfave/cli/compare/v1.10.2...v1.11.0 |  | ||||||
| [1.10.2]: https://github.com/urfave/cli/compare/v1.10.1...v1.10.2 |  | ||||||
| [1.10.1]: https://github.com/urfave/cli/compare/v1.10.0...v1.10.1 |  | ||||||
| [1.10.0]: https://github.com/urfave/cli/compare/v1.9.0...v1.10.0 |  | ||||||
| [1.9.0]: https://github.com/urfave/cli/compare/v1.8.0...v1.9.0 |  | ||||||
| [1.8.0]: https://github.com/urfave/cli/compare/v1.7.1...v1.8.0 |  | ||||||
| [1.7.1]: https://github.com/urfave/cli/compare/v1.7.0...v1.7.1 |  | ||||||
| [1.7.0]: https://github.com/urfave/cli/compare/v1.6.0...v1.7.0 |  | ||||||
| [1.6.0]: https://github.com/urfave/cli/compare/v1.5.0...v1.6.0 |  | ||||||
| [1.5.0]: https://github.com/urfave/cli/compare/v1.4.1...v1.5.0 |  | ||||||
| [1.4.1]: https://github.com/urfave/cli/compare/v1.4.0...v1.4.1 |  | ||||||
| [1.4.0]: https://github.com/urfave/cli/compare/v1.3.1...v1.4.0 |  | ||||||
| [1.3.1]: https://github.com/urfave/cli/compare/v1.3.0...v1.3.1 |  | ||||||
| [1.3.0]: https://github.com/urfave/cli/compare/v1.2.0...v1.3.0 |  | ||||||
| [1.2.0]: https://github.com/urfave/cli/compare/v1.1.0...v1.2.0 |  | ||||||
| [1.1.0]: https://github.com/urfave/cli/compare/v1.0.0...v1.1.0 |  | ||||||
| [1.0.0]: https://github.com/urfave/cli/compare/v0.1.0...v1.0.0 |  | ||||||
							
								
								
									
										74
									
								
								vendor/github.com/urfave/cli/CODE_OF_CONDUCT.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										74
									
								
								vendor/github.com/urfave/cli/CODE_OF_CONDUCT.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,74 @@ | |||||||
|  | # Contributor Covenant Code of Conduct | ||||||
|  |  | ||||||
|  | ## Our Pledge | ||||||
|  |  | ||||||
|  | In the interest of fostering an open and welcoming environment, we as | ||||||
|  | contributors and maintainers pledge to making participation in our project and | ||||||
|  | our community a harassment-free experience for everyone, regardless of age, body | ||||||
|  | size, disability, ethnicity, gender identity and expression, level of experience, | ||||||
|  | education, socio-economic status, nationality, personal appearance, race, | ||||||
|  | religion, or sexual identity and orientation. | ||||||
|  |  | ||||||
|  | ## Our Standards | ||||||
|  |  | ||||||
|  | Examples of behavior that contributes to creating a positive environment | ||||||
|  | include: | ||||||
|  |  | ||||||
|  | * Using welcoming and inclusive language | ||||||
|  | * Being respectful of differing viewpoints and experiences | ||||||
|  | * Gracefully accepting constructive criticism | ||||||
|  | * Focusing on what is best for the community | ||||||
|  | * Showing empathy towards other community members | ||||||
|  |  | ||||||
|  | Examples of unacceptable behavior by participants include: | ||||||
|  |  | ||||||
|  | * The use of sexualized language or imagery and unwelcome sexual attention or | ||||||
|  |   advances | ||||||
|  | * Trolling, insulting/derogatory comments, and personal or political attacks | ||||||
|  | * Public or private harassment | ||||||
|  | * Publishing others' private information, such as a physical or electronic | ||||||
|  |   address, without explicit permission | ||||||
|  | * Other conduct which could reasonably be considered inappropriate in a | ||||||
|  |   professional setting | ||||||
|  |  | ||||||
|  | ## Our Responsibilities | ||||||
|  |  | ||||||
|  | Project maintainers are responsible for clarifying the standards of acceptable | ||||||
|  | behavior and are expected to take appropriate and fair corrective action in | ||||||
|  | response to any instances of unacceptable behavior. | ||||||
|  |  | ||||||
|  | Project maintainers have the right and responsibility to remove, edit, or | ||||||
|  | reject comments, commits, code, wiki edits, issues, and other contributions | ||||||
|  | that are not aligned to this Code of Conduct, or to ban temporarily or | ||||||
|  | permanently any contributor for other behaviors that they deem inappropriate, | ||||||
|  | threatening, offensive, or harmful. | ||||||
|  |  | ||||||
|  | ## Scope | ||||||
|  |  | ||||||
|  | This Code of Conduct applies both within project spaces and in public spaces | ||||||
|  | when an individual is representing the project or its community. Examples of | ||||||
|  | representing a project or community include using an official project e-mail | ||||||
|  | address, posting via an official social media account, or acting as an appointed | ||||||
|  | representative at an online or offline event. Representation of a project may be | ||||||
|  | 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. | ||||||
|  |  | ||||||
|  | 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 | ||||||
|  | members of the project's leadership. | ||||||
|  |  | ||||||
|  | ## Attribution | ||||||
|  |  | ||||||
|  | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, | ||||||
|  | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html | ||||||
|  |  | ||||||
|  | [homepage]: https://www.contributor-covenant.org | ||||||
|  |  | ||||||
							
								
								
									
										1351
									
								
								vendor/github.com/urfave/cli/README.md
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										1351
									
								
								vendor/github.com/urfave/cli/README.md
									
									
									
										generated
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										109
									
								
								vendor/github.com/urfave/cli/app.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										109
									
								
								vendor/github.com/urfave/cli/app.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,9 +1,9 @@ | |||||||
| package cli | package cli | ||||||
|  |  | ||||||
| import ( | import ( | ||||||
|  | 	"flag" | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"io" | 	"io" | ||||||
| 	"io/ioutil" |  | ||||||
| 	"os" | 	"os" | ||||||
| 	"path/filepath" | 	"path/filepath" | ||||||
| 	"sort" | 	"sort" | ||||||
| @@ -13,7 +13,8 @@ import ( | |||||||
| var ( | var ( | ||||||
| 	changeLogURL            = "https://github.com/urfave/cli/blob/master/CHANGELOG.md" | 	changeLogURL            = "https://github.com/urfave/cli/blob/master/CHANGELOG.md" | ||||||
| 	appActionDeprecationURL = fmt.Sprintf("%s#deprecated-cli-app-action-signature", changeLogURL) | 	appActionDeprecationURL = fmt.Sprintf("%s#deprecated-cli-app-action-signature", changeLogURL) | ||||||
| 	runAndExitOnErrorDeprecationURL = fmt.Sprintf("%s#deprecated-cli-app-runandexitonerror", changeLogURL) | 	// unused variable. commented for now. will remove in future if agreed upon by everyone | ||||||
|  | 	//runAndExitOnErrorDeprecationURL = fmt.Sprintf("%s#deprecated-cli-app-runandexitonerror", changeLogURL) | ||||||
|  |  | ||||||
| 	contactSysadmin = "This is an error in the application.  Please contact the distributor of this application if this is not you." | 	contactSysadmin = "This is an error in the application.  Please contact the distributor of this application if this is not you." | ||||||
|  |  | ||||||
| @@ -83,6 +84,9 @@ type App struct { | |||||||
| 	Writer io.Writer | 	Writer io.Writer | ||||||
| 	// ErrWriter writes error output | 	// ErrWriter writes error output | ||||||
| 	ErrWriter io.Writer | 	ErrWriter io.Writer | ||||||
|  | 	// Execute this function to handle ExitErrors. If not provided, HandleExitCoder is provided to | ||||||
|  | 	// function as a default, so this is optional. | ||||||
|  | 	ExitErrHandler ExitErrHandlerFunc | ||||||
| 	// Other custom info | 	// Other custom info | ||||||
| 	Metadata map[string]interface{} | 	Metadata map[string]interface{} | ||||||
| 	// Carries a function which returns app specific info. | 	// Carries a function which returns app specific info. | ||||||
| @@ -91,6 +95,10 @@ type App struct { | |||||||
| 	// cli.go uses text/template to render templates. You can | 	// cli.go uses text/template to render templates. You can | ||||||
| 	// render custom help text by setting this variable. | 	// render custom help text by setting this variable. | ||||||
| 	CustomAppHelpTemplate string | 	CustomAppHelpTemplate string | ||||||
|  | 	// Boolean to enable short-option handling so user can combine several | ||||||
|  | 	// single-character bool arguements into one | ||||||
|  | 	// i.e. foobar -o -v -> foobar -ov | ||||||
|  | 	UseShortOptionHandling bool | ||||||
|  |  | ||||||
| 	didSetup bool | 	didSetup bool | ||||||
| } | } | ||||||
| @@ -135,7 +143,7 @@ func (a *App) Setup() { | |||||||
| 		a.Authors = append(a.Authors, Author{Name: a.Author, Email: a.Email}) | 		a.Authors = append(a.Authors, Author{Name: a.Author, Email: a.Email}) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	newCmds := []Command{} | 	var newCmds []Command | ||||||
| 	for _, c := range a.Commands { | 	for _, c := range a.Commands { | ||||||
| 		if c.HelpName == "" { | 		if c.HelpName == "" { | ||||||
| 			c.HelpName = fmt.Sprintf("%s %s", a.HelpName, c.Name) | 			c.HelpName = fmt.Sprintf("%s %s", a.HelpName, c.Name) | ||||||
| @@ -170,6 +178,14 @@ func (a *App) Setup() { | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func (a *App) newFlagSet() (*flag.FlagSet, error) { | ||||||
|  | 	return flagSet(a.Name, a.Flags) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (a *App) useShortOptionHandling() bool { | ||||||
|  | 	return a.UseShortOptionHandling | ||||||
|  | } | ||||||
|  |  | ||||||
| // Run is the entry point to the cli app. Parses the arguments slice and routes | // Run is the entry point to the cli app. Parses the arguments slice and routes | ||||||
| // to the proper flag/args combination | // to the proper flag/args combination | ||||||
| func (a *App) Run(arguments []string) (err error) { | func (a *App) Run(arguments []string) (err error) { | ||||||
| @@ -183,19 +199,17 @@ func (a *App) Run(arguments []string) (err error) { | |||||||
| 	// always appends the completion flag at the end of the command | 	// always appends the completion flag at the end of the command | ||||||
| 	shellComplete, arguments := checkShellCompleteFlag(a, arguments) | 	shellComplete, arguments := checkShellCompleteFlag(a, arguments) | ||||||
|  |  | ||||||
| 	// parse flags | 	set, err := a.newFlagSet() | ||||||
| 	set, err := flagSet(a.Name, a.Flags) |  | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	set.SetOutput(ioutil.Discard) | 	err = parseIter(set, a, arguments[1:]) | ||||||
| 	err = set.Parse(arguments[1:]) |  | ||||||
| 	nerr := normalizeFlags(a.Flags, set) | 	nerr := normalizeFlags(a.Flags, set) | ||||||
| 	context := NewContext(a, set, nil) | 	context := NewContext(a, set, nil) | ||||||
| 	if nerr != nil { | 	if nerr != nil { | ||||||
| 		fmt.Fprintln(a.Writer, nerr) | 		_, _ = fmt.Fprintln(a.Writer, nerr) | ||||||
| 		ShowAppHelp(context) | 		_ = ShowAppHelp(context) | ||||||
| 		return nerr | 		return nerr | ||||||
| 	} | 	} | ||||||
| 	context.shellComplete = shellComplete | 	context.shellComplete = shellComplete | ||||||
| @@ -207,16 +221,16 @@ func (a *App) Run(arguments []string) (err error) { | |||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		if a.OnUsageError != nil { | 		if a.OnUsageError != nil { | ||||||
| 			err := a.OnUsageError(context, err, false) | 			err := a.OnUsageError(context, err, false) | ||||||
| 			HandleExitCoder(err) | 			a.handleExitCoder(context, err) | ||||||
| 			return err | 			return err | ||||||
| 		} | 		} | ||||||
| 		fmt.Fprintf(a.Writer, "%s %s\n\n", "Incorrect Usage.", err.Error()) | 		_, _ = fmt.Fprintf(a.Writer, "%s %s\n\n", "Incorrect Usage.", err.Error()) | ||||||
| 		ShowAppHelp(context) | 		_ = ShowAppHelp(context) | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if !a.HideHelp && checkHelp(context) { | 	if !a.HideHelp && checkHelp(context) { | ||||||
| 		ShowAppHelp(context) | 		_ = ShowAppHelp(context) | ||||||
| 		return nil | 		return nil | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -225,6 +239,12 @@ func (a *App) Run(arguments []string) (err error) { | |||||||
| 		return nil | 		return nil | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	cerr := checkRequiredFlags(a.Flags, context) | ||||||
|  | 	if cerr != nil { | ||||||
|  | 		_ = ShowAppHelp(context) | ||||||
|  | 		return cerr | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	if a.After != nil { | 	if a.After != nil { | ||||||
| 		defer func() { | 		defer func() { | ||||||
| 			if afterErr := a.After(context); afterErr != nil { | 			if afterErr := a.After(context); afterErr != nil { | ||||||
| @@ -240,8 +260,9 @@ func (a *App) Run(arguments []string) (err error) { | |||||||
| 	if a.Before != nil { | 	if a.Before != nil { | ||||||
| 		beforeErr := a.Before(context) | 		beforeErr := a.Before(context) | ||||||
| 		if beforeErr != nil { | 		if beforeErr != nil { | ||||||
| 			ShowAppHelp(context) | 			_, _ = fmt.Fprintf(a.Writer, "%v\n\n", beforeErr) | ||||||
| 			HandleExitCoder(beforeErr) | 			_ = ShowAppHelp(context) | ||||||
|  | 			a.handleExitCoder(context, beforeErr) | ||||||
| 			err = beforeErr | 			err = beforeErr | ||||||
| 			return err | 			return err | ||||||
| 		} | 		} | ||||||
| @@ -263,7 +284,7 @@ func (a *App) Run(arguments []string) (err error) { | |||||||
| 	// Run default Action | 	// Run default Action | ||||||
| 	err = HandleAction(a.Action, context) | 	err = HandleAction(a.Action, context) | ||||||
|  |  | ||||||
| 	HandleExitCoder(err) | 	a.handleExitCoder(context, err) | ||||||
| 	return err | 	return err | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -274,7 +295,7 @@ func (a *App) Run(arguments []string) (err error) { | |||||||
| // code in the cli.ExitCoder | // code in the cli.ExitCoder | ||||||
| func (a *App) RunAndExitOnError() { | func (a *App) RunAndExitOnError() { | ||||||
| 	if err := a.Run(os.Args); err != nil { | 	if err := a.Run(os.Args); err != nil { | ||||||
| 		fmt.Fprintln(a.errWriter(), err) | 		_, _ = fmt.Fprintln(a.errWriter(), err) | ||||||
| 		OsExiter(1) | 		OsExiter(1) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| @@ -301,24 +322,22 @@ func (a *App) RunAsSubcommand(ctx *Context) (err error) { | |||||||
| 	} | 	} | ||||||
| 	a.Commands = newCmds | 	a.Commands = newCmds | ||||||
|  |  | ||||||
| 	// parse flags | 	set, err := a.newFlagSet() | ||||||
| 	set, err := flagSet(a.Name, a.Flags) |  | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	set.SetOutput(ioutil.Discard) | 	err = parseIter(set, a, ctx.Args().Tail()) | ||||||
| 	err = set.Parse(ctx.Args().Tail()) |  | ||||||
| 	nerr := normalizeFlags(a.Flags, set) | 	nerr := normalizeFlags(a.Flags, set) | ||||||
| 	context := NewContext(a, set, ctx) | 	context := NewContext(a, set, ctx) | ||||||
|  |  | ||||||
| 	if nerr != nil { | 	if nerr != nil { | ||||||
| 		fmt.Fprintln(a.Writer, nerr) | 		_, _ = fmt.Fprintln(a.Writer, nerr) | ||||||
| 		fmt.Fprintln(a.Writer) | 		_, _ = fmt.Fprintln(a.Writer) | ||||||
| 		if len(a.Commands) > 0 { | 		if len(a.Commands) > 0 { | ||||||
| 			ShowSubcommandHelp(context) | 			_ = ShowSubcommandHelp(context) | ||||||
| 		} else { | 		} else { | ||||||
| 			ShowCommandHelp(ctx, context.Args().First()) | 			_ = ShowCommandHelp(ctx, context.Args().First()) | ||||||
| 		} | 		} | ||||||
| 		return nerr | 		return nerr | ||||||
| 	} | 	} | ||||||
| @@ -330,11 +349,11 @@ func (a *App) RunAsSubcommand(ctx *Context) (err error) { | |||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		if a.OnUsageError != nil { | 		if a.OnUsageError != nil { | ||||||
| 			err = a.OnUsageError(context, err, true) | 			err = a.OnUsageError(context, err, true) | ||||||
| 			HandleExitCoder(err) | 			a.handleExitCoder(context, err) | ||||||
| 			return err | 			return err | ||||||
| 		} | 		} | ||||||
| 		fmt.Fprintf(a.Writer, "%s %s\n\n", "Incorrect Usage.", err.Error()) | 		_, _ = fmt.Fprintf(a.Writer, "%s %s\n\n", "Incorrect Usage.", err.Error()) | ||||||
| 		ShowSubcommandHelp(context) | 		_ = ShowSubcommandHelp(context) | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -348,11 +367,17 @@ func (a *App) RunAsSubcommand(ctx *Context) (err error) { | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	cerr := checkRequiredFlags(a.Flags, context) | ||||||
|  | 	if cerr != nil { | ||||||
|  | 		_ = ShowSubcommandHelp(context) | ||||||
|  | 		return cerr | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	if a.After != nil { | 	if a.After != nil { | ||||||
| 		defer func() { | 		defer func() { | ||||||
| 			afterErr := a.After(context) | 			afterErr := a.After(context) | ||||||
| 			if afterErr != nil { | 			if afterErr != nil { | ||||||
| 				HandleExitCoder(err) | 				a.handleExitCoder(context, err) | ||||||
| 				if err != nil { | 				if err != nil { | ||||||
| 					err = NewMultiError(err, afterErr) | 					err = NewMultiError(err, afterErr) | ||||||
| 				} else { | 				} else { | ||||||
| @@ -365,7 +390,7 @@ func (a *App) RunAsSubcommand(ctx *Context) (err error) { | |||||||
| 	if a.Before != nil { | 	if a.Before != nil { | ||||||
| 		beforeErr := a.Before(context) | 		beforeErr := a.Before(context) | ||||||
| 		if beforeErr != nil { | 		if beforeErr != nil { | ||||||
| 			HandleExitCoder(beforeErr) | 			a.handleExitCoder(context, beforeErr) | ||||||
| 			err = beforeErr | 			err = beforeErr | ||||||
| 			return err | 			return err | ||||||
| 		} | 		} | ||||||
| @@ -383,7 +408,7 @@ func (a *App) RunAsSubcommand(ctx *Context) (err error) { | |||||||
| 	// Run default Action | 	// Run default Action | ||||||
| 	err = HandleAction(a.Action, context) | 	err = HandleAction(a.Action, context) | ||||||
|  |  | ||||||
| 	HandleExitCoder(err) | 	a.handleExitCoder(context, err) | ||||||
| 	return err | 	return err | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -424,7 +449,7 @@ func (a *App) VisibleCategories() []*CommandCategory { | |||||||
|  |  | ||||||
| // VisibleCommands returns a slice of the Commands with Hidden=false | // VisibleCommands returns a slice of the Commands with Hidden=false | ||||||
| func (a *App) VisibleCommands() []Command { | func (a *App) VisibleCommands() []Command { | ||||||
| 	ret := []Command{} | 	var ret []Command | ||||||
| 	for _, command := range a.Commands { | 	for _, command := range a.Commands { | ||||||
| 		if !command.Hidden { | 		if !command.Hidden { | ||||||
| 			ret = append(ret, command) | 			ret = append(ret, command) | ||||||
| @@ -449,7 +474,6 @@ func (a *App) hasFlag(flag Flag) bool { | |||||||
| } | } | ||||||
|  |  | ||||||
| func (a *App) errWriter() io.Writer { | func (a *App) errWriter() io.Writer { | ||||||
|  |  | ||||||
| 	// When the app ErrWriter is nil use the package level one. | 	// When the app ErrWriter is nil use the package level one. | ||||||
| 	if a.ErrWriter == nil { | 	if a.ErrWriter == nil { | ||||||
| 		return ErrWriter | 		return ErrWriter | ||||||
| @@ -464,6 +488,14 @@ func (a *App) appendFlag(flag Flag) { | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func (a *App) handleExitCoder(context *Context, err error) { | ||||||
|  | 	if a.ExitErrHandler != nil { | ||||||
|  | 		a.ExitErrHandler(context, err) | ||||||
|  | 	} else { | ||||||
|  | 		HandleExitCoder(err) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
| // Author represents someone who has contributed to a cli project. | // Author represents someone who has contributed to a cli project. | ||||||
| type Author struct { | type Author struct { | ||||||
| 	Name  string // The Authors name | 	Name  string // The Authors name | ||||||
| @@ -484,14 +516,15 @@ func (a Author) String() string { | |||||||
| // it's an ActionFunc or a func with the legacy signature for Action, the func | // it's an ActionFunc or a func with the legacy signature for Action, the func | ||||||
| // is run! | // is run! | ||||||
| func HandleAction(action interface{}, context *Context) (err error) { | func HandleAction(action interface{}, context *Context) (err error) { | ||||||
| 	if a, ok := action.(ActionFunc); ok { | 	switch a := action.(type) { | ||||||
|  | 	case ActionFunc: | ||||||
| 		return a(context) | 		return a(context) | ||||||
| 	} else if a, ok := action.(func(*Context) error); ok { | 	case func(*Context) error: | ||||||
| 		return a(context) | 		return a(context) | ||||||
| 	} else if a, ok := action.(func(*Context)); ok { // deprecated function signature | 	case func(*Context): // deprecated function signature | ||||||
| 		a(context) | 		a(context) | ||||||
| 		return nil | 		return nil | ||||||
| 	} else { |  | ||||||
| 		return errInvalidActionType |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	return errInvalidActionType | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										26
									
								
								vendor/github.com/urfave/cli/appveyor.yml
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										26
									
								
								vendor/github.com/urfave/cli/appveyor.yml
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -6,21 +6,23 @@ image: Visual Studio 2017 | |||||||
|  |  | ||||||
| clone_folder: c:\gopath\src\github.com\urfave\cli | clone_folder: c:\gopath\src\github.com\urfave\cli | ||||||
|  |  | ||||||
|  | cache: | ||||||
|  |   - node_modules | ||||||
|  |  | ||||||
| environment: | environment: | ||||||
|   GOPATH: C:\gopath |   GOPATH: C:\gopath | ||||||
|   GOVERSION: 1.8.x |   GOVERSION: 1.11.x | ||||||
|   PYTHON: C:\Python36-x64 |   GO111MODULE: on | ||||||
|   PYTHON_VERSION: 3.6.x |   GOPROXY: https://proxy.golang.org | ||||||
|   PYTHON_ARCH: 64 |  | ||||||
|  |  | ||||||
| install: | install: | ||||||
| - set PATH=%GOPATH%\bin;C:\go\bin;%PATH% |   - set PATH=%GOPATH%\bin;C:\go\bin;%PATH% | ||||||
| - go version |   - go version | ||||||
| - go env |   - go env | ||||||
| - go get github.com/urfave/gfmrun/... |   - go get github.com/urfave/gfmrun/cmd/gfmrun | ||||||
| - go get -v -t ./... |   - go mod vendor | ||||||
|  |  | ||||||
| build_script: | build_script: | ||||||
| - python runtests vet |   - go run build.go vet | ||||||
| - python runtests test |   - go run build.go test | ||||||
| - python runtests gfmrun |   - go run build.go gfmrun docs/v1/manual.md | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								vendor/github.com/urfave/cli/category.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/urfave/cli/category.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -10,7 +10,7 @@ type CommandCategory struct { | |||||||
| } | } | ||||||
|  |  | ||||||
| func (c CommandCategories) Less(i, j int) bool { | func (c CommandCategories) Less(i, j int) bool { | ||||||
| 	return c[i].Name < c[j].Name | 	return lexicographicLess(c[i].Name, c[j].Name) | ||||||
| } | } | ||||||
|  |  | ||||||
| func (c CommandCategories) Len() int { | func (c CommandCategories) Len() int { | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								vendor/github.com/urfave/cli/cli.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/urfave/cli/cli.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -19,4 +19,4 @@ | |||||||
| //   } | //   } | ||||||
| package cli | package cli | ||||||
|  |  | ||||||
| //go:generate python ./generate-flag-types cli -i flag-types.json -o flag_generated.go | //go:generate go run flag-gen/main.go flag-gen/assets_vfsdata.go | ||||||
|   | |||||||
							
								
								
									
										193
									
								
								vendor/github.com/urfave/cli/command.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										193
									
								
								vendor/github.com/urfave/cli/command.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,8 +1,8 @@ | |||||||
| package cli | package cli | ||||||
|  |  | ||||||
| import ( | import ( | ||||||
|  | 	"flag" | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"io/ioutil" |  | ||||||
| 	"sort" | 	"sort" | ||||||
| 	"strings" | 	"strings" | ||||||
| ) | ) | ||||||
| @@ -55,6 +55,10 @@ type Command struct { | |||||||
| 	HideHelp bool | 	HideHelp bool | ||||||
| 	// Boolean to hide this command from help or completion | 	// Boolean to hide this command from help or completion | ||||||
| 	Hidden bool | 	Hidden bool | ||||||
|  | 	// Boolean to enable short-option handling so user can combine several | ||||||
|  | 	// single-character bool arguments into one | ||||||
|  | 	// i.e. foobar -o -v -> foobar -ov | ||||||
|  | 	UseShortOptionHandling bool | ||||||
|  |  | ||||||
| 	// Full name of command for help, defaults to full command name, including parent commands. | 	// Full name of command for help, defaults to full command name, including parent commands. | ||||||
| 	HelpName        string | 	HelpName        string | ||||||
| @@ -73,7 +77,7 @@ func (c CommandsByName) Len() int { | |||||||
| } | } | ||||||
|  |  | ||||||
| func (c CommandsByName) Less(i, j int) bool { | func (c CommandsByName) Less(i, j int) bool { | ||||||
| 	return c[i].Name < c[j].Name | 	return lexicographicLess(c[i].Name, c[j].Name) | ||||||
| } | } | ||||||
|  |  | ||||||
| func (c CommandsByName) Swap(i, j int) { | func (c CommandsByName) Swap(i, j int) { | ||||||
| @@ -106,57 +110,11 @@ func (c Command) Run(ctx *Context) (err error) { | |||||||
| 		) | 		) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	set, err := flagSet(c.Name, c.Flags) | 	if ctx.App.UseShortOptionHandling { | ||||||
| 	if err != nil { | 		c.UseShortOptionHandling = true | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
| 	set.SetOutput(ioutil.Discard) |  | ||||||
|  |  | ||||||
| 	if c.SkipFlagParsing { |  | ||||||
| 		err = set.Parse(append([]string{"--"}, ctx.Args().Tail()...)) |  | ||||||
| 	} else if !c.SkipArgReorder { |  | ||||||
| 		firstFlagIndex := -1 |  | ||||||
| 		terminatorIndex := -1 |  | ||||||
| 		for index, arg := range ctx.Args() { |  | ||||||
| 			if arg == "--" { |  | ||||||
| 				terminatorIndex = index |  | ||||||
| 				break |  | ||||||
| 			} else if arg == "-" { |  | ||||||
| 				// Do nothing. A dash alone is not really a flag. |  | ||||||
| 				continue |  | ||||||
| 			} else if strings.HasPrefix(arg, "-") && firstFlagIndex == -1 { |  | ||||||
| 				firstFlagIndex = index |  | ||||||
| 			} |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 		if firstFlagIndex > -1 { | 	set, err := c.parseFlags(ctx.Args().Tail()) | ||||||
| 			args := ctx.Args() |  | ||||||
| 			regularArgs := make([]string, len(args[1:firstFlagIndex])) |  | ||||||
| 			copy(regularArgs, args[1:firstFlagIndex]) |  | ||||||
|  |  | ||||||
| 			var flagArgs []string |  | ||||||
| 			if terminatorIndex > -1 { |  | ||||||
| 				flagArgs = args[firstFlagIndex:terminatorIndex] |  | ||||||
| 				regularArgs = append(regularArgs, args[terminatorIndex:]...) |  | ||||||
| 			} else { |  | ||||||
| 				flagArgs = args[firstFlagIndex:] |  | ||||||
| 			} |  | ||||||
|  |  | ||||||
| 			err = set.Parse(append(flagArgs, regularArgs...)) |  | ||||||
| 		} else { |  | ||||||
| 			err = set.Parse(ctx.Args().Tail()) |  | ||||||
| 		} |  | ||||||
| 	} else { |  | ||||||
| 		err = set.Parse(ctx.Args().Tail()) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	nerr := normalizeFlags(c.Flags, set) |  | ||||||
| 	if nerr != nil { |  | ||||||
| 		fmt.Fprintln(ctx.App.Writer, nerr) |  | ||||||
| 		fmt.Fprintln(ctx.App.Writer) |  | ||||||
| 		ShowCommandHelp(ctx, c.Name) |  | ||||||
| 		return nerr |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	context := NewContext(ctx.App, set, ctx) | 	context := NewContext(ctx.App, set, ctx) | ||||||
| 	context.Command = c | 	context.Command = c | ||||||
| @@ -167,12 +125,12 @@ func (c Command) Run(ctx *Context) (err error) { | |||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		if c.OnUsageError != nil { | 		if c.OnUsageError != nil { | ||||||
| 			err := c.OnUsageError(context, err, false) | 			err := c.OnUsageError(context, err, false) | ||||||
| 			HandleExitCoder(err) | 			context.App.handleExitCoder(context, err) | ||||||
| 			return err | 			return err | ||||||
| 		} | 		} | ||||||
| 		fmt.Fprintln(context.App.Writer, "Incorrect Usage:", err.Error()) | 		_, _ = fmt.Fprintln(context.App.Writer, "Incorrect Usage:", err.Error()) | ||||||
| 		fmt.Fprintln(context.App.Writer) | 		_, _ = fmt.Fprintln(context.App.Writer) | ||||||
| 		ShowCommandHelp(context, c.Name) | 		_ = ShowCommandHelp(context, c.Name) | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -180,11 +138,17 @@ func (c Command) Run(ctx *Context) (err error) { | |||||||
| 		return nil | 		return nil | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	cerr := checkRequiredFlags(c.Flags, context) | ||||||
|  | 	if cerr != nil { | ||||||
|  | 		_ = ShowCommandHelp(context, c.Name) | ||||||
|  | 		return cerr | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	if c.After != nil { | 	if c.After != nil { | ||||||
| 		defer func() { | 		defer func() { | ||||||
| 			afterErr := c.After(context) | 			afterErr := c.After(context) | ||||||
| 			if afterErr != nil { | 			if afterErr != nil { | ||||||
| 				HandleExitCoder(err) | 				context.App.handleExitCoder(context, err) | ||||||
| 				if err != nil { | 				if err != nil { | ||||||
| 					err = NewMultiError(err, afterErr) | 					err = NewMultiError(err, afterErr) | ||||||
| 				} else { | 				} else { | ||||||
| @@ -197,8 +161,8 @@ func (c Command) Run(ctx *Context) (err error) { | |||||||
| 	if c.Before != nil { | 	if c.Before != nil { | ||||||
| 		err = c.Before(context) | 		err = c.Before(context) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			ShowCommandHelp(context, c.Name) | 			_ = ShowCommandHelp(context, c.Name) | ||||||
| 			HandleExitCoder(err) | 			context.App.handleExitCoder(context, err) | ||||||
| 			return err | 			return err | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| @@ -210,11 +174,120 @@ func (c Command) Run(ctx *Context) (err error) { | |||||||
| 	err = HandleAction(c.Action, context) | 	err = HandleAction(c.Action, context) | ||||||
|  |  | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		HandleExitCoder(err) | 		context.App.handleExitCoder(context, err) | ||||||
| 	} | 	} | ||||||
| 	return err | 	return err | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func (c *Command) parseFlags(args Args) (*flag.FlagSet, error) { | ||||||
|  | 	if c.SkipFlagParsing { | ||||||
|  | 		set, err := c.newFlagSet() | ||||||
|  | 		if err != nil { | ||||||
|  | 			return nil, err | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		return set, set.Parse(append([]string{"--"}, args...)) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if !c.SkipArgReorder { | ||||||
|  | 		args = reorderArgs(c.Flags, args) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	set, err := c.newFlagSet() | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	err = parseIter(set, c, args) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	err = normalizeFlags(c.Flags, set) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return set, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (c *Command) newFlagSet() (*flag.FlagSet, error) { | ||||||
|  | 	return flagSet(c.Name, c.Flags) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (c *Command) useShortOptionHandling() bool { | ||||||
|  | 	return c.UseShortOptionHandling | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // reorderArgs moves all flags (via reorderedArgs) before the rest of | ||||||
|  | // the arguments (remainingArgs) as this is what flag expects. | ||||||
|  | func reorderArgs(commandFlags []Flag, args []string) []string { | ||||||
|  | 	var remainingArgs, reorderedArgs []string | ||||||
|  |  | ||||||
|  | 	nextIndexMayContainValue := false | ||||||
|  | 	for i, arg := range args { | ||||||
|  |  | ||||||
|  | 		// dont reorder any args after a -- | ||||||
|  | 		// read about -- here: | ||||||
|  | 		// https://unix.stackexchange.com/questions/11376/what-does-double-dash-mean-also-known-as-bare-double-dash | ||||||
|  | 		if arg == "--" { | ||||||
|  | 			remainingArgs = append(remainingArgs, args[i:]...) | ||||||
|  | 			break | ||||||
|  |  | ||||||
|  | 			// checks if this arg is a value that should be re-ordered next to its associated flag | ||||||
|  | 		} else if nextIndexMayContainValue && !strings.HasPrefix(arg, "-") { | ||||||
|  | 			nextIndexMayContainValue = false | ||||||
|  | 			reorderedArgs = append(reorderedArgs, arg) | ||||||
|  |  | ||||||
|  | 			// checks if this is an arg that should be re-ordered | ||||||
|  | 		} else if argIsFlag(commandFlags, arg) { | ||||||
|  | 			// we have determined that this is a flag that we should re-order | ||||||
|  | 			reorderedArgs = append(reorderedArgs, arg) | ||||||
|  | 			// if this arg does not contain a "=", then the next index may contain the value for this flag | ||||||
|  | 			nextIndexMayContainValue = !strings.Contains(arg, "=") | ||||||
|  |  | ||||||
|  | 			// simply append any remaining args | ||||||
|  | 		} else { | ||||||
|  | 			remainingArgs = append(remainingArgs, arg) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return append(reorderedArgs, remainingArgs...) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // argIsFlag checks if an arg is one of our command flags | ||||||
|  | func argIsFlag(commandFlags []Flag, arg string) bool { | ||||||
|  | 	// checks if this is just a `-`, and so definitely not a flag | ||||||
|  | 	if arg == "-" { | ||||||
|  | 		return false | ||||||
|  | 	} | ||||||
|  | 	// flags always start with a - | ||||||
|  | 	if !strings.HasPrefix(arg, "-") { | ||||||
|  | 		return false | ||||||
|  | 	} | ||||||
|  | 	// this line turns `--flag` into `flag` | ||||||
|  | 	if strings.HasPrefix(arg, "--") { | ||||||
|  | 		arg = strings.Replace(arg, "-", "", 2) | ||||||
|  | 	} | ||||||
|  | 	// this line turns `-flag` into `flag` | ||||||
|  | 	if strings.HasPrefix(arg, "-") { | ||||||
|  | 		arg = strings.Replace(arg, "-", "", 1) | ||||||
|  | 	} | ||||||
|  | 	// this line turns `flag=value` into `flag` | ||||||
|  | 	arg = strings.Split(arg, "=")[0] | ||||||
|  | 	// look through all the flags, to see if the `arg` is one of our flags | ||||||
|  | 	for _, flag := range commandFlags { | ||||||
|  | 		for _, key := range strings.Split(flag.GetName(), ",") { | ||||||
|  | 			key := strings.TrimSpace(key) | ||||||
|  | 			if key == arg { | ||||||
|  | 				return true | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	// return false if this arg was not one of our flags | ||||||
|  | 	return false | ||||||
|  | } | ||||||
|  |  | ||||||
| // Names returns the names including short names and aliases. | // Names returns the names including short names and aliases. | ||||||
| func (c Command) Names() []string { | func (c Command) Names() []string { | ||||||
| 	names := []string{c.Name} | 	names := []string{c.Name} | ||||||
| @@ -239,6 +312,7 @@ func (c Command) HasName(name string) bool { | |||||||
| func (c Command) startApp(ctx *Context) error { | func (c Command) startApp(ctx *Context) error { | ||||||
| 	app := NewApp() | 	app := NewApp() | ||||||
| 	app.Metadata = ctx.App.Metadata | 	app.Metadata = ctx.App.Metadata | ||||||
|  | 	app.ExitErrHandler = ctx.App.ExitErrHandler | ||||||
| 	// set the name and usage | 	// set the name and usage | ||||||
| 	app.Name = fmt.Sprintf("%s %s", ctx.App.Name, c.Name) | 	app.Name = fmt.Sprintf("%s %s", ctx.App.Name, c.Name) | ||||||
| 	if c.HelpName == "" { | 	if c.HelpName == "" { | ||||||
| @@ -267,6 +341,7 @@ func (c Command) startApp(ctx *Context) error { | |||||||
| 	app.Email = ctx.App.Email | 	app.Email = ctx.App.Email | ||||||
| 	app.Writer = ctx.App.Writer | 	app.Writer = ctx.App.Writer | ||||||
| 	app.ErrWriter = ctx.App.ErrWriter | 	app.ErrWriter = ctx.App.ErrWriter | ||||||
|  | 	app.UseShortOptionHandling = ctx.App.UseShortOptionHandling | ||||||
|  |  | ||||||
| 	app.categories = CommandCategories{} | 	app.categories = CommandCategories{} | ||||||
| 	for _, command := range c.Subcommands { | 	for _, command := range c.Subcommands { | ||||||
|   | |||||||
							
								
								
									
										77
									
								
								vendor/github.com/urfave/cli/context.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										77
									
								
								vendor/github.com/urfave/cli/context.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -3,6 +3,8 @@ package cli | |||||||
| import ( | import ( | ||||||
| 	"errors" | 	"errors" | ||||||
| 	"flag" | 	"flag" | ||||||
|  | 	"fmt" | ||||||
|  | 	"os" | ||||||
| 	"reflect" | 	"reflect" | ||||||
| 	"strings" | 	"strings" | ||||||
| 	"syscall" | 	"syscall" | ||||||
| @@ -73,7 +75,7 @@ func (c *Context) IsSet(name string) bool { | |||||||
| 		// change in version 2 to add `IsSet` to the Flag interface to push the | 		// change in version 2 to add `IsSet` to the Flag interface to push the | ||||||
| 		// responsibility closer to where the information required to determine | 		// responsibility closer to where the information required to determine | ||||||
| 		// whether a flag is set by non-standard means such as environment | 		// whether a flag is set by non-standard means such as environment | ||||||
| 		// variables is avaliable. | 		// variables is available. | ||||||
| 		// | 		// | ||||||
| 		// See https://github.com/urfave/cli/issues/294 for additional discussion | 		// See https://github.com/urfave/cli/issues/294 for additional discussion | ||||||
| 		flags := c.Command.Flags | 		flags := c.Command.Flags | ||||||
| @@ -93,11 +95,18 @@ func (c *Context) IsSet(name string) bool { | |||||||
| 					val = val.Elem() | 					val = val.Elem() | ||||||
| 				} | 				} | ||||||
|  |  | ||||||
| 				envVarValue := val.FieldByName("EnvVar") | 				filePathValue := val.FieldByName("FilePath") | ||||||
| 				if !envVarValue.IsValid() { | 				if filePathValue.IsValid() { | ||||||
|  | 					eachName(filePathValue.String(), func(filePath string) { | ||||||
|  | 						if _, err := os.Stat(filePath); err == nil { | ||||||
|  | 							c.setFlags[name] = true | ||||||
| 							return | 							return | ||||||
| 						} | 						} | ||||||
|  | 					}) | ||||||
|  | 				} | ||||||
|  |  | ||||||
|  | 				envVarValue := val.FieldByName("EnvVar") | ||||||
|  | 				if envVarValue.IsValid() { | ||||||
| 					eachName(envVarValue.String(), func(envVar string) { | 					eachName(envVarValue.String(), func(envVar string) { | ||||||
| 						envVar = strings.TrimSpace(envVar) | 						envVar = strings.TrimSpace(envVar) | ||||||
| 						if _, ok := syscall.Getenv(envVar); ok { | 						if _, ok := syscall.Getenv(envVar); ok { | ||||||
| @@ -105,6 +114,7 @@ func (c *Context) IsSet(name string) bool { | |||||||
| 							return | 							return | ||||||
| 						} | 						} | ||||||
| 					}) | 					}) | ||||||
|  | 				} | ||||||
| 			}) | 			}) | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| @@ -129,8 +139,8 @@ func (c *Context) GlobalIsSet(name string) bool { | |||||||
|  |  | ||||||
| // FlagNames returns a slice of flag names used in this context. | // FlagNames returns a slice of flag names used in this context. | ||||||
| func (c *Context) FlagNames() (names []string) { | func (c *Context) FlagNames() (names []string) { | ||||||
| 	for _, flag := range c.Command.Flags { | 	for _, f := range c.Command.Flags { | ||||||
| 		name := strings.Split(flag.GetName(), ",")[0] | 		name := strings.Split(f.GetName(), ",")[0] | ||||||
| 		if name == "help" { | 		if name == "help" { | ||||||
| 			continue | 			continue | ||||||
| 		} | 		} | ||||||
| @@ -141,8 +151,8 @@ func (c *Context) FlagNames() (names []string) { | |||||||
|  |  | ||||||
| // GlobalFlagNames returns a slice of global flag names used by the app. | // GlobalFlagNames returns a slice of global flag names used by the app. | ||||||
| func (c *Context) GlobalFlagNames() (names []string) { | func (c *Context) GlobalFlagNames() (names []string) { | ||||||
| 	for _, flag := range c.App.Flags { | 	for _, f := range c.App.Flags { | ||||||
| 		name := strings.Split(flag.GetName(), ",")[0] | 		name := strings.Split(f.GetName(), ",")[0] | ||||||
| 		if name == "help" || name == "version" { | 		if name == "help" || name == "version" { | ||||||
| 			continue | 			continue | ||||||
| 		} | 		} | ||||||
| @@ -240,7 +250,7 @@ func copyFlag(name string, ff *flag.Flag, set *flag.FlagSet) { | |||||||
| 	switch ff.Value.(type) { | 	switch ff.Value.(type) { | ||||||
| 	case *StringSlice: | 	case *StringSlice: | ||||||
| 	default: | 	default: | ||||||
| 		set.Set(name, ff.Value.String()) | 		_ = set.Set(name, ff.Value.String()) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -276,3 +286,54 @@ func normalizeFlags(flags []Flag, set *flag.FlagSet) error { | |||||||
| 	} | 	} | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
|  |  | ||||||
|  | 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 strings.Split(f.GetName(), ",") { | ||||||
|  | 				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 | ||||||
|  | } | ||||||
|   | |||||||
							
								
								
									
										148
									
								
								vendor/github.com/urfave/cli/docs.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										148
									
								
								vendor/github.com/urfave/cli/docs.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,148 @@ | |||||||
|  | package cli | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"bytes" | ||||||
|  | 	"fmt" | ||||||
|  | 	"io" | ||||||
|  | 	"sort" | ||||||
|  | 	"strings" | ||||||
|  | 	"text/template" | ||||||
|  |  | ||||||
|  | 	"github.com/cpuguy83/go-md2man/v2/md2man" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | // ToMarkdown creates a markdown string for the `*App` | ||||||
|  | // 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 { | ||||||
|  | 		return "", err | ||||||
|  | 	} | ||||||
|  | 	return w.String(), 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) { | ||||||
|  | 	var w bytes.Buffer | ||||||
|  | 	if err := a.writeDocTemplate(&w); err != nil { | ||||||
|  | 		return "", err | ||||||
|  | 	} | ||||||
|  | 	man := md2man.Render(w.Bytes()) | ||||||
|  | 	return string(man), nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | type cliTemplate struct { | ||||||
|  | 	App          *App | ||||||
|  | 	Commands     []string | ||||||
|  | 	GlobalArgs   []string | ||||||
|  | 	SynopsisArgs []string | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (a *App) writeDocTemplate(w io.Writer) error { | ||||||
|  | 	const name = "cli" | ||||||
|  | 	t, err := template.New(name).Parse(MarkdownDocTemplate) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 	return t.ExecuteTemplate(w, name, &cliTemplate{ | ||||||
|  | 		App:          a, | ||||||
|  | 		Commands:     prepareCommands(a.Commands, 0), | ||||||
|  | 		GlobalArgs:   prepareArgsWithValues(a.Flags), | ||||||
|  | 		SynopsisArgs: prepareArgsSynopsis(a.Flags), | ||||||
|  | 	}) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func prepareCommands(commands []Command, level int) []string { | ||||||
|  | 	coms := []string{} | ||||||
|  | 	for i := range commands { | ||||||
|  | 		command := &commands[i] | ||||||
|  | 		if command.Hidden { | ||||||
|  | 			continue | ||||||
|  | 		} | ||||||
|  | 		usage := "" | ||||||
|  | 		if command.Usage != "" { | ||||||
|  | 			usage = command.Usage | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		prepared := fmt.Sprintf("%s %s\n\n%s\n", | ||||||
|  | 			strings.Repeat("#", level+2), | ||||||
|  | 			strings.Join(command.Names(), ", "), | ||||||
|  | 			usage, | ||||||
|  | 		) | ||||||
|  |  | ||||||
|  | 		flags := prepareArgsWithValues(command.Flags) | ||||||
|  | 		if len(flags) > 0 { | ||||||
|  | 			prepared += fmt.Sprintf("\n%s", strings.Join(flags, "\n")) | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		coms = append(coms, prepared) | ||||||
|  |  | ||||||
|  | 		// recursevly iterate subcommands | ||||||
|  | 		if len(command.Subcommands) > 0 { | ||||||
|  | 			coms = append( | ||||||
|  | 				coms, | ||||||
|  | 				prepareCommands(command.Subcommands, level+1)..., | ||||||
|  | 			) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return coms | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func prepareArgsWithValues(flags []Flag) []string { | ||||||
|  | 	return prepareFlags(flags, ", ", "**", "**", `""`, true) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func prepareArgsSynopsis(flags []Flag) []string { | ||||||
|  | 	return prepareFlags(flags, "|", "[", "]", "[value]", false) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func prepareFlags( | ||||||
|  | 	flags []Flag, | ||||||
|  | 	sep, opener, closer, value string, | ||||||
|  | 	addDetails bool, | ||||||
|  | ) []string { | ||||||
|  | 	args := []string{} | ||||||
|  | 	for _, f := range flags { | ||||||
|  | 		flag, ok := f.(DocGenerationFlag) | ||||||
|  | 		if !ok { | ||||||
|  | 			continue | ||||||
|  | 		} | ||||||
|  | 		modifiedArg := opener | ||||||
|  | 		for _, s := range strings.Split(flag.GetName(), ",") { | ||||||
|  | 			trimmed := strings.TrimSpace(s) | ||||||
|  | 			if len(modifiedArg) > len(opener) { | ||||||
|  | 				modifiedArg += sep | ||||||
|  | 			} | ||||||
|  | 			if len(trimmed) > 1 { | ||||||
|  | 				modifiedArg += fmt.Sprintf("--%s", trimmed) | ||||||
|  | 			} else { | ||||||
|  | 				modifiedArg += fmt.Sprintf("-%s", trimmed) | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		modifiedArg += closer | ||||||
|  | 		if flag.TakesValue() { | ||||||
|  | 			modifiedArg += fmt.Sprintf("=%s", value) | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		if addDetails { | ||||||
|  | 			modifiedArg += flagDetails(flag) | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		args = append(args, modifiedArg+"\n") | ||||||
|  |  | ||||||
|  | 	} | ||||||
|  | 	sort.Strings(args) | ||||||
|  | 	return args | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // flagDetails returns a string containing the flags metadata | ||||||
|  | func flagDetails(flag DocGenerationFlag) string { | ||||||
|  | 	description := flag.GetUsage() | ||||||
|  | 	value := flag.GetValue() | ||||||
|  | 	if value != "" { | ||||||
|  | 		description += " (default: " + value + ")" | ||||||
|  | 	} | ||||||
|  | 	return ": " + description | ||||||
|  | } | ||||||
							
								
								
									
										194
									
								
								vendor/github.com/urfave/cli/fish.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										194
									
								
								vendor/github.com/urfave/cli/fish.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,194 @@ | |||||||
|  | package cli | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"bytes" | ||||||
|  | 	"fmt" | ||||||
|  | 	"io" | ||||||
|  | 	"strings" | ||||||
|  | 	"text/template" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | // ToFishCompletion creates a fish completion string for the `*App` | ||||||
|  | // The function errors if either parsing or writing of the string fails. | ||||||
|  | func (a *App) ToFishCompletion() (string, error) { | ||||||
|  | 	var w bytes.Buffer | ||||||
|  | 	if err := a.writeFishCompletionTemplate(&w); err != nil { | ||||||
|  | 		return "", err | ||||||
|  | 	} | ||||||
|  | 	return w.String(), nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | type fishCompletionTemplate struct { | ||||||
|  | 	App         *App | ||||||
|  | 	Completions []string | ||||||
|  | 	AllCommands []string | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (a *App) writeFishCompletionTemplate(w io.Writer) error { | ||||||
|  | 	const name = "cli" | ||||||
|  | 	t, err := template.New(name).Parse(FishCompletionTemplate) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 	allCommands := []string{} | ||||||
|  |  | ||||||
|  | 	// Add global flags | ||||||
|  | 	completions := a.prepareFishFlags(a.VisibleFlags(), allCommands) | ||||||
|  |  | ||||||
|  | 	// Add help flag | ||||||
|  | 	if !a.HideHelp { | ||||||
|  | 		completions = append( | ||||||
|  | 			completions, | ||||||
|  | 			a.prepareFishFlags([]Flag{HelpFlag}, allCommands)..., | ||||||
|  | 		) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// Add version flag | ||||||
|  | 	if !a.HideVersion { | ||||||
|  | 		completions = append( | ||||||
|  | 			completions, | ||||||
|  | 			a.prepareFishFlags([]Flag{VersionFlag}, allCommands)..., | ||||||
|  | 		) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// Add commands and their flags | ||||||
|  | 	completions = append( | ||||||
|  | 		completions, | ||||||
|  | 		a.prepareFishCommands(a.VisibleCommands(), &allCommands, []string{})..., | ||||||
|  | 	) | ||||||
|  |  | ||||||
|  | 	return t.ExecuteTemplate(w, name, &fishCompletionTemplate{ | ||||||
|  | 		App:         a, | ||||||
|  | 		Completions: completions, | ||||||
|  | 		AllCommands: allCommands, | ||||||
|  | 	}) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (a *App) prepareFishCommands(commands []Command, allCommands *[]string, previousCommands []string) []string { | ||||||
|  | 	completions := []string{} | ||||||
|  | 	for i := range commands { | ||||||
|  | 		command := &commands[i] | ||||||
|  |  | ||||||
|  | 		if command.Hidden { | ||||||
|  | 			continue | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		var completion strings.Builder | ||||||
|  | 		completion.WriteString(fmt.Sprintf( | ||||||
|  | 			"complete -r -c %s -n '%s' -a '%s'", | ||||||
|  | 			a.Name, | ||||||
|  | 			a.fishSubcommandHelper(previousCommands), | ||||||
|  | 			strings.Join(command.Names(), " "), | ||||||
|  | 		)) | ||||||
|  |  | ||||||
|  | 		if command.Usage != "" { | ||||||
|  | 			completion.WriteString(fmt.Sprintf(" -d '%s'", | ||||||
|  | 				escapeSingleQuotes(command.Usage))) | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		if !command.HideHelp { | ||||||
|  | 			completions = append( | ||||||
|  | 				completions, | ||||||
|  | 				a.prepareFishFlags([]Flag{HelpFlag}, command.Names())..., | ||||||
|  | 			) | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		*allCommands = append(*allCommands, command.Names()...) | ||||||
|  | 		completions = append(completions, completion.String()) | ||||||
|  | 		completions = append( | ||||||
|  | 			completions, | ||||||
|  | 			a.prepareFishFlags(command.Flags, command.Names())..., | ||||||
|  | 		) | ||||||
|  |  | ||||||
|  | 		// recursevly iterate subcommands | ||||||
|  | 		if len(command.Subcommands) > 0 { | ||||||
|  | 			completions = append( | ||||||
|  | 				completions, | ||||||
|  | 				a.prepareFishCommands( | ||||||
|  | 					command.Subcommands, allCommands, command.Names(), | ||||||
|  | 				)..., | ||||||
|  | 			) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return completions | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (a *App) prepareFishFlags(flags []Flag, previousCommands []string) []string { | ||||||
|  | 	completions := []string{} | ||||||
|  | 	for _, f := range flags { | ||||||
|  | 		flag, ok := f.(DocGenerationFlag) | ||||||
|  | 		if !ok { | ||||||
|  | 			continue | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		completion := &strings.Builder{} | ||||||
|  | 		completion.WriteString(fmt.Sprintf( | ||||||
|  | 			"complete -c %s -n '%s'", | ||||||
|  | 			a.Name, | ||||||
|  | 			a.fishSubcommandHelper(previousCommands), | ||||||
|  | 		)) | ||||||
|  |  | ||||||
|  | 		fishAddFileFlag(f, completion) | ||||||
|  |  | ||||||
|  | 		for idx, opt := range strings.Split(flag.GetName(), ",") { | ||||||
|  | 			if idx == 0 { | ||||||
|  | 				completion.WriteString(fmt.Sprintf( | ||||||
|  | 					" -l %s", strings.TrimSpace(opt), | ||||||
|  | 				)) | ||||||
|  | 			} else { | ||||||
|  | 				completion.WriteString(fmt.Sprintf( | ||||||
|  | 					" -s %s", strings.TrimSpace(opt), | ||||||
|  | 				)) | ||||||
|  |  | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		if flag.TakesValue() { | ||||||
|  | 			completion.WriteString(" -r") | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		if flag.GetUsage() != "" { | ||||||
|  | 			completion.WriteString(fmt.Sprintf(" -d '%s'", | ||||||
|  | 				escapeSingleQuotes(flag.GetUsage()))) | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		completions = append(completions, completion.String()) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return completions | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func fishAddFileFlag(flag Flag, completion *strings.Builder) { | ||||||
|  | 	switch f := flag.(type) { | ||||||
|  | 	case GenericFlag: | ||||||
|  | 		if f.TakesFile { | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
|  | 	case StringFlag: | ||||||
|  | 		if f.TakesFile { | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
|  | 	case StringSliceFlag: | ||||||
|  | 		if f.TakesFile { | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	completion.WriteString(" -f") | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (a *App) fishSubcommandHelper(allCommands []string) string { | ||||||
|  | 	fishHelper := fmt.Sprintf("__fish_%s_no_subcommand", a.Name) | ||||||
|  | 	if len(allCommands) > 0 { | ||||||
|  | 		fishHelper = fmt.Sprintf( | ||||||
|  | 			"__fish_seen_subcommand_from %s", | ||||||
|  | 			strings.Join(allCommands, " "), | ||||||
|  | 		) | ||||||
|  | 	} | ||||||
|  | 	return fishHelper | ||||||
|  |  | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func escapeSingleQuotes(input string) string { | ||||||
|  | 	return strings.Replace(input, `'`, `\'`, -1) | ||||||
|  | } | ||||||
							
								
								
									
										93
									
								
								vendor/github.com/urfave/cli/flag-types.json
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										93
									
								
								vendor/github.com/urfave/cli/flag-types.json
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,93 +0,0 @@ | |||||||
| [ |  | ||||||
|   { |  | ||||||
|     "name": "Bool", |  | ||||||
|     "type": "bool", |  | ||||||
|     "value": false, |  | ||||||
|     "context_default": "false", |  | ||||||
|     "parser": "strconv.ParseBool(f.Value.String())" |  | ||||||
|   }, |  | ||||||
|   { |  | ||||||
|     "name": "BoolT", |  | ||||||
|     "type": "bool", |  | ||||||
|     "value": false, |  | ||||||
|     "doctail": " that is true by default", |  | ||||||
|     "context_default": "false", |  | ||||||
|     "parser": "strconv.ParseBool(f.Value.String())" |  | ||||||
|   }, |  | ||||||
|   { |  | ||||||
|     "name": "Duration", |  | ||||||
|     "type": "time.Duration", |  | ||||||
|     "doctail": " (see https://golang.org/pkg/time/#ParseDuration)", |  | ||||||
|     "context_default": "0", |  | ||||||
|     "parser": "time.ParseDuration(f.Value.String())" |  | ||||||
|   }, |  | ||||||
|   { |  | ||||||
|     "name": "Float64", |  | ||||||
|     "type": "float64", |  | ||||||
|     "context_default": "0", |  | ||||||
|     "parser": "strconv.ParseFloat(f.Value.String(), 64)" |  | ||||||
|   }, |  | ||||||
|   { |  | ||||||
|     "name": "Generic", |  | ||||||
|     "type": "Generic", |  | ||||||
|     "dest": false, |  | ||||||
|     "context_default": "nil", |  | ||||||
|     "context_type": "interface{}" |  | ||||||
|   }, |  | ||||||
|   { |  | ||||||
|     "name": "Int64", |  | ||||||
|     "type": "int64", |  | ||||||
|     "context_default": "0", |  | ||||||
|     "parser": "strconv.ParseInt(f.Value.String(), 0, 64)" |  | ||||||
|   }, |  | ||||||
|   { |  | ||||||
|     "name": "Int", |  | ||||||
|     "type": "int", |  | ||||||
|     "context_default": "0", |  | ||||||
|     "parser": "strconv.ParseInt(f.Value.String(), 0, 64)", |  | ||||||
|     "parser_cast": "int(parsed)" |  | ||||||
|   }, |  | ||||||
|   { |  | ||||||
|     "name": "IntSlice", |  | ||||||
|     "type": "*IntSlice", |  | ||||||
|     "dest": false, |  | ||||||
|     "context_default": "nil", |  | ||||||
|     "context_type": "[]int", |  | ||||||
|     "parser": "(f.Value.(*IntSlice)).Value(), error(nil)" |  | ||||||
|   }, |  | ||||||
|   { |  | ||||||
|     "name": "Int64Slice", |  | ||||||
|     "type": "*Int64Slice", |  | ||||||
|     "dest": false, |  | ||||||
|     "context_default": "nil", |  | ||||||
|     "context_type": "[]int64", |  | ||||||
|     "parser": "(f.Value.(*Int64Slice)).Value(), error(nil)" |  | ||||||
|   }, |  | ||||||
|   { |  | ||||||
|     "name": "String", |  | ||||||
|     "type": "string", |  | ||||||
|     "context_default": "\"\"", |  | ||||||
|     "parser": "f.Value.String(), error(nil)" |  | ||||||
|   }, |  | ||||||
|   { |  | ||||||
|     "name": "StringSlice", |  | ||||||
|     "type": "*StringSlice", |  | ||||||
|     "dest": false, |  | ||||||
|     "context_default": "nil", |  | ||||||
|     "context_type": "[]string", |  | ||||||
|     "parser": "(f.Value.(*StringSlice)).Value(), error(nil)" |  | ||||||
|   }, |  | ||||||
|   { |  | ||||||
|     "name": "Uint64", |  | ||||||
|     "type": "uint64", |  | ||||||
|     "context_default": "0", |  | ||||||
|     "parser": "strconv.ParseUint(f.Value.String(), 0, 64)" |  | ||||||
|   }, |  | ||||||
|   { |  | ||||||
|     "name": "Uint", |  | ||||||
|     "type": "uint", |  | ||||||
|     "context_default": "0", |  | ||||||
|     "parser": "strconv.ParseUint(f.Value.String(), 0, 64)", |  | ||||||
|     "parser_cast": "uint(parsed)" |  | ||||||
|   } |  | ||||||
| ] |  | ||||||
							
								
								
									
										659
									
								
								vendor/github.com/urfave/cli/flag.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										659
									
								
								vendor/github.com/urfave/cli/flag.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -3,12 +3,12 @@ package cli | |||||||
| import ( | import ( | ||||||
| 	"flag" | 	"flag" | ||||||
| 	"fmt" | 	"fmt" | ||||||
|  | 	"io/ioutil" | ||||||
| 	"reflect" | 	"reflect" | ||||||
| 	"runtime" | 	"runtime" | ||||||
| 	"strconv" | 	"strconv" | ||||||
| 	"strings" | 	"strings" | ||||||
| 	"syscall" | 	"syscall" | ||||||
| 	"time" |  | ||||||
| ) | ) | ||||||
|  |  | ||||||
| const defaultPlaceholder = "value" | const defaultPlaceholder = "value" | ||||||
| @@ -37,6 +37,18 @@ var HelpFlag Flag = BoolFlag{ | |||||||
| // to display a flag. | // to display a flag. | ||||||
| var FlagStringer FlagStringFunc = stringifyFlag | var FlagStringer FlagStringFunc = stringifyFlag | ||||||
|  |  | ||||||
|  | // FlagNamePrefixer converts a full flag name and its placeholder into the help | ||||||
|  | // message flag prefix. This is used by the default FlagStringer. | ||||||
|  | var FlagNamePrefixer FlagNamePrefixFunc = prefixedNames | ||||||
|  |  | ||||||
|  | // FlagEnvHinter annotates flag help message with the environment variable | ||||||
|  | // details. This is used by the default FlagStringer. | ||||||
|  | var FlagEnvHinter FlagEnvHintFunc = withEnvHint | ||||||
|  |  | ||||||
|  | // FlagFileHinter annotates flag help message with the environment variable | ||||||
|  | // details. This is used by the default FlagStringer. | ||||||
|  | var FlagFileHinter FlagFileHintFunc = withFileHint | ||||||
|  |  | ||||||
| // FlagsByName is a slice of Flag. | // FlagsByName is a slice of Flag. | ||||||
| type FlagsByName []Flag | type FlagsByName []Flag | ||||||
|  |  | ||||||
| @@ -45,7 +57,7 @@ func (f FlagsByName) Len() int { | |||||||
| } | } | ||||||
|  |  | ||||||
| func (f FlagsByName) Less(i, j int) bool { | func (f FlagsByName) Less(i, j int) bool { | ||||||
| 	return f[i].GetName() < f[j].GetName() | 	return lexicographicLess(f[i].GetName(), f[j].GetName()) | ||||||
| } | } | ||||||
|  |  | ||||||
| func (f FlagsByName) Swap(i, j int) { | func (f FlagsByName) Swap(i, j int) { | ||||||
| @@ -62,6 +74,29 @@ type Flag interface { | |||||||
| 	GetName() string | 	GetName() string | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // RequiredFlag is an interface that allows us to mark flags as required | ||||||
|  | // it allows flags required flags to be backwards compatible with the Flag interface | ||||||
|  | type RequiredFlag interface { | ||||||
|  | 	Flag | ||||||
|  |  | ||||||
|  | 	IsRequired() bool | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // DocGenerationFlag is an interface that allows documentation generation for the flag | ||||||
|  | type DocGenerationFlag interface { | ||||||
|  | 	Flag | ||||||
|  |  | ||||||
|  | 	// TakesValue returns true if the flag takes a value, otherwise false | ||||||
|  | 	TakesValue() bool | ||||||
|  |  | ||||||
|  | 	// GetUsage returns the usage string for the flag | ||||||
|  | 	GetUsage() string | ||||||
|  |  | ||||||
|  | 	// GetValue returns the flags value as string representation and an empty | ||||||
|  | 	// string if the flag takes no value at all. | ||||||
|  | 	GetValue() string | ||||||
|  | } | ||||||
|  |  | ||||||
| // errorableFlag is an interface that allows us to return errors during apply | // errorableFlag is an interface that allows us to return errors during apply | ||||||
| // it allows flags defined in this library to return errors in a fashion backwards compatible | // it allows flags defined in this library to return errors in a fashion backwards compatible | ||||||
| // TODO remove in v2 and modify the existing Flag interface to return errors | // TODO remove in v2 and modify the existing Flag interface to return errors | ||||||
| @@ -84,6 +119,7 @@ func flagSet(name string, flags []Flag) (*flag.FlagSet, error) { | |||||||
| 			f.Apply(set) | 			f.Apply(set) | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  | 	set.SetOutput(ioutil.Discard) | ||||||
| 	return set, nil | 	return set, nil | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -95,544 +131,12 @@ func eachName(longName string, fn func(string)) { | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| // Generic is a generic parseable type identified by a specific flag |  | ||||||
| type Generic interface { |  | ||||||
| 	Set(value string) error |  | ||||||
| 	String() string |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Apply takes the flagset and calls Set on the generic flag with the value |  | ||||||
| // provided by the user for parsing by the flag |  | ||||||
| // Ignores parsing errors |  | ||||||
| func (f GenericFlag) Apply(set *flag.FlagSet) { |  | ||||||
| 	f.ApplyWithError(set) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // ApplyWithError 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) ApplyWithError(set *flag.FlagSet) error { |  | ||||||
| 	val := f.Value |  | ||||||
| 	if f.EnvVar != "" { |  | ||||||
| 		for _, envVar := range strings.Split(f.EnvVar, ",") { |  | ||||||
| 			envVar = strings.TrimSpace(envVar) |  | ||||||
| 			if envVal, ok := syscall.Getenv(envVar); ok { |  | ||||||
| 				if err := val.Set(envVal); err != nil { |  | ||||||
| 					return fmt.Errorf("could not parse %s as value for flag %s: %s", envVal, f.Name, err) |  | ||||||
| 				} |  | ||||||
| 				break |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	eachName(f.Name, func(name string) { |  | ||||||
| 		set.Var(f.Value, name, f.Usage) |  | ||||||
| 	}) |  | ||||||
|  |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // StringSlice is an opaque type for []string to satisfy flag.Value and flag.Getter |  | ||||||
| type StringSlice []string |  | ||||||
|  |  | ||||||
| // Set appends the string value to the list of values |  | ||||||
| func (f *StringSlice) Set(value string) error { |  | ||||||
| 	*f = append(*f, value) |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // String returns a readable representation of this value (for usage defaults) |  | ||||||
| func (f *StringSlice) String() string { |  | ||||||
| 	return fmt.Sprintf("%s", *f) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Value returns the slice of strings set by this flag |  | ||||||
| func (f *StringSlice) Value() []string { |  | ||||||
| 	return *f |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Get returns the slice of strings set by this flag |  | ||||||
| func (f *StringSlice) Get() interface{} { |  | ||||||
| 	return *f |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Apply populates the flag given the flag set and environment |  | ||||||
| // Ignores errors |  | ||||||
| func (f StringSliceFlag) Apply(set *flag.FlagSet) { |  | ||||||
| 	f.ApplyWithError(set) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // ApplyWithError populates the flag given the flag set and environment |  | ||||||
| func (f StringSliceFlag) ApplyWithError(set *flag.FlagSet) error { |  | ||||||
| 	if f.EnvVar != "" { |  | ||||||
| 		for _, envVar := range strings.Split(f.EnvVar, ",") { |  | ||||||
| 			envVar = strings.TrimSpace(envVar) |  | ||||||
| 			if envVal, ok := syscall.Getenv(envVar); ok { |  | ||||||
| 				newVal := &StringSlice{} |  | ||||||
| 				for _, s := range strings.Split(envVal, ",") { |  | ||||||
| 					s = strings.TrimSpace(s) |  | ||||||
| 					if err := newVal.Set(s); err != nil { |  | ||||||
| 						return fmt.Errorf("could not parse %s as string value for flag %s: %s", envVal, f.Name, err) |  | ||||||
| 					} |  | ||||||
| 				} |  | ||||||
| 				f.Value = newVal |  | ||||||
| 				break |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	eachName(f.Name, func(name string) { |  | ||||||
| 		if f.Value == nil { |  | ||||||
| 			f.Value = &StringSlice{} |  | ||||||
| 		} |  | ||||||
| 		set.Var(f.Value, name, f.Usage) |  | ||||||
| 	}) |  | ||||||
|  |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // IntSlice is an opaque type for []int to satisfy flag.Value and flag.Getter |  | ||||||
| type IntSlice []int |  | ||||||
|  |  | ||||||
| // Set parses the value into an integer and appends it to the list of values |  | ||||||
| func (f *IntSlice) Set(value string) error { |  | ||||||
| 	tmp, err := strconv.Atoi(value) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
| 	*f = append(*f, tmp) |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // String returns a readable representation of this value (for usage defaults) |  | ||||||
| func (f *IntSlice) String() string { |  | ||||||
| 	return fmt.Sprintf("%#v", *f) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Value returns the slice of ints set by this flag |  | ||||||
| func (f *IntSlice) Value() []int { |  | ||||||
| 	return *f |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Get returns the slice of ints set by this flag |  | ||||||
| func (f *IntSlice) Get() interface{} { |  | ||||||
| 	return *f |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Apply populates the flag given the flag set and environment |  | ||||||
| // Ignores errors |  | ||||||
| func (f IntSliceFlag) Apply(set *flag.FlagSet) { |  | ||||||
| 	f.ApplyWithError(set) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // ApplyWithError populates the flag given the flag set and environment |  | ||||||
| func (f IntSliceFlag) ApplyWithError(set *flag.FlagSet) error { |  | ||||||
| 	if f.EnvVar != "" { |  | ||||||
| 		for _, envVar := range strings.Split(f.EnvVar, ",") { |  | ||||||
| 			envVar = strings.TrimSpace(envVar) |  | ||||||
| 			if envVal, ok := syscall.Getenv(envVar); ok { |  | ||||||
| 				newVal := &IntSlice{} |  | ||||||
| 				for _, s := range strings.Split(envVal, ",") { |  | ||||||
| 					s = strings.TrimSpace(s) |  | ||||||
| 					if err := newVal.Set(s); err != nil { |  | ||||||
| 						return fmt.Errorf("could not parse %s as int slice value for flag %s: %s", envVal, f.Name, err) |  | ||||||
| 					} |  | ||||||
| 				} |  | ||||||
| 				f.Value = newVal |  | ||||||
| 				break |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	eachName(f.Name, func(name string) { |  | ||||||
| 		if f.Value == nil { |  | ||||||
| 			f.Value = &IntSlice{} |  | ||||||
| 		} |  | ||||||
| 		set.Var(f.Value, name, f.Usage) |  | ||||||
| 	}) |  | ||||||
|  |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Int64Slice is an opaque type for []int to satisfy flag.Value and flag.Getter |  | ||||||
| type Int64Slice []int64 |  | ||||||
|  |  | ||||||
| // Set parses the value into an integer and appends it to the list of values |  | ||||||
| func (f *Int64Slice) Set(value string) error { |  | ||||||
| 	tmp, err := strconv.ParseInt(value, 10, 64) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
| 	*f = append(*f, tmp) |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // String returns a readable representation of this value (for usage defaults) |  | ||||||
| func (f *Int64Slice) String() string { |  | ||||||
| 	return fmt.Sprintf("%#v", *f) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Value returns the slice of ints set by this flag |  | ||||||
| func (f *Int64Slice) Value() []int64 { |  | ||||||
| 	return *f |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Get returns the slice of ints set by this flag |  | ||||||
| func (f *Int64Slice) Get() interface{} { |  | ||||||
| 	return *f |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Apply populates the flag given the flag set and environment |  | ||||||
| // Ignores errors |  | ||||||
| func (f Int64SliceFlag) Apply(set *flag.FlagSet) { |  | ||||||
| 	f.ApplyWithError(set) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // ApplyWithError populates the flag given the flag set and environment |  | ||||||
| func (f Int64SliceFlag) ApplyWithError(set *flag.FlagSet) error { |  | ||||||
| 	if f.EnvVar != "" { |  | ||||||
| 		for _, envVar := range strings.Split(f.EnvVar, ",") { |  | ||||||
| 			envVar = strings.TrimSpace(envVar) |  | ||||||
| 			if envVal, ok := syscall.Getenv(envVar); ok { |  | ||||||
| 				newVal := &Int64Slice{} |  | ||||||
| 				for _, s := range strings.Split(envVal, ",") { |  | ||||||
| 					s = strings.TrimSpace(s) |  | ||||||
| 					if err := newVal.Set(s); err != nil { |  | ||||||
| 						return fmt.Errorf("could not parse %s as int64 slice value for flag %s: %s", envVal, f.Name, err) |  | ||||||
| 					} |  | ||||||
| 				} |  | ||||||
| 				f.Value = newVal |  | ||||||
| 				break |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	eachName(f.Name, func(name string) { |  | ||||||
| 		if f.Value == nil { |  | ||||||
| 			f.Value = &Int64Slice{} |  | ||||||
| 		} |  | ||||||
| 		set.Var(f.Value, name, f.Usage) |  | ||||||
| 	}) |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Apply populates the flag given the flag set and environment |  | ||||||
| // Ignores errors |  | ||||||
| func (f BoolFlag) Apply(set *flag.FlagSet) { |  | ||||||
| 	f.ApplyWithError(set) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // ApplyWithError populates the flag given the flag set and environment |  | ||||||
| func (f BoolFlag) ApplyWithError(set *flag.FlagSet) error { |  | ||||||
| 	val := false |  | ||||||
| 	if f.EnvVar != "" { |  | ||||||
| 		for _, envVar := range strings.Split(f.EnvVar, ",") { |  | ||||||
| 			envVar = strings.TrimSpace(envVar) |  | ||||||
| 			if envVal, ok := syscall.Getenv(envVar); ok { |  | ||||||
| 				if envVal == "" { |  | ||||||
| 					val = false |  | ||||||
| 					break |  | ||||||
| 				} |  | ||||||
|  |  | ||||||
| 				envValBool, err := strconv.ParseBool(envVal) |  | ||||||
| 				if err != nil { |  | ||||||
| 					return fmt.Errorf("could not parse %s as bool value for flag %s: %s", envVal, f.Name, err) |  | ||||||
| 				} |  | ||||||
|  |  | ||||||
| 				val = envValBool |  | ||||||
| 				break |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	eachName(f.Name, func(name string) { |  | ||||||
| 		if f.Destination != nil { |  | ||||||
| 			set.BoolVar(f.Destination, name, val, f.Usage) |  | ||||||
| 			return |  | ||||||
| 		} |  | ||||||
| 		set.Bool(name, val, f.Usage) |  | ||||||
| 	}) |  | ||||||
|  |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Apply populates the flag given the flag set and environment |  | ||||||
| // Ignores errors |  | ||||||
| func (f BoolTFlag) Apply(set *flag.FlagSet) { |  | ||||||
| 	f.ApplyWithError(set) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // ApplyWithError populates the flag given the flag set and environment |  | ||||||
| func (f BoolTFlag) ApplyWithError(set *flag.FlagSet) error { |  | ||||||
| 	val := true |  | ||||||
| 	if f.EnvVar != "" { |  | ||||||
| 		for _, envVar := range strings.Split(f.EnvVar, ",") { |  | ||||||
| 			envVar = strings.TrimSpace(envVar) |  | ||||||
| 			if envVal, ok := syscall.Getenv(envVar); ok { |  | ||||||
| 				if envVal == "" { |  | ||||||
| 					val = false |  | ||||||
| 					break |  | ||||||
| 				} |  | ||||||
|  |  | ||||||
| 				envValBool, err := strconv.ParseBool(envVal) |  | ||||||
| 				if err != nil { |  | ||||||
| 					return fmt.Errorf("could not parse %s as bool value for flag %s: %s", envVal, f.Name, err) |  | ||||||
| 				} |  | ||||||
|  |  | ||||||
| 				val = envValBool |  | ||||||
| 				break |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	eachName(f.Name, func(name string) { |  | ||||||
| 		if f.Destination != nil { |  | ||||||
| 			set.BoolVar(f.Destination, name, val, f.Usage) |  | ||||||
| 			return |  | ||||||
| 		} |  | ||||||
| 		set.Bool(name, val, f.Usage) |  | ||||||
| 	}) |  | ||||||
|  |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Apply populates the flag given the flag set and environment |  | ||||||
| // Ignores errors |  | ||||||
| func (f StringFlag) Apply(set *flag.FlagSet) { |  | ||||||
| 	f.ApplyWithError(set) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // ApplyWithError populates the flag given the flag set and environment |  | ||||||
| func (f StringFlag) ApplyWithError(set *flag.FlagSet) error { |  | ||||||
| 	if f.EnvVar != "" { |  | ||||||
| 		for _, envVar := range strings.Split(f.EnvVar, ",") { |  | ||||||
| 			envVar = strings.TrimSpace(envVar) |  | ||||||
| 			if envVal, ok := syscall.Getenv(envVar); ok { |  | ||||||
| 				f.Value = envVal |  | ||||||
| 				break |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	eachName(f.Name, func(name string) { |  | ||||||
| 		if f.Destination != nil { |  | ||||||
| 			set.StringVar(f.Destination, name, f.Value, f.Usage) |  | ||||||
| 			return |  | ||||||
| 		} |  | ||||||
| 		set.String(name, f.Value, f.Usage) |  | ||||||
| 	}) |  | ||||||
|  |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Apply populates the flag given the flag set and environment |  | ||||||
| // Ignores errors |  | ||||||
| func (f IntFlag) Apply(set *flag.FlagSet) { |  | ||||||
| 	f.ApplyWithError(set) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // ApplyWithError populates the flag given the flag set and environment |  | ||||||
| func (f IntFlag) ApplyWithError(set *flag.FlagSet) error { |  | ||||||
| 	if f.EnvVar != "" { |  | ||||||
| 		for _, envVar := range strings.Split(f.EnvVar, ",") { |  | ||||||
| 			envVar = strings.TrimSpace(envVar) |  | ||||||
| 			if envVal, ok := syscall.Getenv(envVar); ok { |  | ||||||
| 				envValInt, err := strconv.ParseInt(envVal, 0, 64) |  | ||||||
| 				if err != nil { |  | ||||||
| 					return fmt.Errorf("could not parse %s as int value for flag %s: %s", envVal, f.Name, err) |  | ||||||
| 				} |  | ||||||
| 				f.Value = int(envValInt) |  | ||||||
| 				break |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	eachName(f.Name, func(name string) { |  | ||||||
| 		if f.Destination != nil { |  | ||||||
| 			set.IntVar(f.Destination, name, f.Value, f.Usage) |  | ||||||
| 			return |  | ||||||
| 		} |  | ||||||
| 		set.Int(name, f.Value, f.Usage) |  | ||||||
| 	}) |  | ||||||
|  |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Apply populates the flag given the flag set and environment |  | ||||||
| // Ignores errors |  | ||||||
| func (f Int64Flag) Apply(set *flag.FlagSet) { |  | ||||||
| 	f.ApplyWithError(set) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // ApplyWithError populates the flag given the flag set and environment |  | ||||||
| func (f Int64Flag) ApplyWithError(set *flag.FlagSet) error { |  | ||||||
| 	if f.EnvVar != "" { |  | ||||||
| 		for _, envVar := range strings.Split(f.EnvVar, ",") { |  | ||||||
| 			envVar = strings.TrimSpace(envVar) |  | ||||||
| 			if envVal, ok := syscall.Getenv(envVar); ok { |  | ||||||
| 				envValInt, err := strconv.ParseInt(envVal, 0, 64) |  | ||||||
| 				if err != nil { |  | ||||||
| 					return fmt.Errorf("could not parse %s as int value for flag %s: %s", envVal, f.Name, err) |  | ||||||
| 				} |  | ||||||
|  |  | ||||||
| 				f.Value = envValInt |  | ||||||
| 				break |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	eachName(f.Name, func(name string) { |  | ||||||
| 		if f.Destination != nil { |  | ||||||
| 			set.Int64Var(f.Destination, name, f.Value, f.Usage) |  | ||||||
| 			return |  | ||||||
| 		} |  | ||||||
| 		set.Int64(name, f.Value, f.Usage) |  | ||||||
| 	}) |  | ||||||
|  |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Apply populates the flag given the flag set and environment |  | ||||||
| // Ignores errors |  | ||||||
| func (f UintFlag) Apply(set *flag.FlagSet) { |  | ||||||
| 	f.ApplyWithError(set) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // ApplyWithError populates the flag given the flag set and environment |  | ||||||
| func (f UintFlag) ApplyWithError(set *flag.FlagSet) error { |  | ||||||
| 	if f.EnvVar != "" { |  | ||||||
| 		for _, envVar := range strings.Split(f.EnvVar, ",") { |  | ||||||
| 			envVar = strings.TrimSpace(envVar) |  | ||||||
| 			if envVal, ok := syscall.Getenv(envVar); ok { |  | ||||||
| 				envValInt, err := strconv.ParseUint(envVal, 0, 64) |  | ||||||
| 				if err != nil { |  | ||||||
| 					return fmt.Errorf("could not parse %s as uint value for flag %s: %s", envVal, f.Name, err) |  | ||||||
| 				} |  | ||||||
|  |  | ||||||
| 				f.Value = uint(envValInt) |  | ||||||
| 				break |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	eachName(f.Name, func(name string) { |  | ||||||
| 		if f.Destination != nil { |  | ||||||
| 			set.UintVar(f.Destination, name, f.Value, f.Usage) |  | ||||||
| 			return |  | ||||||
| 		} |  | ||||||
| 		set.Uint(name, f.Value, f.Usage) |  | ||||||
| 	}) |  | ||||||
|  |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Apply populates the flag given the flag set and environment |  | ||||||
| // Ignores errors |  | ||||||
| func (f Uint64Flag) Apply(set *flag.FlagSet) { |  | ||||||
| 	f.ApplyWithError(set) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // ApplyWithError populates the flag given the flag set and environment |  | ||||||
| func (f Uint64Flag) ApplyWithError(set *flag.FlagSet) error { |  | ||||||
| 	if f.EnvVar != "" { |  | ||||||
| 		for _, envVar := range strings.Split(f.EnvVar, ",") { |  | ||||||
| 			envVar = strings.TrimSpace(envVar) |  | ||||||
| 			if envVal, ok := syscall.Getenv(envVar); ok { |  | ||||||
| 				envValInt, err := strconv.ParseUint(envVal, 0, 64) |  | ||||||
| 				if err != nil { |  | ||||||
| 					return fmt.Errorf("could not parse %s as uint64 value for flag %s: %s", envVal, f.Name, err) |  | ||||||
| 				} |  | ||||||
|  |  | ||||||
| 				f.Value = uint64(envValInt) |  | ||||||
| 				break |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	eachName(f.Name, func(name string) { |  | ||||||
| 		if f.Destination != nil { |  | ||||||
| 			set.Uint64Var(f.Destination, name, f.Value, f.Usage) |  | ||||||
| 			return |  | ||||||
| 		} |  | ||||||
| 		set.Uint64(name, f.Value, f.Usage) |  | ||||||
| 	}) |  | ||||||
|  |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Apply populates the flag given the flag set and environment |  | ||||||
| // Ignores errors |  | ||||||
| func (f DurationFlag) Apply(set *flag.FlagSet) { |  | ||||||
| 	f.ApplyWithError(set) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // ApplyWithError populates the flag given the flag set and environment |  | ||||||
| func (f DurationFlag) ApplyWithError(set *flag.FlagSet) error { |  | ||||||
| 	if f.EnvVar != "" { |  | ||||||
| 		for _, envVar := range strings.Split(f.EnvVar, ",") { |  | ||||||
| 			envVar = strings.TrimSpace(envVar) |  | ||||||
| 			if envVal, ok := syscall.Getenv(envVar); ok { |  | ||||||
| 				envValDuration, err := time.ParseDuration(envVal) |  | ||||||
| 				if err != nil { |  | ||||||
| 					return fmt.Errorf("could not parse %s as duration for flag %s: %s", envVal, f.Name, err) |  | ||||||
| 				} |  | ||||||
|  |  | ||||||
| 				f.Value = envValDuration |  | ||||||
| 				break |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	eachName(f.Name, func(name string) { |  | ||||||
| 		if f.Destination != nil { |  | ||||||
| 			set.DurationVar(f.Destination, name, f.Value, f.Usage) |  | ||||||
| 			return |  | ||||||
| 		} |  | ||||||
| 		set.Duration(name, f.Value, f.Usage) |  | ||||||
| 	}) |  | ||||||
|  |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Apply populates the flag given the flag set and environment |  | ||||||
| // Ignores errors |  | ||||||
| func (f Float64Flag) Apply(set *flag.FlagSet) { |  | ||||||
| 	f.ApplyWithError(set) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // ApplyWithError populates the flag given the flag set and environment |  | ||||||
| func (f Float64Flag) ApplyWithError(set *flag.FlagSet) error { |  | ||||||
| 	if f.EnvVar != "" { |  | ||||||
| 		for _, envVar := range strings.Split(f.EnvVar, ",") { |  | ||||||
| 			envVar = strings.TrimSpace(envVar) |  | ||||||
| 			if envVal, ok := syscall.Getenv(envVar); ok { |  | ||||||
| 				envValFloat, err := strconv.ParseFloat(envVal, 10) |  | ||||||
| 				if err != nil { |  | ||||||
| 					return fmt.Errorf("could not parse %s as float64 value for flag %s: %s", envVal, f.Name, err) |  | ||||||
| 				} |  | ||||||
|  |  | ||||||
| 				f.Value = float64(envValFloat) |  | ||||||
| 				break |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	eachName(f.Name, func(name string) { |  | ||||||
| 		if f.Destination != nil { |  | ||||||
| 			set.Float64Var(f.Destination, name, f.Value, f.Usage) |  | ||||||
| 			return |  | ||||||
| 		} |  | ||||||
| 		set.Float64(name, f.Value, f.Usage) |  | ||||||
| 	}) |  | ||||||
|  |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func visibleFlags(fl []Flag) []Flag { | func visibleFlags(fl []Flag) []Flag { | ||||||
| 	visible := []Flag{} | 	var visible []Flag | ||||||
| 	for _, flag := range fl { | 	for _, f := range fl { | ||||||
| 		field := flagValue(flag).FieldByName("Hidden") | 		field := flagValue(f).FieldByName("Hidden") | ||||||
| 		if !field.IsValid() || !field.Bool() { | 		if !field.IsValid() || !field.Bool() { | ||||||
| 			visible = append(visible, flag) | 			visible = append(visible, f) | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	return visible | 	return visible | ||||||
| @@ -692,11 +196,19 @@ func withEnvHint(envVar, str string) string { | |||||||
| 			suffix = "%" | 			suffix = "%" | ||||||
| 			sep = "%, %" | 			sep = "%, %" | ||||||
| 		} | 		} | ||||||
| 		envText = fmt.Sprintf(" [%s%s%s]", prefix, strings.Join(strings.Split(envVar, ","), sep), suffix) | 		envText = " [" + prefix + strings.Join(strings.Split(envVar, ","), sep) + suffix + "]" | ||||||
| 	} | 	} | ||||||
| 	return str + envText | 	return str + envText | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func withFileHint(filePath, str string) string { | ||||||
|  | 	fileText := "" | ||||||
|  | 	if filePath != "" { | ||||||
|  | 		fileText = fmt.Sprintf(" [%s]", filePath) | ||||||
|  | 	} | ||||||
|  | 	return str + fileText | ||||||
|  | } | ||||||
|  |  | ||||||
| func flagValue(f Flag) reflect.Value { | func flagValue(f Flag) reflect.Value { | ||||||
| 	fv := reflect.ValueOf(f) | 	fv := reflect.ValueOf(f) | ||||||
| 	for fv.Kind() == reflect.Ptr { | 	for fv.Kind() == reflect.Ptr { | ||||||
| @@ -710,14 +222,29 @@ func stringifyFlag(f Flag) string { | |||||||
|  |  | ||||||
| 	switch f.(type) { | 	switch f.(type) { | ||||||
| 	case IntSliceFlag: | 	case IntSliceFlag: | ||||||
| 		return withEnvHint(fv.FieldByName("EnvVar").String(), | 		return FlagFileHinter( | ||||||
| 			stringifyIntSliceFlag(f.(IntSliceFlag))) | 			fv.FieldByName("FilePath").String(), | ||||||
|  | 			FlagEnvHinter( | ||||||
|  | 				fv.FieldByName("EnvVar").String(), | ||||||
|  | 				stringifyIntSliceFlag(f.(IntSliceFlag)), | ||||||
|  | 			), | ||||||
|  | 		) | ||||||
| 	case Int64SliceFlag: | 	case Int64SliceFlag: | ||||||
| 		return withEnvHint(fv.FieldByName("EnvVar").String(), | 		return FlagFileHinter( | ||||||
| 			stringifyInt64SliceFlag(f.(Int64SliceFlag))) | 			fv.FieldByName("FilePath").String(), | ||||||
|  | 			FlagEnvHinter( | ||||||
|  | 				fv.FieldByName("EnvVar").String(), | ||||||
|  | 				stringifyInt64SliceFlag(f.(Int64SliceFlag)), | ||||||
|  | 			), | ||||||
|  | 		) | ||||||
| 	case StringSliceFlag: | 	case StringSliceFlag: | ||||||
| 		return withEnvHint(fv.FieldByName("EnvVar").String(), | 		return FlagFileHinter( | ||||||
| 			stringifyStringSliceFlag(f.(StringSliceFlag))) | 			fv.FieldByName("FilePath").String(), | ||||||
|  | 			FlagEnvHinter( | ||||||
|  | 				fv.FieldByName("EnvVar").String(), | ||||||
|  | 				stringifyStringSliceFlag(f.(StringSliceFlag)), | ||||||
|  | 			), | ||||||
|  | 		) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	placeholder, usage := unquoteUsage(fv.FieldByName("Usage").String()) | 	placeholder, usage := unquoteUsage(fv.FieldByName("Usage").String()) | ||||||
| @@ -742,17 +269,22 @@ func stringifyFlag(f Flag) string { | |||||||
| 		placeholder = defaultPlaceholder | 		placeholder = defaultPlaceholder | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	usageWithDefault := strings.TrimSpace(fmt.Sprintf("%s%s", usage, defaultValueString)) | 	usageWithDefault := strings.TrimSpace(usage + defaultValueString) | ||||||
|  |  | ||||||
| 	return withEnvHint(fv.FieldByName("EnvVar").String(), | 	return FlagFileHinter( | ||||||
| 		fmt.Sprintf("%s\t%s", prefixedNames(fv.FieldByName("Name").String(), placeholder), usageWithDefault)) | 		fv.FieldByName("FilePath").String(), | ||||||
|  | 		FlagEnvHinter( | ||||||
|  | 			fv.FieldByName("EnvVar").String(), | ||||||
|  | 			FlagNamePrefixer(fv.FieldByName("Name").String(), placeholder)+"\t"+usageWithDefault, | ||||||
|  | 		), | ||||||
|  | 	) | ||||||
| } | } | ||||||
|  |  | ||||||
| func stringifyIntSliceFlag(f IntSliceFlag) string { | func stringifyIntSliceFlag(f IntSliceFlag) string { | ||||||
| 	defaultVals := []string{} | 	var defaultVals []string | ||||||
| 	if f.Value != nil && len(f.Value.Value()) > 0 { | 	if f.Value != nil && len(f.Value.Value()) > 0 { | ||||||
| 		for _, i := range f.Value.Value() { | 		for _, i := range f.Value.Value() { | ||||||
| 			defaultVals = append(defaultVals, fmt.Sprintf("%d", i)) | 			defaultVals = append(defaultVals, strconv.Itoa(i)) | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -760,10 +292,10 @@ func stringifyIntSliceFlag(f IntSliceFlag) string { | |||||||
| } | } | ||||||
|  |  | ||||||
| func stringifyInt64SliceFlag(f Int64SliceFlag) string { | func stringifyInt64SliceFlag(f Int64SliceFlag) string { | ||||||
| 	defaultVals := []string{} | 	var defaultVals []string | ||||||
| 	if f.Value != nil && len(f.Value.Value()) > 0 { | 	if f.Value != nil && len(f.Value.Value()) > 0 { | ||||||
| 		for _, i := range f.Value.Value() { | 		for _, i := range f.Value.Value() { | ||||||
| 			defaultVals = append(defaultVals, fmt.Sprintf("%d", i)) | 			defaultVals = append(defaultVals, strconv.FormatInt(i, 10)) | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -771,11 +303,11 @@ func stringifyInt64SliceFlag(f Int64SliceFlag) string { | |||||||
| } | } | ||||||
|  |  | ||||||
| func stringifyStringSliceFlag(f StringSliceFlag) string { | func stringifyStringSliceFlag(f StringSliceFlag) string { | ||||||
| 	defaultVals := []string{} | 	var defaultVals []string | ||||||
| 	if f.Value != nil && len(f.Value.Value()) > 0 { | 	if f.Value != nil && len(f.Value.Value()) > 0 { | ||||||
| 		for _, s := range f.Value.Value() { | 		for _, s := range f.Value.Value() { | ||||||
| 			if len(s) > 0 { | 			if len(s) > 0 { | ||||||
| 				defaultVals = append(defaultVals, fmt.Sprintf("%q", s)) | 				defaultVals = append(defaultVals, strconv.Quote(s)) | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| @@ -794,6 +326,21 @@ func stringifySliceFlag(usage, name string, defaultVals []string) string { | |||||||
| 		defaultVal = fmt.Sprintf(" (default: %s)", strings.Join(defaultVals, ", ")) | 		defaultVal = fmt.Sprintf(" (default: %s)", strings.Join(defaultVals, ", ")) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	usageWithDefault := strings.TrimSpace(fmt.Sprintf("%s%s", usage, defaultVal)) | 	usageWithDefault := strings.TrimSpace(usage + defaultVal) | ||||||
| 	return fmt.Sprintf("%s\t%s", prefixedNames(name, placeholder), usageWithDefault) | 	return FlagNamePrefixer(name, placeholder) + "\t" + usageWithDefault | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func flagFromFileEnv(filePath, envName string) (val string, ok bool) { | ||||||
|  | 	for _, envVar := range strings.Split(envName, ",") { | ||||||
|  | 		envVar = strings.TrimSpace(envVar) | ||||||
|  | 		if envVal, ok := syscall.Getenv(envVar); ok { | ||||||
|  | 			return envVal, true | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	for _, fileVar := range strings.Split(filePath, ",") { | ||||||
|  | 		if data, err := ioutil.ReadFile(fileVar); err == nil { | ||||||
|  | 			return string(data), true | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return "", false | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										109
									
								
								vendor/github.com/urfave/cli/flag_bool.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										109
									
								
								vendor/github.com/urfave/cli/flag_bool.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,109 @@ | |||||||
|  | package cli | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"flag" | ||||||
|  | 	"fmt" | ||||||
|  | 	"strconv" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | // BoolFlag is a flag with type bool | ||||||
|  | type BoolFlag struct { | ||||||
|  | 	Name        string | ||||||
|  | 	Usage       string | ||||||
|  | 	EnvVar      string | ||||||
|  | 	FilePath    string | ||||||
|  | 	Required    bool | ||||||
|  | 	Hidden      bool | ||||||
|  | 	Destination *bool | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // String returns a readable representation of this value | ||||||
|  | // (for usage defaults) | ||||||
|  | func (f BoolFlag) String() string { | ||||||
|  | 	return FlagStringer(f) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // GetName returns the name of the flag | ||||||
|  | func (f BoolFlag) GetName() string { | ||||||
|  | 	return f.Name | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // IsRequired returns whether or not the flag is required | ||||||
|  | func (f BoolFlag) IsRequired() bool { | ||||||
|  | 	return f.Required | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // TakesValue returns true of the flag takes a value, otherwise false | ||||||
|  | func (f BoolFlag) TakesValue() bool { | ||||||
|  | 	return false | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // GetUsage returns the usage string for the flag | ||||||
|  | func (f BoolFlag) GetUsage() string { | ||||||
|  | 	return f.Usage | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // 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 "" | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Bool looks up the value of a local BoolFlag, returns | ||||||
|  | // false if not found | ||||||
|  | func (c *Context) Bool(name string) bool { | ||||||
|  | 	return lookupBool(name, c.flagSet) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // GlobalBool looks up the value of a global BoolFlag, returns | ||||||
|  | // false if not found | ||||||
|  | func (c *Context) GlobalBool(name string) bool { | ||||||
|  | 	if fs := lookupGlobalFlagSet(name, c); fs != nil { | ||||||
|  | 		return lookupBool(name, fs) | ||||||
|  | 	} | ||||||
|  | 	return false | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Apply populates the flag given the flag set and environment | ||||||
|  | // Ignores errors | ||||||
|  | func (f BoolFlag) Apply(set *flag.FlagSet) { | ||||||
|  | 	_ = f.ApplyWithError(set) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // ApplyWithError populates the flag given the flag set and environment | ||||||
|  | func (f BoolFlag) ApplyWithError(set *flag.FlagSet) error { | ||||||
|  | 	val := false | ||||||
|  | 	if envVal, ok := flagFromFileEnv(f.FilePath, f.EnvVar); ok { | ||||||
|  | 		if envVal == "" { | ||||||
|  | 			val = false | ||||||
|  | 		} else { | ||||||
|  | 			envValBool, err := strconv.ParseBool(envVal) | ||||||
|  | 			if err != nil { | ||||||
|  | 				return fmt.Errorf("could not parse %s as bool value for flag %s: %s", envVal, f.Name, err) | ||||||
|  | 			} | ||||||
|  | 			val = envValBool | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	eachName(f.Name, func(name string) { | ||||||
|  | 		if f.Destination != nil { | ||||||
|  | 			set.BoolVar(f.Destination, name, val, f.Usage) | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
|  | 		set.Bool(name, val, f.Usage) | ||||||
|  | 	}) | ||||||
|  |  | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func lookupBool(name string, set *flag.FlagSet) bool { | ||||||
|  | 	f := set.Lookup(name) | ||||||
|  | 	if f != nil { | ||||||
|  | 		parsed, err := strconv.ParseBool(f.Value.String()) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return false | ||||||
|  | 		} | ||||||
|  | 		return parsed | ||||||
|  | 	} | ||||||
|  | 	return false | ||||||
|  | } | ||||||
							
								
								
									
										110
									
								
								vendor/github.com/urfave/cli/flag_bool_t.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										110
									
								
								vendor/github.com/urfave/cli/flag_bool_t.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,110 @@ | |||||||
|  | package cli | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"flag" | ||||||
|  | 	"fmt" | ||||||
|  | 	"strconv" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | // BoolTFlag is a flag with type bool that is true by default | ||||||
|  | type BoolTFlag struct { | ||||||
|  | 	Name        string | ||||||
|  | 	Usage       string | ||||||
|  | 	EnvVar      string | ||||||
|  | 	FilePath    string | ||||||
|  | 	Required    bool | ||||||
|  | 	Hidden      bool | ||||||
|  | 	Destination *bool | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // String returns a readable representation of this value | ||||||
|  | // (for usage defaults) | ||||||
|  | func (f BoolTFlag) String() string { | ||||||
|  | 	return FlagStringer(f) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // GetName returns the name of the flag | ||||||
|  | func (f BoolTFlag) GetName() string { | ||||||
|  | 	return f.Name | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // IsRequired returns whether or not the flag is required | ||||||
|  | func (f BoolTFlag) IsRequired() bool { | ||||||
|  | 	return f.Required | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // TakesValue returns true of the flag takes a value, otherwise false | ||||||
|  | func (f BoolTFlag) TakesValue() bool { | ||||||
|  | 	return false | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // GetUsage returns the usage string for the flag | ||||||
|  | func (f BoolTFlag) GetUsage() string { | ||||||
|  | 	return f.Usage | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // GetValue returns the flags value as string representation and an empty | ||||||
|  | // string if the flag takes no value at all. | ||||||
|  | func (f BoolTFlag) GetValue() string { | ||||||
|  | 	return "" | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // BoolT looks up the value of a local BoolTFlag, returns | ||||||
|  | // false if not found | ||||||
|  | func (c *Context) BoolT(name string) bool { | ||||||
|  | 	return lookupBoolT(name, c.flagSet) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // GlobalBoolT looks up the value of a global BoolTFlag, returns | ||||||
|  | // false if not found | ||||||
|  | func (c *Context) GlobalBoolT(name string) bool { | ||||||
|  | 	if fs := lookupGlobalFlagSet(name, c); fs != nil { | ||||||
|  | 		return lookupBoolT(name, fs) | ||||||
|  | 	} | ||||||
|  | 	return false | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Apply populates the flag given the flag set and environment | ||||||
|  | // Ignores errors | ||||||
|  | func (f BoolTFlag) Apply(set *flag.FlagSet) { | ||||||
|  | 	_ = f.ApplyWithError(set) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // ApplyWithError populates the flag given the flag set and environment | ||||||
|  | func (f BoolTFlag) ApplyWithError(set *flag.FlagSet) error { | ||||||
|  | 	val := true | ||||||
|  |  | ||||||
|  | 	if envVal, ok := flagFromFileEnv(f.FilePath, f.EnvVar); ok { | ||||||
|  | 		if envVal == "" { | ||||||
|  | 			val = false | ||||||
|  | 		} else { | ||||||
|  | 			envValBool, err := strconv.ParseBool(envVal) | ||||||
|  | 			if err != nil { | ||||||
|  | 				return fmt.Errorf("could not parse %s as bool value for flag %s: %s", envVal, f.Name, err) | ||||||
|  | 			} | ||||||
|  | 			val = envValBool | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	eachName(f.Name, func(name string) { | ||||||
|  | 		if f.Destination != nil { | ||||||
|  | 			set.BoolVar(f.Destination, name, val, f.Usage) | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
|  | 		set.Bool(name, val, f.Usage) | ||||||
|  | 	}) | ||||||
|  |  | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func lookupBoolT(name string, set *flag.FlagSet) bool { | ||||||
|  | 	f := set.Lookup(name) | ||||||
|  | 	if f != nil { | ||||||
|  | 		parsed, err := strconv.ParseBool(f.Value.String()) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return false | ||||||
|  | 		} | ||||||
|  | 		return parsed | ||||||
|  | 	} | ||||||
|  | 	return false | ||||||
|  | } | ||||||
							
								
								
									
										106
									
								
								vendor/github.com/urfave/cli/flag_duration.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										106
									
								
								vendor/github.com/urfave/cli/flag_duration.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,106 @@ | |||||||
|  | package cli | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"flag" | ||||||
|  | 	"fmt" | ||||||
|  | 	"time" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | // DurationFlag is a flag with type time.Duration (see https://golang.org/pkg/time/#ParseDuration) | ||||||
|  | type DurationFlag struct { | ||||||
|  | 	Name        string | ||||||
|  | 	Usage       string | ||||||
|  | 	EnvVar      string | ||||||
|  | 	FilePath    string | ||||||
|  | 	Required    bool | ||||||
|  | 	Hidden      bool | ||||||
|  | 	Value       time.Duration | ||||||
|  | 	Destination *time.Duration | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // String returns a readable representation of this value | ||||||
|  | // (for usage defaults) | ||||||
|  | func (f DurationFlag) String() string { | ||||||
|  | 	return FlagStringer(f) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // GetName returns the name of the flag | ||||||
|  | func (f DurationFlag) GetName() string { | ||||||
|  | 	return f.Name | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // 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 | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // GetUsage returns the usage string for the flag | ||||||
|  | func (f DurationFlag) GetUsage() string { | ||||||
|  | 	return f.Usage | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // 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() | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Duration looks up the value of a local DurationFlag, returns | ||||||
|  | // 0 if not found | ||||||
|  | func (c *Context) Duration(name string) time.Duration { | ||||||
|  | 	return lookupDuration(name, c.flagSet) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // GlobalDuration looks up the value of a global DurationFlag, returns | ||||||
|  | // 0 if not found | ||||||
|  | func (c *Context) GlobalDuration(name string) time.Duration { | ||||||
|  | 	if fs := lookupGlobalFlagSet(name, c); fs != nil { | ||||||
|  | 		return lookupDuration(name, fs) | ||||||
|  | 	} | ||||||
|  | 	return 0 | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Apply populates the flag given the flag set and environment | ||||||
|  | // Ignores errors | ||||||
|  | func (f DurationFlag) Apply(set *flag.FlagSet) { | ||||||
|  | 	_ = f.ApplyWithError(set) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // ApplyWithError populates the flag given the flag set and environment | ||||||
|  | func (f DurationFlag) ApplyWithError(set *flag.FlagSet) error { | ||||||
|  | 	if envVal, ok := flagFromFileEnv(f.FilePath, f.EnvVar); ok { | ||||||
|  | 		envValDuration, err := time.ParseDuration(envVal) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return fmt.Errorf("could not parse %s as duration for flag %s: %s", envVal, f.Name, err) | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		f.Value = envValDuration | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	eachName(f.Name, func(name string) { | ||||||
|  | 		if f.Destination != nil { | ||||||
|  | 			set.DurationVar(f.Destination, name, f.Value, f.Usage) | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
|  | 		set.Duration(name, f.Value, f.Usage) | ||||||
|  | 	}) | ||||||
|  |  | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func lookupDuration(name string, set *flag.FlagSet) time.Duration { | ||||||
|  | 	f := set.Lookup(name) | ||||||
|  | 	if f != nil { | ||||||
|  | 		parsed, err := time.ParseDuration(f.Value.String()) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return 0 | ||||||
|  | 		} | ||||||
|  | 		return parsed | ||||||
|  | 	} | ||||||
|  | 	return 0 | ||||||
|  | } | ||||||
							
								
								
									
										106
									
								
								vendor/github.com/urfave/cli/flag_float64.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										106
									
								
								vendor/github.com/urfave/cli/flag_float64.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,106 @@ | |||||||
|  | package cli | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"flag" | ||||||
|  | 	"fmt" | ||||||
|  | 	"strconv" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | // Float64Flag is a flag with type float64 | ||||||
|  | type Float64Flag struct { | ||||||
|  | 	Name        string | ||||||
|  | 	Usage       string | ||||||
|  | 	EnvVar      string | ||||||
|  | 	FilePath    string | ||||||
|  | 	Required    bool | ||||||
|  | 	Hidden      bool | ||||||
|  | 	Value       float64 | ||||||
|  | 	Destination *float64 | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // String returns a readable representation of this value | ||||||
|  | // (for usage defaults) | ||||||
|  | func (f Float64Flag) String() string { | ||||||
|  | 	return FlagStringer(f) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // GetName returns the name of the flag | ||||||
|  | func (f Float64Flag) GetName() string { | ||||||
|  | 	return f.Name | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // 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 | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // GetUsage returns the usage string for the flag | ||||||
|  | func (f Float64Flag) GetUsage() string { | ||||||
|  | 	return f.Usage | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // 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) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Float64 looks up the value of a local Float64Flag, returns | ||||||
|  | // 0 if not found | ||||||
|  | func (c *Context) Float64(name string) float64 { | ||||||
|  | 	return lookupFloat64(name, c.flagSet) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // GlobalFloat64 looks up the value of a global Float64Flag, returns | ||||||
|  | // 0 if not found | ||||||
|  | func (c *Context) GlobalFloat64(name string) float64 { | ||||||
|  | 	if fs := lookupGlobalFlagSet(name, c); fs != nil { | ||||||
|  | 		return lookupFloat64(name, fs) | ||||||
|  | 	} | ||||||
|  | 	return 0 | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Apply populates the flag given the flag set and environment | ||||||
|  | // Ignores errors | ||||||
|  | func (f Float64Flag) Apply(set *flag.FlagSet) { | ||||||
|  | 	_ = f.ApplyWithError(set) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // ApplyWithError populates the flag given the flag set and environment | ||||||
|  | func (f Float64Flag) ApplyWithError(set *flag.FlagSet) error { | ||||||
|  | 	if envVal, ok := flagFromFileEnv(f.FilePath, f.EnvVar); ok { | ||||||
|  | 		envValFloat, err := strconv.ParseFloat(envVal, 10) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return fmt.Errorf("could not parse %s as float64 value for flag %s: %s", envVal, f.Name, err) | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		f.Value = envValFloat | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	eachName(f.Name, func(name string) { | ||||||
|  | 		if f.Destination != nil { | ||||||
|  | 			set.Float64Var(f.Destination, name, f.Value, f.Usage) | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
|  | 		set.Float64(name, f.Value, f.Usage) | ||||||
|  | 	}) | ||||||
|  |  | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func lookupFloat64(name string, set *flag.FlagSet) float64 { | ||||||
|  | 	f := set.Lookup(name) | ||||||
|  | 	if f != nil { | ||||||
|  | 		parsed, err := strconv.ParseFloat(f.Value.String(), 64) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return 0 | ||||||
|  | 		} | ||||||
|  | 		return parsed | ||||||
|  | 	} | ||||||
|  | 	return 0 | ||||||
|  | } | ||||||
							
								
								
									
										627
									
								
								vendor/github.com/urfave/cli/flag_generated.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										627
									
								
								vendor/github.com/urfave/cli/flag_generated.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,627 +0,0 @@ | |||||||
| package cli |  | ||||||
|  |  | ||||||
| import ( |  | ||||||
| 	"flag" |  | ||||||
| 	"strconv" |  | ||||||
| 	"time" |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| // WARNING: This file is generated! |  | ||||||
|  |  | ||||||
| // BoolFlag is a flag with type bool |  | ||||||
| type BoolFlag struct { |  | ||||||
| 	Name        string |  | ||||||
| 	Usage       string |  | ||||||
| 	EnvVar      string |  | ||||||
| 	Hidden      bool |  | ||||||
| 	Destination *bool |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // String returns a readable representation of this value |  | ||||||
| // (for usage defaults) |  | ||||||
| func (f BoolFlag) String() string { |  | ||||||
| 	return FlagStringer(f) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // GetName returns the name of the flag |  | ||||||
| func (f BoolFlag) GetName() string { |  | ||||||
| 	return f.Name |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Bool looks up the value of a local BoolFlag, returns |  | ||||||
| // false if not found |  | ||||||
| func (c *Context) Bool(name string) bool { |  | ||||||
| 	return lookupBool(name, c.flagSet) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // GlobalBool looks up the value of a global BoolFlag, returns |  | ||||||
| // false if not found |  | ||||||
| func (c *Context) GlobalBool(name string) bool { |  | ||||||
| 	if fs := lookupGlobalFlagSet(name, c); fs != nil { |  | ||||||
| 		return lookupBool(name, fs) |  | ||||||
| 	} |  | ||||||
| 	return false |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func lookupBool(name string, set *flag.FlagSet) bool { |  | ||||||
| 	f := set.Lookup(name) |  | ||||||
| 	if f != nil { |  | ||||||
| 		parsed, err := strconv.ParseBool(f.Value.String()) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return false |  | ||||||
| 		} |  | ||||||
| 		return parsed |  | ||||||
| 	} |  | ||||||
| 	return false |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // BoolTFlag is a flag with type bool that is true by default |  | ||||||
| type BoolTFlag struct { |  | ||||||
| 	Name        string |  | ||||||
| 	Usage       string |  | ||||||
| 	EnvVar      string |  | ||||||
| 	Hidden      bool |  | ||||||
| 	Destination *bool |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // String returns a readable representation of this value |  | ||||||
| // (for usage defaults) |  | ||||||
| func (f BoolTFlag) String() string { |  | ||||||
| 	return FlagStringer(f) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // GetName returns the name of the flag |  | ||||||
| func (f BoolTFlag) GetName() string { |  | ||||||
| 	return f.Name |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // BoolT looks up the value of a local BoolTFlag, returns |  | ||||||
| // false if not found |  | ||||||
| func (c *Context) BoolT(name string) bool { |  | ||||||
| 	return lookupBoolT(name, c.flagSet) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // GlobalBoolT looks up the value of a global BoolTFlag, returns |  | ||||||
| // false if not found |  | ||||||
| func (c *Context) GlobalBoolT(name string) bool { |  | ||||||
| 	if fs := lookupGlobalFlagSet(name, c); fs != nil { |  | ||||||
| 		return lookupBoolT(name, fs) |  | ||||||
| 	} |  | ||||||
| 	return false |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func lookupBoolT(name string, set *flag.FlagSet) bool { |  | ||||||
| 	f := set.Lookup(name) |  | ||||||
| 	if f != nil { |  | ||||||
| 		parsed, err := strconv.ParseBool(f.Value.String()) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return false |  | ||||||
| 		} |  | ||||||
| 		return parsed |  | ||||||
| 	} |  | ||||||
| 	return false |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // DurationFlag is a flag with type time.Duration (see https://golang.org/pkg/time/#ParseDuration) |  | ||||||
| type DurationFlag struct { |  | ||||||
| 	Name        string |  | ||||||
| 	Usage       string |  | ||||||
| 	EnvVar      string |  | ||||||
| 	Hidden      bool |  | ||||||
| 	Value       time.Duration |  | ||||||
| 	Destination *time.Duration |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // String returns a readable representation of this value |  | ||||||
| // (for usage defaults) |  | ||||||
| func (f DurationFlag) String() string { |  | ||||||
| 	return FlagStringer(f) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // GetName returns the name of the flag |  | ||||||
| func (f DurationFlag) GetName() string { |  | ||||||
| 	return f.Name |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Duration looks up the value of a local DurationFlag, returns |  | ||||||
| // 0 if not found |  | ||||||
| func (c *Context) Duration(name string) time.Duration { |  | ||||||
| 	return lookupDuration(name, c.flagSet) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // GlobalDuration looks up the value of a global DurationFlag, returns |  | ||||||
| // 0 if not found |  | ||||||
| func (c *Context) GlobalDuration(name string) time.Duration { |  | ||||||
| 	if fs := lookupGlobalFlagSet(name, c); fs != nil { |  | ||||||
| 		return lookupDuration(name, fs) |  | ||||||
| 	} |  | ||||||
| 	return 0 |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func lookupDuration(name string, set *flag.FlagSet) time.Duration { |  | ||||||
| 	f := set.Lookup(name) |  | ||||||
| 	if f != nil { |  | ||||||
| 		parsed, err := time.ParseDuration(f.Value.String()) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return 0 |  | ||||||
| 		} |  | ||||||
| 		return parsed |  | ||||||
| 	} |  | ||||||
| 	return 0 |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Float64Flag is a flag with type float64 |  | ||||||
| type Float64Flag struct { |  | ||||||
| 	Name        string |  | ||||||
| 	Usage       string |  | ||||||
| 	EnvVar      string |  | ||||||
| 	Hidden      bool |  | ||||||
| 	Value       float64 |  | ||||||
| 	Destination *float64 |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // String returns a readable representation of this value |  | ||||||
| // (for usage defaults) |  | ||||||
| func (f Float64Flag) String() string { |  | ||||||
| 	return FlagStringer(f) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // GetName returns the name of the flag |  | ||||||
| func (f Float64Flag) GetName() string { |  | ||||||
| 	return f.Name |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Float64 looks up the value of a local Float64Flag, returns |  | ||||||
| // 0 if not found |  | ||||||
| func (c *Context) Float64(name string) float64 { |  | ||||||
| 	return lookupFloat64(name, c.flagSet) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // GlobalFloat64 looks up the value of a global Float64Flag, returns |  | ||||||
| // 0 if not found |  | ||||||
| func (c *Context) GlobalFloat64(name string) float64 { |  | ||||||
| 	if fs := lookupGlobalFlagSet(name, c); fs != nil { |  | ||||||
| 		return lookupFloat64(name, fs) |  | ||||||
| 	} |  | ||||||
| 	return 0 |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func lookupFloat64(name string, set *flag.FlagSet) float64 { |  | ||||||
| 	f := set.Lookup(name) |  | ||||||
| 	if f != nil { |  | ||||||
| 		parsed, err := strconv.ParseFloat(f.Value.String(), 64) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return 0 |  | ||||||
| 		} |  | ||||||
| 		return parsed |  | ||||||
| 	} |  | ||||||
| 	return 0 |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // GenericFlag is a flag with type Generic |  | ||||||
| type GenericFlag struct { |  | ||||||
| 	Name   string |  | ||||||
| 	Usage  string |  | ||||||
| 	EnvVar string |  | ||||||
| 	Hidden bool |  | ||||||
| 	Value  Generic |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // String returns a readable representation of this value |  | ||||||
| // (for usage defaults) |  | ||||||
| func (f GenericFlag) String() string { |  | ||||||
| 	return FlagStringer(f) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // GetName returns the name of the flag |  | ||||||
| func (f GenericFlag) GetName() string { |  | ||||||
| 	return f.Name |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Generic looks up the value of a local GenericFlag, returns |  | ||||||
| // nil if not found |  | ||||||
| func (c *Context) Generic(name string) interface{} { |  | ||||||
| 	return lookupGeneric(name, c.flagSet) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // GlobalGeneric looks up the value of a global GenericFlag, returns |  | ||||||
| // nil if not found |  | ||||||
| func (c *Context) GlobalGeneric(name string) interface{} { |  | ||||||
| 	if fs := lookupGlobalFlagSet(name, c); fs != nil { |  | ||||||
| 		return lookupGeneric(name, fs) |  | ||||||
| 	} |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func lookupGeneric(name string, set *flag.FlagSet) interface{} { |  | ||||||
| 	f := set.Lookup(name) |  | ||||||
| 	if f != nil { |  | ||||||
| 		parsed, err := f.Value, error(nil) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return nil |  | ||||||
| 		} |  | ||||||
| 		return parsed |  | ||||||
| 	} |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Int64Flag is a flag with type int64 |  | ||||||
| type Int64Flag struct { |  | ||||||
| 	Name        string |  | ||||||
| 	Usage       string |  | ||||||
| 	EnvVar      string |  | ||||||
| 	Hidden      bool |  | ||||||
| 	Value       int64 |  | ||||||
| 	Destination *int64 |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // String returns a readable representation of this value |  | ||||||
| // (for usage defaults) |  | ||||||
| func (f Int64Flag) String() string { |  | ||||||
| 	return FlagStringer(f) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // GetName returns the name of the flag |  | ||||||
| func (f Int64Flag) GetName() string { |  | ||||||
| 	return f.Name |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Int64 looks up the value of a local Int64Flag, returns |  | ||||||
| // 0 if not found |  | ||||||
| func (c *Context) Int64(name string) int64 { |  | ||||||
| 	return lookupInt64(name, c.flagSet) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // GlobalInt64 looks up the value of a global Int64Flag, returns |  | ||||||
| // 0 if not found |  | ||||||
| func (c *Context) GlobalInt64(name string) int64 { |  | ||||||
| 	if fs := lookupGlobalFlagSet(name, c); fs != nil { |  | ||||||
| 		return lookupInt64(name, fs) |  | ||||||
| 	} |  | ||||||
| 	return 0 |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func lookupInt64(name string, set *flag.FlagSet) int64 { |  | ||||||
| 	f := set.Lookup(name) |  | ||||||
| 	if f != nil { |  | ||||||
| 		parsed, err := strconv.ParseInt(f.Value.String(), 0, 64) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return 0 |  | ||||||
| 		} |  | ||||||
| 		return parsed |  | ||||||
| 	} |  | ||||||
| 	return 0 |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // IntFlag is a flag with type int |  | ||||||
| type IntFlag struct { |  | ||||||
| 	Name        string |  | ||||||
| 	Usage       string |  | ||||||
| 	EnvVar      string |  | ||||||
| 	Hidden      bool |  | ||||||
| 	Value       int |  | ||||||
| 	Destination *int |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // String returns a readable representation of this value |  | ||||||
| // (for usage defaults) |  | ||||||
| func (f IntFlag) String() string { |  | ||||||
| 	return FlagStringer(f) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // GetName returns the name of the flag |  | ||||||
| func (f IntFlag) GetName() string { |  | ||||||
| 	return f.Name |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Int looks up the value of a local IntFlag, returns |  | ||||||
| // 0 if not found |  | ||||||
| func (c *Context) Int(name string) int { |  | ||||||
| 	return lookupInt(name, c.flagSet) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // GlobalInt looks up the value of a global IntFlag, returns |  | ||||||
| // 0 if not found |  | ||||||
| func (c *Context) GlobalInt(name string) int { |  | ||||||
| 	if fs := lookupGlobalFlagSet(name, c); fs != nil { |  | ||||||
| 		return lookupInt(name, fs) |  | ||||||
| 	} |  | ||||||
| 	return 0 |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func lookupInt(name string, set *flag.FlagSet) int { |  | ||||||
| 	f := set.Lookup(name) |  | ||||||
| 	if f != nil { |  | ||||||
| 		parsed, err := strconv.ParseInt(f.Value.String(), 0, 64) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return 0 |  | ||||||
| 		} |  | ||||||
| 		return int(parsed) |  | ||||||
| 	} |  | ||||||
| 	return 0 |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // IntSliceFlag is a flag with type *IntSlice |  | ||||||
| type IntSliceFlag struct { |  | ||||||
| 	Name   string |  | ||||||
| 	Usage  string |  | ||||||
| 	EnvVar string |  | ||||||
| 	Hidden bool |  | ||||||
| 	Value  *IntSlice |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // String returns a readable representation of this value |  | ||||||
| // (for usage defaults) |  | ||||||
| func (f IntSliceFlag) String() string { |  | ||||||
| 	return FlagStringer(f) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // GetName returns the name of the flag |  | ||||||
| func (f IntSliceFlag) GetName() string { |  | ||||||
| 	return f.Name |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // IntSlice looks up the value of a local IntSliceFlag, returns |  | ||||||
| // nil if not found |  | ||||||
| func (c *Context) IntSlice(name string) []int { |  | ||||||
| 	return lookupIntSlice(name, c.flagSet) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // GlobalIntSlice looks up the value of a global IntSliceFlag, returns |  | ||||||
| // nil if not found |  | ||||||
| func (c *Context) GlobalIntSlice(name string) []int { |  | ||||||
| 	if fs := lookupGlobalFlagSet(name, c); fs != nil { |  | ||||||
| 		return lookupIntSlice(name, fs) |  | ||||||
| 	} |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func lookupIntSlice(name string, set *flag.FlagSet) []int { |  | ||||||
| 	f := set.Lookup(name) |  | ||||||
| 	if f != nil { |  | ||||||
| 		parsed, err := (f.Value.(*IntSlice)).Value(), error(nil) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return nil |  | ||||||
| 		} |  | ||||||
| 		return parsed |  | ||||||
| 	} |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Int64SliceFlag is a flag with type *Int64Slice |  | ||||||
| type Int64SliceFlag struct { |  | ||||||
| 	Name   string |  | ||||||
| 	Usage  string |  | ||||||
| 	EnvVar string |  | ||||||
| 	Hidden bool |  | ||||||
| 	Value  *Int64Slice |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // String returns a readable representation of this value |  | ||||||
| // (for usage defaults) |  | ||||||
| func (f Int64SliceFlag) String() string { |  | ||||||
| 	return FlagStringer(f) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // GetName returns the name of the flag |  | ||||||
| func (f Int64SliceFlag) GetName() string { |  | ||||||
| 	return f.Name |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // 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) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // GlobalInt64Slice looks up the value of a global Int64SliceFlag, returns |  | ||||||
| // nil if not found |  | ||||||
| func (c *Context) GlobalInt64Slice(name string) []int64 { |  | ||||||
| 	if fs := lookupGlobalFlagSet(name, c); fs != nil { |  | ||||||
| 		return lookupInt64Slice(name, fs) |  | ||||||
| 	} |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func lookupInt64Slice(name string, set *flag.FlagSet) []int64 { |  | ||||||
| 	f := set.Lookup(name) |  | ||||||
| 	if f != nil { |  | ||||||
| 		parsed, err := (f.Value.(*Int64Slice)).Value(), error(nil) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return nil |  | ||||||
| 		} |  | ||||||
| 		return parsed |  | ||||||
| 	} |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // StringFlag is a flag with type string |  | ||||||
| type StringFlag struct { |  | ||||||
| 	Name        string |  | ||||||
| 	Usage       string |  | ||||||
| 	EnvVar      string |  | ||||||
| 	Hidden      bool |  | ||||||
| 	Value       string |  | ||||||
| 	Destination *string |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // String returns a readable representation of this value |  | ||||||
| // (for usage defaults) |  | ||||||
| func (f StringFlag) String() string { |  | ||||||
| 	return FlagStringer(f) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // GetName returns the name of the flag |  | ||||||
| func (f StringFlag) GetName() string { |  | ||||||
| 	return f.Name |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // String looks up the value of a local StringFlag, returns |  | ||||||
| // "" if not found |  | ||||||
| func (c *Context) String(name string) string { |  | ||||||
| 	return lookupString(name, c.flagSet) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // GlobalString looks up the value of a global StringFlag, returns |  | ||||||
| // "" if not found |  | ||||||
| func (c *Context) GlobalString(name string) string { |  | ||||||
| 	if fs := lookupGlobalFlagSet(name, c); fs != nil { |  | ||||||
| 		return lookupString(name, fs) |  | ||||||
| 	} |  | ||||||
| 	return "" |  | ||||||
| } |  | ||||||
|  |  | ||||||
| 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 "" |  | ||||||
| 		} |  | ||||||
| 		return parsed |  | ||||||
| 	} |  | ||||||
| 	return "" |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // StringSliceFlag is a flag with type *StringSlice |  | ||||||
| type StringSliceFlag struct { |  | ||||||
| 	Name   string |  | ||||||
| 	Usage  string |  | ||||||
| 	EnvVar string |  | ||||||
| 	Hidden bool |  | ||||||
| 	Value  *StringSlice |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // String returns a readable representation of this value |  | ||||||
| // (for usage defaults) |  | ||||||
| func (f StringSliceFlag) String() string { |  | ||||||
| 	return FlagStringer(f) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // GetName returns the name of the flag |  | ||||||
| func (f StringSliceFlag) GetName() string { |  | ||||||
| 	return f.Name |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // StringSlice looks up the value of a local StringSliceFlag, returns |  | ||||||
| // nil if not found |  | ||||||
| func (c *Context) StringSlice(name string) []string { |  | ||||||
| 	return lookupStringSlice(name, c.flagSet) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // GlobalStringSlice looks up the value of a global StringSliceFlag, returns |  | ||||||
| // nil if not found |  | ||||||
| func (c *Context) GlobalStringSlice(name string) []string { |  | ||||||
| 	if fs := lookupGlobalFlagSet(name, c); fs != nil { |  | ||||||
| 		return lookupStringSlice(name, fs) |  | ||||||
| 	} |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func lookupStringSlice(name string, set *flag.FlagSet) []string { |  | ||||||
| 	f := set.Lookup(name) |  | ||||||
| 	if f != nil { |  | ||||||
| 		parsed, err := (f.Value.(*StringSlice)).Value(), error(nil) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return nil |  | ||||||
| 		} |  | ||||||
| 		return parsed |  | ||||||
| 	} |  | ||||||
| 	return nil |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Uint64Flag is a flag with type uint64 |  | ||||||
| type Uint64Flag struct { |  | ||||||
| 	Name        string |  | ||||||
| 	Usage       string |  | ||||||
| 	EnvVar      string |  | ||||||
| 	Hidden      bool |  | ||||||
| 	Value       uint64 |  | ||||||
| 	Destination *uint64 |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // String returns a readable representation of this value |  | ||||||
| // (for usage defaults) |  | ||||||
| func (f Uint64Flag) String() string { |  | ||||||
| 	return FlagStringer(f) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // GetName returns the name of the flag |  | ||||||
| func (f Uint64Flag) GetName() string { |  | ||||||
| 	return f.Name |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Uint64 looks up the value of a local Uint64Flag, returns |  | ||||||
| // 0 if not found |  | ||||||
| func (c *Context) Uint64(name string) uint64 { |  | ||||||
| 	return lookupUint64(name, c.flagSet) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // GlobalUint64 looks up the value of a global Uint64Flag, returns |  | ||||||
| // 0 if not found |  | ||||||
| func (c *Context) GlobalUint64(name string) uint64 { |  | ||||||
| 	if fs := lookupGlobalFlagSet(name, c); fs != nil { |  | ||||||
| 		return lookupUint64(name, fs) |  | ||||||
| 	} |  | ||||||
| 	return 0 |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func lookupUint64(name string, set *flag.FlagSet) uint64 { |  | ||||||
| 	f := set.Lookup(name) |  | ||||||
| 	if f != nil { |  | ||||||
| 		parsed, err := strconv.ParseUint(f.Value.String(), 0, 64) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return 0 |  | ||||||
| 		} |  | ||||||
| 		return parsed |  | ||||||
| 	} |  | ||||||
| 	return 0 |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // UintFlag is a flag with type uint |  | ||||||
| type UintFlag struct { |  | ||||||
| 	Name        string |  | ||||||
| 	Usage       string |  | ||||||
| 	EnvVar      string |  | ||||||
| 	Hidden      bool |  | ||||||
| 	Value       uint |  | ||||||
| 	Destination *uint |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // String returns a readable representation of this value |  | ||||||
| // (for usage defaults) |  | ||||||
| func (f UintFlag) String() string { |  | ||||||
| 	return FlagStringer(f) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // GetName returns the name of the flag |  | ||||||
| func (f UintFlag) GetName() string { |  | ||||||
| 	return f.Name |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Uint looks up the value of a local UintFlag, returns |  | ||||||
| // 0 if not found |  | ||||||
| func (c *Context) Uint(name string) uint { |  | ||||||
| 	return lookupUint(name, c.flagSet) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // GlobalUint looks up the value of a global UintFlag, returns |  | ||||||
| // 0 if not found |  | ||||||
| func (c *Context) GlobalUint(name string) uint { |  | ||||||
| 	if fs := lookupGlobalFlagSet(name, c); fs != nil { |  | ||||||
| 		return lookupUint(name, fs) |  | ||||||
| 	} |  | ||||||
| 	return 0 |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func lookupUint(name string, set *flag.FlagSet) uint { |  | ||||||
| 	f := set.Lookup(name) |  | ||||||
| 	if f != nil { |  | ||||||
| 		parsed, err := strconv.ParseUint(f.Value.String(), 0, 64) |  | ||||||
| 		if err != nil { |  | ||||||
| 			return 0 |  | ||||||
| 		} |  | ||||||
| 		return uint(parsed) |  | ||||||
| 	} |  | ||||||
| 	return 0 |  | ||||||
| } |  | ||||||
							
								
								
									
										110
									
								
								vendor/github.com/urfave/cli/flag_generic.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										110
									
								
								vendor/github.com/urfave/cli/flag_generic.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,110 @@ | |||||||
|  | package cli | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"flag" | ||||||
|  | 	"fmt" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | // Generic is a generic parseable type identified by a specific flag | ||||||
|  | type Generic interface { | ||||||
|  | 	Set(value string) error | ||||||
|  | 	String() string | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // GenericFlag is a flag with type Generic | ||||||
|  | type GenericFlag struct { | ||||||
|  | 	Name      string | ||||||
|  | 	Usage     string | ||||||
|  | 	EnvVar    string | ||||||
|  | 	FilePath  string | ||||||
|  | 	Required  bool | ||||||
|  | 	Hidden    bool | ||||||
|  | 	TakesFile bool | ||||||
|  | 	Value     Generic | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // String returns a readable representation of this value | ||||||
|  | // (for usage defaults) | ||||||
|  | func (f GenericFlag) String() string { | ||||||
|  | 	return FlagStringer(f) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // GetName returns the name of the flag | ||||||
|  | func (f GenericFlag) GetName() string { | ||||||
|  | 	return f.Name | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // 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 | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // GetUsage returns the usage string for the flag | ||||||
|  | func (f GenericFlag) GetUsage() string { | ||||||
|  | 	return f.Usage | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // 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 { | ||||||
|  | 	if f.Value != nil { | ||||||
|  | 		return f.Value.String() | ||||||
|  | 	} | ||||||
|  | 	return "" | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Apply takes the flagset and calls Set on the generic flag with the value | ||||||
|  | // provided by the user for parsing by the flag | ||||||
|  | // Ignores parsing errors | ||||||
|  | func (f GenericFlag) Apply(set *flag.FlagSet) { | ||||||
|  | 	_ = f.ApplyWithError(set) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // ApplyWithError 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) ApplyWithError(set *flag.FlagSet) error { | ||||||
|  | 	val := f.Value | ||||||
|  | 	if fileEnvVal, ok := flagFromFileEnv(f.FilePath, f.EnvVar); ok { | ||||||
|  | 		if err := val.Set(fileEnvVal); err != nil { | ||||||
|  | 			return fmt.Errorf("could not parse %s as value for flag %s: %s", fileEnvVal, f.Name, err) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	eachName(f.Name, func(name string) { | ||||||
|  | 		set.Var(f.Value, name, f.Usage) | ||||||
|  | 	}) | ||||||
|  |  | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Generic looks up the value of a local GenericFlag, returns | ||||||
|  | // nil if not found | ||||||
|  | func (c *Context) Generic(name string) interface{} { | ||||||
|  | 	return lookupGeneric(name, c.flagSet) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // GlobalGeneric looks up the value of a global GenericFlag, returns | ||||||
|  | // nil if not found | ||||||
|  | func (c *Context) GlobalGeneric(name string) interface{} { | ||||||
|  | 	if fs := lookupGlobalFlagSet(name, c); fs != nil { | ||||||
|  | 		return lookupGeneric(name, fs) | ||||||
|  | 	} | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func lookupGeneric(name string, set *flag.FlagSet) interface{} { | ||||||
|  | 	f := set.Lookup(name) | ||||||
|  | 	if f != nil { | ||||||
|  | 		parsed, err := f.Value, error(nil) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return nil | ||||||
|  | 		} | ||||||
|  | 		return parsed | ||||||
|  | 	} | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
							
								
								
									
										105
									
								
								vendor/github.com/urfave/cli/flag_int.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										105
									
								
								vendor/github.com/urfave/cli/flag_int.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,105 @@ | |||||||
|  | package cli | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"flag" | ||||||
|  | 	"fmt" | ||||||
|  | 	"strconv" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | // IntFlag is a flag with type int | ||||||
|  | type IntFlag struct { | ||||||
|  | 	Name        string | ||||||
|  | 	Usage       string | ||||||
|  | 	EnvVar      string | ||||||
|  | 	FilePath    string | ||||||
|  | 	Required    bool | ||||||
|  | 	Hidden      bool | ||||||
|  | 	Value       int | ||||||
|  | 	Destination *int | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // String returns a readable representation of this value | ||||||
|  | // (for usage defaults) | ||||||
|  | func (f IntFlag) String() string { | ||||||
|  | 	return FlagStringer(f) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // GetName returns the name of the flag | ||||||
|  | func (f IntFlag) GetName() string { | ||||||
|  | 	return f.Name | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // 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 | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // GetUsage returns the usage string for the flag | ||||||
|  | func (f IntFlag) GetUsage() string { | ||||||
|  | 	return f.Usage | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // 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) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Apply populates the flag given the flag set and environment | ||||||
|  | // Ignores errors | ||||||
|  | func (f IntFlag) Apply(set *flag.FlagSet) { | ||||||
|  | 	_ = f.ApplyWithError(set) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // ApplyWithError populates the flag given the flag set and environment | ||||||
|  | func (f IntFlag) ApplyWithError(set *flag.FlagSet) error { | ||||||
|  | 	if envVal, ok := flagFromFileEnv(f.FilePath, f.EnvVar); ok { | ||||||
|  | 		envValInt, err := strconv.ParseInt(envVal, 0, 64) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return fmt.Errorf("could not parse %s as int value for flag %s: %s", envVal, f.Name, err) | ||||||
|  | 		} | ||||||
|  | 		f.Value = int(envValInt) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	eachName(f.Name, func(name string) { | ||||||
|  | 		if f.Destination != nil { | ||||||
|  | 			set.IntVar(f.Destination, name, f.Value, f.Usage) | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
|  | 		set.Int(name, f.Value, f.Usage) | ||||||
|  | 	}) | ||||||
|  |  | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Int looks up the value of a local IntFlag, returns | ||||||
|  | // 0 if not found | ||||||
|  | func (c *Context) Int(name string) int { | ||||||
|  | 	return lookupInt(name, c.flagSet) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // GlobalInt looks up the value of a global IntFlag, returns | ||||||
|  | // 0 if not found | ||||||
|  | func (c *Context) GlobalInt(name string) int { | ||||||
|  | 	if fs := lookupGlobalFlagSet(name, c); fs != nil { | ||||||
|  | 		return lookupInt(name, fs) | ||||||
|  | 	} | ||||||
|  | 	return 0 | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func lookupInt(name string, set *flag.FlagSet) int { | ||||||
|  | 	f := set.Lookup(name) | ||||||
|  | 	if f != nil { | ||||||
|  | 		parsed, err := strconv.ParseInt(f.Value.String(), 0, 64) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return 0 | ||||||
|  | 		} | ||||||
|  | 		return int(parsed) | ||||||
|  | 	} | ||||||
|  | 	return 0 | ||||||
|  | } | ||||||
							
								
								
									
										106
									
								
								vendor/github.com/urfave/cli/flag_int64.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										106
									
								
								vendor/github.com/urfave/cli/flag_int64.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,106 @@ | |||||||
|  | package cli | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"flag" | ||||||
|  | 	"fmt" | ||||||
|  | 	"strconv" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | // Int64Flag is a flag with type int64 | ||||||
|  | type Int64Flag struct { | ||||||
|  | 	Name        string | ||||||
|  | 	Usage       string | ||||||
|  | 	EnvVar      string | ||||||
|  | 	FilePath    string | ||||||
|  | 	Required    bool | ||||||
|  | 	Hidden      bool | ||||||
|  | 	Value       int64 | ||||||
|  | 	Destination *int64 | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // String returns a readable representation of this value | ||||||
|  | // (for usage defaults) | ||||||
|  | func (f Int64Flag) String() string { | ||||||
|  | 	return FlagStringer(f) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // GetName returns the name of the flag | ||||||
|  | func (f Int64Flag) GetName() string { | ||||||
|  | 	return f.Name | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // 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 | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // GetUsage returns the usage string for the flag | ||||||
|  | func (f Int64Flag) GetUsage() string { | ||||||
|  | 	return f.Usage | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // 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) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Apply populates the flag given the flag set and environment | ||||||
|  | // Ignores errors | ||||||
|  | func (f Int64Flag) Apply(set *flag.FlagSet) { | ||||||
|  | 	_ = f.ApplyWithError(set) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // ApplyWithError populates the flag given the flag set and environment | ||||||
|  | func (f Int64Flag) ApplyWithError(set *flag.FlagSet) error { | ||||||
|  | 	if envVal, ok := flagFromFileEnv(f.FilePath, f.EnvVar); ok { | ||||||
|  | 		envValInt, err := strconv.ParseInt(envVal, 0, 64) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return fmt.Errorf("could not parse %s as int value for flag %s: %s", envVal, f.Name, err) | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		f.Value = envValInt | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	eachName(f.Name, func(name string) { | ||||||
|  | 		if f.Destination != nil { | ||||||
|  | 			set.Int64Var(f.Destination, name, f.Value, f.Usage) | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
|  | 		set.Int64(name, f.Value, f.Usage) | ||||||
|  | 	}) | ||||||
|  |  | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Int64 looks up the value of a local Int64Flag, returns | ||||||
|  | // 0 if not found | ||||||
|  | func (c *Context) Int64(name string) int64 { | ||||||
|  | 	return lookupInt64(name, c.flagSet) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // GlobalInt64 looks up the value of a global Int64Flag, returns | ||||||
|  | // 0 if not found | ||||||
|  | func (c *Context) GlobalInt64(name string) int64 { | ||||||
|  | 	if fs := lookupGlobalFlagSet(name, c); fs != nil { | ||||||
|  | 		return lookupInt64(name, fs) | ||||||
|  | 	} | ||||||
|  | 	return 0 | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func lookupInt64(name string, set *flag.FlagSet) int64 { | ||||||
|  | 	f := set.Lookup(name) | ||||||
|  | 	if f != nil { | ||||||
|  | 		parsed, err := strconv.ParseInt(f.Value.String(), 0, 64) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return 0 | ||||||
|  | 		} | ||||||
|  | 		return parsed | ||||||
|  | 	} | ||||||
|  | 	return 0 | ||||||
|  | } | ||||||
							
								
								
									
										141
									
								
								vendor/github.com/urfave/cli/flag_int64_slice.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										141
									
								
								vendor/github.com/urfave/cli/flag_int64_slice.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,141 @@ | |||||||
|  | package cli | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"flag" | ||||||
|  | 	"fmt" | ||||||
|  | 	"strconv" | ||||||
|  | 	"strings" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | // Int64Slice is an opaque type for []int to satisfy flag.Value and flag.Getter | ||||||
|  | type Int64Slice []int64 | ||||||
|  |  | ||||||
|  | // Set parses the value into an integer and appends it to the list of values | ||||||
|  | func (f *Int64Slice) Set(value string) error { | ||||||
|  | 	tmp, err := strconv.ParseInt(value, 10, 64) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 	*f = append(*f, tmp) | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // String returns a readable representation of this value (for usage defaults) | ||||||
|  | func (f *Int64Slice) String() string { | ||||||
|  | 	return fmt.Sprintf("%#v", *f) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Value returns the slice of ints set by this flag | ||||||
|  | func (f *Int64Slice) Value() []int64 { | ||||||
|  | 	return *f | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Get returns the slice of ints set by this flag | ||||||
|  | func (f *Int64Slice) Get() interface{} { | ||||||
|  | 	return *f | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Int64SliceFlag is a flag with type *Int64Slice | ||||||
|  | type Int64SliceFlag struct { | ||||||
|  | 	Name     string | ||||||
|  | 	Usage    string | ||||||
|  | 	EnvVar   string | ||||||
|  | 	FilePath string | ||||||
|  | 	Required bool | ||||||
|  | 	Hidden   bool | ||||||
|  | 	Value    *Int64Slice | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // String returns a readable representation of this value | ||||||
|  | // (for usage defaults) | ||||||
|  | func (f Int64SliceFlag) String() string { | ||||||
|  | 	return FlagStringer(f) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // GetName returns the name of the flag | ||||||
|  | func (f Int64SliceFlag) GetName() string { | ||||||
|  | 	return f.Name | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // 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 { | ||||||
|  | 	return f.Usage | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // 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() | ||||||
|  | 	} | ||||||
|  | 	return "" | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Apply populates the flag given the flag set and environment | ||||||
|  | // Ignores errors | ||||||
|  | func (f Int64SliceFlag) Apply(set *flag.FlagSet) { | ||||||
|  | 	_ = f.ApplyWithError(set) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // ApplyWithError populates the flag given the flag set and environment | ||||||
|  | func (f Int64SliceFlag) ApplyWithError(set *flag.FlagSet) error { | ||||||
|  | 	if envVal, ok := flagFromFileEnv(f.FilePath, f.EnvVar); ok { | ||||||
|  | 		newVal := &Int64Slice{} | ||||||
|  | 		for _, s := range strings.Split(envVal, ",") { | ||||||
|  | 			s = strings.TrimSpace(s) | ||||||
|  | 			if err := newVal.Set(s); err != nil { | ||||||
|  | 				return fmt.Errorf("could not parse %s as int64 slice value for flag %s: %s", envVal, f.Name, err) | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		if f.Value == nil { | ||||||
|  | 			f.Value = newVal | ||||||
|  | 		} else { | ||||||
|  | 			*f.Value = *newVal | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	eachName(f.Name, func(name string) { | ||||||
|  | 		if f.Value == nil { | ||||||
|  | 			f.Value = &Int64Slice{} | ||||||
|  | 		} | ||||||
|  | 		set.Var(f.Value, name, f.Usage) | ||||||
|  | 	}) | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // 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) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // GlobalInt64Slice looks up the value of a global Int64SliceFlag, returns | ||||||
|  | // nil if not found | ||||||
|  | func (c *Context) GlobalInt64Slice(name string) []int64 { | ||||||
|  | 	if fs := lookupGlobalFlagSet(name, c); fs != nil { | ||||||
|  | 		return lookupInt64Slice(name, fs) | ||||||
|  | 	} | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func lookupInt64Slice(name string, set *flag.FlagSet) []int64 { | ||||||
|  | 	f := set.Lookup(name) | ||||||
|  | 	if f != nil { | ||||||
|  | 		parsed, err := (f.Value.(*Int64Slice)).Value(), error(nil) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return nil | ||||||
|  | 		} | ||||||
|  | 		return parsed | ||||||
|  | 	} | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
							
								
								
									
										142
									
								
								vendor/github.com/urfave/cli/flag_int_slice.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										142
									
								
								vendor/github.com/urfave/cli/flag_int_slice.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,142 @@ | |||||||
|  | package cli | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"flag" | ||||||
|  | 	"fmt" | ||||||
|  | 	"strconv" | ||||||
|  | 	"strings" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | // IntSlice is an opaque type for []int to satisfy flag.Value and flag.Getter | ||||||
|  | type IntSlice []int | ||||||
|  |  | ||||||
|  | // Set parses the value into an integer and appends it to the list of values | ||||||
|  | func (f *IntSlice) Set(value string) error { | ||||||
|  | 	tmp, err := strconv.Atoi(value) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 	*f = append(*f, tmp) | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // String returns a readable representation of this value (for usage defaults) | ||||||
|  | func (f *IntSlice) String() string { | ||||||
|  | 	return fmt.Sprintf("%#v", *f) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Value returns the slice of ints set by this flag | ||||||
|  | func (f *IntSlice) Value() []int { | ||||||
|  | 	return *f | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Get returns the slice of ints set by this flag | ||||||
|  | func (f *IntSlice) Get() interface{} { | ||||||
|  | 	return *f | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // IntSliceFlag is a flag with type *IntSlice | ||||||
|  | type IntSliceFlag struct { | ||||||
|  | 	Name     string | ||||||
|  | 	Usage    string | ||||||
|  | 	EnvVar   string | ||||||
|  | 	FilePath string | ||||||
|  | 	Required bool | ||||||
|  | 	Hidden   bool | ||||||
|  | 	Value    *IntSlice | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // String returns a readable representation of this value | ||||||
|  | // (for usage defaults) | ||||||
|  | func (f IntSliceFlag) String() string { | ||||||
|  | 	return FlagStringer(f) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // GetName returns the name of the flag | ||||||
|  | func (f IntSliceFlag) GetName() string { | ||||||
|  | 	return f.Name | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // 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 { | ||||||
|  | 	return f.Usage | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // 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() | ||||||
|  | 	} | ||||||
|  | 	return "" | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Apply populates the flag given the flag set and environment | ||||||
|  | // Ignores errors | ||||||
|  | func (f IntSliceFlag) Apply(set *flag.FlagSet) { | ||||||
|  | 	_ = f.ApplyWithError(set) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // ApplyWithError populates the flag given the flag set and environment | ||||||
|  | func (f IntSliceFlag) ApplyWithError(set *flag.FlagSet) error { | ||||||
|  | 	if envVal, ok := flagFromFileEnv(f.FilePath, f.EnvVar); ok { | ||||||
|  | 		newVal := &IntSlice{} | ||||||
|  | 		for _, s := range strings.Split(envVal, ",") { | ||||||
|  | 			s = strings.TrimSpace(s) | ||||||
|  | 			if err := newVal.Set(s); err != nil { | ||||||
|  | 				return fmt.Errorf("could not parse %s as int slice value for flag %s: %s", envVal, f.Name, err) | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		if f.Value == nil { | ||||||
|  | 			f.Value = newVal | ||||||
|  | 		} else { | ||||||
|  | 			*f.Value = *newVal | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	eachName(f.Name, func(name string) { | ||||||
|  | 		if f.Value == nil { | ||||||
|  | 			f.Value = &IntSlice{} | ||||||
|  | 		} | ||||||
|  | 		set.Var(f.Value, name, f.Usage) | ||||||
|  | 	}) | ||||||
|  |  | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // IntSlice looks up the value of a local IntSliceFlag, returns | ||||||
|  | // nil if not found | ||||||
|  | func (c *Context) IntSlice(name string) []int { | ||||||
|  | 	return lookupIntSlice(name, c.flagSet) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // GlobalIntSlice looks up the value of a global IntSliceFlag, returns | ||||||
|  | // nil if not found | ||||||
|  | func (c *Context) GlobalIntSlice(name string) []int { | ||||||
|  | 	if fs := lookupGlobalFlagSet(name, c); fs != nil { | ||||||
|  | 		return lookupIntSlice(name, fs) | ||||||
|  | 	} | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func lookupIntSlice(name string, set *flag.FlagSet) []int { | ||||||
|  | 	f := set.Lookup(name) | ||||||
|  | 	if f != nil { | ||||||
|  | 		parsed, err := (f.Value.(*IntSlice)).Value(), error(nil) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return nil | ||||||
|  | 		} | ||||||
|  | 		return parsed | ||||||
|  | 	} | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
							
								
								
									
										98
									
								
								vendor/github.com/urfave/cli/flag_string.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										98
									
								
								vendor/github.com/urfave/cli/flag_string.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,98 @@ | |||||||
|  | package cli | ||||||
|  |  | ||||||
|  | import "flag" | ||||||
|  |  | ||||||
|  | // StringFlag is a flag with type string | ||||||
|  | type StringFlag struct { | ||||||
|  | 	Name        string | ||||||
|  | 	Usage       string | ||||||
|  | 	EnvVar      string | ||||||
|  | 	FilePath    string | ||||||
|  | 	Required    bool | ||||||
|  | 	Hidden      bool | ||||||
|  | 	TakesFile   bool | ||||||
|  | 	Value       string | ||||||
|  | 	Destination *string | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // String returns a readable representation of this value | ||||||
|  | // (for usage defaults) | ||||||
|  | func (f StringFlag) String() string { | ||||||
|  | 	return FlagStringer(f) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // GetName returns the name of the flag | ||||||
|  | func (f StringFlag) GetName() string { | ||||||
|  | 	return f.Name | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // IsRequired returns whether or not the flag is required | ||||||
|  | func (f StringFlag) IsRequired() bool { | ||||||
|  | 	return f.Required | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // TakesValue returns true of the flag takes a value, otherwise false | ||||||
|  | func (f StringFlag) TakesValue() bool { | ||||||
|  | 	return true | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // GetUsage returns the usage string for the flag | ||||||
|  | func (f StringFlag) GetUsage() string { | ||||||
|  | 	return f.Usage | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // 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 | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Apply populates the flag given the flag set and environment | ||||||
|  | // Ignores errors | ||||||
|  | func (f StringFlag) Apply(set *flag.FlagSet) { | ||||||
|  | 	_ = f.ApplyWithError(set) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // ApplyWithError populates the flag given the flag set and environment | ||||||
|  | func (f StringFlag) ApplyWithError(set *flag.FlagSet) error { | ||||||
|  | 	if envVal, ok := flagFromFileEnv(f.FilePath, f.EnvVar); ok { | ||||||
|  | 		f.Value = envVal | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	eachName(f.Name, func(name string) { | ||||||
|  | 		if f.Destination != nil { | ||||||
|  | 			set.StringVar(f.Destination, name, f.Value, f.Usage) | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
|  | 		set.String(name, f.Value, f.Usage) | ||||||
|  | 	}) | ||||||
|  |  | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // String looks up the value of a local StringFlag, returns | ||||||
|  | // "" if not found | ||||||
|  | func (c *Context) String(name string) string { | ||||||
|  | 	return lookupString(name, c.flagSet) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // GlobalString looks up the value of a global StringFlag, returns | ||||||
|  | // "" if not found | ||||||
|  | func (c *Context) GlobalString(name string) string { | ||||||
|  | 	if fs := lookupGlobalFlagSet(name, c); fs != nil { | ||||||
|  | 		return lookupString(name, fs) | ||||||
|  | 	} | ||||||
|  | 	return "" | ||||||
|  | } | ||||||
|  |  | ||||||
|  | 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 "" | ||||||
|  | 		} | ||||||
|  | 		return parsed | ||||||
|  | 	} | ||||||
|  | 	return "" | ||||||
|  | } | ||||||
							
								
								
									
										138
									
								
								vendor/github.com/urfave/cli/flag_string_slice.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										138
									
								
								vendor/github.com/urfave/cli/flag_string_slice.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,138 @@ | |||||||
|  | package cli | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"flag" | ||||||
|  | 	"fmt" | ||||||
|  | 	"strings" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | // StringSlice is an opaque type for []string to satisfy flag.Value and flag.Getter | ||||||
|  | type StringSlice []string | ||||||
|  |  | ||||||
|  | // Set appends the string value to the list of values | ||||||
|  | func (f *StringSlice) Set(value string) error { | ||||||
|  | 	*f = append(*f, value) | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // String returns a readable representation of this value (for usage defaults) | ||||||
|  | func (f *StringSlice) String() string { | ||||||
|  | 	return fmt.Sprintf("%s", *f) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Value returns the slice of strings set by this flag | ||||||
|  | func (f *StringSlice) Value() []string { | ||||||
|  | 	return *f | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Get returns the slice of strings set by this flag | ||||||
|  | func (f *StringSlice) Get() interface{} { | ||||||
|  | 	return *f | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // StringSliceFlag is a flag with type *StringSlice | ||||||
|  | type StringSliceFlag struct { | ||||||
|  | 	Name      string | ||||||
|  | 	Usage     string | ||||||
|  | 	EnvVar    string | ||||||
|  | 	FilePath  string | ||||||
|  | 	Required  bool | ||||||
|  | 	Hidden    bool | ||||||
|  | 	TakesFile bool | ||||||
|  | 	Value     *StringSlice | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // String returns a readable representation of this value | ||||||
|  | // (for usage defaults) | ||||||
|  | func (f StringSliceFlag) String() string { | ||||||
|  | 	return FlagStringer(f) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // GetName returns the name of the flag | ||||||
|  | func (f StringSliceFlag) GetName() string { | ||||||
|  | 	return f.Name | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // 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 | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // GetUsage returns the usage string for the flag | ||||||
|  | func (f StringSliceFlag) GetUsage() string { | ||||||
|  | 	return f.Usage | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // 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() | ||||||
|  | 	} | ||||||
|  | 	return "" | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Apply populates the flag given the flag set and environment | ||||||
|  | // Ignores errors | ||||||
|  | func (f StringSliceFlag) Apply(set *flag.FlagSet) { | ||||||
|  | 	_ = f.ApplyWithError(set) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // ApplyWithError populates the flag given the flag set and environment | ||||||
|  | func (f StringSliceFlag) ApplyWithError(set *flag.FlagSet) error { | ||||||
|  | 	if envVal, ok := flagFromFileEnv(f.FilePath, f.EnvVar); ok { | ||||||
|  | 		newVal := &StringSlice{} | ||||||
|  | 		for _, s := range strings.Split(envVal, ",") { | ||||||
|  | 			s = strings.TrimSpace(s) | ||||||
|  | 			if err := newVal.Set(s); err != nil { | ||||||
|  | 				return fmt.Errorf("could not parse %s as string value for flag %s: %s", envVal, f.Name, err) | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		if f.Value == nil { | ||||||
|  | 			f.Value = newVal | ||||||
|  | 		} else { | ||||||
|  | 			*f.Value = *newVal | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	eachName(f.Name, func(name string) { | ||||||
|  | 		if f.Value == nil { | ||||||
|  | 			f.Value = &StringSlice{} | ||||||
|  | 		} | ||||||
|  | 		set.Var(f.Value, name, f.Usage) | ||||||
|  | 	}) | ||||||
|  |  | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // StringSlice looks up the value of a local StringSliceFlag, returns | ||||||
|  | // nil if not found | ||||||
|  | func (c *Context) StringSlice(name string) []string { | ||||||
|  | 	return lookupStringSlice(name, c.flagSet) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // GlobalStringSlice looks up the value of a global StringSliceFlag, returns | ||||||
|  | // nil if not found | ||||||
|  | func (c *Context) GlobalStringSlice(name string) []string { | ||||||
|  | 	if fs := lookupGlobalFlagSet(name, c); fs != nil { | ||||||
|  | 		return lookupStringSlice(name, fs) | ||||||
|  | 	} | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func lookupStringSlice(name string, set *flag.FlagSet) []string { | ||||||
|  | 	f := set.Lookup(name) | ||||||
|  | 	if f != nil { | ||||||
|  | 		parsed, err := (f.Value.(*StringSlice)).Value(), error(nil) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return nil | ||||||
|  | 		} | ||||||
|  | 		return parsed | ||||||
|  | 	} | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
							
								
								
									
										106
									
								
								vendor/github.com/urfave/cli/flag_uint.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										106
									
								
								vendor/github.com/urfave/cli/flag_uint.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,106 @@ | |||||||
|  | package cli | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"flag" | ||||||
|  | 	"fmt" | ||||||
|  | 	"strconv" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | // UintFlag is a flag with type uint | ||||||
|  | type UintFlag struct { | ||||||
|  | 	Name        string | ||||||
|  | 	Usage       string | ||||||
|  | 	EnvVar      string | ||||||
|  | 	FilePath    string | ||||||
|  | 	Required    bool | ||||||
|  | 	Hidden      bool | ||||||
|  | 	Value       uint | ||||||
|  | 	Destination *uint | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // String returns a readable representation of this value | ||||||
|  | // (for usage defaults) | ||||||
|  | func (f UintFlag) String() string { | ||||||
|  | 	return FlagStringer(f) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // GetName returns the name of the flag | ||||||
|  | func (f UintFlag) GetName() string { | ||||||
|  | 	return f.Name | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // 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 | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // GetUsage returns the usage string for the flag | ||||||
|  | func (f UintFlag) GetUsage() string { | ||||||
|  | 	return f.Usage | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Apply populates the flag given the flag set and environment | ||||||
|  | // Ignores errors | ||||||
|  | func (f UintFlag) Apply(set *flag.FlagSet) { | ||||||
|  | 	_ = f.ApplyWithError(set) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // ApplyWithError populates the flag given the flag set and environment | ||||||
|  | func (f UintFlag) ApplyWithError(set *flag.FlagSet) error { | ||||||
|  | 	if envVal, ok := flagFromFileEnv(f.FilePath, f.EnvVar); ok { | ||||||
|  | 		envValInt, err := strconv.ParseUint(envVal, 0, 64) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return fmt.Errorf("could not parse %s as uint value for flag %s: %s", envVal, f.Name, err) | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		f.Value = uint(envValInt) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	eachName(f.Name, func(name string) { | ||||||
|  | 		if f.Destination != nil { | ||||||
|  | 			set.UintVar(f.Destination, name, f.Value, f.Usage) | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
|  | 		set.Uint(name, f.Value, f.Usage) | ||||||
|  | 	}) | ||||||
|  |  | ||||||
|  | 	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) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Uint looks up the value of a local UintFlag, returns | ||||||
|  | // 0 if not found | ||||||
|  | func (c *Context) Uint(name string) uint { | ||||||
|  | 	return lookupUint(name, c.flagSet) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // GlobalUint looks up the value of a global UintFlag, returns | ||||||
|  | // 0 if not found | ||||||
|  | func (c *Context) GlobalUint(name string) uint { | ||||||
|  | 	if fs := lookupGlobalFlagSet(name, c); fs != nil { | ||||||
|  | 		return lookupUint(name, fs) | ||||||
|  | 	} | ||||||
|  | 	return 0 | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func lookupUint(name string, set *flag.FlagSet) uint { | ||||||
|  | 	f := set.Lookup(name) | ||||||
|  | 	if f != nil { | ||||||
|  | 		parsed, err := strconv.ParseUint(f.Value.String(), 0, 64) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return 0 | ||||||
|  | 		} | ||||||
|  | 		return uint(parsed) | ||||||
|  | 	} | ||||||
|  | 	return 0 | ||||||
|  | } | ||||||
							
								
								
									
										106
									
								
								vendor/github.com/urfave/cli/flag_uint64.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										106
									
								
								vendor/github.com/urfave/cli/flag_uint64.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,106 @@ | |||||||
|  | package cli | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"flag" | ||||||
|  | 	"fmt" | ||||||
|  | 	"strconv" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | // Uint64Flag is a flag with type uint64 | ||||||
|  | type Uint64Flag struct { | ||||||
|  | 	Name        string | ||||||
|  | 	Usage       string | ||||||
|  | 	EnvVar      string | ||||||
|  | 	FilePath    string | ||||||
|  | 	Required    bool | ||||||
|  | 	Hidden      bool | ||||||
|  | 	Value       uint64 | ||||||
|  | 	Destination *uint64 | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // String returns a readable representation of this value | ||||||
|  | // (for usage defaults) | ||||||
|  | func (f Uint64Flag) String() string { | ||||||
|  | 	return FlagStringer(f) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // GetName returns the name of the flag | ||||||
|  | func (f Uint64Flag) GetName() string { | ||||||
|  | 	return f.Name | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // 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 | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // GetUsage returns the usage string for the flag | ||||||
|  | func (f Uint64Flag) GetUsage() string { | ||||||
|  | 	return f.Usage | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // 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) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Apply populates the flag given the flag set and environment | ||||||
|  | // Ignores errors | ||||||
|  | func (f Uint64Flag) Apply(set *flag.FlagSet) { | ||||||
|  | 	_ = f.ApplyWithError(set) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // ApplyWithError populates the flag given the flag set and environment | ||||||
|  | func (f Uint64Flag) ApplyWithError(set *flag.FlagSet) error { | ||||||
|  | 	if envVal, ok := flagFromFileEnv(f.FilePath, f.EnvVar); ok { | ||||||
|  | 		envValInt, err := strconv.ParseUint(envVal, 0, 64) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return fmt.Errorf("could not parse %s as uint64 value for flag %s: %s", envVal, f.Name, err) | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		f.Value = envValInt | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	eachName(f.Name, func(name string) { | ||||||
|  | 		if f.Destination != nil { | ||||||
|  | 			set.Uint64Var(f.Destination, name, f.Value, f.Usage) | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
|  | 		set.Uint64(name, f.Value, f.Usage) | ||||||
|  | 	}) | ||||||
|  |  | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Uint64 looks up the value of a local Uint64Flag, returns | ||||||
|  | // 0 if not found | ||||||
|  | func (c *Context) Uint64(name string) uint64 { | ||||||
|  | 	return lookupUint64(name, c.flagSet) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // GlobalUint64 looks up the value of a global Uint64Flag, returns | ||||||
|  | // 0 if not found | ||||||
|  | func (c *Context) GlobalUint64(name string) uint64 { | ||||||
|  | 	if fs := lookupGlobalFlagSet(name, c); fs != nil { | ||||||
|  | 		return lookupUint64(name, fs) | ||||||
|  | 	} | ||||||
|  | 	return 0 | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func lookupUint64(name string, set *flag.FlagSet) uint64 { | ||||||
|  | 	f := set.Lookup(name) | ||||||
|  | 	if f != nil { | ||||||
|  | 		parsed, err := strconv.ParseUint(f.Value.String(), 0, 64) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return 0 | ||||||
|  | 		} | ||||||
|  | 		return parsed | ||||||
|  | 	} | ||||||
|  | 	return 0 | ||||||
|  | } | ||||||
							
								
								
									
										16
									
								
								vendor/github.com/urfave/cli/funcs.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										16
									
								
								vendor/github.com/urfave/cli/funcs.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -23,6 +23,22 @@ type CommandNotFoundFunc func(*Context, string) | |||||||
| // is displayed and the execution is interrupted. | // is displayed and the execution is interrupted. | ||||||
| type OnUsageErrorFunc func(context *Context, err error, isSubcommand bool) error | type OnUsageErrorFunc func(context *Context, err error, isSubcommand bool) error | ||||||
|  |  | ||||||
|  | // 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) | ||||||
|  |  | ||||||
| // FlagStringFunc is used by the help generation to display a flag, which is | // FlagStringFunc is used by the help generation to display a flag, which is | ||||||
| // expected to be a single line. | // expected to be a single line. | ||||||
| type FlagStringFunc func(Flag) string | type FlagStringFunc func(Flag) string | ||||||
|  |  | ||||||
|  | // FlagNamePrefixFunc is used by the default FlagStringFunc to create prefix | ||||||
|  | // text for a flag's full name. | ||||||
|  | type FlagNamePrefixFunc func(fullName, placeholder string) string | ||||||
|  |  | ||||||
|  | // FlagEnvHintFunc is used by the default FlagStringFunc to annotate flag help | ||||||
|  | // with the environment variable details. | ||||||
|  | type FlagEnvHintFunc func(envVar, str string) string | ||||||
|  |  | ||||||
|  | // FlagFileHintFunc is used by the default FlagStringFunc to annotate flag help | ||||||
|  | // with the file path details. | ||||||
|  | type FlagFileHintFunc func(filePath, str string) string | ||||||
|   | |||||||
							
								
								
									
										255
									
								
								vendor/github.com/urfave/cli/generate-flag-types
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										255
									
								
								vendor/github.com/urfave/cli/generate-flag-types
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,255 +0,0 @@ | |||||||
| #!/usr/bin/env python |  | ||||||
| """ |  | ||||||
| The flag types that ship with the cli library have many things in common, and |  | ||||||
| so we can take advantage of the `go generate` command to create much of the |  | ||||||
| source code from a list of definitions.  These definitions attempt to cover |  | ||||||
| the parts that vary between flag types, and should evolve as needed. |  | ||||||
|  |  | ||||||
| An example of the minimum definition needed is: |  | ||||||
|  |  | ||||||
|     { |  | ||||||
|       "name": "SomeType", |  | ||||||
|       "type": "sometype", |  | ||||||
|       "context_default": "nil" |  | ||||||
|     } |  | ||||||
|  |  | ||||||
| In this example, the code generated for the `cli` package will include a type |  | ||||||
| named `SomeTypeFlag` that is expected to wrap a value of type `sometype`. |  | ||||||
| Fetching values by name via `*cli.Context` will default to a value of `nil`. |  | ||||||
|  |  | ||||||
| A more complete, albeit somewhat redundant, example showing all available |  | ||||||
| definition keys is: |  | ||||||
|  |  | ||||||
|     { |  | ||||||
|       "name": "VeryMuchType", |  | ||||||
|       "type": "*VeryMuchType", |  | ||||||
|       "value": true, |  | ||||||
|       "dest": false, |  | ||||||
|       "doctail": " which really only wraps a []float64, oh well!", |  | ||||||
|       "context_type": "[]float64", |  | ||||||
|       "context_default": "nil", |  | ||||||
|       "parser": "parseVeryMuchType(f.Value.String())", |  | ||||||
|       "parser_cast": "[]float64(parsed)" |  | ||||||
|     } |  | ||||||
|  |  | ||||||
| The meaning of each field is as follows: |  | ||||||
|  |  | ||||||
|                name (string) - The type "name", which will be suffixed with |  | ||||||
|                                `Flag` when generating the type definition |  | ||||||
|                                for `cli` and the wrapper type for `altsrc` |  | ||||||
|                type (string) - The type that the generated `Flag` type for `cli` |  | ||||||
|                                is expected to "contain" as its `.Value` member |  | ||||||
|                 value (bool) - Should the generated `cli` type have a `Value` |  | ||||||
|                                member? |  | ||||||
|                  dest (bool) - Should the generated `cli` type support a |  | ||||||
|                                destination pointer? |  | ||||||
|             doctail (string) - Additional docs for the `cli` flag type comment |  | ||||||
|        context_type (string) - The literal type used in the `*cli.Context` |  | ||||||
|                                reader func signature |  | ||||||
|     context_default (string) - The literal value used as the default by the |  | ||||||
|                                `*cli.Context` reader funcs when no value is |  | ||||||
|                                present |  | ||||||
|              parser (string) - Literal code used to parse the flag `f`, |  | ||||||
|                                expected to have a return signature of |  | ||||||
|                                (value, error) |  | ||||||
|         parser_cast (string) - Literal code used to cast the `parsed` value |  | ||||||
|                                returned from the `parser` code |  | ||||||
| """ |  | ||||||
|  |  | ||||||
| from __future__ import print_function, unicode_literals |  | ||||||
|  |  | ||||||
| import argparse |  | ||||||
| import json |  | ||||||
| import os |  | ||||||
| import subprocess |  | ||||||
| import sys |  | ||||||
| import tempfile |  | ||||||
| import textwrap |  | ||||||
|  |  | ||||||
|  |  | ||||||
| class _FancyFormatter(argparse.ArgumentDefaultsHelpFormatter, |  | ||||||
|                       argparse.RawDescriptionHelpFormatter): |  | ||||||
|     pass |  | ||||||
|  |  | ||||||
|  |  | ||||||
| def main(sysargs=sys.argv[:]): |  | ||||||
|     parser = argparse.ArgumentParser( |  | ||||||
|         description='Generate flag type code!', |  | ||||||
|         formatter_class=_FancyFormatter) |  | ||||||
|     parser.add_argument( |  | ||||||
|         'package', |  | ||||||
|         type=str, default='cli', choices=_WRITEFUNCS.keys(), |  | ||||||
|         help='Package for which flag types will be generated' |  | ||||||
|     ) |  | ||||||
|     parser.add_argument( |  | ||||||
|         '-i', '--in-json', |  | ||||||
|         type=argparse.FileType('r'), |  | ||||||
|         default=sys.stdin, |  | ||||||
|         help='Input JSON file which defines each type to be generated' |  | ||||||
|     ) |  | ||||||
|     parser.add_argument( |  | ||||||
|         '-o', '--out-go', |  | ||||||
|         type=argparse.FileType('w'), |  | ||||||
|         default=sys.stdout, |  | ||||||
|         help='Output file/stream to which generated source will be written' |  | ||||||
|     ) |  | ||||||
|     parser.epilog = __doc__ |  | ||||||
|  |  | ||||||
|     args = parser.parse_args(sysargs[1:]) |  | ||||||
|     _generate_flag_types(_WRITEFUNCS[args.package], args.out_go, args.in_json) |  | ||||||
|     return 0 |  | ||||||
|  |  | ||||||
|  |  | ||||||
| def _generate_flag_types(writefunc, output_go, input_json): |  | ||||||
|     types = json.load(input_json) |  | ||||||
|  |  | ||||||
|     tmp = tempfile.NamedTemporaryFile(suffix='.go', delete=False) |  | ||||||
|     writefunc(tmp, types) |  | ||||||
|     tmp.close() |  | ||||||
|  |  | ||||||
|     new_content = subprocess.check_output( |  | ||||||
|         ['goimports', tmp.name] |  | ||||||
|     ).decode('utf-8') |  | ||||||
|  |  | ||||||
|     print(new_content, file=output_go, end='') |  | ||||||
|     output_go.flush() |  | ||||||
|     os.remove(tmp.name) |  | ||||||
|  |  | ||||||
|  |  | ||||||
| def _set_typedef_defaults(typedef): |  | ||||||
|     typedef.setdefault('doctail', '') |  | ||||||
|     typedef.setdefault('context_type', typedef['type']) |  | ||||||
|     typedef.setdefault('dest', True) |  | ||||||
|     typedef.setdefault('value', True) |  | ||||||
|     typedef.setdefault('parser', 'f.Value, error(nil)') |  | ||||||
|     typedef.setdefault('parser_cast', 'parsed') |  | ||||||
|  |  | ||||||
|  |  | ||||||
| def _write_cli_flag_types(outfile, types): |  | ||||||
|     _fwrite(outfile, """\ |  | ||||||
|         package cli |  | ||||||
|  |  | ||||||
|         // WARNING: This file is generated! |  | ||||||
|  |  | ||||||
|         """) |  | ||||||
|  |  | ||||||
|     for typedef in types: |  | ||||||
|         _set_typedef_defaults(typedef) |  | ||||||
|  |  | ||||||
|         _fwrite(outfile, """\ |  | ||||||
|         // {name}Flag is a flag with type {type}{doctail} |  | ||||||
|         type {name}Flag struct {{ |  | ||||||
|             Name string |  | ||||||
|             Usage string |  | ||||||
|             EnvVar string |  | ||||||
|             Hidden bool |  | ||||||
|         """.format(**typedef)) |  | ||||||
|  |  | ||||||
|         if typedef['value']: |  | ||||||
|             _fwrite(outfile, """\ |  | ||||||
|             Value {type} |  | ||||||
|             """.format(**typedef)) |  | ||||||
|  |  | ||||||
|         if typedef['dest']: |  | ||||||
|             _fwrite(outfile, """\ |  | ||||||
|             Destination *{type} |  | ||||||
|             """.format(**typedef)) |  | ||||||
|  |  | ||||||
|         _fwrite(outfile, "\n}\n\n") |  | ||||||
|  |  | ||||||
|         _fwrite(outfile, """\ |  | ||||||
|             // String returns a readable representation of this value |  | ||||||
|             // (for usage defaults) |  | ||||||
|             func (f {name}Flag) String() string {{ |  | ||||||
|                 return FlagStringer(f) |  | ||||||
|             }} |  | ||||||
|  |  | ||||||
|             // GetName returns the name of the flag |  | ||||||
|             func (f {name}Flag) GetName() string {{ |  | ||||||
|                 return f.Name |  | ||||||
|             }} |  | ||||||
|  |  | ||||||
|             // {name} looks up the value of a local {name}Flag, returns |  | ||||||
|             // {context_default} if not found |  | ||||||
|             func (c *Context) {name}(name string) {context_type} {{ |  | ||||||
|                 return lookup{name}(name, c.flagSet) |  | ||||||
|             }} |  | ||||||
|  |  | ||||||
|             // Global{name} looks up the value of a global {name}Flag, returns |  | ||||||
|             // {context_default} if not found |  | ||||||
|             func (c *Context) Global{name}(name string) {context_type} {{ |  | ||||||
|                 if fs := lookupGlobalFlagSet(name, c); fs != nil {{ |  | ||||||
|                     return lookup{name}(name, fs) |  | ||||||
|                 }} |  | ||||||
|                 return {context_default} |  | ||||||
|             }} |  | ||||||
|  |  | ||||||
|             func lookup{name}(name string, set *flag.FlagSet) {context_type} {{ |  | ||||||
|                 f := set.Lookup(name) |  | ||||||
|                 if f != nil {{ |  | ||||||
|                     parsed, err := {parser} |  | ||||||
|                     if err != nil {{ |  | ||||||
|                         return {context_default} |  | ||||||
|                     }} |  | ||||||
|                     return {parser_cast} |  | ||||||
|                 }} |  | ||||||
|                 return {context_default} |  | ||||||
|             }} |  | ||||||
|             """.format(**typedef)) |  | ||||||
|  |  | ||||||
|  |  | ||||||
| def _write_altsrc_flag_types(outfile, types): |  | ||||||
|     _fwrite(outfile, """\ |  | ||||||
|         package altsrc |  | ||||||
|  |  | ||||||
|         import ( |  | ||||||
|             "gopkg.in/urfave/cli.v1" |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
|         // WARNING: This file is generated! |  | ||||||
|  |  | ||||||
|         """) |  | ||||||
|  |  | ||||||
|     for typedef in types: |  | ||||||
|         _set_typedef_defaults(typedef) |  | ||||||
|  |  | ||||||
|         _fwrite(outfile, """\ |  | ||||||
|         // {name}Flag is the flag type that wraps cli.{name}Flag to allow |  | ||||||
|         // for other values to be specified |  | ||||||
|         type {name}Flag struct {{ |  | ||||||
|             cli.{name}Flag |  | ||||||
|             set *flag.FlagSet |  | ||||||
|         }} |  | ||||||
|  |  | ||||||
|         // New{name}Flag creates a new {name}Flag |  | ||||||
|         func New{name}Flag(fl cli.{name}Flag) *{name}Flag {{ |  | ||||||
|             return &{name}Flag{{{name}Flag: fl, set: nil}} |  | ||||||
|         }} |  | ||||||
|  |  | ||||||
|         // Apply saves the flagSet for later usage calls, then calls the |  | ||||||
|         // wrapped {name}Flag.Apply |  | ||||||
|         func (f *{name}Flag) Apply(set *flag.FlagSet) {{ |  | ||||||
|             f.set = set |  | ||||||
|             f.{name}Flag.Apply(set) |  | ||||||
|         }} |  | ||||||
|  |  | ||||||
|         // ApplyWithError saves the flagSet for later usage calls, then calls the |  | ||||||
|         // wrapped {name}Flag.ApplyWithError |  | ||||||
|         func (f *{name}Flag) ApplyWithError(set *flag.FlagSet) error {{ |  | ||||||
|             f.set = set |  | ||||||
|             return f.{name}Flag.ApplyWithError(set) |  | ||||||
|         }} |  | ||||||
|         """.format(**typedef)) |  | ||||||
|  |  | ||||||
|  |  | ||||||
| def _fwrite(outfile, text): |  | ||||||
|     print(textwrap.dedent(text), end='', file=outfile) |  | ||||||
|  |  | ||||||
|  |  | ||||||
| _WRITEFUNCS = { |  | ||||||
|     'cli': _write_cli_flag_types, |  | ||||||
|     'altsrc': _write_altsrc_flag_types |  | ||||||
| } |  | ||||||
|  |  | ||||||
| if __name__ == '__main__': |  | ||||||
|     sys.exit(main()) |  | ||||||
							
								
								
									
										9
									
								
								vendor/github.com/urfave/cli/go.mod
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								vendor/github.com/urfave/cli/go.mod
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | |||||||
|  | module github.com/urfave/cli | ||||||
|  |  | ||||||
|  | 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.2 | ||||||
|  | ) | ||||||
							
								
								
									
										14
									
								
								vendor/github.com/urfave/cli/go.sum
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								vendor/github.com/urfave/cli/go.sum
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,14 @@ | |||||||
|  | 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.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= | ||||||
|  | gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= | ||||||
							
								
								
									
										225
									
								
								vendor/github.com/urfave/cli/help.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										225
									
								
								vendor/github.com/urfave/cli/help.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -7,77 +7,9 @@ import ( | |||||||
| 	"strings" | 	"strings" | ||||||
| 	"text/tabwriter" | 	"text/tabwriter" | ||||||
| 	"text/template" | 	"text/template" | ||||||
|  | 	"unicode/utf8" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| // 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}} |  | ||||||
|  |  | ||||||
| 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}} |  | ||||||
|  |  | ||||||
| VERSION: |  | ||||||
|    {{.Version}}{{end}}{{end}}{{if .Description}} |  | ||||||
|  |  | ||||||
| DESCRIPTION: |  | ||||||
|    {{.Description}}{{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}} |  | ||||||
|  |  | ||||||
| COMMANDS:{{range .VisibleCategories}}{{if .Name}} |  | ||||||
|    {{.Name}}:{{end}}{{range .VisibleCommands}} |  | ||||||
|      {{join .Names ", "}}{{"\t"}}{{.Usage}}{{end}}{{end}}{{end}}{{if .VisibleFlags}} |  | ||||||
|  |  | ||||||
| GLOBAL OPTIONS: |  | ||||||
|    {{range $index, $option := .VisibleFlags}}{{if $index}} |  | ||||||
|    {{end}}{{$option}}{{end}}{{end}}{{if .Copyright}} |  | ||||||
|  |  | ||||||
| COPYRIGHT: |  | ||||||
|    {{.Copyright}}{{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}} |  | ||||||
|  |  | ||||||
| USAGE: |  | ||||||
|    {{if .UsageText}}{{.UsageText}}{{else}}{{.HelpName}}{{if .VisibleFlags}} [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{end}}{{if .Category}} |  | ||||||
|  |  | ||||||
| CATEGORY: |  | ||||||
|    {{.Category}}{{end}}{{if .Description}} |  | ||||||
|  |  | ||||||
| DESCRIPTION: |  | ||||||
|    {{.Description}}{{end}}{{if .VisibleFlags}} |  | ||||||
|  |  | ||||||
| OPTIONS: |  | ||||||
|    {{range .VisibleFlags}}{{.}} |  | ||||||
|    {{end}}{{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}} - {{if .Description}}{{.Description}}{{else}}{{.Usage}}{{end}} |  | ||||||
|  |  | ||||||
| USAGE: |  | ||||||
|    {{if .UsageText}}{{.UsageText}}{{else}}{{.HelpName}} command{{if .VisibleFlags}} [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{end}} |  | ||||||
|  |  | ||||||
| COMMANDS:{{range .VisibleCategories}}{{if .Name}} |  | ||||||
|    {{.Name}}:{{end}}{{range .VisibleCommands}} |  | ||||||
|      {{join .Names ", "}}{{"\t"}}{{.Usage}}{{end}} |  | ||||||
| {{end}}{{if .VisibleFlags}} |  | ||||||
| OPTIONS: |  | ||||||
|    {{range .VisibleFlags}}{{.}} |  | ||||||
|    {{end}}{{end}} |  | ||||||
| ` |  | ||||||
|  |  | ||||||
| var helpCommand = Command{ | var helpCommand = Command{ | ||||||
| 	Name:      "help", | 	Name:      "help", | ||||||
| 	Aliases:   []string{"h"}, | 	Aliases:   []string{"h"}, | ||||||
| @@ -89,7 +21,7 @@ var helpCommand = Command{ | |||||||
| 			return ShowCommandHelp(c, args.First()) | 			return ShowCommandHelp(c, args.First()) | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		ShowAppHelp(c) | 		_ = ShowAppHelp(c) | ||||||
| 		return nil | 		return nil | ||||||
| 	}, | 	}, | ||||||
| } | } | ||||||
| @@ -115,13 +47,18 @@ type helpPrinter func(w io.Writer, templ string, data interface{}) | |||||||
| // Prints help for the App or Command with custom template function. | // Prints help for the App or Command with custom template function. | ||||||
| type helpPrinterCustom func(w io.Writer, templ string, data interface{}, customFunc map[string]interface{}) | type helpPrinterCustom func(w io.Writer, templ string, data interface{}, customFunc map[string]interface{}) | ||||||
|  |  | ||||||
| // HelpPrinter is a function that writes the help output. If not set a default | // HelpPrinter is a function that writes the help output. If not set explicitly, | ||||||
| // is used. The function signature is: | // this calls HelpPrinterCustom using only the default template functions. | ||||||
| // func(w io.Writer, templ string, data interface{}) | // | ||||||
|  | // If custom logic for printing help is required, this function can be | ||||||
|  | // overridden. If the ExtraInfo field is defined on an App, this function | ||||||
|  | // should not be modified, as HelpPrinterCustom will be used directly in order | ||||||
|  | // to capture the extra information. | ||||||
| var HelpPrinter helpPrinter = printHelp | var HelpPrinter helpPrinter = printHelp | ||||||
|  |  | ||||||
| // HelpPrinterCustom is same as HelpPrinter but | // HelpPrinterCustom is a function that writes the help output. It is used as | ||||||
| // takes a custom function for template function map. | // the default implementation of HelpPrinter, and may be called directly if | ||||||
|  | // the ExtraInfo field is set on an App. | ||||||
| var HelpPrinterCustom helpPrinterCustom = printHelpCustom | var HelpPrinterCustom helpPrinterCustom = printHelpCustom | ||||||
|  |  | ||||||
| // VersionPrinter prints the version for the App | // VersionPrinter prints the version for the App | ||||||
| @@ -129,43 +66,122 @@ var VersionPrinter = printVersion | |||||||
|  |  | ||||||
| // ShowAppHelpAndExit - Prints the list of subcommands for the app and exits with exit code. | // ShowAppHelpAndExit - Prints the list of subcommands for the app and exits with exit code. | ||||||
| func ShowAppHelpAndExit(c *Context, exitCode int) { | func ShowAppHelpAndExit(c *Context, exitCode int) { | ||||||
| 	ShowAppHelp(c) | 	_ = ShowAppHelp(c) | ||||||
| 	os.Exit(exitCode) | 	os.Exit(exitCode) | ||||||
| } | } | ||||||
|  |  | ||||||
| // ShowAppHelp is an action that displays the help. | // ShowAppHelp is an action that displays the help. | ||||||
| func ShowAppHelp(c *Context) (err error) { | func ShowAppHelp(c *Context) error { | ||||||
| 	if c.App.CustomAppHelpTemplate == "" { | 	template := c.App.CustomAppHelpTemplate | ||||||
| 		HelpPrinter(c.App.Writer, AppHelpTemplate, c.App) | 	if template == "" { | ||||||
| 		return | 		template = AppHelpTemplate | ||||||
| 	} | 	} | ||||||
| 	customAppData := func() map[string]interface{} { |  | ||||||
| 	if c.App.ExtraInfo == nil { | 	if c.App.ExtraInfo == nil { | ||||||
|  | 		HelpPrinter(c.App.Writer, template, c.App) | ||||||
| 		return nil | 		return nil | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	customAppData := func() map[string]interface{} { | ||||||
| 		return map[string]interface{}{ | 		return map[string]interface{}{ | ||||||
| 			"ExtraInfo": c.App.ExtraInfo, | 			"ExtraInfo": c.App.ExtraInfo, | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	HelpPrinterCustom(c.App.Writer, c.App.CustomAppHelpTemplate, c.App, customAppData()) | 	HelpPrinterCustom(c.App.Writer, template, c.App, customAppData()) | ||||||
|  |  | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
|  |  | ||||||
| // DefaultAppComplete prints the list of subcommands as the default app completion method | // DefaultAppComplete prints the list of subcommands as the default app completion method | ||||||
| func DefaultAppComplete(c *Context) { | func DefaultAppComplete(c *Context) { | ||||||
| 	for _, command := range c.App.Commands { | 	DefaultCompleteWithFlags(nil)(c) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func printCommandSuggestions(commands []Command, writer io.Writer) { | ||||||
|  | 	for _, command := range commands { | ||||||
| 		if command.Hidden { | 		if command.Hidden { | ||||||
| 			continue | 			continue | ||||||
| 		} | 		} | ||||||
|  | 		if os.Getenv("_CLI_ZSH_AUTOCOMPLETE_HACK") == "1" { | ||||||
| 			for _, name := range command.Names() { | 			for _, name := range command.Names() { | ||||||
| 			fmt.Fprintln(c.App.Writer, name) | 				_, _ = fmt.Fprintf(writer, "%s:%s\n", name, command.Usage) | ||||||
|  | 			} | ||||||
|  | 		} else { | ||||||
|  | 			for _, name := range command.Names() { | ||||||
|  | 				_, _ = fmt.Fprintf(writer, "%s\n", name) | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func cliArgContains(flagName string) bool { | ||||||
|  | 	for _, name := range strings.Split(flagName, ",") { | ||||||
|  | 		name = strings.TrimSpace(name) | ||||||
|  | 		count := utf8.RuneCountInString(name) | ||||||
|  | 		if count > 2 { | ||||||
|  | 			count = 2 | ||||||
|  | 		} | ||||||
|  | 		flag := fmt.Sprintf("%s%s", strings.Repeat("-", count), name) | ||||||
|  | 		for _, a := range os.Args { | ||||||
|  | 			if a == flag { | ||||||
|  | 				return true | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return false | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func printFlagSuggestions(lastArg string, flags []Flag, writer io.Writer) { | ||||||
|  | 	cur := strings.TrimPrefix(lastArg, "-") | ||||||
|  | 	cur = strings.TrimPrefix(cur, "-") | ||||||
|  | 	for _, flag := range flags { | ||||||
|  | 		if bflag, ok := flag.(BoolFlag); ok && bflag.Hidden { | ||||||
|  | 			continue | ||||||
|  | 		} | ||||||
|  | 		for _, name := range strings.Split(flag.GetName(), ",") { | ||||||
|  | 			name = strings.TrimSpace(name) | ||||||
|  | 			// this will get total count utf8 letters in flag name | ||||||
|  | 			count := utf8.RuneCountInString(name) | ||||||
|  | 			if count > 2 { | ||||||
|  | 				count = 2 // resuse this count to generate single - or -- in flag completion | ||||||
|  | 			} | ||||||
|  | 			// if flag name has more than one utf8 letter and last argument in cli has -- prefix then | ||||||
|  | 			// skip flag completion for short flags example -v or -x | ||||||
|  | 			if strings.HasPrefix(lastArg, "--") && count == 1 { | ||||||
|  | 				continue | ||||||
|  | 			} | ||||||
|  | 			// match if last argument matches this flag and it is not repeated | ||||||
|  | 			if strings.HasPrefix(name, cur) && cur != name && !cliArgContains(flag.GetName()) { | ||||||
|  | 				flagCompletion := fmt.Sprintf("%s%s", strings.Repeat("-", count), name) | ||||||
|  | 				_, _ = fmt.Fprintln(writer, flagCompletion) | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func DefaultCompleteWithFlags(cmd *Command) func(c *Context) { | ||||||
|  | 	return func(c *Context) { | ||||||
|  | 		if len(os.Args) > 2 { | ||||||
|  | 			lastArg := os.Args[len(os.Args)-2] | ||||||
|  | 			if strings.HasPrefix(lastArg, "-") { | ||||||
|  | 				printFlagSuggestions(lastArg, c.App.Flags, c.App.Writer) | ||||||
|  | 				if cmd != nil { | ||||||
|  | 					printFlagSuggestions(lastArg, cmd.Flags, c.App.Writer) | ||||||
|  | 				} | ||||||
|  | 				return | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		if cmd != nil { | ||||||
|  | 			printCommandSuggestions(cmd.Subcommands, c.App.Writer) | ||||||
|  | 		} else { | ||||||
|  | 			printCommandSuggestions(c.App.Commands, c.App.Writer) | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| // ShowCommandHelpAndExit - exits with code after showing help | // ShowCommandHelpAndExit - exits with code after showing help | ||||||
| func ShowCommandHelpAndExit(c *Context, command string, code int) { | func ShowCommandHelpAndExit(c *Context, command string, code int) { | ||||||
| 	ShowCommandHelp(c, command) | 	_ = ShowCommandHelp(c, command) | ||||||
| 	os.Exit(code) | 	os.Exit(code) | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -179,11 +195,13 @@ func ShowCommandHelp(ctx *Context, command string) error { | |||||||
|  |  | ||||||
| 	for _, c := range ctx.App.Commands { | 	for _, c := range ctx.App.Commands { | ||||||
| 		if c.HasName(command) { | 		if c.HasName(command) { | ||||||
| 			if c.CustomHelpTemplate != "" { | 			templ := c.CustomHelpTemplate | ||||||
| 				HelpPrinterCustom(ctx.App.Writer, c.CustomHelpTemplate, c, nil) | 			if templ == "" { | ||||||
| 			} else { | 				templ = CommandHelpTemplate | ||||||
| 				HelpPrinter(ctx.App.Writer, CommandHelpTemplate, c) |  | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
|  | 			HelpPrinter(ctx.App.Writer, templ, c) | ||||||
|  |  | ||||||
| 			return nil | 			return nil | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| @@ -207,7 +225,7 @@ func ShowVersion(c *Context) { | |||||||
| } | } | ||||||
|  |  | ||||||
| func printVersion(c *Context) { | func printVersion(c *Context) { | ||||||
| 	fmt.Fprintf(c.App.Writer, "%v version %v\n", c.App.Name, c.App.Version) | 	_, _ = fmt.Fprintf(c.App.Writer, "%v version %v\n", c.App.Name, c.App.Version) | ||||||
| } | } | ||||||
|  |  | ||||||
| // ShowCompletions prints the lists of commands within a given context | // ShowCompletions prints the lists of commands within a given context | ||||||
| @@ -221,20 +239,27 @@ func ShowCompletions(c *Context) { | |||||||
| // ShowCommandCompletions prints the custom completions for a given command | // ShowCommandCompletions prints the custom completions for a given command | ||||||
| func ShowCommandCompletions(ctx *Context, command string) { | func ShowCommandCompletions(ctx *Context, command string) { | ||||||
| 	c := ctx.App.Command(command) | 	c := ctx.App.Command(command) | ||||||
| 	if c != nil && c.BashComplete != nil { | 	if c != nil { | ||||||
|  | 		if c.BashComplete != nil { | ||||||
| 			c.BashComplete(ctx) | 			c.BashComplete(ctx) | ||||||
|  | 		} else { | ||||||
|  | 			DefaultCompleteWithFlags(c)(ctx) | ||||||
| 		} | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
| } | } | ||||||
|  |  | ||||||
| func printHelpCustom(out io.Writer, templ string, data interface{}, customFunc map[string]interface{}) { | // printHelpCustom is the default implementation of HelpPrinterCustom. | ||||||
|  | // | ||||||
|  | // 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{}) { | ||||||
| 	funcMap := template.FuncMap{ | 	funcMap := template.FuncMap{ | ||||||
| 		"join": strings.Join, | 		"join": strings.Join, | ||||||
| 	} | 	} | ||||||
| 	if customFunc != nil { | 	for key, value := range customFuncs { | ||||||
| 		for key, value := range customFunc { |  | ||||||
| 		funcMap[key] = value | 		funcMap[key] = value | ||||||
| 	} | 	} | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	w := tabwriter.NewWriter(out, 1, 8, 2, ' ', 0) | 	w := tabwriter.NewWriter(out, 1, 8, 2, ' ', 0) | ||||||
| 	t := template.Must(template.New("help").Funcs(funcMap).Parse(templ)) | 	t := template.Must(template.New("help").Funcs(funcMap).Parse(templ)) | ||||||
| @@ -243,15 +268,15 @@ func printHelpCustom(out io.Writer, templ string, data interface{}, customFunc m | |||||||
| 		// If the writer is closed, t.Execute will fail, and there's nothing | 		// If the writer is closed, t.Execute will fail, and there's nothing | ||||||
| 		// we can do to recover. | 		// we can do to recover. | ||||||
| 		if os.Getenv("CLI_TEMPLATE_ERROR_DEBUG") != "" { | 		if os.Getenv("CLI_TEMPLATE_ERROR_DEBUG") != "" { | ||||||
| 			fmt.Fprintf(ErrWriter, "CLI TEMPLATE ERROR: %#v\n", err) | 			_, _ = fmt.Fprintf(ErrWriter, "CLI TEMPLATE ERROR: %#v\n", err) | ||||||
| 		} | 		} | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 	w.Flush() | 	_ = w.Flush() | ||||||
| } | } | ||||||
|  |  | ||||||
| func printHelp(out io.Writer, templ string, data interface{}) { | func printHelp(out io.Writer, templ string, data interface{}) { | ||||||
| 	printHelpCustom(out, templ, data, nil) | 	HelpPrinterCustom(out, templ, data, nil) | ||||||
| } | } | ||||||
|  |  | ||||||
| func checkVersion(c *Context) bool { | func checkVersion(c *Context) bool { | ||||||
| @@ -280,7 +305,7 @@ func checkHelp(c *Context) bool { | |||||||
|  |  | ||||||
| func checkCommandHelp(c *Context, name string) bool { | func checkCommandHelp(c *Context, name string) bool { | ||||||
| 	if c.Bool("h") || c.Bool("help") { | 	if c.Bool("h") || c.Bool("help") { | ||||||
| 		ShowCommandHelp(c, name) | 		_ = ShowCommandHelp(c, name) | ||||||
| 		return true | 		return true | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -289,7 +314,7 @@ func checkCommandHelp(c *Context, name string) bool { | |||||||
|  |  | ||||||
| func checkSubcommandHelp(c *Context) bool { | func checkSubcommandHelp(c *Context) bool { | ||||||
| 	if c.Bool("h") || c.Bool("help") { | 	if c.Bool("h") || c.Bool("help") { | ||||||
| 		ShowSubcommandHelp(c) | 		_ = ShowSubcommandHelp(c) | ||||||
| 		return true | 		return true | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										89
									
								
								vendor/github.com/urfave/cli/parse.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										89
									
								
								vendor/github.com/urfave/cli/parse.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,89 @@ | |||||||
|  | package cli | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"flag" | ||||||
|  | 	"strings" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | type iterativeParser interface { | ||||||
|  | 	newFlagSet() (*flag.FlagSet, error) | ||||||
|  | 	useShortOptionHandling() bool | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // To enable short-option handling (e.g., "-it" vs "-i -t") we have to | ||||||
|  | // iteratively catch parsing errors.  This way we achieve LR parsing without | ||||||
|  | // transforming any arguments. Otherwise, there is no way we can discriminate | ||||||
|  | // combined short options from common arguments that should be left untouched. | ||||||
|  | func parseIter(set *flag.FlagSet, ip iterativeParser, args []string) error { | ||||||
|  | 	for { | ||||||
|  | 		err := set.Parse(args) | ||||||
|  | 		if !ip.useShortOptionHandling() || err == nil { | ||||||
|  | 			return err | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		errStr := err.Error() | ||||||
|  | 		trimmed := strings.TrimPrefix(errStr, "flag provided but not defined: -") | ||||||
|  | 		if errStr == trimmed { | ||||||
|  | 			return err | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		// regenerate the initial args with the split short opts | ||||||
|  | 		argsWereSplit := false | ||||||
|  | 		for i, arg := range args { | ||||||
|  | 			// skip args that are not part of the error message | ||||||
|  | 			if name := strings.TrimLeft(arg, "-"); name != trimmed { | ||||||
|  | 				continue | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			// if we can't split, the error was accurate | ||||||
|  | 			shortOpts := splitShortOptions(set, arg) | ||||||
|  | 			if len(shortOpts) == 1 { | ||||||
|  | 				return err | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			// swap current argument with the split version | ||||||
|  | 			args = append(args[:i], append(shortOpts, args[i+1:]...)...) | ||||||
|  | 			argsWereSplit = true | ||||||
|  | 			break | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		// This should be an impossible to reach code path, but in case the arg | ||||||
|  | 		// splitting failed to happen, this will prevent infinite loops | ||||||
|  | 		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 | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func splitShortOptions(set *flag.FlagSet, arg string) []string { | ||||||
|  | 	shortFlagsExist := func(s string) bool { | ||||||
|  | 		for _, c := range s[1:] { | ||||||
|  | 			if f := set.Lookup(string(c)); f == nil { | ||||||
|  | 				return false | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		return true | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if !isSplittable(arg) || !shortFlagsExist(arg) { | ||||||
|  | 		return []string{arg} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	separated := make([]string, 0, len(arg)-1) | ||||||
|  | 	for _, flagChar := range arg[1:] { | ||||||
|  | 		separated = append(separated, "-"+string(flagChar)) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return separated | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func isSplittable(flagArg string) bool { | ||||||
|  | 	return strings.HasPrefix(flagArg, "-") && !strings.HasPrefix(flagArg, "--") && len(flagArg) > 2 | ||||||
|  | } | ||||||
							
								
								
									
										122
									
								
								vendor/github.com/urfave/cli/runtests
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										122
									
								
								vendor/github.com/urfave/cli/runtests
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,122 +0,0 @@ | |||||||
| #!/usr/bin/env python |  | ||||||
| from __future__ import print_function |  | ||||||
|  |  | ||||||
| import argparse |  | ||||||
| import os |  | ||||||
| import sys |  | ||||||
| import tempfile |  | ||||||
|  |  | ||||||
| from subprocess import check_call, check_output |  | ||||||
|  |  | ||||||
|  |  | ||||||
| PACKAGE_NAME = os.environ.get( |  | ||||||
|     'CLI_PACKAGE_NAME', 'github.com/urfave/cli' |  | ||||||
| ) |  | ||||||
|  |  | ||||||
|  |  | ||||||
| def main(sysargs=sys.argv[:]): |  | ||||||
|     targets = { |  | ||||||
|         'vet': _vet, |  | ||||||
|         'test': _test, |  | ||||||
|         'gfmrun': _gfmrun, |  | ||||||
|         'toc': _toc, |  | ||||||
|         'gen': _gen, |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     parser = argparse.ArgumentParser() |  | ||||||
|     parser.add_argument( |  | ||||||
|         'target', nargs='?', choices=tuple(targets.keys()), default='test' |  | ||||||
|     ) |  | ||||||
|     args = parser.parse_args(sysargs[1:]) |  | ||||||
|  |  | ||||||
|     targets[args.target]() |  | ||||||
|     return 0 |  | ||||||
|  |  | ||||||
|  |  | ||||||
| def _test(): |  | ||||||
|     if check_output('go version'.split()).split()[2] < 'go1.2': |  | ||||||
|         _run('go test -v .') |  | ||||||
|         return |  | ||||||
|  |  | ||||||
|     coverprofiles = [] |  | ||||||
|     for subpackage in ['', 'altsrc']: |  | ||||||
|         coverprofile = 'cli.coverprofile' |  | ||||||
|         if subpackage != '': |  | ||||||
|             coverprofile = '{}.coverprofile'.format(subpackage) |  | ||||||
|  |  | ||||||
|         coverprofiles.append(coverprofile) |  | ||||||
|  |  | ||||||
|         _run('go test -v'.split() + [ |  | ||||||
|             '-coverprofile={}'.format(coverprofile), |  | ||||||
|             ('{}/{}'.format(PACKAGE_NAME, subpackage)).rstrip('/') |  | ||||||
|         ]) |  | ||||||
|  |  | ||||||
|     combined_name = _combine_coverprofiles(coverprofiles) |  | ||||||
|     _run('go tool cover -func={}'.format(combined_name)) |  | ||||||
|     os.remove(combined_name) |  | ||||||
|  |  | ||||||
|  |  | ||||||
| def _gfmrun(): |  | ||||||
|     go_version = check_output('go version'.split()).split()[2] |  | ||||||
|     if go_version < 'go1.3': |  | ||||||
|         print('runtests: skip on {}'.format(go_version), file=sys.stderr) |  | ||||||
|         return |  | ||||||
|     _run(['gfmrun', '-c', str(_gfmrun_count()), '-s', 'README.md']) |  | ||||||
|  |  | ||||||
|  |  | ||||||
| def _vet(): |  | ||||||
|     _run('go vet ./...') |  | ||||||
|  |  | ||||||
|  |  | ||||||
| def _toc(): |  | ||||||
|     _run('node_modules/.bin/markdown-toc -i README.md') |  | ||||||
|     _run('git diff --exit-code') |  | ||||||
|  |  | ||||||
|  |  | ||||||
| def _gen(): |  | ||||||
|     go_version = check_output('go version'.split()).split()[2] |  | ||||||
|     if go_version < 'go1.5': |  | ||||||
|         print('runtests: skip on {}'.format(go_version), file=sys.stderr) |  | ||||||
|         return |  | ||||||
|  |  | ||||||
|     _run('go generate ./...') |  | ||||||
|     _run('git diff --exit-code') |  | ||||||
|  |  | ||||||
|  |  | ||||||
| def _run(command): |  | ||||||
|     if hasattr(command, 'split'): |  | ||||||
|         command = command.split() |  | ||||||
|     print('runtests: {}'.format(' '.join(command)), file=sys.stderr) |  | ||||||
|     check_call(command) |  | ||||||
|  |  | ||||||
|  |  | ||||||
| def _gfmrun_count(): |  | ||||||
|     with open('README.md') as infile: |  | ||||||
|         lines = infile.read().splitlines() |  | ||||||
|         return len(filter(_is_go_runnable, lines)) |  | ||||||
|  |  | ||||||
|  |  | ||||||
| def _is_go_runnable(line): |  | ||||||
|     return line.startswith('package main') |  | ||||||
|  |  | ||||||
|  |  | ||||||
| def _combine_coverprofiles(coverprofiles): |  | ||||||
|     combined = tempfile.NamedTemporaryFile( |  | ||||||
|         suffix='.coverprofile', delete=False |  | ||||||
|     ) |  | ||||||
|     combined.write('mode: set\n') |  | ||||||
|  |  | ||||||
|     for coverprofile in coverprofiles: |  | ||||||
|         with open(coverprofile, 'r') as infile: |  | ||||||
|             for line in infile.readlines(): |  | ||||||
|                 if not line.startswith('mode: '): |  | ||||||
|                     combined.write(line) |  | ||||||
|  |  | ||||||
|     combined.flush() |  | ||||||
|     name = combined.name |  | ||||||
|     combined.close() |  | ||||||
|     return name |  | ||||||
|  |  | ||||||
|  |  | ||||||
| if __name__ == '__main__': |  | ||||||
|     sys.exit(main()) |  | ||||||
							
								
								
									
										29
									
								
								vendor/github.com/urfave/cli/sort.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								vendor/github.com/urfave/cli/sort.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,29 @@ | |||||||
|  | package cli | ||||||
|  |  | ||||||
|  | import "unicode" | ||||||
|  |  | ||||||
|  | // lexicographicLess compares strings alphabetically considering case. | ||||||
|  | func lexicographicLess(i, j string) bool { | ||||||
|  | 	iRunes := []rune(i) | ||||||
|  | 	jRunes := []rune(j) | ||||||
|  |  | ||||||
|  | 	lenShared := len(iRunes) | ||||||
|  | 	if lenShared > len(jRunes) { | ||||||
|  | 		lenShared = len(jRunes) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	for index := 0; index < lenShared; index++ { | ||||||
|  | 		ir := iRunes[index] | ||||||
|  | 		jr := jRunes[index] | ||||||
|  |  | ||||||
|  | 		if lir, ljr := unicode.ToLower(ir), unicode.ToLower(jr); lir != ljr { | ||||||
|  | 			return lir < ljr | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		if ir != jr { | ||||||
|  | 			return ir < jr | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return i < j | ||||||
|  | } | ||||||
							
								
								
									
										121
									
								
								vendor/github.com/urfave/cli/template.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										121
									
								
								vendor/github.com/urfave/cli/template.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,121 @@ | |||||||
|  | package cli | ||||||
|  |  | ||||||
|  | // 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}} | ||||||
|  |  | ||||||
|  | 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}} | ||||||
|  |  | ||||||
|  | VERSION: | ||||||
|  |    {{.Version}}{{end}}{{end}}{{if .Description}} | ||||||
|  |  | ||||||
|  | DESCRIPTION: | ||||||
|  |    {{.Description}}{{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}} | ||||||
|  |  | ||||||
|  | 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}} | ||||||
|  |  | ||||||
|  | GLOBAL OPTIONS: | ||||||
|  |    {{range $index, $option := .VisibleFlags}}{{if $index}} | ||||||
|  |    {{end}}{{$option}}{{end}}{{end}}{{if .Copyright}} | ||||||
|  |  | ||||||
|  | COPYRIGHT: | ||||||
|  |    {{.Copyright}}{{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}} | ||||||
|  |  | ||||||
|  | USAGE: | ||||||
|  |    {{if .UsageText}}{{.UsageText}}{{else}}{{.HelpName}}{{if .VisibleFlags}} [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{end}}{{if .Category}} | ||||||
|  |  | ||||||
|  | CATEGORY: | ||||||
|  |    {{.Category}}{{end}}{{if .Description}} | ||||||
|  |  | ||||||
|  | DESCRIPTION: | ||||||
|  |    {{.Description}}{{end}}{{if .VisibleFlags}} | ||||||
|  |  | ||||||
|  | OPTIONS: | ||||||
|  |    {{range .VisibleFlags}}{{.}} | ||||||
|  |    {{end}}{{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}} - {{if .Description}}{{.Description}}{{else}}{{.Usage}}{{end}} | ||||||
|  |  | ||||||
|  | USAGE: | ||||||
|  |    {{if .UsageText}}{{.UsageText}}{{else}}{{.HelpName}} command{{if .VisibleFlags}} [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{end}} | ||||||
|  |  | ||||||
|  | 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}} | ||||||
|  |  | ||||||
|  | OPTIONS: | ||||||
|  |    {{range .VisibleFlags}}{{.}} | ||||||
|  |    {{end}}{{end}} | ||||||
|  | ` | ||||||
|  |  | ||||||
|  | var MarkdownDocTemplate = `% {{ .App.Name }}(8) {{ .App.Description }} | ||||||
|  |  | ||||||
|  | % {{ .App.Author }} | ||||||
|  |  | ||||||
|  | # NAME | ||||||
|  |  | ||||||
|  | {{ .App.Name }}{{ if .App.Usage }} - {{ .App.Usage }}{{ end }} | ||||||
|  |  | ||||||
|  | # SYNOPSIS | ||||||
|  |  | ||||||
|  | {{ .App.Name }} | ||||||
|  | {{ if .SynopsisArgs }} | ||||||
|  | ` + "```" + ` | ||||||
|  | {{ range $v := .SynopsisArgs }}{{ $v }}{{ end }}` + "```" + ` | ||||||
|  | {{ end }}{{ if .App.UsageText }} | ||||||
|  | # DESCRIPTION | ||||||
|  |  | ||||||
|  | {{ .App.UsageText }} | ||||||
|  | {{ end }} | ||||||
|  | **Usage**: | ||||||
|  |  | ||||||
|  | ` + "```" + ` | ||||||
|  | {{ .App.Name }} [GLOBAL OPTIONS] command [COMMAND OPTIONS] [ARGUMENTS...] | ||||||
|  | ` + "```" + ` | ||||||
|  | {{ if .GlobalArgs }} | ||||||
|  | # GLOBAL OPTIONS | ||||||
|  | {{ range $v := .GlobalArgs }} | ||||||
|  | {{ $v }}{{ end }} | ||||||
|  | {{ end }}{{ if .Commands }} | ||||||
|  | # COMMANDS | ||||||
|  | {{ range $v := .Commands }} | ||||||
|  | {{ $v }}{{ end }}{{ end }}` | ||||||
|  |  | ||||||
|  | var FishCompletionTemplate = `# {{ .App.Name }} fish shell completion | ||||||
|  |  | ||||||
|  | function __fish_{{ .App.Name }}_no_subcommand --description 'Test if there has been any subcommand yet' | ||||||
|  |     for i in (commandline -opc) | ||||||
|  |         if contains -- $i{{ range $v := .AllCommands }} {{ $v }}{{ end }} | ||||||
|  |             return 1 | ||||||
|  |         end | ||||||
|  |     end | ||||||
|  |     return 0 | ||||||
|  | end | ||||||
|  |  | ||||||
|  | {{ range $v := .Completions }}{{ $v }} | ||||||
|  | {{ end }}` | ||||||
							
								
								
									
										8
									
								
								vendor/modules.txt
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										8
									
								
								vendor/modules.txt
									
									
									
									
										vendored
									
									
								
							| @@ -1,5 +1,7 @@ | |||||||
| # code.gitea.io/sdk/gitea v0.0.0-20200103062250-c7686bd633c6 | # code.gitea.io/sdk/gitea v0.0.0-20200103062250-c7686bd633c6 | ||||||
| code.gitea.io/sdk/gitea | code.gitea.io/sdk/gitea | ||||||
|  | # github.com/cpuguy83/go-md2man/v2 v2.0.0 | ||||||
|  | github.com/cpuguy83/go-md2man/v2/md2man | ||||||
| # github.com/davecgh/go-spew v1.1.1 | # github.com/davecgh/go-spew v1.1.1 | ||||||
| github.com/davecgh/go-spew/spew | github.com/davecgh/go-spew/spew | ||||||
| # github.com/emirpasic/gods v1.12.0 | # github.com/emirpasic/gods v1.12.0 | ||||||
| @@ -23,8 +25,12 @@ github.com/mitchellh/go-homedir | |||||||
| github.com/olekukonko/tablewriter | github.com/olekukonko/tablewriter | ||||||
| # github.com/pmezard/go-difflib v1.0.0 | # github.com/pmezard/go-difflib v1.0.0 | ||||||
| github.com/pmezard/go-difflib/difflib | github.com/pmezard/go-difflib/difflib | ||||||
|  | # github.com/russross/blackfriday/v2 v2.0.1 | ||||||
|  | github.com/russross/blackfriday/v2 | ||||||
| # github.com/sergi/go-diff v1.0.0 | # github.com/sergi/go-diff v1.0.0 | ||||||
| github.com/sergi/go-diff/diffmatchpatch | github.com/sergi/go-diff/diffmatchpatch | ||||||
|  | # github.com/shurcooL/sanitized_anchor_name v1.0.0 | ||||||
|  | github.com/shurcooL/sanitized_anchor_name | ||||||
| # github.com/src-d/gcfg v1.4.0 | # github.com/src-d/gcfg v1.4.0 | ||||||
| github.com/src-d/gcfg | github.com/src-d/gcfg | ||||||
| github.com/src-d/gcfg/scanner | github.com/src-d/gcfg/scanner | ||||||
| @@ -32,7 +38,7 @@ github.com/src-d/gcfg/token | |||||||
| github.com/src-d/gcfg/types | github.com/src-d/gcfg/types | ||||||
| # github.com/stretchr/testify v1.4.0 | # github.com/stretchr/testify v1.4.0 | ||||||
| github.com/stretchr/testify/assert | github.com/stretchr/testify/assert | ||||||
| # github.com/urfave/cli v1.20.0 | # github.com/urfave/cli v1.22.2 | ||||||
| github.com/urfave/cli | github.com/urfave/cli | ||||||
| # github.com/xanzy/ssh-agent v0.2.1 | # github.com/xanzy/ssh-agent v0.2.1 | ||||||
| github.com/xanzy/ssh-agent | github.com/xanzy/ssh-agent | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 6543
					6543