Skip to content

Commit

Permalink
Add plugin registry commit commands
Browse files Browse the repository at this point in the history
  • Loading branch information
emcfarlane committed Nov 27, 2024
1 parent bbefdb8 commit 4f00937
Show file tree
Hide file tree
Showing 17 changed files with 816 additions and 18 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

- Add `buf registry plugin {create,delete,info,update}` commands to manage BSR plugins.
- Breaking analysis support for `buf beta lsp`.
- Add `buf registry plugin commit {add-label,info,list,resolve}` to manage BSR plugin commits.

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

Expand Down
45 changes: 35 additions & 10 deletions private/buf/bufprint/bufprint.go
Original file line number Diff line number Diff line change
Expand Up @@ -199,8 +199,8 @@ func PrintEntity(writer io.Writer, format Format, entity Entity) error {
}
}

// NewLabelEntity returns a new label entity to print.
func NewLabelEntity(label *modulev1.Label, moduleFullName bufparse.FullName) Entity {
// NewModuleLabelEntity returns a new label entity to print.
func NewModuleLabelEntity(label *modulev1.Label, moduleFullName bufparse.FullName) Entity {
var archiveTime *time.Time
if label.ArchiveTime != nil {
timeValue := label.ArchiveTime.AsTime()
Expand All @@ -211,16 +211,16 @@ func NewLabelEntity(label *modulev1.Label, moduleFullName bufparse.FullName) Ent
Commit: label.CommitId,
CreateTime: label.CreateTime.AsTime(),
ArchiveTime: archiveTime,
moduleFullName: moduleFullName,
entityFullName: moduleFullName,
}
}

// NewCommitEntity returns a new commit entity to print.
func NewCommitEntity(commit *modulev1.Commit, moduleFullName bufparse.FullName) Entity {
// NewModuleCommitEntity returns a new commit entity to print.
func NewModuleCommitEntity(commit *modulev1.Commit, moduleFullName bufparse.FullName) Entity {
return outputCommit{
Commit: commit.Id,
CreateTime: commit.CreateTime.AsTime(),
moduleFullName: moduleFullName,
entityFullName: moduleFullName,
}
}

Expand Down Expand Up @@ -261,6 +261,31 @@ func NewPluginEntity(plugin *pluginv1beta1.Plugin, pluginFullName bufparse.FullN
}
}

// NewPluginLabelEntity returns a new label entity to print.
func NewPluginLabelEntity(label *pluginv1beta1.Label, pluginFullName bufparse.FullName) Entity {
var archiveTime *time.Time
if label.ArchiveTime != nil {
timeValue := label.ArchiveTime.AsTime()
archiveTime = &timeValue
}
return outputLabel{
Name: label.Name,
Commit: label.CommitId,
CreateTime: label.CreateTime.AsTime(),
ArchiveTime: archiveTime,
entityFullName: pluginFullName,
}
}

// NewPluginCommitEntity returns a new commit entity to print.
func NewPluginCommitEntity(commit *pluginv1beta1.Commit, moduleFullName bufparse.FullName) Entity {
return outputCommit{
Commit: commit.Id,
CreateTime: commit.CreateTime.AsTime(),
entityFullName: moduleFullName,
}
}

// NewUserEntity returns a new user entity to print.
func NewUserEntity(user *registryv1alpha1.User) Entity {
return outputUser{
Expand Down Expand Up @@ -434,22 +459,22 @@ type outputLabel struct {
CreateTime time.Time `json:"create_time,omitempty" bufprint:"Create Time"`
ArchiveTime *time.Time `json:"archive_time,omitempty" bufprint:"Archive Time,omitempty"`

moduleFullName bufparse.FullName
entityFullName bufparse.FullName
}

func (l outputLabel) fullName() string {
return fmt.Sprintf("%s:%s", l.moduleFullName.String(), l.Name)
return fmt.Sprintf("%s:%s", l.entityFullName.String(), l.Name)
}

type outputCommit struct {
Commit string `json:"commit,omitempty" bufprint:"Commit"`
CreateTime time.Time `json:"create_time,omitempty" bufprint:"Create Time"`

moduleFullName bufparse.FullName
entityFullName bufparse.FullName
}

func (c outputCommit) fullName() string {
return fmt.Sprintf("%s:%s", c.moduleFullName.String(), c.Commit)
return fmt.Sprintf("%s:%s", c.entityFullName.String(), c.Commit)
}

type outputModule struct {
Expand Down
14 changes: 14 additions & 0 deletions private/buf/cmd/buf/buf.go
Original file line number Diff line number Diff line change
Expand Up @@ -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/plugincommit/plugincommitaddlabel"
"github.com/bufbuild/buf/private/buf/cmd/buf/command/registry/plugin/plugincommit/plugincommitinfo"
"github.com/bufbuild/buf/private/buf/cmd/buf/command/registry/plugin/plugincommit/plugincommitlist"
"github.com/bufbuild/buf/private/buf/cmd/buf/command/registry/plugin/plugincommit/plugincommitresolve"
"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"
Expand Down Expand Up @@ -260,6 +264,16 @@ func NewRootCommand(name string) *appcmd.Command {
Use: "plugin",
Short: "Manage BSR plugins",
SubCommands: []*appcmd.Command{
{
Use: "commit",
Short: "Manage a plugin's commits",
SubCommands: []*appcmd.Command{
plugincommitaddlabel.NewCommand("add-label", builder, ""),
plugincommitinfo.NewCommand("info", builder, ""),
plugincommitlist.NewCommand("list", builder, ""),
plugincommitresolve.NewCommand("resolve", builder, ""),
},
},
plugincreate.NewCommand("create", builder),
plugininfo.NewCommand("info", builder),
plugindelete.NewCommand("delete", builder),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ func run(
container.Stdout(),
format,
slicesext.Map(resp.Msg.Labels, func(label *modulev1.Label) bufprint.Entity {
return bufprint.NewLabelEntity(label, moduleRef.FullName())
return bufprint.NewModuleLabelEntity(label, moduleRef.FullName())
})...,
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,6 @@ func run(
return bufprint.PrintEntity(
container.Stdout(),
format,
bufprint.NewCommitEntity(commits[0], moduleRef.FullName()),
bufprint.NewModuleCommitEntity(commits[0], moduleRef.FullName()),
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ func run(
format,
"",
"",
[]bufprint.Entity{bufprint.NewCommitEntity(commit, moduleRef.FullName())},
[]bufprint.Entity{bufprint.NewModuleCommitEntity(commit, moduleRef.FullName())},
)
}
if resource.GetModule() != nil {
Expand Down Expand Up @@ -200,7 +200,7 @@ func run(
resp.Msg.NextPageToken,
nextPageCommand(container, flags, resp.Msg.NextPageToken),
slicesext.Map(resp.Msg.Commits, func(commit *modulev1.Commit) bufprint.Entity {
return bufprint.NewCommitEntity(commit, moduleRef.FullName())
return bufprint.NewModuleCommitEntity(commit, moduleRef.FullName())
}),
)
}
Expand Down Expand Up @@ -252,7 +252,7 @@ func run(
resp.Msg.NextPageToken,
nextPageCommand(container, flags, resp.Msg.NextPageToken),
slicesext.Map(commits, func(commit *modulev1.Commit) bufprint.Entity {
return bufprint.NewCommitEntity(commit, moduleRef.FullName())
return bufprint.NewModuleCommitEntity(commit, moduleRef.FullName())
}),
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,6 @@ func run(
return bufprint.PrintNames(
container.Stdout(),
format,
bufprint.NewCommitEntity(commit, moduleRef.FullName()),
bufprint.NewModuleCommitEntity(commit, moduleRef.FullName()),
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,6 @@ func run(
return bufprint.PrintEntity(
container.Stdout(),
format,
bufprint.NewLabelEntity(labels[0], moduleFullName),
bufprint.NewModuleLabelEntity(labels[0], moduleFullName),
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ func run(
resp.Msg.NextPageToken,
nextPageCommand(container, flags, resp.Msg.NextPageToken),
slicesext.Map(resp.Msg.Labels, func(label *modulev1.Label) bufprint.Entity {
return bufprint.NewLabelEntity(label, moduleFullName)
return bufprint.NewModuleLabelEntity(label, moduleFullName)
}),
)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
// 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 plugincommitaddlabel

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/slicesext"
"github.com/bufbuild/buf/private/pkg/uuidutil"
"github.com/spf13/pflag"
)

const (
formatFlagName = "format"
labelsFlagName = "label"
)

// NewCommand returns a new Command.
func NewCommand(
name string,
builder appext.SubCommandBuilder,
deprecated string,
) *appcmd.Command {
flags := newFlags()
return &appcmd.Command{
Use: name + " <remote/owner/plugin:commit> --label <label>",
Short: "Add labels to a commit",
Args: appcmd.ExactArgs(1),
Deprecated: deprecated,
Run: builder.NewRunFunc(
func(ctx context.Context, container appext.Container) error {
return run(ctx, container, flags)
},
),
BindFlags: flags.Bind,
}
}

type flags struct {
Format string
Labels []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),
)
flagSet.StringSliceVar(
&f.Labels,
labelsFlagName,
nil,
"The labels to add to the commit. Must have at least one",
)
}

func run(
ctx context.Context,
container appext.Container,
flags *flags,
) error {
pluginRef, err := bufparse.ParseRef(container.Arg(0))
if err != nil {
return appcmd.WrapInvalidArgumentError(err)
}
if pluginRef.Ref() == "" {
return appcmd.NewInvalidArgumentError("commit is required")
}
commitID := pluginRef.Ref()
if _, err := uuidutil.FromDashless(commitID); err != nil {
return appcmd.NewInvalidArgumentErrorf("invalid commit: %w", err)
}
labels := flags.Labels
if len(labels) == 0 {
return appcmd.NewInvalidArgumentError("must create at least one label")
}
format, err := bufprint.ParseFormat(flags.Format)
if err != nil {
return appcmd.WrapInvalidArgumentError(err)
}
clientConfig, err := bufcli.NewConnectClientConfig(container)
if err != nil {
return err
}
pluginClientProvider := bufregistryapiplugin.NewClientProvider(clientConfig)
labelServiceClient := pluginClientProvider.V1Beta1LabelServiceClient(pluginRef.FullName().Registry())
requestValues := slicesext.Map(labels, func(label string) *pluginv1beta1.CreateOrUpdateLabelsRequest_Value {
return &pluginv1beta1.CreateOrUpdateLabelsRequest_Value{
LabelRef: &pluginv1beta1.LabelRef{
Value: &pluginv1beta1.LabelRef_Name_{
Name: &pluginv1beta1.LabelRef_Name{
Owner: pluginRef.FullName().Owner(),
Plugin: pluginRef.FullName().Name(),
Label: label,
},
},
},
CommitId: commitID,
}
})
resp, err := labelServiceClient.CreateOrUpdateLabels(
ctx,
connect.NewRequest(
&pluginv1beta1.CreateOrUpdateLabelsRequest{
Values: requestValues,
},
),
)
if err != nil {
// Not explicitly handling error with connect.CodeNotFound as
// it can be Plugin or Commit not found error. May be caused by
// a misformatted ID.
return err
}
return bufprint.PrintNames(
container.Stdout(),
format,
slicesext.Map(resp.Msg.Labels, func(label *pluginv1beta1.Label) bufprint.Entity {
return bufprint.NewPluginLabelEntity(label, pluginRef.FullName())
})...,
)
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 4f00937

Please sign in to comment.