Browse Source

feat: update the datasets new

tags/v1.21.12.1
colorfulberry 5 years ago
parent
commit
40d0274bc7
100 changed files with 11222 additions and 3910 deletions
  1. +2
    -1
      go.mod
  2. +16
    -0
      go.sum
  3. +10
    -2
      options/locale/locale_en-US.ini
  4. +12
    -3
      options/locale/locale_zh-CN.ini
  5. +4
    -2
      routers/dataset/dataset.go
  6. +2
    -2
      routers/routes/routes.go
  7. +7
    -4
      templates/base/head_navbar.tmpl
  8. +0
    -1
      templates/dataset/index.tmpl
  9. +45
    -0
      templates/datasets/create.tmpl
  10. +3
    -0
      templates/datasets/index.tmpl
  11. +0
    -4
      templates/repo/header.tmpl
  12. +21
    -0
      vendor/github.com/cpuguy83/go-md2man/v2/LICENSE.md
  13. +14
    -0
      vendor/github.com/cpuguy83/go-md2man/v2/md2man/md2man.go
  14. +345
    -0
      vendor/github.com/cpuguy83/go-md2man/v2/md2man/roff.go
  15. +8
    -0
      vendor/github.com/russross/blackfriday/v2/.gitignore
  16. +17
    -0
      vendor/github.com/russross/blackfriday/v2/.travis.yml
  17. +29
    -0
      vendor/github.com/russross/blackfriday/v2/LICENSE.txt
  18. +291
    -0
      vendor/github.com/russross/blackfriday/v2/README.md
  19. +1590
    -0
      vendor/github.com/russross/blackfriday/v2/block.go
  20. +18
    -0
      vendor/github.com/russross/blackfriday/v2/doc.go
  21. +34
    -0
      vendor/github.com/russross/blackfriday/v2/esc.go
  22. +1
    -0
      vendor/github.com/russross/blackfriday/v2/go.mod
  23. +949
    -0
      vendor/github.com/russross/blackfriday/v2/html.go
  24. +1228
    -0
      vendor/github.com/russross/blackfriday/v2/inline.go
  25. +950
    -0
      vendor/github.com/russross/blackfriday/v2/markdown.go
  26. +354
    -0
      vendor/github.com/russross/blackfriday/v2/node.go
  27. +457
    -0
      vendor/github.com/russross/blackfriday/v2/smartypants.go
  28. +16
    -0
      vendor/github.com/shurcooL/sanitized_anchor_name/.travis.yml
  29. +21
    -0
      vendor/github.com/shurcooL/sanitized_anchor_name/LICENSE
  30. +36
    -0
      vendor/github.com/shurcooL/sanitized_anchor_name/README.md
  31. +1
    -0
      vendor/github.com/shurcooL/sanitized_anchor_name/go.mod
  32. +29
    -0
      vendor/github.com/shurcooL/sanitized_anchor_name/main.go
  33. +1
    -0
      vendor/github.com/urfave/cli/.gitignore
  34. +24
    -16
      vendor/github.com/urfave/cli/.travis.yml
  35. +71
    -2
      vendor/github.com/urfave/cli/CHANGELOG.md
  36. +74
    -0
      vendor/github.com/urfave/cli/CODE_OF_CONDUCT.md
  37. +18
    -0
      vendor/github.com/urfave/cli/CONTRIBUTING.md
  38. +253
    -63
      vendor/github.com/urfave/cli/README.md
  39. +73
    -40
      vendor/github.com/urfave/cli/app.go
  40. +9
    -12
      vendor/github.com/urfave/cli/appveyor.yml
  41. +1
    -1
      vendor/github.com/urfave/cli/category.go
  42. +1
    -1
      vendor/github.com/urfave/cli/cli.go
  43. +90
    -59
      vendor/github.com/urfave/cli/command.go
  44. +77
    -16
      vendor/github.com/urfave/cli/context.go
  45. +148
    -0
      vendor/github.com/urfave/cli/docs.go
  46. +194
    -0
      vendor/github.com/urfave/cli/fish.go
  47. +0
    -93
      vendor/github.com/urfave/cli/flag-types.json
  48. +103
    -556
      vendor/github.com/urfave/cli/flag.go
  49. +109
    -0
      vendor/github.com/urfave/cli/flag_bool.go
  50. +110
    -0
      vendor/github.com/urfave/cli/flag_bool_t.go
  51. +106
    -0
      vendor/github.com/urfave/cli/flag_duration.go
  52. +106
    -0
      vendor/github.com/urfave/cli/flag_float64.go
  53. +0
    -627
      vendor/github.com/urfave/cli/flag_generated.go
  54. +110
    -0
      vendor/github.com/urfave/cli/flag_generic.go
  55. +105
    -0
      vendor/github.com/urfave/cli/flag_int.go
  56. +106
    -0
      vendor/github.com/urfave/cli/flag_int64.go
  57. +141
    -0
      vendor/github.com/urfave/cli/flag_int64_slice.go
  58. +142
    -0
      vendor/github.com/urfave/cli/flag_int_slice.go
  59. +98
    -0
      vendor/github.com/urfave/cli/flag_string.go
  60. +138
    -0
      vendor/github.com/urfave/cli/flag_string_slice.go
  61. +106
    -0
      vendor/github.com/urfave/cli/flag_uint.go
  62. +106
    -0
      vendor/github.com/urfave/cli/flag_uint64.go
  63. +16
    -0
      vendor/github.com/urfave/cli/funcs.go
  64. +0
    -255
      vendor/github.com/urfave/cli/generate-flag-types
  65. +9
    -0
      vendor/github.com/urfave/cli/go.mod
  66. +14
    -0
      vendor/github.com/urfave/cli/go.sum
  67. +96
    -86
      vendor/github.com/urfave/cli/help.go
  68. +80
    -0
      vendor/github.com/urfave/cli/parse.go
  69. +0
    -122
      vendor/github.com/urfave/cli/runtests
  70. +29
    -0
      vendor/github.com/urfave/cli/sort.go
  71. +121
    -0
      vendor/github.com/urfave/cli/template.go
  72. +1
    -1
      vendor/github.com/yuin/goldmark/parser/list.go
  73. +1
    -1
      vendor/github.com/yuin/goldmark/util/util.go
  74. +1
    -1
      vendor/github.com/yuin/goldmark/util/util_safe.go
  75. +16
    -0
      vendor/golang.org/x/tools/go/analysis/analysis.go
  76. +1
    -1
      vendor/golang.org/x/tools/go/analysis/internal/analysisflags/flags.go
  77. +4
    -8
      vendor/golang.org/x/tools/go/gcexportdata/gcexportdata.go
  78. +0
    -852
      vendor/golang.org/x/tools/go/internal/gcimporter/bexport.go
  79. +0
    -1039
      vendor/golang.org/x/tools/go/internal/gcimporter/bimport.go
  80. +4
    -7
      vendor/golang.org/x/tools/go/internal/gcimporter/gcimporter.go
  81. +20
    -0
      vendor/golang.org/x/tools/go/internal/gcimporter/iexport.go
  82. +170
    -0
      vendor/golang.org/x/tools/go/internal/gcimporter/iimport.go
  83. +5
    -6
      vendor/golang.org/x/tools/go/internal/packagesdriver/sizes.go
  84. +40
    -8
      vendor/golang.org/x/tools/go/packages/golist.go
  85. +63
    -1
      vendor/golang.org/x/tools/go/packages/golist_overlay.go
  86. +1
    -1
      vendor/golang.org/x/tools/go/packages/loadmode_string.go
  87. +32
    -1
      vendor/golang.org/x/tools/go/packages/packages.go
  88. +3
    -2
      vendor/golang.org/x/tools/go/types/objectpath/objectpath.go
  89. +118
    -0
      vendor/golang.org/x/tools/internal/analysisinternal/analysis.go
  90. +85
    -0
      vendor/golang.org/x/tools/internal/event/core/event.go
  91. +70
    -0
      vendor/golang.org/x/tools/internal/event/core/export.go
  92. +77
    -0
      vendor/golang.org/x/tools/internal/event/core/fast.go
  93. +7
    -0
      vendor/golang.org/x/tools/internal/event/doc.go
  94. +127
    -0
      vendor/golang.org/x/tools/internal/event/event.go
  95. +564
    -0
      vendor/golang.org/x/tools/internal/event/keys/keys.go
  96. +22
    -0
      vendor/golang.org/x/tools/internal/event/keys/standard.go
  97. +213
    -0
      vendor/golang.org/x/tools/internal/event/label/label.go
  98. +72
    -11
      vendor/golang.org/x/tools/internal/gocommand/invoke.go
  99. +5
    -2
      vendor/golang.org/x/tools/internal/imports/fix.go
  100. +5
    -0
      vendor/golang.org/x/tools/internal/imports/imports.go

+ 2
- 1
go.mod View File

@@ -94,11 +94,12 @@ require (
github.com/tecbot/gorocksdb v0.0.0-20181010114359-8752a9433481 // indirect github.com/tecbot/gorocksdb v0.0.0-20181010114359-8752a9433481 // indirect
github.com/tinylib/msgp v1.1.2 // indirect github.com/tinylib/msgp v1.1.2 // indirect
github.com/tstranex/u2f v1.0.0 github.com/tstranex/u2f v1.0.0
github.com/unknwon/bra v0.0.0-20200517080246-1e3013ecaff8 // indirect
github.com/unknwon/cae v1.0.0 github.com/unknwon/cae v1.0.0
github.com/unknwon/com v1.0.1 github.com/unknwon/com v1.0.1
github.com/unknwon/i18n v0.0.0-20190805065654-5c6446a380b6 github.com/unknwon/i18n v0.0.0-20190805065654-5c6446a380b6
github.com/unknwon/paginater v0.0.0-20151104151617-7748a72e0141 github.com/unknwon/paginater v0.0.0-20151104151617-7748a72e0141
github.com/urfave/cli v1.20.0
github.com/urfave/cli v1.22.1
github.com/xanzy/go-gitlab v0.31.0 github.com/xanzy/go-gitlab v0.31.0
github.com/yohcop/openid-go v1.0.0 github.com/yohcop/openid-go v1.0.0
github.com/yuin/goldmark v1.1.27 github.com/yuin/goldmark v1.1.27


+ 16
- 0
go.sum View File

@@ -132,7 +132,10 @@ github.com/couchbase/vellum v1.0.1 h1:qrj9ohvZedvc51S5KzPfJ6P6z0Vqzv7Lx7k3mVc2WO
github.com/couchbase/vellum v1.0.1/go.mod h1:FcwrEivFpNi24R3jLOs3n+fs5RnuQnQqCLBJ1uAg1W4= github.com/couchbase/vellum v1.0.1/go.mod h1:FcwrEivFpNi24R3jLOs3n+fs5RnuQnQqCLBJ1uAg1W4=
github.com/couchbaselabs/go-couchbase v0.0.0-20190708161019-23e7ca2ce2b7 h1:1XjEY/gnjQ+AfXef2U6dxCquhiRzkEpxZuWqs+QxTL8= github.com/couchbaselabs/go-couchbase v0.0.0-20190708161019-23e7ca2ce2b7 h1:1XjEY/gnjQ+AfXef2U6dxCquhiRzkEpxZuWqs+QxTL8=
github.com/couchbaselabs/go-couchbase v0.0.0-20190708161019-23e7ca2ce2b7/go.mod h1:mby/05p8HE5yHEAKiIH/555NoblMs7PtW6NrYshDruc= github.com/couchbaselabs/go-couchbase v0.0.0-20190708161019-23e7ca2ce2b7/go.mod h1:mby/05p8HE5yHEAKiIH/555NoblMs7PtW6NrYshDruc=
github.com/cpuguy83/go-md2man v1.0.10 h1:BSKMNlYxDvnunlTymqtgONjNnaRV1sTpcovwwjF22jk=
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
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/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/cupcake/rdb v0.0.0-20161107195141-43ba34106c76/go.mod h1:vYwsqCOLxGiisLwp9rITslkFNpZD5rz43tf41QFkTWY= github.com/cupcake/rdb v0.0.0-20161107195141-43ba34106c76/go.mod h1:vYwsqCOLxGiisLwp9rITslkFNpZD5rz43tf41QFkTWY=
github.com/cznic/b v0.0.0-20181122101859-a26611c4d92d h1:SwD98825d6bdB+pEuTxWOXiSjBrHdOl/UVp75eI7JT8= github.com/cznic/b v0.0.0-20181122101859-a26611c4d92d h1:SwD98825d6bdB+pEuTxWOXiSjBrHdOl/UVp75eI7JT8=
@@ -556,12 +559,16 @@ github.com/remyoudompheng/bigfft v0.0.0-20190321074620-2f0d2b0e0001/go.mod h1:qq
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo= github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo=
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww= github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
github.com/shurcooL/httpfs v0.0.0-20190527155220-6a4d4a70508b h1:4kg1wyftSKxLtnPAvcRWakIPpokB9w780/KwrNLnfPA= github.com/shurcooL/httpfs v0.0.0-20190527155220-6a4d4a70508b h1:4kg1wyftSKxLtnPAvcRWakIPpokB9w780/KwrNLnfPA=
github.com/shurcooL/httpfs v0.0.0-20190527155220-6a4d4a70508b/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg= github.com/shurcooL/httpfs v0.0.0-20190527155220-6a4d4a70508b/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg=
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/shurcooL/vfsgen v0.0.0-20181202132449-6a9ea43bcacd h1:ug7PpSOB5RBPK1Kg6qskGBoP3Vnj/aNYFTznWvlkGo0= github.com/shurcooL/vfsgen v0.0.0-20181202132449-6a9ea43bcacd h1:ug7PpSOB5RBPK1Kg6qskGBoP3Vnj/aNYFTznWvlkGo0=
github.com/shurcooL/vfsgen v0.0.0-20181202132449-6a9ea43bcacd/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw= github.com/shurcooL/vfsgen v0.0.0-20181202132449-6a9ea43bcacd/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw=
github.com/siddontang/go v0.0.0-20180604090527-bdc77568d726/go.mod h1:3yhqj7WBBfRhbBlzyOC3gUxftwsU0u8gqevxwIHQpMw= github.com/siddontang/go v0.0.0-20180604090527-bdc77568d726/go.mod h1:3yhqj7WBBfRhbBlzyOC3gUxftwsU0u8gqevxwIHQpMw=
@@ -626,6 +633,8 @@ github.com/tstranex/u2f v1.0.0 h1:HhJkSzDDlVSVIVt7pDJwCHQj67k7A5EeBgPmeD+pVsQ=
github.com/tstranex/u2f v1.0.0/go.mod h1:eahSLaqAS0zsIEv80+vXT7WanXs7MQQDg3j3wGBSayo= github.com/tstranex/u2f v1.0.0/go.mod h1:eahSLaqAS0zsIEv80+vXT7WanXs7MQQDg3j3wGBSayo=
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
github.com/unknwon/bra v0.0.0-20200517080246-1e3013ecaff8 h1:aVGB3YnaS/JNfOW3tiHIlmNmTDg618va+eT0mVomgyI=
github.com/unknwon/bra v0.0.0-20200517080246-1e3013ecaff8/go.mod h1:fVle4kNr08ydeohzYafr20oZzbAkhQT39gKK/pFQ5M4=
github.com/unknwon/cae v1.0.0 h1:i39lOFaBXZxhGjQOy/RNbi8uzettCs6OQxpR0xXohGU= github.com/unknwon/cae v1.0.0 h1:i39lOFaBXZxhGjQOy/RNbi8uzettCs6OQxpR0xXohGU=
github.com/unknwon/cae v1.0.0/go.mod h1:QaSeRctcea9fK6piJpAMCCPKxzJ01+xFcr2k1m3WRPU= github.com/unknwon/cae v1.0.0/go.mod h1:QaSeRctcea9fK6piJpAMCCPKxzJ01+xFcr2k1m3WRPU=
github.com/unknwon/com v0.0.0-20190804042917-757f69c95f3e h1:GSGeB9EAKY2spCABz6xOX5DbxZEXolK+nBSvmsQwRjM= github.com/unknwon/com v0.0.0-20190804042917-757f69c95f3e h1:GSGeB9EAKY2spCABz6xOX5DbxZEXolK+nBSvmsQwRjM=
@@ -634,10 +643,14 @@ github.com/unknwon/com v1.0.1 h1:3d1LTxD+Lnf3soQiD4Cp/0BRB+Rsa/+RTvz8GMMzIXs=
github.com/unknwon/com v1.0.1/go.mod h1:tOOxU81rwgoCLoOVVPHb6T/wt8HZygqH5id+GNnlCXM= github.com/unknwon/com v1.0.1/go.mod h1:tOOxU81rwgoCLoOVVPHb6T/wt8HZygqH5id+GNnlCXM=
github.com/unknwon/i18n v0.0.0-20190805065654-5c6446a380b6 h1:sRrkJEHtNoaSvyXMbRgofEOX4/3gMiraevQKJdIBhYE= github.com/unknwon/i18n v0.0.0-20190805065654-5c6446a380b6 h1:sRrkJEHtNoaSvyXMbRgofEOX4/3gMiraevQKJdIBhYE=
github.com/unknwon/i18n v0.0.0-20190805065654-5c6446a380b6/go.mod h1:+5rDk6sDGpl3azws3O+f+GpFSyN9GVr0K8cvQLQM2ZQ= github.com/unknwon/i18n v0.0.0-20190805065654-5c6446a380b6/go.mod h1:+5rDk6sDGpl3azws3O+f+GpFSyN9GVr0K8cvQLQM2ZQ=
github.com/unknwon/log v0.0.0-20150304194804-e617c87089d3 h1:4EYQaWAatQokdji3zqZloVIW/Ke1RQjYw2zHULyrHJg=
github.com/unknwon/log v0.0.0-20150304194804-e617c87089d3/go.mod h1:1xEUf2abjfP92w2GZTV+GgaRxXErwRXcClbUwrNJffU=
github.com/unknwon/paginater v0.0.0-20151104151617-7748a72e0141 h1:Z79lyIznnziKADUf0J7EP8Z4ZL7YJDiPuaazlfUBSy4= github.com/unknwon/paginater v0.0.0-20151104151617-7748a72e0141 h1:Z79lyIznnziKADUf0J7EP8Z4ZL7YJDiPuaazlfUBSy4=
github.com/unknwon/paginater v0.0.0-20151104151617-7748a72e0141/go.mod h1:TBwoao3Q4Eb/cp+dHbXDfRTrZSsj/k7kLr2j1oWRWC0= github.com/unknwon/paginater v0.0.0-20151104151617-7748a72e0141/go.mod h1:TBwoao3Q4Eb/cp+dHbXDfRTrZSsj/k7kLr2j1oWRWC0=
github.com/urfave/cli v1.20.0 h1:fDqGv3UG/4jbVl/QkFwEdddtEDjh/5Ov6X+0B/3bPaw= github.com/urfave/cli v1.20.0 h1:fDqGv3UG/4jbVl/QkFwEdddtEDjh/5Ov6X+0B/3bPaw=
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
github.com/urfave/cli v1.22.1 h1:+mkCCcOFKPnCmVYVcURKps1Xe+3zP90gSYGNfRkjoIY=
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
github.com/willf/bitset v1.1.10 h1:NotGKqX0KwQ72NUzqrjZq5ipPNDQex9lo3WpaS8L2sc= github.com/willf/bitset v1.1.10 h1:NotGKqX0KwQ72NUzqrjZq5ipPNDQex9lo3WpaS8L2sc=
github.com/willf/bitset v1.1.10/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= github.com/willf/bitset v1.1.10/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4=
github.com/xanzy/go-gitlab v0.31.0 h1:+nHztQuCXGSMluKe5Q9IRaPdz6tO8O0gMkQ0vqGpiBk= github.com/xanzy/go-gitlab v0.31.0 h1:+nHztQuCXGSMluKe5Q9IRaPdz6tO8O0gMkQ0vqGpiBk=
@@ -771,6 +784,7 @@ golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20190907184412-d223b2b6db03/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190907184412-d223b2b6db03/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191010194322-b09406accb47 h1:/XfQ9z7ib8eEJX2hdgFTZJ/ntt0swNk5oYBziWeTCvY= golang.org/x/sys v0.0.0-20191010194322-b09406accb47 h1:/XfQ9z7ib8eEJX2hdgFTZJ/ntt0swNk5oYBziWeTCvY=
golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191020152052-9984515f0562/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527 h1:uYVVQ9WP/Ds2ROhcaGPeIdVq0RIXVLwsHlnvJ+cT1So= golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527 h1:uYVVQ9WP/Ds2ROhcaGPeIdVq0RIXVLwsHlnvJ+cT1So=
@@ -868,6 +882,8 @@ gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8X
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/fsnotify/fsnotify.v1 v1.4.7 h1:XNNYLJHt73EyYiCZi6+xjupS9CpvmiDgjPTAjrBlQbo=
gopkg.in/fsnotify/fsnotify.v1 v1.4.7/go.mod h1:Fyux9zXlo4rWoMSIzpn9fDAYjalPqJ/K1qJ27s+7ltE=
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df h1:n7WqCuqOuCbNr617RXOY0AWRXxgwEyPp2z+p0+hgMuE= gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df h1:n7WqCuqOuCbNr617RXOY0AWRXxgwEyPp2z+p0+hgMuE=
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df/go.mod h1:LRQQ+SO6ZHR7tOkpBDuZnXENFzX8qRjMDMyPD6BRkCw= gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df/go.mod h1:LRQQ+SO6ZHR7tOkpBDuZnXENFzX8qRjMDMyPD6BRkCw=
gopkg.in/ini.v1 v1.42.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.42.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=


+ 10
- 2
options/locale/locale_en-US.ini View File

@@ -1,7 +1,7 @@
home = Home home = Home
dashboard = Dashboard dashboard = Dashboard
explore = Explore explore = Explore
data_sets = Data Sets
datasets = Datasets
help = Help help = Help
sign_in = Sign In sign_in = Sign In
sign_in_with = Sign In With sign_in_with = Sign In With
@@ -49,6 +49,7 @@ organization = Organization
mirror = Mirror mirror = Mirror
new_repo = New Repository new_repo = New Repository
new_migrate = New Migration new_migrate = New Migration
new_dataset = New Dataset
new_mirror = New Mirror new_mirror = New Mirror
new_fork = New Repository Fork new_fork = New Repository Fork
new_org = New Organization new_org = New Organization
@@ -618,6 +619,13 @@ email_notifications.onmention = Only Email on Mention
email_notifications.disable = Disable Email Notifications email_notifications.disable = Disable Email Notifications
email_notifications.submit = Set Email Preference email_notifications.submit = Set Email Preference


[dataset]
title = Title
description = Description
create_dataset = Create Dataset
category = Category
file = Dataset File

[repo] [repo]
owner = Owner owner = Owner
repo_name = Repository Name repo_name = Repository Name
@@ -667,7 +675,7 @@ pick_reaction = Pick your reaction
reactions_more = and %d more reactions_more = and %d more
unit_disabled = The site administrator has disabled this repository section. unit_disabled = The site administrator has disabled this repository section.
language_other = Other language_other = Other
data_sets = Data Sets
datasets = Datasets


template.items = Template Items template.items = Template Items
template.git_content = Git Content (Default Branch) template.git_content = Git Content (Default Branch)


+ 12
- 3
options/locale/locale_zh-CN.ini View File

@@ -47,6 +47,7 @@ repository=仓库
organization=组织 organization=组织
mirror=镜像 mirror=镜像
new_repo=创建仓库 new_repo=创建仓库
new_dataset=创建数据集
new_migrate=迁移外部仓库 new_migrate=迁移外部仓库
new_mirror=创建新的镜像 new_mirror=创建新的镜像
new_fork=新的仓库Fork new_fork=新的仓库Fork
@@ -514,8 +515,8 @@ last_used=上次使用在
no_activity=没有最近活动 no_activity=没有最近活动
can_read_info=读取 can_read_info=读取
can_write_info=写入 can_write_info=写入
key_state_desc=7 天内使用过该密钥
token_state_desc=7 天内使用过该密钥
key_state_desc=7 天内使用过该密钥
token_state_desc=7 天内使用过该密钥
show_openid=在个人信息上显示 show_openid=在个人信息上显示
hide_openid=在个人信息上隐藏 hide_openid=在个人信息上隐藏
ssh_disabled=SSH 被禁用 ssh_disabled=SSH 被禁用
@@ -616,6 +617,13 @@ email_notifications.onmention=只在被提到时邮件通知
email_notifications.disable=停用邮件通知 email_notifications.disable=停用邮件通知
email_notifications.submit=邮件通知设置 email_notifications.submit=邮件通知设置


[dataset]
title = 主题
description = 描述
create_dataset = 创建数据集
category = 分类
file = 数据集文件

[repo] [repo]
owner=拥有者 owner=拥有者
repo_name=仓库名称 repo_name=仓库名称
@@ -662,9 +670,10 @@ watchers=关注者
stargazers=称赞者 stargazers=称赞者
forks=派生仓库 forks=派生仓库
pick_reaction=选择你的表情 pick_reaction=选择你的表情
reactions_more=再加载 %d
reactions_more=再加载 %d
unit_disabled=站点管理员已禁用此仓库单元。 unit_disabled=站点管理员已禁用此仓库单元。
language_other=其它 language_other=其它
datasets=数据集


template.items=模板选项 template.items=模板选项
template.git_content=Git数据(默认分支) template.git_content=Git数据(默认分支)


+ 4
- 2
routers/dataset/dataset.go View File

@@ -7,16 +7,18 @@ import (
) )


const ( const (
tplDataSet base.TplName = "dataset/index"
tplDataSet base.TplName = "datasets/index"
tplCreate base.TplName = "datasets/create"
) )


func MyList(ctx *context.Context) { func MyList(ctx *context.Context) {
log.Debug("[dataset] mylist...\n") log.Debug("[dataset] mylist...\n")
ctx.HTML(200, tplDataSet) ctx.HTML(200, tplDataSet)

} }

func Create(ctx *context.Context) { func Create(ctx *context.Context) {
log.Debug("[dataset] Create...\n") log.Debug("[dataset] Create...\n")
ctx.HTML(200, tplCreate)
} }
func Delete(ctx *context.Context) { func Delete(ctx *context.Context) {
log.Debug("[dataset] Delete...\n") log.Debug("[dataset] Delete...\n")


+ 2
- 2
routers/routes/routes.go View File

@@ -1001,9 +1001,9 @@ func RegisterRoutes(m *macaron.Macaron) {
// ***** END: Repository ***** // ***** END: Repository *****


// DataSet // DataSet
m.Group("/dataset", func() {
m.Group("/datasets", func() {
m.Get("", dataset.MyList) m.Get("", dataset.MyList)
m.Post("", dataset.Create)
m.Get("/create", dataset.Create)
m.Post("/delete", dataset.Delete) m.Post("/delete", dataset.Delete)
}, ignSignIn) }, ignSignIn)
// ***** END: DataSet***** // ***** END: DataSet*****


+ 7
- 4
templates/base/head_navbar.tmpl View File

@@ -10,6 +10,7 @@


{{if .IsSigned}} {{if .IsSigned}}
<a class="item {{if .PageIsDashboard}}active{{end}}" href="{{AppSubUrl}}/">{{.i18n.Tr "dashboard"}}</a> <a class="item {{if .PageIsDashboard}}active{{end}}" href="{{AppSubUrl}}/">{{.i18n.Tr "dashboard"}}</a>
<a class="item {{if .PageIsDataSets}}active{{end}}" href="{{AppSubUrl}}/datasets">{{.i18n.Tr "datasets"}}</a>
{{if not .UnitIssuesGlobalDisabled}} {{if not .UnitIssuesGlobalDisabled}}
<a class="item {{if .PageIsIssues}}active{{end}}" href="{{AppSubUrl}}/issues">{{.i18n.Tr "issues"}}</a> <a class="item {{if .PageIsIssues}}active{{end}}" href="{{AppSubUrl}}/issues">{{.i18n.Tr "issues"}}</a>
{{end}} {{end}}
@@ -20,17 +21,16 @@
{{if .ShowMilestonesDashboardPage}}<a class="item {{if .PageIsMilestonesDashboard}}active{{end}}" href="{{AppSubUrl}}/milestones">{{.i18n.Tr "milestones"}}</a>{{end}} {{if .ShowMilestonesDashboardPage}}<a class="item {{if .PageIsMilestonesDashboard}}active{{end}}" href="{{AppSubUrl}}/milestones">{{.i18n.Tr "milestones"}}</a>{{end}}
{{end}} {{end}}
<a class="item {{if .PageIsExplore}}active{{end}}" href="{{AppSubUrl}}/explore/repos">{{.i18n.Tr "explore"}}</a> <a class="item {{if .PageIsExplore}}active{{end}}" href="{{AppSubUrl}}/explore/repos">{{.i18n.Tr "explore"}}</a>
<a class="item {{if .PageIsDataSets}}active{{end}}" href="{{AppSubUrl}}/explore/repos">{{.i18n.Tr "data_sets"}}</a>
{{else if .IsLandingPageHome}} {{else if .IsLandingPageHome}}
<a class="item {{if .PageIsHome}}active{{end}}" href="{{AppSubUrl}}/">{{.i18n.Tr "home"}}</a> <a class="item {{if .PageIsHome}}active{{end}}" href="{{AppSubUrl}}/">{{.i18n.Tr "home"}}</a>
<a class="item {{if .PageIsDataSets}}active{{end}}" href="{{AppSubUrl}}/datasets">{{.i18n.Tr "datasets"}}</a>
<a class="item {{if .PageIsExplore}}active{{end}}" href="{{AppSubUrl}}/explore/repos">{{.i18n.Tr "explore"}}</a> <a class="item {{if .PageIsExplore}}active{{end}}" href="{{AppSubUrl}}/explore/repos">{{.i18n.Tr "explore"}}</a>
<a class="item {{if .PageIsDataSets}}active{{end}}" href="{{AppSubUrl}}/explore/repos">{{.i18n.Tr "data_sets"}}</a>
{{else if .IsLandingPageExplore}} {{else if .IsLandingPageExplore}}
<a class="item {{if .PageIsExplore}}active{{end}}" href="{{AppSubUrl}}/explore/repos">{{.i18n.Tr "home"}}</a> <a class="item {{if .PageIsExplore}}active{{end}}" href="{{AppSubUrl}}/explore/repos">{{.i18n.Tr "home"}}</a>
<a class="item {{if .PageIsDataSets}}active{{end}}" href="{{AppSubUrl}}/explore/repos">{{.i18n.Tr "data_sets"}}</a>
<a class="item {{if .PageIsDataSets}}active{{end}}" href="{{AppSubUrl}}/datasets">{{.i18n.Tr "datasets"}}</a>
{{else if .IsLandingPageOrganizations}} {{else if .IsLandingPageOrganizations}}
<a class="item {{if .PageIsExplore}}active{{end}}" href="{{AppSubUrl}}/explore/organizations">{{.i18n.Tr "home"}}</a> <a class="item {{if .PageIsExplore}}active{{end}}" href="{{AppSubUrl}}/explore/organizations">{{.i18n.Tr "home"}}</a>
<a class="item {{if .PageIsDataSets}}active{{end}}" href="{{AppSubUrl}}/explore/repos">{{.i18n.Tr "data_sets"}}</a>
<a class="item {{if .PageIsDataSets}}active{{end}}" href="{{AppSubUrl}}/datasets">{{.i18n.Tr "datasets"}}</a>
{{end}} {{end}}


{{template "custom/extra_links" .}} {{template "custom/extra_links" .}}
@@ -68,6 +68,9 @@
<a class="item" href="{{AppSubUrl}}/repo/create"> <a class="item" href="{{AppSubUrl}}/repo/create">
<span class="fitted">{{svg "octicon-plus" 16}}</span> {{.i18n.Tr "new_repo"}} <span class="fitted">{{svg "octicon-plus" 16}}</span> {{.i18n.Tr "new_repo"}}
</a> </a>
<a class="item" href="{{AppSubUrl}}/datasets/create">
<span class="fitted">{{svg "octicon-plus" 16}}</span> {{.i18n.Tr "new_dataset"}}
</a>
<a class="item" href="{{AppSubUrl}}/repo/migrate"> <a class="item" href="{{AppSubUrl}}/repo/migrate">
<span class="fitted">{{svg "octicon-repo-clone" 16}}</span> {{.i18n.Tr "new_migrate"}} <span class="fitted">{{svg "octicon-repo-clone" 16}}</span> {{.i18n.Tr "new_migrate"}}
</a> </a>


+ 0
- 1
templates/dataset/index.tmpl View File

@@ -1 +0,0 @@
index.tmpl

+ 45
- 0
templates/datasets/create.tmpl View File

@@ -0,0 +1,45 @@
{{template "base/head" .}}
<div class="dataset new dataset">
<div class="ui middle very relaxed page grid">
<div class="column">
<form class="ui form" action="{{.Link}}" method="post">
{{.CsrfTokenHtml}}
<h3 class="ui top attached header">
{{.i18n.Tr "new_dataset"}}
</h3>
<div class="ui attached segment">
{{template "base/alert" .}}
<div class="field">
<label>{{.i18n.Tr "dataset.title"}}</label>
<input name="title" placeholder="{{.i18n.Tr "dataset.title"}}" value="{{.title}}" autofocus required maxlength="255">
</div>

<div class="field">
<label>{{.i18n.Tr "dataset.description"}}</label>
<textarea name="description">{{.description}}</textarea>
</div>

<div class="field">
<label>{{.i18n.Tr "dataset.category"}}</label>
<input name="category" placeholder="{{.i18n.Tr "dataset.category"}}" value="{{.category}}" autofocus required maxlength="255">
</div>

<div class="field">
<label>{{.i18n.Tr "dataset.file"}}</label>
<div class="files"></div>
<div class="ui dropzone" id="dropzone" data-upload-url="{{AppSubUrl}}/attachments" data-accepts="{{.AttachmentAllowedTypes}}" data-max-file="{{.AttachmentMaxFiles}}" data-max-size="{{.AttachmentMaxSize}}" data-default-message="{{.i18n.Tr "dropzone.default_message"}}" data-invalid-input-type="{{.i18n.Tr "dropzone.invalid_input_type"}}" data-file-too-big="{{.i18n.Tr "dropzone.file_too_big"}}" data-remove-file="{{.i18n.Tr "dropzone.remove_file"}}"></div>
</div>
<br/>
<div class="inline field">
<label></label>
<button class="ui green button">
{{.i18n.Tr "repo.create_dataset"}}
</button>
<a class="ui button" href="{{AppSubUrl}}/">{{.i18n.Tr "cancel"}}</a>
</div>
</div>
</form>
</div>
</div>
</div>
{{template "base/footer" .}}

+ 3
- 0
templates/datasets/index.tmpl View File

@@ -0,0 +1,3 @@
{{template "base/head" .}}
index.tmpl
{{template "base/footer" .}}

+ 0
- 4
templates/repo/header.tmpl View File

@@ -101,10 +101,6 @@
<a class="{{if .PageIsIssueList}}active{{end}} item" href="{{.RepoLink}}/issues"> <a class="{{if .PageIsIssueList}}active{{end}} item" href="{{.RepoLink}}/issues">
{{svg "octicon-issue-opened" 16}} {{.i18n.Tr "repo.issues"}} <span class="ui {{if not .Repository.NumOpenIssues}}gray{{else}}blue{{end}} small label">{{.Repository.NumOpenIssues}}</span> {{svg "octicon-issue-opened" 16}} {{.i18n.Tr "repo.issues"}} <span class="ui {{if not .Repository.NumOpenIssues}}gray{{else}}blue{{end}} small label">{{.Repository.NumOpenIssues}}</span>
</a> </a>

<a class="{{if .PageIsIssueList}}active{{end}} item" href="{{.RepoLink}}/issues">
{{svg "octicon-file-submodule" 16}} {{.i18n.Tr "repo.data_sets"}}
</a>
{{end}} {{end}}


{{if .Permission.CanRead $.UnitTypeExternalTracker}} {{if .Permission.CanRead $.UnitTypeExternalTracker}}


+ 21
- 0
vendor/github.com/cpuguy83/go-md2man/v2/LICENSE.md View 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
- 0
vendor/github.com/cpuguy83/go-md2man/v2/md2man/md2man.go View 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
- 0
vendor/github.com/cpuguy83/go-md2man/v2/md2man/roff.go View 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
- 0
vendor/github.com/russross/blackfriday/v2/.gitignore View File

@@ -0,0 +1,8 @@
*.out
*.swp
*.8
*.6
_obj
_test*
markdown
tags

+ 17
- 0
vendor/github.com/russross/blackfriday/v2/.travis.yml View 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
- 0
vendor/github.com/russross/blackfriday/v2/LICENSE.txt View 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
- 0
vendor/github.com/russross/blackfriday/v2/README.md View File

@@ -0,0 +1,291 @@
Blackfriday [![Build Status](https://travis-ci.org/russross/blackfriday.svg?branch=master)](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 `&ndash;`, and `---` is translated into
`&mdash;`. 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>&frasl;<sub>5</sub>`, which renders as
<sup>4</sup>&frasl;<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
- 0
vendor/github.com/russross/blackfriday/v2/block.go
File diff suppressed because it is too large
View File


+ 18
- 0
vendor/github.com/russross/blackfriday/v2/doc.go View 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
- 0
vendor/github.com/russross/blackfriday/v2/esc.go View File

@@ -0,0 +1,34 @@
package blackfriday

import (
"html"
"io"
)

var htmlEscaper = [256][]byte{
'&': []byte("&amp;"),
'<': []byte("&lt;"),
'>': []byte("&gt;"),
'"': []byte("&quot;"),
}

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
- 0
vendor/github.com/russross/blackfriday/v2/go.mod View File

@@ -0,0 +1 @@
module github.com/russross/blackfriday/v2

+ 949
- 0
vendor/github.com/russross/blackfriday/v2/html.go View 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
- 0
vendor/github.com/russross/blackfriday/v2/inline.go
File diff suppressed because it is too large
View File


+ 950
- 0
vendor/github.com/russross/blackfriday/v2/markdown.go View 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
- 0
vendor/github.com/russross/blackfriday/v2/node.go View 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
- 0
vendor/github.com/russross/blackfriday/v2/smartypants.go View 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("&nbsp;")
}

out.WriteByte('&')
if *isOpen {
out.WriteByte('l')
} else {
out.WriteByte('r')
}
out.WriteByte(quote)
out.WriteString("quo;")

if addNBSP && *isOpen {
out.WriteString("&nbsp;")
}

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("&rsquo;")
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("&rsquo;")
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("&copy;")
return 2
}

if t1 == 'r' && t2 == ')' {
out.WriteString("&reg;")
return 2
}

if len(text) >= 4 && t1 == 't' && t2 == 'm' && text[3] == ')' {
out.WriteString("&trade;")
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("&mdash;")
return 1
}

if wordBoundary(previousChar) && wordBoundary(text[1]) {
out.WriteString("&ndash;")
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("&mdash;")
return 2
}
if len(text) >= 2 && text[1] == '-' {
out.WriteString("&ndash;")
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("&quot;")) {
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("&#0;")) {
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("&hellip;")
return 2
}

if len(text) >= 5 && text[1] == ' ' && text[2] == '.' && text[3] == ' ' && text[4] == '.' {
out.WriteString("&hellip;")
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>&frasl;<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("&frac12;")
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("&frac14;")
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("&frac34;")
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("&quot;")
}

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
- 0
vendor/github.com/shurcooL/sanitized_anchor_name/.travis.yml View 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
- 0
vendor/github.com/shurcooL/sanitized_anchor_name/LICENSE View 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
- 0
vendor/github.com/shurcooL/sanitized_anchor_name/README.md View File

@@ -0,0 +1,36 @@
sanitized_anchor_name
=====================

[![Build Status](https://travis-ci.org/shurcooL/sanitized_anchor_name.svg?branch=master)](https://travis-ci.org/shurcooL/sanitized_anchor_name) [![GoDoc](https://godoc.org/github.com/shurcooL/sanitized_anchor_name?status.svg)](https://godoc.org/github.com/shurcooL/sanitized_anchor_name)

Package sanitized_anchor_name provides a func to create sanitized anchor names.

Its logic can be reused by multiple packages to create interoperable anchor names
and links to those anchors.

At this time, it does not try to ensure that generated anchor names
are unique, that responsibility falls on the caller.

Installation
------------

```bash
go get -u github.com/shurcooL/sanitized_anchor_name
```

Example
-------

```Go
anchorName := sanitized_anchor_name.Create("This is a header")

fmt.Println(anchorName)

// Output:
// this-is-a-header
```

License
-------

- [MIT License](LICENSE)

+ 1
- 0
vendor/github.com/shurcooL/sanitized_anchor_name/go.mod View File

@@ -0,0 +1 @@
module github.com/shurcooL/sanitized_anchor_name

+ 29
- 0
vendor/github.com/shurcooL/sanitized_anchor_name/main.go View 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
- 0
vendor/github.com/urfave/cli/.gitignore View File

@@ -1,2 +1,3 @@
*.coverprofile *.coverprofile
node_modules/ node_modules/
vendor

+ 24
- 16
vendor/github.com/urfave/cli/.travis.yml View File

@@ -1,27 +1,35 @@
language: go language: go
sudo: false sudo: false
dist: trusty
osx_image: xcode8.3
go: 1.8.x
dist: bionic
osx_image: xcode10
go:
- 1.11.x
- 1.12.x
- 1.13.x


os: os:
- linux
- osx
- linux
- 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 golang.org/x/tools/cmd/goimports
- if [ ! -f node_modules/.bin/markdown-toc ] ; then
npm install markdown-toc ;
fi
- go get github.com/urfave/gfmrun/cmd/gfmrun
- go get golang.org/x/tools/cmd/goimports
- npm install markdown-toc
- go mod tidy


script: script:
- ./runtests gen
- ./runtests vet
- ./runtests test
- ./runtests gfmrun
- ./runtests toc
- go run build.go vet
- go run build.go test
- go run build.go gfmrun
- go run build.go toc

after_success:
- bash <(curl -s https://codecov.io/bash)

+ 71
- 2
vendor/github.com/urfave/cli/CHANGELOG.md View File

@@ -4,7 +4,70 @@


## [Unreleased] ## [Unreleased]


## 1.20.0 - 2017-08-10
## [1.22.1] - 2019-09-11

### Fixed

* Hide output of hidden commands on man pages in [urfave/cli/pull/889](https://github.com/urfave/cli/pull/889) via [@crosbymichael](https://github.com/crosbymichael)
* Don't generate fish completion for hidden commands [urfave/cli/pull/891](https://github.com/urfave/891) via [@saschagrunert](https://github.com/saschagrunert)
* Using short flag names for required flags throws an error in [urfave/cli/pull/890](https://github.com/urfave/cli/pull/890) via [@asahasrabuddhe](https://github.com/asahasrabuddhe)

### Changed

* Remove flag code generation logic, legacy python test runner in [urfave/cli/pull/883](https://github.com/urfave/cli/pull/883) via [@asahasrabuddhe](https://github.com/asahasrabuddhe)
* Enable Go Modules support, drop support for `Go 1.10` add support for `Go 1.13` in [urfave/cli/pull/885](https://github.com/urfave/cli/pull/885) via [@asahasrabuddhe](https://github.com/asahasrabuddhe)

## [1.22.0] - 2019-09-07

### Fixed

* Fix Subcommands not falling back to `app.ExitEventHandler` in [urfave/cli/pull/856](https://github.com/urfave/cli/pull/856) via [@FaranIdo](https://github.com/FaranIdo)

### Changed

* Clarify that altsrc supports both TOML and JSON in [urfave/cli/pull/774](https://github.com/urfave/cli/pull/774) via [@whereswaldon](https://github.com/whereswaldon)
* Made the exit code example more clear in [urfave/cli/pull/823](https://github.com/urfave/cli/pull/823) via [@xordspar0](https://github.com/xordspar0)
* Removed the use of python for internal flag generation in [urfave/cli/pull/836](https://github.com/urfave/cli/pull/836) via [@asahasrabuddhe](https://github.com/asahasrabuddhe)
* Changed the supported go versions to `1.10`, `1.11`, `1.12` in [urfave/cli/pull/843](https://github.com/urfave/cli/pull/843) via [@lafriks](https://github.com/lafriks)
* Changed the v1 releases section in the readme in [urfave/cli/pull/862](https://github.com/urfave/cli/pull/862) via [@russoj88](https://github.com/russoj88)
* Cleaned up go modules in [urfave/cli/pull/874](https://github.com/urfave/cli/pull/874) via [@saschagrunert](https://github.com/saschagrunert)

### Added

* Added `UseShortOptionHandling` for combining short flags in [urfave/cli/pull/735](https://github.com/urfave/cli/pull/735) via [@rliebz](https://github.com/rliebz)
* Added support for flags bash completion in [urfave/cli/pull/808](https://github.com/urfave/cli/pull/808) via [@yogeshlonkar](https://github.com/yogeshlonkar)
* Added the `TakesFile` indicator to flag in [urfave/cli/pull/851](https://github.com/urfave/cli/pull/851) via [@saschagrunert](https://github.com/saschagrunert)
* Added fish shell completion support in [urfave/cli/pull/848](https://github.com/urfave/cli/pull/848) via [@saschagrunert](https://github.com/saschagrunert)

## [1.21.0] - 2019-08-02

### Fixed

* Fix using "slice" flag types with `EnvVar` in [urfave/cli/pull/687](https://github.com/urfave/cli/pull/687) via [@joshuarubin](https://github.com/joshuarubin)
* Fix regression of `SkipFlagParsing` behavior in [urfave/cli/pull/697](https://github.com/urfave/cli/pull/697) via [@jszwedko](https://github.com/jszwedko)
* Fix handling `ShortOptions` and `SkipArgReorder` in [urfave/cli/pull/686](https://github.com/urfave/cli/pull/686) via [@baude](https://github.com/baude)
* Fix args reordering when bool flags are present in [urfave/cli/pull/712](https://github.com/urfave/cli/pull/712) via [@windler](https://github.com/windler)
* Fix parsing of short options in [urfave/cli/pull/758](https://github.com/urfave/cli/pull/758) via [@vrothberg](https://github.com/vrothberg)
* Fix unaligned indents for the command help messages in [urfave/cli/pull/806](https://github.com/urfave/cli/pull/806) via [@mingrammer](https://github.com/mingrammer)

### Changed

* Cleaned up help output in [urfave/cli/pull/664](https://github.com/urfave/cli/pull/664) via [@maguro](https://github.com/maguro)
* Remove redundant nil checks in [urfave/cli/pull/773](https://github.com/urfave/cli/pull/773) via [@teresy](https://github.com/teresy)
* Case is now considered when sorting strings in [urfave/cli/pull/676](https://github.com/urfave/cli/pull/676) via [@rliebz](https://github.com/rliebz)

### Added

* Added _"required flags"_ support in [urfave/cli/pull/819](https://github.com/urfave/cli/pull/819) via [@lynncyrin](https://github.com/lynncyrin/)
* Backport JSON `InputSource` to v1 in [urfave/cli/pull/598](https://github.com/urfave/cli/pull/598) via [@jszwedko](https://github.com/jszwedko)
* Allow more customization of flag help strings in [urfave/cli/pull/661](https://github.com/urfave/cli/pull/661) via [@rliebz](https://github.com/rliebz)
* Allow custom `ExitError` handler function in [urfave/cli/pull/628](https://github.com/urfave/cli/pull/628) via [@phinnaeus](https://github.com/phinnaeus)
* Allow loading a variable from a file in [urfave/cli/pull/675](https://github.com/urfave/cli/pull/675) via [@jmccann](https://github.com/jmccann)
* Allow combining short bool names in [urfave/cli/pull/684](https://github.com/urfave/cli/pull/684) via [@baude](https://github.com/baude)
* Added test coverage to context in [urfave/cli/pull/788](https://github.com/urfave/cli/pull/788) via [@benzvan](https://github.com/benzvan)
* Added go module support in [urfave/cli/pull/831](https://github.com/urfave/cli/pull/831) via [@saschagrunert](https://github.com/saschagrunert)

## [1.20.0] - 2017-08-10


### Fixed ### Fixed


@@ -407,7 +470,13 @@ signature of `func(*cli.Context) error`, as defined by `cli.ActionFunc`.
### Added ### Added
- Initial implementation. - Initial implementation.


[Unreleased]: https://github.com/urfave/cli/compare/v1.18.0...HEAD
[Unreleased]: https://github.com/urfave/cli/compare/v1.22.1...HEAD
[1.22.1]: https://github.com/urfave/cli/compare/v1.22.0...v1.22.1
[1.22.0]: https://github.com/urfave/cli/compare/v1.21.0...v1.22.0
[1.21.0]: https://github.com/urfave/cli/compare/v1.20.0...v1.21.0
[1.20.0]: https://github.com/urfave/cli/compare/v1.19.1...v1.20.0
[1.19.1]: https://github.com/urfave/cli/compare/v1.19.0...v1.19.1
[1.19.0]: https://github.com/urfave/cli/compare/v1.18.0...v1.19.0
[1.18.0]: https://github.com/urfave/cli/compare/v1.17.0...v1.18.0 [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.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.16.0]: https://github.com/urfave/cli/compare/v1.15.0...v1.16.0


+ 74
- 0
vendor/github.com/urfave/cli/CODE_OF_CONDUCT.md View 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


+ 18
- 0
vendor/github.com/urfave/cli/CONTRIBUTING.md View File

@@ -0,0 +1,18 @@
## Contributing

Use @urfave/cli to ping the maintainers.

Feel free to put up a pull request to fix a bug or maybe add a feature. We will
give it a code review and make sure that it does not break backwards
compatibility. If collaborators agree that it is in line with
the vision of the project, we will work with you to get the code into
a mergeable state and merge it into the master branch.

If you have contributed something significant to the project, we will most
likely add you as a collaborator. As a collaborator you are given the ability
to merge others pull requests. It is very important that new code does not
break existing code, so be careful about what code you do choose to merge.

If you feel like you have contributed to the project but have not yet been added
as a collaborator, we probably forgot to add you :sweat_smile:. Please open an
issue!

+ 253
- 63
vendor/github.com/urfave/cli/README.md View File

@@ -3,15 +3,11 @@ cli


[![Build Status](https://travis-ci.org/urfave/cli.svg?branch=master)](https://travis-ci.org/urfave/cli) [![Build Status](https://travis-ci.org/urfave/cli.svg?branch=master)](https://travis-ci.org/urfave/cli)
[![Windows Build Status](https://ci.appveyor.com/api/projects/status/rtgk5xufi932pb2v?svg=true)](https://ci.appveyor.com/project/urfave/cli) [![Windows Build Status](https://ci.appveyor.com/api/projects/status/rtgk5xufi932pb2v?svg=true)](https://ci.appveyor.com/project/urfave/cli)

[![GoDoc](https://godoc.org/github.com/urfave/cli?status.svg)](https://godoc.org/github.com/urfave/cli) [![GoDoc](https://godoc.org/github.com/urfave/cli?status.svg)](https://godoc.org/github.com/urfave/cli)
[![codebeat](https://codebeat.co/badges/0a8f30aa-f975-404b-b878-5fab3ae1cc5f)](https://codebeat.co/projects/github-com-urfave-cli) [![codebeat](https://codebeat.co/badges/0a8f30aa-f975-404b-b878-5fab3ae1cc5f)](https://codebeat.co/projects/github-com-urfave-cli)
[![Go Report Card](https://goreportcard.com/badge/urfave/cli)](https://goreportcard.com/report/urfave/cli) [![Go Report Card](https://goreportcard.com/badge/urfave/cli)](https://goreportcard.com/report/urfave/cli)
[![top level coverage](https://gocover.io/_badge/github.com/urfave/cli?0 "top level coverage")](http://gocover.io/github.com/urfave/cli) /
[![altsrc coverage](https://gocover.io/_badge/github.com/urfave/cli/altsrc?0 "altsrc coverage")](http://gocover.io/github.com/urfave/cli/altsrc)

**Notice:** This is the library formerly known as
`github.com/codegangsta/cli` -- Github will automatically redirect requests
to this repository, but we recommend updating your references for clarity.
[![codecov](https://codecov.io/gh/urfave/cli/branch/master/graph/badge.svg)](https://codecov.io/gh/urfave/cli)


cli is a simple, fast, and fun package for building command line apps in Go. The cli is a simple, fast, and fun package for building command line apps in Go. The
goal is to enable developers to write fast and distributable command line goal is to enable developers to write fast and distributable command line
@@ -23,7 +19,7 @@ applications in an expressive way.
- [Installation](#installation) - [Installation](#installation)
* [Supported platforms](#supported-platforms) * [Supported platforms](#supported-platforms)
* [Using the `v2` branch](#using-the-v2-branch) * [Using the `v2` branch](#using-the-v2-branch)
* [Pinning to the `v1` releases](#pinning-to-the-v1-releases)
* [Using `v1` releases](#using-v1-releases)
- [Getting Started](#getting-started) - [Getting Started](#getting-started)
- [Examples](#examples) - [Examples](#examples)
* [Arguments](#arguments) * [Arguments](#arguments)
@@ -32,10 +28,13 @@ applications in an expressive way.
+ [Alternate Names](#alternate-names) + [Alternate Names](#alternate-names)
+ [Ordering](#ordering) + [Ordering](#ordering)
+ [Values from the Environment](#values-from-the-environment) + [Values from the Environment](#values-from-the-environment)
+ [Values from files](#values-from-files)
+ [Values from alternate input sources (YAML, TOML, and others)](#values-from-alternate-input-sources-yaml-toml-and-others) + [Values from alternate input sources (YAML, TOML, and others)](#values-from-alternate-input-sources-yaml-toml-and-others)
+ [Precedence](#precedence)
* [Subcommands](#subcommands) * [Subcommands](#subcommands)
* [Subcommands categories](#subcommands-categories) * [Subcommands categories](#subcommands-categories)
* [Exit code](#exit-code) * [Exit code](#exit-code)
* [Combining short options](#combining-short-options)
* [Bash Completion](#bash-completion) * [Bash Completion](#bash-completion)
+ [Enabling](#enabling) + [Enabling](#enabling)
+ [Distribution](#distribution) + [Distribution](#distribution)
@@ -61,7 +60,7 @@ organized, and expressive!


## Installation ## Installation


Make sure you have a working Go environment. Go version 1.2+ is supported. [See
Make sure you have a working Go environment. Go version 1.10+ is supported. [See
the install instructions for Go](http://golang.org/doc/install.html). the install instructions for Go](http://golang.org/doc/install.html).


To install cli, simply run: To install cli, simply run:
@@ -105,25 +104,20 @@ import (
... ...
``` ```


### Pinning to the `v1` releases

Similarly to the section above describing use of the `v2` branch, if one wants
to avoid any unexpected compatibility pains once `v2` becomes `master`, then
pinning to `v1` is an acceptable option, e.g.:
### Using `v1` releases


``` ```
$ go get gopkg.in/urfave/cli.v1
$ go get github.com/urfave/cli
``` ```


``` go
```go
... ...
import ( import (
"gopkg.in/urfave/cli.v1" // imports as package "cli"
"github.com/urfave/cli"
) )
... ...
``` ```


This will pull the latest tagged `v1` release (e.g. `v1.18.1` at the time of writing).


## Getting Started ## Getting Started


@@ -138,13 +132,17 @@ discovery. So a cli app can be as little as one line of code in `main()`.
package main package main


import ( import (
"log"
"os" "os"


"github.com/urfave/cli" "github.com/urfave/cli"
) )


func main() { func main() {
cli.NewApp().Run(os.Args)
err := cli.NewApp().Run(os.Args)
if err != nil {
log.Fatal(err)
}
} }
``` ```


@@ -159,6 +157,7 @@ package main


import ( import (
"fmt" "fmt"
"log"
"os" "os"


"github.com/urfave/cli" "github.com/urfave/cli"
@@ -173,7 +172,10 @@ func main() {
return nil return nil
} }


app.Run(os.Args)
err := app.Run(os.Args)
if err != nil {
log.Fatal(err)
}
} }
``` ```


@@ -197,6 +199,7 @@ package main


import ( import (
"fmt" "fmt"
"log"
"os" "os"


"github.com/urfave/cli" "github.com/urfave/cli"
@@ -211,7 +214,10 @@ func main() {
return nil return nil
} }


app.Run(os.Args)
err := app.Run(os.Args)
if err != nil {
log.Fatal(err)
}
} }
``` ```


@@ -260,6 +266,7 @@ package main


import ( import (
"fmt" "fmt"
"log"
"os" "os"


"github.com/urfave/cli" "github.com/urfave/cli"
@@ -273,7 +280,10 @@ func main() {
return nil return nil
} }


app.Run(os.Args)
err := app.Run(os.Args)
if err != nil {
log.Fatal(err)
}
} }
``` ```


@@ -289,6 +299,7 @@ package main


import ( import (
"fmt" "fmt"
"log"
"os" "os"


"github.com/urfave/cli" "github.com/urfave/cli"
@@ -318,7 +329,10 @@ func main() {
return nil return nil
} }


app.Run(os.Args)
err := app.Run(os.Args)
if err != nil {
log.Fatal(err)
}
} }
``` ```


@@ -332,6 +346,7 @@ scanned.
package main package main


import ( import (
"log"
"os" "os"
"fmt" "fmt"


@@ -365,7 +380,10 @@ func main() {
return nil return nil
} }


app.Run(os.Args)
err := app.Run(os.Args)
if err != nil {
log.Fatal(err)
}
} }
``` ```


@@ -386,6 +404,7 @@ For example this:
package main package main


import ( import (
"log"
"os" "os"


"github.com/urfave/cli" "github.com/urfave/cli"
@@ -401,7 +420,10 @@ func main() {
}, },
} }


app.Run(os.Args)
err := app.Run(os.Args)
if err != nil {
log.Fatal(err)
}
} }
``` ```


@@ -427,6 +449,7 @@ list for the `Name`. e.g.
package main package main


import ( import (
"log"
"os" "os"


"github.com/urfave/cli" "github.com/urfave/cli"
@@ -443,7 +466,10 @@ func main() {
}, },
} }


app.Run(os.Args)
err := app.Run(os.Args)
if err != nil {
log.Fatal(err)
}
} }
``` ```


@@ -467,6 +493,7 @@ For example this:
package main package main


import ( import (
"log"
"os" "os"
"sort" "sort"


@@ -510,7 +537,10 @@ func main() {
sort.Sort(cli.FlagsByName(app.Flags)) sort.Sort(cli.FlagsByName(app.Flags))
sort.Sort(cli.CommandsByName(app.Commands)) sort.Sort(cli.CommandsByName(app.Commands))


app.Run(os.Args)
err := app.Run(os.Args)
if err != nil {
log.Fatal(err)
}
} }
``` ```


@@ -533,6 +563,7 @@ You can also have the default value set from the environment via `EnvVar`. e.g.
package main package main


import ( import (
"log"
"os" "os"


"github.com/urfave/cli" "github.com/urfave/cli"
@@ -550,7 +581,10 @@ func main() {
}, },
} }


app.Run(os.Args)
err := app.Run(os.Args)
if err != nil {
log.Fatal(err)
}
} }
``` ```


@@ -565,6 +599,7 @@ environment variable that resolves is used as the default.
package main package main


import ( import (
"log"
"os" "os"


"github.com/urfave/cli" "github.com/urfave/cli"
@@ -582,10 +617,52 @@ func main() {
}, },
} }


app.Run(os.Args)
err := app.Run(os.Args)
if err != nil {
log.Fatal(err)
}
} }
``` ```


#### Values from files

You can also have the default value set from file via `FilePath`. e.g.

<!-- {
"args": ["&#45;&#45;help"],
"output": "password for the mysql database"
} -->
``` go
package main

import (
"log"
"os"

"github.com/urfave/cli"
)

func main() {
app := cli.NewApp()

app.Flags = []cli.Flag {
cli.StringFlag{
Name: "password, p",
Usage: "password for the mysql database",
FilePath: "/etc/mysql/password",
},
}

err := app.Run(os.Args)
if err != nil {
log.Fatal(err)
}
}
```

Note that default values set from file (e.g. `FilePath`) take precedence over
default values set from the environment (e.g. `EnvVar`).

#### Values from alternate input sources (YAML, TOML, and others) #### Values from alternate input sources (YAML, TOML, and others)


There is a separate package altsrc that adds support for getting flag values There is a separate package altsrc that adds support for getting flag values
@@ -593,6 +670,7 @@ from other file input sources.


Currently supported input source formats: Currently supported input source formats:
* YAML * YAML
* JSON
* TOML * TOML


In order to get values for a flag from an alternate input source the following In order to get values for a flag from an alternate input source the following
@@ -615,9 +693,9 @@ the yaml input source for any flags that are defined on that command. As a note
the "load" flag used would also have to be defined on the command flags in order the "load" flag used would also have to be defined on the command flags in order
for this code snipped to work. for this code snipped to work.


Currently only the aboved specified formats are supported but developers can
add support for other input sources by implementing the
altsrc.InputSourceContext for their given sources.
Currently only YAML, JSON, and TOML files are supported but developers can add support
for other input sources by implementing the altsrc.InputSourceContext for their
given sources.


Here is a more complete sample of a command using YAML support: Here is a more complete sample of a command using YAML support:


@@ -630,6 +708,7 @@ package notmain


import ( import (
"fmt" "fmt"
"log"
"os" "os"


"github.com/urfave/cli" "github.com/urfave/cli"
@@ -652,10 +731,22 @@ func main() {
app.Before = altsrc.InitInputSourceWithContext(flags, altsrc.NewYamlSourceFromFlagFunc("load")) app.Before = altsrc.InitInputSourceWithContext(flags, altsrc.NewYamlSourceFromFlagFunc("load"))
app.Flags = flags app.Flags = flags


app.Run(os.Args)
err := app.Run(os.Args)
if err != nil {
log.Fatal(err)
}
} }
``` ```


#### Precedence

The precedence for flag value sources is as follows (highest to lowest):

0. Command line flag value from user
0. Environment variable (if specified)
0. Configuration file (if specified)
0. Default defined on the flag

### Subcommands ### Subcommands


Subcommands can be defined for a more git-like command line app. Subcommands can be defined for a more git-like command line app.
@@ -669,6 +760,7 @@ package main


import ( import (
"fmt" "fmt"
"log"
"os" "os"


"github.com/urfave/cli" "github.com/urfave/cli"
@@ -721,7 +813,10 @@ func main() {
}, },
} }


app.Run(os.Args)
err := app.Run(os.Args)
if err != nil {
log.Fatal(err)
}
} }
``` ```


@@ -737,6 +832,7 @@ E.g.
package main package main


import ( import (
"log"
"os" "os"


"github.com/urfave/cli" "github.com/urfave/cli"
@@ -751,15 +847,18 @@ func main() {
}, },
{ {
Name: "add", Name: "add",
Category: "template",
Category: "Template actions",
}, },
{ {
Name: "remove", Name: "remove",
Category: "template",
Category: "Template actions",
}, },
} }


app.Run(os.Args)
err := app.Run(os.Args)
if err != nil {
log.Fatal(err)
}
} }
``` ```


@@ -767,7 +866,7 @@ Will include:


``` ```
COMMANDS: COMMANDS:
noop
noop


Template actions: Template actions:
add add
@@ -780,11 +879,14 @@ Calling `App.Run` will not automatically call `os.Exit`, which means that by
default the exit code will "fall through" to being `0`. An explicit exit code default the exit code will "fall through" to being `0`. An explicit exit code
may be set by returning a non-nil error that fulfills `cli.ExitCoder`, *or* a may be set by returning a non-nil error that fulfills `cli.ExitCoder`, *or* a
`cli.MultiError` that includes an error that fulfills `cli.ExitCoder`, e.g.: `cli.MultiError` that includes an error that fulfills `cli.ExitCoder`, e.g.:

<!-- {
"error": "Ginger croutons are not in the soup"
} -->
``` go ``` go
package main package main


import ( import (
"log"
"os" "os"


"github.com/urfave/cli" "github.com/urfave/cli"
@@ -793,22 +895,95 @@ import (
func main() { func main() {
app := cli.NewApp() app := cli.NewApp()
app.Flags = []cli.Flag{ app.Flags = []cli.Flag{
cli.BoolTFlag{
cli.BoolFlag{
Name: "ginger-crouton", Name: "ginger-crouton",
Usage: "is it in the soup?",
Usage: "Add ginger croutons to the soup",
}, },
} }
app.Action = func(ctx *cli.Context) error { app.Action = func(ctx *cli.Context) error {
if !ctx.Bool("ginger-crouton") { if !ctx.Bool("ginger-crouton") {
return cli.NewExitError("it is not in the soup", 86)
return cli.NewExitError("Ginger croutons are not in the soup", 86)
} }
return nil return nil
} }


app.Run(os.Args)
err := app.Run(os.Args)
if err != nil {
log.Fatal(err)
}
}
```

### Combining short options

Traditional use of options using their shortnames look like this:

```
$ cmd -s -o -m "Some message"
```

Suppose you want users to be able to combine options with their shortnames. This
can be done using the `UseShortOptionHandling` bool in your app configuration,
or for individual commands by attaching it to the command configuration. For
example:

<!-- {
"args": ["short", "&#45;som", "Some message"],
"output": "serve: true\noption: true\nmessage: Some message\n"
} -->
``` go
package main

import (
"fmt"
"log"
"os"

"github.com/urfave/cli"
)

func main() {
app := cli.NewApp()
app.UseShortOptionHandling = true
app.Commands = []cli.Command{
{
Name: "short",
Usage: "complete a task on the list",
Flags: []cli.Flag{
cli.BoolFlag{Name: "serve, s"},
cli.BoolFlag{Name: "option, o"},
cli.StringFlag{Name: "message, m"},
},
Action: func(c *cli.Context) error {
fmt.Println("serve:", c.Bool("serve"))
fmt.Println("option:", c.Bool("option"))
fmt.Println("message:", c.String("message"))
return nil
},
},
}

err := app.Run(os.Args)
if err != nil {
log.Fatal(err)
}
} }
``` ```


If your program has any number of bool flags such as `serve` and `option`, and
optionally one non-bool flag `message`, with the short options of `-s`, `-o`,
and `-m` respectively, setting `UseShortOptionHandling` will also support the
following syntax:

```
$ cmd -som "Some message"
```

If you enable `UseShortOptionHandling`, then you must not use any flags that
have a single leading `-` or this will result in failures. For example,
`-option` can no longer be used. Flags with two leading dashes (such as
`--options`) are still valid.

### Bash Completion ### Bash Completion


You can enable completion commands by setting the `EnableBashCompletion` You can enable completion commands by setting the `EnableBashCompletion`
@@ -825,6 +1000,7 @@ package main


import ( import (
"fmt" "fmt"
"log"
"os" "os"


"github.com/urfave/cli" "github.com/urfave/cli"
@@ -856,7 +1032,10 @@ func main() {
}, },
} }


app.Run(os.Args)
err := app.Run(os.Args)
if err != nil {
log.Fatal(err)
}
} }
``` ```


@@ -896,6 +1075,7 @@ The default bash completion flag (`--generate-bash-completion`) is defined as
package main package main


import ( import (
"log"
"os" "os"


"github.com/urfave/cli" "github.com/urfave/cli"
@@ -914,7 +1094,10 @@ func main() {
Name: "wat", Name: "wat",
}, },
} }
app.Run(os.Args)
err := app.Run(os.Args)
if err != nil {
log.Fatal(err)
}
} }
``` ```


@@ -940,6 +1123,7 @@ package main


import ( import (
"fmt" "fmt"
"log"
"io" "io"
"os" "os"


@@ -983,7 +1167,10 @@ VERSION:
fmt.Println("Ha HA. I pwnd the help!!1") fmt.Println("Ha HA. I pwnd the help!!1")
} }


cli.NewApp().Run(os.Args)
err := cli.NewApp().Run(os.Args)
if err != nil {
log.Fatal(err)
}
} }
``` ```


@@ -998,6 +1185,7 @@ setting `cli.HelpFlag`, e.g.:
package main package main


import ( import (
"log"
"os" "os"


"github.com/urfave/cli" "github.com/urfave/cli"
@@ -1010,7 +1198,10 @@ func main() {
EnvVar: "SHOW_HALP,HALPPLZ", EnvVar: "SHOW_HALP,HALPPLZ",
} }


cli.NewApp().Run(os.Args)
err := cli.NewApp().Run(os.Args)
if err != nil {
log.Fatal(err)
}
} }
``` ```


@@ -1033,6 +1224,7 @@ setting `cli.VersionFlag`, e.g.:
package main package main


import ( import (
"log"
"os" "os"


"github.com/urfave/cli" "github.com/urfave/cli"
@@ -1047,7 +1239,10 @@ func main() {
app := cli.NewApp() app := cli.NewApp()
app.Name = "partay" app.Name = "partay"
app.Version = "19.99.0" app.Version = "19.99.0"
app.Run(os.Args)
err := app.Run(os.Args)
if err != nil {
log.Fatal(err)
}
} }
``` ```


@@ -1062,6 +1257,7 @@ package main


import ( import (
"fmt" "fmt"
"log"
"os" "os"


"github.com/urfave/cli" "github.com/urfave/cli"
@@ -1079,7 +1275,10 @@ func main() {
app := cli.NewApp() app := cli.NewApp()
app.Name = "partay" app.Name = "partay"
app.Version = "19.99.0" app.Version = "19.99.0"
app.Run(os.Args)
err := app.Run(os.Args)
if err != nil {
log.Fatal(err)
}
} }
``` ```


@@ -1236,6 +1435,7 @@ func main() {
cli.Uint64Flag{Name: "bigage"}, cli.Uint64Flag{Name: "bigage"},
} }
app.EnableBashCompletion = true app.EnableBashCompletion = true
app.UseShortOptionHandling = true
app.HideHelp = false app.HideHelp = false
app.HideVersion = false app.HideVersion = false
app.BashComplete = func(c *cli.Context) { app.BashComplete = func(c *cli.Context) {
@@ -1341,7 +1541,7 @@ func main() {
ec := cli.NewExitError("ohwell", 86) ec := cli.NewExitError("ohwell", 86)
fmt.Fprintf(c.App.Writer, "%d", ec.ExitCode()) fmt.Fprintf(c.App.Writer, "%d", ec.ExitCode())
fmt.Printf("made it!\n") fmt.Printf("made it!\n")
return ec
return nil
} }


if os.Getenv("HEXY") != "" { if os.Getenv("HEXY") != "" {
@@ -1355,7 +1555,9 @@ func main() {
"whatever-values": 19.99, "whatever-values": 19.99,
} }


app.Run(os.Args)

// ignore error so we don't exit non-zero and break gfmrun README example tests
_ = app.Run(os.Args)
} }


func wopAction(c *cli.Context) error { func wopAction(c *cli.Context) error {
@@ -1366,16 +1568,4 @@ func wopAction(c *cli.Context) error {


## Contribution Guidelines ## Contribution Guidelines


Feel free to put up a pull request to fix a bug or maybe add a feature. I will
give it a code review and make sure that it does not break backwards
compatibility. If I or any other collaborators agree that it is in line with
the vision of the project, we will work with you to get the code into
a mergeable state and merge it into the master branch.

If you have contributed something significant to the project, we will most
likely add you as a collaborator. As a collaborator you are given the ability
to merge others pull requests. It is very important that new code does not
break existing code, so be careful about what code you do choose to merge.

If you feel like you have contributed to the project but have not yet been
added as a collaborator, we probably forgot to add you, please open an issue.
See [./CONTRIBUTING.md](./CONTRIBUTING.md)

+ 73
- 40
vendor/github.com/urfave/cli/app.go View File

@@ -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"
@@ -11,9 +11,10 @@ import (
) )


var ( var (
changeLogURL = "https://github.com/urfave/cli/blob/master/CHANGELOG.md"
appActionDeprecationURL = fmt.Sprintf("%s#deprecated-cli-app-action-signature", changeLogURL)
runAndExitOnErrorDeprecationURL = fmt.Sprintf("%s#deprecated-cli-app-runandexitonerror", changeLogURL)
changeLogURL = "https://github.com/urfave/cli/blob/master/CHANGELOG.md"
appActionDeprecationURL = fmt.Sprintf("%s#deprecated-cli-app-action-signature", 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 := flagSet(a.Name, a.Flags)
_, err = a.newFlagSet()
if err != nil { if err != nil {
return err return err
} }


set.SetOutput(ioutil.Discard)
err = set.Parse(arguments[1:])
set, err := parseIter(a, 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)
ShowAppHelp(context)
_, _ = fmt.Fprintln(a.Writer, nerr)
_ = 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())
ShowAppHelp(context)
_, _ = fmt.Fprintf(a.Writer, "%s %s\n\n", "Incorrect Usage.", err.Error())
_ = 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)
HandleExitCoder(beforeErr)
_, _ = fmt.Fprintf(a.Writer, "%v\n\n", 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 := flagSet(a.Name, a.Flags)
_, err = a.newFlagSet()
if err != nil { if err != nil {
return err return err
} }


set.SetOutput(ioutil.Discard)
err = set.Parse(ctx.Args().Tail())
set, err := parseIter(a, 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)
_, _ = fmt.Fprintln(a.Writer, nerr)
_, _ = 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())
ShowSubcommandHelp(context)
_, _ = fmt.Fprintf(a.Writer, "%s %s\n\n", "Incorrect Usage.", err.Error())
_ = 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
} }

+ 9
- 12
vendor/github.com/urfave/cli/appveyor.yml View File

@@ -8,19 +8,16 @@ clone_folder: c:\gopath\src\github.com\urfave\cli


environment: environment:
GOPATH: C:\gopath GOPATH: C:\gopath
GOVERSION: 1.8.x
PYTHON: C:\Python36-x64
PYTHON_VERSION: 3.6.x
PYTHON_ARCH: 64
GOVERSION: 1.11.x


install: install:
- set PATH=%GOPATH%\bin;C:\go\bin;%PATH%
- go version
- go env
- go get github.com/urfave/gfmrun/...
- go get -v -t ./...
- set PATH=%GOPATH%\bin;C:\go\bin;%PATH%
- go version
- go env
- go get github.com/urfave/gfmrun/...
- go get -v -t ./...


build_script: build_script:
- python runtests vet
- python runtests test
- python runtests gfmrun
- go run build.go vet
- go run build.go test
- go run build.go gfmrun

+ 1
- 1
vendor/github.com/urfave/cli/category.go View File

@@ -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 {


+ 1
- 1
vendor/github.com/urfave/cli/cli.go View File

@@ -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

+ 90
- 59
vendor/github.com/urfave/cli/command.go View File

@@ -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 err != nil {
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 {
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())
if ctx.App.UseShortOptionHandling {
c.UseShortOptionHandling = true
} }


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
}
set, err := c.parseFlags(ctx.Args().Tail())


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)
ShowCommandHelp(context, c.Name)
_, _ = fmt.Fprintln(context.App.Writer, "Incorrect Usage:", err.Error())
_, _ = fmt.Fprintln(context.App.Writer)
_ = 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)
HandleExitCoder(err)
_ = ShowCommandHelp(context, c.Name)
context.App.handleExitCoder(context, err)
return err return err
} }
} }
@@ -210,11 +174,76 @@ 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(args)
}

set, err := parseIter(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 before arguments as this is what flag expects
func reorderArgs(args []string) []string {
var nonflags, flags []string

readFlagValue := false
for i, arg := range args {
if arg == "--" {
nonflags = append(nonflags, args[i:]...)
break
}

if readFlagValue && !strings.HasPrefix(arg, "-") && !strings.HasPrefix(arg, "--") {
readFlagValue = false
flags = append(flags, arg)
continue
}
readFlagValue = false

if arg != "-" && strings.HasPrefix(arg, "-") {
flags = append(flags, arg)

readFlagValue = !strings.Contains(arg, "=")
} else {
nonflags = append(nonflags, arg)
}
}

return append(flags, nonflags...)
}

// 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 +268,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 +297,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
- 16
vendor/github.com/urfave/cli/context.go View File

@@ -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,18 +95,26 @@ func (c *Context) IsSet(name string) bool {
val = val.Elem() val = val.Elem()
} }


envVarValue := val.FieldByName("EnvVar")
if !envVarValue.IsValid() {
return
filePathValue := val.FieldByName("FilePath")
if filePathValue.IsValid() {
eachName(filePathValue.String(), func(filePath string) {
if _, err := os.Stat(filePath); err == nil {
c.setFlags[name] = true
return
}
})
} }


eachName(envVarValue.String(), func(envVar string) {
envVar = strings.TrimSpace(envVar)
if _, ok := syscall.Getenv(envVar); ok {
c.setFlags[name] = true
return
}
})
envVarValue := val.FieldByName("EnvVar")
if envVarValue.IsValid() {
eachName(envVarValue.String(), func(envVar string) {
envVar = strings.TrimSpace(envVar)
if _, ok := syscall.Getenv(envVar); ok {
c.setFlags[name] = true
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 {
name := strings.Split(flag.GetName(), ",")[0]
for _, f := range c.Command.Flags {
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 {
name := strings.Split(flag.GetName(), ",")[0]
for _, f := range c.App.Flags {
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
- 0
vendor/github.com/urfave/cli/docs.go View 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
- 0
vendor/github.com/urfave/cli/fish.go View 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)
}

+ 0
- 93
vendor/github.com/urfave/cli/flag-types.json View File

@@ -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)"
}
]

+ 103
- 556
vendor/github.com/urfave/cli/flag.go View File

@@ -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 of 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{}
for _, flag := range fl {
field := flagValue(flag).FieldByName("Hidden")
var visible []Flag
for _, f := range fl {
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(),
stringifyIntSliceFlag(f.(IntSliceFlag)))
return FlagFileHinter(
fv.FieldByName("FilePath").String(),
FlagEnvHinter(
fv.FieldByName("EnvVar").String(),
stringifyIntSliceFlag(f.(IntSliceFlag)),
),
)
case Int64SliceFlag: case Int64SliceFlag:
return withEnvHint(fv.FieldByName("EnvVar").String(),
stringifyInt64SliceFlag(f.(Int64SliceFlag)))
return FlagFileHinter(
fv.FieldByName("FilePath").String(),
FlagEnvHinter(
fv.FieldByName("EnvVar").String(),
stringifyInt64SliceFlag(f.(Int64SliceFlag)),
),
)
case StringSliceFlag: case StringSliceFlag:
return withEnvHint(fv.FieldByName("EnvVar").String(),
stringifyStringSliceFlag(f.(StringSliceFlag)))
return FlagFileHinter(
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(),
fmt.Sprintf("%s\t%s", prefixedNames(fv.FieldByName("Name").String(), placeholder), usageWithDefault))
return FlagFileHinter(
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))
return fmt.Sprintf("%s\t%s", prefixedNames(name, placeholder), usageWithDefault)
usageWithDefault := strings.TrimSpace(usage + defaultVal)
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
- 0
vendor/github.com/urfave/cli/flag_bool.go View 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
- 0
vendor/github.com/urfave/cli/flag_bool_t.go View 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
- 0
vendor/github.com/urfave/cli/flag_duration.go View 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
- 0
vendor/github.com/urfave/cli/flag_float64.go View 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
}

+ 0
- 627
vendor/github.com/urfave/cli/flag_generated.go View File

@@ -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
- 0
vendor/github.com/urfave/cli/flag_generic.go View 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
- 0
vendor/github.com/urfave/cli/flag_int.go View 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
- 0
vendor/github.com/urfave/cli/flag_int64.go View 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
- 0
vendor/github.com/urfave/cli/flag_int64_slice.go View 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
- 0
vendor/github.com/urfave/cli/flag_int_slice.go View 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
- 0
vendor/github.com/urfave/cli/flag_string.go View 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
- 0
vendor/github.com/urfave/cli/flag_string_slice.go View 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
- 0
vendor/github.com/urfave/cli/flag_uint.go View 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
- 0
vendor/github.com/urfave/cli/flag_uint64.go View 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
- 0
vendor/github.com/urfave/cli/funcs.go View File

@@ -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

+ 0
- 255
vendor/github.com/urfave/cli/generate-flag-types View File

@@ -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
- 0
vendor/github.com/urfave/cli/go.mod View 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
- 0
vendor/github.com/urfave/cli/go.sum View 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=

+ 96
- 86
vendor/github.com/urfave/cli/help.go View File

@@ -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
}, },
} }
@@ -129,7 +61,7 @@ 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)
} }


@@ -153,19 +85,94 @@ func ShowAppHelp(c *Context) (err error) {


// 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
} }
for _, name := range command.Names() {
fmt.Fprintln(c.App.Writer, name)
if os.Getenv("_CLI_ZSH_AUTOCOMPLETE_HACK") == "1" {
for _, name := range command.Names() {
_, _ = 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)
} }


@@ -207,7 +214,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,19 +228,22 @@ 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 {
c.BashComplete(ctx)
if c != nil {
if c.BashComplete != nil {
c.BashComplete(ctx)
} else {
DefaultCompleteWithFlags(c)(ctx)
}
} }

} }


func printHelpCustom(out io.Writer, templ string, data interface{}, customFunc map[string]interface{}) { func printHelpCustom(out io.Writer, templ string, data interface{}, customFunc map[string]interface{}) {
funcMap := template.FuncMap{ funcMap := template.FuncMap{
"join": strings.Join, "join": strings.Join,
} }
if customFunc != nil {
for key, value := range customFunc {
funcMap[key] = value
}
for key, value := range customFunc {
funcMap[key] = value
} }


w := tabwriter.NewWriter(out, 1, 8, 2, ' ', 0) w := tabwriter.NewWriter(out, 1, 8, 2, ' ', 0)
@@ -243,11 +253,11 @@ 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{}) {
@@ -280,7 +290,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 +299,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
} }




+ 80
- 0
vendor/github.com/urfave/cli/parse.go View File

@@ -0,0 +1,80 @@
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(ip iterativeParser, args []string) (*flag.FlagSet, error) {
for {
set, err := ip.newFlagSet()
if err != nil {
return nil, err
}

err = set.Parse(args)
if !ip.useShortOptionHandling() || err == nil {
return set, err
}

errStr := err.Error()
trimmed := strings.TrimPrefix(errStr, "flag provided but not defined: ")
if errStr == trimmed {
return nil, err
}

// regenerate the initial args with the split short opts
newArgs := []string{}
for i, arg := range args {
if arg != trimmed {
newArgs = append(newArgs, arg)
continue
}

shortOpts := splitShortOptions(set, trimmed)
if len(shortOpts) == 1 {
return nil, err
}

// add each short option and all remaining arguments
newArgs = append(newArgs, shortOpts...)
newArgs = append(newArgs, args[i+1:]...)
args = newArgs
}
}
}

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
}

+ 0
- 122
vendor/github.com/urfave/cli/runtests View File

@@ -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
- 0
vendor/github.com/urfave/cli/sort.go View 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
- 0
vendor/github.com/urfave/cli/template.go View 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 }}`

+ 1
- 1
vendor/github.com/yuin/goldmark/parser/list.go View File

@@ -191,7 +191,7 @@ func (b *listParser) Continue(node ast.Node, reader text.Reader, pc Context) Sta
isHeading := false isHeading := false
last := pc.LastOpenedBlock().Node last := pc.LastOpenedBlock().Node
if ast.IsParagraph(last) { if ast.IsParagraph(last) {
c, ok := matchesSetextHeadingBar(line)
c, ok := matchesSetextHeadingBar(line[match[3]-1:])
if ok && c == '-' { if ok && c == '-' {
isHeading = true isHeading = true
} }


+ 1
- 1
vendor/github.com/yuin/goldmark/util/util.go View File

@@ -268,7 +268,7 @@ func FindClosure(bs []byte, opener, closure byte, codeSpan, allowNesting bool) i
if codeSpanCloser == codeSpanOpener { if codeSpanCloser == codeSpanOpener {
codeSpanOpener = 0 codeSpanOpener = 0
} }
} else if c == '\\' && i < len(bs)-1 && IsPunct(bs[i+1]) {
} else if codeSpanOpener == 0 && c == '\\' && i < len(bs)-1 && IsPunct(bs[i+1]) {
i += 2 i += 2
continue continue
} else if codeSpan && codeSpanOpener == 0 && c == '`' { } else if codeSpan && codeSpanOpener == 0 && c == '`' {


+ 1
- 1
vendor/github.com/yuin/goldmark/util/util_safe.go View File

@@ -1,4 +1,4 @@
// +build appengine,js
// +build appengine js


package util package util




+ 16
- 0
vendor/golang.org/x/tools/go/analysis/analysis.go View File

@@ -7,6 +7,8 @@ import (
"go/token" "go/token"
"go/types" "go/types"
"reflect" "reflect"

"golang.org/x/tools/internal/analysisinternal"
) )


// An Analyzer describes an analysis function and its options. // An Analyzer describes an analysis function and its options.
@@ -69,6 +71,17 @@ type Analyzer struct {


func (a *Analyzer) String() string { return a.Name } func (a *Analyzer) String() string { return a.Name }


func init() {
// Set the analysisinternal functions to be able to pass type errors
// to the Pass type without modifying the go/analysis API.
analysisinternal.SetTypeErrors = func(p interface{}, errors []types.Error) {
p.(*Pass).typeErrors = errors
}
analysisinternal.GetTypeErrors = func(p interface{}) []types.Error {
return p.(*Pass).typeErrors
}
}

// A Pass provides information to the Run function that // A Pass provides information to the Run function that
// applies a specific analyzer to a single Go package. // applies a specific analyzer to a single Go package.
// //
@@ -138,6 +151,9 @@ type Pass struct {
// WARNING: This is an experimental API and may change in the future. // WARNING: This is an experimental API and may change in the future.
AllObjectFacts func() []ObjectFact AllObjectFacts func() []ObjectFact


// typeErrors contains types.Errors that are associated with the pkg.
typeErrors []types.Error

/* Further fields may be added in future. */ /* Further fields may be added in future. */
// For example, suggested or applied refactorings. // For example, suggested or applied refactorings.
} }


+ 1
- 1
vendor/golang.org/x/tools/go/analysis/internal/analysisflags/flags.go View File

@@ -382,7 +382,7 @@ func (tree JSONTree) Add(fset *token.FileSet, id, name string, diags []analysis.
func (tree JSONTree) Print() { func (tree JSONTree) Print() {
data, err := json.MarshalIndent(tree, "", "\t") data, err := json.MarshalIndent(tree, "", "\t")
if err != nil { if err != nil {
log.Panicf("internal error: JSON marshalling failed: %v", err)
log.Panicf("internal error: JSON marshaling failed: %v", err)
} }
fmt.Printf("%s\n", data) fmt.Printf("%s\n", data)
} }

+ 4
- 8
vendor/golang.org/x/tools/go/gcexportdata/gcexportdata.go View File

@@ -85,15 +85,11 @@ func Read(in io.Reader, fset *token.FileSet, imports map[string]*types.Package,
return gcimporter.ImportData(imports, path, path, bytes.NewReader(data)) return gcimporter.ImportData(imports, path, path, bytes.NewReader(data))
} }


// The indexed export format starts with an 'i'; the older
// binary export format starts with a 'c', 'd', or 'v'
// (from "version"). Select appropriate importer.
if len(data) > 0 && data[0] == 'i' {
_, pkg, err := gcimporter.IImportData(fset, imports, data[1:], path)
return pkg, err
// The indexed export format starts with an 'i'.
if len(data) == 0 || data[0] != 'i' {
return nil, fmt.Errorf("unknown export data format")
} }

_, pkg, err := gcimporter.BImportData(fset, imports, data, path)
_, pkg, err := gcimporter.IImportData(fset, imports, data[1:], path)
return pkg, err return pkg, err
} }




+ 0
- 852
vendor/golang.org/x/tools/go/internal/gcimporter/bexport.go View File

@@ -1,852 +0,0 @@
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Binary package export.
// This file was derived from $GOROOT/src/cmd/compile/internal/gc/bexport.go;
// see that file for specification of the format.

package gcimporter

import (
"bytes"
"encoding/binary"
"fmt"
"go/ast"
"go/constant"
"go/token"
"go/types"
"math"
"math/big"
"sort"
"strings"
)

// If debugFormat is set, each integer and string value is preceded by a marker
// and position information in the encoding. This mechanism permits an importer
// to recognize immediately when it is out of sync. The importer recognizes this
// mode automatically (i.e., it can import export data produced with debugging
// support even if debugFormat is not set at the time of import). This mode will
// lead to massively larger export data (by a factor of 2 to 3) and should only
// be enabled during development and debugging.
//
// NOTE: This flag is the first flag to enable if importing dies because of
// (suspected) format errors, and whenever a change is made to the format.
const debugFormat = false // default: false

// If trace is set, debugging output is printed to std out.
const trace = false // default: false

// Current export format version. Increase with each format change.
// Note: The latest binary (non-indexed) export format is at version 6.
// This exporter is still at level 4, but it doesn't matter since
// the binary importer can handle older versions just fine.
// 6: package height (CL 105038) -- NOT IMPLEMENTED HERE
// 5: improved position encoding efficiency (issue 20080, CL 41619) -- NOT IMPLEMEMTED HERE
// 4: type name objects support type aliases, uses aliasTag
// 3: Go1.8 encoding (same as version 2, aliasTag defined but never used)
// 2: removed unused bool in ODCL export (compiler only)
// 1: header format change (more regular), export package for _ struct fields
// 0: Go1.7 encoding
const exportVersion = 4

// trackAllTypes enables cycle tracking for all types, not just named
// types. The existing compiler invariants assume that unnamed types
// that are not completely set up are not used, or else there are spurious
// errors.
// If disabled, only named types are tracked, possibly leading to slightly
// less efficient encoding in rare cases. It also prevents the export of
// some corner-case type declarations (but those are not handled correctly
// with with the textual export format either).
// TODO(gri) enable and remove once issues caused by it are fixed
const trackAllTypes = false

type exporter struct {
fset *token.FileSet
out bytes.Buffer

// object -> index maps, indexed in order of serialization
strIndex map[string]int
pkgIndex map[*types.Package]int
typIndex map[types.Type]int

// position encoding
posInfoFormat bool
prevFile string
prevLine int

// debugging support
written int // bytes written
indent int // for trace
}

// internalError represents an error generated inside this package.
type internalError string

func (e internalError) Error() string { return "gcimporter: " + string(e) }

func internalErrorf(format string, args ...interface{}) error {
return internalError(fmt.Sprintf(format, args...))
}

// BExportData returns binary export data for pkg.
// If no file set is provided, position info will be missing.
func BExportData(fset *token.FileSet, pkg *types.Package) (b []byte, err error) {
defer func() {
if e := recover(); e != nil {
if ierr, ok := e.(internalError); ok {
err = ierr
return
}
// Not an internal error; panic again.
panic(e)
}
}()

p := exporter{
fset: fset,
strIndex: map[string]int{"": 0}, // empty string is mapped to 0
pkgIndex: make(map[*types.Package]int),
typIndex: make(map[types.Type]int),
posInfoFormat: true, // TODO(gri) might become a flag, eventually
}

// write version info
// The version string must start with "version %d" where %d is the version
// number. Additional debugging information may follow after a blank; that
// text is ignored by the importer.
p.rawStringln(fmt.Sprintf("version %d", exportVersion))
var debug string
if debugFormat {
debug = "debug"
}
p.rawStringln(debug) // cannot use p.bool since it's affected by debugFormat; also want to see this clearly
p.bool(trackAllTypes)
p.bool(p.posInfoFormat)

// --- generic export data ---

// populate type map with predeclared "known" types
for index, typ := range predeclared() {
p.typIndex[typ] = index
}
if len(p.typIndex) != len(predeclared()) {
return nil, internalError("duplicate entries in type map?")
}

// write package data
p.pkg(pkg, true)
if trace {
p.tracef("\n")
}

// write objects
objcount := 0
scope := pkg.Scope()
for _, name := range scope.Names() {
if !ast.IsExported(name) {
continue
}
if trace {
p.tracef("\n")
}
p.obj(scope.Lookup(name))
objcount++
}

// indicate end of list
if trace {
p.tracef("\n")
}
p.tag(endTag)

// for self-verification only (redundant)
p.int(objcount)

if trace {
p.tracef("\n")
}

// --- end of export data ---

return p.out.Bytes(), nil
}

func (p *exporter) pkg(pkg *types.Package, emptypath bool) {
if pkg == nil {
panic(internalError("unexpected nil pkg"))
}

// if we saw the package before, write its index (>= 0)
if i, ok := p.pkgIndex[pkg]; ok {
p.index('P', i)
return
}

// otherwise, remember the package, write the package tag (< 0) and package data
if trace {
p.tracef("P%d = { ", len(p.pkgIndex))
defer p.tracef("} ")
}
p.pkgIndex[pkg] = len(p.pkgIndex)

p.tag(packageTag)
p.string(pkg.Name())
if emptypath {
p.string("")
} else {
p.string(pkg.Path())
}
}

func (p *exporter) obj(obj types.Object) {
switch obj := obj.(type) {
case *types.Const:
p.tag(constTag)
p.pos(obj)
p.qualifiedName(obj)
p.typ(obj.Type())
p.value(obj.Val())

case *types.TypeName:
if obj.IsAlias() {
p.tag(aliasTag)
p.pos(obj)
p.qualifiedName(obj)
} else {
p.tag(typeTag)
}
p.typ(obj.Type())

case *types.Var:
p.tag(varTag)
p.pos(obj)
p.qualifiedName(obj)
p.typ(obj.Type())

case *types.Func:
p.tag(funcTag)
p.pos(obj)
p.qualifiedName(obj)
sig := obj.Type().(*types.Signature)
p.paramList(sig.Params(), sig.Variadic())
p.paramList(sig.Results(), false)

default:
panic(internalErrorf("unexpected object %v (%T)", obj, obj))
}
}

func (p *exporter) pos(obj types.Object) {
if !p.posInfoFormat {
return
}

file, line := p.fileLine(obj)
if file == p.prevFile {
// common case: write line delta
// delta == 0 means different file or no line change
delta := line - p.prevLine
p.int(delta)
if delta == 0 {
p.int(-1) // -1 means no file change
}
} else {
// different file
p.int(0)
// Encode filename as length of common prefix with previous
// filename, followed by (possibly empty) suffix. Filenames
// frequently share path prefixes, so this can save a lot
// of space and make export data size less dependent on file
// path length. The suffix is unlikely to be empty because
// file names tend to end in ".go".
n := commonPrefixLen(p.prevFile, file)
p.int(n) // n >= 0
p.string(file[n:]) // write suffix only
p.prevFile = file
p.int(line)
}
p.prevLine = line
}

func (p *exporter) fileLine(obj types.Object) (file string, line int) {
if p.fset != nil {
pos := p.fset.Position(obj.Pos())
file = pos.Filename
line = pos.Line
}
return
}

func commonPrefixLen(a, b string) int {
if len(a) > len(b) {
a, b = b, a
}
// len(a) <= len(b)
i := 0
for i < len(a) && a[i] == b[i] {
i++
}
return i
}

func (p *exporter) qualifiedName(obj types.Object) {
p.string(obj.Name())
p.pkg(obj.Pkg(), false)
}

func (p *exporter) typ(t types.Type) {
if t == nil {
panic(internalError("nil type"))
}

// Possible optimization: Anonymous pointer types *T where
// T is a named type are common. We could canonicalize all
// such types *T to a single type PT = *T. This would lead
// to at most one *T entry in typIndex, and all future *T's
// would be encoded as the respective index directly. Would
// save 1 byte (pointerTag) per *T and reduce the typIndex
// size (at the cost of a canonicalization map). We can do
// this later, without encoding format change.

// if we saw the type before, write its index (>= 0)
if i, ok := p.typIndex[t]; ok {
p.index('T', i)
return
}

// otherwise, remember the type, write the type tag (< 0) and type data
if trackAllTypes {
if trace {
p.tracef("T%d = {>\n", len(p.typIndex))
defer p.tracef("<\n} ")
}
p.typIndex[t] = len(p.typIndex)
}

switch t := t.(type) {
case *types.Named:
if !trackAllTypes {
// if we don't track all types, track named types now
p.typIndex[t] = len(p.typIndex)
}

p.tag(namedTag)
p.pos(t.Obj())
p.qualifiedName(t.Obj())
p.typ(t.Underlying())
if !types.IsInterface(t) {
p.assocMethods(t)
}

case *types.Array:
p.tag(arrayTag)
p.int64(t.Len())
p.typ(t.Elem())

case *types.Slice:
p.tag(sliceTag)
p.typ(t.Elem())

case *dddSlice:
p.tag(dddTag)
p.typ(t.elem)

case *types.Struct:
p.tag(structTag)
p.fieldList(t)

case *types.Pointer:
p.tag(pointerTag)
p.typ(t.Elem())

case *types.Signature:
p.tag(signatureTag)
p.paramList(t.Params(), t.Variadic())
p.paramList(t.Results(), false)

case *types.Interface:
p.tag(interfaceTag)
p.iface(t)

case *types.Map:
p.tag(mapTag)
p.typ(t.Key())
p.typ(t.Elem())

case *types.Chan:
p.tag(chanTag)
p.int(int(3 - t.Dir())) // hack
p.typ(t.Elem())

default:
panic(internalErrorf("unexpected type %T: %s", t, t))
}
}

func (p *exporter) assocMethods(named *types.Named) {
// Sort methods (for determinism).
var methods []*types.Func
for i := 0; i < named.NumMethods(); i++ {
methods = append(methods, named.Method(i))
}
sort.Sort(methodsByName(methods))

p.int(len(methods))

if trace && methods != nil {
p.tracef("associated methods {>\n")
}

for i, m := range methods {
if trace && i > 0 {
p.tracef("\n")
}

p.pos(m)
name := m.Name()
p.string(name)
if !exported(name) {
p.pkg(m.Pkg(), false)
}

sig := m.Type().(*types.Signature)
p.paramList(types.NewTuple(sig.Recv()), false)
p.paramList(sig.Params(), sig.Variadic())
p.paramList(sig.Results(), false)
p.int(0) // dummy value for go:nointerface pragma - ignored by importer
}

if trace && methods != nil {
p.tracef("<\n} ")
}
}

type methodsByName []*types.Func

func (x methodsByName) Len() int { return len(x) }
func (x methodsByName) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
func (x methodsByName) Less(i, j int) bool { return x[i].Name() < x[j].Name() }

func (p *exporter) fieldList(t *types.Struct) {
if trace && t.NumFields() > 0 {
p.tracef("fields {>\n")
defer p.tracef("<\n} ")
}

p.int(t.NumFields())
for i := 0; i < t.NumFields(); i++ {
if trace && i > 0 {
p.tracef("\n")
}
p.field(t.Field(i))
p.string(t.Tag(i))
}
}

func (p *exporter) field(f *types.Var) {
if !f.IsField() {
panic(internalError("field expected"))
}

p.pos(f)
p.fieldName(f)
p.typ(f.Type())
}

func (p *exporter) iface(t *types.Interface) {
// TODO(gri): enable importer to load embedded interfaces,
// then emit Embeddeds and ExplicitMethods separately here.
p.int(0)

n := t.NumMethods()
if trace && n > 0 {
p.tracef("methods {>\n")
defer p.tracef("<\n} ")
}
p.int(n)
for i := 0; i < n; i++ {
if trace && i > 0 {
p.tracef("\n")
}
p.method(t.Method(i))
}
}

func (p *exporter) method(m *types.Func) {
sig := m.Type().(*types.Signature)
if sig.Recv() == nil {
panic(internalError("method expected"))
}

p.pos(m)
p.string(m.Name())
if m.Name() != "_" && !ast.IsExported(m.Name()) {
p.pkg(m.Pkg(), false)
}

// interface method; no need to encode receiver.
p.paramList(sig.Params(), sig.Variadic())
p.paramList(sig.Results(), false)
}

func (p *exporter) fieldName(f *types.Var) {
name := f.Name()

if f.Anonymous() {
// anonymous field - we distinguish between 3 cases:
// 1) field name matches base type name and is exported
// 2) field name matches base type name and is not exported
// 3) field name doesn't match base type name (alias name)
bname := basetypeName(f.Type())
if name == bname {
if ast.IsExported(name) {
name = "" // 1) we don't need to know the field name or package
} else {
name = "?" // 2) use unexported name "?" to force package export
}
} else {
// 3) indicate alias and export name as is
// (this requires an extra "@" but this is a rare case)
p.string("@")
}
}

p.string(name)
if name != "" && !ast.IsExported(name) {
p.pkg(f.Pkg(), false)
}
}

func basetypeName(typ types.Type) string {
switch typ := deref(typ).(type) {
case *types.Basic:
return typ.Name()
case *types.Named:
return typ.Obj().Name()
default:
return "" // unnamed type
}
}

func (p *exporter) paramList(params *types.Tuple, variadic bool) {
// use negative length to indicate unnamed parameters
// (look at the first parameter only since either all
// names are present or all are absent)
n := params.Len()
if n > 0 && params.At(0).Name() == "" {
n = -n
}
p.int(n)
for i := 0; i < params.Len(); i++ {
q := params.At(i)
t := q.Type()
if variadic && i == params.Len()-1 {
t = &dddSlice{t.(*types.Slice).Elem()}
}
p.typ(t)
if n > 0 {
name := q.Name()
p.string(name)
if name != "_" {
p.pkg(q.Pkg(), false)
}
}
p.string("") // no compiler-specific info
}
}

func (p *exporter) value(x constant.Value) {
if trace {
p.tracef("= ")
}

switch x.Kind() {
case constant.Bool:
tag := falseTag
if constant.BoolVal(x) {
tag = trueTag
}
p.tag(tag)

case constant.Int:
if v, exact := constant.Int64Val(x); exact {
// common case: x fits into an int64 - use compact encoding
p.tag(int64Tag)
p.int64(v)
return
}
// uncommon case: large x - use float encoding
// (powers of 2 will be encoded efficiently with exponent)
p.tag(floatTag)
p.float(constant.ToFloat(x))

case constant.Float:
p.tag(floatTag)
p.float(x)

case constant.Complex:
p.tag(complexTag)
p.float(constant.Real(x))
p.float(constant.Imag(x))

case constant.String:
p.tag(stringTag)
p.string(constant.StringVal(x))

case constant.Unknown:
// package contains type errors
p.tag(unknownTag)

default:
panic(internalErrorf("unexpected value %v (%T)", x, x))
}
}

func (p *exporter) float(x constant.Value) {
if x.Kind() != constant.Float {
panic(internalErrorf("unexpected constant %v, want float", x))
}
// extract sign (there is no -0)
sign := constant.Sign(x)
if sign == 0 {
// x == 0
p.int(0)
return
}
// x != 0

var f big.Float
if v, exact := constant.Float64Val(x); exact {
// float64
f.SetFloat64(v)
} else if num, denom := constant.Num(x), constant.Denom(x); num.Kind() == constant.Int {
// TODO(gri): add big.Rat accessor to constant.Value.
r := valueToRat(num)
f.SetRat(r.Quo(r, valueToRat(denom)))
} else {
// Value too large to represent as a fraction => inaccessible.
// TODO(gri): add big.Float accessor to constant.Value.
f.SetFloat64(math.MaxFloat64) // FIXME
}

// extract exponent such that 0.5 <= m < 1.0
var m big.Float
exp := f.MantExp(&m)

// extract mantissa as *big.Int
// - set exponent large enough so mant satisfies mant.IsInt()
// - get *big.Int from mant
m.SetMantExp(&m, int(m.MinPrec()))
mant, acc := m.Int(nil)
if acc != big.Exact {
panic(internalError("internal error"))
}

p.int(sign)
p.int(exp)
p.string(string(mant.Bytes()))
}

func valueToRat(x constant.Value) *big.Rat {
// Convert little-endian to big-endian.
// I can't believe this is necessary.
bytes := constant.Bytes(x)
for i := 0; i < len(bytes)/2; i++ {
bytes[i], bytes[len(bytes)-1-i] = bytes[len(bytes)-1-i], bytes[i]
}
return new(big.Rat).SetInt(new(big.Int).SetBytes(bytes))
}

func (p *exporter) bool(b bool) bool {
if trace {
p.tracef("[")
defer p.tracef("= %v] ", b)
}

x := 0
if b {
x = 1
}
p.int(x)
return b
}

// ----------------------------------------------------------------------------
// Low-level encoders

func (p *exporter) index(marker byte, index int) {
if index < 0 {
panic(internalError("invalid index < 0"))
}
if debugFormat {
p.marker('t')
}
if trace {
p.tracef("%c%d ", marker, index)
}
p.rawInt64(int64(index))
}

func (p *exporter) tag(tag int) {
if tag >= 0 {
panic(internalError("invalid tag >= 0"))
}
if debugFormat {
p.marker('t')
}
if trace {
p.tracef("%s ", tagString[-tag])
}
p.rawInt64(int64(tag))
}

func (p *exporter) int(x int) {
p.int64(int64(x))
}

func (p *exporter) int64(x int64) {
if debugFormat {
p.marker('i')
}
if trace {
p.tracef("%d ", x)
}
p.rawInt64(x)
}

func (p *exporter) string(s string) {
if debugFormat {
p.marker('s')
}
if trace {
p.tracef("%q ", s)
}
// if we saw the string before, write its index (>= 0)
// (the empty string is mapped to 0)
if i, ok := p.strIndex[s]; ok {
p.rawInt64(int64(i))
return
}
// otherwise, remember string and write its negative length and bytes
p.strIndex[s] = len(p.strIndex)
p.rawInt64(-int64(len(s)))
for i := 0; i < len(s); i++ {
p.rawByte(s[i])
}
}

// marker emits a marker byte and position information which makes
// it easy for a reader to detect if it is "out of sync". Used for
// debugFormat format only.
func (p *exporter) marker(m byte) {
p.rawByte(m)
// Enable this for help tracking down the location
// of an incorrect marker when running in debugFormat.
if false && trace {
p.tracef("#%d ", p.written)
}
p.rawInt64(int64(p.written))
}

// rawInt64 should only be used by low-level encoders.
func (p *exporter) rawInt64(x int64) {
var tmp [binary.MaxVarintLen64]byte
n := binary.PutVarint(tmp[:], x)
for i := 0; i < n; i++ {
p.rawByte(tmp[i])
}
}

// rawStringln should only be used to emit the initial version string.
func (p *exporter) rawStringln(s string) {
for i := 0; i < len(s); i++ {
p.rawByte(s[i])
}
p.rawByte('\n')
}

// rawByte is the bottleneck interface to write to p.out.
// rawByte escapes b as follows (any encoding does that
// hides '$'):
//
// '$' => '|' 'S'
// '|' => '|' '|'
//
// Necessary so other tools can find the end of the
// export data by searching for "$$".
// rawByte should only be used by low-level encoders.
func (p *exporter) rawByte(b byte) {
switch b {
case '$':
// write '$' as '|' 'S'
b = 'S'
fallthrough
case '|':
// write '|' as '|' '|'
p.out.WriteByte('|')
p.written++
}
p.out.WriteByte(b)
p.written++
}

// tracef is like fmt.Printf but it rewrites the format string
// to take care of indentation.
func (p *exporter) tracef(format string, args ...interface{}) {
if strings.ContainsAny(format, "<>\n") {
var buf bytes.Buffer
for i := 0; i < len(format); i++ {
// no need to deal with runes
ch := format[i]
switch ch {
case '>':
p.indent++
continue
case '<':
p.indent--
continue
}
buf.WriteByte(ch)
if ch == '\n' {
for j := p.indent; j > 0; j-- {
buf.WriteString(". ")
}
}
}
format = buf.String()
}
fmt.Printf(format, args...)
}

// Debugging support.
// (tagString is only used when tracing is enabled)
var tagString = [...]string{
// Packages
-packageTag: "package",

// Types
-namedTag: "named type",
-arrayTag: "array",
-sliceTag: "slice",
-dddTag: "ddd",
-structTag: "struct",
-pointerTag: "pointer",
-signatureTag: "signature",
-interfaceTag: "interface",
-mapTag: "map",
-chanTag: "chan",

// Values
-falseTag: "false",
-trueTag: "true",
-int64Tag: "int64",
-floatTag: "float",
-fractionTag: "fraction",
-complexTag: "complex",
-stringTag: "string",
-unknownTag: "unknown",

// Type aliases
-aliasTag: "alias",
}

+ 0
- 1039
vendor/golang.org/x/tools/go/internal/gcimporter/bimport.go
File diff suppressed because it is too large
View File


+ 4
- 7
vendor/golang.org/x/tools/go/internal/gcimporter/gcimporter.go View File

@@ -204,14 +204,11 @@ func Import(packages map[string]*types.Package, path, srcDir string, lookup func
// Or, define a new standard go/types/gcexportdata package. // Or, define a new standard go/types/gcexportdata package.
fset := token.NewFileSet() fset := token.NewFileSet()


// The indexed export format starts with an 'i'; the older
// binary export format starts with a 'c', 'd', or 'v'
// (from "version"). Select appropriate importer.
if len(data) > 0 && data[0] == 'i' {
_, pkg, err = IImportData(fset, packages, data[1:], id)
} else {
_, pkg, err = BImportData(fset, packages, data, id)
// The indexed export format starts with an 'i'.
if len(data) == 0 || data[0] != 'i' {
return nil, fmt.Errorf("unknown export data format")
} }
_, pkg, err = IImportData(fset, packages, data[1:], id)


default: default:
err = fmt.Errorf("unknown export data header: %q", hdr) err = fmt.Errorf("unknown export data header: %q", hdr)


+ 20
- 0
vendor/golang.org/x/tools/go/internal/gcimporter/iexport.go View File

@@ -11,6 +11,7 @@ package gcimporter
import ( import (
"bytes" "bytes"
"encoding/binary" "encoding/binary"
"fmt"
"go/ast" "go/ast"
"go/constant" "go/constant"
"go/token" "go/token"
@@ -25,6 +26,15 @@ import (
// 0: Go1.11 encoding // 0: Go1.11 encoding
const iexportVersion = 0 const iexportVersion = 0


// internalError represents an error generated inside this package.
type internalError string

func (e internalError) Error() string { return "gcimporter: " + string(e) }

func internalErrorf(format string, args ...interface{}) error {
return internalError(fmt.Sprintf(format, args...))
}

// IExportData returns the binary export data for pkg. // IExportData returns the binary export data for pkg.
// //
// If no file set is provided, position info will be missing. // If no file set is provided, position info will be missing.
@@ -528,6 +538,16 @@ func constantToFloat(x constant.Value) *big.Float {
return &f return &f
} }


func valueToRat(x constant.Value) *big.Rat {
// Convert little-endian to big-endian.
// I can't believe this is necessary.
bytes := constant.Bytes(x)
for i := 0; i < len(bytes)/2; i++ {
bytes[i], bytes[len(bytes)-1-i] = bytes[len(bytes)-1-i], bytes[i]
}
return new(big.Rat).SetInt(new(big.Int).SetBytes(bytes))
}

// mpint exports a multi-precision integer. // mpint exports a multi-precision integer.
// //
// For unsigned types, small values are written out as a single // For unsigned types, small values are written out as a single


+ 170
- 0
vendor/golang.org/x/tools/go/internal/gcimporter/iimport.go View File

@@ -18,6 +18,9 @@ import (
"go/types" "go/types"
"io" "io"
"sort" "sort"
"sync"
"unicode"
"unicode/utf8"
) )


type intReader struct { type intReader struct {
@@ -25,6 +28,10 @@ type intReader struct {
path string path string
} }


func errorf(format string, args ...interface{}) {
panic(fmt.Sprintf(format, args...))
}

func (r *intReader) int64() int64 { func (r *intReader) int64() int64 {
i, err := binary.ReadVarint(r.Reader) i, err := binary.ReadVarint(r.Reader)
if err != nil { if err != nil {
@@ -628,3 +635,166 @@ func (r *importReader) byte() byte {
} }
return x return x
} }

const deltaNewFile = -64 // see cmd/compile/internal/gc/bexport.go

// Synthesize a token.Pos
type fakeFileSet struct {
fset *token.FileSet
files map[string]*token.File
}

func (s *fakeFileSet) pos(file string, line, column int) token.Pos {
// TODO(mdempsky): Make use of column.

// Since we don't know the set of needed file positions, we
// reserve maxlines positions per file.
const maxlines = 64 * 1024
f := s.files[file]
if f == nil {
f = s.fset.AddFile(file, -1, maxlines)
s.files[file] = f
// Allocate the fake linebreak indices on first use.
// TODO(adonovan): opt: save ~512KB using a more complex scheme?
fakeLinesOnce.Do(func() {
fakeLines = make([]int, maxlines)
for i := range fakeLines {
fakeLines[i] = i
}
})
f.SetLines(fakeLines)
}

if line > maxlines {
line = 1
}

// Treat the file as if it contained only newlines
// and column=1: use the line number as the offset.
return f.Pos(line - 1)
}

var (
fakeLines []int
fakeLinesOnce sync.Once
)

func chanDir(d int) types.ChanDir {
// tag values must match the constants in cmd/compile/internal/gc/go.go
switch d {
case 1 /* Crecv */ :
return types.RecvOnly
case 2 /* Csend */ :
return types.SendOnly
case 3 /* Cboth */ :
return types.SendRecv
default:
errorf("unexpected channel dir %d", d)
return 0
}
}

func exported(name string) bool {
ch, _ := utf8.DecodeRuneInString(name)
return unicode.IsUpper(ch)
}

// ----------------------------------------------------------------------------
// Export format

// Tags. Must be < 0.
const (
// Objects
packageTag = -(iota + 1)
constTag
typeTag
varTag
funcTag
endTag

// Types
namedTag
arrayTag
sliceTag
dddTag
structTag
pointerTag
signatureTag
interfaceTag
mapTag
chanTag

// Values
falseTag
trueTag
int64Tag
floatTag
fractionTag // not used by gc
complexTag
stringTag
nilTag // only used by gc (appears in exported inlined function bodies)
unknownTag // not used by gc (only appears in packages with errors)

// Type aliases
aliasTag
)

var predeclOnce sync.Once
var predecl []types.Type // initialized lazily

func predeclared() []types.Type {
predeclOnce.Do(func() {
// initialize lazily to be sure that all
// elements have been initialized before
predecl = []types.Type{ // basic types
types.Typ[types.Bool],
types.Typ[types.Int],
types.Typ[types.Int8],
types.Typ[types.Int16],
types.Typ[types.Int32],
types.Typ[types.Int64],
types.Typ[types.Uint],
types.Typ[types.Uint8],
types.Typ[types.Uint16],
types.Typ[types.Uint32],
types.Typ[types.Uint64],
types.Typ[types.Uintptr],
types.Typ[types.Float32],
types.Typ[types.Float64],
types.Typ[types.Complex64],
types.Typ[types.Complex128],
types.Typ[types.String],

// basic type aliases
types.Universe.Lookup("byte").Type(),
types.Universe.Lookup("rune").Type(),

// error
types.Universe.Lookup("error").Type(),

// untyped types
types.Typ[types.UntypedBool],
types.Typ[types.UntypedInt],
types.Typ[types.UntypedRune],
types.Typ[types.UntypedFloat],
types.Typ[types.UntypedComplex],
types.Typ[types.UntypedString],
types.Typ[types.UntypedNil],

// package unsafe
types.Typ[types.UnsafePointer],

// invalid type
types.Typ[types.Invalid], // only appears in packages with errors

// used internally by gc; never used by this package or in .a files
anyType{},
}
})
return predecl
}

type anyType struct{}

func (t anyType) Underlying() types.Type { return t }
func (t anyType) String() string { return "any" }

+ 5
- 6
vendor/golang.org/x/tools/go/internal/packagesdriver/sizes.go View File

@@ -19,8 +19,7 @@ import (


var debug = false var debug = false


// GetSizes returns the sizes used by the underlying driver with the given parameters.
func GetSizes(ctx context.Context, buildFlags, env []string, dir string, usesExportData bool) (types.Sizes, error) {
func GetSizes(ctx context.Context, buildFlags, env []string, gocmdRunner *gocommand.Runner, dir string) (types.Sizes, error) {
// TODO(matloob): Clean this up. This code is mostly a copy of packages.findExternalDriver. // TODO(matloob): Clean this up. This code is mostly a copy of packages.findExternalDriver.
const toolPrefix = "GOPACKAGESDRIVER=" const toolPrefix = "GOPACKAGESDRIVER="
tool := "" tool := ""
@@ -40,7 +39,7 @@ func GetSizes(ctx context.Context, buildFlags, env []string, dir string, usesExp
} }


if tool == "off" { if tool == "off" {
return GetSizesGolist(ctx, buildFlags, env, dir, usesExportData)
return GetSizesGolist(ctx, buildFlags, env, gocmdRunner, dir)
} }


req, err := json.Marshal(struct { req, err := json.Marshal(struct {
@@ -76,7 +75,7 @@ func GetSizes(ctx context.Context, buildFlags, env []string, dir string, usesExp
return response.Sizes, nil return response.Sizes, nil
} }


func GetSizesGolist(ctx context.Context, buildFlags, env []string, dir string, usesExportData bool) (types.Sizes, error) {
func GetSizesGolist(ctx context.Context, buildFlags, env []string, gocmdRunner *gocommand.Runner, dir string) (types.Sizes, error) {
inv := gocommand.Invocation{ inv := gocommand.Invocation{
Verb: "list", Verb: "list",
Args: []string{"-f", "{{context.GOARCH}} {{context.Compiler}}", "--", "unsafe"}, Args: []string{"-f", "{{context.GOARCH}} {{context.Compiler}}", "--", "unsafe"},
@@ -84,7 +83,7 @@ func GetSizesGolist(ctx context.Context, buildFlags, env []string, dir string, u
BuildFlags: buildFlags, BuildFlags: buildFlags,
WorkingDir: dir, WorkingDir: dir,
} }
stdout, stderr, friendlyErr, rawErr := inv.RunRaw(ctx)
stdout, stderr, friendlyErr, rawErr := gocmdRunner.RunRaw(ctx, inv)
var goarch, compiler string var goarch, compiler string
if rawErr != nil { if rawErr != nil {
if strings.Contains(rawErr.Error(), "cannot find main module") { if strings.Contains(rawErr.Error(), "cannot find main module") {
@@ -96,7 +95,7 @@ func GetSizesGolist(ctx context.Context, buildFlags, env []string, dir string, u
Env: env, Env: env,
WorkingDir: dir, WorkingDir: dir,
} }
envout, enverr := inv.Run(ctx)
envout, enverr := gocmdRunner.Run(ctx, inv)
if enverr != nil { if enverr != nil {
return nil, enverr return nil, enverr
} }


+ 40
- 8
vendor/golang.org/x/tools/go/packages/golist.go View File

@@ -25,6 +25,7 @@ import (
"golang.org/x/tools/go/internal/packagesdriver" "golang.org/x/tools/go/internal/packagesdriver"
"golang.org/x/tools/internal/gocommand" "golang.org/x/tools/internal/gocommand"
"golang.org/x/tools/internal/packagesinternal" "golang.org/x/tools/internal/packagesinternal"
"golang.org/x/xerrors"
) )


// debug controls verbose logging. // debug controls verbose logging.
@@ -142,7 +143,7 @@ func goListDriver(cfg *Config, patterns ...string) (*driverResponse, error) {
sizeswg.Add(1) sizeswg.Add(1)
go func() { go func() {
var sizes types.Sizes var sizes types.Sizes
sizes, sizeserr = packagesdriver.GetSizesGolist(ctx, cfg.BuildFlags, cfg.Env, cfg.Dir, usesExportData(cfg))
sizes, sizeserr = packagesdriver.GetSizesGolist(ctx, cfg.BuildFlags, cfg.Env, cfg.gocmdRunner, cfg.Dir)
// types.SizesFor always returns nil or a *types.StdSizes. // types.SizesFor always returns nil or a *types.StdSizes.
response.dr.Sizes, _ = sizes.(*types.StdSizes) response.dr.Sizes, _ = sizes.(*types.StdSizes)
sizeswg.Done() sizeswg.Done()
@@ -502,10 +503,19 @@ func (state *golistState) createDriverResponse(words ...string) (*driverResponse
errkind = "use of internal package not allowed" errkind = "use of internal package not allowed"
} }
if errkind != "" { if errkind != "" {
if len(old.Error.ImportStack) < 2 {
return nil, fmt.Errorf(`internal error: go list gave a %q error with an import stack with fewer than two elements`, errkind)
if len(old.Error.ImportStack) < 1 {
return nil, fmt.Errorf(`internal error: go list gave a %q error with empty import stack`, errkind)
}
importingPkg := old.Error.ImportStack[len(old.Error.ImportStack)-1]
if importingPkg == old.ImportPath {
// Using an older version of Go which put this package itself on top of import
// stack, instead of the importer. Look for importer in second from top
// position.
if len(old.Error.ImportStack) < 2 {
return nil, fmt.Errorf(`internal error: go list gave a %q error with an import stack without importing package`, errkind)
}
importingPkg = old.Error.ImportStack[len(old.Error.ImportStack)-2]
} }
importingPkg := old.Error.ImportStack[len(old.Error.ImportStack)-2]
additionalErrors[importingPkg] = append(additionalErrors[importingPkg], Error{ additionalErrors[importingPkg] = append(additionalErrors[importingPkg], Error{
Pos: old.Error.Pos, Pos: old.Error.Pos,
Msg: old.Error.Err, Msg: old.Error.Err,
@@ -534,6 +544,25 @@ func (state *golistState) createDriverResponse(words ...string) (*driverResponse
module: p.Module, module: p.Module,
} }


if (state.cfg.Mode&TypecheckCgo) != 0 && len(p.CgoFiles) != 0 {
if len(p.CompiledGoFiles) > len(p.GoFiles) {
// We need the cgo definitions, which are in the first
// CompiledGoFile after the non-cgo ones. This is a hack but there
// isn't currently a better way to find it. We also need the pure
// Go files and unprocessed cgo files, all of which are already
// in pkg.GoFiles.
cgoTypes := p.CompiledGoFiles[len(p.GoFiles)]
pkg.CompiledGoFiles = append([]string{cgoTypes}, pkg.GoFiles...)
} else {
// golang/go#38990: go list silently fails to do cgo processing
pkg.CompiledGoFiles = nil
pkg.Errors = append(pkg.Errors, Error{
Msg: "go list failed to return CompiledGoFiles; https://golang.org/issue/38990?",
Kind: ListError,
})
}
}

// Work around https://golang.org/issue/28749: // Work around https://golang.org/issue/28749:
// cmd/go puts assembly, C, and C++ files in CompiledGoFiles. // cmd/go puts assembly, C, and C++ files in CompiledGoFiles.
// Filter out any elements of CompiledGoFiles that are also in OtherFiles. // Filter out any elements of CompiledGoFiles that are also in OtherFiles.
@@ -707,7 +736,7 @@ func golistargs(cfg *Config, words []string) []string {
func (state *golistState) invokeGo(verb string, args ...string) (*bytes.Buffer, error) { func (state *golistState) invokeGo(verb string, args ...string) (*bytes.Buffer, error) {
cfg := state.cfg cfg := state.cfg


inv := &gocommand.Invocation{
inv := gocommand.Invocation{
Verb: verb, Verb: verb,
Args: args, Args: args,
BuildFlags: cfg.BuildFlags, BuildFlags: cfg.BuildFlags,
@@ -715,8 +744,11 @@ func (state *golistState) invokeGo(verb string, args ...string) (*bytes.Buffer,
Logf: cfg.Logf, Logf: cfg.Logf,
WorkingDir: cfg.Dir, WorkingDir: cfg.Dir,
} }

stdout, stderr, _, err := inv.RunRaw(cfg.Context)
gocmdRunner := cfg.gocmdRunner
if gocmdRunner == nil {
gocmdRunner = &gocommand.Runner{}
}
stdout, stderr, _, err := gocmdRunner.RunRaw(cfg.Context, inv)
if err != nil { if err != nil {
// Check for 'go' executable not being found. // Check for 'go' executable not being found.
if ee, ok := err.(*exec.Error); ok && ee.Err == exec.ErrNotFound { if ee, ok := err.(*exec.Error); ok && ee.Err == exec.ErrNotFound {
@@ -727,7 +759,7 @@ func (state *golistState) invokeGo(verb string, args ...string) (*bytes.Buffer,
if !ok { if !ok {
// Catastrophic error: // Catastrophic error:
// - context cancellation // - context cancellation
return nil, fmt.Errorf("couldn't run 'go': %v", err)
return nil, xerrors.Errorf("couldn't run 'go': %w", err)
} }


// Old go version? // Old go version?


+ 63
- 1
vendor/golang.org/x/tools/go/packages/golist_overlay.go View File

@@ -5,6 +5,7 @@ import (
"fmt" "fmt"
"go/parser" "go/parser"
"go/token" "go/token"
"log"
"os" "os"
"path/filepath" "path/filepath"
"sort" "sort"
@@ -22,10 +23,15 @@ func (state *golistState) processGolistOverlay(response *responseDeduper) (modif
needPkgsSet := make(map[string]bool) needPkgsSet := make(map[string]bool)
modifiedPkgsSet := make(map[string]bool) modifiedPkgsSet := make(map[string]bool)


pkgOfDir := make(map[string][]*Package)
for _, pkg := range response.dr.Packages { for _, pkg := range response.dr.Packages {
// This is an approximation of import path to id. This can be // This is an approximation of import path to id. This can be
// wrong for tests, vendored packages, and a number of other cases. // wrong for tests, vendored packages, and a number of other cases.
havePkgs[pkg.PkgPath] = pkg.ID havePkgs[pkg.PkgPath] = pkg.ID
x := commonDir(pkg.GoFiles)
if x != "" {
pkgOfDir[x] = append(pkgOfDir[x], pkg)
}
} }


// If no new imports are added, it is safe to avoid loading any needPkgs. // If no new imports are added, it is safe to avoid loading any needPkgs.
@@ -64,6 +70,9 @@ func (state *golistState) processGolistOverlay(response *responseDeduper) (modif
// to the overlay. // to the overlay.
continue continue
} }
// if all the overlay files belong to a different package, change the package
// name to that package. Otherwise leave it alone; there will be an error message.
maybeFixPackageName(pkgName, pkgOfDir, dir)
nextPackage: nextPackage:
for _, p := range response.dr.Packages { for _, p := range response.dr.Packages {
if pkgName != p.Name && p.ID != "command-line-arguments" { if pkgName != p.Name && p.ID != "command-line-arguments" {
@@ -282,7 +291,17 @@ func (state *golistState) determineRootDirs() (map[string]string, error) {
} }


func (state *golistState) determineRootDirsModules() (map[string]string, error) { func (state *golistState) determineRootDirsModules() (map[string]string, error) {
out, err := state.invokeGo("list", "-m", "-json", "all")
// This will only return the root directory for the main module.
// For now we only support overlays in main modules.
// Editing files in the module cache isn't a great idea, so we don't
// plan to ever support that, but editing files in replaced modules
// is something we may want to support. To do that, we'll want to
// do a go list -m to determine the replaced module's module path and
// directory, and then a go list -m {{with .Replace}}{{.Dir}}{{end}} <replaced module's path>
// from the main module to determine if that module is actually a replacement.
// See bcmills's comment here: https://github.com/golang/go/issues/37629#issuecomment-594179751
// for more information.
out, err := state.invokeGo("list", "-m", "-json")
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -374,3 +393,46 @@ func extractPackageName(filename string, contents []byte) (string, bool) {
} }
return f.Name.Name, true return f.Name.Name, true
} }

func commonDir(a []string) string {
seen := make(map[string]bool)
x := append([]string{}, a...)
for _, f := range x {
seen[filepath.Dir(f)] = true
}
if len(seen) > 1 {
log.Fatalf("commonDir saw %v for %v", seen, x)
}
for k := range seen {
// len(seen) == 1
return k
}
return "" // no files
}

// It is possible that the files in the disk directory dir have a different package
// name from newName, which is deduced from the overlays. If they all have a different
// package name, and they all have the same package name, then that name becomes
// the package name.
// It returns true if it changes the package name, false otherwise.
func maybeFixPackageName(newName string, pkgOfDir map[string][]*Package, dir string) bool {
names := make(map[string]int)
for _, p := range pkgOfDir[dir] {
names[p.Name]++
}
if len(names) != 1 {
// some files are in different packages
return false
}
oldName := ""
for k := range names {
oldName = k
}
if newName == oldName {
return false
}
for _, p := range pkgOfDir[dir] {
p.Name = newName
}
return true
}

+ 1
- 1
vendor/golang.org/x/tools/go/packages/loadmode_string.go View File

@@ -38,7 +38,7 @@ var modeStrings = []string{
func (mod LoadMode) String() string { func (mod LoadMode) String() string {
m := mod m := mod
if m == 0 { if m == 0 {
return fmt.Sprintf("LoadMode(0)")
return "LoadMode(0)"
} }
var out []string var out []string
for i, x := range allModes { for i, x := range allModes {


+ 32
- 1
vendor/golang.org/x/tools/go/packages/packages.go View File

@@ -19,10 +19,12 @@ import (
"log" "log"
"os" "os"
"path/filepath" "path/filepath"
"reflect"
"strings" "strings"
"sync" "sync"


"golang.org/x/tools/go/gcexportdata" "golang.org/x/tools/go/gcexportdata"
"golang.org/x/tools/internal/gocommand"
"golang.org/x/tools/internal/packagesinternal" "golang.org/x/tools/internal/packagesinternal"
) )


@@ -69,6 +71,10 @@ const (


// NeedTypesSizes adds TypesSizes. // NeedTypesSizes adds TypesSizes.
NeedTypesSizes NeedTypesSizes

// TypecheckCgo enables full support for type checking cgo. Requires Go 1.15+.
// Modifies CompiledGoFiles and Types, and has no effect on its own.
TypecheckCgo
) )


const ( const (
@@ -127,6 +133,9 @@ type Config struct {
// //
Env []string Env []string


// gocmdRunner guards go command calls from concurrency errors.
gocmdRunner *gocommand.Runner

// BuildFlags is a list of command-line flags to be passed through to // BuildFlags is a list of command-line flags to be passed through to
// the build system's query tool. // the build system's query tool.
BuildFlags []string BuildFlags []string
@@ -253,7 +262,7 @@ type Package struct {
GoFiles []string GoFiles []string


// CompiledGoFiles lists the absolute file paths of the package's source // CompiledGoFiles lists the absolute file paths of the package's source
// files that were presented to the compiler.
// files that are suitable for type checking.
// This may differ from GoFiles if files are processed before compilation. // This may differ from GoFiles if files are processed before compilation.
CompiledGoFiles []string CompiledGoFiles []string


@@ -311,6 +320,12 @@ func init() {
packagesinternal.GetModule = func(p interface{}) *packagesinternal.Module { packagesinternal.GetModule = func(p interface{}) *packagesinternal.Module {
return p.(*Package).module return p.(*Package).module
} }
packagesinternal.GetGoCmdRunner = func(config interface{}) *gocommand.Runner {
return config.(*Config).gocmdRunner
}
packagesinternal.SetGoCmdRunner = func(config interface{}, runner *gocommand.Runner) {
config.(*Config).gocmdRunner = runner
}
} }


// An Error describes a problem with a package's metadata, syntax, or types. // An Error describes a problem with a package's metadata, syntax, or types.
@@ -473,6 +488,9 @@ func newLoader(cfg *Config) *loader {
if ld.Config.Env == nil { if ld.Config.Env == nil {
ld.Config.Env = os.Environ() ld.Config.Env = os.Environ()
} }
if ld.Config.gocmdRunner == nil {
ld.Config.gocmdRunner = &gocommand.Runner{}
}
if ld.Context == nil { if ld.Context == nil {
ld.Context = context.Background() ld.Context = context.Background()
} }
@@ -865,6 +883,19 @@ func (ld *loader) loadPackage(lpkg *loaderPackage) {
Error: appendError, Error: appendError,
Sizes: ld.sizes, Sizes: ld.sizes,
} }
if (ld.Mode & TypecheckCgo) != 0 {
// TODO: remove this when we stop supporting 1.14.
rtc := reflect.ValueOf(tc).Elem()
usesCgo := rtc.FieldByName("UsesCgo")
if !usesCgo.IsValid() {
appendError(Error{
Msg: "TypecheckCgo requires Go 1.15+",
Kind: ListError,
})
return
}
usesCgo.SetBool(true)
}
types.NewChecker(tc, ld.Fset, lpkg.Types, lpkg.TypesInfo).Files(lpkg.Syntax) types.NewChecker(tc, ld.Fset, lpkg.Types, lpkg.TypesInfo).Files(lpkg.Syntax)


lpkg.importErrors = nil // no longer needed lpkg.importErrors = nil // no longer needed


+ 3
- 2
vendor/golang.org/x/tools/go/types/objectpath/objectpath.go View File

@@ -226,7 +226,8 @@ func For(obj types.Object) (Path, error) {
// the best paths because non-types may // the best paths because non-types may
// refer to types, but not the reverse. // refer to types, but not the reverse.
empty := make([]byte, 0, 48) // initial space empty := make([]byte, 0, 48) // initial space
for _, name := range scope.Names() {
names := scope.Names()
for _, name := range names {
o := scope.Lookup(name) o := scope.Lookup(name)
tname, ok := o.(*types.TypeName) tname, ok := o.(*types.TypeName)
if !ok { if !ok {
@@ -253,7 +254,7 @@ func For(obj types.Object) (Path, error) {


// Then inspect everything else: // Then inspect everything else:
// non-types, and declared methods of defined types. // non-types, and declared methods of defined types.
for _, name := range scope.Names() {
for _, name := range names {
o := scope.Lookup(name) o := scope.Lookup(name)
path := append(empty, name...) path := append(empty, name...)
if _, ok := o.(*types.TypeName); !ok { if _, ok := o.(*types.TypeName); !ok {


+ 118
- 0
vendor/golang.org/x/tools/internal/analysisinternal/analysis.go View File

@@ -0,0 +1,118 @@
// Copyright 2020 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package analysisinternal exposes internal-only fields from go/analysis.
package analysisinternal

import (
"bytes"
"fmt"
"go/ast"
"go/token"
"go/types"
"strings"

"golang.org/x/tools/go/ast/astutil"
)

func TypeErrorEndPos(fset *token.FileSet, src []byte, start token.Pos) token.Pos {
// Get the end position for the type error.
offset, end := fset.PositionFor(start, false).Offset, start
if offset >= len(src) {
return end
}
if width := bytes.IndexAny(src[offset:], " \n,():;[]+-*"); width > 0 {
end = start + token.Pos(width)
}
return end
}

func ZeroValue(fset *token.FileSet, f *ast.File, pkg *types.Package, typ types.Type) ast.Expr {
under := typ
if n, ok := typ.(*types.Named); ok {
under = n.Underlying()
}
switch u := under.(type) {
case *types.Basic:
switch {
case u.Info()&types.IsNumeric != 0:
return &ast.BasicLit{Kind: token.INT, Value: "0"}
case u.Info()&types.IsBoolean != 0:
return &ast.Ident{Name: "false"}
case u.Info()&types.IsString != 0:
return &ast.BasicLit{Kind: token.STRING, Value: `""`}
default:
panic("unknown basic type")
}
case *types.Chan, *types.Interface, *types.Map, *types.Pointer, *types.Signature, *types.Slice:
return ast.NewIdent("nil")
case *types.Struct:
texpr := typeExpr(fset, f, pkg, typ) // typ because we want the name here.
if texpr == nil {
return nil
}
return &ast.CompositeLit{
Type: texpr,
}
case *types.Array:
texpr := typeExpr(fset, f, pkg, u.Elem())
if texpr == nil {
return nil
}
return &ast.CompositeLit{
Type: &ast.ArrayType{
Elt: texpr,
Len: &ast.BasicLit{Kind: token.INT, Value: fmt.Sprintf("%v", u.Len())},
},
}
}
return nil
}

func typeExpr(fset *token.FileSet, f *ast.File, pkg *types.Package, typ types.Type) ast.Expr {
switch t := typ.(type) {
case *types.Basic:
switch t.Kind() {
case types.UnsafePointer:
return &ast.SelectorExpr{X: ast.NewIdent("unsafe"), Sel: ast.NewIdent("Pointer")}
default:
return ast.NewIdent(t.Name())
}
case *types.Named:
if t.Obj().Pkg() == pkg {
return ast.NewIdent(t.Obj().Name())
}
pkgName := t.Obj().Pkg().Name()
// If the file already imports the package under another name, use that.
for _, group := range astutil.Imports(fset, f) {
for _, cand := range group {
if strings.Trim(cand.Path.Value, `"`) == t.Obj().Pkg().Path() {
if cand.Name != nil && cand.Name.Name != "" {
pkgName = cand.Name.Name
}
}
}
}
if pkgName == "." {
return ast.NewIdent(t.Obj().Name())
}
return &ast.SelectorExpr{
X: ast.NewIdent(pkgName),
Sel: ast.NewIdent(t.Obj().Name()),
}
default:
return nil // TODO: anonymous structs, but who does that
}
}

var GetTypeErrors = func(p interface{}) []types.Error { return nil }
var SetTypeErrors = func(p interface{}, errors []types.Error) {}

type TypeErrorPass string

const (
NoNewVars TypeErrorPass = "nonewvars"
NoResultValues TypeErrorPass = "noresultvalues"
UndeclaredName TypeErrorPass = "undeclaredname"
)

+ 85
- 0
vendor/golang.org/x/tools/internal/event/core/event.go View File

@@ -0,0 +1,85 @@
// Copyright 2019 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package core provides support for event based telemetry.
package core

import (
"fmt"
"time"

"golang.org/x/tools/internal/event/label"
)

// Event holds the information about an event of note that ocurred.
type Event struct {
at time.Time

// As events are often on the stack, storing the first few labels directly
// in the event can avoid an allocation at all for the very common cases of
// simple events.
// The length needs to be large enough to cope with the majority of events
// but no so large as to cause undue stack pressure.
// A log message with two values will use 3 labels (one for each value and
// one for the message itself).

static [3]label.Label // inline storage for the first few labels
dynamic []label.Label // dynamically sized storage for remaining labels
}

// eventLabelMap implements label.Map for a the labels of an Event.
type eventLabelMap struct {
event Event
}

func (ev Event) At() time.Time { return ev.at }

func (ev Event) Format(f fmt.State, r rune) {
if !ev.at.IsZero() {
fmt.Fprint(f, ev.at.Format("2006/01/02 15:04:05 "))
}
for index := 0; ev.Valid(index); index++ {
if l := ev.Label(index); l.Valid() {
fmt.Fprintf(f, "\n\t%v", l)
}
}
}

func (ev Event) Valid(index int) bool {
return index >= 0 && index < len(ev.static)+len(ev.dynamic)
}

func (ev Event) Label(index int) label.Label {
if index < len(ev.static) {
return ev.static[index]
}
return ev.dynamic[index-len(ev.static)]
}

func (ev Event) Find(key label.Key) label.Label {
for _, l := range ev.static {
if l.Key() == key {
return l
}
}
for _, l := range ev.dynamic {
if l.Key() == key {
return l
}
}
return label.Label{}
}

func MakeEvent(static [3]label.Label, labels []label.Label) Event {
return Event{
static: static,
dynamic: labels,
}
}

// CloneEvent event returns a copy of the event with the time adjusted to at.
func CloneEvent(ev Event, at time.Time) Event {
ev.at = at
return ev
}

+ 70
- 0
vendor/golang.org/x/tools/internal/event/core/export.go View File

@@ -0,0 +1,70 @@
// Copyright 2019 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package core

import (
"context"
"sync/atomic"
"time"
"unsafe"

"golang.org/x/tools/internal/event/label"
)

// Exporter is a function that handles events.
// It may return a modified context and event.
type Exporter func(context.Context, Event, label.Map) context.Context

var (
exporter unsafe.Pointer
)

// SetExporter sets the global exporter function that handles all events.
// The exporter is called synchronously from the event call site, so it should
// return quickly so as not to hold up user code.
func SetExporter(e Exporter) {
p := unsafe.Pointer(&e)
if e == nil {
// &e is always valid, and so p is always valid, but for the early abort
// of ProcessEvent to be efficient it needs to make the nil check on the
// pointer without having to dereference it, so we make the nil function
// also a nil pointer
p = nil
}
atomic.StorePointer(&exporter, p)
}

// deliver is called to deliver an event to the supplied exporter.
// it will fill in the time.
func deliver(ctx context.Context, exporter Exporter, ev Event) context.Context {
// add the current time to the event
ev.at = time.Now()
// hand the event off to the current exporter
return exporter(ctx, ev, ev)
}

// Export is called to deliver an event to the global exporter if set.
func Export(ctx context.Context, ev Event) context.Context {
// get the global exporter and abort early if there is not one
exporterPtr := (*Exporter)(atomic.LoadPointer(&exporter))
if exporterPtr == nil {
return ctx
}
return deliver(ctx, *exporterPtr, ev)
}

// ExportPair is called to deliver a start event to the supplied exporter.
// It also returns a function that will deliver the end event to the same
// exporter.
// It will fill in the time.
func ExportPair(ctx context.Context, begin, end Event) (context.Context, func()) {
// get the global exporter and abort early if there is not one
exporterPtr := (*Exporter)(atomic.LoadPointer(&exporter))
if exporterPtr == nil {
return ctx, func() {}
}
ctx = deliver(ctx, *exporterPtr, begin)
return ctx, func() { deliver(ctx, *exporterPtr, end) }
}

+ 77
- 0
vendor/golang.org/x/tools/internal/event/core/fast.go View File

@@ -0,0 +1,77 @@
// Copyright 2019 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package core

import (
"context"

"golang.org/x/tools/internal/event/keys"
"golang.org/x/tools/internal/event/label"
)

// Log1 takes a message and one label delivers a log event to the exporter.
// It is a customized version of Print that is faster and does no allocation.
func Log1(ctx context.Context, message string, t1 label.Label) {
Export(ctx, MakeEvent([3]label.Label{
keys.Msg.Of(message),
t1,
}, nil))
}

// Log2 takes a message and two labels and delivers a log event to the exporter.
// It is a customized version of Print that is faster and does no allocation.
func Log2(ctx context.Context, message string, t1 label.Label, t2 label.Label) {
Export(ctx, MakeEvent([3]label.Label{
keys.Msg.Of(message),
t1,
t2,
}, nil))
}

// Metric1 sends a label event to the exporter with the supplied labels.
func Metric1(ctx context.Context, t1 label.Label) context.Context {
return Export(ctx, MakeEvent([3]label.Label{
keys.Metric.New(),
t1,
}, nil))
}

// Metric2 sends a label event to the exporter with the supplied labels.
func Metric2(ctx context.Context, t1, t2 label.Label) context.Context {
return Export(ctx, MakeEvent([3]label.Label{
keys.Metric.New(),
t1,
t2,
}, nil))
}

// Start1 sends a span start event with the supplied label list to the exporter.
// It also returns a function that will end the span, which should normally be
// deferred.
func Start1(ctx context.Context, name string, t1 label.Label) (context.Context, func()) {
return ExportPair(ctx,
MakeEvent([3]label.Label{
keys.Start.Of(name),
t1,
}, nil),
MakeEvent([3]label.Label{
keys.End.New(),
}, nil))
}

// Start2 sends a span start event with the supplied label list to the exporter.
// It also returns a function that will end the span, which should normally be
// deferred.
func Start2(ctx context.Context, name string, t1, t2 label.Label) (context.Context, func()) {
return ExportPair(ctx,
MakeEvent([3]label.Label{
keys.Start.Of(name),
t1,
t2,
}, nil),
MakeEvent([3]label.Label{
keys.End.New(),
}, nil))
}

+ 7
- 0
vendor/golang.org/x/tools/internal/event/doc.go View File

@@ -0,0 +1,7 @@
// Copyright 2019 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package event provides a set of packages that cover the main
// concepts of telemetry in an implementation agnostic way.
package event

+ 127
- 0
vendor/golang.org/x/tools/internal/event/event.go View File

@@ -0,0 +1,127 @@
// Copyright 2019 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package event

import (
"context"

"golang.org/x/tools/internal/event/core"
"golang.org/x/tools/internal/event/keys"
"golang.org/x/tools/internal/event/label"
)

// Exporter is a function that handles events.
// It may return a modified context and event.
type Exporter func(context.Context, core.Event, label.Map) context.Context

// SetExporter sets the global exporter function that handles all events.
// The exporter is called synchronously from the event call site, so it should
// return quickly so as not to hold up user code.
func SetExporter(e Exporter) {
core.SetExporter(core.Exporter(e))
}

// Log takes a message and a label list and combines them into a single event
// before delivering them to the exporter.
func Log(ctx context.Context, message string, labels ...label.Label) {
core.Export(ctx, core.MakeEvent([3]label.Label{
keys.Msg.Of(message),
}, labels))
}

// IsLog returns true if the event was built by the Log function.
// It is intended to be used in exporters to identify the semantics of the
// event when deciding what to do with it.
func IsLog(ev core.Event) bool {
return ev.Label(0).Key() == keys.Msg
}

// Error takes a message and a label list and combines them into a single event
// before delivering them to the exporter. It captures the error in the
// delivered event.
func Error(ctx context.Context, message string, err error, labels ...label.Label) {
core.Export(ctx, core.MakeEvent([3]label.Label{
keys.Msg.Of(message),
keys.Err.Of(err),
}, labels))
}

// IsError returns true if the event was built by the Error function.
// It is intended to be used in exporters to identify the semantics of the
// event when deciding what to do with it.
func IsError(ev core.Event) bool {
return ev.Label(0).Key() == keys.Msg &&
ev.Label(1).Key() == keys.Err
}

// Metric sends a label event to the exporter with the supplied labels.
func Metric(ctx context.Context, labels ...label.Label) {
core.Export(ctx, core.MakeEvent([3]label.Label{
keys.Metric.New(),
}, labels))
}

// IsMetric returns true if the event was built by the Metric function.
// It is intended to be used in exporters to identify the semantics of the
// event when deciding what to do with it.
func IsMetric(ev core.Event) bool {
return ev.Label(0).Key() == keys.Metric
}

// Label sends a label event to the exporter with the supplied labels.
func Label(ctx context.Context, labels ...label.Label) context.Context {
return core.Export(ctx, core.MakeEvent([3]label.Label{
keys.Label.New(),
}, labels))
}

// IsLabel returns true if the event was built by the Label function.
// It is intended to be used in exporters to identify the semantics of the
// event when deciding what to do with it.
func IsLabel(ev core.Event) bool {
return ev.Label(0).Key() == keys.Label
}

// Start sends a span start event with the supplied label list to the exporter.
// It also returns a function that will end the span, which should normally be
// deferred.
func Start(ctx context.Context, name string, labels ...label.Label) (context.Context, func()) {
return core.ExportPair(ctx,
core.MakeEvent([3]label.Label{
keys.Start.Of(name),
}, labels),
core.MakeEvent([3]label.Label{
keys.End.New(),
}, nil))
}

// IsStart returns true if the event was built by the Start function.
// It is intended to be used in exporters to identify the semantics of the
// event when deciding what to do with it.
func IsStart(ev core.Event) bool {
return ev.Label(0).Key() == keys.Start
}

// IsEnd returns true if the event was built by the End function.
// It is intended to be used in exporters to identify the semantics of the
// event when deciding what to do with it.
func IsEnd(ev core.Event) bool {
return ev.Label(0).Key() == keys.End
}

// Detach returns a context without an associated span.
// This allows the creation of spans that are not children of the current span.
func Detach(ctx context.Context) context.Context {
return core.Export(ctx, core.MakeEvent([3]label.Label{
keys.Detach.New(),
}, nil))
}

// IsDetach returns true if the event was built by the Detach function.
// It is intended to be used in exporters to identify the semantics of the
// event when deciding what to do with it.
func IsDetach(ev core.Event) bool {
return ev.Label(0).Key() == keys.Detach
}

+ 564
- 0
vendor/golang.org/x/tools/internal/event/keys/keys.go View File

@@ -0,0 +1,564 @@
// Copyright 2019 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package keys

import (
"fmt"
"io"
"math"
"strconv"

"golang.org/x/tools/internal/event/label"
)

// Value represents a key for untyped values.
type Value struct {
name string
description string
}

// New creates a new Key for untyped values.
func New(name, description string) *Value {
return &Value{name: name, description: description}
}

func (k *Value) Name() string { return k.name }
func (k *Value) Description() string { return k.description }

func (k *Value) Format(w io.Writer, buf []byte, l label.Label) {
fmt.Fprint(w, k.From(l))
}

// Get can be used to get a label for the key from a label.Map.
func (k *Value) Get(lm label.Map) interface{} {
if t := lm.Find(k); t.Valid() {
return k.From(t)
}
return nil
}

// From can be used to get a value from a Label.
func (k *Value) From(t label.Label) interface{} { return t.UnpackValue() }

// Of creates a new Label with this key and the supplied value.
func (k *Value) Of(value interface{}) label.Label { return label.OfValue(k, value) }

// Tag represents a key for tagging labels that have no value.
// These are used when the existence of the label is the entire information it
// carries, such as marking events to be of a specific kind, or from a specific
// package.
type Tag struct {
name string
description string
}

// NewTag creates a new Key for tagging labels.
func NewTag(name, description string) *Tag {
return &Tag{name: name, description: description}
}

func (k *Tag) Name() string { return k.name }
func (k *Tag) Description() string { return k.description }

func (k *Tag) Format(w io.Writer, buf []byte, l label.Label) {}

// New creates a new Label with this key.
func (k *Tag) New() label.Label { return label.OfValue(k, nil) }

// Int represents a key
type Int struct {
name string
description string
}

// NewInt creates a new Key for int values.
func NewInt(name, description string) *Int {
return &Int{name: name, description: description}
}

func (k *Int) Name() string { return k.name }
func (k *Int) Description() string { return k.description }

func (k *Int) Format(w io.Writer, buf []byte, l label.Label) {
w.Write(strconv.AppendInt(buf, int64(k.From(l)), 10))
}

// Of creates a new Label with this key and the supplied value.
func (k *Int) Of(v int) label.Label { return label.Of64(k, uint64(v)) }

// Get can be used to get a label for the key from a label.Map.
func (k *Int) Get(lm label.Map) int {
if t := lm.Find(k); t.Valid() {
return k.From(t)
}
return 0
}

// From can be used to get a value from a Label.
func (k *Int) From(t label.Label) int { return int(t.Unpack64()) }

// Int8 represents a key
type Int8 struct {
name string
description string
}

// NewInt8 creates a new Key for int8 values.
func NewInt8(name, description string) *Int8 {
return &Int8{name: name, description: description}
}

func (k *Int8) Name() string { return k.name }
func (k *Int8) Description() string { return k.description }

func (k *Int8) Format(w io.Writer, buf []byte, l label.Label) {
w.Write(strconv.AppendInt(buf, int64(k.From(l)), 10))
}

// Of creates a new Label with this key and the supplied value.
func (k *Int8) Of(v int8) label.Label { return label.Of64(k, uint64(v)) }

// Get can be used to get a label for the key from a label.Map.
func (k *Int8) Get(lm label.Map) int8 {
if t := lm.Find(k); t.Valid() {
return k.From(t)
}
return 0
}

// From can be used to get a value from a Label.
func (k *Int8) From(t label.Label) int8 { return int8(t.Unpack64()) }

// Int16 represents a key
type Int16 struct {
name string
description string
}

// NewInt16 creates a new Key for int16 values.
func NewInt16(name, description string) *Int16 {
return &Int16{name: name, description: description}
}

func (k *Int16) Name() string { return k.name }
func (k *Int16) Description() string { return k.description }

func (k *Int16) Format(w io.Writer, buf []byte, l label.Label) {
w.Write(strconv.AppendInt(buf, int64(k.From(l)), 10))
}

// Of creates a new Label with this key and the supplied value.
func (k *Int16) Of(v int16) label.Label { return label.Of64(k, uint64(v)) }

// Get can be used to get a label for the key from a label.Map.
func (k *Int16) Get(lm label.Map) int16 {
if t := lm.Find(k); t.Valid() {
return k.From(t)
}
return 0
}

// From can be used to get a value from a Label.
func (k *Int16) From(t label.Label) int16 { return int16(t.Unpack64()) }

// Int32 represents a key
type Int32 struct {
name string
description string
}

// NewInt32 creates a new Key for int32 values.
func NewInt32(name, description string) *Int32 {
return &Int32{name: name, description: description}
}

func (k *Int32) Name() string { return k.name }
func (k *Int32) Description() string { return k.description }

func (k *Int32) Format(w io.Writer, buf []byte, l label.Label) {
w.Write(strconv.AppendInt(buf, int64(k.From(l)), 10))
}

// Of creates a new Label with this key and the supplied value.
func (k *Int32) Of(v int32) label.Label { return label.Of64(k, uint64(v)) }

// Get can be used to get a label for the key from a label.Map.
func (k *Int32) Get(lm label.Map) int32 {
if t := lm.Find(k); t.Valid() {
return k.From(t)
}
return 0
}

// From can be used to get a value from a Label.
func (k *Int32) From(t label.Label) int32 { return int32(t.Unpack64()) }

// Int64 represents a key
type Int64 struct {
name string
description string
}

// NewInt64 creates a new Key for int64 values.
func NewInt64(name, description string) *Int64 {
return &Int64{name: name, description: description}
}

func (k *Int64) Name() string { return k.name }
func (k *Int64) Description() string { return k.description }

func (k *Int64) Format(w io.Writer, buf []byte, l label.Label) {
w.Write(strconv.AppendInt(buf, k.From(l), 10))
}

// Of creates a new Label with this key and the supplied value.
func (k *Int64) Of(v int64) label.Label { return label.Of64(k, uint64(v)) }

// Get can be used to get a label for the key from a label.Map.
func (k *Int64) Get(lm label.Map) int64 {
if t := lm.Find(k); t.Valid() {
return k.From(t)
}
return 0
}

// From can be used to get a value from a Label.
func (k *Int64) From(t label.Label) int64 { return int64(t.Unpack64()) }

// UInt represents a key
type UInt struct {
name string
description string
}

// NewUInt creates a new Key for uint values.
func NewUInt(name, description string) *UInt {
return &UInt{name: name, description: description}
}

func (k *UInt) Name() string { return k.name }
func (k *UInt) Description() string { return k.description }

func (k *UInt) Format(w io.Writer, buf []byte, l label.Label) {
w.Write(strconv.AppendUint(buf, uint64(k.From(l)), 10))
}

// Of creates a new Label with this key and the supplied value.
func (k *UInt) Of(v uint) label.Label { return label.Of64(k, uint64(v)) }

// Get can be used to get a label for the key from a label.Map.
func (k *UInt) Get(lm label.Map) uint {
if t := lm.Find(k); t.Valid() {
return k.From(t)
}
return 0
}

// From can be used to get a value from a Label.
func (k *UInt) From(t label.Label) uint { return uint(t.Unpack64()) }

// UInt8 represents a key
type UInt8 struct {
name string
description string
}

// NewUInt8 creates a new Key for uint8 values.
func NewUInt8(name, description string) *UInt8 {
return &UInt8{name: name, description: description}
}

func (k *UInt8) Name() string { return k.name }
func (k *UInt8) Description() string { return k.description }

func (k *UInt8) Format(w io.Writer, buf []byte, l label.Label) {
w.Write(strconv.AppendUint(buf, uint64(k.From(l)), 10))
}

// Of creates a new Label with this key and the supplied value.
func (k *UInt8) Of(v uint8) label.Label { return label.Of64(k, uint64(v)) }

// Get can be used to get a label for the key from a label.Map.
func (k *UInt8) Get(lm label.Map) uint8 {
if t := lm.Find(k); t.Valid() {
return k.From(t)
}
return 0
}

// From can be used to get a value from a Label.
func (k *UInt8) From(t label.Label) uint8 { return uint8(t.Unpack64()) }

// UInt16 represents a key
type UInt16 struct {
name string
description string
}

// NewUInt16 creates a new Key for uint16 values.
func NewUInt16(name, description string) *UInt16 {
return &UInt16{name: name, description: description}
}

func (k *UInt16) Name() string { return k.name }
func (k *UInt16) Description() string { return k.description }

func (k *UInt16) Format(w io.Writer, buf []byte, l label.Label) {
w.Write(strconv.AppendUint(buf, uint64(k.From(l)), 10))
}

// Of creates a new Label with this key and the supplied value.
func (k *UInt16) Of(v uint16) label.Label { return label.Of64(k, uint64(v)) }

// Get can be used to get a label for the key from a label.Map.
func (k *UInt16) Get(lm label.Map) uint16 {
if t := lm.Find(k); t.Valid() {
return k.From(t)
}
return 0
}

// From can be used to get a value from a Label.
func (k *UInt16) From(t label.Label) uint16 { return uint16(t.Unpack64()) }

// UInt32 represents a key
type UInt32 struct {
name string
description string
}

// NewUInt32 creates a new Key for uint32 values.
func NewUInt32(name, description string) *UInt32 {
return &UInt32{name: name, description: description}
}

func (k *UInt32) Name() string { return k.name }
func (k *UInt32) Description() string { return k.description }

func (k *UInt32) Format(w io.Writer, buf []byte, l label.Label) {
w.Write(strconv.AppendUint(buf, uint64(k.From(l)), 10))
}

// Of creates a new Label with this key and the supplied value.
func (k *UInt32) Of(v uint32) label.Label { return label.Of64(k, uint64(v)) }

// Get can be used to get a label for the key from a label.Map.
func (k *UInt32) Get(lm label.Map) uint32 {
if t := lm.Find(k); t.Valid() {
return k.From(t)
}
return 0
}

// From can be used to get a value from a Label.
func (k *UInt32) From(t label.Label) uint32 { return uint32(t.Unpack64()) }

// UInt64 represents a key
type UInt64 struct {
name string
description string
}

// NewUInt64 creates a new Key for uint64 values.
func NewUInt64(name, description string) *UInt64 {
return &UInt64{name: name, description: description}
}

func (k *UInt64) Name() string { return k.name }
func (k *UInt64) Description() string { return k.description }

func (k *UInt64) Format(w io.Writer, buf []byte, l label.Label) {
w.Write(strconv.AppendUint(buf, k.From(l), 10))
}

// Of creates a new Label with this key and the supplied value.
func (k *UInt64) Of(v uint64) label.Label { return label.Of64(k, v) }

// Get can be used to get a label for the key from a label.Map.
func (k *UInt64) Get(lm label.Map) uint64 {
if t := lm.Find(k); t.Valid() {
return k.From(t)
}
return 0
}

// From can be used to get a value from a Label.
func (k *UInt64) From(t label.Label) uint64 { return t.Unpack64() }

// Float32 represents a key
type Float32 struct {
name string
description string
}

// NewFloat32 creates a new Key for float32 values.
func NewFloat32(name, description string) *Float32 {
return &Float32{name: name, description: description}
}

func (k *Float32) Name() string { return k.name }
func (k *Float32) Description() string { return k.description }

func (k *Float32) Format(w io.Writer, buf []byte, l label.Label) {
w.Write(strconv.AppendFloat(buf, float64(k.From(l)), 'E', -1, 32))
}

// Of creates a new Label with this key and the supplied value.
func (k *Float32) Of(v float32) label.Label {
return label.Of64(k, uint64(math.Float32bits(v)))
}

// Get can be used to get a label for the key from a label.Map.
func (k *Float32) Get(lm label.Map) float32 {
if t := lm.Find(k); t.Valid() {
return k.From(t)
}
return 0
}

// From can be used to get a value from a Label.
func (k *Float32) From(t label.Label) float32 {
return math.Float32frombits(uint32(t.Unpack64()))
}

// Float64 represents a key
type Float64 struct {
name string
description string
}

// NewFloat64 creates a new Key for int64 values.
func NewFloat64(name, description string) *Float64 {
return &Float64{name: name, description: description}
}

func (k *Float64) Name() string { return k.name }
func (k *Float64) Description() string { return k.description }

func (k *Float64) Format(w io.Writer, buf []byte, l label.Label) {
w.Write(strconv.AppendFloat(buf, k.From(l), 'E', -1, 64))
}

// Of creates a new Label with this key and the supplied value.
func (k *Float64) Of(v float64) label.Label {
return label.Of64(k, math.Float64bits(v))
}

// Get can be used to get a label for the key from a label.Map.
func (k *Float64) Get(lm label.Map) float64 {
if t := lm.Find(k); t.Valid() {
return k.From(t)
}
return 0
}

// From can be used to get a value from a Label.
func (k *Float64) From(t label.Label) float64 {
return math.Float64frombits(t.Unpack64())
}

// String represents a key
type String struct {
name string
description string
}

// NewString creates a new Key for int64 values.
func NewString(name, description string) *String {
return &String{name: name, description: description}
}

func (k *String) Name() string { return k.name }
func (k *String) Description() string { return k.description }

func (k *String) Format(w io.Writer, buf []byte, l label.Label) {
w.Write(strconv.AppendQuote(buf, k.From(l)))
}

// Of creates a new Label with this key and the supplied value.
func (k *String) Of(v string) label.Label { return label.OfString(k, v) }

// Get can be used to get a label for the key from a label.Map.
func (k *String) Get(lm label.Map) string {
if t := lm.Find(k); t.Valid() {
return k.From(t)
}
return ""
}

// From can be used to get a value from a Label.
func (k *String) From(t label.Label) string { return t.UnpackString() }

// Boolean represents a key
type Boolean struct {
name string
description string
}

// NewBoolean creates a new Key for bool values.
func NewBoolean(name, description string) *Boolean {
return &Boolean{name: name, description: description}
}

func (k *Boolean) Name() string { return k.name }
func (k *Boolean) Description() string { return k.description }

func (k *Boolean) Format(w io.Writer, buf []byte, l label.Label) {
w.Write(strconv.AppendBool(buf, k.From(l)))
}

// Of creates a new Label with this key and the supplied value.
func (k *Boolean) Of(v bool) label.Label {
if v {
return label.Of64(k, 1)
}
return label.Of64(k, 0)
}

// Get can be used to get a label for the key from a label.Map.
func (k *Boolean) Get(lm label.Map) bool {
if t := lm.Find(k); t.Valid() {
return k.From(t)
}
return false
}

// From can be used to get a value from a Label.
func (k *Boolean) From(t label.Label) bool { return t.Unpack64() > 0 }

// Error represents a key
type Error struct {
name string
description string
}

// NewError creates a new Key for int64 values.
func NewError(name, description string) *Error {
return &Error{name: name, description: description}
}

func (k *Error) Name() string { return k.name }
func (k *Error) Description() string { return k.description }

func (k *Error) Format(w io.Writer, buf []byte, l label.Label) {
io.WriteString(w, k.From(l).Error())
}

// Of creates a new Label with this key and the supplied value.
func (k *Error) Of(v error) label.Label { return label.OfValue(k, v) }

// Get can be used to get a label for the key from a label.Map.
func (k *Error) Get(lm label.Map) error {
if t := lm.Find(k); t.Valid() {
return k.From(t)
}
return nil
}

// From can be used to get a value from a Label.
func (k *Error) From(t label.Label) error {
err, _ := t.UnpackValue().(error)
return err
}

+ 22
- 0
vendor/golang.org/x/tools/internal/event/keys/standard.go View File

@@ -0,0 +1,22 @@
// Copyright 2020 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package keys

var (
// Msg is a key used to add message strings to label lists.
Msg = NewString("message", "a readable message")
// Label is a key used to indicate an event adds labels to the context.
Label = NewTag("label", "a label context marker")
// Start is used for things like traces that have a name.
Start = NewString("start", "span start")
// Metric is a key used to indicate an event records metrics.
End = NewTag("end", "a span end marker")
// Metric is a key used to indicate an event records metrics.
Detach = NewTag("detach", "a span detach marker")
// Err is a key used to add error values to label lists.
Err = NewError("error", "an error that occurred")
// Metric is a key used to indicate an event records metrics.
Metric = NewTag("metric", "a metric event marker")
)

+ 213
- 0
vendor/golang.org/x/tools/internal/event/label/label.go View File

@@ -0,0 +1,213 @@
// Copyright 2019 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package label

import (
"fmt"
"io"
"reflect"
"unsafe"
)

// Key is used as the identity of a Label.
// Keys are intended to be compared by pointer only, the name should be unique
// for communicating with external systems, but it is not required or enforced.
type Key interface {
// Name returns the key name.
Name() string
// Description returns a string that can be used to describe the value.
Description() string

// Format is used in formatting to append the value of the label to the
// supplied buffer.
// The formatter may use the supplied buf as a scratch area to avoid
// allocations.
Format(w io.Writer, buf []byte, l Label)
}

// Label holds a key and value pair.
// It is normally used when passing around lists of labels.
type Label struct {
key Key
packed uint64
untyped interface{}
}

// Map is the interface to a collection of Labels indexed by key.
type Map interface {
// Find returns the label that matches the supplied key.
Find(key Key) Label
}

// List is the interface to something that provides an iterable
// list of labels.
// Iteration should start from 0 and continue until Valid returns false.
type List interface {
// Valid returns true if the index is within range for the list.
// It does not imply the label at that index will itself be valid.
Valid(index int) bool
// Label returns the label at the given index.
Label(index int) Label
}

// list implements LabelList for a list of Labels.
type list struct {
labels []Label
}

// filter wraps a LabelList filtering out specific labels.
type filter struct {
keys []Key
underlying List
}

// listMap implements LabelMap for a simple list of labels.
type listMap struct {
labels []Label
}

// mapChain implements LabelMap for a list of underlying LabelMap.
type mapChain struct {
maps []Map
}

// OfValue creates a new label from the key and value.
// This method is for implementing new key types, label creation should
// normally be done with the Of method of the key.
func OfValue(k Key, value interface{}) Label { return Label{key: k, untyped: value} }

// UnpackValue assumes the label was built using LabelOfValue and returns the value
// that was passed to that constructor.
// This method is for implementing new key types, for type safety normal
// access should be done with the From method of the key.
func (t Label) UnpackValue() interface{} { return t.untyped }

// Of64 creates a new label from a key and a uint64. This is often
// used for non uint64 values that can be packed into a uint64.
// This method is for implementing new key types, label creation should
// normally be done with the Of method of the key.
func Of64(k Key, v uint64) Label { return Label{key: k, packed: v} }

// Unpack64 assumes the label was built using LabelOf64 and returns the value that
// was passed to that constructor.
// This method is for implementing new key types, for type safety normal
// access should be done with the From method of the key.
func (t Label) Unpack64() uint64 { return t.packed }

// OfString creates a new label from a key and a string.
// This method is for implementing new key types, label creation should
// normally be done with the Of method of the key.
func OfString(k Key, v string) Label {
hdr := (*reflect.StringHeader)(unsafe.Pointer(&v))
return Label{
key: k,
packed: uint64(hdr.Len),
untyped: unsafe.Pointer(hdr.Data),
}
}

// UnpackString assumes the label was built using LabelOfString and returns the
// value that was passed to that constructor.
// This method is for implementing new key types, for type safety normal
// access should be done with the From method of the key.
func (t Label) UnpackString() string {
var v string
hdr := (*reflect.StringHeader)(unsafe.Pointer(&v))
hdr.Data = uintptr(t.untyped.(unsafe.Pointer))
hdr.Len = int(t.packed)
return *(*string)(unsafe.Pointer(hdr))
}

// Valid returns true if the Label is a valid one (it has a key).
func (t Label) Valid() bool { return t.key != nil }

// Key returns the key of this Label.
func (t Label) Key() Key { return t.key }

// Format is used for debug printing of labels.
func (t Label) Format(f fmt.State, r rune) {
if !t.Valid() {
io.WriteString(f, `nil`)
return
}
io.WriteString(f, t.Key().Name())
io.WriteString(f, "=")
var buf [128]byte
t.Key().Format(f, buf[:0], t)
}

func (l *list) Valid(index int) bool {
return index >= 0 && index < len(l.labels)
}

func (l *list) Label(index int) Label {
return l.labels[index]
}

func (f *filter) Valid(index int) bool {
return f.underlying.Valid(index)
}

func (f *filter) Label(index int) Label {
l := f.underlying.Label(index)
for _, f := range f.keys {
if l.Key() == f {
return Label{}
}
}
return l
}

func (lm listMap) Find(key Key) Label {
for _, l := range lm.labels {
if l.Key() == key {
return l
}
}
return Label{}
}

func (c mapChain) Find(key Key) Label {
for _, src := range c.maps {
l := src.Find(key)
if l.Valid() {
return l
}
}
return Label{}
}

var emptyList = &list{}

func NewList(labels ...Label) List {
if len(labels) == 0 {
return emptyList
}
return &list{labels: labels}
}

func Filter(l List, keys ...Key) List {
if len(keys) == 0 {
return l
}
return &filter{keys: keys, underlying: l}
}

func NewMap(labels ...Label) Map {
return listMap{labels: labels}
}

func MergeMaps(srcs ...Map) Map {
var nonNil []Map
for _, src := range srcs {
if src != nil {
nonNil = append(nonNil, src)
}
}
if len(nonNil) == 1 {
return nonNil[0]
}
return mapChain{maps: nonNil}
}

+ 72
- 11
vendor/golang.org/x/tools/internal/gocommand/invoke.go View File

@@ -1,3 +1,7 @@
// Copyright 2020 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package gocommand is a helper for calling the go command. // Package gocommand is a helper for calling the go command.
package gocommand package gocommand


@@ -8,10 +12,70 @@ import (
"io" "io"
"os" "os"
"os/exec" "os/exec"
"regexp"
"strings" "strings"
"sync"
"time" "time"

"golang.org/x/tools/internal/event"
) )


// An Runner will run go command invocations and serialize
// them if it sees a concurrency error.
type Runner struct {
// LoadMu guards packages.Load calls and associated state.
loadMu sync.Mutex
serializeLoads int
}

// 1.13: go: updates to go.mod needed, but contents have changed
// 1.14: go: updating go.mod: existing contents have changed since last read
var modConcurrencyError = regexp.MustCompile(`go:.*go.mod.*contents have changed`)

// Run calls Runner.RunRaw, serializing requests if they fight over
// go.mod changes.
func (runner *Runner) Run(ctx context.Context, inv Invocation) (*bytes.Buffer, error) {
stdout, _, friendly, _ := runner.RunRaw(ctx, inv)
return stdout, friendly
}

// RunRaw calls Invocation.runRaw, serializing requests if they fight over
// go.mod changes.
func (runner *Runner) RunRaw(ctx context.Context, inv Invocation) (*bytes.Buffer, *bytes.Buffer, error, error) {
// We want to run invocations concurrently as much as possible. However,
// if go.mod updates are needed, only one can make them and the others will
// fail. We need to retry in those cases, but we don't want to thrash so
// badly we never recover. To avoid that, once we've seen one concurrency
// error, start serializing everything until the backlog has cleared out.
runner.loadMu.Lock()
var locked bool // If true, we hold the mutex and have incremented.
if runner.serializeLoads == 0 {
runner.loadMu.Unlock()
} else {
locked = true
runner.serializeLoads++
}
defer func() {
if locked {
runner.serializeLoads--
runner.loadMu.Unlock()
}
}()

for {
stdout, stderr, friendlyErr, err := inv.runRaw(ctx)
if friendlyErr == nil || !modConcurrencyError.MatchString(friendlyErr.Error()) {
return stdout, stderr, friendlyErr, err
}
event.Error(ctx, "Load concurrency error, will retry serially", err)
if !locked {
runner.loadMu.Lock()
runner.serializeLoads++
locked = true
}
}
}

// An Invocation represents a call to the go command. // An Invocation represents a call to the go command.
type Invocation struct { type Invocation struct {
Verb string Verb string
@@ -22,20 +86,14 @@ type Invocation struct {
Logf func(format string, args ...interface{}) Logf func(format string, args ...interface{})
} }


// Run runs the invocation, returning its stdout and an error suitable for
// human consumption, including stderr.
func (i *Invocation) Run(ctx context.Context) (*bytes.Buffer, error) {
stdout, _, friendly, _ := i.RunRaw(ctx)
return stdout, friendly
}

// RunRaw is like RunPiped, but also returns the raw stderr and error for callers // RunRaw is like RunPiped, but also returns the raw stderr and error for callers
// that want to do low-level error handling/recovery. // that want to do low-level error handling/recovery.
func (i *Invocation) RunRaw(ctx context.Context) (stdout *bytes.Buffer, stderr *bytes.Buffer, friendlyError error, rawError error) {
func (i *Invocation) runRaw(ctx context.Context) (stdout *bytes.Buffer, stderr *bytes.Buffer, friendlyError error, rawError error) {
stdout = &bytes.Buffer{} stdout = &bytes.Buffer{}
stderr = &bytes.Buffer{} stderr = &bytes.Buffer{}
rawError = i.RunPiped(ctx, stdout, stderr) rawError = i.RunPiped(ctx, stdout, stderr)
if rawError != nil { if rawError != nil {
friendlyError = rawError
// Check for 'go' executable not being found. // Check for 'go' executable not being found.
if ee, ok := rawError.(*exec.Error); ok && ee.Err == exec.ErrNotFound { if ee, ok := rawError.(*exec.Error); ok && ee.Err == exec.ErrNotFound {
friendlyError = fmt.Errorf("go command required, not found: %v", ee) friendlyError = fmt.Errorf("go command required, not found: %v", ee)
@@ -43,7 +101,7 @@ func (i *Invocation) RunRaw(ctx context.Context) (stdout *bytes.Buffer, stderr *
if ctx.Err() != nil { if ctx.Err() != nil {
friendlyError = ctx.Err() friendlyError = ctx.Err()
} }
friendlyError = fmt.Errorf("err: %v: stderr: %s", rawError, stderr)
friendlyError = fmt.Errorf("err: %v: stderr: %s", friendlyError, stderr)
} }
return return
} }
@@ -78,8 +136,11 @@ func (i *Invocation) RunPiped(ctx context.Context, stdout, stderr io.Writer) err
// The Go stdlib has a special feature where if the cwd and the PWD are the // The Go stdlib has a special feature where if the cwd and the PWD are the
// same node then it trusts the PWD, so by setting it in the env for the child // same node then it trusts the PWD, so by setting it in the env for the child
// process we fix up all the paths returned by the go command. // process we fix up all the paths returned by the go command.
cmd.Env = append(append([]string{}, i.Env...), "PWD="+i.WorkingDir)
cmd.Dir = i.WorkingDir
cmd.Env = append(os.Environ(), i.Env...)
if i.WorkingDir != "" {
cmd.Env = append(cmd.Env, "PWD="+i.WorkingDir)
cmd.Dir = i.WorkingDir
}


defer func(start time.Time) { log("%s for %v", time.Since(start), cmdDebugStr(cmd)) }(time.Now()) defer func(start time.Time) { log("%s for %v", time.Since(start), cmdDebugStr(cmd)) }(time.Now())




+ 5
- 2
vendor/golang.org/x/tools/internal/imports/fix.go View File

@@ -50,7 +50,8 @@ var importToGroup = []func(env *ProcessEnv, importPath string) (num int, ok bool
return return
}, },
func(_ *ProcessEnv, importPath string) (num int, ok bool) { func(_ *ProcessEnv, importPath string) (num int, ok bool) {
if strings.Contains(importPath, ".") {
firstComponent := strings.Split(importPath, "/")[0]
if strings.Contains(firstComponent, ".") {
return 1, true return 1, true
} }
return return
@@ -747,6 +748,8 @@ func getPackageExports(ctx context.Context, wrapped func(PackageExport), searchP
type ProcessEnv struct { type ProcessEnv struct {
LocalPrefix string LocalPrefix string


GocmdRunner *gocommand.Runner

BuildFlags []string BuildFlags []string


// If non-empty, these will be used instead of the // If non-empty, these will be used instead of the
@@ -830,7 +833,7 @@ func (e *ProcessEnv) invokeGo(ctx context.Context, verb string, args ...string)
Logf: e.Logf, Logf: e.Logf,
WorkingDir: e.WorkingDir, WorkingDir: e.WorkingDir,
} }
return inv.Run(ctx)
return e.GocmdRunner.Run(ctx, inv)
} }


func addStdlibCandidates(pass *pass, refs references) { func addStdlibCandidates(pass *pass, refs references) {


+ 5
- 0
vendor/golang.org/x/tools/internal/imports/imports.go View File

@@ -27,6 +27,7 @@ import (
"strings" "strings"


"golang.org/x/tools/go/ast/astutil" "golang.org/x/tools/go/ast/astutil"
"golang.org/x/tools/internal/gocommand"
) )


// Options is golang.org/x/tools/imports.Options with extra internal-only options. // Options is golang.org/x/tools/imports.Options with extra internal-only options.
@@ -154,6 +155,10 @@ func initialize(filename string, src []byte, opt *Options) ([]byte, *Options, er
GOSUMDB: os.Getenv("GOSUMDB"), GOSUMDB: os.Getenv("GOSUMDB"),
} }
} }
// Set the gocmdRunner if the user has not provided it.
if opt.Env.GocmdRunner == nil {
opt.Env.GocmdRunner = &gocommand.Runner{}
}
if src == nil { if src == nil {
b, err := ioutil.ReadFile(filename) b, err := ioutil.ReadFile(filename)
if err != nil { if err != nil {


Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save