Skip to content

Commit 4519b93

Browse files
authored
Add buf registry plugin label commands (#3499)
1 parent 1101ca1 commit 4519b93

File tree

12 files changed

+641
-3
lines changed

12 files changed

+641
-3
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
- Add `buf plugin push` command to push a plugin to the Buf Schema Registry.
1010
Only WebAssembly check plugins are supported at this time.
1111
- Add `buf registry plugin commit {add-label,info,list,resolve}` to manage BSR plugin commits.
12+
- Add `buf registry plugin label {archive,info,list,unarchive}` to manage BSR plugin commits.
1213

1314
## [v1.47.2] - 2024-11-14
1415

private/buf/bufcli/flags_args.go

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -318,8 +318,8 @@ func VisibilityFlagToPluginVisibilityAllowUnspecified(visibility string) (plugin
318318
}
319319
}
320320

321-
// ArchiveStatusFlagToArchiveStatusFilter parses the given string as a modulev1.ListLabelsRequest_ArchiveFilter.
322-
func ArchiveStatusFlagToArchiveStatusFilter(archiveStatus string) (modulev1.ListLabelsRequest_ArchiveFilter, error) {
321+
// ArchiveStatusFlagToModuleArchiveStatusFilter parses the given string as a modulev1.ListLabelsRequest_ArchiveFilter.
322+
func ArchiveStatusFlagToModuleArchiveStatusFilter(archiveStatus string) (modulev1.ListLabelsRequest_ArchiveFilter, error) {
323323
switch archiveStatus {
324324
case archivedArchiveStatus:
325325
return modulev1.ListLabelsRequest_ARCHIVE_FILTER_ARCHIVED_ONLY, nil
@@ -332,6 +332,20 @@ func ArchiveStatusFlagToArchiveStatusFilter(archiveStatus string) (modulev1.List
332332
}
333333
}
334334

335+
// ArchiveStatusFlagToPluginArchiveStatusFilter parses the given string as a pluginv1beta1.ListLabelsRequest_ArchiveFilter.
336+
func ArchiveStatusFlagToPluginArchiveStatusFilter(archiveStatus string) (pluginv1beta1.ListLabelsRequest_ArchiveFilter, error) {
337+
switch archiveStatus {
338+
case archivedArchiveStatus:
339+
return pluginv1beta1.ListLabelsRequest_ARCHIVE_FILTER_ARCHIVED_ONLY, nil
340+
case unarchivedArchiveStatus:
341+
return pluginv1beta1.ListLabelsRequest_ARCHIVE_FILTER_UNARCHIVED_ONLY, nil
342+
case allArchiveStatus:
343+
return pluginv1beta1.ListLabelsRequest_ARCHIVE_FILTER_ALL, nil
344+
default:
345+
return 0, fmt.Errorf("invalid archive status: %s", archiveStatus)
346+
}
347+
}
348+
335349
// ValidateRequiredFlag validates that the required flag is set.
336350
func ValidateRequiredFlag[T comparable](flagName string, value T) error {
337351
var zero T

private/buf/cmd/buf/buf.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,10 @@ import (
8989
"github.com/bufbuild/buf/private/buf/cmd/buf/command/registry/plugin/plugincreate"
9090
"github.com/bufbuild/buf/private/buf/cmd/buf/command/registry/plugin/plugindelete"
9191
"github.com/bufbuild/buf/private/buf/cmd/buf/command/registry/plugin/plugininfo"
92+
"github.com/bufbuild/buf/private/buf/cmd/buf/command/registry/plugin/pluginlabel/pluginlabelarchive"
93+
"github.com/bufbuild/buf/private/buf/cmd/buf/command/registry/plugin/pluginlabel/pluginlabelinfo"
94+
"github.com/bufbuild/buf/private/buf/cmd/buf/command/registry/plugin/pluginlabel/pluginlabellist"
95+
"github.com/bufbuild/buf/private/buf/cmd/buf/command/registry/plugin/pluginlabel/pluginlabelunarchive"
9296
"github.com/bufbuild/buf/private/buf/cmd/buf/command/registry/plugin/pluginupdate"
9397
"github.com/bufbuild/buf/private/buf/cmd/buf/command/registry/registrycc"
9498
"github.com/bufbuild/buf/private/buf/cmd/buf/command/registry/registrylogin"
@@ -282,6 +286,16 @@ func NewRootCommand(name string) *appcmd.Command {
282286
plugincommitresolve.NewCommand("resolve", builder, ""),
283287
},
284288
},
289+
{
290+
Use: "label",
291+
Short: "Manage a plugin's labels",
292+
SubCommands: []*appcmd.Command{
293+
pluginlabelarchive.NewCommand("archive", builder, ""),
294+
pluginlabelinfo.NewCommand("info", builder, ""),
295+
pluginlabellist.NewCommand("list", builder, ""),
296+
pluginlabelunarchive.NewCommand("unarchive", builder, ""),
297+
},
298+
},
285299
plugincreate.NewCommand("create", builder),
286300
plugininfo.NewCommand("info", builder),
287301
plugindelete.NewCommand("delete", builder),

private/buf/cmd/buf/command/registry/module/modulelabel/modulelabellist/modulelabellist.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ func run(
110110
if err != nil {
111111
return appcmd.WrapInvalidArgumentError(err)
112112
}
113-
archiveStatusFitler, err := bufcli.ArchiveStatusFlagToArchiveStatusFilter(flags.ArchiveStatus)
113+
archiveStatusFitler, err := bufcli.ArchiveStatusFlagToModuleArchiveStatusFilter(flags.ArchiveStatus)
114114
if err != nil {
115115
return appcmd.WrapInvalidArgumentError(err)
116116
}
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
// Copyright 2020-2024 Buf Technologies, Inc.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package pluginlabelarchive
16+
17+
import (
18+
"context"
19+
"fmt"
20+
21+
pluginv1beta1 "buf.build/gen/go/bufbuild/registry/protocolbuffers/go/buf/registry/plugin/v1beta1"
22+
"connectrpc.com/connect"
23+
"github.com/bufbuild/buf/private/buf/bufcli"
24+
"github.com/bufbuild/buf/private/bufpkg/bufparse"
25+
"github.com/bufbuild/buf/private/bufpkg/bufregistryapi/bufregistryapiplugin"
26+
"github.com/bufbuild/buf/private/pkg/app/appcmd"
27+
"github.com/bufbuild/buf/private/pkg/app/appext"
28+
"github.com/spf13/pflag"
29+
)
30+
31+
// NewCommand returns a new Command.
32+
func NewCommand(
33+
name string,
34+
builder appext.SubCommandBuilder,
35+
deprecated string,
36+
) *appcmd.Command {
37+
flags := newFlags()
38+
return &appcmd.Command{
39+
Use: name + " <remote/owner/plugin:label>",
40+
Short: "Archive a plugin label",
41+
Args: appcmd.ExactArgs(1),
42+
Deprecated: deprecated,
43+
Run: builder.NewRunFunc(
44+
func(ctx context.Context, container appext.Container) error {
45+
return run(ctx, container, flags)
46+
},
47+
),
48+
BindFlags: flags.Bind,
49+
}
50+
}
51+
52+
type flags struct {
53+
}
54+
55+
func newFlags() *flags {
56+
return &flags{}
57+
}
58+
59+
func (f *flags) Bind(flagSet *pflag.FlagSet) {
60+
}
61+
62+
func run(
63+
ctx context.Context,
64+
container appext.Container,
65+
_ *flags,
66+
) error {
67+
pluginRef, err := bufparse.ParseRef(container.Arg(0))
68+
if err != nil {
69+
return appcmd.WrapInvalidArgumentError(err)
70+
}
71+
labelName := pluginRef.Ref()
72+
if labelName == "" {
73+
return appcmd.NewInvalidArgumentError("label is required")
74+
}
75+
clientConfig, err := bufcli.NewConnectClientConfig(container)
76+
if err != nil {
77+
return err
78+
}
79+
pluginFullName := pluginRef.FullName()
80+
labelServiceClient := bufregistryapiplugin.NewClientProvider(clientConfig).V1Beta1LabelServiceClient(pluginFullName.Registry())
81+
// ArchiveLabelsResponse is empty.
82+
if _, err := labelServiceClient.ArchiveLabels(
83+
ctx,
84+
connect.NewRequest(
85+
&pluginv1beta1.ArchiveLabelsRequest{
86+
LabelRefs: []*pluginv1beta1.LabelRef{
87+
{
88+
Value: &pluginv1beta1.LabelRef_Name_{
89+
Name: &pluginv1beta1.LabelRef_Name{
90+
Owner: pluginFullName.Owner(),
91+
Plugin: pluginFullName.Name(),
92+
Label: labelName,
93+
},
94+
},
95+
},
96+
},
97+
},
98+
),
99+
); err != nil {
100+
if connect.CodeOf(err) == connect.CodeNotFound {
101+
return bufcli.NewLabelNotFoundError(pluginRef)
102+
}
103+
return err
104+
}
105+
_, err = fmt.Fprintf(container.Stdout(), "Archived %s.\n", pluginRef)
106+
return err
107+
}

private/buf/cmd/buf/command/registry/plugin/pluginlabel/pluginlabelarchive/usage.gen.go

Lines changed: 19 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
// Copyright 2020-2024 Buf Technologies, Inc.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package pluginlabelinfo
16+
17+
import (
18+
"context"
19+
"fmt"
20+
21+
pluginv1beta1 "buf.build/gen/go/bufbuild/registry/protocolbuffers/go/buf/registry/plugin/v1beta1"
22+
"connectrpc.com/connect"
23+
"github.com/bufbuild/buf/private/buf/bufcli"
24+
"github.com/bufbuild/buf/private/buf/bufprint"
25+
"github.com/bufbuild/buf/private/bufpkg/bufparse"
26+
"github.com/bufbuild/buf/private/bufpkg/bufregistryapi/bufregistryapiplugin"
27+
"github.com/bufbuild/buf/private/pkg/app/appcmd"
28+
"github.com/bufbuild/buf/private/pkg/app/appext"
29+
"github.com/bufbuild/buf/private/pkg/syserror"
30+
"github.com/spf13/pflag"
31+
)
32+
33+
const formatFlagName = "format"
34+
35+
// NewCommand returns a new Command
36+
func NewCommand(
37+
name string,
38+
builder appext.SubCommandBuilder,
39+
deprecated string,
40+
) *appcmd.Command {
41+
flags := newFlags()
42+
return &appcmd.Command{
43+
Use: name + " <remote/owner/plugin:label>",
44+
Short: "Show label information",
45+
Args: appcmd.ExactArgs(1),
46+
Deprecated: deprecated,
47+
Run: builder.NewRunFunc(
48+
func(ctx context.Context, container appext.Container) error {
49+
return run(ctx, container, flags)
50+
},
51+
),
52+
BindFlags: flags.Bind,
53+
}
54+
}
55+
56+
type flags struct {
57+
Format string
58+
}
59+
60+
func newFlags() *flags {
61+
return &flags{}
62+
}
63+
64+
func (f *flags) Bind(flagSet *pflag.FlagSet) {
65+
flagSet.StringVar(
66+
&f.Format,
67+
formatFlagName,
68+
bufprint.FormatText.String(),
69+
fmt.Sprintf(`The output format to use. Must be one of %s`, bufprint.AllFormatsString),
70+
)
71+
}
72+
73+
func run(
74+
ctx context.Context,
75+
container appext.Container,
76+
flags *flags,
77+
) error {
78+
pluginRef, err := bufparse.ParseRef(container.Arg(0))
79+
if err != nil {
80+
return appcmd.WrapInvalidArgumentError(err)
81+
}
82+
labelName := pluginRef.Ref()
83+
if labelName == "" {
84+
return appcmd.NewInvalidArgumentError("label is required")
85+
}
86+
format, err := bufprint.ParseFormat(flags.Format)
87+
if err != nil {
88+
return appcmd.WrapInvalidArgumentError(err)
89+
}
90+
clientConfig, err := bufcli.NewConnectClientConfig(container)
91+
if err != nil {
92+
return err
93+
}
94+
pluginClientProvider := bufregistryapiplugin.NewClientProvider(clientConfig)
95+
pluginFullName := pluginRef.FullName()
96+
labelServiceClient := pluginClientProvider.V1Beta1LabelServiceClient(pluginFullName.Registry())
97+
resp, err := labelServiceClient.GetLabels(
98+
ctx,
99+
connect.NewRequest(
100+
&pluginv1beta1.GetLabelsRequest{
101+
LabelRefs: []*pluginv1beta1.LabelRef{
102+
{
103+
Value: &pluginv1beta1.LabelRef_Name_{
104+
Name: &pluginv1beta1.LabelRef_Name{
105+
Owner: pluginFullName.Owner(),
106+
Plugin: pluginFullName.Name(),
107+
Label: labelName,
108+
},
109+
},
110+
},
111+
},
112+
},
113+
),
114+
)
115+
if err != nil {
116+
if connect.CodeOf(err) == connect.CodeNotFound {
117+
return bufcli.NewLabelNotFoundError(pluginRef)
118+
}
119+
return err
120+
}
121+
labels := resp.Msg.Labels
122+
if len(labels) != 1 {
123+
return syserror.Newf("expect 1 label from response, got %d", len(labels))
124+
}
125+
return bufprint.PrintEntity(
126+
container.Stdout(),
127+
format,
128+
bufprint.NewLabelEntity(labels[0], pluginFullName),
129+
)
130+
}

private/buf/cmd/buf/command/registry/plugin/pluginlabel/pluginlabelinfo/usage.gen.go

Lines changed: 19 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)