diff --git a/CHANGELOG.md b/CHANGELOG.md index ec4d834d4e..fcd8101d81 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## [Unreleased] +- Add `buf registry plugin {create,delete,info,update}` commands to manage BSR plugins. - Breaking analysis support for `buf beta lsp`. ## [v1.47.2] - 2024-11-14 diff --git a/go.mod b/go.mod index 2cd1848eec..aab2d4b101 100644 --- a/go.mod +++ b/go.mod @@ -16,11 +16,11 @@ require ( connectrpc.com/otelconnect v0.7.1 github.com/bufbuild/protocompile v0.14.1 github.com/bufbuild/protoplugin v0.0.0-20240911180120-7bb73e41a54a - github.com/bufbuild/protovalidate-go v0.7.3-0.20241015162221-1446f1e1d576 + github.com/bufbuild/protovalidate-go v0.7.3 github.com/docker/docker v27.3.1+incompatible github.com/go-chi/chi/v5 v5.1.0 github.com/gofrs/flock v0.12.1 - github.com/google/cel-go v0.22.0 + github.com/google/cel-go v0.22.1 github.com/google/go-cmp v0.6.0 github.com/google/go-containerregistry v0.20.2 github.com/google/uuid v1.6.0 @@ -34,7 +34,7 @@ require ( github.com/rs/cors v1.11.1 github.com/spf13/cobra v1.8.1 github.com/spf13/pflag v1.0.5 - github.com/stretchr/testify v1.9.0 + github.com/stretchr/testify v1.10.0 github.com/tetratelabs/wazero v1.8.1 go.lsp.dev/jsonrpc2 v0.10.0 go.lsp.dev/protocol v0.12.0 @@ -53,14 +53,14 @@ require ( ) require ( - buf.build/gen/go/pluginrpc/pluginrpc/protocolbuffers/go v1.35.1-20241007202033-cf42259fcbfc.1 // indirect + buf.build/gen/go/pluginrpc/pluginrpc/protocolbuffers/go v1.35.2-20241007202033-cf42259fcbfc.1 // indirect cel.dev/expr v0.18.0 // indirect github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect github.com/Microsoft/go-winio v0.6.2 // indirect github.com/Microsoft/hcsshim v0.12.9 // indirect github.com/antlr4-go/antlr/v4 v4.13.1 // indirect - github.com/containerd/cgroups/v3 v3.0.3 // indirect - github.com/containerd/containerd v1.7.23 // indirect + github.com/containerd/cgroups/v3 v3.0.4 // indirect + github.com/containerd/containerd v1.7.24 // indirect github.com/containerd/continuity v0.4.5 // indirect github.com/containerd/errdefs v1.0.0 // indirect github.com/containerd/errdefs/pkg v0.3.0 // indirect @@ -84,7 +84,7 @@ require ( github.com/go-task/slim-sprig/v3 v3.0.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect - github.com/google/pprof v0.0.0-20241101162523-b92577c0c142 // indirect + github.com/google/pprof v0.0.0-20241122213907-cbe949e5a41b // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect @@ -98,7 +98,7 @@ require ( github.com/moby/sys/userns v0.1.0 // indirect github.com/moby/term v0.5.0 // indirect github.com/morikuni/aec v1.0.0 // indirect - github.com/onsi/ginkgo/v2 v2.21.0 // indirect + github.com/onsi/ginkgo/v2 v2.22.0 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/image-spec v1.1.0 // indirect github.com/opencontainers/runtime-spec v1.2.0 // indirect @@ -107,7 +107,7 @@ require ( github.com/quic-go/qpack v0.5.1 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/segmentio/asm v1.2.0 // indirect - github.com/segmentio/encoding v0.4.0 // indirect + github.com/segmentio/encoding v0.4.1 // indirect github.com/sirupsen/logrus v1.9.3 // indirect github.com/stoewer/go-strcase v1.3.0 // indirect github.com/vbatts/tar-split v0.11.6 // indirect @@ -122,7 +122,7 @@ require ( go.uber.org/multierr v1.11.0 // indirect golang.org/x/sys v0.27.0 // indirect golang.org/x/text v0.20.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20241113202542-65e8d215514f // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20241113202542-65e8d215514f // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20241118233622-e639e219e697 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20241118233622-e639e219e697 // indirect google.golang.org/grpc v1.68.0 // indirect ) diff --git a/go.sum b/go.sum index 4190f7615c..cf3c84d1b8 100644 --- a/go.sum +++ b/go.sum @@ -6,8 +6,8 @@ buf.build/gen/go/bufbuild/registry/connectrpc/go v1.17.0-20241025140216-aa40f2c9 buf.build/gen/go/bufbuild/registry/connectrpc/go v1.17.0-20241025140216-aa40f2c93090.1/go.mod h1:5iwF5l+9lKCnvr1zLvDgUHrv6X+vU5nNPjvig1sbnao= buf.build/gen/go/bufbuild/registry/protocolbuffers/go v1.35.2-20241025140216-aa40f2c93090.1 h1:a1OY15kRBrD1AF0SYIPYFLE8GCC1d85zqENnzUC3lNM= buf.build/gen/go/bufbuild/registry/protocolbuffers/go v1.35.2-20241025140216-aa40f2c93090.1/go.mod h1:EQCcR04Wp6ffVPfxNb4ZXAVJXrZJopDNKQWp37BDCgU= -buf.build/gen/go/pluginrpc/pluginrpc/protocolbuffers/go v1.35.1-20241007202033-cf42259fcbfc.1 h1:rPi3qs3qpDIXIl5QW2IPOaYZhppRkvuVKwEZrfhpy78= -buf.build/gen/go/pluginrpc/pluginrpc/protocolbuffers/go v1.35.1-20241007202033-cf42259fcbfc.1/go.mod h1:4IVMTaeh4JIjBYcGFLlTorfWpKVEXDjDfHAgKTeR0Ds= +buf.build/gen/go/pluginrpc/pluginrpc/protocolbuffers/go v1.35.2-20241007202033-cf42259fcbfc.1 h1:FcoYwX9eJhc73MdVlqyJjMOQ863akpHK0VEQ/+Zkt9U= +buf.build/gen/go/pluginrpc/pluginrpc/protocolbuffers/go v1.35.2-20241007202033-cf42259fcbfc.1/go.mod h1:uTCf/J5B6H9XCTgHuI91LC9qaNqxJxQFh0kDY/GLn2k= buf.build/go/bufplugin v0.6.0 h1:3lhoh+0z+IUPS3ZajTPn/27LaLIkero2BDVnV7yXD1s= buf.build/go/bufplugin v0.6.0/go.mod h1:hWCjxxv24xdR6F5pNlQavZV2oo0J3uF4Ff1XEoyV6vU= buf.build/go/protoyaml v0.2.0 h1:2g3OHjtLDqXBREIOjpZGHmQ+U/4mkN1YiQjxNB68Ip8= @@ -36,8 +36,8 @@ github.com/bufbuild/protocompile v0.14.1 h1:iA73zAf/fyljNjQKwYzUHD6AD4R8KMasmwa/ github.com/bufbuild/protocompile v0.14.1/go.mod h1:ppVdAIhbr2H8asPk6k4pY7t9zB1OU5DoEw9xY/FUi1c= github.com/bufbuild/protoplugin v0.0.0-20240911180120-7bb73e41a54a h1:l3RhVoG0RtC61h6TVWnkniGj4TgBebuyPQRdleFAmTg= github.com/bufbuild/protoplugin v0.0.0-20240911180120-7bb73e41a54a/go.mod h1:c5D8gWRIZ2HLWO3gXYTtUfw/hbJyD8xikv2ooPxnklQ= -github.com/bufbuild/protovalidate-go v0.7.3-0.20241015162221-1446f1e1d576 h1:A4TfjZJqApnAvGKDgxHqA1rG6BK1OswyNcTcnSrDbJc= -github.com/bufbuild/protovalidate-go v0.7.3-0.20241015162221-1446f1e1d576/go.mod h1:R/UFeIPyFAh0eH7Ic/JJbO2ABdkxFuZZKDbzsI5UiwM= +github.com/bufbuild/protovalidate-go v0.7.3 h1:kKnoSueygR3xxppvuBpm9SEwIsP359MMRfMBGmRByPg= +github.com/bufbuild/protovalidate-go v0.7.3/go.mod h1:CFv34wMqiBzAHdQ4q/tWYi9ILFYKuaC3/4zh6eqdUck= github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= @@ -52,10 +52,10 @@ github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMn github.com/chzyer/test v1.0.0/go.mod h1:2JlltgoNkt4TW/z9V/IzDdFaMTM2JPIi26O1pF38GC8= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= -github.com/containerd/cgroups/v3 v3.0.3 h1:S5ByHZ/h9PMe5IOQoN7E+nMc2UcLEM/V48DGDJ9kip0= -github.com/containerd/cgroups/v3 v3.0.3/go.mod h1:8HBe7V3aWGLFPd/k03swSIsGjZhHI2WzJmticMgVuz0= -github.com/containerd/containerd v1.7.23 h1:H2CClyUkmpKAGlhQp95g2WXHfLYc7whAuvZGBNYOOwQ= -github.com/containerd/containerd v1.7.23/go.mod h1:7QUzfURqZWCZV7RLNEn1XjUCQLEf0bkaK4GjUaZehxw= +github.com/containerd/cgroups/v3 v3.0.4 h1:2fs7l3P0Qxb1nKWuJNFiwhp2CqiKzho71DQkDrHJIo4= +github.com/containerd/cgroups/v3 v3.0.4/go.mod h1:SA5DLYnXO8pTGYiAHXz94qvLQTKfVM5GEVisn4jpins= +github.com/containerd/containerd v1.7.24 h1:zxszGrGjrra1yYJW/6rhm9cJ1ZQ8rkKBR48brqsa7nA= +github.com/containerd/containerd v1.7.24/go.mod h1:7QUzfURqZWCZV7RLNEn1XjUCQLEf0bkaK4GjUaZehxw= github.com/containerd/continuity v0.4.5 h1:ZRoN1sXq9u7V6QoHMcVWGhOwDFqZ4B9i5H6un1Wh0x4= github.com/containerd/continuity v0.4.5/go.mod h1:/lNJvtJKUQStBzpVQ1+rasXO1LAWtUQssk28EZvJ3nE= github.com/containerd/errdefs v1.0.0 h1:tg5yIfIlQIrxYtu9ajqY42W3lpS19XqdxRQeEwYG8PI= @@ -137,8 +137,8 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= -github.com/google/cel-go v0.22.0 h1:b3FJZxpiv1vTMo2/5RDUqAHPxkT8mmMfJIrq1llbf7g= -github.com/google/cel-go v0.22.0/go.mod h1:BuznPXXfQDpXKWQ9sPW3TzlAJN5zzFe+i9tIs0yC4s8= +github.com/google/cel-go v0.22.1 h1:AfVXx3chM2qwoSbM7Da8g8hX8OVSkBFwX+rz2+PcK40= +github.com/google/cel-go v0.22.1/go.mod h1:BuznPXXfQDpXKWQ9sPW3TzlAJN5zzFe+i9tIs0yC4s8= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -151,8 +151,8 @@ github.com/google/go-containerregistry v0.20.2 h1:B1wPJ1SN/S7pB+ZAimcciVD+r+yV/l github.com/google/go-containerregistry v0.20.2/go.mod h1:z38EKdKh4h7IP2gSfUUqEvalZBqs6AoLeWfUy34nQC8= github.com/google/pprof v0.0.0-20211214055906-6f57359322fd/go.mod h1:KgnwoLYCZ8IQu3XUZ8Nc/bM9CCZFOyjUNOSygVozoDg= github.com/google/pprof v0.0.0-20240227163752-401108e1b7e7/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= -github.com/google/pprof v0.0.0-20241101162523-b92577c0c142 h1:sAGdeJj0bnMgUNVeUpp6AYlVdCt3/GdI3pGRqsNSQLs= -github.com/google/pprof v0.0.0-20241101162523-b92577c0c142/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= +github.com/google/pprof v0.0.0-20241122213907-cbe949e5a41b h1:SXO0REt4iu865upYCk8aKBBJQ4BqoE0ReP23ClMu60s= +github.com/google/pprof v0.0.0-20241122213907-cbe949e5a41b/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -203,8 +203,8 @@ github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0= github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= -github.com/onsi/ginkgo/v2 v2.21.0 h1:7rg/4f3rB88pb5obDgNZrNHrQ4e6WpjonchcpuBRnZM= -github.com/onsi/ginkgo/v2 v2.21.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo= +github.com/onsi/ginkgo/v2 v2.22.0 h1:Yed107/8DjTr0lKCNt7Dn8yQ6ybuDRQoMGrNFKzMfHg= +github.com/onsi/ginkgo/v2 v2.22.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo= github.com/onsi/gomega v1.34.2 h1:pNCwDkzrsv7MS9kpaQvVb1aVLahQXyJ/Tv5oAZMI3i8= github.com/onsi/gomega v1.34.2/go.mod h1:v1xfxRgk0KIsG+QOdm7p8UosrOzPYRo60fd3B/1Dukc= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= @@ -239,8 +239,8 @@ github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/segmentio/asm v1.2.0 h1:9BQrFxC+YOHJlTlHGkTrFWf59nbL3XnCoFLTwDCI7ys= github.com/segmentio/asm v1.2.0/go.mod h1:BqMnlJP91P8d+4ibuonYZw9mfnzI9HfxselHZr5aAcs= -github.com/segmentio/encoding v0.4.0 h1:MEBYvRqiUB2nfR2criEXWqwdY6HJOUrCn5hboVOVmy8= -github.com/segmentio/encoding v0.4.0/go.mod h1:/d03Cd8PoaDeceuhUUUQWjU0KhWjrmYrWPgtJHYZSnI= +github.com/segmentio/encoding v0.4.1 h1:KLGaLSW0jrmhB58Nn4+98spfvPvmo4Ci1P/WIQ9wn7w= +github.com/segmentio/encoding v0.4.1/go.mod h1:/d03Cd8PoaDeceuhUUUQWjU0KhWjrmYrWPgtJHYZSnI= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= @@ -256,8 +256,8 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/tetratelabs/wazero v1.8.1 h1:NrcgVbWfkWvVc4UtT4LRLDf91PsOzDzefMdwhLfA550= github.com/tetratelabs/wazero v1.8.1/go.mod h1:yAI0XTsMBhREkM/YDAK/zNou3GoiAce1P6+rp/wQhjs= github.com/vbatts/tar-split v0.11.6 h1:4SjTW5+PU11n6fZenf2IPoV8/tz3AaYHMWjf23envGs= @@ -375,10 +375,10 @@ google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7 google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto/googleapis/api v0.0.0-20241113202542-65e8d215514f h1:M65LEviCfuZTfrfzwwEoxVtgvfkFkBUbFnRbxCXuXhU= -google.golang.org/genproto/googleapis/api v0.0.0-20241113202542-65e8d215514f/go.mod h1:Yo94eF2nj7igQt+TiJ49KxjIH8ndLYPZMIRSiRcEbg0= -google.golang.org/genproto/googleapis/rpc v0.0.0-20241113202542-65e8d215514f h1:C1QccEa9kUwvMgEUORqQD9S17QesQijxjZ84sO82mfo= -google.golang.org/genproto/googleapis/rpc v0.0.0-20241113202542-65e8d215514f/go.mod h1:GX3210XPVPUjJbTUbvwI8f2IpZDMZuPJWDzDuebbviI= +google.golang.org/genproto/googleapis/api v0.0.0-20241118233622-e639e219e697 h1:pgr/4QbFyktUv9CtQ/Fq4gzEE6/Xs7iCXbktaGzLHbQ= +google.golang.org/genproto/googleapis/api v0.0.0-20241118233622-e639e219e697/go.mod h1:+D9ySVjN8nY8YCVjc5O7PZDIdZporIDY3KaGfJunh88= +google.golang.org/genproto/googleapis/rpc v0.0.0-20241118233622-e639e219e697 h1:LWZqQOEjDyONlF1H6afSWpAL/znlREo2tHfLoe+8LMA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20241118233622-e639e219e697/go.mod h1:5uTbfoYQed2U9p3KIj2/Zzm02PYhndfdmML0qC3q3FU= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= diff --git a/private/buf/bufcli/errors.go b/private/buf/bufcli/errors.go index 0e0de9344d..3a82786174 100644 --- a/private/buf/bufcli/errors.go +++ b/private/buf/bufcli/errors.go @@ -54,6 +54,12 @@ func NewLabelNameAlreadyExistsError(name string) error { return fmt.Errorf("a label named %q already exists", name) } +// NewPluginNameAlreadyExistsError informs the user that a plugin +// with that name already exists. +func NewPluginNameAlreadyExistsError(name string) error { + return fmt.Errorf("a plugin named %q already exists", name) +} + // NewOrganizationNotFoundError informs the user that an organization with // that name does not exist. func NewOrganizationNotFoundError(name string) error { @@ -88,6 +94,12 @@ func NewTokenNotFoundError(tokenID string) error { return fmt.Errorf("a token with ID %q does not exist", tokenID) } +// NewPluginNotFoundError informs the user that a plugin with +// that name does not exist. +func NewPluginNotFoundError(name string) error { + return fmt.Errorf("a plugin named %q does not exist", name) +} + // NewInvalidRemoteError informs the user that the given remote is invalid. func NewInvalidRemoteError(err error, remote string, moduleFullName string) error { var connectErr *connect.Error diff --git a/private/buf/bufcli/flags_args.go b/private/buf/bufcli/flags_args.go index a2238f7c67..e8d2ca56f7 100644 --- a/private/buf/bufcli/flags_args.go +++ b/private/buf/bufcli/flags_args.go @@ -19,6 +19,7 @@ import ( "fmt" modulev1 "buf.build/gen/go/bufbuild/registry/protocolbuffers/go/buf/registry/module/v1" + pluginv1beta1 "buf.build/gen/go/bufbuild/registry/protocolbuffers/go/buf/registry/plugin/v1beta1" "github.com/bufbuild/buf/private/buf/buffetch" "github.com/bufbuild/buf/private/pkg/app" "github.com/bufbuild/buf/private/pkg/app/appcmd" @@ -302,6 +303,21 @@ func VisibilityFlagToVisibilityAllowUnspecified(visibility string) (modulev1.Mod } } +// VisibilityFlagToPluginVisibilityAllowUnspecified parses the given string as a pluginv1.PluginVisibility +// where an empty string will be parsed as unspecified. +func VisibilityFlagToPluginVisibilityAllowUnspecified(visibility string) (pluginv1beta1.PluginVisibility, error) { + switch visibility { + case publicVisibility: + return pluginv1beta1.PluginVisibility_PLUGIN_VISIBILITY_PUBLIC, nil + case privateVisibility: + return pluginv1beta1.PluginVisibility_PLUGIN_VISIBILITY_PRIVATE, nil + case "": + return pluginv1beta1.PluginVisibility_PLUGIN_VISIBILITY_UNSPECIFIED, nil + default: + return 0, fmt.Errorf("invalid visibility: %s", visibility) + } +} + // ArchiveStatusFlagToArchiveStatusFilter parses the given string as a modulev1.ListLabelsRequest_ArchiveFilter. func ArchiveStatusFlagToArchiveStatusFilter(archiveStatus string) (modulev1.ListLabelsRequest_ArchiveFilter, error) { switch archiveStatus { diff --git a/private/buf/buflsp/symbol.go b/private/buf/buflsp/symbol.go index 1886272ef1..f9c07f577b 100644 --- a/private/buf/buflsp/symbol.go +++ b/private/buf/buflsp/symbol.go @@ -672,7 +672,9 @@ func (w *symbolWalker) Walk(node, parent ast.Node) { case *ast.GroupNode: def := w.newDef(node, node.Name) w.newDef(node, node.Name) - w.newTag(node.Tag, def) + if node.Tag != nil { + w.newTag(node.Tag, def) + } // TODO: also do the name of the generated field. for _, decl := range node.Decls { w.Walk(decl, node) @@ -681,7 +683,9 @@ func (w *symbolWalker) Walk(node, parent ast.Node) { case *ast.FieldNode: def := w.newDef(node, node.Name) w.newRef(node.FldType) - w.newTag(node.Tag, def) + if node.Tag != nil { + w.newTag(node.Tag, def) + } if node.Options != nil { for _, option := range node.Options.Options { w.Walk(option, node) @@ -692,7 +696,9 @@ func (w *symbolWalker) Walk(node, parent ast.Node) { def := w.newDef(node, node.Name) w.newRef(node.MapType.KeyType) w.newRef(node.MapType.ValueType) - w.newTag(node.Tag, def) + if node.Tag != nil { + w.newTag(node.Tag, def) + } if node.Options != nil { for _, option := range node.Options.Options { w.Walk(option, node) @@ -717,7 +723,9 @@ func (w *symbolWalker) Walk(node, parent ast.Node) { case *ast.EnumValueNode: def := w.newDef(node, node.Name) - w.newTag(node.Number, def) + if node.Number != nil { + w.newTag(node.Number, def) + } if node.Options != nil { for _, option := range node.Options.Options { w.Walk(option, node) diff --git a/private/buf/bufprint/bufprint.go b/private/buf/bufprint/bufprint.go index c4e6402816..28dd537109 100644 --- a/private/buf/bufprint/bufprint.go +++ b/private/buf/bufprint/bufprint.go @@ -27,6 +27,7 @@ import ( modulev1 "buf.build/gen/go/bufbuild/registry/protocolbuffers/go/buf/registry/module/v1" ownerv1 "buf.build/gen/go/bufbuild/registry/protocolbuffers/go/buf/registry/owner/v1" + pluginv1beta1 "buf.build/gen/go/bufbuild/registry/protocolbuffers/go/buf/registry/plugin/v1beta1" "github.com/bufbuild/buf/private/bufpkg/bufparse" registryv1alpha1 "github.com/bufbuild/buf/private/gen/proto/go/buf/alpha/registry/v1alpha1" "github.com/bufbuild/buf/private/pkg/protoencoding" @@ -248,6 +249,18 @@ func NewOrganizationEntity(organization *ownerv1.Organization, remote string) En } } +// NewPluginEntity returns a new plugin entity to print. +func NewPluginEntity(plugin *pluginv1beta1.Plugin, pluginFullName bufparse.FullName) Entity { + return outputPlugin{ + ID: plugin.Id, + Remote: pluginFullName.Registry(), + Owner: pluginFullName.Owner(), + Name: pluginFullName.Name(), + FullName: pluginFullName.String(), + CreateTime: plugin.CreateTime.AsTime(), + } +} + // NewUserEntity returns a new user entity to print. func NewUserEntity(user *registryv1alpha1.User) Entity { return outputUser{ @@ -466,6 +479,19 @@ func (o outputOrganization) fullName() string { return o.FullName } +type outputPlugin struct { + ID string `json:"id,omitempty"` + Remote string `json:"remote,omitempty"` + Owner string `json:"owner,omitempty"` + Name string `json:"name,omitempty"` + FullName string `json:"-" bufprint:"Name"` + CreateTime time.Time `json:"create_time,omitempty" bufprint:"Create Time"` +} + +func (m outputPlugin) fullName() string { + return m.FullName +} + type outputUser struct { Username string `json:"username,omitempty"` FullName string `json:"-" bufprint:"Name"` diff --git a/private/buf/cmd/buf/buf.go b/private/buf/cmd/buf/buf.go index 57dcc15bfc..776b611c06 100644 --- a/private/buf/cmd/buf/buf.go +++ b/private/buf/cmd/buf/buf.go @@ -35,8 +35,8 @@ import ( "github.com/bufbuild/buf/private/buf/cmd/buf/command/beta/bufpluginv2" "github.com/bufbuild/buf/private/buf/cmd/buf/command/beta/lsp" "github.com/bufbuild/buf/private/buf/cmd/buf/command/beta/price" - "github.com/bufbuild/buf/private/buf/cmd/buf/command/beta/registry/plugin/plugindelete" - "github.com/bufbuild/buf/private/buf/cmd/buf/command/beta/registry/plugin/pluginpush" + betaplugindelete "github.com/bufbuild/buf/private/buf/cmd/buf/command/beta/registry/plugin/plugindelete" + betapluginpush "github.com/bufbuild/buf/private/buf/cmd/buf/command/beta/registry/plugin/pluginpush" "github.com/bufbuild/buf/private/buf/cmd/buf/command/beta/registry/webhook/webhookcreate" "github.com/bufbuild/buf/private/buf/cmd/buf/command/beta/registry/webhook/webhookdelete" "github.com/bufbuild/buf/private/buf/cmd/buf/command/beta/registry/webhook/webhooklist" @@ -81,6 +81,10 @@ import ( "github.com/bufbuild/buf/private/buf/cmd/buf/command/registry/organization/organizationdelete" "github.com/bufbuild/buf/private/buf/cmd/buf/command/registry/organization/organizationinfo" "github.com/bufbuild/buf/private/buf/cmd/buf/command/registry/organization/organizationupdate" + "github.com/bufbuild/buf/private/buf/cmd/buf/command/registry/plugin/plugincreate" + "github.com/bufbuild/buf/private/buf/cmd/buf/command/registry/plugin/plugindelete" + "github.com/bufbuild/buf/private/buf/cmd/buf/command/registry/plugin/plugininfo" + "github.com/bufbuild/buf/private/buf/cmd/buf/command/registry/plugin/pluginupdate" "github.com/bufbuild/buf/private/buf/cmd/buf/command/registry/registrycc" "github.com/bufbuild/buf/private/buf/cmd/buf/command/registry/registrylogin" "github.com/bufbuild/buf/private/buf/cmd/buf/command/registry/registrylogout" @@ -252,6 +256,16 @@ func NewRootCommand(name string) *appcmd.Command { moduleupdate.NewCommand("update", builder), }, }, + { + Use: "plugin", + Short: "Manage BSR plugins", + SubCommands: []*appcmd.Command{ + plugincreate.NewCommand("create", builder), + plugininfo.NewCommand("info", builder), + plugindelete.NewCommand("delete", builder), + pluginupdate.NewCommand("update", builder), + }, + }, }, }, { @@ -282,8 +296,8 @@ func NewRootCommand(name string) *appcmd.Command { Use: "plugin", Short: "Manage plugins on the Buf Schema Registry", SubCommands: []*appcmd.Command{ - pluginpush.NewCommand("push", builder), - plugindelete.NewCommand("delete", builder), + betapluginpush.NewCommand("push", builder), + betaplugindelete.NewCommand("delete", builder), }, }, }, diff --git a/private/buf/cmd/buf/command/registry/module/moduleupdate/moduleupdate.go b/private/buf/cmd/buf/command/registry/module/moduleupdate/moduleupdate.go index f4c66ab26c..a6463a1700 100644 --- a/private/buf/cmd/buf/command/registry/module/moduleupdate/moduleupdate.go +++ b/private/buf/cmd/buf/command/registry/module/moduleupdate/moduleupdate.go @@ -139,7 +139,7 @@ func run( } return err } - if _, err := fmt.Fprintln(container.Stdout(), "Module updated."); err != nil { + if _, err := fmt.Fprintf(container.Stdout(), "Updated %s.\n", moduleFullName); err != nil { return syserror.Wrap(err) } return nil diff --git a/private/buf/cmd/buf/command/registry/plugin/plugincreate/plugincreate.go b/private/buf/cmd/buf/command/registry/plugin/plugincreate/plugincreate.go new file mode 100644 index 0000000000..5cbf0b2572 --- /dev/null +++ b/private/buf/cmd/buf/command/registry/plugin/plugincreate/plugincreate.go @@ -0,0 +1,185 @@ +// Copyright 2020-2024 Buf Technologies, Inc. +// +// 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 plugincreate + +import ( + "context" + "fmt" + + ownerv1 "buf.build/gen/go/bufbuild/registry/protocolbuffers/go/buf/registry/owner/v1" + pluginv1beta1 "buf.build/gen/go/bufbuild/registry/protocolbuffers/go/buf/registry/plugin/v1beta1" + "connectrpc.com/connect" + "github.com/bufbuild/buf/private/buf/bufcli" + "github.com/bufbuild/buf/private/buf/bufprint" + "github.com/bufbuild/buf/private/bufpkg/bufparse" + "github.com/bufbuild/buf/private/bufpkg/bufregistryapi/bufregistryapiplugin" + "github.com/bufbuild/buf/private/pkg/app/appcmd" + "github.com/bufbuild/buf/private/pkg/app/appext" + "github.com/bufbuild/buf/private/pkg/stringutil" + "github.com/bufbuild/buf/private/pkg/syserror" + "github.com/spf13/pflag" +) + +const ( + formatFlagName = "format" + visibilityFlagName = "visibility" + defaultLabeFlagName = "default-label-name" + typeFlagName = "type" + + defaultDefaultLabel = "main" + + pluginTypeCheck = "check" +) + +var ( + allPluginTypeStrings = []string{ + pluginTypeCheck, + } +) + +// NewCommand returns a new Command. +func NewCommand( + name string, + builder appext.SubCommandBuilder, +) *appcmd.Command { + flags := newFlags() + return &appcmd.Command{ + Use: name + " ", + Short: "Create a BSR plugin", + Args: appcmd.ExactArgs(1), + Run: builder.NewRunFunc( + func(ctx context.Context, container appext.Container) error { + return run(ctx, container, flags) + }, + ), + BindFlags: flags.Bind, + } +} + +type flags struct { + Format string + Visibility string + DefautlLabel string + Type string +} + +func newFlags() *flags { + return &flags{} +} + +func (f *flags) Bind(flagSet *pflag.FlagSet) { + bufcli.BindVisibility(flagSet, &f.Visibility, visibilityFlagName, false) + flagSet.StringVar( + &f.Format, + formatFlagName, + bufprint.FormatText.String(), + fmt.Sprintf(`The output format to use. Must be one of %s`, bufprint.AllFormatsString), + ) + flagSet.StringVar( + &f.DefautlLabel, + defaultLabeFlagName, + defaultDefaultLabel, + "The default label name of the module", + ) + flagSet.StringVar( + &f.Type, + typeFlagName, + "", + fmt.Sprintf( + "The type of the plugin. Must be one of %s", + stringutil.SliceToString(allPluginTypeStrings), + ), + ) + _ = appcmd.MarkFlagRequired(flagSet, typeFlagName) +} + +func run( + ctx context.Context, + container appext.Container, + flags *flags, +) error { + pluginFullName, err := bufparse.ParseFullName(container.Arg(0)) + if err != nil { + return appcmd.WrapInvalidArgumentError(err) + } + visibility, err := bufcli.VisibilityFlagToPluginVisibilityAllowUnspecified(flags.Visibility) + if err != nil { + return appcmd.WrapInvalidArgumentError(err) + } + format, err := bufprint.ParseFormat(flags.Format) + if err != nil { + return appcmd.WrapInvalidArgumentError(err) + } + pluginType, err := typeFlagToPluginType(flags.Type) + if err != nil { + return appcmd.WrapInvalidArgumentError(err) + } + + clientConfig, err := bufcli.NewConnectClientConfig(container) + if err != nil { + return err + } + pluginServiceClient := bufregistryapiplugin.NewClientProvider(clientConfig). + V1Beta1PluginServiceClient(pluginFullName.Registry()) + + pluginResponse, err := pluginServiceClient.CreatePlugins(ctx, connect.NewRequest( + &pluginv1beta1.CreatePluginsRequest{ + Values: []*pluginv1beta1.CreatePluginsRequest_Value{ + { + OwnerRef: &ownerv1.OwnerRef{ + Value: &ownerv1.OwnerRef_Name{ + Name: pluginFullName.Owner(), + }, + }, + Name: pluginFullName.Name(), + Visibility: visibility, + Type: pluginType, + }, + }, + }, + )) + if err != nil { + if connect.CodeOf(err) == connect.CodeAlreadyExists { + return bufcli.NewPluginNameAlreadyExistsError(pluginFullName.String()) + } + return err + } + plugins := pluginResponse.Msg.Plugins + if len(plugins) != 1 { + return syserror.Newf("unexpected number of plugins returned from server: %d", len(plugins)) + } + if format == bufprint.FormatText { + _, err = fmt.Fprintf(container.Stdout(), "Created %s.\n", pluginFullName) + if err != nil { + return syserror.Wrap(err) + } + return nil + } + return bufprint.PrintNames( + container.Stdout(), + format, + bufprint.NewPluginEntity(plugins[0], pluginFullName), + ) +} + +// typeFlagToPluginType parses the given string as a pluginv1.PluginType. +func typeFlagToPluginType(pluginType string) (pluginv1beta1.PluginType, error) { + switch pluginType { + case pluginTypeCheck: + return pluginv1beta1.PluginType_PLUGIN_TYPE_CHECK, nil + default: + return 0, fmt.Errorf("invalid plugin type: %s", pluginType) + } +} diff --git a/private/buf/cmd/buf/command/registry/plugin/plugincreate/usage.gen.go b/private/buf/cmd/buf/command/registry/plugin/plugincreate/usage.gen.go new file mode 100644 index 0000000000..6934f63116 --- /dev/null +++ b/private/buf/cmd/buf/command/registry/plugin/plugincreate/usage.gen.go @@ -0,0 +1,19 @@ +// Copyright 2020-2024 Buf Technologies, Inc. +// +// 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. + +// Generated. DO NOT EDIT. + +package plugincreate + +import _ "github.com/bufbuild/buf/private/usage" diff --git a/private/buf/cmd/buf/command/registry/plugin/plugindelete/plugindelete.go b/private/buf/cmd/buf/command/registry/plugin/plugindelete/plugindelete.go new file mode 100644 index 0000000000..0734e95c33 --- /dev/null +++ b/private/buf/cmd/buf/command/registry/plugin/plugindelete/plugindelete.go @@ -0,0 +1,114 @@ +// Copyright 2020-2024 Buf Technologies, Inc. +// +// 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 plugindelete + +import ( + "context" + "fmt" + + pluginv1beta1 "buf.build/gen/go/bufbuild/registry/protocolbuffers/go/buf/registry/plugin/v1beta1" + "connectrpc.com/connect" + "github.com/bufbuild/buf/private/buf/bufcli" + "github.com/bufbuild/buf/private/bufpkg/bufparse" + "github.com/bufbuild/buf/private/bufpkg/bufregistryapi/bufregistryapiplugin" + "github.com/bufbuild/buf/private/pkg/app/appcmd" + "github.com/bufbuild/buf/private/pkg/app/appext" + "github.com/bufbuild/buf/private/pkg/syserror" + "github.com/spf13/pflag" +) + +const forceFlagName = "force" + +// NewCommand returns a new Command. +func NewCommand( + name string, + builder appext.SubCommandBuilder, +) *appcmd.Command { + flags := newFlags() + return &appcmd.Command{ + Use: name + " ", + Short: "Delete a BSR plugin", + Args: appcmd.ExactArgs(1), + Run: builder.NewRunFunc( + func(ctx context.Context, container appext.Container) error { + return run(ctx, container, flags) + }, + ), + BindFlags: flags.Bind, + } +} + +type flags struct { + Force bool +} + +func newFlags() *flags { + return &flags{} +} + +func (f *flags) Bind(flagSet *pflag.FlagSet) { + flagSet.BoolVar( + &f.Force, + forceFlagName, + false, + "Force deletion without confirming. Use with caution", + ) +} + +func run( + ctx context.Context, + container appext.Container, + flags *flags, +) error { + pluginFullName, err := bufparse.ParseFullName(container.Arg(0)) + if err != nil { + return appcmd.WrapInvalidArgumentError(err) + } + if !flags.Force { + if err := bufcli.PromptUserForDelete(container, "entity", pluginFullName.Name()); err != nil { + return err + } + } + clientConfig, err := bufcli.NewConnectClientConfig(container) + if err != nil { + return err + } + pluginServiceClient := bufregistryapiplugin.NewClientProvider(clientConfig). + V1Beta1PluginServiceClient(pluginFullName.Registry()) + + if _, err := pluginServiceClient.DeletePlugins(ctx, connect.NewRequest( + &pluginv1beta1.DeletePluginsRequest{ + PluginRefs: []*pluginv1beta1.PluginRef{ + { + Value: &pluginv1beta1.PluginRef_Name_{ + Name: &pluginv1beta1.PluginRef_Name{ + Owner: pluginFullName.Owner(), + Plugin: pluginFullName.Name(), + }, + }, + }, + }, + }, + )); err != nil { + if connect.CodeOf(err) == connect.CodeNotFound { + return bufcli.NewPluginNotFoundError(container.Arg(0)) + } + return err + } + if _, err := fmt.Fprintf(container.Stdout(), "Deleted %s.\n", pluginFullName); err != nil { + return syserror.Wrap(err) + } + return nil +} diff --git a/private/buf/cmd/buf/command/registry/plugin/plugindelete/usage.gen.go b/private/buf/cmd/buf/command/registry/plugin/plugindelete/usage.gen.go new file mode 100644 index 0000000000..34654783cf --- /dev/null +++ b/private/buf/cmd/buf/command/registry/plugin/plugindelete/usage.gen.go @@ -0,0 +1,19 @@ +// Copyright 2020-2024 Buf Technologies, Inc. +// +// 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. + +// Generated. DO NOT EDIT. + +package plugindelete + +import _ "github.com/bufbuild/buf/private/usage" diff --git a/private/buf/cmd/buf/command/registry/plugin/plugininfo/plugininfo.go b/private/buf/cmd/buf/command/registry/plugin/plugininfo/plugininfo.go new file mode 100644 index 0000000000..0d10a1cce3 --- /dev/null +++ b/private/buf/cmd/buf/command/registry/plugin/plugininfo/plugininfo.go @@ -0,0 +1,121 @@ +// Copyright 2020-2024 Buf Technologies, Inc. +// +// 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 plugininfo + +import ( + "context" + "fmt" + + pluginv1beta1 "buf.build/gen/go/bufbuild/registry/protocolbuffers/go/buf/registry/plugin/v1beta1" + "connectrpc.com/connect" + "github.com/bufbuild/buf/private/buf/bufcli" + "github.com/bufbuild/buf/private/buf/bufprint" + "github.com/bufbuild/buf/private/bufpkg/bufparse" + "github.com/bufbuild/buf/private/bufpkg/bufregistryapi/bufregistryapiplugin" + "github.com/bufbuild/buf/private/pkg/app/appcmd" + "github.com/bufbuild/buf/private/pkg/app/appext" + "github.com/bufbuild/buf/private/pkg/syserror" + "github.com/spf13/pflag" +) + +const formatFlagName = "format" + +// NewCommand returns a new Command. +func NewCommand( + name string, + builder appext.SubCommandBuilder, +) *appcmd.Command { + flags := newFlags() + return &appcmd.Command{ + Use: name + " ", + Short: "Get a BSR plugin", + Args: appcmd.ExactArgs(1), + Run: builder.NewRunFunc( + func(ctx context.Context, container appext.Container) error { + return run(ctx, container, flags) + }, + ), + BindFlags: flags.Bind, + } +} + +type flags struct { + Format string +} + +func newFlags() *flags { + return &flags{} +} + +func (f *flags) Bind(flagSet *pflag.FlagSet) { + flagSet.StringVar( + &f.Format, + formatFlagName, + bufprint.FormatText.String(), + fmt.Sprintf(`The output format to use. Must be one of %s`, bufprint.AllFormatsString), + ) +} + +func run( + ctx context.Context, + container appext.Container, + flags *flags, +) error { + pluginFullName, err := bufparse.ParseFullName(container.Arg(0)) + if err != nil { + return appcmd.WrapInvalidArgumentError(err) + } + format, err := bufprint.ParseFormat(flags.Format) + if err != nil { + return appcmd.WrapInvalidArgumentError(err) + } + + clientConfig, err := bufcli.NewConnectClientConfig(container) + if err != nil { + return err + } + pluginServiceClient := bufregistryapiplugin.NewClientProvider(clientConfig). + V1Beta1PluginServiceClient(pluginFullName.Registry()) + + pluginsResponse, err := pluginServiceClient.GetPlugins(ctx, connect.NewRequest( + &pluginv1beta1.GetPluginsRequest{ + PluginRefs: []*pluginv1beta1.PluginRef{ + { + Value: &pluginv1beta1.PluginRef_Name_{ + Name: &pluginv1beta1.PluginRef_Name{ + Owner: pluginFullName.Owner(), + Plugin: pluginFullName.Name(), + }, + }, + }, + }, + }, + )) + if err != nil { + if connect.CodeOf(err) == connect.CodeNotFound { + return bufcli.NewPluginNotFoundError(container.Arg(0)) + } + return err + } + plugins := pluginsResponse.Msg.Plugins + if len(plugins) != 1 { + return syserror.Newf("unexpected number of plugins returned from server: %d", len(plugins)) + } + return bufprint.PrintEntity( + container.Stdout(), + format, + bufprint.NewPluginEntity(plugins[0], pluginFullName), + ) +} diff --git a/private/buf/cmd/buf/command/registry/plugin/plugininfo/usage.gen.go b/private/buf/cmd/buf/command/registry/plugin/plugininfo/usage.gen.go new file mode 100644 index 0000000000..7889165761 --- /dev/null +++ b/private/buf/cmd/buf/command/registry/plugin/plugininfo/usage.gen.go @@ -0,0 +1,19 @@ +// Copyright 2020-2024 Buf Technologies, Inc. +// +// 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. + +// Generated. DO NOT EDIT. + +package plugininfo + +import _ "github.com/bufbuild/buf/private/usage" diff --git a/private/buf/cmd/buf/command/registry/plugin/pluginupdate/pluginupdate.go b/private/buf/cmd/buf/command/registry/plugin/pluginupdate/pluginupdate.go new file mode 100644 index 0000000000..5656c1dc7b --- /dev/null +++ b/private/buf/cmd/buf/command/registry/plugin/pluginupdate/pluginupdate.go @@ -0,0 +1,138 @@ +// Copyright 2020-2024 Buf Technologies, Inc. +// +// 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 pluginupdate + +import ( + "context" + "fmt" + + pluginv1beta1 "buf.build/gen/go/bufbuild/registry/protocolbuffers/go/buf/registry/plugin/v1beta1" + "connectrpc.com/connect" + "github.com/bufbuild/buf/private/buf/bufcli" + "github.com/bufbuild/buf/private/bufpkg/bufparse" + "github.com/bufbuild/buf/private/bufpkg/bufregistryapi/bufregistryapiplugin" + "github.com/bufbuild/buf/private/pkg/app/appcmd" + "github.com/bufbuild/buf/private/pkg/app/appext" + "github.com/bufbuild/buf/private/pkg/syserror" + "github.com/spf13/pflag" +) + +const ( + visibilityFlagName = "visibility" + descriptionFlagName = "description" + urlFlagName = "url" +) + +// NewCommand returns a new Command. +func NewCommand(name string, builder appext.SubCommandBuilder) *appcmd.Command { + flags := newFlags() + return &appcmd.Command{ + Use: name + " ", + Short: "Update BSR plugin settings", + Args: appcmd.ExactArgs(1), + Run: builder.NewRunFunc( + func(ctx context.Context, container appext.Container) error { + return run(ctx, container, flags) + }, + ), + BindFlags: flags.Bind, + } +} + +type flags struct { + Visibility string + Description *string + URL *string + DefaultLabel string +} + +func newFlags() *flags { + return &flags{} +} + +func (f *flags) Bind(flagSet *pflag.FlagSet) { + bufcli.BindVisibility(flagSet, &f.Visibility, visibilityFlagName, true) + bufcli.BindStringPointer( + flagSet, + descriptionFlagName, + &f.Description, + "The new description for the plugin", + ) + bufcli.BindStringPointer( + flagSet, + urlFlagName, + &f.URL, + "The new URL for the plugin", + ) +} + +func run( + ctx context.Context, + container appext.Container, + flags *flags, +) error { + pluginFullName, err := bufparse.ParseFullName(container.Arg(0)) + if err != nil { + return appcmd.WrapInvalidArgumentError(err) + } + visibility, err := bufcli.VisibilityFlagToPluginVisibilityAllowUnspecified(flags.Visibility) + if err != nil { + return appcmd.WrapInvalidArgumentError(err) + } + clientConfig, err := bufcli.NewConnectClientConfig(container) + if err != nil { + return err + } + var visibilityUpdate *pluginv1beta1.PluginVisibility + if visibility != pluginv1beta1.PluginVisibility_PLUGIN_VISIBILITY_UNSPECIFIED { + visibilityUpdate = &visibility + } + + pluginServiceClient := bufregistryapiplugin.NewClientProvider(clientConfig). + V1Beta1PluginServiceClient(pluginFullName.Registry()) + + pluginResponse, err := pluginServiceClient.UpdatePlugins(ctx, connect.NewRequest( + &pluginv1beta1.UpdatePluginsRequest{ + Values: []*pluginv1beta1.UpdatePluginsRequest_Value{ + { + PluginRef: &pluginv1beta1.PluginRef{ + Value: &pluginv1beta1.PluginRef_Name_{ + Name: &pluginv1beta1.PluginRef_Name{ + Owner: pluginFullName.Owner(), + Plugin: pluginFullName.Name(), + }, + }, + }, + Visibility: visibilityUpdate, + }, + }, + }, + )) + if err != nil { + if connect.CodeOf(err) == connect.CodeNotFound { + return bufcli.NewModuleNotFoundError(container.Arg(0)) + } + return err + } + plugins := pluginResponse.Msg.Plugins + if len(plugins) != 1 { + return syserror.Newf("unexpected number of plugins returned from server: %d", len(plugins)) + } + _, err = fmt.Fprintf(container.Stdout(), "Updated %s.\n", pluginFullName) + if err != nil { + return syserror.Wrap(err) + } + return nil +} diff --git a/private/buf/cmd/buf/command/registry/plugin/pluginupdate/usage.gen.go b/private/buf/cmd/buf/command/registry/plugin/pluginupdate/usage.gen.go new file mode 100644 index 0000000000..23136ff2a4 --- /dev/null +++ b/private/buf/cmd/buf/command/registry/plugin/pluginupdate/usage.gen.go @@ -0,0 +1,19 @@ +// Copyright 2020-2024 Buf Technologies, Inc. +// +// 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. + +// Generated. DO NOT EDIT. + +package pluginupdate + +import _ "github.com/bufbuild/buf/private/usage"