From 45ce7d8cae2f9267d1207839a27a66b4fb4289e6 Mon Sep 17 00:00:00 2001 From: David Simansky Date: Wed, 3 Apr 2024 19:12:43 +0200 Subject: [PATCH] Update to latest dependecies --- go.mod | 5 +- go.sum | 64 ++- pkg/plugin/plugin.go | 2 +- .../github.com/mitchellh/go-homedir/LICENSE | 21 + .../client-pkg/pkg/{kn => }/plugin/LICENSE | 0 .../github.com/mitchellh/go-homedir/LICENSE | 21 + .../github.com/mitchellh/go-homedir/README.md | 14 + .../mitchellh/go-homedir/homedir.go | 167 ++++++ .../client-pkg/pkg/kn/plugin/types.go | 30 - .../pkg/plugin/context_sharing_types.go | 54 ++ .../client-pkg/pkg/plugin/manager.go | 514 ++++++++++++++++++ .../knative.dev/client-pkg/pkg/plugin/stat.go | 36 ++ .../client-pkg/pkg/plugin/stat_windows.go | 24 + .../client-pkg/pkg/plugin/verify.go | 256 +++++++++ vendor/knative.dev/hack/README.md | 5 + vendor/knative.dev/hack/SECURITY.md | 7 + vendor/knative.dev/hack/go.work.sum | 61 +++ vendor/knative.dev/hack/library.sh | 18 +- vendor/modules.txt | 9 +- 19 files changed, 1254 insertions(+), 54 deletions(-) create mode 100644 third_party/VENDOR-LICENSE/github.com/mitchellh/go-homedir/LICENSE rename third_party/VENDOR-LICENSE/knative.dev/client-pkg/pkg/{kn => }/plugin/LICENSE (100%) create mode 100644 vendor/github.com/mitchellh/go-homedir/LICENSE create mode 100644 vendor/github.com/mitchellh/go-homedir/README.md create mode 100644 vendor/github.com/mitchellh/go-homedir/homedir.go delete mode 100644 vendor/knative.dev/client-pkg/pkg/kn/plugin/types.go create mode 100644 vendor/knative.dev/client-pkg/pkg/plugin/context_sharing_types.go create mode 100644 vendor/knative.dev/client-pkg/pkg/plugin/manager.go create mode 100644 vendor/knative.dev/client-pkg/pkg/plugin/stat.go create mode 100644 vendor/knative.dev/client-pkg/pkg/plugin/stat_windows.go create mode 100644 vendor/knative.dev/client-pkg/pkg/plugin/verify.go create mode 100644 vendor/knative.dev/hack/SECURITY.md create mode 100644 vendor/knative.dev/hack/go.work.sum diff --git a/go.mod b/go.mod index 19d4529a..1d056ade 100644 --- a/go.mod +++ b/go.mod @@ -5,13 +5,14 @@ go 1.21 require ( github.com/spf13/cobra v1.7.0 gotest.tools/v3 v3.3.0 - knative.dev/client-pkg v0.0.0-20240313113642-ca457df5ea78 - knative.dev/hack v0.0.0-20240313135155-b9f6bf0b323b + knative.dev/client-pkg v0.0.0-20240329013337-eff7cfdc981e + knative.dev/hack v0.0.0-20240327150553-47368d631660 ) require ( github.com/google/go-cmp v0.6.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect + github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/spf13/pflag v1.0.5 // indirect ) diff --git a/go.sum b/go.sum index 19e42b38..63ac276e 100644 --- a/go.sum +++ b/go.sum @@ -1,9 +1,27 @@ github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= +github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= +github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I= github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0= @@ -18,14 +36,26 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc= +golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= +golang.org/x/oauth2 v0.18.0 h1:09qnuIAgzdx1XplqJvW6CQqMCtGZykZWcXzPMPUusvI= +golang.org/x/oauth2 v0.18.0/go.mod h1:Wf7knwG0MPoWIMMBgFlEaSUDaKskp0dCfrlJRJXbBi8= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= +golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8= +golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= +golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= @@ -33,11 +63,37 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM= +google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= +google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= +google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= +gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools/v3 v3.3.0 h1:MfDY1b1/0xN1CyMlQDac0ziEy9zJQd9CXBRRDHw2jJo= gotest.tools/v3 v3.3.0/go.mod h1:Mcr9QNxkg0uMvy/YElmo4SpXgJKWgQvYrT7Kw5RzJ1A= -knative.dev/client-pkg v0.0.0-20240313113642-ca457df5ea78 h1:Dyk9poFb3XsKle6bgI3+XoyBZRpKkPXNuZmaw6BcWfE= -knative.dev/client-pkg v0.0.0-20240313113642-ca457df5ea78/go.mod h1:CODwMfQexBzzgB2fv9hYF1+FZfrYc9TF3B26GxW69zQ= -knative.dev/hack v0.0.0-20240313135155-b9f6bf0b323b h1:u2D/mdleFeMwjlnMG4ni7vIcaWio8NeYWYtBJe8C6xE= -knative.dev/hack v0.0.0-20240313135155-b9f6bf0b323b/go.mod h1:yk2OjGDsbEnQjfxdm0/HJKS2WqTLEFg/N6nUs6Rqx3Q= +k8s.io/api v0.29.2 h1:hBC7B9+MU+ptchxEqTNW2DkUosJpp1P+Wn6YncZ474A= +k8s.io/api v0.29.2/go.mod h1:sdIaaKuU7P44aoyyLlikSLayT6Vb7bvJNCX105xZXY0= +k8s.io/apimachinery v0.29.2 h1:EWGpfJ856oj11C52NRCHuU7rFDwxev48z+6DSlGNsV8= +k8s.io/apimachinery v0.29.2/go.mod h1:6HVkd1FwxIagpYrHSwJlQqZI3G9LfYWRPAkUvLnXTKU= +k8s.io/client-go v0.29.2 h1:FEg85el1TeZp+/vYJM7hkDlSTFZ+c5nnK44DJ4FyoRg= +k8s.io/client-go v0.29.2/go.mod h1:knlvFZE58VpqbQpJNbCbctTVXcd35mMyAAwBdpt4jrA= +k8s.io/klog/v2 v2.120.1 h1:QXU6cPEOIslTGvZaXvFWiP9VKyeet3sawzTOvdXb4Vw= +k8s.io/klog/v2 v2.120.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= +k8s.io/utils v0.0.0-20240102154912-e7106e64919e h1:eQ/4ljkx21sObifjzXwlPKpdGLrCfRziVtos3ofG/sQ= +k8s.io/utils v0.0.0-20240102154912-e7106e64919e/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +knative.dev/client-pkg v0.0.0-20240329013337-eff7cfdc981e h1:GAl3ulwQIbvl1x5476zAbqr0ULqk1nvtSGF6XJx7Yoc= +knative.dev/client-pkg v0.0.0-20240329013337-eff7cfdc981e/go.mod h1:PYodo1bmKTrxnNCfLJa6a8wdg3QQH0XTOPlZJwrY64A= +knative.dev/hack v0.0.0-20240327150553-47368d631660 h1:tW6NgyjMnSXBS75+k+Xh5uNiLhJ9TFswS9hrkC3OQOc= +knative.dev/hack v0.0.0-20240327150553-47368d631660/go.mod h1:yk2OjGDsbEnQjfxdm0/HJKS2WqTLEFg/N6nUs6Rqx3Q= +knative.dev/pkg v0.0.0-20240325103648-fd7cc2153e6a h1:17E1oL6VhFTZBmgF4D3DlHt+GH8y9MQNlGCM60Db7fY= +knative.dev/pkg v0.0.0-20240325103648-fd7cc2153e6a/go.mod h1:Meb7JQFjMOloRJRA2GG2RcRT/JnscMOI8/6KmBaC2/k= +sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= +sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= +sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4= +sigs.k8s.io/structured-merge-diff/v4 v4.4.1/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08= +sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= +sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= diff --git a/pkg/plugin/plugin.go b/pkg/plugin/plugin.go index b59a8f11..1fa78a9d 100644 --- a/pkg/plugin/plugin.go +++ b/pkg/plugin/plugin.go @@ -19,7 +19,7 @@ import ( "knative.dev/kn-plugin-quickstart/internal/root" - knplugin "knative.dev/client-pkg/pkg/kn/plugin" + knplugin "knative.dev/client-pkg/pkg/plugin" ) func init() { diff --git a/third_party/VENDOR-LICENSE/github.com/mitchellh/go-homedir/LICENSE b/third_party/VENDOR-LICENSE/github.com/mitchellh/go-homedir/LICENSE new file mode 100644 index 00000000..f9c841a5 --- /dev/null +++ b/third_party/VENDOR-LICENSE/github.com/mitchellh/go-homedir/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2013 Mitchell Hashimoto + +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/third_party/VENDOR-LICENSE/knative.dev/client-pkg/pkg/kn/plugin/LICENSE b/third_party/VENDOR-LICENSE/knative.dev/client-pkg/pkg/plugin/LICENSE similarity index 100% rename from third_party/VENDOR-LICENSE/knative.dev/client-pkg/pkg/kn/plugin/LICENSE rename to third_party/VENDOR-LICENSE/knative.dev/client-pkg/pkg/plugin/LICENSE diff --git a/vendor/github.com/mitchellh/go-homedir/LICENSE b/vendor/github.com/mitchellh/go-homedir/LICENSE new file mode 100644 index 00000000..f9c841a5 --- /dev/null +++ b/vendor/github.com/mitchellh/go-homedir/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2013 Mitchell Hashimoto + +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/mitchellh/go-homedir/README.md b/vendor/github.com/mitchellh/go-homedir/README.md new file mode 100644 index 00000000..d70706d5 --- /dev/null +++ b/vendor/github.com/mitchellh/go-homedir/README.md @@ -0,0 +1,14 @@ +# go-homedir + +This is a Go library for detecting the user's home directory without +the use of cgo, so the library can be used in cross-compilation environments. + +Usage is incredibly simple, just call `homedir.Dir()` to get the home directory +for a user, and `homedir.Expand()` to expand the `~` in a path to the home +directory. + +**Why not just use `os/user`?** The built-in `os/user` package requires +cgo on Darwin systems. This means that any Go code that uses that package +cannot cross compile. But 99% of the time the use for `os/user` is just to +retrieve the home directory, which we can do for the current user without +cgo. This library does that, enabling cross-compilation. diff --git a/vendor/github.com/mitchellh/go-homedir/homedir.go b/vendor/github.com/mitchellh/go-homedir/homedir.go new file mode 100644 index 00000000..25378537 --- /dev/null +++ b/vendor/github.com/mitchellh/go-homedir/homedir.go @@ -0,0 +1,167 @@ +package homedir + +import ( + "bytes" + "errors" + "os" + "os/exec" + "path/filepath" + "runtime" + "strconv" + "strings" + "sync" +) + +// DisableCache will disable caching of the home directory. Caching is enabled +// by default. +var DisableCache bool + +var homedirCache string +var cacheLock sync.RWMutex + +// Dir returns the home directory for the executing user. +// +// This uses an OS-specific method for discovering the home directory. +// An error is returned if a home directory cannot be detected. +func Dir() (string, error) { + if !DisableCache { + cacheLock.RLock() + cached := homedirCache + cacheLock.RUnlock() + if cached != "" { + return cached, nil + } + } + + cacheLock.Lock() + defer cacheLock.Unlock() + + var result string + var err error + if runtime.GOOS == "windows" { + result, err = dirWindows() + } else { + // Unix-like system, so just assume Unix + result, err = dirUnix() + } + + if err != nil { + return "", err + } + homedirCache = result + return result, nil +} + +// Expand expands the path to include the home directory if the path +// is prefixed with `~`. If it isn't prefixed with `~`, the path is +// returned as-is. +func Expand(path string) (string, error) { + if len(path) == 0 { + return path, nil + } + + if path[0] != '~' { + return path, nil + } + + if len(path) > 1 && path[1] != '/' && path[1] != '\\' { + return "", errors.New("cannot expand user-specific home dir") + } + + dir, err := Dir() + if err != nil { + return "", err + } + + return filepath.Join(dir, path[1:]), nil +} + +// Reset clears the cache, forcing the next call to Dir to re-detect +// the home directory. This generally never has to be called, but can be +// useful in tests if you're modifying the home directory via the HOME +// env var or something. +func Reset() { + cacheLock.Lock() + defer cacheLock.Unlock() + homedirCache = "" +} + +func dirUnix() (string, error) { + homeEnv := "HOME" + if runtime.GOOS == "plan9" { + // On plan9, env vars are lowercase. + homeEnv = "home" + } + + // First prefer the HOME environmental variable + if home := os.Getenv(homeEnv); home != "" { + return home, nil + } + + var stdout bytes.Buffer + + // If that fails, try OS specific commands + if runtime.GOOS == "darwin" { + cmd := exec.Command("sh", "-c", `dscl -q . -read /Users/"$(whoami)" NFSHomeDirectory | sed 's/^[^ ]*: //'`) + cmd.Stdout = &stdout + if err := cmd.Run(); err == nil { + result := strings.TrimSpace(stdout.String()) + if result != "" { + return result, nil + } + } + } else { + cmd := exec.Command("getent", "passwd", strconv.Itoa(os.Getuid())) + cmd.Stdout = &stdout + if err := cmd.Run(); err != nil { + // If the error is ErrNotFound, we ignore it. Otherwise, return it. + if err != exec.ErrNotFound { + return "", err + } + } else { + if passwd := strings.TrimSpace(stdout.String()); passwd != "" { + // username:password:uid:gid:gecos:home:shell + passwdParts := strings.SplitN(passwd, ":", 7) + if len(passwdParts) > 5 { + return passwdParts[5], nil + } + } + } + } + + // If all else fails, try the shell + stdout.Reset() + cmd := exec.Command("sh", "-c", "cd && pwd") + cmd.Stdout = &stdout + if err := cmd.Run(); err != nil { + return "", err + } + + result := strings.TrimSpace(stdout.String()) + if result == "" { + return "", errors.New("blank output when reading home directory") + } + + return result, nil +} + +func dirWindows() (string, error) { + // First prefer the HOME environmental variable + if home := os.Getenv("HOME"); home != "" { + return home, nil + } + + // Prefer standard environment variable USERPROFILE + if home := os.Getenv("USERPROFILE"); home != "" { + return home, nil + } + + drive := os.Getenv("HOMEDRIVE") + path := os.Getenv("HOMEPATH") + home := drive + path + if drive == "" || path == "" { + return "", errors.New("HOMEDRIVE, HOMEPATH, or USERPROFILE are blank") + } + + return home, nil +} diff --git a/vendor/knative.dev/client-pkg/pkg/kn/plugin/types.go b/vendor/knative.dev/client-pkg/pkg/kn/plugin/types.go deleted file mode 100644 index 1d740b9a..00000000 --- a/vendor/knative.dev/client-pkg/pkg/kn/plugin/types.go +++ /dev/null @@ -1,30 +0,0 @@ -package plugin - -// Allow plugins to register to this slice for inlining -var InternalPlugins PluginList - -// Interface describing a plugin -type Plugin interface { - // Get the name of the plugin (the file name without extensions) - Name() string - - // Execute the plugin with the given arguments - Execute(args []string) error - - // Return a description of the plugin (if support by the plugin binary) - Description() (string, error) - - // The command path leading to this plugin. - // Eg. for a plugin "kn source github" this will be [ "source", "github" ] - CommandParts() []string - - // Location of the plugin where it is stored in the filesystem - Path() string -} - -// Used for sorting a list of plugins -type PluginList []Plugin - -func (p PluginList) Len() int { return len(p) } -func (p PluginList) Less(i, j int) bool { return p[i].Name() < p[j].Name() } -func (p PluginList) Swap(i, j int) { p[i], p[j] = p[j], p[i] } diff --git a/vendor/knative.dev/client-pkg/pkg/plugin/context_sharing_types.go b/vendor/knative.dev/client-pkg/pkg/plugin/context_sharing_types.go new file mode 100644 index 00000000..f36fa6e3 --- /dev/null +++ b/vendor/knative.dev/client-pkg/pkg/plugin/context_sharing_types.go @@ -0,0 +1,54 @@ +// Copyright © 2023 The Knative Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package plugin + +// Manifest represents plugin metadata +type Manifest struct { + // Path to external plugin binary. Always empty for inlined plugins. + Path string `json:"path,omitempty"` + + // Plugin declares its own manifest to be included in Context Sharing feature + HasManifest bool `json:"hasManifest"` + + // ProducesContextDataKeys is a list of keys for the ContextData that + // a plugin can produce. Nil or an empty list declares that this + // plugin is not ContextDataProducer + ProducesContextDataKeys []string `json:"producesKeys,omitempty"` + + // ConsumesContextDataKeys is a list of keys from a ContextData that a + // plugin is interested in to consume. Nil or an empty list declares + // that this plugin is not a ContextDataConsumer + ConsumesContextDataKeys []string `json:"consumesKeys,omitempty"` +} + +// PluginWithManifest represents extended plugin support for Manifest and Context Sharing feature +type PluginWithManifest interface { + // Plugin original interface wrapper + Plugin + + // GetManifest returns a metadata descriptor of plugin + GetManifest() *Manifest + + // GetContextData returns a map structure that is used to share common context data from plugin + GetContextData() map[string]string + + // ExecuteWithContextData an extended version of plugin.Execute command to allow injection and use of ContextData. + // This is a map[string]string structure to share common value service name between kn and plugins. + ExecuteWithContextData(ctx map[string]string, args []string) error + // Alternative impl: use of native context.Context as a data structure. + // We decided to use plain map, because Context can't be extended to external plugins anyway. + // Another encode to JSON is required to pass it. We might reconsider that in future development iterations. + +} diff --git a/vendor/knative.dev/client-pkg/pkg/plugin/manager.go b/vendor/knative.dev/client-pkg/pkg/plugin/manager.go new file mode 100644 index 00000000..007404ca --- /dev/null +++ b/vendor/knative.dev/client-pkg/pkg/plugin/manager.go @@ -0,0 +1,514 @@ +// Copyright © 2020 The Knative Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package plugin + +import ( + "errors" + "fmt" + "os" + "os/exec" + "path/filepath" + "runtime" + "sort" + "strings" + "text/template" + + homedir "github.com/mitchellh/go-homedir" + "github.com/spf13/cobra" +) + +// Allow plugins to register to this slice for inlining +var InternalPlugins PluginList + +// Interface describing a plugin +type Plugin interface { + // Get the name of the plugin (the file name without extensions) + Name() string + + // Execute the plugin with the given arguments + Execute(args []string) error + + // Return a description of the plugin (if support by the plugin binary) + Description() (string, error) + + // The command path leading to this plugin. + // Eg. for a plugin "kn source github" this will be [ "source", "github" ] + CommandParts() []string + + // Location of the plugin where it is stored in the filesystem + Path() string +} + +type ContextData map[string]string + +type PluginManifest struct { + // ProducesContextDataKeys is a list of keys for the ContextData that + // a plugin can produce. Nil or an empty list declares that this + // plugin is not ContextDataProducer + ProducesContextDataKeys []string + + // ConsumesContextDataKeys is a list of keys from a ContextData that a + // plugin is interested in to consume. Nil or an empty list declares + // that this plugin is not a ContextDataConsumer + ConsumesContextDataKeys []string +} + +type ContextDataConsumer interface { + // ExecuteWithContextData executes the plugin with the given args much like + // Execute() but with an additional argument that holds the ContextData + ExecuteWithContextData(args []string, data ContextData) error +} + +type Manager struct { + // Dedicated plugin directory as configured + pluginsDir string + + // Whether to check the OS path or not + lookupInPath bool +} + +type plugin struct { + // Path to the plugin to execute + path string + + // Name of the plugin + name string + + // Commands leading to the execution of this plugin (e.g. "service","log" for a plugin kn-service-log) + commandParts []string +} + +// All extensions that are supposed to be windows executable +var windowsExecExtensions = []string{".bat", ".cmd", ".com", ".exe", ".ps1"} + +// Used for sorting a list of plugins +type PluginList []Plugin + +func (p PluginList) Len() int { return len(p) } +func (p PluginList) Less(i, j int) bool { return p[i].Name() < p[j].Name() } +func (p PluginList) Swap(i, j int) { p[i], p[j] = p[j], p[i] } + +// === PluginManager ======================================================================= + +// NewManager creates a new manager for looking up plugins on the file system +func NewManager(pluginDir string, lookupInPath bool) *Manager { + return &Manager{ + pluginsDir: pluginDir, + lookupInPath: lookupInPath, + } +} + +// FindPlugin checks if a plugin for the given parts exist and return it. +// The args given must not contain any options and contain only +// the commands (like in [ "source", "github" ] for a plugin called 'kn-source-github' +// The plugin with the most specific (longest) name is returned or nil if non is found. +// An error is returned if the lookup fails for some reason like an io error +func (manager *Manager) FindPlugin(parts []string) (Plugin, error) { + if len(parts) == 0 { + // No command given + return nil, nil + } + + // Try to find internal plugin fist + plugin := lookupInternalPlugin(parts) + if plugin != nil { + return plugin, nil + } + + // Try to find plugin in pluginsDir + pluginDir, err := homedir.Expand(manager.pluginsDir) + if err != nil { + return nil, err + } + + return findMostSpecificPluginInPath(pluginDir, parts, manager.lookupInPath) +} + +// ListPlugins lists all plugins that can be found in the plugin directory or in the path (if configured) +func (manager *Manager) ListPlugins() (PluginList, error) { + return manager.ListPluginsForCommandGroup(nil) +} + +// ListPluginsForCommandGroup lists all plugins that can be found in the plugin directory or in the path (if configured), +// and which fits to a command group +func (manager *Manager) ListPluginsForCommandGroup(commandGroupParts []string) (PluginList, error) { + + // Initialize with list of internal plugins + var plugins = append([]Plugin{}, filterPluginsByCommandGroup(InternalPlugins, commandGroupParts)...) + + dirs, err := manager.pluginLookupDirectories() + if err != nil { + return nil, err + } + + // Examine all files in possible plugin directories + hasSeen := make(map[string]bool) + for _, pl := range plugins { + hasSeen[pl.Name()] = true + } + for _, dir := range dirs { + files, err := os.ReadDir(dir) + + // Ignore non-existing directories + if os.IsNotExist(err) { + continue + } + + // Check for plugins within given directory + for _, f := range files { + name := f.Name() + if f.IsDir() { + continue + } + if !strings.HasPrefix(name, "kn-") { + continue + } + + // Check if plugin matches a command group + if !isPluginFileNamePartOfCommandGroup(commandGroupParts, f.Name()) { + continue + } + + // Ignore all plugins that are shadowed + if seen, ok := hasSeen[name]; !ok || !seen { + plugins = append(plugins, &plugin{ + path: filepath.Join(dir, f.Name()), + name: stripWindowsExecExtensions(f.Name()), + commandParts: extractPluginCommandFromFileName(f.Name()), + }) + hasSeen[name] = true + } + } + } + + // Sort according to name + sort.Sort(PluginList(plugins)) + return plugins, nil +} + +func filterPluginsByCommandGroup(plugins PluginList, commandGroupParts []string) PluginList { + ret := PluginList{} + for _, pl := range plugins { + if isPartOfCommandGroup(commandGroupParts, pl.CommandParts()) { + ret = append(ret, pl) + } + } + return ret +} + +func isPartOfCommandGroup(commandGroupParts []string, commandParts []string) bool { + if len(commandParts) != len(commandGroupParts)+1 { + return false + } + for i := range commandGroupParts { + if commandParts[i] != commandGroupParts[i] { + return false + } + } + return true +} + +func isPluginFileNamePartOfCommandGroup(commandGroupParts []string, pluginFileName string) bool { + if commandGroupParts == nil { + return true + } + + commandParts := extractPluginCommandFromFileName(pluginFileName) + if len(commandParts) != len(commandGroupParts)+1 { + return false + } + for i := range commandGroupParts { + if commandParts[i] != commandGroupParts[i] { + return false + } + } + return true +} + +// PluginsDir returns the configured directory holding plugins +func (manager *Manager) PluginsDir() string { + return manager.pluginsDir +} + +// LookupInPath returns true if plugins should be also looked up within the path +func (manager *Manager) LookupInPath() bool { + return manager.lookupInPath +} + +// === Plugin ============================================================================== + +// Execute the plugin with the given arguments +func (plugin *plugin) Execute(args []string) error { + //nolint:gosec // Passing the arguments through is expected, the plugins are trusted. + cmd := exec.Command(plugin.path, args...) + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + cmd.Stdin = os.Stdin + cmd.Env = os.Environ() + return cmd.Run() +} + +// Return a description of the plugin (if support by the plugin binary) +func (plugin *plugin) Description() (string, error) { + // TODO: Call out to the plugin to find a description. + // For now just use the path to the plugin + return plugin.path, nil + // return strings.Join(plugin.commandParts, "-"), nil +} + +// The the command path leading to this plugin. +// Eg. for a plugin "kn source github" this will be [ "source", "github" ] +func (plugin *plugin) CommandParts() []string { + return plugin.commandParts +} + +// Return the path to the plugin +func (plugin *plugin) Path() string { + return plugin.path +} + +// Name of the plugin +func (plugin *plugin) Name() string { + return plugin.name +} + +// ========================================================================================= + +// Find out all directories that might hold a plugin +func (manager *Manager) pluginLookupDirectories() ([]string, error) { + pluginPath, err := homedir.Expand(manager.pluginsDir) + if err != nil { + return nil, err + } + dirs := []string{pluginPath} + if manager.lookupInPath { + dirs = append(dirs, filepath.SplitList(os.Getenv("PATH"))...) + } + dirs = uniquePathsList(dirs) + return dirs, nil +} + +// HelpTemplateFuncs returns a function map which can be used in templates for resolving +// plugin related help messages +func (manager *Manager) HelpTemplateFuncs() *template.FuncMap { + ret := template.FuncMap{ + "listPlugins": manager.listPluginsHelpMessage(), + } + + return &ret +} + +// listPluginsHelpMessage returns a function which returns all plugins that are directly below the given +// command as a properly formatted string +func (manager *Manager) listPluginsHelpMessage() func(cmd *cobra.Command) string { + return func(cmd *cobra.Command) string { + if !cmd.HasSubCommands() { + return "" + } + list, err := manager.ListPluginsForCommandGroup(extractCommandGroup(cmd, []string{})) + if err != nil || len(list) == 0 { + // We don't show plugins if there is an error + return "" + } + var plugins []string + for _, pl := range list { + t := fmt.Sprintf(" %%-%ds %%s", cmd.NamePadding()) + desc, _ := pl.Description() + command := (pl.CommandParts())[len(pl.CommandParts())-1] + help := fmt.Sprintf(t, command, desc) + plugins = append(plugins, help) + } + return strings.Join(plugins, "\n") + } +} + +// extractCommandGroup constructs the command path as array of strings +func extractCommandGroup(cmd *cobra.Command, parts []string) []string { + if cmd.HasParent() { + parts = extractCommandGroup(cmd.Parent(), parts) + parts = append(parts, cmd.Name()) + } + return parts +} + +// uniquePathsList deduplicates a given slice of strings without +// sorting or otherwise altering its order in any way. +func uniquePathsList(paths []string) []string { + seen := map[string]bool{} + newPaths := make([]string, 0, len(paths)) + for _, p := range paths { + if seen[p] { + continue + } + seen[p] = true + newPaths = append(newPaths, p) + } + return newPaths +} + +// Split up a command name, discard the initial prefix ("kn-") and convert +// parts to command syntax (i.e. replace _ with -) +func extractPluginCommandFromFileName(name string) []string { + // Remove extension on windows + name = stripWindowsExecExtensions(name) + parts := strings.Split(name, "-") + if len(parts) < 1 { + return []string{} + } + ret := make([]string, 0, len(parts)-1) + for _, p := range parts[1:] { + ret = append(ret, convertUnderscoreToDash(p)) + } + return ret +} + +// Strip any extension that indicates an EXE on Windows +func stripWindowsExecExtensions(name string) string { + if runtime.GOOS == "windows" { + ext := filepath.Ext(name) + if len(ext) > 0 { + for _, e := range windowsExecExtensions { + if ext == e { + name = name[:len(name)-len(ext)] + break + } + } + } + } + return name +} + +// Return the path and the parts building the most specific plugin in the given directory +// If lookupInPath is true, then also the OS PATH is checked. +// An error returned if any IO operation fails +func findMostSpecificPluginInPath(dir string, parts []string, lookupInPath bool) (Plugin, error) { + for i := len(parts); i > 0; i-- { + + // Construct plugin name to lookup + var nameParts []string + var commandParts []string + for _, p := range parts[0:i] { + // for arguments that contain the path separator, + // stop the loop once the separator appears + if strings.Contains(p, string(os.PathSeparator)) { + break + } + // Subcommands with "-" are translated to "_" + // (e.g. a command "kn log-all" is translated to a plugin "kn-log_all") + nameParts = append(nameParts, convertDashToUnderscore(p)) + commandParts = append(commandParts, p) + } + name := fmt.Sprintf("kn-%s", strings.Join(nameParts, "-")) + + // Check for the name in plugin directory and PATH (if requested) + path, err := findInDirOrPath(name, dir, lookupInPath) + if err != nil { + return nil, fmt.Errorf("cannot lookup plugin %s in directory %s (lookup in path: %t): %w", name, dir, lookupInPath, err) + } + + // Found, return it + if path != "" { + return &plugin{ + path: path, + commandParts: commandParts, + name: name, + }, nil + } + } + + // Nothing found + return nil, nil +} + +// convertDashToUnderscore converts from the command name to the file name +func convertDashToUnderscore(p string) string { + return strings.Replace(p, "-", "_", -1) +} + +// convertUnderscoreToDash converts from the filename to the command name +func convertUnderscoreToDash(p string) string { + return strings.Replace(p, "_", "-", -1) +} + +// Find a command with name in the given directory or on the execution PATH (if lookupInPath is true) +// On Windows, also check well known extensions for executables +// Return the full path found or "" if none has found +// Return an error on any IO error. +func findInDirOrPath(name string, dir string, lookupInPath bool) (string, error) { + + exts := []string{""} + if runtime.GOOS == "windows" { + // Add also well known extensions for windows + exts = append(exts, windowsExecExtensions...) + } + + for _, ext := range exts { + nameExt := name + ext + + // Check plugin dir first + path := filepath.Join(dir, nameExt) + _, err := os.Stat(path) + if err == nil { + // Found in dir + return path, nil + } + if !os.IsNotExist(err) { + return "", fmt.Errorf("i/o error while reading %s: %w", path, err) + } + + // Check in PATH if requested + if lookupInPath { + path, err = exec.LookPath(name) + if err == nil { + // Found in path + return path, nil + } + if !errors.Is(err, exec.ErrNotFound) { + return "", fmt.Errorf("error for looking up %s in path: %w", name, err) + } + } + } + + // Not found + return "", nil +} + +// lookupInternalPlugin looks up internally registered plugins. Return nil if none is found. +// Start with longest argument path first to find the most specific match +func lookupInternalPlugin(parts []string) Plugin { + for i := len(parts); i > 0; i-- { + checkParts := parts[0:i] + for _, plugin := range InternalPlugins { + if equalsSlice(plugin.CommandParts(), checkParts) { + return plugin + } + } + } + return nil +} + +// equalsSlice return true if two string slices contain the same elements +func equalsSlice(a, b []string) bool { + if len(a) != len(b) || len(a) == 0 { + return false + } + + for i := range a { + if a[i] != b[i] { + return false + } + } + return true +} diff --git a/vendor/knative.dev/client-pkg/pkg/plugin/stat.go b/vendor/knative.dev/client-pkg/pkg/plugin/stat.go new file mode 100644 index 00000000..d7cd7a19 --- /dev/null +++ b/vendor/knative.dev/client-pkg/pkg/plugin/stat.go @@ -0,0 +1,36 @@ +// Copyright © 2019 The Knative Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//go:build !windows +// +build !windows + +package plugin + +// This file doesn't compile for Windows platform, therefor a second stat_windows.go is +// added with a no-op + +import ( + "fmt" + "os" + "syscall" +) + +func statFileOwner(fileInfo os.FileInfo) (uint32, uint32, error) { + var sys *syscall.Stat_t + var ok bool + if sys, ok = fileInfo.Sys().(*syscall.Stat_t); !ok { + return 0, 0, fmt.Errorf("cannot check owner/group of file %s", fileInfo.Name()) + } + return sys.Uid, sys.Gid, nil +} diff --git a/vendor/knative.dev/client-pkg/pkg/plugin/stat_windows.go b/vendor/knative.dev/client-pkg/pkg/plugin/stat_windows.go new file mode 100644 index 00000000..8a0af80f --- /dev/null +++ b/vendor/knative.dev/client-pkg/pkg/plugin/stat_windows.go @@ -0,0 +1,24 @@ +// Copyright © 2019 The Knative Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package plugin + +import ( + "os" +) + +// statFileOwner is a no-op on windows +func statFileOwner(fileInfo os.FileInfo) (uint32, uint32, error) { + return 0, 0, nil +} diff --git a/vendor/knative.dev/client-pkg/pkg/plugin/verify.go b/vendor/knative.dev/client-pkg/pkg/plugin/verify.go new file mode 100644 index 00000000..5f5a03ce --- /dev/null +++ b/vendor/knative.dev/client-pkg/pkg/plugin/verify.go @@ -0,0 +1,256 @@ +// Copyright © 2019 The Knative Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package plugin + +import ( + "errors" + "fmt" + "io" + "os" + "path/filepath" + "runtime" + "strings" +) + +// Collection of errors and warning collected during verifications +type VerificationErrorsAndWarnings struct { + Errors []string + Warnings []string +} + +// permission bits for execute +const ( + UserExecute = 1 << 6 + GroupExecute = 1 << 3 + OtherExecute = 1 << 0 +) + +// Verification of a ll plugins. This method returns all errors and warnings +// for the verification. The following criteria are verified (for each plugin): +// * If the plugin is executable +// * If the plugin is overshadowed by a previous plugin +func (manager *Manager) Verify() VerificationErrorsAndWarnings { + eaw := VerificationErrorsAndWarnings{} + + dirs, err := manager.pluginLookupDirectories() + if err != nil { + return eaw.AddError("cannot lookup plugin directories: %v", err) + } + + // Examine all files in possible plugin directories + + seenPlugins := make(map[string]string) + for _, dir := range dirs { + files, err := os.ReadDir(dir) + + // Ignore non-existing directories + if os.IsNotExist(err) { + continue + } + + if err != nil { + eaw.AddError("unable to read directory '%s' from your plugin path: %v", dir, err) + continue + } + + for _, f := range files { + if f.IsDir() { + continue + } + if !strings.HasPrefix(f.Name(), "kn-") { + continue + } + eaw = verifyPath(filepath.Join(dir, f.Name()), seenPlugins, eaw) + } + } + return eaw +} + +func verifyPath(path string, seenPlugins map[string]string, eaw VerificationErrorsAndWarnings) VerificationErrorsAndWarnings { + + // Verify that plugin actually exists + fileInfo, err := os.Stat(path) + if err != nil { + if errors.Is(err, os.ErrNotExist) { + return eaw.AddError("cannot find plugin in %s", path) + } + return eaw.AddError("cannot stat %s: %v", path, err) + } + + eaw = addWarningIfNotExecutable(eaw, path, fileInfo) + eaw = addWarningIfAlreadySeen(eaw, seenPlugins, path) + + // Remember each verified plugin for duplicate check + seenPlugins[filepath.Base(path)] = path + + return eaw +} + +func addWarningIfNotExecutable(eaw VerificationErrorsAndWarnings, path string, fileInfo os.FileInfo) VerificationErrorsAndWarnings { + if runtime.GOOS == "windows" { + return checkForWindowsExecutable(eaw, fileInfo, path) + } + + mode := fileInfo.Mode() + if !mode.IsRegular() && !isSymlink(mode) { + return eaw.AddWarning("%s is not a file", path) + } + perms := uint32(mode.Perm()) + + uid, gid, err := statFileOwner(fileInfo) + if err != nil { + return eaw.AddWarning("%s", err.Error()) + } + isOwner := checkIfUserIsFileOwner(uid) + isInGroup, err := checkIfUserInGroup(gid) + if err != nil { + return eaw.AddError("cannot get group ids for checking executable status of file %s", path) + } + + // User is owner and owner can execute + if canOwnerExecute(perms, isOwner) { + return eaw + } + + // User is in group which can execute, but user is not file owner + if canGroupExecute(perms, isOwner, isInGroup) { + return eaw + } + + // All can execute, and the user is not file owner and not in the file's perm group + if canOtherExecute(perms, isOwner, isInGroup) { + return eaw + } + + return eaw.AddWarning("%s is not executable by current user", path) +} + +func addWarningIfAlreadySeen(eaw VerificationErrorsAndWarnings, seenPlugins map[string]string, path string) VerificationErrorsAndWarnings { + fileName := filepath.Base(path) + if existingPath, ok := seenPlugins[fileName]; ok { + return eaw.AddWarning("%s is ignored because it is shadowed by an equally named plugin: %s", path, existingPath) + } + return eaw +} + +func checkForWindowsExecutable(eaw VerificationErrorsAndWarnings, fileInfo os.FileInfo, path string) VerificationErrorsAndWarnings { + name := fileInfo.Name() + nameWithoutExecExtension := stripWindowsExecExtensions(name) + + if name == nameWithoutExecExtension { + return eaw.AddWarning("%s is not executable as it does not have a Windows exec extension (one of %s)", path, strings.Join(windowsExecExtensions, ", ")) + } + return eaw +} + +func checkIfUserInGroup(gid uint32) (bool, error) { + groups, err := os.Getgroups() + if err != nil { + return false, err + } + for _, g := range groups { + if int(gid) == g { + return true, nil + } + } + return false, nil +} + +func checkIfUserIsFileOwner(uid uint32) bool { + return int(uid) == os.Getuid() +} + +// Check if all can execute, and the user is not file owner and not in the file's perm group +func canOtherExecute(perms uint32, isOwner bool, isInGroup bool) bool { + if perms&OtherExecute != 0 { + if os.Getuid() == 0 { + return true + } + if !isOwner && !isInGroup { + return true + } + } + return false +} + +// Check if user is owner and owner can execute +func canOwnerExecute(perms uint32, isOwner bool) bool { + if perms&UserExecute != 0 { + if os.Getuid() == 0 { + return true + } + if isOwner { + return true + } + } + return false +} + +// Check if user is in group which can execute, but user is not file owner +func canGroupExecute(perms uint32, isOwner bool, isInGroup bool) bool { + if perms&GroupExecute != 0 { + if os.Getuid() == 0 { + return true + } + if !isOwner && isInGroup { + return true + } + } + return false +} + +func (eaw *VerificationErrorsAndWarnings) AddError(format string, args ...interface{}) VerificationErrorsAndWarnings { + eaw.Errors = append(eaw.Errors, fmt.Sprintf(format, args...)) + return *eaw +} + +func (eaw *VerificationErrorsAndWarnings) AddWarning(format string, args ...interface{}) VerificationErrorsAndWarnings { + eaw.Warnings = append(eaw.Warnings, fmt.Sprintf(format, args...)) + return *eaw +} + +func (eaw *VerificationErrorsAndWarnings) PrintWarningsAndErrors(out io.Writer) { + printSection(out, "ERROR", eaw.Errors) + printSection(out, "WARNING", eaw.Warnings) +} + +func (eaw *VerificationErrorsAndWarnings) HasErrors() bool { + return len(eaw.Errors) > 0 +} + +func (eaw *VerificationErrorsAndWarnings) IsEmpty() bool { + return len(eaw.Errors)+len(eaw.Warnings) == 0 +} + +func printSection(out io.Writer, label string, values []string) { + if len(values) > 0 { + printLabelWithConditionalPluralS(out, label, len(values)) + for _, value := range values { + fmt.Fprintf(out, " - %s\n", value) + } + } +} + +func printLabelWithConditionalPluralS(out io.Writer, label string, nr int) { + if nr == 1 { + fmt.Fprintf(out, "%s:\n", label) + } else { + fmt.Fprintf(out, "%ss:\n", label) + } +} + +func isSymlink(mode os.FileMode) bool { + return mode&os.ModeSymlink != 0 +} diff --git a/vendor/knative.dev/hack/README.md b/vendor/knative.dev/hack/README.md index 8799e0b5..fd9c4d99 100644 --- a/vendor/knative.dev/hack/README.md +++ b/vendor/knative.dev/hack/README.md @@ -3,6 +3,11 @@ `hack` is a collection of scripts used to bootstrap CI processes and other vital entrypoint functionality. +## Contributing + +If you are interested in contributing to Knative, take a look at [CLOTRIBUTOR](https://clotributor.dev/search?project=knative&page=1) +for a list of help wanted issues across the project. + ## Using the `presubmit-tests.sh` helper script This is a helper script to run the presubmit tests. To use it: diff --git a/vendor/knative.dev/hack/SECURITY.md b/vendor/knative.dev/hack/SECURITY.md new file mode 100644 index 00000000..52ec3c9f --- /dev/null +++ b/vendor/knative.dev/hack/SECURITY.md @@ -0,0 +1,7 @@ +# Knative Security Policy + +We're extremely grateful for security researchers and users that report vulnerabilities to the Knative Open Source Community. All reports are thoroughly investigated by a set of community volunteers. + +To make a report, please email the private security@knative.team list with the security details and the details expected for all Knative bug reports. + +See [Knative Security and Disclosure Information](https://knative.dev/docs/reference/security/) for more details. diff --git a/vendor/knative.dev/hack/go.work.sum b/vendor/knative.dev/hack/go.work.sum new file mode 100644 index 00000000..1cc0cde9 --- /dev/null +++ b/vendor/knative.dev/hack/go.work.sum @@ -0,0 +1,61 @@ +cloud.google.com/go v0.26.0 h1:e0WKqKTd5BnrG8aKH3J3h+QvEIQtSUcf2n5UZ5ZgLtQ= +github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= +github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46 h1:lsxEuwrXEAokXB9qhlbKWPpo3KMLZQ5WB5WLQRW1uq0= +github.com/PuerkitoBio/purell v1.0.0 h1:0GoNN3taZV6QI81IXgCbxMyEaJDXMSIjArYBCYzVVvs= +github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2 h1:JCHLVE3B+kJde7bIEo5N4J+ZbLhp0J1Fs+ulyRws4gE= +github.com/census-instrumentation/opencensus-proto v0.2.1 h1:glEXhBS5PSLLv4IXzLA5yPRVX4bilULVyxxbrfOtDAk= +github.com/client9/misspell v0.3.4 h1:ta993UF76GwbvJcIo3Y68y/M3WxlpEHPWIGDkJYwzJI= +github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= +github.com/creack/pty v1.1.9 h1:uDmaGzcdjhF4i/plgjmEsriH11Y0o7RKapEf/LDaM3w= +github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96 h1:cenwrSVm+Z7QLSV/BsnenAOcDXdX4cMv4wP0B/5QbPg= +github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815 h1:bWDMxwH3px2JBh6AyO7hdCn/PkvCZXii8TGj7sbtEbQ= +github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153 h1:yUdfgN0XgIJw7foRItutHYUIhlcKzcSf5vDpdhQAKTc= +github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633 h1:H2pdYOb3KQ1/YsqVWoWNLQO+fusocsw354rqGTZtAgw= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473 h1:4cmBvAEBNJaGARUEs3/suWRyfyBfhf7I60WBZq+bv2w= +github.com/envoyproxy/protoc-gen-validate v0.1.0 h1:EQciDnbrYxy13PgWoY8AqoxGiPrpgBZ1R8UNe3ddc+A= +github.com/evanphx/json-patch v4.9.0+incompatible h1:kLcOMZeuLAJvL2BPWLMIj5oaZQobrkAqrL+WFZwQses= +github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= +github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680 h1:ZktWZesgun21uEDrwW7iEV1zPCGQldM2atlJZ3TdvVM= +github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1 h1:wSt/4CYxs70xbATrGXhokKF1i0tZjENLOo1ioIO13zk= +github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9 h1:tF+augKRWlWx0J0B7ZyyKSiTyV6E1zZe+7b3qQlcEf8= +github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501 h1:C1JKChikHGpXwT5UQDFaryIpDtyyGL/CR6C2kB7F1oc= +github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87 h1:zP3nY8Tk2E6RTkqGYrarZXuzh+ffyLDljLxCy1iJw80= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= +github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7 h1:5ZkaAPbicIKTF2I64qf5Fh8Aa83Q/dnOafMYV0OMwjA= +github.com/golang/mock v1.1.1 h1:G5FRp8JnTd7RQH5kemVNlMeyXQAztQ3mOWV95KxsXH8= +github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0= +github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= +github.com/googleapis/gnostic v0.4.1 h1:DLJCy1n/vrD4HPjOvYcT8aYQXpPIzoRZONaYwyycI+I= +github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU= +github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= +github.com/kisielk/errcheck v1.2.0 h1:reN85Pxc5larApoH1keMBiu2GWtPqXQ1nc9gx+jOU+E= +github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg= +github.com/kr/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs= +github.com/kr/pty v1.1.1 h1:VkoXIwSboBpnk99O/KFauAEILuNHv5DVFKZMBN/gUgw= +github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a h1:TpvdAwDAt1K4ANVOfcihouRdvP+MgAfDWwBuct4l6ZY= +github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d h1:7PxY7LVfSZm7PEeBTyK1rj1gABdCO2mbri6GKO1cMDs= +github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J1GEMiLbxo1LJaP8RfCpH6pymGZus= +github.com/onsi/ginkgo v1.11.0 h1:JAKSXpt1YjtLA7YpPiqO9ss6sNXEsPfSGdwN0UHqzrw= +github.com/onsi/gomega v1.7.0 h1:XPnZz8VVBHjVsy1vzJmRwIcSwiUO+JFfrv/xGiigmME= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4 h1:gQz4mCbXsO+nc9n1hCxHcGA3Zx3Eo+UHZoInFGUIXNM= +github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= +github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4 h1:c2HOrn5iMezYjSlGPncknSEr/8x5LELb/ilJbXi9DEA= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3 h1:XQyxROzUlZH+WIQwySDgnISgOivlhjIEwaQaJEJrrN0= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be h1:vEDujvNQGv4jgYKudGeI/+DAX4Jffq6hpD55MmoEvKs= +golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU= +golang.org/x/sys v0.0.0-20201112073958-5cba982894dd h1:5CtCZbICpIOFdgO940moixOPjc0178IU44m4EjOO5IY= +golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= +google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 h1:+kGHl1aib/qcwaRi1CbqBZ1rk19r85MNUf8HaBghugY= +google.golang.org/grpc v1.27.0 h1:rRYRFMVgRv6E0D70Skyfsr28tDXIuuPZyWGMPdMcnXg= +google.golang.org/protobuf v1.24.0 h1:UhZDfRO8JRQru4/+LlLE0BRKGF8L+PICnvYZmx/fEGA= +gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc h1:/hemPrYIhOhy8zYrNj+069zDB68us2sMGsfkFJO0iZs= +k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac h1:sAvhNk5RRuc6FNYGqe7Ygz3PSo/2wGWbulskmzRX8Vs= +k8s.io/kube-openapi v0.0.0-20200805222855-6aeccd4b50c6 h1:+WnxoVtG8TMiudHBSEtrVL1egv36TkkJm+bA8AxicmQ= diff --git a/vendor/knative.dev/hack/library.sh b/vendor/knative.dev/hack/library.sh index ca67e684..e5d21b70 100644 --- a/vendor/knative.dev/hack/library.sh +++ b/vendor/knative.dev/hack/library.sh @@ -753,6 +753,8 @@ function __go_update_deps_for_module() { if [[ "${FORCE_VENDOR:-false}" == "true" ]] || [ -d vendor ]; then group "Go mod vendor" go mod vendor 2>&1 | grep -v "ignoring symlink" || true + else + go mod download -x fi eval "$orig_pipefail_opt" @@ -770,8 +772,8 @@ function __go_update_deps_for_module() { remove_broken_symlinks ./vendor fi - group "Updating licenses" - update_licenses third_party/VENDOR-LICENSE "./..." + group "Checking licenses" + check_licenses ) } @@ -807,18 +809,6 @@ function run_kntest() { go_run knative.dev/test-infra/tools/kntest/cmd/kntest@latest "$@" } -# Run go-licenses to update licenses. -# Parameters: $1 - output file, relative to repo root dir. -# $2 - directory to inspect. -function update_licenses() { - local dst=$1 - local dir=$2 - shift - go_run github.com/google/go-licenses@v1.6.0 \ - save "${dir}" --save_path="${dst}" --force || \ - { echo "--- FAIL: go-licenses failed to update licenses"; return 1; } -} - # Run go-licenses to check for forbidden licenses. function check_licenses() { # Check that we don't have any forbidden licenses. diff --git a/vendor/modules.txt b/vendor/modules.txt index 25ea4b3b..4fc07953 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -8,6 +8,9 @@ github.com/google/go-cmp/cmp/internal/value # github.com/inconshreveable/mousetrap v1.1.0 ## explicit; go 1.18 github.com/inconshreveable/mousetrap +# github.com/mitchellh/go-homedir v1.1.0 +## explicit +github.com/mitchellh/go-homedir # github.com/spf13/cobra v1.7.0 ## explicit; go 1.15 github.com/spf13/cobra @@ -22,9 +25,9 @@ gotest.tools/v3/internal/assert gotest.tools/v3/internal/difflib gotest.tools/v3/internal/format gotest.tools/v3/internal/source -# knative.dev/client-pkg v0.0.0-20240313113642-ca457df5ea78 +# knative.dev/client-pkg v0.0.0-20240329013337-eff7cfdc981e ## explicit; go 1.21 -knative.dev/client-pkg/pkg/kn/plugin -# knative.dev/hack v0.0.0-20240313135155-b9f6bf0b323b +knative.dev/client-pkg/pkg/plugin +# knative.dev/hack v0.0.0-20240327150553-47368d631660 ## explicit; go 1.18 knative.dev/hack