From a7a818ae7b22b2907de0e968deaa448362551a7f Mon Sep 17 00:00:00 2001 From: Andrew Bayer Date: Tue, 28 Jun 2022 14:41:45 -0400 Subject: [PATCH] Upgrade AlecAivazais/survey to v2.3.5 I was having trouble debugging some tests I was working on refactoring, and eventually realized this was due to https://github.com/AlecAivazis/survey/issues/408, which was fixed in survey v2.3.3. This also ends up upgrading hinshun/vt10x, getting rid of the `NewVT10xTerminal` function we'd been calling in a few places, so I band-aided that by adding an equivalent function in `test/helper/helpers.go`. Signed-off-by: Andrew Bayer --- go.mod | 8 +- go.sum | 16 +- pkg/cmd/pipelineresource/resource_testUtil.go | 8 +- test/cli/cli.go | 4 +- test/helper/helper.go | 21 ++ test/prompt/prompt.go | 4 +- .../github.com/{kr => creack}/pty/LICENSE | 0 .../github.com/gdamore/tcell/{ => v2}/LICENSE | 0 .../github.com/hashicorp/go-plugin/README.md | 5 +- .../github.com/hashicorp/go-plugin/client.go | 15 +- .../hashicorp/go-plugin/rpc_server.go | 6 +- .../github.com/hashicorp/go-plugin/server.go | 6 +- .../hashicorp/go-rootcerts/rootcerts_base.go | 1 - .../go-secure-stdlib/mlock/mlock_unavail.go | 1 - .../go-secure-stdlib/mlock/mlock_unix.go | 1 - .../go-secure-stdlib/parseutil/parseutil.go | 99 +++++++ .../hashicorp/go-sockaddr/ifaddrs.go | 3 +- .../go-sockaddr/route_info_android.go | 1 + .../hashicorp/go-sockaddr/route_info_bsd.go | 1 - .../go-sockaddr/route_info_default.go | 1 - .../hashicorp/go-sockaddr/route_info_linux.go | 1 - .../github.com/hashicorp/go-uuid/uuid.go | 3 +- .../hashicorp/go-version/CHANGELOG.md | 2 +- .../github.com/hashicorp/go-version/README.md | 2 +- .../hashicorp/go-version/version.go | 17 ++ .../golang-lru/simplelru/lru_interface.go | 4 +- .../vault/sdk/helper/certutil/helpers.go | 212 ++++++++++----- .../vault/sdk/helper/certutil/types.go | 213 +++++++++++++-- .../vault/sdk/helper/consts/consts.go | 2 + .../sdk/helper/pluginutil/multiplexing.pb.go | 2 +- .../hashicorp/vault/sdk/logical/auth.go | 21 +- .../vault/sdk/logical/identity.pb.go | 2 +- .../vault/sdk/logical/managed_key.go | 8 +- .../hashicorp/vault/sdk/logical/plugin.pb.go | 41 ++- .../hashicorp/vault/sdk/logical/plugin.proto | 6 + .../vault/sdk/logical/response_util.go | 2 + .../hashicorp/vault/sdk/version/version.go | 6 + .../vault/sdk/version/version_base.go | 7 +- .../github.com/ktr0731/go-fuzzyfinder/LICENSE | 2 +- .../github.com/nsf/termbox-go/LICENSE | 19 ++ .../AlecAivazis/survey/v2/.travis.yml | 22 -- .../AlecAivazis/survey/v2/CONTRIBUTING.md | 40 +-- .../AlecAivazis/survey/v2/Gopkg.lock | 78 ------ .../AlecAivazis/survey/v2/Gopkg.toml | 54 ---- .../AlecAivazis/survey/v2/README.md | 50 ++-- .../AlecAivazis/survey/v2/_tasks.hcl | 19 -- .../AlecAivazis/survey/v2/confirm.go | 8 +- .../AlecAivazis/survey/v2/core/write.go | 10 +- .../AlecAivazis/survey/v2/editor.go | 10 +- .../github.com/AlecAivazis/survey/v2/input.go | 7 +- .../AlecAivazis/survey/v2/multiline.go | 8 +- .../AlecAivazis/survey/v2/multiselect.go | 8 +- .../AlecAivazis/survey/v2/password.go | 13 +- .../AlecAivazis/survey/v2/renderer.go | 10 +- .../AlecAivazis/survey/v2/select.go | 30 ++- .../AlecAivazis/survey/v2/survey.go | 86 +++---- .../AlecAivazis/survey/v2/terminal/cursor.go | 83 +++--- .../survey/v2/terminal/cursor_windows.go | 98 ++++--- .../survey/v2/terminal/display_posix.go | 5 +- .../survey/v2/terminal/display_windows.go | 10 +- .../survey/v2/terminal/output_windows.go | 94 ++++--- .../survey/v2/terminal/runereader.go | 51 ++-- .../survey/v2/terminal/runereader_posix.go | 5 + .../survey/v2/terminal/sequences.go | 5 +- .../AlecAivazis/survey/v2/validate.go | 2 +- .../github.com/Netflix/go-expect/.travis.yml | 3 +- .../github.com/Netflix/go-expect/Gopkg.lock | 15 -- .../github.com/Netflix/go-expect/Gopkg.toml | 34 --- vendor/github.com/Netflix/go-expect/README.md | 5 +- .../github.com/Netflix/go-expect/console.go | 4 +- .../github.com/{kr => creack}/pty/.gitignore | 0 .../{kr => creack}/pty/Dockerfile.golang | 0 .../{kr => creack}/pty/Dockerfile.riscv | 0 vendor/github.com/{kr => creack}/pty/LICENSE | 0 .../github.com/{kr => creack}/pty/README.md | 0 .../{kr => creack}/pty/asm_solaris_amd64.s | 0 vendor/github.com/{kr => creack}/pty/doc.go | 0 vendor/github.com/{kr => creack}/pty/ioctl.go | 0 .../{kr => creack}/pty/ioctl_bsd.go | 0 .../{kr => creack}/pty/ioctl_solaris.go | 0 .../{kr => creack}/pty/mktypes.bash | 0 .../{kr => creack}/pty/pty_darwin.go | 0 .../{kr => creack}/pty/pty_dragonfly.go | 0 .../{kr => creack}/pty/pty_freebsd.go | 0 .../{kr => creack}/pty/pty_linux.go | 0 .../{kr => creack}/pty/pty_netbsd.go | 0 .../{kr => creack}/pty/pty_openbsd.go | 0 .../{kr => creack}/pty/pty_solaris.go | 0 .../{kr => creack}/pty/pty_unsupported.go | 0 vendor/github.com/{kr => creack}/pty/run.go | 0 .../{kr => creack}/pty/test_crosscompile.sh | 0 .../github.com/{kr => creack}/pty/winsize.go | 0 .../{kr => creack}/pty/winsize_unix.go | 0 .../{kr => creack}/pty/winsize_unsupported.go | 0 .../{kr => creack}/pty/ztypes_386.go | 0 .../{kr => creack}/pty/ztypes_amd64.go | 0 .../{kr => creack}/pty/ztypes_arm.go | 0 .../{kr => creack}/pty/ztypes_arm64.go | 0 .../pty/ztypes_dragonfly_amd64.go | 0 .../{kr => creack}/pty/ztypes_freebsd_386.go | 0 .../pty/ztypes_freebsd_amd64.go | 0 .../{kr => creack}/pty/ztypes_freebsd_arm.go | 0 .../pty/ztypes_freebsd_arm64.go | 0 .../pty/ztypes_freebsd_ppc64.go | 0 .../pty/ztypes_loong64.go} | 5 +- .../{kr => creack}/pty/ztypes_mipsx.go | 0 .../pty/ztypes_netbsd_32bit_int.go | 0 .../pty/ztypes_openbsd_32bit_int.go | 0 .../{kr => creack}/pty/ztypes_ppc64.go | 0 .../{kr => creack}/pty/ztypes_ppc64le.go | 0 .../{kr => creack}/pty/ztypes_riscvx.go | 0 .../{kr => creack}/pty/ztypes_s390x.go | 0 vendor/github.com/hinshun/vt10x/Gopkg.lock | 96 ------- vendor/github.com/hinshun/vt10x/Gopkg.toml | 38 --- vendor/github.com/hinshun/vt10x/color.go | 5 +- vendor/github.com/hinshun/vt10x/csi.go | 40 +-- vendor/github.com/hinshun/vt10x/expect.go | 29 --- vendor/github.com/hinshun/vt10x/parse.go | 36 +-- vendor/github.com/hinshun/vt10x/state.go | 209 ++++++++------- vendor/github.com/hinshun/vt10x/str.go | 242 +++++++++++++++++- vendor/github.com/hinshun/vt10x/vt.go | 89 +++++++ vendor/github.com/hinshun/vt10x/vt_other.go | 82 +++--- vendor/github.com/hinshun/vt10x/vt_posix.go | 79 +++--- vendor/modules.txt | 16 +- 124 files changed, 1560 insertions(+), 1046 deletions(-) rename third_party/VENDOR-LICENSE/github.com/{kr => creack}/pty/LICENSE (100%) rename third_party/VENDOR-LICENSE/github.com/gdamore/tcell/{ => v2}/LICENSE (100%) create mode 100644 third_party/VENDOR-LICENSE/github.com/nsf/termbox-go/LICENSE delete mode 100644 vendor/github.com/AlecAivazis/survey/v2/.travis.yml delete mode 100644 vendor/github.com/AlecAivazis/survey/v2/Gopkg.lock delete mode 100644 vendor/github.com/AlecAivazis/survey/v2/Gopkg.toml delete mode 100644 vendor/github.com/AlecAivazis/survey/v2/_tasks.hcl delete mode 100644 vendor/github.com/Netflix/go-expect/Gopkg.lock delete mode 100644 vendor/github.com/Netflix/go-expect/Gopkg.toml rename vendor/github.com/{kr => creack}/pty/.gitignore (100%) rename vendor/github.com/{kr => creack}/pty/Dockerfile.golang (100%) rename vendor/github.com/{kr => creack}/pty/Dockerfile.riscv (100%) rename vendor/github.com/{kr => creack}/pty/LICENSE (100%) rename vendor/github.com/{kr => creack}/pty/README.md (100%) rename vendor/github.com/{kr => creack}/pty/asm_solaris_amd64.s (100%) rename vendor/github.com/{kr => creack}/pty/doc.go (100%) rename vendor/github.com/{kr => creack}/pty/ioctl.go (100%) rename vendor/github.com/{kr => creack}/pty/ioctl_bsd.go (100%) rename vendor/github.com/{kr => creack}/pty/ioctl_solaris.go (100%) rename vendor/github.com/{kr => creack}/pty/mktypes.bash (100%) rename vendor/github.com/{kr => creack}/pty/pty_darwin.go (100%) rename vendor/github.com/{kr => creack}/pty/pty_dragonfly.go (100%) rename vendor/github.com/{kr => creack}/pty/pty_freebsd.go (100%) rename vendor/github.com/{kr => creack}/pty/pty_linux.go (100%) rename vendor/github.com/{kr => creack}/pty/pty_netbsd.go (100%) rename vendor/github.com/{kr => creack}/pty/pty_openbsd.go (100%) rename vendor/github.com/{kr => creack}/pty/pty_solaris.go (100%) rename vendor/github.com/{kr => creack}/pty/pty_unsupported.go (100%) rename vendor/github.com/{kr => creack}/pty/run.go (100%) rename vendor/github.com/{kr => creack}/pty/test_crosscompile.sh (100%) rename vendor/github.com/{kr => creack}/pty/winsize.go (100%) rename vendor/github.com/{kr => creack}/pty/winsize_unix.go (100%) rename vendor/github.com/{kr => creack}/pty/winsize_unsupported.go (100%) rename vendor/github.com/{kr => creack}/pty/ztypes_386.go (100%) rename vendor/github.com/{kr => creack}/pty/ztypes_amd64.go (100%) rename vendor/github.com/{kr => creack}/pty/ztypes_arm.go (100%) rename vendor/github.com/{kr => creack}/pty/ztypes_arm64.go (100%) rename vendor/github.com/{kr => creack}/pty/ztypes_dragonfly_amd64.go (100%) rename vendor/github.com/{kr => creack}/pty/ztypes_freebsd_386.go (100%) rename vendor/github.com/{kr => creack}/pty/ztypes_freebsd_amd64.go (100%) rename vendor/github.com/{kr => creack}/pty/ztypes_freebsd_arm.go (100%) rename vendor/github.com/{kr => creack}/pty/ztypes_freebsd_arm64.go (100%) rename vendor/github.com/{kr => creack}/pty/ztypes_freebsd_ppc64.go (100%) rename vendor/github.com/{kr/pty/ztypes_loongarchx.go => creack/pty/ztypes_loong64.go} (55%) rename vendor/github.com/{kr => creack}/pty/ztypes_mipsx.go (100%) rename vendor/github.com/{kr => creack}/pty/ztypes_netbsd_32bit_int.go (100%) rename vendor/github.com/{kr => creack}/pty/ztypes_openbsd_32bit_int.go (100%) rename vendor/github.com/{kr => creack}/pty/ztypes_ppc64.go (100%) rename vendor/github.com/{kr => creack}/pty/ztypes_ppc64le.go (100%) rename vendor/github.com/{kr => creack}/pty/ztypes_riscvx.go (100%) rename vendor/github.com/{kr => creack}/pty/ztypes_s390x.go (100%) delete mode 100644 vendor/github.com/hinshun/vt10x/Gopkg.lock delete mode 100644 vendor/github.com/hinshun/vt10x/Gopkg.toml delete mode 100644 vendor/github.com/hinshun/vt10x/expect.go create mode 100644 vendor/github.com/hinshun/vt10x/vt.go diff --git a/go.mod b/go.mod index f2b22ee528..eb6b09e54a 100644 --- a/go.mod +++ b/go.mod @@ -3,8 +3,8 @@ module github.com/tektoncd/cli go 1.17 require ( - github.com/AlecAivazis/survey/v2 v2.3.2 - github.com/Netflix/go-expect v0.0.0-20200312175327-da48e75238e2 + github.com/AlecAivazis/survey/v2 v2.3.5 + github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2 github.com/armon/go-metrics v0.4.0 github.com/armon/go-radix v1.0.0 github.com/blang/semver v3.5.1+incompatible @@ -38,7 +38,7 @@ require ( github.com/hashicorp/hcl v1.0.0 github.com/hashicorp/vault/sdk v0.5.2 github.com/hashicorp/yamux v0.0.0-20211028200310-0bc27b27de87 - github.com/hinshun/vt10x v0.0.0-20180809195222-d55458df857c + github.com/hinshun/vt10x v0.0.0-20220228203356-1ab2cad5fd82 github.com/jonboulle/clockwork v0.3.0 github.com/ktr0731/go-fuzzyfinder v0.6.0 github.com/mitchellh/copystructure v1.2.0 @@ -81,6 +81,7 @@ require ( ) require ( + github.com/creack/pty v1.1.17 github.com/letsencrypt/boulder v0.0.0-20220331220046-b23ab962616e github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399 ) @@ -231,7 +232,6 @@ require ( github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect github.com/kelseyhightower/envconfig v1.4.0 // indirect github.com/klauspost/compress v1.15.1 // indirect - github.com/kr/pty v1.1.8 // indirect github.com/leodido/go-urn v1.2.1 // indirect github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect github.com/lucasb-eyer/go-colorful v1.0.3 // indirect diff --git a/go.sum b/go.sum index 3c8d9bdbdc..6af5b3dc23 100644 --- a/go.sum +++ b/go.sum @@ -134,8 +134,8 @@ git.apache.org/thrift.git v0.12.0/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqbl github.com/AdaLogics/go-fuzz-headers v0.0.0-20210715213245-6c3934b029d8/go.mod h1:CzsSbkDixRphAF5hS6wbMKq0eI6ccJRb7/A0M6JBnwg= github.com/AdaLogics/go-fuzz-headers v0.0.0-20211102141018-f7be0cbad29c/go.mod h1:WpB7kf89yJUETZxQnP1kgYPNwlT2jjdDYUCoxVggM3g= github.com/AlecAivazis/survey/v2 v2.2.12/go.mod h1:6d4saEvBsfSHXeN1a5OA5m2+HJ2LuVokllnC77pAIKI= -github.com/AlecAivazis/survey/v2 v2.3.2 h1:TqTB+aDDCLYhf9/bD2TwSO8u8jDSmMUd2SUVO4gCnU8= -github.com/AlecAivazis/survey/v2 v2.3.2/go.mod h1:TH2kPCDU3Kqq7pLbnCWwZXDBjnhZtmsCle5EiYDJ2fg= +github.com/AlecAivazis/survey/v2 v2.3.5 h1:A8cYupsAZkjaUmhtTYv3sSqc7LO5mp1XDfqe5E/9wRQ= +github.com/AlecAivazis/survey/v2 v2.3.5/go.mod h1:4AuI9b7RjAR+G7v9+C4YSlX/YL3K3cWNXgWXOhllqvI= github.com/Antonboom/errname v0.1.5/go.mod h1:DugbBstvPFQbv/5uLcRRzfrNqKE9tVdVCqWCLp6Cifo= github.com/Antonboom/nilnil v0.1.0/go.mod h1:PhHLvRPSghY5Y7mX4TW+BHZQYo1A8flE5H20D3IPZBo= github.com/Azure/azure-amqp-common-go/v2 v2.1.0/go.mod h1:R8rea+gJRuJR6QxTir/XuEd+YuKoUiazDC/N96FiDEU= @@ -280,8 +280,9 @@ github.com/Microsoft/hcsshim/test v0.0.0-20210227013316-43a75bb4edd3/go.mod h1:m github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c= github.com/Netflix/go-expect v0.0.0-20180615182759-c93bf25de8e8/go.mod h1:oX5x61PbNXchhh0oikYAH+4Pcfw5LKv21+Jnpr6r6Pc= -github.com/Netflix/go-expect v0.0.0-20200312175327-da48e75238e2 h1:y2avNRjCeJT8b7svzjhKZjsvW5Jki/iAqTBEPJURaUg= github.com/Netflix/go-expect v0.0.0-20200312175327-da48e75238e2/go.mod h1:oX5x61PbNXchhh0oikYAH+4Pcfw5LKv21+Jnpr6r6Pc= +github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2 h1:+vx7roKuyA63nhn5WAunQHLTznkw5W8b1Xc0dNjp83s= +github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2/go.mod h1:HBCaDeC1lPdgDeDbhX8XFpy1jqjK0IBG8W5K+xYqA0w= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/OneOfOne/xxhash v1.2.8/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q= github.com/OpenPeeDeeP/depguard v1.0.1/go.mod h1:xsIw86fROiiwelg+jB2uM9PiKihMMmUx/1V+TNhjQvM= @@ -781,8 +782,9 @@ github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46t github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/creack/pty v1.1.16 h1:vfetlOf3A+9YKggibynnX9mnFjuSVvkRj+IWpcTSLEQ= github.com/creack/pty v1.1.16/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= +github.com/creack/pty v1.1.17 h1:QeVUsEDNrLBW4tMgZHvxy18sKtr6VI492kBhUfhDJNI= +github.com/creack/pty v1.1.17/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= github.com/cyberphone/json-canonicalization v0.0.0-20210303052042-6bc126869bf4/go.mod h1:uzvlm1mxhHkdfqitSA92i7Se+S9ksOn3a3qmv/kyOCw= github.com/cyberphone/json-canonicalization v0.0.0-20210823021906-dc406ceaf94b h1:lMzA7yYThpwx7iYNpTeiQnRH6h5JSfSYMJdz+pxZOW8= github.com/cyberphone/json-canonicalization v0.0.0-20210823021906-dc406ceaf94b/go.mod h1:uzvlm1mxhHkdfqitSA92i7Se+S9ksOn3a3qmv/kyOCw= @@ -1657,8 +1659,9 @@ github.com/hashicorp/yamux v0.0.0-20211028200310-0bc27b27de87 h1:xixZ2bWeofWV68J github.com/hashicorp/yamux v0.0.0-20211028200310-0bc27b27de87/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ= github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg= github.com/hinshun/vt10x v0.0.0-20180616224451-1954e6464174/go.mod h1:DqJ97dSdRW1W22yXSB90986pcOyQ7r45iio1KN2ez1A= -github.com/hinshun/vt10x v0.0.0-20180809195222-d55458df857c h1:kp3AxgXgDOmIJFR7bIwqFhwJ2qWar8tEQSE5XXhCfVk= -github.com/hinshun/vt10x v0.0.0-20180809195222-d55458df857c/go.mod h1:DqJ97dSdRW1W22yXSB90986pcOyQ7r45iio1KN2ez1A= +github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec/go.mod h1:Q48J4R4DvxnHolD5P8pOtXigYlRuPLGl6moFx3ulM68= +github.com/hinshun/vt10x v0.0.0-20220228203356-1ab2cad5fd82 h1:uf1FmugJNeFovjWtxD7FSPWQXdi0KuKnZfvN4CFUAtA= +github.com/hinshun/vt10x v0.0.0-20220228203356-1ab2cad5fd82/go.mod h1:Q48J4R4DvxnHolD5P8pOtXigYlRuPLGl6moFx3ulM68= github.com/honeycombio/beeline-go v1.1.1 h1:sU8r4ae34uEL3/CguSl8Mr+Asz9DL1nfH9Wwk85Pc7U= github.com/honeycombio/beeline-go v1.1.1/go.mod h1:kN0cfUGBMfA87DyCYbiiLoSzWsnw3bluZvNEWtatHxk= github.com/honeycombio/libhoney-go v1.15.2 h1:5NGcjOxZZma13dmzNcl3OtGbF1hECA0XHJNHEb2t2ck= @@ -3325,6 +3328,7 @@ golang.org/x/sys v0.0.0-20220315194320-039c03cc5b86/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220328115105-d36c6a25d886/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220330033206-e17cdc41300f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220422013727-9388b58f7150/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6 h1:nonptSpoQ4vQjyraW20DXPAglgQfVnM9ZC6MmNLMR60= golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= diff --git a/pkg/cmd/pipelineresource/resource_testUtil.go b/pkg/cmd/pipelineresource/resource_testUtil.go index a39ddd70b9..707dc325af 100644 --- a/pkg/cmd/pipelineresource/resource_testUtil.go +++ b/pkg/cmd/pipelineresource/resource_testUtil.go @@ -21,7 +21,7 @@ import ( "github.com/AlecAivazis/survey/v2" "github.com/AlecAivazis/survey/v2/terminal" goexpect "github.com/Netflix/go-expect" - "github.com/hinshun/vt10x" + "github.com/tektoncd/cli/test/helper" "gotest.tools/v3/assert" ) @@ -53,9 +53,11 @@ func (pt *promptTest) runTest(t *testing.T, procedure func(*goexpect.Console) er // Multiplex output to a buffer as well for the raw bytes. buf := new(bytes.Buffer) - c, state, err := vt10x.NewVT10XConsole(goexpect.WithStdout(buf)) + c, state, err := helper.NewVT10XConsole(goexpect.WithStdout(buf)) assert.NilError(t, err) - defer c.Close() + defer func() { + _ = c.Close() + }() donec := make(chan struct{}) go func() { diff --git a/test/cli/cli.go b/test/cli/cli.go index c113426603..285560c47a 100644 --- a/test/cli/cli.go +++ b/test/cli/cli.go @@ -25,7 +25,7 @@ import ( "github.com/Netflix/go-expect" goexpect "github.com/Netflix/go-expect" - "github.com/hinshun/vt10x" + "github.com/tektoncd/cli/test/helper" "gotest.tools/v3/assert" "gotest.tools/v3/icmd" ) @@ -113,7 +113,7 @@ func (e TknRunner) RunInteractiveTests(t *testing.T, ops *Prompt) *expect.Consol // Multiplex output to a buffer as well for the raw bytes. buf := new(bytes.Buffer) - c, state, err := vt10x.NewVT10XConsole(goexpect.WithStdout(buf)) + c, state, err := helper.NewVT10XConsole(goexpect.WithStdout(buf)) assert.NilError(t, err) defer c.Close() diff --git a/test/helper/helper.go b/test/helper/helper.go index 7838acb5de..8157724150 100644 --- a/test/helper/helper.go +++ b/test/helper/helper.go @@ -24,7 +24,10 @@ import ( "testing" "text/template" + "github.com/Netflix/go-expect" + "github.com/creack/pty" "github.com/google/go-cmp/cmp" + "github.com/hinshun/vt10x" gotestcmp "gotest.tools/assert/cmp" ) @@ -92,3 +95,21 @@ func ContainsAll(target string, substrings ...string) gotestcmp.Comparison { return gotestcmp.ResultSuccess } } + +// NewVT10XConsole returns a new expect.Console that multiplexes the +// Stdin/Stdout to a VT10X terminal, allowing Console to interact with an +// application sending ANSI escape sequences. +func NewVT10XConsole(opts ...expect.ConsoleOpt) (*expect.Console, vt10x.Terminal, error) { + ptm, pts, err := pty.Open() + if err != nil { + return nil, nil, err + } + + term := vt10x.New(vt10x.WithWriter(pts)) + c, err := expect.NewConsole(append(opts, expect.WithStdin(ptm), expect.WithStdout(term), expect.WithCloser(ptm, pts))...) + if err != nil { + return nil, nil, err + } + + return c, term, nil +} diff --git a/test/prompt/prompt.go b/test/prompt/prompt.go index 29bf348627..e22ef16f56 100644 --- a/test/prompt/prompt.go +++ b/test/prompt/prompt.go @@ -21,7 +21,7 @@ import ( "github.com/AlecAivazis/survey/v2" "github.com/AlecAivazis/survey/v2/terminal" goexpect "github.com/Netflix/go-expect" - "github.com/hinshun/vt10x" + "github.com/tektoncd/cli/test/helper" "gotest.tools/v3/assert" ) @@ -36,7 +36,7 @@ type Prompt struct { func (pt *Prompt) RunTest(t *testing.T, procedure func(*goexpect.Console) error, test func(terminal.Stdio) error) { // Multiplex output to a buffer as well for the raw bytes. buf := new(bytes.Buffer) - c, state, err := vt10x.NewVT10XConsole(goexpect.WithStdout(buf)) + c, state, err := helper.NewVT10XConsole(goexpect.WithStdout(buf)) assert.NilError(t, err) defer c.Close() diff --git a/third_party/VENDOR-LICENSE/github.com/kr/pty/LICENSE b/third_party/VENDOR-LICENSE/github.com/creack/pty/LICENSE similarity index 100% rename from third_party/VENDOR-LICENSE/github.com/kr/pty/LICENSE rename to third_party/VENDOR-LICENSE/github.com/creack/pty/LICENSE diff --git a/third_party/VENDOR-LICENSE/github.com/gdamore/tcell/LICENSE b/third_party/VENDOR-LICENSE/github.com/gdamore/tcell/v2/LICENSE similarity index 100% rename from third_party/VENDOR-LICENSE/github.com/gdamore/tcell/LICENSE rename to third_party/VENDOR-LICENSE/github.com/gdamore/tcell/v2/LICENSE diff --git a/third_party/VENDOR-LICENSE/github.com/hashicorp/go-plugin/README.md b/third_party/VENDOR-LICENSE/github.com/hashicorp/go-plugin/README.md index 46ee09fc0c..39391f24fe 100644 --- a/third_party/VENDOR-LICENSE/github.com/hashicorp/go-plugin/README.md +++ b/third_party/VENDOR-LICENSE/github.com/hashicorp/go-plugin/README.md @@ -3,8 +3,9 @@ `go-plugin` is a Go (golang) plugin system over RPC. It is the plugin system that has been in use by HashiCorp tooling for over 4 years. While initially created for [Packer](https://www.packer.io), it is additionally in use by -[Terraform](https://www.terraform.io), [Nomad](https://www.nomadproject.io), and -[Vault](https://www.vaultproject.io). +[Terraform](https://www.terraform.io), [Nomad](https://www.nomadproject.io), +[Vault](https://www.vaultproject.io), and +[Boundary](https://www.boundaryproject.io). While the plugin system is over RPC, it is currently only designed to work over a local [reliable] network. Plugins over a real network are not supported diff --git a/third_party/VENDOR-LICENSE/github.com/hashicorp/go-plugin/client.go b/third_party/VENDOR-LICENSE/github.com/hashicorp/go-plugin/client.go index 67dca88357..e0bee88a1d 100644 --- a/third_party/VENDOR-LICENSE/github.com/hashicorp/go-plugin/client.go +++ b/third_party/VENDOR-LICENSE/github.com/hashicorp/go-plugin/client.go @@ -574,6 +574,8 @@ func (c *Client) Start() (addr net.Addr, err error) { c.config.TLSConfig = &tls.Config{ Certificates: []tls.Certificate{cert}, + ClientAuth: tls.RequireAndVerifyClientCert, + MinVersion: tls.VersionTLS12, ServerName: "localhost", } } @@ -629,17 +631,19 @@ func (c *Client) Start() (addr net.Addr, err error) { // Wait for the command to end. err := cmd.Wait() - debugMsgArgs := []interface{}{ + msgArgs := []interface{}{ "path", path, "pid", pid, } if err != nil { - debugMsgArgs = append(debugMsgArgs, + msgArgs = append(msgArgs, []interface{}{"error", err.Error()}...) + c.logger.Error("plugin process exited", msgArgs...) + } else { + // Log and make sure to flush the logs right away + c.logger.Info("plugin process exited", msgArgs...) } - // Log and make sure to flush the logs write away - c.logger.Debug("plugin process exited", debugMsgArgs...) os.Stderr.Sync() // Set that we exited, which takes a lock @@ -774,7 +778,7 @@ func (c *Client) Start() (addr net.Addr, err error) { } // loadServerCert is used by AutoMTLS to read an x.509 cert returned by the -// server, and load it as the RootCA for the client TLSConfig. +// server, and load it as the RootCA and ClientCA for the client TLSConfig. func (c *Client) loadServerCert(cert string) error { certPool := x509.NewCertPool() @@ -791,6 +795,7 @@ func (c *Client) loadServerCert(cert string) error { certPool.AddCert(x509Cert) c.config.TLSConfig.RootCAs = certPool + c.config.TLSConfig.ClientCAs = certPool return nil } diff --git a/third_party/VENDOR-LICENSE/github.com/hashicorp/go-plugin/rpc_server.go b/third_party/VENDOR-LICENSE/github.com/hashicorp/go-plugin/rpc_server.go index 5bb18dd5db..449ba6cc1e 100644 --- a/third_party/VENDOR-LICENSE/github.com/hashicorp/go-plugin/rpc_server.go +++ b/third_party/VENDOR-LICENSE/github.com/hashicorp/go-plugin/rpc_server.go @@ -45,7 +45,11 @@ func (s *RPCServer) Serve(lis net.Listener) { for { conn, err := lis.Accept() if err != nil { - log.Printf("[ERR] plugin: plugin server: %s", err) + severity := "ERR" + if errors.Is(err, net.ErrClosed) { + severity = "DEBUG" + } + log.Printf("[%s] plugin: plugin server: %s", severity, err) return } diff --git a/third_party/VENDOR-LICENSE/github.com/hashicorp/go-plugin/server.go b/third_party/VENDOR-LICENSE/github.com/hashicorp/go-plugin/server.go index 7a58cc3919..e134999103 100644 --- a/third_party/VENDOR-LICENSE/github.com/hashicorp/go-plugin/server.go +++ b/third_party/VENDOR-LICENSE/github.com/hashicorp/go-plugin/server.go @@ -304,13 +304,13 @@ func Serve(opts *ServeConfig) { certPEM, keyPEM, err := generateCert() if err != nil { - logger.Error("failed to generate client certificate", "error", err) + logger.Error("failed to generate server certificate", "error", err) panic(err) } cert, err := tls.X509KeyPair(certPEM, keyPEM) if err != nil { - logger.Error("failed to parse client certificate", "error", err) + logger.Error("failed to parse server certificate", "error", err) panic(err) } @@ -319,6 +319,8 @@ func Serve(opts *ServeConfig) { ClientAuth: tls.RequireAndVerifyClientCert, ClientCAs: clientCertPool, MinVersion: tls.VersionTLS12, + RootCAs: clientCertPool, + ServerName: "localhost", } // We send back the raw leaf cert data for the client rather than the diff --git a/third_party/VENDOR-LICENSE/github.com/hashicorp/go-rootcerts/rootcerts_base.go b/third_party/VENDOR-LICENSE/github.com/hashicorp/go-rootcerts/rootcerts_base.go index ba58717f59..66b1472c4a 100644 --- a/third_party/VENDOR-LICENSE/github.com/hashicorp/go-rootcerts/rootcerts_base.go +++ b/third_party/VENDOR-LICENSE/github.com/hashicorp/go-rootcerts/rootcerts_base.go @@ -1,4 +1,3 @@ -//go:build !darwin // +build !darwin package rootcerts diff --git a/third_party/VENDOR-LICENSE/github.com/hashicorp/go-secure-stdlib/mlock/mlock_unavail.go b/third_party/VENDOR-LICENSE/github.com/hashicorp/go-secure-stdlib/mlock/mlock_unavail.go index ca6887e91a..941eb2d7bd 100644 --- a/third_party/VENDOR-LICENSE/github.com/hashicorp/go-secure-stdlib/mlock/mlock_unavail.go +++ b/third_party/VENDOR-LICENSE/github.com/hashicorp/go-secure-stdlib/mlock/mlock_unavail.go @@ -1,4 +1,3 @@ -//go:build darwin || nacl || netbsd || plan9 || windows // +build darwin nacl netbsd plan9 windows package mlock diff --git a/third_party/VENDOR-LICENSE/github.com/hashicorp/go-secure-stdlib/mlock/mlock_unix.go b/third_party/VENDOR-LICENSE/github.com/hashicorp/go-secure-stdlib/mlock/mlock_unix.go index 1a774bea5c..af0a69d48a 100644 --- a/third_party/VENDOR-LICENSE/github.com/hashicorp/go-secure-stdlib/mlock/mlock_unix.go +++ b/third_party/VENDOR-LICENSE/github.com/hashicorp/go-secure-stdlib/mlock/mlock_unix.go @@ -1,4 +1,3 @@ -//go:build dragonfly || freebsd || linux || openbsd || solaris // +build dragonfly freebsd linux openbsd solaris package mlock diff --git a/third_party/VENDOR-LICENSE/github.com/hashicorp/go-secure-stdlib/parseutil/parseutil.go b/third_party/VENDOR-LICENSE/github.com/hashicorp/go-secure-stdlib/parseutil/parseutil.go index 167953158c..e469499bdc 100644 --- a/third_party/VENDOR-LICENSE/github.com/hashicorp/go-secure-stdlib/parseutil/parseutil.go +++ b/third_party/VENDOR-LICENSE/github.com/hashicorp/go-secure-stdlib/parseutil/parseutil.go @@ -4,6 +4,7 @@ import ( "encoding/json" "errors" "fmt" + "math" "regexp" "strconv" "strings" @@ -92,6 +93,9 @@ func ParseCapacityString(in interface{}) (uint64, error) { return cap, nil } +// Parse a duration from an arbitrary value (a string or numeric value) into +// a time.Duration; when units are missing (such as when a numeric type is +// provided), the duration is assumed to be in seconds. func ParseDurationSecond(in interface{}) (time.Duration, error) { var dur time.Duration jsonIn, ok := in.(json.Number) @@ -147,6 +151,9 @@ func ParseDurationSecond(in interface{}) (time.Duration, error) { return dur, nil } +// Parse an absolute timestamp from the provided arbitrary value (string or +// numeric value). When an untyped numeric value is provided, it is assumed +// to be seconds from the Unix Epoch. func ParseAbsoluteTime(in interface{}) (time.Time, error) { var t time.Time switch inp := in.(type) { @@ -195,6 +202,13 @@ func ParseAbsoluteTime(in interface{}) (time.Time, error) { return t, nil } +// ParseInt takes an arbitrary value (either a string or numeric type) and +// parses it as an int64 value. This value is assumed to be larger than the +// provided type, but cannot safely be cast. +// +// When the end value is bounded (such as an int value), it is recommended +// to instead call SafeParseInt or SafeParseIntRange to safely cast to a +// more restrictive type. func ParseInt(in interface{}) (int64, error) { var ret int64 jsonIn, ok := in.(json.Number) @@ -232,6 +246,11 @@ func ParseInt(in interface{}) (int64, error) { return ret, nil } +// ParseDirectIntSlice behaves similarly to ParseInt, but accepts typed +// slices, returning a slice of int64s. +// +// If the starting value may not be in slice form (e.g.. a bare numeric value +// could be provided), it is suggested to call ParseIntSlice instead. func ParseDirectIntSlice(in interface{}) ([]int64, error) { var ret []int64 @@ -290,6 +309,10 @@ func ParseDirectIntSlice(in interface{}) ([]int64, error) { // nicely handle the common cases of providing only an int-ish, providing // an actual slice of int-ishes, or providing a comma-separated list of // numbers. +// +// When []int64 is not the desired final type (or the values should be +// range-bound), it is suggested to call SafeParseIntSlice or +// SafeParseIntSliceRange instead. func ParseIntSlice(in interface{}) ([]int64, error) { if ret, err := ParseInt(in); err == nil { return []int64{ret}, nil @@ -320,6 +343,7 @@ func ParseIntSlice(in interface{}) ([]int64, error) { return nil, errors.New("could not parse value from input") } +// Parses the provided arbitrary value as a boolean-like value. func ParseBool(in interface{}) (bool, error) { var result bool if err := mapstructure.WeakDecode(in, &result); err != nil { @@ -328,6 +352,7 @@ func ParseBool(in interface{}) (bool, error) { return result, nil } +// Parses the provided arbitrary value as a string. func ParseString(in interface{}) (string, error) { var result string if err := mapstructure.WeakDecode(in, &result); err != nil { @@ -336,6 +361,7 @@ func ParseString(in interface{}) (string, error) { return result, nil } +// Parses the provided string-like value as a comma-separated list of values. func ParseCommaStringSlice(in interface{}) ([]string, error) { jsonIn, ok := in.(json.Number) if ok { @@ -362,6 +388,7 @@ func ParseCommaStringSlice(in interface{}) ([]string, error) { return strutil.TrimStrings(result), nil } +// Parses the specified value as one or more addresses, separated by commas. func ParseAddrs(addrs interface{}) ([]*sockaddr.SockAddrMarshaler, error) { out := make([]*sockaddr.SockAddrMarshaler, 0) stringAddrs := make([]string, 0) @@ -401,3 +428,75 @@ func ParseAddrs(addrs interface{}) ([]*sockaddr.SockAddrMarshaler, error) { return out, nil } + +// Parses the provided arbitrary value (see ParseInt), ensuring it is within +// the specified range (inclusive of bounds). If this range corresponds to a +// smaller type, the returned value can then be safely cast without risking +// overflow. +func SafeParseIntRange(in interface{}, min int64, max int64) (int64, error) { + raw, err := ParseInt(in) + if err != nil { + return 0, err + } + + if raw < min || raw > max { + return 0, fmt.Errorf("error parsing int value; out of range [%v to %v]: %v", min, max, raw) + } + + return raw, nil +} + +// Parses the specified arbitrary value (see ParseInt), ensuring that the +// resulting value is within the range for an int value. If no error occurred, +// the caller knows no overflow occurred. +func SafeParseInt(in interface{}) (int, error) { + raw, err := SafeParseIntRange(in, math.MinInt, math.MaxInt) + return int(raw), err +} + +// Parses the provided arbitrary value (see ParseIntSlice) into a slice of +// int64 values, ensuring each is within the specified range (inclusive of +// bounds). If this range corresponds to a smaller type, the returned value +// can then be safely cast without risking overflow. +// +// If elements is positive, it is used to ensure the resulting slice is +// bounded above by that many number of elements (inclusive). +func SafeParseIntSliceRange(in interface{}, minValue int64, maxValue int64, elements int) ([]int64, error) { + raw, err := ParseIntSlice(in) + if err != nil { + return nil, err + } + + if elements > 0 && len(raw) > elements { + return nil, fmt.Errorf("error parsing value from input: got %v but expected at most %v elements", len(raw), elements) + } + + for index, value := range raw { + if value < minValue || value > maxValue { + return nil, fmt.Errorf("error parsing value from input: element %v was outside of range [%v to %v]: %v", index, minValue, maxValue, value) + } + } + + return raw, nil +} + +// Parses the provided arbitrary value (see ParseIntSlice) into a slice of +// int values, ensuring the each resulting value in the slice is within the +// range for an int value. If no error occurred, the caller knows no overflow +// occurred. +// +// If elements is positive, it is used to ensure the resulting slice is +// bounded above by that many number of elements (inclusive). +func SafeParseIntSlice(in interface{}, elements int) ([]int, error) { + raw, err := SafeParseIntSliceRange(in, math.MinInt, math.MaxInt, elements) + if err != nil || raw == nil { + return nil, err + } + + var result = make([]int, 0, len(raw)) + for _, element := range raw { + result = append(result, int(element)) + } + + return result, nil +} diff --git a/third_party/VENDOR-LICENSE/github.com/hashicorp/go-sockaddr/ifaddrs.go b/third_party/VENDOR-LICENSE/github.com/hashicorp/go-sockaddr/ifaddrs.go index d58cb50af3..80f61bef68 100644 --- a/third_party/VENDOR-LICENSE/github.com/hashicorp/go-sockaddr/ifaddrs.go +++ b/third_party/VENDOR-LICENSE/github.com/hashicorp/go-sockaddr/ifaddrs.go @@ -1214,7 +1214,7 @@ func parseDefaultIfNameFromIPCmd(routeOut string) (string, error) { // Android. func parseDefaultIfNameFromIPCmdAndroid(routeOut string) (string, error) { parsedLines := parseIfNameFromIPCmd(routeOut) - if len(parsedLines) > 0 { + if (len(parsedLines) > 0) { ifName := strings.TrimSpace(parsedLines[0][4]) return ifName, nil } @@ -1222,6 +1222,7 @@ func parseDefaultIfNameFromIPCmdAndroid(routeOut string) (string, error) { return "", errors.New("No default interface found") } + // parseIfNameFromIPCmd parses interfaces from ip(8) for // Linux. func parseIfNameFromIPCmd(routeOut string) [][]string { diff --git a/third_party/VENDOR-LICENSE/github.com/hashicorp/go-sockaddr/route_info_android.go b/third_party/VENDOR-LICENSE/github.com/hashicorp/go-sockaddr/route_info_android.go index 6f484cc448..9885915a6b 100644 --- a/third_party/VENDOR-LICENSE/github.com/hashicorp/go-sockaddr/route_info_android.go +++ b/third_party/VENDOR-LICENSE/github.com/hashicorp/go-sockaddr/route_info_android.go @@ -25,6 +25,7 @@ func (ri routeInfo) GetDefaultInterfaceName() (string, error) { return "", err } + var ifName string if ifName, err = parseDefaultIfNameFromIPCmdAndroid(string(out)); err != nil { return "", errors.New("No default interface found") diff --git a/third_party/VENDOR-LICENSE/github.com/hashicorp/go-sockaddr/route_info_bsd.go b/third_party/VENDOR-LICENSE/github.com/hashicorp/go-sockaddr/route_info_bsd.go index 89308cf7cf..705757abc7 100644 --- a/third_party/VENDOR-LICENSE/github.com/hashicorp/go-sockaddr/route_info_bsd.go +++ b/third_party/VENDOR-LICENSE/github.com/hashicorp/go-sockaddr/route_info_bsd.go @@ -1,4 +1,3 @@ -//go:build darwin || dragonfly || freebsd || netbsd || openbsd // +build darwin dragonfly freebsd netbsd openbsd package sockaddr diff --git a/third_party/VENDOR-LICENSE/github.com/hashicorp/go-sockaddr/route_info_default.go b/third_party/VENDOR-LICENSE/github.com/hashicorp/go-sockaddr/route_info_default.go index fe291fb0d6..d1b009f653 100644 --- a/third_party/VENDOR-LICENSE/github.com/hashicorp/go-sockaddr/route_info_default.go +++ b/third_party/VENDOR-LICENSE/github.com/hashicorp/go-sockaddr/route_info_default.go @@ -1,4 +1,3 @@ -//go:build android || nacl || plan9 // +build android nacl plan9 package sockaddr diff --git a/third_party/VENDOR-LICENSE/github.com/hashicorp/go-sockaddr/route_info_linux.go b/third_party/VENDOR-LICENSE/github.com/hashicorp/go-sockaddr/route_info_linux.go index 1b27204885..b62ce6ecb2 100644 --- a/third_party/VENDOR-LICENSE/github.com/hashicorp/go-sockaddr/route_info_linux.go +++ b/third_party/VENDOR-LICENSE/github.com/hashicorp/go-sockaddr/route_info_linux.go @@ -1,4 +1,3 @@ -//go:build !android // +build !android package sockaddr diff --git a/third_party/VENDOR-LICENSE/github.com/hashicorp/go-uuid/uuid.go b/third_party/VENDOR-LICENSE/github.com/hashicorp/go-uuid/uuid.go index 6424c84651..0c10c4e9f5 100644 --- a/third_party/VENDOR-LICENSE/github.com/hashicorp/go-uuid/uuid.go +++ b/third_party/VENDOR-LICENSE/github.com/hashicorp/go-uuid/uuid.go @@ -24,6 +24,7 @@ func GenerateRandomBytesWithReader(size int, reader io.Reader) ([]byte, error) { return buf, nil } + const uuidLen = 16 // GenerateUUID is used to generate a random UUID @@ -57,7 +58,7 @@ func FormatUUID(buf []byte) (string, error) { } func ParseUUID(uuid string) ([]byte, error) { - if len(uuid) != 2*uuidLen+4 { + if len(uuid) != 2 * uuidLen + 4 { return nil, fmt.Errorf("uuid string is wrong length") } diff --git a/third_party/VENDOR-LICENSE/github.com/hashicorp/go-version/CHANGELOG.md b/third_party/VENDOR-LICENSE/github.com/hashicorp/go-version/CHANGELOG.md index 2020c47274..094550020e 100644 --- a/third_party/VENDOR-LICENSE/github.com/hashicorp/go-version/CHANGELOG.md +++ b/third_party/VENDOR-LICENSE/github.com/hashicorp/go-version/CHANGELOG.md @@ -1,4 +1,4 @@ -# 1.4.0 (January 5, 2021) +# 1.4.0 (January 5, 2022) FEATURES: diff --git a/third_party/VENDOR-LICENSE/github.com/hashicorp/go-version/README.md b/third_party/VENDOR-LICENSE/github.com/hashicorp/go-version/README.md index 851a337beb..4d25050903 100644 --- a/third_party/VENDOR-LICENSE/github.com/hashicorp/go-version/README.md +++ b/third_party/VENDOR-LICENSE/github.com/hashicorp/go-version/README.md @@ -1,5 +1,5 @@ # Versioning Library for Go -[![Build Status](https://circleci.com/gh/hashicorp/go-version/tree/master.svg?style=svg)](https://circleci.com/gh/hashicorp/go-version/tree/master) +[![Build Status](https://circleci.com/gh/hashicorp/go-version/tree/main.svg?style=svg)](https://circleci.com/gh/hashicorp/go-version/tree/main) [![GoDoc](https://godoc.org/github.com/hashicorp/go-version?status.svg)](https://godoc.org/github.com/hashicorp/go-version) go-version is a library for parsing versions and version constraints, diff --git a/third_party/VENDOR-LICENSE/github.com/hashicorp/go-version/version.go b/third_party/VENDOR-LICENSE/github.com/hashicorp/go-version/version.go index 116a74466d..e87df69906 100644 --- a/third_party/VENDOR-LICENSE/github.com/hashicorp/go-version/version.go +++ b/third_party/VENDOR-LICENSE/github.com/hashicorp/go-version/version.go @@ -388,3 +388,20 @@ func (v *Version) String() string { func (v *Version) Original() string { return v.original } + +// UnmarshalText implements encoding.TextUnmarshaler interface. +func (v *Version) UnmarshalText(b []byte) error { + temp, err := NewVersion(string(b)) + if err != nil { + return err + } + + *v = *temp + + return nil +} + +// MarshalText implements encoding.TextMarshaler interface. +func (v *Version) MarshalText() ([]byte, error) { + return []byte(v.String()), nil +} diff --git a/third_party/VENDOR-LICENSE/github.com/hashicorp/golang-lru/simplelru/lru_interface.go b/third_party/VENDOR-LICENSE/github.com/hashicorp/golang-lru/simplelru/lru_interface.go index a0b97e3f77..92d70934d6 100644 --- a/third_party/VENDOR-LICENSE/github.com/hashicorp/golang-lru/simplelru/lru_interface.go +++ b/third_party/VENDOR-LICENSE/github.com/hashicorp/golang-lru/simplelru/lru_interface.go @@ -34,6 +34,6 @@ type LRUCache interface { // Clears all cache entries. Purge() - // Resizes cache, returning number evicted - Resize(int) int + // Resizes cache, returning number evicted + Resize(int) int } diff --git a/third_party/VENDOR-LICENSE/github.com/hashicorp/vault/sdk/helper/certutil/helpers.go b/third_party/VENDOR-LICENSE/github.com/hashicorp/vault/sdk/helper/certutil/helpers.go index b6bee2e342..457de9b022 100644 --- a/third_party/VENDOR-LICENSE/github.com/hashicorp/vault/sdk/helper/certutil/helpers.go +++ b/third_party/VENDOR-LICENSE/github.com/hashicorp/vault/sdk/helper/certutil/helpers.go @@ -150,6 +150,46 @@ func ParsePKIJSON(input []byte) (*ParsedCertBundle, error) { return nil, errutil.UserError{Err: "unable to parse out of either secret data or a secret object"} } +func ParseDERKey(privateKeyBytes []byte) (signer crypto.Signer, format BlockType, err error) { + if signer, err = x509.ParseECPrivateKey(privateKeyBytes); err == nil { + format = ECBlock + return + } + + if signer, err = x509.ParsePKCS1PrivateKey(privateKeyBytes); err == nil { + format = PKCS1Block + return + } + + var rawKey interface{} + if rawKey, err = x509.ParsePKCS8PrivateKey(privateKeyBytes); err == nil { + switch rawSigner := rawKey.(type) { + case *rsa.PrivateKey: + signer = rawSigner + case *ecdsa.PrivateKey: + signer = rawSigner + case ed25519.PrivateKey: + signer = rawSigner + default: + return nil, UnknownBlock, errutil.InternalError{Err: "unknown type for parsed PKCS8 Private Key"} + } + + format = PKCS8Block + return + } + + return nil, UnknownBlock, err +} + +func ParsePEMKey(keyPem string) (crypto.Signer, BlockType, error) { + pemBlock, _ := pem.Decode([]byte(keyPem)) + if pemBlock == nil { + return nil, UnknownBlock, errutil.UserError{Err: "no data found in PEM block"} + } + + return ParseDERKey(pemBlock.Bytes) +} + // ParsePEMBundle takes a string of concatenated PEM-format certificate // and private key values and decodes/parses them, checking validity along // the way. The first certificate must be the subject certificate and issuing @@ -170,43 +210,19 @@ func ParsePEMBundle(pemBundle string) (*ParsedCertBundle, error) { return nil, errutil.UserError{Err: "no data found in PEM block"} } - if signer, err := x509.ParseECPrivateKey(pemBlock.Bytes); err == nil { + if signer, format, err := ParseDERKey(pemBlock.Bytes); err == nil { if parsedBundle.PrivateKeyType != UnknownPrivateKey { return nil, errutil.UserError{Err: "more than one private key given; provide only one private key in the bundle"} } - parsedBundle.PrivateKeyFormat = ECBlock - parsedBundle.PrivateKeyType = ECPrivateKey - parsedBundle.PrivateKeyBytes = pemBlock.Bytes - parsedBundle.PrivateKey = signer - } else if signer, err := x509.ParsePKCS1PrivateKey(pemBlock.Bytes); err == nil { - if parsedBundle.PrivateKeyType != UnknownPrivateKey { - return nil, errutil.UserError{Err: "more than one private key given; provide only one private key in the bundle"} + parsedBundle.PrivateKeyFormat = format + parsedBundle.PrivateKeyType = GetPrivateKeyTypeFromSigner(signer) + if parsedBundle.PrivateKeyType == UnknownPrivateKey { + return nil, errutil.UserError{Err: "Unknown type of private key included in the bundle: %v"} } - parsedBundle.PrivateKeyType = RSAPrivateKey - parsedBundle.PrivateKeyFormat = PKCS1Block + parsedBundle.PrivateKeyBytes = pemBlock.Bytes parsedBundle.PrivateKey = signer - } else if signer, err := x509.ParsePKCS8PrivateKey(pemBlock.Bytes); err == nil { - parsedBundle.PrivateKeyFormat = PKCS8Block - - if parsedBundle.PrivateKeyType != UnknownPrivateKey { - return nil, errutil.UserError{Err: "More than one private key given; provide only one private key in the bundle"} - } - switch signer := signer.(type) { - case *rsa.PrivateKey: - parsedBundle.PrivateKey = signer - parsedBundle.PrivateKeyType = RSAPrivateKey - parsedBundle.PrivateKeyBytes = pemBlock.Bytes - case *ecdsa.PrivateKey: - parsedBundle.PrivateKey = signer - parsedBundle.PrivateKeyType = ECPrivateKey - parsedBundle.PrivateKeyBytes = pemBlock.Bytes - case ed25519.PrivateKey: - parsedBundle.PrivateKey = signer - parsedBundle.PrivateKeyType = Ed25519PrivateKey - parsedBundle.PrivateKeyBytes = pemBlock.Bytes - } } else if certificates, err := x509.ParseCertificates(pemBlock.Bytes); err == nil { certPath = append(certPath, &CertBlock{ Certificate: certificates[0], @@ -336,7 +352,21 @@ func generateSerialNumber(randReader io.Reader) (*big.Int, error) { return serial, nil } -// ComparePublicKeys compares two public keys and returns true if they match +// ComparePublicKeysAndType compares two public keys and returns true if they match, +// false if their types or contents differ, and an error on unsupported key types. +func ComparePublicKeysAndType(key1Iface, key2Iface crypto.PublicKey) (bool, error) { + equal, err := ComparePublicKeys(key1Iface, key2Iface) + if err != nil { + if strings.Contains(err.Error(), "key types do not match:") { + return false, nil + } + } + + return equal, err +} + +// ComparePublicKeys compares two public keys and returns true if they match, +// returns an error if public key types are mismatched, or they are an unsupported key type. func ComparePublicKeys(key1Iface, key2Iface crypto.PublicKey) (bool, error) { switch key1Iface.(type) { case *rsa.PublicKey: @@ -416,18 +446,30 @@ func ParsePublicKeyPEM(data []byte) (interface{}, error) { return nil, errors.New("data does not contain any valid public keys") } -// addPolicyIdentifiers adds certificate policies extension -// +// AddPolicyIdentifiers adds certificate policies extension, based on CreationBundle func AddPolicyIdentifiers(data *CreationBundle, certTemplate *x509.Certificate) { - for _, oidstr := range data.Params.PolicyIdentifiers { - oid, err := StringToOid(oidstr) + oidOnly := true + for _, oidStr := range data.Params.PolicyIdentifiers { + oid, err := StringToOid(oidStr) if err == nil { certTemplate.PolicyIdentifiers = append(certTemplate.PolicyIdentifiers, oid) } + if err != nil { + oidOnly = false + } + } + if !oidOnly { // Because all policy information is held in the same extension, when we use an extra extension to + // add policy qualifier information, that overwrites any information in the PolicyIdentifiers field on the Cert + // Template, so we need to reparse all the policy identifiers here + extension, err := CreatePolicyInformationExtensionFromStorageStrings(data.Params.PolicyIdentifiers) + if err == nil { + // If this errors out, don't add it, rely on the OIDs parsed into PolicyIdentifiers above + certTemplate.ExtraExtensions = append(certTemplate.ExtraExtensions, *extension) + } } } -// addExtKeyUsageOids adds custom extended key usage OIDs to certificate +// AddExtKeyUsageOids adds custom extended key usage OIDs to certificate func AddExtKeyUsageOids(data *CreationBundle, certTemplate *x509.Certificate) { for _, oidstr := range data.Params.ExtKeyUsageOIDs { oid, err := StringToOid(oidstr) @@ -585,25 +627,17 @@ func DefaultOrValueKeyBits(keyType string, keyBits int) (int, error) { // certain internal circumstances. func DefaultOrValueHashBits(keyType string, keyBits int, hashBits int) (int, error) { if keyType == "ec" { - // To comply with BSI recommendations Section 4.2 and Mozilla root - // store policy section 5.1.2, enforce that NIST P-curves use a hash - // length corresponding to curve length. Note that ed25519 does not - // the "ec" key type. - expectedHashBits := expectedNISTPCurveHashBits[keyBits] - - if expectedHashBits != hashBits && hashBits != 0 { - return hashBits, fmt.Errorf("unsupported signature hash algorithm length (%d) for NIST P-%d", hashBits, keyBits) - } else if hashBits == 0 { - hashBits = expectedHashBits - } + // Enforcement of curve moved to selectSignatureAlgorithmForECDSA. See + // note there about why. } else if keyType == "rsa" && hashBits == 0 { // To match previous behavior (and ignoring NIST's recommendations for // hash size to align with RSA key sizes), default to SHA-2-256. hashBits = 256 - } else if keyType == "ed25519" || keyType == "ed448" { + } else if keyType == "ed25519" || keyType == "ed448" || keyType == "any" { // No-op; ed25519 and ed448 internally specify their own hash and // we do not need to select one. Double hashing isn't supported in - // certificate signing and we must + // certificate signing. Additionally, the any key type can't know + // what hash algorithm to use yet, so default to zero. return 0, nil } @@ -642,7 +676,7 @@ func ValidateDefaultOrValueKeyTypeSignatureLength(keyType string, keyBits int, h // Validates that the length of the hash (in bits) used in the signature // calculation is a known, approved value. func ValidateSignatureLength(keyType string, hashBits int) error { - if keyType == "ed25519" || keyType == "ed448" { + if keyType == "any" || keyType == "ec" || keyType == "ed25519" || keyType == "ed448" { // ed25519 and ed448 include built-in hashing and is not externally // configurable. There are three modes for each of these schemes: // @@ -654,6 +688,13 @@ func ValidateSignatureLength(keyType string, hashBits int) error { // // In all cases, we won't have a hash algorithm to validate here, so // return nil. + // + // Additionally, when KeyType is any, we can't yet validate the + // signature algorithm size, so it takes the default zero value. + // + // When KeyType is ec, we also can't validate this value as we're + // forcefully ignoring the users' choice and specifying a value based + // on issuer type. return nil } @@ -842,16 +883,25 @@ func createCertificate(data *CreationBundle, randReader io.Reader, privateKeyGen } if data.SigningBundle != nil { - if len(data.SigningBundle.Certificate.AuthorityKeyId) > 0 && - !bytes.Equal(data.SigningBundle.Certificate.AuthorityKeyId, data.SigningBundle.Certificate.SubjectKeyId) { - - result.CAChain = []*CertBlock{ - { + if (len(data.SigningBundle.Certificate.AuthorityKeyId) > 0 && + !bytes.Equal(data.SigningBundle.Certificate.AuthorityKeyId, data.SigningBundle.Certificate.SubjectKeyId)) || + data.Params.ForceAppendCaChain { + var chain []*CertBlock + + signingChain := data.SigningBundle.CAChain + // Some bundles already include the root included in the chain, so don't include it twice. + if len(signingChain) == 0 || !bytes.Equal(signingChain[0].Bytes, data.SigningBundle.CertificateBytes) { + chain = append(chain, &CertBlock{ Certificate: data.SigningBundle.Certificate, Bytes: data.SigningBundle.CertificateBytes, - }, + }) } - result.CAChain = append(result.CAChain, data.SigningBundle.CAChain...) + + if len(signingChain) > 0 { + chain = append(chain, signingChain...) + } + + result.CAChain = chain } } @@ -859,16 +909,25 @@ func createCertificate(data *CreationBundle, randReader io.Reader, privateKeyGen } func selectSignatureAlgorithmForECDSA(pub crypto.PublicKey, signatureBits int) x509.SignatureAlgorithm { - // If signature bits are configured, prefer them to the default choice. - switch signatureBits { - case 256: - return x509.ECDSAWithSHA256 - case 384: - return x509.ECDSAWithSHA384 - case 512: - return x509.ECDSAWithSHA512 - } - + // Previously we preferred the user-specified signature bits for ECDSA + // keys. However, this could result in using a longer hash function than + // the underlying NIST P-curve will encode (e.g., a SHA-512 hash with a + // P-256 key). This isn't ideal: the hash is implicitly truncated + // (effectively turning it into SHA-512/256) and we then need to rely + // on the prefix security of the hash. Since both NIST and Mozilla guidance + // suggest instead using the correct hash function, we should prefer that + // over the operator-specified signatureBits. + // + // Lastly, note that pub above needs to be the _signer's_ public key; + // the issue with DefaultOrValueHashBits is that it is called at role + // configuration time, which might _precede_ issuer generation. Thus + // it only has access to the desired key type and not the actual issuer. + // The reference from that function is reproduced below: + // + // > To comply with BSI recommendations Section 4.2 and Mozilla root + // > store policy section 5.1.2, enforce that NIST P-curves use a hash + // > length corresponding to curve length. Note that ed25519 does not + // > implement the "ec" key type. key, ok := pub.(*ecdsa.PublicKey) if !ok { return x509.ECDSAWithSHA256 @@ -1120,7 +1179,7 @@ func signCertificate(data *CreationBundle, randReader io.Reader) (*ParsedCertBun return nil, errutil.InternalError{Err: fmt.Sprintf("unable to parse created certificate: %s", err)} } - result.CAChain = data.SigningBundle.GetCAChain() + result.CAChain = data.SigningBundle.GetFullChain() return result, nil } @@ -1190,3 +1249,20 @@ func GetPublicKeySize(key crypto.PublicKey) int { return -1 } + +// CreateKeyBundle create a KeyBundle struct object which includes a generated key +// of keyType with keyBits leveraging the randomness from randReader. +func CreateKeyBundle(keyType string, keyBits int, randReader io.Reader) (KeyBundle, error) { + return CreateKeyBundleWithKeyGenerator(keyType, keyBits, randReader, generatePrivateKey) +} + +// CreateKeyBundleWithKeyGenerator create a KeyBundle struct object which includes +// a generated key of keyType with keyBits leveraging the randomness from randReader and +// delegates the actual key generation to keyGenerator +func CreateKeyBundleWithKeyGenerator(keyType string, keyBits int, randReader io.Reader, keyGenerator KeyGenerator) (KeyBundle, error) { + result := KeyBundle{} + if err := keyGenerator(keyType, keyBits, &result, randReader); err != nil { + return result, err + } + return result, nil +} diff --git a/third_party/VENDOR-LICENSE/github.com/hashicorp/vault/sdk/helper/certutil/types.go b/third_party/VENDOR-LICENSE/github.com/hashicorp/vault/sdk/helper/certutil/types.go index 076a4e3528..a5caa2e440 100644 --- a/third_party/VENDOR-LICENSE/github.com/hashicorp/vault/sdk/helper/certutil/types.go +++ b/third_party/VENDOR-LICENSE/github.com/hashicorp/vault/sdk/helper/certutil/types.go @@ -17,7 +17,10 @@ import ( "crypto/tls" "crypto/x509" "crypto/x509/pkix" + "encoding/asn1" + "encoding/json" "encoding/pem" + "errors" "fmt" "math/big" "net" @@ -78,9 +81,10 @@ type BlockType string // Well-known formats const ( - PKCS1Block BlockType = "RSA PRIVATE KEY" - PKCS8Block BlockType = "PRIVATE KEY" - ECBlock BlockType = "EC PRIVATE KEY" + UnknownBlock BlockType = "" + PKCS1Block BlockType = "RSA PRIVATE KEY" + PKCS8Block BlockType = "PRIVATE KEY" + ECBlock BlockType = "EC PRIVATE KEY" ) // ParsedPrivateKeyContainer allows common key setting for certs and CSRs @@ -137,6 +141,25 @@ type ParsedCSRBundle struct { CSR *x509.CertificateRequest } +type KeyBundle struct { + PrivateKeyType PrivateKeyType + PrivateKeyBytes []byte + PrivateKey crypto.Signer +} + +func GetPrivateKeyTypeFromSigner(signer crypto.Signer) PrivateKeyType { + switch signer.(type) { + case *rsa.PrivateKey: + return RSAPrivateKey + case *ecdsa.PrivateKey: + return ECPrivateKey + case ed25519.PrivateKey: + return Ed25519PrivateKey + default: + return UnknownPrivateKey + } +} + // ToPEMBundle converts a string-based certificate bundle // to a PEM-based string certificate bundle in trust path // order, leaf certificate first @@ -661,9 +684,32 @@ type URLEntries struct { OCSPServers []string `json:"ocsp_servers" structs:"ocsp_servers" mapstructure:"ocsp_servers"` } +type NotAfterBehavior int + +const ( + ErrNotAfterBehavior NotAfterBehavior = iota + TruncateNotAfterBehavior + PermitNotAfterBehavior +) + +var notAfterBehaviorNames = map[NotAfterBehavior]string{ + ErrNotAfterBehavior: "err", + TruncateNotAfterBehavior: "truncate", + PermitNotAfterBehavior: "permit", +} + +func (n NotAfterBehavior) String() string { + if name, ok := notAfterBehaviorNames[n]; ok && len(name) > 0 { + return name + } + + return "unknown" +} + type CAInfoBundle struct { ParsedCertBundle - URLs *URLEntries + URLs *URLEntries + LeafNotAfterBehavior NotAfterBehavior } func (b *CAInfoBundle) GetCAChain() []*CertBlock { @@ -675,13 +721,7 @@ func (b *CAInfoBundle) GetCAChain() []*CertBlock { (len(b.Certificate.AuthorityKeyId) == 0 && !bytes.Equal(b.Certificate.RawIssuer, b.Certificate.RawSubject)) { - chain = append(chain, &CertBlock{ - Certificate: b.Certificate, - Bytes: b.CertificateBytes, - }) - if b.CAChain != nil && len(b.CAChain) > 0 { - chain = append(chain, b.CAChain...) - } + chain = b.GetFullChain() } return chain @@ -690,10 +730,14 @@ func (b *CAInfoBundle) GetCAChain() []*CertBlock { func (b *CAInfoBundle) GetFullChain() []*CertBlock { var chain []*CertBlock - chain = append(chain, &CertBlock{ - Certificate: b.Certificate, - Bytes: b.CertificateBytes, - }) + // Some bundles already include the root included in the chain, + // so don't include it twice. + if len(b.CAChain) == 0 || !bytes.Equal(b.CAChain[0].Bytes, b.CertificateBytes) { + chain = append(chain, &CertBlock{ + Certificate: b.Certificate, + Bytes: b.CertificateBytes, + }) + } if len(b.CAChain) > 0 { chain = append(chain, b.CAChain...) @@ -738,6 +782,7 @@ type CreationParameters struct { PolicyIdentifiers []string BasicConstraintsValidForNonCA bool SignatureBits int + ForceAppendCaChain bool // Only used when signing a CA cert UseCSRValues bool @@ -825,3 +870,141 @@ func AddKeyUsages(data *CreationBundle, certTemplate *x509.Certificate) { certTemplate.ExtKeyUsage = append(certTemplate.ExtKeyUsage, x509.ExtKeyUsageMicrosoftKernelCodeSigning) } } + +// SetParsedPrivateKey sets the private key parameters on the bundle +func (p *KeyBundle) SetParsedPrivateKey(privateKey crypto.Signer, privateKeyType PrivateKeyType, privateKeyBytes []byte) { + p.PrivateKey = privateKey + p.PrivateKeyType = privateKeyType + p.PrivateKeyBytes = privateKeyBytes +} + +func (p *KeyBundle) ToPrivateKeyPemString() (string, error) { + block := pem.Block{} + + if p.PrivateKeyBytes != nil && len(p.PrivateKeyBytes) > 0 { + block.Bytes = p.PrivateKeyBytes + switch p.PrivateKeyType { + case RSAPrivateKey: + block.Type = "RSA PRIVATE KEY" + case ECPrivateKey: + block.Type = "EC PRIVATE KEY" + default: + block.Type = "PRIVATE KEY" + } + privateKeyPemString := strings.TrimSpace(string(pem.EncodeToMemory(&block))) + return privateKeyPemString, nil + } + + return "", errutil.InternalError{Err: "No Private Key Bytes to Wrap"} +} + +// PolicyIdentifierWithQualifierEntry Structure for Internal Storage +type PolicyIdentifierWithQualifierEntry struct { + PolicyIdentifierOid string `json:"oid",mapstructure:"oid"` + CPS string `json:"cps,omitempty",mapstructure:"cps"` + Notice string `json:"notice,omitempty",mapstructure:"notice"` +} + +// GetPolicyIdentifierFromString parses out the internal structure of a Policy Identifier +func GetPolicyIdentifierFromString(policyIdentifier string) (*PolicyIdentifierWithQualifierEntry, error) { + if policyIdentifier == "" { + return nil, nil + } + entry := &PolicyIdentifierWithQualifierEntry{} + // Either a OID, or a JSON Entry: First check OID: + _, err := StringToOid(policyIdentifier) + if err == nil { + entry.PolicyIdentifierOid = policyIdentifier + return entry, nil + } + // Now Check If JSON Entry + jsonErr := json.Unmarshal([]byte(policyIdentifier), &entry) + if jsonErr != nil { // Neither, if we got here + return entry, errors.New(fmt.Sprintf("Policy Identifier %q is neither a valid OID: %s, Nor JSON Policy Identifier: %s", policyIdentifier, err.Error(), jsonErr.Error())) + } + return entry, nil +} + +// Policy Identifier with Qualifier Structure for ASN Marshalling: + +var policyInformationOid = asn1.ObjectIdentifier{2, 5, 29, 32} + +type policyInformation struct { + PolicyIdentifier asn1.ObjectIdentifier + Qualifiers []interface{} `asn1:"tag:optional,omitempty"` +} + +var cpsPolicyQualifierID = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 2, 1} + +type cpsUrlPolicyQualifier struct { + PolicyQualifierID asn1.ObjectIdentifier + Qualifier string `asn1:"tag:optional,ia5"` +} + +var userNoticePolicyQualifierID = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 2, 2} + +type userNoticePolicyQualifier struct { + PolicyQualifierID asn1.ObjectIdentifier + Qualifier userNotice +} + +type userNotice struct { + ExplicitText string `asn1:"tag:optional,utf8"` +} + +func createPolicyIdentifierWithQualifier(entry PolicyIdentifierWithQualifierEntry) (*policyInformation, error) { + // Each Policy is Identified by a Unique ID, as designated here: + policyOid, err := StringToOid(entry.PolicyIdentifierOid) + if err != nil { + return nil, err + } + pi := policyInformation{ + PolicyIdentifier: policyOid, + } + if entry.CPS != "" { + qualifier := cpsUrlPolicyQualifier{ + PolicyQualifierID: cpsPolicyQualifierID, + Qualifier: entry.CPS, + } + pi.Qualifiers = append(pi.Qualifiers, qualifier) + } + if entry.Notice != "" { + qualifier := userNoticePolicyQualifier{ + PolicyQualifierID: userNoticePolicyQualifierID, + Qualifier: userNotice{ + ExplicitText: entry.Notice, + }, + } + pi.Qualifiers = append(pi.Qualifiers, qualifier) + } + return &pi, nil +} + +// CreatePolicyInformationExtensionFromStorageStrings parses the stored policyIdentifiers, which might be JSON Policy +// Identifier with Qualifier Entries or String OIDs, and returns an extension if everything parsed correctly, and an +// error if constructing +func CreatePolicyInformationExtensionFromStorageStrings(policyIdentifiers []string) (*pkix.Extension, error) { + var policyInformationList []policyInformation + for _, policyIdentifierStr := range policyIdentifiers { + policyIdentifierEntry, err := GetPolicyIdentifierFromString(policyIdentifierStr) + if err != nil { + return nil, err + } + if policyIdentifierEntry != nil { // Okay to skip empty entries if there is no error + policyInformationStruct, err := createPolicyIdentifierWithQualifier(*policyIdentifierEntry) + if err != nil { + return nil, err + } + policyInformationList = append(policyInformationList, *policyInformationStruct) + } + } + asn1Bytes, err := asn1.Marshal(policyInformationList) + if err != nil { + return nil, err + } + return &pkix.Extension{ + Id: policyInformationOid, + Critical: false, + Value: asn1Bytes, + }, nil +} diff --git a/third_party/VENDOR-LICENSE/github.com/hashicorp/vault/sdk/helper/consts/consts.go b/third_party/VENDOR-LICENSE/github.com/hashicorp/vault/sdk/helper/consts/consts.go index b10f57a229..c431e2e594 100644 --- a/third_party/VENDOR-LICENSE/github.com/hashicorp/vault/sdk/helper/consts/consts.go +++ b/third_party/VENDOR-LICENSE/github.com/hashicorp/vault/sdk/helper/consts/consts.go @@ -32,4 +32,6 @@ const ( // ReplicationResolverALPN is the negotiated protocol used for // resolving replicaiton addresses ReplicationResolverALPN = "replication_resolver_v1" + + VaultEnableFilePermissionsCheckEnv = "VAULT_ENABLE_FILE_PERMISSIONS_CHECK" ) diff --git a/third_party/VENDOR-LICENSE/github.com/hashicorp/vault/sdk/helper/pluginutil/multiplexing.pb.go b/third_party/VENDOR-LICENSE/github.com/hashicorp/vault/sdk/helper/pluginutil/multiplexing.pb.go index fa3357d490..d0ff51e57b 100644 --- a/third_party/VENDOR-LICENSE/github.com/hashicorp/vault/sdk/helper/pluginutil/multiplexing.pb.go +++ b/third_party/VENDOR-LICENSE/github.com/hashicorp/vault/sdk/helper/pluginutil/multiplexing.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.27.1 -// protoc v3.19.3 +// protoc v3.19.4 // source: sdk/helper/pluginutil/multiplexing.proto package pluginutil diff --git a/third_party/VENDOR-LICENSE/github.com/hashicorp/vault/sdk/logical/auth.go b/third_party/VENDOR-LICENSE/github.com/hashicorp/vault/sdk/logical/auth.go index 7f68bc936e..62707e8195 100644 --- a/third_party/VENDOR-LICENSE/github.com/hashicorp/vault/sdk/logical/auth.go +++ b/third_party/VENDOR-LICENSE/github.com/hashicorp/vault/sdk/logical/auth.go @@ -8,7 +8,8 @@ import ( ) // Auth is the resulting authentication information that is part of -// Response for credential backends. +// Response for credential backends. It's also attached to Request objects and +// defines the authentication used for the request. This value is audit logged. type Auth struct { LeaseOptions @@ -101,10 +102,28 @@ type Auth struct { // Orphan is set if the token does not have a parent Orphan bool `json:"orphan"` + // PolicyResults is the set of policies that grant the token access to the + // requesting path. + PolicyResults *PolicyResults `json:"policy_results"` + // MFARequirement MFARequirement *MFARequirement `json:"mfa_requirement"` + + // EntityCreated is set to true if an entity is created as part of a login request + EntityCreated bool `json:"entity_created"` } func (a *Auth) GoString() string { return fmt.Sprintf("*%#v", *a) } + +type PolicyResults struct { + Allowed bool `json:"allowed"` + GrantingPolicies []PolicyInfo `json:"granting_policies"` +} + +type PolicyInfo struct { + Name string `json:"name"` + NamespaceId string `json:"namespace_id"` + Type string `json:"type"` +} diff --git a/third_party/VENDOR-LICENSE/github.com/hashicorp/vault/sdk/logical/identity.pb.go b/third_party/VENDOR-LICENSE/github.com/hashicorp/vault/sdk/logical/identity.pb.go index c472b68a09..4b1a36b398 100644 --- a/third_party/VENDOR-LICENSE/github.com/hashicorp/vault/sdk/logical/identity.pb.go +++ b/third_party/VENDOR-LICENSE/github.com/hashicorp/vault/sdk/logical/identity.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.27.1 -// protoc v3.19.3 +// protoc v3.19.4 // source: sdk/logical/identity.proto package logical diff --git a/third_party/VENDOR-LICENSE/github.com/hashicorp/vault/sdk/logical/managed_key.go b/third_party/VENDOR-LICENSE/github.com/hashicorp/vault/sdk/logical/managed_key.go index 917d1c5e5a..750459542c 100644 --- a/third_party/VENDOR-LICENSE/github.com/hashicorp/vault/sdk/logical/managed_key.go +++ b/third_party/VENDOR-LICENSE/github.com/hashicorp/vault/sdk/logical/managed_key.go @@ -40,17 +40,17 @@ type ( type ManagedKeySystemView interface { // WithManagedKeyByName retrieves an instantiated managed key for consumption by the given function. The // provided key can only be used within the scope of that function call - WithManagedKeyByName(ctx context.Context, keyName, mountPoint string, f ManagedKeyConsumer) error + WithManagedKeyByName(ctx context.Context, keyName, backendUUID string, f ManagedKeyConsumer) error // WithManagedKeyByUUID retrieves an instantiated managed key for consumption by the given function. The // provided key can only be used within the scope of that function call - WithManagedKeyByUUID(ctx context.Context, keyUuid, mountPoint string, f ManagedKeyConsumer) error + WithManagedKeyByUUID(ctx context.Context, keyUuid, backendUUID string, f ManagedKeyConsumer) error // WithManagedSigningKeyByName retrieves an instantiated managed signing key for consumption by the given function, // with the same semantics as WithManagedKeyByName - WithManagedSigningKeyByName(ctx context.Context, keyName, mountPoint string, f ManagedSigningKeyConsumer) error + WithManagedSigningKeyByName(ctx context.Context, keyName, backendUUID string, f ManagedSigningKeyConsumer) error // WithManagedSigningKeyByUUID retrieves an instantiated managed signing key for consumption by the given function, // with the same semantics as WithManagedKeyByUUID - WithManagedSigningKeyByUUID(ctx context.Context, keyUuid, mountPoint string, f ManagedSigningKeyConsumer) error + WithManagedSigningKeyByUUID(ctx context.Context, keyUuid, backendUUID string, f ManagedSigningKeyConsumer) error } type ManagedAsymmetricKey interface { diff --git a/third_party/VENDOR-LICENSE/github.com/hashicorp/vault/sdk/logical/plugin.pb.go b/third_party/VENDOR-LICENSE/github.com/hashicorp/vault/sdk/logical/plugin.pb.go index d4722ce097..1fb53f9a79 100644 --- a/third_party/VENDOR-LICENSE/github.com/hashicorp/vault/sdk/logical/plugin.pb.go +++ b/third_party/VENDOR-LICENSE/github.com/hashicorp/vault/sdk/logical/plugin.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.27.1 -// protoc v3.19.3 +// protoc v3.19.4 // source: sdk/logical/plugin.proto package logical @@ -27,6 +27,10 @@ type PluginEnvironment struct { // VaultVersion is the version of the Vault server VaultVersion string `protobuf:"bytes,1,opt,name=vault_version,json=vaultVersion,proto3" json:"vault_version,omitempty"` + // VaultVersionPrerelease is the prerelease information of the Vault server + VaultVersionPrerelease string `protobuf:"bytes,2,opt,name=vault_version_prerelease,json=vaultVersionPrerelease,proto3" json:"vault_version_prerelease,omitempty"` + // VaultVersionMetadata is the version metadata of the Vault server + VaultVersionMetadata string `protobuf:"bytes,3,opt,name=vault_version_metadata,json=vaultVersionMetadata,proto3" json:"vault_version_metadata,omitempty"` } func (x *PluginEnvironment) Reset() { @@ -68,18 +72,39 @@ func (x *PluginEnvironment) GetVaultVersion() string { return "" } +func (x *PluginEnvironment) GetVaultVersionPrerelease() string { + if x != nil { + return x.VaultVersionPrerelease + } + return "" +} + +func (x *PluginEnvironment) GetVaultVersionMetadata() string { + if x != nil { + return x.VaultVersionMetadata + } + return "" +} + var File_sdk_logical_plugin_proto protoreflect.FileDescriptor var file_sdk_logical_plugin_proto_rawDesc = []byte{ 0x0a, 0x18, 0x73, 0x64, 0x6b, 0x2f, 0x6c, 0x6f, 0x67, 0x69, 0x63, 0x61, 0x6c, 0x2f, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x07, 0x6c, 0x6f, 0x67, 0x69, - 0x63, 0x61, 0x6c, 0x22, 0x38, 0x0a, 0x11, 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x45, 0x6e, 0x76, - 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x23, 0x0a, 0x0d, 0x76, 0x61, 0x75, 0x6c, - 0x74, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0c, 0x76, 0x61, 0x75, 0x6c, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x42, 0x28, 0x5a, - 0x26, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, - 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x76, 0x61, 0x75, 0x6c, 0x74, 0x2f, 0x73, 0x64, 0x6b, 0x2f, - 0x6c, 0x6f, 0x67, 0x69, 0x63, 0x61, 0x6c, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x63, 0x61, 0x6c, 0x22, 0xa8, 0x01, 0x0a, 0x11, 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x45, 0x6e, + 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x23, 0x0a, 0x0d, 0x76, 0x61, 0x75, + 0x6c, 0x74, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0c, 0x76, 0x61, 0x75, 0x6c, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x38, + 0x0a, 0x18, 0x76, 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x5f, + 0x70, 0x72, 0x65, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x16, 0x76, 0x61, 0x75, 0x6c, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x50, 0x72, + 0x65, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x12, 0x34, 0x0a, 0x16, 0x76, 0x61, 0x75, 0x6c, + 0x74, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, + 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x14, 0x76, 0x61, 0x75, 0x6c, 0x74, 0x56, + 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x42, 0x28, + 0x5a, 0x26, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, + 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x76, 0x61, 0x75, 0x6c, 0x74, 0x2f, 0x73, 0x64, 0x6b, + 0x2f, 0x6c, 0x6f, 0x67, 0x69, 0x63, 0x61, 0x6c, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/third_party/VENDOR-LICENSE/github.com/hashicorp/vault/sdk/logical/plugin.proto b/third_party/VENDOR-LICENSE/github.com/hashicorp/vault/sdk/logical/plugin.proto index 5992c21395..f2df6c75d9 100644 --- a/third_party/VENDOR-LICENSE/github.com/hashicorp/vault/sdk/logical/plugin.proto +++ b/third_party/VENDOR-LICENSE/github.com/hashicorp/vault/sdk/logical/plugin.proto @@ -7,4 +7,10 @@ package logical; message PluginEnvironment { // VaultVersion is the version of the Vault server string vault_version = 1; + + // VaultVersionPrerelease is the prerelease information of the Vault server + string vault_version_prerelease = 2; + + // VaultVersionMetadata is the version metadata of the Vault server + string vault_version_metadata = 3; } diff --git a/third_party/VENDOR-LICENSE/github.com/hashicorp/vault/sdk/logical/response_util.go b/third_party/VENDOR-LICENSE/github.com/hashicorp/vault/sdk/logical/response_util.go index 92e3483d87..7454189f1d 100644 --- a/third_party/VENDOR-LICENSE/github.com/hashicorp/vault/sdk/logical/response_util.go +++ b/third_party/VENDOR-LICENSE/github.com/hashicorp/vault/sdk/logical/response_util.go @@ -120,6 +120,8 @@ func RespondErrorCommon(req *Request, resp *Response, err error) (int, error) { statusCode = http.StatusPreconditionFailed case errwrap.Contains(err, ErrPathFunctionalityRemoved.Error()): statusCode = http.StatusNotFound + case errwrap.Contains(err, ErrRelativePath.Error()): + statusCode = http.StatusBadRequest } } diff --git a/third_party/VENDOR-LICENSE/github.com/hashicorp/vault/sdk/version/version.go b/third_party/VENDOR-LICENSE/github.com/hashicorp/vault/sdk/version/version.go index 1a4521ae61..78b8eb829c 100644 --- a/third_party/VENDOR-LICENSE/github.com/hashicorp/vault/sdk/version/version.go +++ b/third_party/VENDOR-LICENSE/github.com/hashicorp/vault/sdk/version/version.go @@ -11,6 +11,7 @@ type VersionInfo struct { Version string `json:"version,omitempty"` VersionPrerelease string `json:"version_prerelease,omitempty"` VersionMetadata string `json:"version_metadata,omitempty"` + BuildDate string `json:"build_date,omitempty"` } func GetVersion() *VersionInfo { @@ -29,6 +30,7 @@ func GetVersion() *VersionInfo { Version: ver, VersionPrerelease: rel, VersionMetadata: md, + BuildDate: BuildDate, } } @@ -70,5 +72,9 @@ func (c *VersionInfo) FullVersionNumber(rev bool) string { fmt.Fprintf(&versionString, " (%s)", c.Revision) } + if c.BuildDate != "" { + fmt.Fprintf(&versionString, ", built %s", c.BuildDate) + } + return versionString.String() } diff --git a/third_party/VENDOR-LICENSE/github.com/hashicorp/vault/sdk/version/version_base.go b/third_party/VENDOR-LICENSE/github.com/hashicorp/vault/sdk/version/version_base.go index 5211c15ba0..fd2cba1207 100644 --- a/third_party/VENDOR-LICENSE/github.com/hashicorp/vault/sdk/version/version_base.go +++ b/third_party/VENDOR-LICENSE/github.com/hashicorp/vault/sdk/version/version_base.go @@ -5,10 +5,13 @@ var ( GitCommit string GitDescribe string + // The compilation date. This will be filled in by the compiler. + BuildDate string + // Whether cgo is enabled or not; set at build time CgoEnabled bool - Version = "1.10.0" - VersionPrerelease = "dev1" + Version = "1.11.0" + VersionPrerelease = "" VersionMetadata = "" ) diff --git a/third_party/VENDOR-LICENSE/github.com/ktr0731/go-fuzzyfinder/LICENSE b/third_party/VENDOR-LICENSE/github.com/ktr0731/go-fuzzyfinder/LICENSE index a14c474632..2591bc981a 100644 --- a/third_party/VENDOR-LICENSE/github.com/ktr0731/go-fuzzyfinder/LICENSE +++ b/third_party/VENDOR-LICENSE/github.com/ktr0731/go-fuzzyfinder/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2019 ktr0731 +Copyright (c) 2019-2021 ktr0731 Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/third_party/VENDOR-LICENSE/github.com/nsf/termbox-go/LICENSE b/third_party/VENDOR-LICENSE/github.com/nsf/termbox-go/LICENSE new file mode 100644 index 0000000000..d9bc068ce7 --- /dev/null +++ b/third_party/VENDOR-LICENSE/github.com/nsf/termbox-go/LICENSE @@ -0,0 +1,19 @@ +Copyright (C) 2012 termbox-go authors + +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. diff --git a/vendor/github.com/AlecAivazis/survey/v2/.travis.yml b/vendor/github.com/AlecAivazis/survey/v2/.travis.yml deleted file mode 100644 index f96db1ac0e..0000000000 --- a/vendor/github.com/AlecAivazis/survey/v2/.travis.yml +++ /dev/null @@ -1,22 +0,0 @@ -language: go - -go: - - 1.12 - -os: - - linux - - linux-ppc64le - - osx - - windows - -go_import_path: github.com/AlecAivazis/survey/v2 - -before_install: - - go get github.com/alecaivazis/run - -install: - - run install-deps - -script: - - run tests - # - run autoplay-tests diff --git a/vendor/github.com/AlecAivazis/survey/v2/CONTRIBUTING.md b/vendor/github.com/AlecAivazis/survey/v2/CONTRIBUTING.md index a84e06061e..31f5be9066 100644 --- a/vendor/github.com/AlecAivazis/survey/v2/CONTRIBUTING.md +++ b/vendor/github.com/AlecAivazis/survey/v2/CONTRIBUTING.md @@ -4,48 +4,26 @@ The following is a set of guidelines to follow when contributing to this package. These are not hard rules, please use common sense and feel free to propose changes to this document in a pull request. -## Table of Contents - -1. [Code of Conduct](#code-of-conduct) -1. [Getting Help](#getting-help) -1. [Filing a Bug Report](#how-to-file-a-bug-report) -1. [Suggesting an API change](#suggesting-an-api-change) -1. [Submitting a Contribution](#submitting-a-contribution) -1. [Writing and Running Tests](#writing-and-running-tests) - ## Code of Conduct This project and its contibutors are expected to uphold the [Go Community Code of Conduct](https://golang.org/conduct). By participating, you are expected to follow these guidelines. ## Getting help -Feel free to [open up an issue](https://github.com/AlecAivazis/survey/v2/issues/new) on GitHub when asking a question so others will be able to find it. Please remember to tag the issue with the `Question` label so the maintainers can get to your question as soon as possible. If the question is urgent, feel free to reach out to `@AlecAivazis` directly in the gophers slack channel. - -## How to file a bug report - -Bugs are tracked using the Github Issue tracker. When filing a bug, please remember to label the issue as a `Bug` and answer/provide the following: - -1. What operating system and terminal are you using? -1. An example that showcases the bug. -1. What did you expect to see? -1. What did you see instead? - -## Suggesting an API change - -If you have an idea, I'm more than happy to discuss it. Please open an issue and we can work through it. In order to maintain some sense of stability, additions to the top-level API are taken just as seriously as changes that break it. Adding stuff is much easier than removing it. +* [Open an issue](https://github.com/AlecAivazis/survey/issues/new/choose) +* Reach out to `@AlecAivazis` or `@mislav` in the Gophers slack (please use only when urgent) ## Submitting a contribution -In order to maintain stability, most features get fully integrated in more than one PR. This allows for more opportunity to think through each API change without amassing large amounts of tech debt and API changes at once. If your feature can be broken into separate chunks, it will be able to be reviewed much quicker. For example, if the PR that implemented the `Validate` field was submitted in a PR separately from one that included `survey.Required`, it would be able to get merge without having to decide how many different `Validators` we want to provide as part of `survey`'s API. - When submitting a contribution, -- Provide a description of the feature or change -- Reference the ticket addressed by the PR if there is one -- Following community standards, add comments for all exported members so that all necessary information is available on godocs -- Remember to update the project README.md with changes to the high-level API -- Include both positive and negative unit tests (when applicable) -- Contributions with visual ramifications or interaction changes should be accompanied with the appropriate `go-expect` tests. For more information on writing these tests, see [Writing and Running Tests](#writing-and-running-tests) +- Try to make a series of smaller changes instead of one large change +- Provide a description of each change that you are proposing +- Reference the issue addressed by your pull request (if there is one) +- Document all new exported Go APIs +- Update the project's README when applicable +- Include unit tests if possible +- Contributions with visual ramifications or interaction changes should be accompanied with an integration test—see below for details. ## Writing and running tests diff --git a/vendor/github.com/AlecAivazis/survey/v2/Gopkg.lock b/vendor/github.com/AlecAivazis/survey/v2/Gopkg.lock deleted file mode 100644 index b764f30811..0000000000 --- a/vendor/github.com/AlecAivazis/survey/v2/Gopkg.lock +++ /dev/null @@ -1,78 +0,0 @@ -# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. - - -[[projects]] - branch = "master" - name = "github.com/Netflix/go-expect" - packages = ["."] - revision = "c93bf25de8e869da25cf26bcd2932b36141f61ae" - -[[projects]] - name = "github.com/davecgh/go-spew" - packages = ["spew"] - revision = "346938d642f2ec3594ed81d874461961cd0faa76" - version = "v1.1.0" - -[[projects]] - branch = "master" - name = "github.com/hinshun/vt10x" - packages = ["."] - revision = "1954e646417484a2a687ea344edade2c2b6523c8" - -[[projects]] - branch = "master" - name = "github.com/kballard/go-shellquote" - packages = ["."] - revision = "95032a82bc518f77982ea72343cc1ade730072f0" - -[[projects]] - name = "github.com/kr/pty" - packages = ["."] - revision = "282ce0e5322c82529687d609ee670fac7c7d917c" - version = "v1.1.1" - -[[projects]] - name = "github.com/mattn/go-colorable" - packages = ["."] - revision = "167de6bfdfba052fa6b2d3664c8f5272e23c9072" - version = "v0.0.9" - -[[projects]] - name = "github.com/mattn/go-isatty" - packages = ["."] - revision = "0360b2af4f38e8d38c7fce2a9f4e702702d73a39" - version = "v0.0.3" - -[[projects]] - branch = "master" - name = "github.com/mgutz/ansi" - packages = ["."] - revision = "9520e82c474b0a04dd04f8a40959027271bab992" - -[[projects]] - name = "github.com/pmezard/go-difflib" - packages = ["difflib"] - revision = "792786c7400a136282c1664665ae0a8db921c6c2" - version = "v1.0.0" - -[[projects]] - name = "github.com/stretchr/testify" - packages = [ - "assert", - "require" - ] - revision = "12b6f73e6084dad08a7c6e575284b177ecafbc71" - version = "v1.2.1" - -[[projects]] - branch = "master" - name = "golang.org/x/sys" - packages = ["unix"] - revision = "9527bec2660bd847c050fda93a0f0c6dee0800bb" - -[solve-meta] - analyzer-name = "dep" - analyzer-version = 1 - inputs-digest = "371508ebad4798adc38a118f858b5c17a65b58594203548f9feb74cb781dd907" - solver-name = "gps-cdcl" - solver-version = 1 diff --git a/vendor/github.com/AlecAivazis/survey/v2/Gopkg.toml b/vendor/github.com/AlecAivazis/survey/v2/Gopkg.toml deleted file mode 100644 index 8acb825aac..0000000000 --- a/vendor/github.com/AlecAivazis/survey/v2/Gopkg.toml +++ /dev/null @@ -1,54 +0,0 @@ -# Gopkg.toml example -# -# Refer to https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md -# for detailed Gopkg.toml documentation. -# -# required = ["github.com/user/thing/cmd/thing"] -# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"] -# -# [[constraint]] -# name = "github.com/user/project" -# version = "1.0.0" -# -# [[constraint]] -# name = "github.com/user/project2" -# branch = "dev" -# source = "github.com/myfork/project2" -# -# [[override]] -# name = "github.com/x/y" -# version = "2.4.0" -# -# [prune] -# non-go = false -# go-tests = true -# unused-packages = true - - -[[constraint]] - branch = "master" - name = "github.com/Netflix/go-expect" - -[[constraint]] - branch = "master" - name = "github.com/hinshun/vt10x" - -[[constraint]] - name = "github.com/mattn/go-isatty" - version = "0.0.3" - -[[constraint]] - branch = "master" - name = "github.com/mgutz/ansi" - -[[constraint]] - name = "github.com/stretchr/testify" - version = "1.2.1" - -[prune] - go-tests = true - unused-packages = true - -[[constraint]] - branch = "master" - name = "github.com/kballard/go-shellquote" diff --git a/vendor/github.com/AlecAivazis/survey/v2/README.md b/vendor/github.com/AlecAivazis/survey/v2/README.md index 5ab410e30d..ac2c6fc7f9 100644 --- a/vendor/github.com/AlecAivazis/survey/v2/README.md +++ b/vendor/github.com/AlecAivazis/survey/v2/README.md @@ -1,6 +1,5 @@ # Survey -[![Build Status](https://travis-ci.org/AlecAivazis/survey.svg?branch=feature%2Fpretty)](https://travis-ci.org/AlecAivazis/survey) [![GoDoc](http://img.shields.io/badge/godoc-reference-5272B4.svg)](https://pkg.go.dev/github.com/AlecAivazis/survey/v2) A library for building interactive and accessible prompts on terminals supporting ANSI escape sequences. @@ -56,39 +55,12 @@ func main() { } ``` -## Table of Contents - -1. [Examples](#examples) -1. [Running the Prompts](#running-the-prompts) -1. [Prompts](#prompts) - 1. [Input](#input) - 1. [Suggestion Options](#suggestion-options) - 1. [Multiline](#multiline) - 1. [Password](#password) - 1. [Confirm](#confirm) - 1. [Select](#select) - 1. [MultiSelect](#multiselect) - 1. [Editor](#editor) -1. [Filtering Options](#filtering-options) -1. [Validation](#validation) - 1. [Built-in Validators](#built-in-validators) -1. [Help Text](#help-text) - 1. [Changing the input rune](#changing-the-input-rune) -1. [Changing the Icons ](#changing-the-icons) -1. [Custom Types](#custom-types) -1. [Testing](#testing) -1. [FAQ](#faq) - ## Examples Examples can be found in the `examples/` directory. Run them to see basic behavior: ```bash -go get github.com/AlecAivazis/survey/v2 - -cd $GOPATH/src/github.com/AlecAivazis/survey - go run examples/simple.go go run examples/validation.go ``` @@ -221,6 +193,28 @@ prompt := &survey.MultiSelect{..., PageSize: 10} survey.AskOne(prompt, &days, survey.WithPageSize(10)) ``` +#### Select options description + +The optional description text can be used to add extra information to each option listed in the select prompt: + +```golang +color := "" +prompt := &survey.Select{ + Message: "Choose a color:", + Options: []string{"red", "blue", "green"}, + Description: func(value string, index int) string { + if value == "red" { + return "My favorite color" + } + return "" + }, +} +survey.AskOne(prompt, &color) + +// Assuming that the user chose "red - My favorite color": +fmt.Println(color) //=> "red" +``` + ### MultiSelect ![Example](img/multi-select-all-none.gif) diff --git a/vendor/github.com/AlecAivazis/survey/v2/_tasks.hcl b/vendor/github.com/AlecAivazis/survey/v2/_tasks.hcl deleted file mode 100644 index 0eefcb5486..0000000000 --- a/vendor/github.com/AlecAivazis/survey/v2/_tasks.hcl +++ /dev/null @@ -1,19 +0,0 @@ -task "install-deps" { - description = "Install all of package dependencies" - pipeline = [ - "go get -v {{.files}}", - ] -} - -task "tests" { - description = "Run the test suite" - command = "go test -v {{.files}}" - environment = { - GOFLAGS = "-mod=vendor" - } -} - -variables = { - files = "$(go list -v ./... | grep -iEv \"tests|examples\")" -} - diff --git a/vendor/github.com/AlecAivazis/survey/v2/confirm.go b/vendor/github.com/AlecAivazis/survey/v2/confirm.go index 8e5d7efaaf..9662e6cdb7 100644 --- a/vendor/github.com/AlecAivazis/survey/v2/confirm.go +++ b/vendor/github.com/AlecAivazis/survey/v2/confirm.go @@ -49,8 +49,10 @@ func yesNo(t bool) string { func (c *Confirm) getBool(showHelp bool, config *PromptConfig) (bool, error) { cursor := c.NewCursor() rr := c.NewRuneReader() - rr.SetTermMode() - defer rr.RestoreTermMode() + _ = rr.SetTermMode() + defer func() { + _ = rr.RestoreTermMode() + }() // start waiting for input for { @@ -107,8 +109,6 @@ func (c *Confirm) getBool(showHelp bool, config *PromptConfig) (bool, error) { } return answer, nil } - // should not get here - return c.Default, nil } /* diff --git a/vendor/github.com/AlecAivazis/survey/v2/core/write.go b/vendor/github.com/AlecAivazis/survey/v2/core/write.go index dfe9b49995..94a886c361 100644 --- a/vendor/github.com/AlecAivazis/survey/v2/core/write.go +++ b/vendor/github.com/AlecAivazis/survey/v2/core/write.go @@ -178,7 +178,7 @@ func findField(s reflect.Value, name string) (reflect.Value, reflect.StructField // then look for matching names for _, f := range fields { // if the name of the field matches what we're looking for - if strings.ToLower(f.fieldType.Name) == strings.ToLower(name) { + if strings.EqualFold(f.fieldType.Name, name) { return f.value, f.fieldType, nil } } @@ -197,9 +197,7 @@ func flattenFields(s reflect.Value) []reflectField { if field.Kind() == reflect.Struct && fieldType.Anonymous { // field is a promoted structure - for _, f := range flattenFields(field) { - fields = append(fields, f) - } + fields = append(fields, flattenFields(field)...) continue } fields = append(fields, reflectField{field, fieldType}) @@ -361,7 +359,9 @@ func copy(t reflect.Value, v reflect.Value) (err error) { // otherwise it could be an array case reflect.Array: // set the index to the appropriate value - copy(t.Slice(i, i+1).Index(0), v.Index(i)) + if err := copy(t.Slice(i, i+1).Index(0), v.Index(i)); err != nil { + return err + } } } } else { diff --git a/vendor/github.com/AlecAivazis/survey/v2/editor.go b/vendor/github.com/AlecAivazis/survey/v2/editor.go index ec6a141782..20470f1195 100644 --- a/vendor/github.com/AlecAivazis/survey/v2/editor.go +++ b/vendor/github.com/AlecAivazis/survey/v2/editor.go @@ -101,8 +101,10 @@ func (e *Editor) prompt(initialValue string, config *PromptConfig) (interface{}, // start reading runes from the standard in rr := e.NewRuneReader() - rr.SetTermMode() - defer rr.RestoreTermMode() + _ = rr.SetTermMode() + defer func() { + _ = rr.RestoreTermMode() + }() cursor := e.NewCursor() cursor.Hide() @@ -147,7 +149,9 @@ func (e *Editor) prompt(initialValue string, config *PromptConfig) (interface{}, if err != nil { return "", err } - defer os.Remove(f.Name()) + defer func() { + _ = os.Remove(f.Name()) + }() // write utf8 BOM header // The reason why we do this is because notepad.exe on Windows determines the diff --git a/vendor/github.com/AlecAivazis/survey/v2/input.go b/vendor/github.com/AlecAivazis/survey/v2/input.go index a1abab1456..dbc7c08cd1 100644 --- a/vendor/github.com/AlecAivazis/survey/v2/input.go +++ b/vendor/github.com/AlecAivazis/survey/v2/input.go @@ -152,9 +152,10 @@ func (i *Input) Prompt(config *PromptConfig) (interface{}, error) { // start reading runes from the standard in rr := i.NewRuneReader() - rr.SetTermMode() - defer rr.RestoreTermMode() - + _ = rr.SetTermMode() + defer func() { + _ = rr.RestoreTermMode() + }() cursor := i.NewCursor() if !config.ShowCursor { cursor.Hide() // hide the cursor diff --git a/vendor/github.com/AlecAivazis/survey/v2/multiline.go b/vendor/github.com/AlecAivazis/survey/v2/multiline.go index d0523b7eb4..bff9622f63 100644 --- a/vendor/github.com/AlecAivazis/survey/v2/multiline.go +++ b/vendor/github.com/AlecAivazis/survey/v2/multiline.go @@ -50,8 +50,10 @@ func (i *Multiline) Prompt(config *PromptConfig) (interface{}, error) { // start reading runes from the standard in rr := i.NewRuneReader() - rr.SetTermMode() - defer rr.RestoreTermMode() + _ = rr.SetTermMode() + defer func() { + _ = rr.RestoreTermMode() + }() cursor := i.NewCursor() @@ -60,7 +62,7 @@ func (i *Multiline) Prompt(config *PromptConfig) (interface{}, error) { emptyOnce := false // get the next line for { - line := []rune{} + var line []rune line, err = rr.ReadLine(0) if err != nil { return string(line), err diff --git a/vendor/github.com/AlecAivazis/survey/v2/multiselect.go b/vendor/github.com/AlecAivazis/survey/v2/multiselect.go index 1e94f80f1c..3251ea1ccc 100644 --- a/vendor/github.com/AlecAivazis/survey/v2/multiselect.go +++ b/vendor/github.com/AlecAivazis/survey/v2/multiselect.go @@ -184,7 +184,7 @@ func (m *MultiSelect) OnChange(key rune, config *PromptConfig) { } // render the options - m.RenderWithCursorOffset(MultiSelectQuestionTemplate, tmplData, opts, idx) + _ = m.RenderWithCursorOffset(MultiSelectQuestionTemplate, tmplData, opts, idx) } func (m *MultiSelect) filterOptions(config *PromptConfig) []core.OptionAnswer { @@ -284,8 +284,10 @@ func (m *MultiSelect) Prompt(config *PromptConfig) (interface{}, error) { } rr := m.NewRuneReader() - rr.SetTermMode() - defer rr.RestoreTermMode() + _ = rr.SetTermMode() + defer func() { + _ = rr.RestoreTermMode() + }() // start waiting for input for { diff --git a/vendor/github.com/AlecAivazis/survey/v2/password.go b/vendor/github.com/AlecAivazis/survey/v2/password.go index 285bff5e75..877102c69e 100644 --- a/vendor/github.com/AlecAivazis/survey/v2/password.go +++ b/vendor/github.com/AlecAivazis/survey/v2/password.go @@ -44,14 +44,19 @@ func (p *Password) Prompt(config *PromptConfig) (interface{}, error) { Config: config, }, ) - fmt.Fprint(terminal.NewAnsiStdout(p.Stdio().Out), userOut) if err != nil { return "", err } + if _, err := fmt.Fprint(terminal.NewAnsiStdout(p.Stdio().Out), userOut); err != nil { + return "", err + } + rr := p.NewRuneReader() - rr.SetTermMode() - defer rr.RestoreTermMode() + _ = rr.SetTermMode() + defer func() { + _ = rr.RestoreTermMode() + }() // no help msg? Just return any response if p.Help == "" { @@ -61,7 +66,7 @@ func (p *Password) Prompt(config *PromptConfig) (interface{}, error) { cursor := p.NewCursor() - line := []rune{} + var line []rune // process answers looking for help prompt answer for { line, err = rr.ReadLine('*') diff --git a/vendor/github.com/AlecAivazis/survey/v2/renderer.go b/vendor/github.com/AlecAivazis/survey/v2/renderer.go index 5503d81e7e..a89b061e05 100644 --- a/vendor/github.com/AlecAivazis/survey/v2/renderer.go +++ b/vendor/github.com/AlecAivazis/survey/v2/renderer.go @@ -61,7 +61,9 @@ func (r *Renderer) Error(config *PromptConfig, invalid error) error { } // send the message to the user - fmt.Fprint(terminal.NewAnsiStdout(r.stdio.Out), userOut) + if _, err := fmt.Fprint(terminal.NewAnsiStdout(r.stdio.Out), userOut); err != nil { + return err + } // add the printed text to the rendered error buffer so we can cleanup later r.appendRenderedError(layoutOut) @@ -90,7 +92,9 @@ func (r *Renderer) Render(tmpl string, data interface{}) error { } // print the summary - fmt.Fprint(terminal.NewAnsiStdout(r.stdio.Out), userOut) + if _, err := fmt.Fprint(terminal.NewAnsiStdout(r.stdio.Out), userOut); err != nil { + return err + } // add the printed text to the rendered text buffer so we can cleanup later r.AppendRenderedText(layoutOut) @@ -165,8 +169,8 @@ func (r *Renderer) countLines(buf bytes.Buffer) int { count := 0 curr := 0 - delim := -1 for curr < len(bufBytes) { + var delim int // read until the next newline or the end of the string relDelim := bytes.IndexRune(bufBytes[curr:], '\n') if relDelim != -1 { diff --git a/vendor/github.com/AlecAivazis/survey/v2/select.go b/vendor/github.com/AlecAivazis/survey/v2/select.go index 915f34bcb3..494f15d1b9 100644 --- a/vendor/github.com/AlecAivazis/survey/v2/select.go +++ b/vendor/github.com/AlecAivazis/survey/v2/select.go @@ -28,6 +28,7 @@ type Select struct { VimMode bool FilterMessage string Filter func(filter string, value string, index int) bool + Description func(value string, index int) string filter string selectedIndex int useDefault bool @@ -42,6 +43,7 @@ type SelectTemplateData struct { Answer string ShowAnswer bool ShowHelp bool + Description func(value string, index int) string Config *PromptConfig // These fields are used when rendering an individual option @@ -57,10 +59,17 @@ func (s SelectTemplateData) IterateOption(ix int, opt core.OptionAnswer) interfa return copy } +func (s SelectTemplateData) GetDescription(opt core.OptionAnswer) string { + if s.Description == nil { + return "" + } + return s.Description(opt.Value, opt.Index) +} + var SelectQuestionTemplate = ` {{- define "option"}} {{- if eq .SelectedIndex .CurrentIndex }}{{color .Config.Icons.SelectFocus.Format }}{{ .Config.Icons.SelectFocus.Text }} {{else}}{{color "default"}} {{end}} - {{- .CurrentOpt.Value}} + {{- .CurrentOpt.Value}}{{ if ne ($.GetDescription .CurrentOpt) "" }} - {{color "cyan"}}{{ $.GetDescription .CurrentOpt }}{{end}} {{- color "reset"}} {{end}} {{- if .ShowHelp }}{{- color .Config.Icons.Help.Format }}{{ .Config.Icons.Help.Text }} {{ .Help }}{{color "reset"}}{{"\n"}}{{end}} @@ -171,12 +180,13 @@ func (s *Select) OnChange(key rune, config *PromptConfig) bool { Select: *s, SelectedIndex: idx, ShowHelp: s.showingHelp, + Description: s.Description, PageEntries: opts, Config: config, } // render the options - s.RenderWithCursorOffset(SelectQuestionTemplate, tmplData, opts, idx) + _ = s.RenderWithCursorOffset(SelectQuestionTemplate, tmplData, opts, idx) // keep prompting return false @@ -257,6 +267,7 @@ func (s *Select) Prompt(config *PromptConfig) (interface{}, error) { tmplData := SelectTemplateData{ Select: *s, SelectedIndex: idx, + Description: s.Description, ShowHelp: s.showingHelp, PageEntries: opts, Config: config, @@ -272,8 +283,10 @@ func (s *Select) Prompt(config *PromptConfig) (interface{}, error) { s.useDefault = true rr := s.NewRuneReader() - rr.SetTermMode() - defer rr.RestoreTermMode() + _ = rr.SetTermMode() + defer func() { + _ = rr.RestoreTermMode() + }() // start waiting for input for { @@ -338,10 +351,11 @@ func (s *Select) Cleanup(config *PromptConfig, val interface{}) error { return s.Render( SelectQuestionTemplate, SelectTemplateData{ - Select: *s, - Answer: val.(core.OptionAnswer).Value, - ShowAnswer: true, - Config: config, + Select: *s, + Answer: val.(core.OptionAnswer).Value, + ShowAnswer: true, + Description: s.Description, + Config: config, }, ) } diff --git a/vendor/github.com/AlecAivazis/survey/v2/survey.go b/vendor/github.com/AlecAivazis/survey/v2/survey.go index 1aae459ef3..95136ebe37 100644 --- a/vendor/github.com/AlecAivazis/survey/v2/survey.go +++ b/vendor/github.com/AlecAivazis/survey/v2/survey.go @@ -297,6 +297,20 @@ func Ask(qs []*Question, response interface{}, opts ...AskOpt) error { return errors.New("cannot call Ask() with a nil reference to record the answers") } + validate := func(q *Question, val interface{}) error { + if q.Validate != nil { + if err := q.Validate(val); err != nil { + return err + } + } + for _, v := range options.Validators { + if err := v(val); err != nil { + return err + } + } + return nil + } + // go over every question for _, q := range qs { // If Prompt implements controllable stdio, pass in specified stdio. @@ -304,46 +318,28 @@ func Ask(qs []*Question, response interface{}, opts ...AskOpt) error { p.WithStdio(options.Stdio) } - // grab the user input and save it - ans, err := q.Prompt.Prompt(&options.PromptConfig) - // if there was a problem - if err != nil { - return err - } - - // build up a list of validators that we have to apply to this question - validators := []Validator{} - - // make sure to include the question specific one - if q.Validate != nil { - validators = append(validators, q.Validate) - } - // add any "global" validators - for _, validator := range options.Validators { - validators = append(validators, validator) - } - - // apply every validator to thte response - for _, validator := range validators { - // wait for a valid response - for invalid := validator(ans); invalid != nil; invalid = validator(ans) { - err := q.Prompt.Error(&options.PromptConfig, invalid) - // if there was a problem - if err != nil { - return err - } - - // ask for more input - if promptAgainer, ok := q.Prompt.(PromptAgainer); ok { - ans, err = promptAgainer.PromptAgain(&options.PromptConfig, ans, invalid) - } else { - ans, err = q.Prompt.Prompt(&options.PromptConfig) - } - // if there was a problem - if err != nil { + var ans interface{} + var validationErr error + // prompt and validation loop + for { + if validationErr != nil { + if err := q.Prompt.Error(&options.PromptConfig, validationErr); err != nil { return err } } + var err error + if promptAgainer, ok := q.Prompt.(PromptAgainer); ok && validationErr != nil { + ans, err = promptAgainer.PromptAgain(&options.PromptConfig, ans, validationErr) + } else { + ans, err = q.Prompt.Prompt(&options.PromptConfig) + } + if err != nil { + return err + } + validationErr = validate(q, ans) + if validationErr == nil { + break + } } if q.Transform != nil { @@ -356,21 +352,14 @@ func Ask(qs []*Question, response interface{}, opts ...AskOpt) error { } // tell the prompt to cleanup with the validated value - q.Prompt.Cleanup(&options.PromptConfig, ans) - - // if something went wrong - if err != nil { - // stop listening + if err := q.Prompt.Cleanup(&options.PromptConfig, ans); err != nil { return err } // add it to the map - err = core.WriteAnswer(response, q.Name, ans) - // if something went wrong - if err != nil { + if err := core.WriteAnswer(response, q.Name, ans); err != nil { return err } - } // return the response @@ -420,7 +409,6 @@ type IterableOpts interface { func computeCursorOffset(tmpl string, data IterableOpts, opts []core.OptionAnswer, idx, tWidth int) int { tmpls, err := core.GetTemplatePair(tmpl) - if err != nil { return 0 } @@ -428,8 +416,8 @@ func computeCursorOffset(tmpl string, data IterableOpts, opts []core.OptionAnswe t := tmpls[0] renderOpt := func(ix int, opt core.OptionAnswer) string { - buf := bytes.NewBufferString("") - t.ExecuteTemplate(buf, "option", data.IterateOption(ix, opt)) + var buf bytes.Buffer + _ = t.ExecuteTemplate(&buf, "option", data.IterateOption(ix, opt)) return buf.String() } diff --git a/vendor/github.com/AlecAivazis/survey/v2/terminal/cursor.go b/vendor/github.com/AlecAivazis/survey/v2/terminal/cursor.go index 1ac74fd6f5..75117e0806 100644 --- a/vendor/github.com/AlecAivazis/survey/v2/terminal/cursor.go +++ b/vendor/github.com/AlecAivazis/survey/v2/terminal/cursor.go @@ -1,3 +1,4 @@ +//go:build !windows // +build !windows package terminal @@ -21,81 +22,99 @@ type Cursor struct { } // Up moves the cursor n cells to up. -func (c *Cursor) Up(n int) { - fmt.Fprintf(c.Out, "\x1b[%dA", n) +func (c *Cursor) Up(n int) error { + _, err := fmt.Fprintf(c.Out, "\x1b[%dA", n) + return err } // Down moves the cursor n cells to down. -func (c *Cursor) Down(n int) { - fmt.Fprintf(c.Out, "\x1b[%dB", n) +func (c *Cursor) Down(n int) error { + _, err := fmt.Fprintf(c.Out, "\x1b[%dB", n) + return err } // Forward moves the cursor n cells to right. -func (c *Cursor) Forward(n int) { - fmt.Fprintf(c.Out, "\x1b[%dC", n) +func (c *Cursor) Forward(n int) error { + _, err := fmt.Fprintf(c.Out, "\x1b[%dC", n) + return err } // Back moves the cursor n cells to left. -func (c *Cursor) Back(n int) { - fmt.Fprintf(c.Out, "\x1b[%dD", n) +func (c *Cursor) Back(n int) error { + _, err := fmt.Fprintf(c.Out, "\x1b[%dD", n) + return err } // NextLine moves cursor to beginning of the line n lines down. -func (c *Cursor) NextLine(n int) { - c.Down(1) - c.HorizontalAbsolute(0) +func (c *Cursor) NextLine(n int) error { + if err := c.Down(1); err != nil { + return err + } + return c.HorizontalAbsolute(0) } // PreviousLine moves cursor to beginning of the line n lines up. -func (c *Cursor) PreviousLine(n int) { - c.Up(1) - c.HorizontalAbsolute(0) +func (c *Cursor) PreviousLine(n int) error { + if err := c.Up(1); err != nil { + return err + } + return c.HorizontalAbsolute(0) } // HorizontalAbsolute moves cursor horizontally to x. -func (c *Cursor) HorizontalAbsolute(x int) { - fmt.Fprintf(c.Out, "\x1b[%dG", x) +func (c *Cursor) HorizontalAbsolute(x int) error { + _, err := fmt.Fprintf(c.Out, "\x1b[%dG", x) + return err } // Show shows the cursor. -func (c *Cursor) Show() { - fmt.Fprint(c.Out, "\x1b[?25h") +func (c *Cursor) Show() error { + _, err := fmt.Fprint(c.Out, "\x1b[?25h") + return err } // Hide hide the cursor. -func (c *Cursor) Hide() { - fmt.Fprint(c.Out, "\x1b[?25l") +func (c *Cursor) Hide() error { + _, err := fmt.Fprint(c.Out, "\x1b[?25l") + return err } -// Move moves the cursor to a specific x,y location. -func (c *Cursor) Move(x int, y int) { - fmt.Fprintf(c.Out, "\x1b[%d;%df", x, y) +// move moves the cursor to a specific x,y location. +func (c *Cursor) move(x int, y int) error { + _, err := fmt.Fprintf(c.Out, "\x1b[%d;%df", x, y) + return err } // Save saves the current position -func (c *Cursor) Save() { - fmt.Fprint(c.Out, "\x1b7") +func (c *Cursor) Save() error { + _, err := fmt.Fprint(c.Out, "\x1b7") + return err } // Restore restores the saved position of the cursor -func (c *Cursor) Restore() { - fmt.Fprint(c.Out, "\x1b8") +func (c *Cursor) Restore() error { + _, err := fmt.Fprint(c.Out, "\x1b8") + return err } // for comparability purposes between windows // in unix we need to print out a new line on some terminals -func (c *Cursor) MoveNextLine(cur *Coord, terminalSize *Coord) { +func (c *Cursor) MoveNextLine(cur *Coord, terminalSize *Coord) error { if cur.Y == terminalSize.Y { - fmt.Fprintln(c.Out) + if _, err := fmt.Fprintln(c.Out); err != nil { + return err + } } - c.NextLine(1) + return c.NextLine(1) } // Location returns the current location of the cursor in the terminal func (c *Cursor) Location(buf *bytes.Buffer) (*Coord, error) { // ANSI escape sequence for DSR - Device Status Report // https://en.wikipedia.org/wiki/ANSI_escape_code#CSI_sequences - fmt.Fprint(c.Out, "\x1b[6n") + if _, err := fmt.Fprint(c.Out, "\x1b[6n"); err != nil { + return nil, err + } // There may be input in Stdin prior to CursorLocation so make sure we don't // drop those bytes. @@ -176,7 +195,7 @@ func (c *Cursor) Size(buf *bytes.Buffer) (*Coord, error) { defer c.Restore() // move the cursor to the very bottom of the terminal - c.Move(999, 999) + c.move(999, 999) // ask for the current location bottom, err := c.Location(buf) diff --git a/vendor/github.com/AlecAivazis/survey/v2/terminal/cursor_windows.go b/vendor/github.com/AlecAivazis/survey/v2/terminal/cursor_windows.go index e24440e7c5..c264591995 100644 --- a/vendor/github.com/AlecAivazis/survey/v2/terminal/cursor_windows.go +++ b/vendor/github.com/AlecAivazis/survey/v2/terminal/cursor_windows.go @@ -16,31 +16,37 @@ type Cursor struct { Out FileWriter } -func (c *Cursor) Up(n int) { - c.cursorMove(0, n) +func (c *Cursor) Up(n int) error { + return c.cursorMove(0, n) } -func (c *Cursor) Down(n int) { - c.cursorMove(0, -1*n) +func (c *Cursor) Down(n int) error { + return c.cursorMove(0, -1*n) } -func (c *Cursor) Forward(n int) { - c.cursorMove(n, 0) +func (c *Cursor) Forward(n int) error { + return c.cursorMove(n, 0) } -func (c *Cursor) Back(n int) { - c.cursorMove(-1*n, 0) +func (c *Cursor) Back(n int) error { + return c.cursorMove(-1*n, 0) } // save the cursor location -func (c *Cursor) Save() { - cursorLoc, _ = c.Location(nil) +func (c *Cursor) Save() error { + loc, err := c.Location(nil) + if err != nil { + return err + } + cursorLoc = *loc + return nil } -func (c *Cursor) Restore() { +func (c *Cursor) Restore() error { handle := syscall.Handle(c.Out.Fd()) // restore it to the original position - procSetConsoleCursorPosition.Call(uintptr(handle), uintptr(*(*int32)(unsafe.Pointer(&cursorLoc)))) + _, _, err := procSetConsoleCursorPosition.Call(uintptr(handle), uintptr(*(*int32)(unsafe.Pointer(&cursorLoc)))) + return normalizeError(err) } func (cur Coord) CursorIsAtLineEnd(size *Coord) bool { @@ -51,40 +57,49 @@ func (cur Coord) CursorIsAtLineBegin() bool { return cur.X == 0 } -func (c *Cursor) cursorMove(x int, y int) { +func (c *Cursor) cursorMove(x int, y int) error { handle := syscall.Handle(c.Out.Fd()) var csbi consoleScreenBufferInfo - procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi))) + if _, _, err := procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi))); normalizeError(err) != nil { + return err + } var cursor Coord cursor.X = csbi.cursorPosition.X + Short(x) cursor.Y = csbi.cursorPosition.Y + Short(y) - procSetConsoleCursorPosition.Call(uintptr(handle), uintptr(*(*int32)(unsafe.Pointer(&cursor)))) + _, _, err := procSetConsoleCursorPosition.Call(uintptr(handle), uintptr(*(*int32)(unsafe.Pointer(&cursor)))) + return normalizeError(err) } -func (c *Cursor) NextLine(n int) { - c.Up(n) - c.HorizontalAbsolute(0) +func (c *Cursor) NextLine(n int) error { + if err := c.Up(n); err != nil { + return err + } + return c.HorizontalAbsolute(0) } -func (c *Cursor) PreviousLine(n int) { - c.Down(n) - c.HorizontalAbsolute(0) +func (c *Cursor) PreviousLine(n int) error { + if err := c.Down(n); err != nil { + return err + } + return c.HorizontalAbsolute(0) } // for comparability purposes between windows // in windows we don't have to print out a new line -func (c *Cursor) MoveNextLine(cur Coord, terminalSize *Coord) { - c.NextLine(1) +func (c *Cursor) MoveNextLine(cur *Coord, terminalSize *Coord) error { + return c.NextLine(1) } -func (c *Cursor) HorizontalAbsolute(x int) { +func (c *Cursor) HorizontalAbsolute(x int) error { handle := syscall.Handle(c.Out.Fd()) var csbi consoleScreenBufferInfo - procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi))) + if _, _, err := procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi))); normalizeError(err) != nil { + return err + } var cursor Coord cursor.X = Short(x) @@ -94,43 +109,54 @@ func (c *Cursor) HorizontalAbsolute(x int) { cursor.X = csbi.size.X } - procSetConsoleCursorPosition.Call(uintptr(handle), uintptr(*(*int32)(unsafe.Pointer(&cursor)))) + _, _, err := procSetConsoleCursorPosition.Call(uintptr(handle), uintptr(*(*int32)(unsafe.Pointer(&cursor)))) + return normalizeError(err) } -func (c *Cursor) Show() { +func (c *Cursor) Show() error { handle := syscall.Handle(c.Out.Fd()) var cci consoleCursorInfo - procGetConsoleCursorInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&cci))) + if _, _, err := procGetConsoleCursorInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&cci))); normalizeError(err) != nil { + return err + } cci.visible = 1 - procSetConsoleCursorInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&cci))) + _, _, err := procSetConsoleCursorInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&cci))) + return normalizeError(err) } -func (c *Cursor) Hide() { +func (c *Cursor) Hide() error { handle := syscall.Handle(c.Out.Fd()) var cci consoleCursorInfo - procGetConsoleCursorInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&cci))) + if _, _, err := procGetConsoleCursorInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&cci))); normalizeError(err) != nil { + return err + } cci.visible = 0 - procSetConsoleCursorInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&cci))) + _, _, err := procSetConsoleCursorInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&cci))) + return normalizeError(err) } -func (c *Cursor) Location(buf *bytes.Buffer) (Coord, error) { +func (c *Cursor) Location(buf *bytes.Buffer) (*Coord, error) { handle := syscall.Handle(c.Out.Fd()) var csbi consoleScreenBufferInfo - procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi))) + if _, _, err := procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi))); normalizeError(err) != nil { + return nil, err + } - return csbi.cursorPosition, nil + return &csbi.cursorPosition, nil } func (c *Cursor) Size(buf *bytes.Buffer) (*Coord, error) { handle := syscall.Handle(c.Out.Fd()) var csbi consoleScreenBufferInfo - procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi))) + if _, _, err := procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi))); normalizeError(err) != nil { + return nil, err + } // windows' coordinate system begins at (0, 0) csbi.size.X-- csbi.size.Y-- diff --git a/vendor/github.com/AlecAivazis/survey/v2/terminal/display_posix.go b/vendor/github.com/AlecAivazis/survey/v2/terminal/display_posix.go index 838dd6646e..4660808751 100644 --- a/vendor/github.com/AlecAivazis/survey/v2/terminal/display_posix.go +++ b/vendor/github.com/AlecAivazis/survey/v2/terminal/display_posix.go @@ -6,6 +6,7 @@ import ( "fmt" ) -func EraseLine(out FileWriter, mode EraseLineMode) { - fmt.Fprintf(out, "\x1b[%dK", mode) +func EraseLine(out FileWriter, mode EraseLineMode) error { + _, err := fmt.Fprintf(out, "\x1b[%dK", mode) + return err } diff --git a/vendor/github.com/AlecAivazis/survey/v2/terminal/display_windows.go b/vendor/github.com/AlecAivazis/survey/v2/terminal/display_windows.go index 0adc1ded38..fc9db9f74d 100644 --- a/vendor/github.com/AlecAivazis/survey/v2/terminal/display_windows.go +++ b/vendor/github.com/AlecAivazis/survey/v2/terminal/display_windows.go @@ -5,11 +5,13 @@ import ( "unsafe" ) -func EraseLine(out FileWriter, mode EraseLineMode) { +func EraseLine(out FileWriter, mode EraseLineMode) error { handle := syscall.Handle(out.Fd()) var csbi consoleScreenBufferInfo - procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi))) + if _, _, err := procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi))); normalizeError(err) != nil { + return err + } var w uint32 var x Short @@ -23,5 +25,7 @@ func EraseLine(out FileWriter, mode EraseLineMode) { cursor.X = 0 x = csbi.size.X } - procFillConsoleOutputCharacter.Call(uintptr(handle), uintptr(' '), uintptr(x), uintptr(*(*int32)(unsafe.Pointer(&cursor))), uintptr(unsafe.Pointer(&w))) + + _, _, err := procFillConsoleOutputCharacter.Call(uintptr(handle), uintptr(' '), uintptr(x), uintptr(*(*int32)(unsafe.Pointer(&cursor))), uintptr(unsafe.Pointer(&w))) + return normalizeError(err) } diff --git a/vendor/github.com/AlecAivazis/survey/v2/terminal/output_windows.go b/vendor/github.com/AlecAivazis/survey/v2/terminal/output_windows.go index 6622690f32..eaf5c4341f 100644 --- a/vendor/github.com/AlecAivazis/survey/v2/terminal/output_windows.go +++ b/vendor/github.com/AlecAivazis/survey/v2/terminal/output_windows.go @@ -12,18 +12,6 @@ import ( "github.com/mattn/go-isatty" ) -var ( - cursorFunctions = map[rune]func(c *Cursor) func(int){ - 'A': func(c *Cursor) func(int) { return c.Up }, - 'B': func(c *Cursor) func(int) { return c.Down }, - 'C': func(c *Cursor) func(int) { return c.Forward }, - 'D': func(c *Cursor) func(int) { return c.Back }, - 'E': func(c *Cursor) func(int) { return c.NextLine }, - 'F': func(c *Cursor) func(int) { return c.PreviousLine }, - 'G': func(c *Cursor) func(int) { return c.HorizontalAbsolute }, - } -) - const ( foregroundBlue = 0x1 foregroundGreen = 0x2 @@ -67,9 +55,14 @@ func (w *Writer) Write(data []byte) (n int, err error) { r := bytes.NewReader(data) for { - ch, size, err := r.ReadRune() + var ch rune + var size int + ch, size, err = r.ReadRune() if err != nil { - break + if err == io.EOF { + err = nil + } + return } n += size @@ -78,22 +71,29 @@ func (w *Writer) Write(data []byte) (n int, err error) { size, err = w.handleEscape(r) n += size if err != nil { - break + return } default: - fmt.Fprint(w.out, string(ch)) + _, err = fmt.Fprint(w.out, string(ch)) + if err != nil { + return + } } } - return } func (w *Writer) handleEscape(r *bytes.Reader) (n int, err error) { buf := make([]byte, 0, 10) buf = append(buf, "\x1b"...) + var ch rune + var size int // Check '[' continues after \x1b - ch, size, err := r.ReadRune() + ch, size, err = r.ReadRune() if err != nil { + if err == io.EOF { + err = nil + } fmt.Fprint(w.out, string(buf)) return } @@ -109,6 +109,9 @@ func (w *Writer) handleEscape(r *bytes.Reader) (n int, err error) { for { ch, size, err = r.ReadRune() if err != nil { + if err == io.EOF { + err = nil + } fmt.Fprint(w.out, string(buf)) return } @@ -120,47 +123,62 @@ func (w *Writer) handleEscape(r *bytes.Reader) (n int, err error) { argBuf = append(argBuf, string(ch)...) } - w.applyEscapeCode(buf, string(argBuf), code) + err = w.applyEscapeCode(buf, string(argBuf), code) return } -func (w *Writer) applyEscapeCode(buf []byte, arg string, code rune) { +func (w *Writer) applyEscapeCode(buf []byte, arg string, code rune) error { c := &Cursor{Out: w.out} switch arg + string(code) { case "?25h": - c.Show() - return + return c.Show() case "?25l": - c.Hide() - return + return c.Hide() } - if f, ok := cursorFunctions[code]; ok { + if code >= 'A' && code <= 'G' { if n, err := strconv.Atoi(arg); err == nil { - f(c)(n) - return + switch code { + case 'A': + return c.Up(n) + case 'B': + return c.Down(n) + case 'C': + return c.Forward(n) + case 'D': + return c.Back(n) + case 'E': + return c.NextLine(n) + case 'F': + return c.PreviousLine(n) + case 'G': + return c.HorizontalAbsolute(n) + } } } switch code { case 'm': - w.applySelectGraphicRendition(arg) + return w.applySelectGraphicRendition(arg) default: buf = append(buf, string(code)...) - fmt.Fprint(w.out, string(buf)) + _, err := fmt.Fprint(w.out, string(buf)) + return err } } // Original implementation: https://github.com/mattn/go-colorable -func (w *Writer) applySelectGraphicRendition(arg string) { +func (w *Writer) applySelectGraphicRendition(arg string) error { if arg == "" { - procSetConsoleTextAttribute.Call(uintptr(w.handle), uintptr(w.orgAttr)) - return + _, _, err := procSetConsoleTextAttribute.Call(uintptr(w.handle), uintptr(w.orgAttr)) + return normalizeError(err) } var csbi consoleScreenBufferInfo - procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) + if _, _, err := procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))); normalizeError(err) != nil { + return err + } attr := csbi.attributes for _, param := range strings.Split(arg, ";") { @@ -223,5 +241,13 @@ func (w *Writer) applySelectGraphicRendition(arg string) { } } - procSetConsoleTextAttribute.Call(uintptr(w.handle), uintptr(attr)) + _, _, err := procSetConsoleTextAttribute.Call(uintptr(w.handle), uintptr(attr)) + return normalizeError(err) +} + +func normalizeError(err error) error { + if syserr, ok := err.(syscall.Errno); ok && syserr == 0 { + return nil + } + return err } diff --git a/vendor/github.com/AlecAivazis/survey/v2/terminal/runereader.go b/vendor/github.com/AlecAivazis/survey/v2/terminal/runereader.go index 94c915c5de..e881d7532c 100644 --- a/vendor/github.com/AlecAivazis/survey/v2/terminal/runereader.go +++ b/vendor/github.com/AlecAivazis/survey/v2/terminal/runereader.go @@ -8,9 +8,8 @@ import ( ) type RuneReader struct { - stdio Stdio - cursor *Cursor - state runeReaderState + stdio Stdio + state runeReaderState } func NewRuneReader(stdio Stdio) *RuneReader { @@ -20,15 +19,16 @@ func NewRuneReader(stdio Stdio) *RuneReader { } } -func (rr *RuneReader) printChar(char rune, mask rune) { +func (rr *RuneReader) printChar(char rune, mask rune) error { // if we don't need to mask the input if mask == 0 { // just print the character the user pressed - fmt.Fprintf(rr.stdio.Out, "%c", char) - } else { - // otherwise print the mask we were given - fmt.Fprintf(rr.stdio.Out, "%c", mask) + _, err := fmt.Fprintf(rr.stdio.Out, "%c", char) + return err } + // otherwise print the mask we were given + _, err := fmt.Fprintf(rr.stdio.Out, "%c", mask) + return err } type OnRuneFn func(rune, []rune) ([]rune, bool, error) @@ -80,7 +80,9 @@ func (rr *RuneReader) ReadLineWithDefault(mask rune, d []rune, onRunes ...OnRune if len(d) > 0 { index = len(d) - fmt.Fprint(rr.stdio.Out, string(d)) + if _, err := fmt.Fprint(rr.stdio.Out, string(d)); err != nil { + return d, err + } line = d for range d { increment() @@ -121,7 +123,9 @@ func (rr *RuneReader) ReadLineWithDefault(mask rune, d []rune, onRunes ...OnRune // if the user interrupts (ie with ctrl+c) if r == KeyInterrupt { // go to the beginning of the next line - fmt.Fprint(rr.stdio.Out, "\r\n") + if _, err := fmt.Fprint(rr.stdio.Out, "\r\n"); err != nil { + return line, err + } // we're done processing the input, and treat interrupt like an error return line, InterruptErr @@ -168,8 +172,9 @@ func (rr *RuneReader) ReadLineWithDefault(mask rune, d []rune, onRunes ...OnRune //Erase symbols which are left over from older print EraseLine(rr.stdio.Out, ERASE_LINE_END) // print characters to the new line appropriately - rr.printChar(char, mask) - + if err := rr.printChar(char, mask); err != nil { + return line, err + } } // erase what's left over from last print if cursorCurrent.Y < terminalSize.Y { @@ -191,7 +196,7 @@ func (rr *RuneReader) ReadLineWithDefault(mask rune, d []rune, onRunes ...OnRune decrement() } else { // otherwise the user pressed backspace while at the beginning of the line - soundBell(rr.stdio.Out) + _ = soundBell(rr.stdio.Out) } // we're done processing this key @@ -216,7 +221,7 @@ func (rr *RuneReader) ReadLineWithDefault(mask rune, d []rune, onRunes ...OnRune } else { // otherwise we are at the beginning of where we started reading lines // sound the bell - soundBell(rr.stdio.Out) + _ = soundBell(rr.stdio.Out) } // we're done processing this key press @@ -239,7 +244,7 @@ func (rr *RuneReader) ReadLineWithDefault(mask rune, d []rune, onRunes ...OnRune } else { // otherwise we are at the end of the word and can't go past // sound the bell - soundBell(rr.stdio.Out) + _ = soundBell(rr.stdio.Out) } // we're done processing this key press @@ -288,7 +293,9 @@ func (rr *RuneReader) ReadLineWithDefault(mask rune, d []rune, onRunes ...OnRune for _, char := range line[index:] { EraseLine(rr.stdio.Out, ERASE_LINE_END) // print out the character - rr.printChar(char, mask) + if err := rr.printChar(char, mask); err != nil { + return line, err + } } // erase what's left on last line if cursorCurrent.Y < terminalSize.Y { @@ -320,7 +327,9 @@ func (rr *RuneReader) ReadLineWithDefault(mask rune, d []rune, onRunes ...OnRune index++ increment() // print out the character - rr.printChar(r, mask) + if err := rr.printChar(r, mask); err != nil { + return line, err + } } else { // we are in the middle of the word so we need to insert the character the user pressed line = append(line[:index], append([]rune{r}, line[index:]...)...) @@ -334,13 +343,17 @@ func (rr *RuneReader) ReadLineWithDefault(mask rune, d []rune, onRunes ...OnRune for _, char := range line[index:] { EraseLine(rr.stdio.Out, ERASE_LINE_END) // print out the character - rr.printChar(char, mask) + if err := rr.printChar(char, mask); err != nil { + return line, err + } increment() } // if we are at the last line, we want to visually insert a new line and append to it. if cursorCurrent.CursorIsAtLineEnd(terminalSize) && cursorCurrent.Y == terminalSize.Y { // add a new line to the terminal - fmt.Fprintln(rr.stdio.Out) + if _, err := fmt.Fprintln(rr.stdio.Out); err != nil { + return line, err + } // restore the position of the cursor horizontally cursor.Restore() // restore the position of the cursor vertically diff --git a/vendor/github.com/AlecAivazis/survey/v2/terminal/runereader_posix.go b/vendor/github.com/AlecAivazis/survey/v2/terminal/runereader_posix.go index 99cbf4345b..3b8460497a 100644 --- a/vendor/github.com/AlecAivazis/survey/v2/terminal/runereader_posix.go +++ b/vendor/github.com/AlecAivazis/survey/v2/terminal/runereader_posix.go @@ -50,6 +50,11 @@ func (rr *RuneReader) SetTermMode() error { newState := rr.state.term newState.Lflag &^= syscall.ECHO | syscall.ECHONL | syscall.ICANON | syscall.ISIG + // Because we are clearing canonical mode, we need to ensure VMIN & VTIME are + // set to the values we expect. This combination puts things in standard + // "blocking read" mode (see termios(3)). + newState.Cc[syscall.VMIN] = 1 + newState.Cc[syscall.VTIME] = 0 if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(rr.stdio.In.Fd()), ioctlWriteTermios, uintptr(unsafe.Pointer(&newState)), 0, 0, 0); err != 0 { return err diff --git a/vendor/github.com/AlecAivazis/survey/v2/terminal/sequences.go b/vendor/github.com/AlecAivazis/survey/v2/terminal/sequences.go index 6d9e87755b..5f61e2b65e 100644 --- a/vendor/github.com/AlecAivazis/survey/v2/terminal/sequences.go +++ b/vendor/github.com/AlecAivazis/survey/v2/terminal/sequences.go @@ -26,6 +26,7 @@ const ( KeyTab = '\t' ) -func soundBell(out io.Writer) { - fmt.Fprint(out, "\a") +func soundBell(out io.Writer) error { + _, err := fmt.Fprint(out, "\a") + return err } diff --git a/vendor/github.com/AlecAivazis/survey/v2/validate.go b/vendor/github.com/AlecAivazis/survey/v2/validate.go index 462dc5e75c..f196148433 100644 --- a/vendor/github.com/AlecAivazis/survey/v2/validate.go +++ b/vendor/github.com/AlecAivazis/survey/v2/validate.go @@ -87,7 +87,7 @@ func MinItems(numberItems int) Validator { // if the list is shorter than the given value if len(list) < numberItems { // yell loudly - return fmt.Errorf("value is too long. Min items is %v", numberItems) + return fmt.Errorf("value is too short. Min items is %v", numberItems) } } else { // otherwise we cannot convert the value into a list of answer and cannot enforce length diff --git a/vendor/github.com/Netflix/go-expect/.travis.yml b/vendor/github.com/Netflix/go-expect/.travis.yml index 5f7b63a68c..5d6c8fefd2 100644 --- a/vendor/github.com/Netflix/go-expect/.travis.yml +++ b/vendor/github.com/Netflix/go-expect/.travis.yml @@ -5,5 +5,6 @@ os: - osx go: - - "1.10.2" + - "1.13.15" + - "1.14.10" - master diff --git a/vendor/github.com/Netflix/go-expect/Gopkg.lock b/vendor/github.com/Netflix/go-expect/Gopkg.lock deleted file mode 100644 index 40e8df1107..0000000000 --- a/vendor/github.com/Netflix/go-expect/Gopkg.lock +++ /dev/null @@ -1,15 +0,0 @@ -# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. - - -[[projects]] - name = "github.com/kr/pty" - packages = ["."] - revision = "282ce0e5322c82529687d609ee670fac7c7d917c" - version = "v1.1.1" - -[solve-meta] - analyzer-name = "dep" - analyzer-version = 1 - inputs-digest = "ef150ea4826ef379630452277fe5e4539161827fcf6176f9b693f68a4b9c89de" - solver-name = "gps-cdcl" - solver-version = 1 diff --git a/vendor/github.com/Netflix/go-expect/Gopkg.toml b/vendor/github.com/Netflix/go-expect/Gopkg.toml deleted file mode 100644 index b88aab354e..0000000000 --- a/vendor/github.com/Netflix/go-expect/Gopkg.toml +++ /dev/null @@ -1,34 +0,0 @@ -# Gopkg.toml example -# -# Refer to https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md -# for detailed Gopkg.toml documentation. -# -# required = ["github.com/user/thing/cmd/thing"] -# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"] -# -# [[constraint]] -# name = "github.com/user/project" -# version = "1.0.0" -# -# [[constraint]] -# name = "github.com/user/project2" -# branch = "dev" -# source = "github.com/myfork/project2" -# -# [[override]] -# name = "github.com/x/y" -# version = "2.4.0" -# -# [prune] -# non-go = false -# go-tests = true -# unused-packages = true - - -[[constraint]] - name = "github.com/kr/pty" - version = "1.1.1" - -[prune] - go-tests = true - unused-packages = true diff --git a/vendor/github.com/Netflix/go-expect/README.md b/vendor/github.com/Netflix/go-expect/README.md index 7a33316a32..ccd807e0d5 100644 --- a/vendor/github.com/Netflix/go-expect/README.md +++ b/vendor/github.com/Netflix/go-expect/README.md @@ -1,6 +1,7 @@ # go-expect -[![Build Status](https://travis-ci.org/Netflix/go-expect.svg?branch=master)](https://travis-ci.org/Netflix/go-expect) +![Go](https://github.com/Netflix/go-expect/workflows/Go/badge.svg) +[![Build Status](https://travis-ci.com/Netflix/go-expect.svg?branch=master)](https://travis-ci.com/Netflix/go-expect) [![GoDoc](https://godoc.org/github.com/Netflix/go-expect?status.svg)](https://godoc.org/github.com/Netflix/go-expect) [![NetflixOSS Lifecycle](https://img.shields.io/osslifecycle/Netflix/go-expect.svg)]() @@ -59,7 +60,7 @@ func main() { ### `golang.org/x/crypto/ssh/terminal` example -``` +```go package main import ( diff --git a/vendor/github.com/Netflix/go-expect/console.go b/vendor/github.com/Netflix/go-expect/console.go index 35c97dcdb9..26deeadc0d 100644 --- a/vendor/github.com/Netflix/go-expect/console.go +++ b/vendor/github.com/Netflix/go-expect/console.go @@ -24,7 +24,7 @@ import ( "time" "unicode/utf8" - "github.com/kr/pty" + "github.com/creack/pty" ) // Console is an interface to automate input and output for interactive @@ -155,7 +155,7 @@ func NewConsole(opts ...ConsoleOpt) (*Console, error) { if err != nil { return nil, err } - closers = append(options.Closers, passthroughPipe) + closers = append(closers, passthroughPipe) c := &Console{ opts: options, diff --git a/vendor/github.com/kr/pty/.gitignore b/vendor/github.com/creack/pty/.gitignore similarity index 100% rename from vendor/github.com/kr/pty/.gitignore rename to vendor/github.com/creack/pty/.gitignore diff --git a/vendor/github.com/kr/pty/Dockerfile.golang b/vendor/github.com/creack/pty/Dockerfile.golang similarity index 100% rename from vendor/github.com/kr/pty/Dockerfile.golang rename to vendor/github.com/creack/pty/Dockerfile.golang diff --git a/vendor/github.com/kr/pty/Dockerfile.riscv b/vendor/github.com/creack/pty/Dockerfile.riscv similarity index 100% rename from vendor/github.com/kr/pty/Dockerfile.riscv rename to vendor/github.com/creack/pty/Dockerfile.riscv diff --git a/vendor/github.com/kr/pty/LICENSE b/vendor/github.com/creack/pty/LICENSE similarity index 100% rename from vendor/github.com/kr/pty/LICENSE rename to vendor/github.com/creack/pty/LICENSE diff --git a/vendor/github.com/kr/pty/README.md b/vendor/github.com/creack/pty/README.md similarity index 100% rename from vendor/github.com/kr/pty/README.md rename to vendor/github.com/creack/pty/README.md diff --git a/vendor/github.com/kr/pty/asm_solaris_amd64.s b/vendor/github.com/creack/pty/asm_solaris_amd64.s similarity index 100% rename from vendor/github.com/kr/pty/asm_solaris_amd64.s rename to vendor/github.com/creack/pty/asm_solaris_amd64.s diff --git a/vendor/github.com/kr/pty/doc.go b/vendor/github.com/creack/pty/doc.go similarity index 100% rename from vendor/github.com/kr/pty/doc.go rename to vendor/github.com/creack/pty/doc.go diff --git a/vendor/github.com/kr/pty/ioctl.go b/vendor/github.com/creack/pty/ioctl.go similarity index 100% rename from vendor/github.com/kr/pty/ioctl.go rename to vendor/github.com/creack/pty/ioctl.go diff --git a/vendor/github.com/kr/pty/ioctl_bsd.go b/vendor/github.com/creack/pty/ioctl_bsd.go similarity index 100% rename from vendor/github.com/kr/pty/ioctl_bsd.go rename to vendor/github.com/creack/pty/ioctl_bsd.go diff --git a/vendor/github.com/kr/pty/ioctl_solaris.go b/vendor/github.com/creack/pty/ioctl_solaris.go similarity index 100% rename from vendor/github.com/kr/pty/ioctl_solaris.go rename to vendor/github.com/creack/pty/ioctl_solaris.go diff --git a/vendor/github.com/kr/pty/mktypes.bash b/vendor/github.com/creack/pty/mktypes.bash similarity index 100% rename from vendor/github.com/kr/pty/mktypes.bash rename to vendor/github.com/creack/pty/mktypes.bash diff --git a/vendor/github.com/kr/pty/pty_darwin.go b/vendor/github.com/creack/pty/pty_darwin.go similarity index 100% rename from vendor/github.com/kr/pty/pty_darwin.go rename to vendor/github.com/creack/pty/pty_darwin.go diff --git a/vendor/github.com/kr/pty/pty_dragonfly.go b/vendor/github.com/creack/pty/pty_dragonfly.go similarity index 100% rename from vendor/github.com/kr/pty/pty_dragonfly.go rename to vendor/github.com/creack/pty/pty_dragonfly.go diff --git a/vendor/github.com/kr/pty/pty_freebsd.go b/vendor/github.com/creack/pty/pty_freebsd.go similarity index 100% rename from vendor/github.com/kr/pty/pty_freebsd.go rename to vendor/github.com/creack/pty/pty_freebsd.go diff --git a/vendor/github.com/kr/pty/pty_linux.go b/vendor/github.com/creack/pty/pty_linux.go similarity index 100% rename from vendor/github.com/kr/pty/pty_linux.go rename to vendor/github.com/creack/pty/pty_linux.go diff --git a/vendor/github.com/kr/pty/pty_netbsd.go b/vendor/github.com/creack/pty/pty_netbsd.go similarity index 100% rename from vendor/github.com/kr/pty/pty_netbsd.go rename to vendor/github.com/creack/pty/pty_netbsd.go diff --git a/vendor/github.com/kr/pty/pty_openbsd.go b/vendor/github.com/creack/pty/pty_openbsd.go similarity index 100% rename from vendor/github.com/kr/pty/pty_openbsd.go rename to vendor/github.com/creack/pty/pty_openbsd.go diff --git a/vendor/github.com/kr/pty/pty_solaris.go b/vendor/github.com/creack/pty/pty_solaris.go similarity index 100% rename from vendor/github.com/kr/pty/pty_solaris.go rename to vendor/github.com/creack/pty/pty_solaris.go diff --git a/vendor/github.com/kr/pty/pty_unsupported.go b/vendor/github.com/creack/pty/pty_unsupported.go similarity index 100% rename from vendor/github.com/kr/pty/pty_unsupported.go rename to vendor/github.com/creack/pty/pty_unsupported.go diff --git a/vendor/github.com/kr/pty/run.go b/vendor/github.com/creack/pty/run.go similarity index 100% rename from vendor/github.com/kr/pty/run.go rename to vendor/github.com/creack/pty/run.go diff --git a/vendor/github.com/kr/pty/test_crosscompile.sh b/vendor/github.com/creack/pty/test_crosscompile.sh similarity index 100% rename from vendor/github.com/kr/pty/test_crosscompile.sh rename to vendor/github.com/creack/pty/test_crosscompile.sh diff --git a/vendor/github.com/kr/pty/winsize.go b/vendor/github.com/creack/pty/winsize.go similarity index 100% rename from vendor/github.com/kr/pty/winsize.go rename to vendor/github.com/creack/pty/winsize.go diff --git a/vendor/github.com/kr/pty/winsize_unix.go b/vendor/github.com/creack/pty/winsize_unix.go similarity index 100% rename from vendor/github.com/kr/pty/winsize_unix.go rename to vendor/github.com/creack/pty/winsize_unix.go diff --git a/vendor/github.com/kr/pty/winsize_unsupported.go b/vendor/github.com/creack/pty/winsize_unsupported.go similarity index 100% rename from vendor/github.com/kr/pty/winsize_unsupported.go rename to vendor/github.com/creack/pty/winsize_unsupported.go diff --git a/vendor/github.com/kr/pty/ztypes_386.go b/vendor/github.com/creack/pty/ztypes_386.go similarity index 100% rename from vendor/github.com/kr/pty/ztypes_386.go rename to vendor/github.com/creack/pty/ztypes_386.go diff --git a/vendor/github.com/kr/pty/ztypes_amd64.go b/vendor/github.com/creack/pty/ztypes_amd64.go similarity index 100% rename from vendor/github.com/kr/pty/ztypes_amd64.go rename to vendor/github.com/creack/pty/ztypes_amd64.go diff --git a/vendor/github.com/kr/pty/ztypes_arm.go b/vendor/github.com/creack/pty/ztypes_arm.go similarity index 100% rename from vendor/github.com/kr/pty/ztypes_arm.go rename to vendor/github.com/creack/pty/ztypes_arm.go diff --git a/vendor/github.com/kr/pty/ztypes_arm64.go b/vendor/github.com/creack/pty/ztypes_arm64.go similarity index 100% rename from vendor/github.com/kr/pty/ztypes_arm64.go rename to vendor/github.com/creack/pty/ztypes_arm64.go diff --git a/vendor/github.com/kr/pty/ztypes_dragonfly_amd64.go b/vendor/github.com/creack/pty/ztypes_dragonfly_amd64.go similarity index 100% rename from vendor/github.com/kr/pty/ztypes_dragonfly_amd64.go rename to vendor/github.com/creack/pty/ztypes_dragonfly_amd64.go diff --git a/vendor/github.com/kr/pty/ztypes_freebsd_386.go b/vendor/github.com/creack/pty/ztypes_freebsd_386.go similarity index 100% rename from vendor/github.com/kr/pty/ztypes_freebsd_386.go rename to vendor/github.com/creack/pty/ztypes_freebsd_386.go diff --git a/vendor/github.com/kr/pty/ztypes_freebsd_amd64.go b/vendor/github.com/creack/pty/ztypes_freebsd_amd64.go similarity index 100% rename from vendor/github.com/kr/pty/ztypes_freebsd_amd64.go rename to vendor/github.com/creack/pty/ztypes_freebsd_amd64.go diff --git a/vendor/github.com/kr/pty/ztypes_freebsd_arm.go b/vendor/github.com/creack/pty/ztypes_freebsd_arm.go similarity index 100% rename from vendor/github.com/kr/pty/ztypes_freebsd_arm.go rename to vendor/github.com/creack/pty/ztypes_freebsd_arm.go diff --git a/vendor/github.com/kr/pty/ztypes_freebsd_arm64.go b/vendor/github.com/creack/pty/ztypes_freebsd_arm64.go similarity index 100% rename from vendor/github.com/kr/pty/ztypes_freebsd_arm64.go rename to vendor/github.com/creack/pty/ztypes_freebsd_arm64.go diff --git a/vendor/github.com/kr/pty/ztypes_freebsd_ppc64.go b/vendor/github.com/creack/pty/ztypes_freebsd_ppc64.go similarity index 100% rename from vendor/github.com/kr/pty/ztypes_freebsd_ppc64.go rename to vendor/github.com/creack/pty/ztypes_freebsd_ppc64.go diff --git a/vendor/github.com/kr/pty/ztypes_loongarchx.go b/vendor/github.com/creack/pty/ztypes_loong64.go similarity index 55% rename from vendor/github.com/kr/pty/ztypes_loongarchx.go rename to vendor/github.com/creack/pty/ztypes_loong64.go index 674d2a4088..3beb5c1762 100644 --- a/vendor/github.com/kr/pty/ztypes_loongarchx.go +++ b/vendor/github.com/creack/pty/ztypes_loong64.go @@ -1,6 +1,5 @@ -//go:build (loongarch32 || loongarch64) && linux -//+build linux -//+build loongarch32 loongarch64 +//go:build loong64 +// +build loong64 // Created by cgo -godefs - DO NOT EDIT // cgo -godefs types.go diff --git a/vendor/github.com/kr/pty/ztypes_mipsx.go b/vendor/github.com/creack/pty/ztypes_mipsx.go similarity index 100% rename from vendor/github.com/kr/pty/ztypes_mipsx.go rename to vendor/github.com/creack/pty/ztypes_mipsx.go diff --git a/vendor/github.com/kr/pty/ztypes_netbsd_32bit_int.go b/vendor/github.com/creack/pty/ztypes_netbsd_32bit_int.go similarity index 100% rename from vendor/github.com/kr/pty/ztypes_netbsd_32bit_int.go rename to vendor/github.com/creack/pty/ztypes_netbsd_32bit_int.go diff --git a/vendor/github.com/kr/pty/ztypes_openbsd_32bit_int.go b/vendor/github.com/creack/pty/ztypes_openbsd_32bit_int.go similarity index 100% rename from vendor/github.com/kr/pty/ztypes_openbsd_32bit_int.go rename to vendor/github.com/creack/pty/ztypes_openbsd_32bit_int.go diff --git a/vendor/github.com/kr/pty/ztypes_ppc64.go b/vendor/github.com/creack/pty/ztypes_ppc64.go similarity index 100% rename from vendor/github.com/kr/pty/ztypes_ppc64.go rename to vendor/github.com/creack/pty/ztypes_ppc64.go diff --git a/vendor/github.com/kr/pty/ztypes_ppc64le.go b/vendor/github.com/creack/pty/ztypes_ppc64le.go similarity index 100% rename from vendor/github.com/kr/pty/ztypes_ppc64le.go rename to vendor/github.com/creack/pty/ztypes_ppc64le.go diff --git a/vendor/github.com/kr/pty/ztypes_riscvx.go b/vendor/github.com/creack/pty/ztypes_riscvx.go similarity index 100% rename from vendor/github.com/kr/pty/ztypes_riscvx.go rename to vendor/github.com/creack/pty/ztypes_riscvx.go diff --git a/vendor/github.com/kr/pty/ztypes_s390x.go b/vendor/github.com/creack/pty/ztypes_s390x.go similarity index 100% rename from vendor/github.com/kr/pty/ztypes_s390x.go rename to vendor/github.com/creack/pty/ztypes_s390x.go diff --git a/vendor/github.com/hinshun/vt10x/Gopkg.lock b/vendor/github.com/hinshun/vt10x/Gopkg.lock deleted file mode 100644 index c17e0c6e46..0000000000 --- a/vendor/github.com/hinshun/vt10x/Gopkg.lock +++ /dev/null @@ -1,96 +0,0 @@ -# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. - - -[[projects]] - branch = "master" - name = "github.com/Netflix/go-expect" - packages = ["."] - revision = "c93bf25de8e869da25cf26bcd2932b36141f61ae" - -[[projects]] - name = "github.com/davecgh/go-spew" - packages = ["spew"] - revision = "346938d642f2ec3594ed81d874461961cd0faa76" - version = "v1.1.0" - -[[projects]] - branch = "master" - name = "github.com/gdamore/encoding" - packages = ["."] - revision = "b23993cbb6353f0e6aa98d0ee318a34728f628b9" - -[[projects]] - branch = "master" - name = "github.com/gdamore/tcell" - packages = [ - ".", - "terminfo" - ] - revision = "b3cebc399d6f98536af845ed8a5144ab586f6759" - -[[projects]] - name = "github.com/kr/pty" - packages = ["."] - revision = "282ce0e5322c82529687d609ee670fac7c7d917c" - version = "v1.1.1" - -[[projects]] - name = "github.com/lucasb-eyer/go-colorful" - packages = ["."] - revision = "345fbb3dbcdb252d9985ee899a84963c0fa24c82" - version = "v1.0" - -[[projects]] - name = "github.com/mattn/go-runewidth" - packages = ["."] - revision = "9e777a8366cce605130a531d2cd6363d07ad7317" - version = "v0.0.2" - -[[projects]] - name = "github.com/pmezard/go-difflib" - packages = ["difflib"] - revision = "792786c7400a136282c1664665ae0a8db921c6c2" - version = "v1.0.0" - -[[projects]] - name = "github.com/stretchr/testify" - packages = [ - "assert", - "require" - ] - revision = "12b6f73e6084dad08a7c6e575284b177ecafbc71" - version = "v1.2.1" - -[[projects]] - branch = "master" - name = "golang.org/x/crypto" - packages = ["ssh/terminal"] - revision = "8ac0e0d97ce45cd83d1d7243c060cb8461dda5e9" - -[[projects]] - branch = "master" - name = "golang.org/x/sys" - packages = [ - "unix", - "windows" - ] - revision = "9527bec2660bd847c050fda93a0f0c6dee0800bb" - -[[projects]] - name = "golang.org/x/text" - packages = [ - "encoding", - "encoding/internal/identifier", - "internal/gen", - "transform", - "unicode/cldr" - ] - revision = "f21a4dfb5e38f5895301dc265a8def02365cc3d0" - version = "v0.3.0" - -[solve-meta] - analyzer-name = "dep" - analyzer-version = 1 - inputs-digest = "bd24f29ad753e2f861768c734d71fbbc4e0380b5d7b43b6b101c01274cabcedb" - solver-name = "gps-cdcl" - solver-version = 1 diff --git a/vendor/github.com/hinshun/vt10x/Gopkg.toml b/vendor/github.com/hinshun/vt10x/Gopkg.toml deleted file mode 100644 index f63b1c2db2..0000000000 --- a/vendor/github.com/hinshun/vt10x/Gopkg.toml +++ /dev/null @@ -1,38 +0,0 @@ -# Gopkg.toml example -# -# Refer to https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md -# for detailed Gopkg.toml documentation. -# -# required = ["github.com/user/thing/cmd/thing"] -# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"] -# -# [[constraint]] -# name = "github.com/user/project" -# version = "1.0.0" -# -# [[constraint]] -# name = "github.com/user/project2" -# branch = "dev" -# source = "github.com/myfork/project2" -# -# [[override]] -# name = "github.com/x/y" -# version = "2.4.0" -# -# [prune] -# non-go = false -# go-tests = true -# unused-packages = true - - -[[constraint]] - name = "github.com/kr/pty" - version = "1.1.1" - -[[constraint]] - name = "github.com/stretchr/testify" - version = "1.2.1" - -[prune] - go-tests = true - unused-packages = true diff --git a/vendor/github.com/hinshun/vt10x/color.go b/vendor/github.com/hinshun/vt10x/color.go index 4ce0d8f323..c16d3ac4a2 100644 --- a/vendor/github.com/hinshun/vt10x/color.go +++ b/vendor/github.com/hinshun/vt10x/color.go @@ -24,12 +24,13 @@ const ( // For example, a transparent background. Otherwise, the simple case is to // map default colors to another color. const ( - DefaultFG Color = 0xff80 + iota + DefaultFG Color = 1<<24 + iota DefaultBG + DefaultCursor ) // Color maps to the ANSI colors [0, 16) and the xterm colors [16, 256). -type Color uint16 +type Color uint32 // ANSI returns true if Color is within [0, 16). func (c Color) ANSI() bool { diff --git a/vendor/github.com/hinshun/vt10x/csi.go b/vendor/github.com/hinshun/vt10x/csi.go index 138cff9078..f5df174ecd 100644 --- a/vendor/github.com/hinshun/vt10x/csi.go +++ b/vendor/github.com/hinshun/vt10x/csi.go @@ -74,26 +74,26 @@ func (t *State) handleCSI() { case '@': // ICH - insert blank char t.insertBlanks(c.arg(0, 1)) case 'A': // CUU - cursor up - t.moveTo(t.cur.x, t.cur.y-c.maxarg(0, 1)) + t.moveTo(t.cur.X, t.cur.Y-c.maxarg(0, 1)) case 'B', 'e': // CUD, VPR - cursor down - t.moveTo(t.cur.x, t.cur.y+c.maxarg(0, 1)) + t.moveTo(t.cur.X, t.cur.Y+c.maxarg(0, 1)) case 'c': // DA - device attributes if c.arg(0, 0) == 0 { // TODO: write vt102 id } case 'C', 'a': // CUF, HPR - cursor forward - t.moveTo(t.cur.x+c.maxarg(0, 1), t.cur.y) + t.moveTo(t.cur.X+c.maxarg(0, 1), t.cur.Y) case 'D': // CUB - cursor backward - t.moveTo(t.cur.x-c.maxarg(0, 1), t.cur.y) + t.moveTo(t.cur.X-c.maxarg(0, 1), t.cur.Y) case 'E': // CNL - cursor down and first col - t.moveTo(0, t.cur.y+c.arg(0, 1)) + t.moveTo(0, t.cur.Y+c.arg(0, 1)) case 'F': // CPL - cursor up and first col - t.moveTo(0, t.cur.y-c.arg(0, 1)) + t.moveTo(0, t.cur.Y-c.arg(0, 1)) case 'g': // TBC - tabulation clear switch c.arg(0, 0) { // clear current tab stop case 0: - t.tabs[t.cur.x] = false + t.tabs[t.cur.X] = false // clear all tabs case 3: for i := range t.tabs { @@ -103,7 +103,7 @@ func (t *State) handleCSI() { goto unknown } case 'G', '`': // CHA, HPA - Move to - t.moveTo(c.arg(0, 1)-1, t.cur.y) + t.moveTo(c.arg(0, 1)-1, t.cur.Y) case 'H', 'f': // CUP, HVP - move to t.moveAbsTo(c.arg(1, 1)-1, c.arg(0, 1)-1) case 'I': // CHT - cursor forward tabulation tab stops @@ -115,15 +115,15 @@ func (t *State) handleCSI() { // TODO: sel.ob.x = -1 switch c.arg(0, 0) { case 0: // below - t.clear(t.cur.x, t.cur.y, t.cols-1, t.cur.y) - if t.cur.y < t.rows-1 { - t.clear(0, t.cur.y+1, t.cols-1, t.rows-1) + t.clear(t.cur.X, t.cur.Y, t.cols-1, t.cur.Y) + if t.cur.Y < t.rows-1 { + t.clear(0, t.cur.Y+1, t.cols-1, t.rows-1) } case 1: // above - if t.cur.y > 1 { - t.clear(0, 0, t.cols-1, t.cur.y-1) + if t.cur.Y > 1 { + t.clear(0, 0, t.cols-1, t.cur.Y-1) } - t.clear(0, t.cur.y, t.cur.x, t.cur.y) + t.clear(0, t.cur.Y, t.cur.X, t.cur.Y) case 2: // all t.clear(0, 0, t.cols-1, t.rows-1) default: @@ -132,11 +132,11 @@ func (t *State) handleCSI() { case 'K': // EL - clear line switch c.arg(0, 0) { case 0: // right - t.clear(t.cur.x, t.cur.y, t.cols-1, t.cur.y) + t.clear(t.cur.X, t.cur.Y, t.cols-1, t.cur.Y) case 1: // left - t.clear(0, t.cur.y, t.cur.x, t.cur.y) + t.clear(0, t.cur.Y, t.cur.X, t.cur.Y) case 2: // all - t.clear(0, t.cur.y, t.cols-1, t.cur.y) + t.clear(0, t.cur.Y, t.cols-1, t.cur.Y) } case 'S': // SU - scroll lines up t.scrollUp(t.top, c.arg(0, 1)) @@ -149,7 +149,7 @@ func (t *State) handleCSI() { case 'M': // DL - delete lines t.deleteLines(c.arg(0, 1)) case 'X': // ECH - erase chars - t.clear(t.cur.x, t.cur.y, t.cur.x+c.arg(0, 1)-1, t.cur.y) + t.clear(t.cur.X, t.cur.Y, t.cur.X+c.arg(0, 1)-1, t.cur.Y) case 'P': // DCH - delete chars t.deleteChars(c.arg(0, 1)) case 'Z': // CBT - cursor backward tabulation tab stops @@ -158,7 +158,7 @@ func (t *State) handleCSI() { t.putTab(false) } case 'd': // VPA - move to - t.moveAbsTo(t.cur.x, c.arg(0, 1)-1) + t.moveAbsTo(t.cur.X, c.arg(0, 1)-1) case 'h': // SM - set terminal mode t.setMode(c.priv, true, c.args) case 'm': // SGR - terminal attribute (color) @@ -168,7 +168,7 @@ func (t *State) handleCSI() { case 5: // DSR - device status report t.w.Write([]byte("\033[0n")) case 6: // CPR - cursor position report - t.w.Write([]byte(fmt.Sprintf("\033[%d;%dR", t.cur.y+1, t.cur.x+1))) + t.w.Write([]byte(fmt.Sprintf("\033[%d;%dR", t.cur.Y+1, t.cur.X+1))) } case 'r': // DECSTBM - set scrolling region if c.priv { diff --git a/vendor/github.com/hinshun/vt10x/expect.go b/vendor/github.com/hinshun/vt10x/expect.go deleted file mode 100644 index 1c1c646b8c..0000000000 --- a/vendor/github.com/hinshun/vt10x/expect.go +++ /dev/null @@ -1,29 +0,0 @@ -package vt10x - -import ( - expect "github.com/Netflix/go-expect" - "github.com/kr/pty" -) - -// NewVT10XConsole returns a new expect.Console that multiplexes the -// Stdin/Stdout to a VT10X terminal, allowing Console to interact with an -// application sending ANSI escape sequences. -func NewVT10XConsole(opts ...expect.ConsoleOpt) (*expect.Console, *State, error) { - ptm, pts, err := pty.Open() - if err != nil { - return nil, nil, err - } - - var state State - term, err := Create(&state, pts) - if err != nil { - return nil, nil, err - } - - c, err := expect.NewConsole(append(opts, expect.WithStdin(ptm), expect.WithStdout(term), expect.WithCloser(pts, ptm, term))...) - if err != nil { - return nil, nil, err - } - - return c, &state, nil -} diff --git a/vendor/github.com/hinshun/vt10x/parse.go b/vendor/github.com/hinshun/vt10x/parse.go index 51a19800b3..0b841457c2 100644 --- a/vendor/github.com/hinshun/vt10x/parse.go +++ b/vendor/github.com/hinshun/vt10x/parse.go @@ -7,27 +7,27 @@ func isControlCode(c rune) bool { func (t *State) parse(c rune) { t.logf("%q", string(c)) if isControlCode(c) { - if t.handleControlCodes(c) || t.cur.attr.mode&attrGfx == 0 { + if t.handleControlCodes(c) || t.cur.Attr.Mode&attrGfx == 0 { return } } // TODO: update selection; see st.c:2450 - if t.mode&ModeWrap != 0 && t.cur.state&cursorWrapNext != 0 { - t.lines[t.cur.y][t.cur.x].mode |= attrWrap + if t.mode&ModeWrap != 0 && t.cur.State&cursorWrapNext != 0 { + t.lines[t.cur.Y][t.cur.X].Mode |= attrWrap t.newline(true) } - if t.mode&ModeInsert != 0 && t.cur.x+1 < t.cols { + if t.mode&ModeInsert != 0 && t.cur.X+1 < t.cols { // TODO: move shiz, look at st.c:2458 t.logln("insert mode not implemented") } - t.setChar(c, &t.cur.attr, t.cur.x, t.cur.y) - if t.cur.x+1 < t.cols { - t.moveTo(t.cur.x+1, t.cur.y) + t.setChar(c, &t.cur.Attr, t.cur.X, t.cur.Y) + if t.cur.X+1 < t.cols { + t.moveTo(t.cur.X+1, t.cur.Y) } else { - t.cur.state |= cursorWrapNext + t.cur.State |= cursorWrapNext } } @@ -56,20 +56,20 @@ func (t *State) parseEsc(c rune) { '*', // set tertiary charset G2 (ignored) '+': // set quaternary charset G3 (ignored) case 'D': // IND - linefeed - if t.cur.y == t.bottom { + if t.cur.Y == t.bottom { t.scrollUp(t.top, 1) } else { - t.moveTo(t.cur.x, t.cur.y+1) + t.moveTo(t.cur.X, t.cur.Y+1) } case 'E': // NEL - next line t.newline(true) case 'H': // HTS - horizontal tab stop - t.tabs[t.cur.x] = true + t.tabs[t.cur.X] = true case 'M': // RI - reverse index - if t.cur.y == t.top { + if t.cur.Y == t.top { t.scrollDown(t.top, 1) } else { - t.moveTo(t.cur.x, t.cur.y-1) + t.moveTo(t.cur.X, t.cur.Y-1) } case 'Z': // DECID - identify terminal // TODO: write to our writer our id @@ -132,9 +132,9 @@ func (t *State) parseEscAltCharset(c rune) { t.logf("%q", string(c)) switch c { case '0': // line drawing set - t.cur.attr.mode |= attrGfx + t.cur.Attr.Mode |= attrGfx case 'B': // USASCII - t.cur.attr.mode &^= attrGfx + t.cur.Attr.Mode &^= attrGfx case 'A', // UK (ignored) '<', // multinational (ignored) '5', // Finnish (ignored) @@ -154,7 +154,7 @@ func (t *State) parseEscTest(c rune) { if c == '8' { for y := 0; y < t.rows; y++ { for x := 0; x < t.cols; x++ { - t.setChar('E', &t.cur.attr, x, y) + t.setChar('E', &t.cur.Attr, x, y) } } } @@ -171,10 +171,10 @@ func (t *State) handleControlCodes(c rune) bool { t.putTab(true) // BS case '\b': - t.moveTo(t.cur.x-1, t.cur.y) + t.moveTo(t.cur.X-1, t.cur.Y) // CR case '\r': - t.moveTo(0, t.cur.y) + t.moveTo(0, t.cur.Y) // LF, VT, LF case '\f', '\v', '\n': // go to first col if mode is set diff --git a/vendor/github.com/hinshun/vt10x/state.go b/vendor/github.com/hinshun/vt10x/state.go index 9e8dd3e320..b2b40786d0 100644 --- a/vendor/github.com/hinshun/vt10x/state.go +++ b/vendor/github.com/hinshun/vt10x/state.go @@ -62,18 +62,18 @@ const ( ChangedTitle ) -type glyph struct { - c rune - mode int16 - fg, bg Color +type Glyph struct { + Char rune + Mode int16 + FG, BG Color } -type line []glyph +type line []Glyph -type cursor struct { - attr glyph - x, y int - state uint8 +type Cursor struct { + Attr Glyph + X, Y int + State uint8 } type parseState func(c rune) @@ -91,7 +91,7 @@ type State struct { altLines []line dirty []bool // line dirtiness anydirty bool - cur, curSaved cursor + cur, curSaved Cursor top, bottom int // scroll limits mode ModeFlag state parseState @@ -100,6 +100,14 @@ type State struct { numlock bool tabs []bool title string + colorOverride map[Color]Color +} + +func newState(w io.Writer) *State { + return &State{ + w: w, + colorOverride: make(map[Color]Color), + } } func (t *State) logf(format string, args ...interface{}) { @@ -133,15 +141,24 @@ func (t *State) Unlock() { t.mu.Unlock() } -// Cell returns the character code, foreground color, and background -// color at position (x, y) relative to the top left of the terminal. -func (t *State) Cell(x, y int) (ch rune, fg Color, bg Color) { - return t.lines[y][x].c, Color(t.lines[y][x].fg), Color(t.lines[y][x].bg) +// Cell returns the glyph containing the character code, foreground color, and +// background color at position (x, y) relative to the top left of the terminal. +func (t *State) Cell(x, y int) Glyph { + cell := t.lines[y][x] + fg, ok := t.colorOverride[cell.FG] + if ok { + cell.FG = fg + } + bg, ok := t.colorOverride[cell.BG] + if ok { + cell.BG = bg + } + return cell } // Cursor returns the current position of the cursor. -func (t *State) Cursor() (int, int) { - return t.cur.x, t.cur.y +func (t *State) Cursor() Cursor { + return t.cur } // CursorVisible returns the visible state of the cursor. @@ -149,9 +166,9 @@ func (t *State) CursorVisible() bool { return t.mode&ModeHide == 0 } -// Mode tests if mode is currently set. -func (t *State) Mode(mode ModeFlag) bool { - return t.mode&mode != 0 +// Mode returns the current terminal mode. +func (t *State) Mode() ModeFlag { + return t.mode } // Title returns the current title set via the tty. @@ -186,7 +203,7 @@ func (t *State) saveCursor() { func (t *State) restoreCursor() { t.cur = t.curSaved - t.moveTo(t.cur.x, t.cur.y) + t.moveTo(t.cur.X, t.cur.Y) } func (t *State) put(c rune) { @@ -194,7 +211,7 @@ func (t *State) put(c rune) { } func (t *State) putTab(forward bool) { - x := t.cur.x + x := t.cur.X if forward { if x == t.cols { return @@ -208,11 +225,11 @@ func (t *State) putTab(forward bool) { for x--; x > 0 && !t.tabs[x]; x-- { } } - t.moveTo(x, t.cur.y) + t.moveTo(x, t.cur.Y) } func (t *State) newline(firstCol bool) { - y := t.cur.y + y := t.cur.Y if y == t.bottom { cur := t.cur t.cur = t.defaultCursor() @@ -224,7 +241,7 @@ func (t *State) newline(firstCol bool) { if firstCol { t.moveTo(0, y) } else { - t.moveTo(t.cur.x, y) + t.moveTo(t.cur.X, y) } } @@ -240,8 +257,8 @@ var gfxCharTable = [62]rune{ '│', '≤', '≥', 'π', '≠', '£', '·', // x - ~ } -func (t *State) setChar(c rune, attr *glyph, x, y int) { - if attr.mode&attrGfx != 0 { +func (t *State) setChar(c rune, attr *Glyph, x, y int) { + if attr.Mode&attrGfx != 0 { if c >= 0x41 && c <= 0x7e && gfxCharTable[c-0x41] != 0 { c = gfxCharTable[c-0x41] } @@ -249,21 +266,21 @@ func (t *State) setChar(c rune, attr *glyph, x, y int) { t.changed |= ChangedScreen t.dirty[y] = true t.lines[y][x] = *attr - t.lines[y][x].c = c - //if t.options.BrightBold && attr.mode&attrBold != 0 && attr.fg < 8 { - if attr.mode&attrBold != 0 && attr.fg < 8 { - t.lines[y][x].fg = attr.fg + 8 + t.lines[y][x].Char = c + //if t.options.BrightBold && attr.Mode&attrBold != 0 && attr.FG < 8 { + if attr.Mode&attrBold != 0 && attr.FG < 8 { + t.lines[y][x].FG = attr.FG + 8 } - if attr.mode&attrReverse != 0 { - t.lines[y][x].fg = attr.bg - t.lines[y][x].bg = attr.fg + if attr.Mode&attrReverse != 0 { + t.lines[y][x].FG = attr.BG + t.lines[y][x].BG = attr.FG } } -func (t *State) defaultCursor() cursor { - c := cursor{} - c.attr.fg = DefaultFG - c.attr.bg = DefaultBG +func (t *State) defaultCursor() Cursor { + c := Cursor{} + c.Attr.FG = DefaultFG + c.Attr.BG = DefaultBG return c } @@ -291,7 +308,7 @@ func (t *State) resize(cols, rows int) bool { if cols < 1 || rows < 1 { return false } - slide := t.cur.y - rows + 1 + slide := t.cur.Y - rows + 1 if slide > 0 { copy(t.lines, t.lines[slide:slide+rows]) copy(t.altLines, t.altLines[slide:slide+rows]) @@ -329,7 +346,7 @@ func (t *State) resize(cols, rows int) bool { t.cols = cols t.rows = rows t.setScroll(0, rows-1) - t.moveTo(t.cur.x, t.cur.y) + t.moveTo(t.cur.X, t.cur.Y) for i := 0; i < 2; i++ { if mincols < cols && minrows > 0 { t.clear(mincols, 0, cols-1, minrows-1) @@ -357,8 +374,8 @@ func (t *State) clear(x0, y0, x1, y1 int) { for y := y0; y <= y1; y++ { t.dirty[y] = true for x := x0; x <= x1; x++ { - t.lines[y][x] = t.cur.attr - t.lines[y][x].c = ' ' + t.lines[y][x] = t.cur.Attr + t.lines[y][x].Char = ' ' } } } @@ -368,7 +385,7 @@ func (t *State) clearAll() { } func (t *State) moveAbsTo(x, y int) { - if t.cur.state&cursorOrigin != 0 { + if t.cur.State&cursorOrigin != 0 { y += t.top } t.moveTo(x, y) @@ -376,7 +393,7 @@ func (t *State) moveAbsTo(x, y int) { func (t *State) moveTo(x, y int) { var miny, maxy int - if t.cur.state&cursorOrigin != 0 { + if t.cur.State&cursorOrigin != 0 { miny = t.top maxy = t.bottom } else { @@ -386,9 +403,9 @@ func (t *State) moveTo(x, y int) { x = clamp(x, 0, t.cols-1) y = clamp(y, miny, maxy) t.changed |= ChangedScreen - t.cur.state &^= cursorWrapNext - t.cur.x = x - t.cur.y = y + t.cur.State &^= cursorWrapNext + t.cur.X = x + t.cur.Y = y } func (t *State) swapScreen() { @@ -492,9 +509,9 @@ func (t *State) setMode(priv bool, set bool, args []int) { } case 6: // DECOM - origin if set { - t.cur.state |= cursorOrigin + t.cur.State |= cursorOrigin } else { - t.cur.state &^= cursorOrigin + t.cur.State &^= cursorOrigin } t.moveAbsTo(0, 0) case 7: // DECAWM - auto wrap @@ -594,64 +611,80 @@ func (t *State) setAttr(attr []int) { a := attr[i] switch a { case 0: - t.cur.attr.mode &^= attrReverse | attrUnderline | attrBold | attrItalic | attrBlink - t.cur.attr.fg = DefaultFG - t.cur.attr.bg = DefaultBG + t.cur.Attr.Mode &^= attrReverse | attrUnderline | attrBold | attrItalic | attrBlink + t.cur.Attr.FG = DefaultFG + t.cur.Attr.BG = DefaultBG case 1: - t.cur.attr.mode |= attrBold + t.cur.Attr.Mode |= attrBold case 3: - t.cur.attr.mode |= attrItalic + t.cur.Attr.Mode |= attrItalic case 4: - t.cur.attr.mode |= attrUnderline + t.cur.Attr.Mode |= attrUnderline case 5, 6: // slow, rapid blink - t.cur.attr.mode |= attrBlink + t.cur.Attr.Mode |= attrBlink case 7: - t.cur.attr.mode |= attrReverse + t.cur.Attr.Mode |= attrReverse case 21, 22: - t.cur.attr.mode &^= attrBold + t.cur.Attr.Mode &^= attrBold case 23: - t.cur.attr.mode &^= attrItalic + t.cur.Attr.Mode &^= attrItalic case 24: - t.cur.attr.mode &^= attrUnderline + t.cur.Attr.Mode &^= attrUnderline case 25, 26: - t.cur.attr.mode &^= attrBlink + t.cur.Attr.Mode &^= attrBlink case 27: - t.cur.attr.mode &^= attrReverse + t.cur.Attr.Mode &^= attrReverse case 38: if i+2 < len(attr) && attr[i+1] == 5 { i += 2 if between(attr[i], 0, 255) { - t.cur.attr.fg = Color(attr[i]) + t.cur.Attr.FG = Color(attr[i]) } else { t.logf("bad fgcolor %d\n", attr[i]) } + } else if i+4 < len(attr) && attr[i+1] == 2 { + i += 4 + r, g, b := attr[i-2], attr[i-1], attr[i] + if !between(r, 0, 255) || !between(g, 0, 255) || !between(b, 0, 255) { + t.logf("bad fg rgb color (%d,%d,%d)\n", r, g, b) + } else { + t.cur.Attr.FG = Color(r<<16 | g<<8 | b) + } } else { t.logf("gfx attr %d unknown\n", a) } case 39: - t.cur.attr.fg = DefaultFG + t.cur.Attr.FG = DefaultFG case 48: if i+2 < len(attr) && attr[i+1] == 5 { i += 2 if between(attr[i], 0, 255) { - t.cur.attr.bg = Color(attr[i]) + t.cur.Attr.BG = Color(attr[i]) } else { t.logf("bad bgcolor %d\n", attr[i]) } + } else if i+4 < len(attr) && attr[i+1] == 2 { + i += 4 + r, g, b := attr[i-2], attr[i-1], attr[i] + if !between(r, 0, 255) || !between(g, 0, 255) || !between(b, 0, 255) { + t.logf("bad bg rgb color (%d,%d,%d)\n", r, g, b) + } else { + t.cur.Attr.BG = Color(r<<16 | g<<8 | b) + } } else { t.logf("gfx attr %d unknown\n", a) } case 49: - t.cur.attr.bg = DefaultBG + t.cur.Attr.BG = DefaultBG default: if between(a, 30, 37) { - t.cur.attr.fg = Color(a - 30) + t.cur.Attr.FG = Color(a - 30) } else if between(a, 40, 47) { - t.cur.attr.bg = Color(a - 40) + t.cur.Attr.BG = Color(a - 40) } else if between(a, 90, 97) { - t.cur.attr.fg = Color(a - 90 + 8) + t.cur.Attr.FG = Color(a - 90 + 8) } else if between(a, 100, 107) { - t.cur.attr.bg = Color(a - 100 + 8) + t.cur.Attr.BG = Color(a - 100 + 8) } else { t.logf("gfx attr %d unknown\n", a) } @@ -660,46 +693,46 @@ func (t *State) setAttr(attr []int) { } func (t *State) insertBlanks(n int) { - src := t.cur.x + src := t.cur.X dst := src + n size := t.cols - dst t.changed |= ChangedScreen - t.dirty[t.cur.y] = true + t.dirty[t.cur.Y] = true if dst >= t.cols { - t.clear(t.cur.x, t.cur.y, t.cols-1, t.cur.y) + t.clear(t.cur.X, t.cur.Y, t.cols-1, t.cur.Y) } else { - copy(t.lines[t.cur.y][dst:dst+size], t.lines[t.cur.y][src:src+size]) - t.clear(src, t.cur.y, dst-1, t.cur.y) + copy(t.lines[t.cur.Y][dst:dst+size], t.lines[t.cur.Y][src:src+size]) + t.clear(src, t.cur.Y, dst-1, t.cur.Y) } } func (t *State) insertBlankLines(n int) { - if t.cur.y < t.top || t.cur.y > t.bottom { + if t.cur.Y < t.top || t.cur.Y > t.bottom { return } - t.scrollDown(t.cur.y, n) + t.scrollDown(t.cur.Y, n) } func (t *State) deleteLines(n int) { - if t.cur.y < t.top || t.cur.y > t.bottom { + if t.cur.Y < t.top || t.cur.Y > t.bottom { return } - t.scrollUp(t.cur.y, n) + t.scrollUp(t.cur.Y, n) } func (t *State) deleteChars(n int) { - src := t.cur.x + n - dst := t.cur.x + src := t.cur.X + n + dst := t.cur.X size := t.cols - src t.changed |= ChangedScreen - t.dirty[t.cur.y] = true + t.dirty[t.cur.Y] = true if src >= t.cols { - t.clear(t.cur.x, t.cur.y, t.cols-1, t.cur.y) + t.clear(t.cur.X, t.cur.Y, t.cols-1, t.cur.Y) } else { - copy(t.lines[t.cur.y][dst:dst+size], t.lines[t.cur.y][src:src+size]) - t.clear(t.cols-n, t.cur.y, t.cols-1, t.cur.y) + copy(t.lines[t.cur.Y][dst:dst+size], t.lines[t.cur.Y][src:src+size]) + t.clear(t.cols-n, t.cur.Y, t.cols-1, t.cur.Y) } } @@ -708,8 +741,8 @@ func (t *State) setTitle(title string) { t.title = title } -func (t *State) Size() (rows int, cols int) { - return t.rows, t.cols +func (t *State) Size() (cols, rows int) { + return t.cols, t.rows } func (t *State) String() string { @@ -719,8 +752,8 @@ func (t *State) String() string { var view []rune for y := 0; y < t.rows; y++ { for x := 0; x < t.cols; x++ { - c, _, _ := t.Cell(x, y) - view = append(view, c) + attr := t.Cell(x, y) + view = append(view, attr.Char) } view = append(view, '\n') } diff --git a/vendor/github.com/hinshun/vt10x/str.go b/vendor/github.com/hinshun/vt10x/str.go index c8ca50cbcb..2a42b04f63 100644 --- a/vendor/github.com/hinshun/vt10x/str.go +++ b/vendor/github.com/hinshun/vt10x/str.go @@ -1,6 +1,9 @@ package vt10x import ( + "fmt" + "math" + "regexp" "strconv" "strings" ) @@ -59,20 +62,77 @@ func (t *State) handleSTR() { switch s.typ { case ']': // OSC - operating system command + var p *string switch d := s.arg(0, 0); d { case 0, 1, 2: title := s.argString(1, "") if title != "" { t.setTitle(title) } + case 10: + if len(s.args) < 2 { + break + } + + c := s.argString(1, "") + p := &c + if p != nil && *p == "?" { + t.oscColorResponse(int(DefaultFG), 10) + } else if err := t.setColorName(int(DefaultFG), p); err != nil { + t.logf("invalid foreground color: %s\n", maybe(p)) + } else { + // TODO: redraw + } + case 11: + if len(s.args) < 2 { + break + } + + c := s.argString(1, "") + p := &c + if p != nil && *p == "?" { + t.oscColorResponse(int(DefaultBG), 11) + } else if err := t.setColorName(int(DefaultBG), p); err != nil { + t.logf("invalid cursor color: %s\n", maybe(p)) + } else { + // TODO: redraw + } + // case 12: + // if len(s.args) < 2 { + // break + // } + + // c := s.argString(1, "") + // p := &c + // if p != nil && *p == "?" { + // t.oscColorResponse(int(DefaultCursor), 12) + // } else if err := t.setColorName(int(DefaultCursor), p); err != nil { + // t.logf("invalid background color: %s\n", p) + // } else { + // // TODO: redraw + // } case 4: // color set if len(s.args) < 3 { break } - // setcolorname(s.arg(1, 0), s.argString(2, "")) + + c := s.argString(2, "") + p = &c + fallthrough case 104: // color reset - // TODO: complain about invalid color, redraw, etc. - // setcolorname(s.arg(1, 0), nil) + j := -1 + if len(s.args) > 1 { + j = s.arg(1, 0) + } + if p != nil && *p == "?" { // report + t.osc4ColorResponse(j) + } else if err := t.setColorName(j, p); err != nil { + if !(d == 104 && len(s.args) <= 1) { + t.logf("invalid color j=%d, p=%s\n", j, maybe(p)) + } + } else { + // TODO: redraw + } default: t.logf("unknown OSC command %d\n", d) // TODO: s.dump() @@ -92,3 +152,179 @@ func (t *State) handleSTR() { // t.str.dump() } } + +func (t *State) setColorName(j int, p *string) error { + if !between(j, 0, 1<<24) { + return fmt.Errorf("invalid color value %d", j) + } + + if p == nil { + // restore color + delete(t.colorOverride, Color(j)) + } else { + // set color + r, g, b, err := parseColor(*p) + if err != nil { + return err + } + t.colorOverride[Color(j)] = Color(r<<16 | g<<8 | b) + } + + return nil +} + +func (t *State) oscColorResponse(j, num int) { + if j < 0 { + t.logf("failed to fetch osc color %d\n", j) + return + } + + k, ok := t.colorOverride[Color(j)] + if ok { + j = int(k) + } + + r, g, b := rgb(j) + t.w.Write([]byte(fmt.Sprintf("\033]%d;rgb:%02x%02x/%02x%02x/%02x%02x\007", num, r, r, g, g, b, b))) +} + +func (t *State) osc4ColorResponse(j int) { + if j < 0 { + t.logf("failed to fetch osc4 color %d\n", j) + return + } + + k, ok := t.colorOverride[Color(j)] + if ok { + j = int(k) + } + + r, g, b := rgb(j) + t.w.Write([]byte(fmt.Sprintf("\033]4;%d;rgb:%02x%02x/%02x%02x/%02x%02x\007", j, r, r, g, g, b, b))) +} + +func rgb(j int) (r, g, b int) { + return (j >> 16) & 0xff, (j >> 8) & 0xff, j & 0xff +} + +var ( + RGBPattern = regexp.MustCompile(`^([\da-f]{1})\/([\da-f]{1})\/([\da-f]{1})$|^([\da-f]{2})\/([\da-f]{2})\/([\da-f]{2})$|^([\da-f]{3})\/([\da-f]{3})\/([\da-f]{3})$|^([\da-f]{4})\/([\da-f]{4})\/([\da-f]{4})$`) + HashPattern = regexp.MustCompile(`[\da-f]`) +) + +func parseColor(p string) (r, g, b int, err error) { + if len(p) == 0 { + err = fmt.Errorf("empty color spec") + return + } + + low := strings.ToLower(p) + if strings.HasPrefix(low, "rgb:") { + low = low[4:] + sm := RGBPattern.FindAllStringSubmatch(low, -1) + if len(sm) != 1 || len(sm[0]) == 0 { + err = fmt.Errorf("invalid rgb color spec: %s", p) + return + } + m := sm[0] + + var base float64 + if len(m[1]) > 0 { + base = 15 + } else if len(m[4]) > 0 { + base = 255 + } else if len(m[7]) > 0 { + base = 4095 + } else { + base = 65535 + } + + r64, err := strconv.ParseInt(firstNonEmpty(m[1], m[4], m[7], m[10]), 16, 0) + if err != nil { + return r, g, b, err + } + + g64, err := strconv.ParseInt(firstNonEmpty(m[2], m[5], m[8], m[11]), 16, 0) + if err != nil { + return r, g, b, err + } + + b64, err := strconv.ParseInt(firstNonEmpty(m[3], m[6], m[9], m[12]), 16, 0) + if err != nil { + return r, g, b, err + } + + r = int(math.Round(float64(r64) / base * 255)) + g = int(math.Round(float64(g64) / base * 255)) + b = int(math.Round(float64(b64) / base * 255)) + return r, g, b, nil + } else if strings.HasPrefix(low, "#") { + low = low[1:] + m := HashPattern.FindAllString(low, -1) + if !oneOf(len(m), []int{3, 6, 9, 12}) { + err = fmt.Errorf("invalid hash color spec: %s", p) + return + } + + adv := len(low) / 3 + for i := 0; i < 3; i++ { + c, err := strconv.ParseInt(low[adv*i:adv*i+adv], 16, 0) + if err != nil { + return r, g, b, err + } + + var v int64 + switch adv { + case 1: + v = c << 4 + case 2: + v = c + case 3: + v = c >> 4 + default: + v = c >> 8 + } + + switch i { + case 0: + r = int(v) + case 1: + g = int(v) + case 2: + b = int(v) + } + } + return + } else { + err = fmt.Errorf("invalid color spec: %s", p) + return + } +} + +func maybe(p *string) string { + if p == nil { + return "" + } + return *p +} + +func firstNonEmpty(strs ...string) string { + if len(strs) == 0 { + return "" + } + for _, str := range strs { + if len(str) > 0 { + return str + } + } + return strs[len(strs)-1] +} + +func oneOf(v int, is []int) bool { + for _, i := range is { + if v == i { + return true + } + } + return false +} diff --git a/vendor/github.com/hinshun/vt10x/vt.go b/vendor/github.com/hinshun/vt10x/vt.go new file mode 100644 index 0000000000..c4e58dd6a4 --- /dev/null +++ b/vendor/github.com/hinshun/vt10x/vt.go @@ -0,0 +1,89 @@ +package vt10x + +import ( + "bufio" + "fmt" + "io" + "io/ioutil" +) + +// Terminal represents the virtual terminal emulator. +type Terminal interface { + // View displays the virtual terminal. + View + + // Write parses input and writes terminal changes to state. + io.Writer + + // Parse blocks on read on pty or io.Reader, then parses sequences until + // buffer empties. State is locked as soon as first rune is read, and unlocked + // when buffer is empty. + Parse(bf *bufio.Reader) error +} + +// View represents the view of the virtual terminal emulator. +type View interface { + // String dumps the virtual terminal contents. + fmt.Stringer + + // Size returns the size of the virtual terminal. + Size() (cols, rows int) + + // Resize changes the size of the virtual terminal. + Resize(cols, rows int) + + // Mode returns the current terminal mode.// + Mode() ModeFlag + + // Title represents the title of the console window. + Title() string + + // Cell returns the glyph containing the character code, foreground color, and + // background color at position (x, y) relative to the top left of the terminal. + Cell(x, y int) Glyph + + // Cursor returns the current position of the cursor. + Cursor() Cursor + + // CursorVisible returns the visible state of the cursor. + CursorVisible() bool + + // Lock locks the state object's mutex. + Lock() + + // Unlock resets change flags and unlocks the state object's mutex. + Unlock() +} + +type TerminalOption func(*TerminalInfo) + +type TerminalInfo struct { + w io.Writer + cols, rows int +} + +func WithWriter(w io.Writer) TerminalOption { + return func(info *TerminalInfo) { + info.w = w + } +} + +func WithSize(cols, rows int) TerminalOption { + return func(info *TerminalInfo) { + info.cols = cols + info.rows = rows + } +} + +// New returns a new virtual terminal emulator. +func New(opts ...TerminalOption) Terminal { + info := TerminalInfo{ + w: ioutil.Discard, + cols: 80, + rows: 24, + } + for _, opt := range opts { + opt(&info) + } + return newTerminal(info) +} diff --git a/vendor/github.com/hinshun/vt10x/vt_other.go b/vendor/github.com/hinshun/vt10x/vt_other.go index 6d4b500718..c9d364ee53 100644 --- a/vendor/github.com/hinshun/vt10x/vt_other.go +++ b/vendor/github.com/hinshun/vt10x/vt_other.go @@ -6,47 +6,34 @@ import ( "bufio" "bytes" "io" - "os" "unicode" "unicode/utf8" ) -// VT represents the virtual terminal emulator. -type VT struct { - dest *State - rwc io.ReadWriteCloser - br *bufio.Reader - pty *os.File +type terminal struct { + *State } -// Create initializes a virtual terminal emulator with the target state -// and io.ReadWriteCloser input. -func Create(state *State, rwc io.ReadWriteCloser) (*VT, error) { - t := &VT{ - dest: state, - rwc: rwc, - } - t.init() - return t, nil +func newTerminal(info TerminalInfo) *terminal { + t := &terminal{newState(info.w)} + t.init(info.cols, info.rows) + return t } -func (t *VT) init() { - t.br = bufio.NewReader(t.rwc) - t.dest.w = t.rwc - t.dest.numlock = true - t.dest.state = t.dest.parse - t.dest.cur.attr.fg = DefaultFG - t.dest.cur.attr.bg = DefaultBG - t.Resize(80, 24) - t.dest.reset() +func (t *terminal) init(cols, rows int) { + t.numlock = true + t.state = t.parse + t.cur.Attr.FG = DefaultFG + t.cur.Attr.BG = DefaultBG + t.Resize(cols, rows) + t.reset() } -// Write parses input and writes terminal changes to state. -func (t *VT) Write(p []byte) (int, error) { +func (t *terminal) Write(p []byte) (int, error) { var written int r := bytes.NewReader(p) - t.dest.lock() - defer t.dest.unlock() + t.lock() + defer t.unlock() for { c, sz, err := r.ReadRune() if err != nil { @@ -61,51 +48,43 @@ func (t *VT) Write(p []byte) (int, error) { // not enough bytes for a full rune return written - 1, nil } - t.dest.logln("invalid utf8 sequence") + t.logln("invalid utf8 sequence") continue } - t.dest.put(c) + t.put(c) } return written, nil } -// Close closes the io.ReadWriteCloser. -func (t *VT) Close() error { - return t.rwc.Close() -} - -// Parse blocks on read on io.ReadWriteCloser, then parses sequences until -// buffer empties. State is locked as soon as first rune is read, and unlocked -// when buffer is empty. // TODO: add tests for expected blocking behavior -func (t *VT) Parse() error { +func (t *terminal) Parse(br *bufio.Reader) error { var locked bool defer func() { if locked { - t.dest.unlock() + t.unlock() } }() for { - c, sz, err := t.br.ReadRune() + c, sz, err := br.ReadRune() if err != nil { return err } if c == unicode.ReplacementChar && sz == 1 { - t.dest.logln("invalid utf8 sequence") + t.logln("invalid utf8 sequence") break } if !locked { - t.dest.lock() + t.lock() locked = true } // put rune for parsing and update state - t.dest.put(c) + t.put(c) // break if our buffer is empty, or if buffer contains an // incomplete rune. - n := t.br.Buffered() - if n == 0 || (n < 4 && !fullRuneBuffered(t.br)) { + n := br.Buffered() + if n == 0 || (n < 4 && !fullRuneBuffered(br)) { break } } @@ -121,9 +100,8 @@ func fullRuneBuffered(br *bufio.Reader) bool { return utf8.FullRune(buf) } -// Resize reports new size to pty and updates state. -func (t *VT) Resize(cols, rows int) { - t.dest.lock() - defer t.dest.unlock() - _ = t.dest.resize(cols, rows) +func (t *terminal) Resize(cols, rows int) { + t.lock() + defer t.unlock() + _ = t.resize(cols, rows) } diff --git a/vendor/github.com/hinshun/vt10x/vt_posix.go b/vendor/github.com/hinshun/vt10x/vt_posix.go index 94e4d007db..80644f4bdc 100644 --- a/vendor/github.com/hinshun/vt10x/vt_posix.go +++ b/vendor/github.com/hinshun/vt10x/vt_posix.go @@ -10,41 +10,31 @@ import ( "unicode/utf8" ) -// VT represents the virtual terminal emulator. -type VT struct { - dest *State - rwc io.ReadWriteCloser - br *bufio.Reader +type terminal struct { + *State } -// Create initializes a virtual terminal emulator with the target state -// and io.ReadWriteCloser input. -func Create(state *State, rwc io.ReadWriteCloser) (*VT, error) { - t := &VT{ - dest: state, - rwc: rwc, - } - t.init() - return t, nil +func newTerminal(info TerminalInfo) *terminal { + t := &terminal{newState(info.w)} + t.init(info.cols, info.rows) + return t } -func (t *VT) init() { - t.br = bufio.NewReader(t.rwc) - t.dest.w = t.rwc - t.dest.numlock = true - t.dest.state = t.dest.parse - t.dest.cur.attr.fg = DefaultFG - t.dest.cur.attr.bg = DefaultBG - t.Resize(80, 24) - t.dest.reset() +func (t *terminal) init(cols, rows int) { + t.numlock = true + t.state = t.parse + t.cur.Attr.FG = DefaultFG + t.cur.Attr.BG = DefaultBG + t.Resize(cols, rows) + t.reset() } // Write parses input and writes terminal changes to state. -func (t *VT) Write(p []byte) (int, error) { +func (t *terminal) Write(p []byte) (int, error) { var written int r := bytes.NewReader(p) - t.dest.lock() - defer t.dest.unlock() + t.lock() + defer t.unlock() for { c, sz, err := r.ReadRune() if err != nil { @@ -59,51 +49,43 @@ func (t *VT) Write(p []byte) (int, error) { // not enough bytes for a full rune return written - 1, nil } - t.dest.logln("invalid utf8 sequence") + t.logln("invalid utf8 sequence") continue } - t.dest.put(c) + t.put(c) } return written, nil } -// Close closes the io.ReadWriteCloser. -func (t *VT) Close() error { - return t.rwc.Close() -} - -// Parse blocks on read on pty or io.ReadCloser, then parses sequences until -// buffer empties. State is locked as soon as first rune is read, and unlocked -// when buffer is empty. // TODO: add tests for expected blocking behavior -func (t *VT) Parse() error { +func (t *terminal) Parse(br *bufio.Reader) error { var locked bool defer func() { if locked { - t.dest.unlock() + t.unlock() } }() for { - c, sz, err := t.br.ReadRune() + c, sz, err := br.ReadRune() if err != nil { return err } if c == unicode.ReplacementChar && sz == 1 { - t.dest.logln("invalid utf8 sequence") + t.logln("invalid utf8 sequence") break } if !locked { - t.dest.lock() + t.lock() locked = true } // put rune for parsing and update state - t.dest.put(c) + t.put(c) // break if our buffer is empty, or if buffer contains an // incomplete rune. - n := t.br.Buffered() - if n == 0 || (n < 4 && !fullRuneBuffered(t.br)) { + n := br.Buffered() + if n == 0 || (n < 4 && !fullRuneBuffered(br)) { break } } @@ -119,9 +101,8 @@ func fullRuneBuffered(br *bufio.Reader) bool { return utf8.FullRune(buf) } -// Resize reports new size to pty and updates state. -func (t *VT) Resize(cols, rows int) { - t.dest.lock() - defer t.dest.unlock() - _ = t.dest.resize(cols, rows) +func (t *terminal) Resize(cols, rows int) { + t.lock() + defer t.unlock() + _ = t.resize(cols, rows) } diff --git a/vendor/modules.txt b/vendor/modules.txt index 26cc5f8f8b..3df2cc1ab0 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -32,7 +32,7 @@ contrib.go.opencensus.io/exporter/ocagent # contrib.go.opencensus.io/exporter/prometheus v0.4.0 ## explicit; go 1.13 contrib.go.opencensus.io/exporter/prometheus -# github.com/AlecAivazis/survey/v2 v2.3.2 +# github.com/AlecAivazis/survey/v2 v2.3.5 ## explicit; go 1.13 github.com/AlecAivazis/survey/v2 github.com/AlecAivazis/survey/v2/core @@ -78,8 +78,8 @@ github.com/Azure/go-autorest/tracing ## explicit; go 1.13 github.com/Microsoft/go-winio github.com/Microsoft/go-winio/pkg/guid -# github.com/Netflix/go-expect v0.0.0-20200312175327-da48e75238e2 -## explicit +# github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2 +## explicit; go 1.13 github.com/Netflix/go-expect # github.com/PaesslerAG/gval v1.0.0 ## explicit @@ -339,6 +339,9 @@ github.com/cpuguy83/go-md2man/md2man # github.com/cpuguy83/go-md2man/v2 v2.0.1 ## explicit; go 1.11 github.com/cpuguy83/go-md2man/v2/md2man +# github.com/creack/pty v1.1.17 +## explicit; go 1.13 +github.com/creack/pty # github.com/cyberphone/json-canonicalization v0.0.0-20210823021906-dc406ceaf94b ## explicit github.com/cyberphone/json-canonicalization/go/src/webpki.org/jsoncanonicalizer @@ -855,8 +858,8 @@ github.com/hashicorp/vault/sdk/version # github.com/hashicorp/yamux v0.0.0-20211028200310-0bc27b27de87 ## explicit; go 1.15 github.com/hashicorp/yamux -# github.com/hinshun/vt10x v0.0.0-20180809195222-d55458df857c -## explicit +# github.com/hinshun/vt10x v0.0.0-20220228203356-1ab2cad5fd82 +## explicit; go 1.14 github.com/hinshun/vt10x # github.com/imdario/mergo v0.3.12 ## explicit; go 1.13 @@ -959,9 +962,6 @@ github.com/klauspost/compress/huff0 github.com/klauspost/compress/internal/snapref github.com/klauspost/compress/zstd github.com/klauspost/compress/zstd/internal/xxhash -# github.com/kr/pty v1.1.8 => github.com/creack/pty v1.1.16 -## explicit; go 1.13 -github.com/kr/pty # github.com/ktr0731/go-fuzzyfinder v0.6.0 ## explicit; go 1.13 github.com/ktr0731/go-fuzzyfinder