Skip to content

Commit

Permalink
Promote beta registry organization, module, label and commit commands (
Browse files Browse the repository at this point in the history
…#3170)

This PR moves `[module, organization, label, commit]` commands out of
beta. Here are pruned outputs of `--help-tree` before and after.

Before

```
buf registry  --help-tree
registry         Manage assets on the Buf Schema Registry
  archive        Archive one or more labels for the given input
  commit         Manage a repository's commits
    get          Get commit details
    list         List repository commits
  label          Manage a repository's labels
    create       Create a label for a specified commit
    get          Get label details
    list         List repository labels
  organization   Manage organizations
    create       Create a new BSR organization
    delete       Delete a BSR organization
    get          Get a BSR organization
  repository     Manage repositories
    create       Create a BSR repository
    delete       Delete a BSR repository
    deprecate    Deprecate a BSR repository
    get          Get a BSR repository
    list         List BSR repositories
    undeprecate  Undeprecate a BSR repository
    update       Update BSR repository settings
  unarchive      Unarchive one or more labels for the given input
```

After

```
buf registry  --help-tree            
registry         Manage assets on the Buf Schema Registry
  commit         Manage a module's commits
    add-label    Add labels to a commit
    info         Get commit information
    list         List modules commits
    resolve      Resolve commit from a reference
  label          Manage a module's labels
    archive      Archive a module label
    info         Show label information
    list         List module labels
    unarchive    Unarchive a module label
  module         Manage BSR modules
    create       Create a BSR module
    delete       Delete a BSR module
    deprecate    Deprecate a BSR module
    info         Get a BSR module
    undeprecate  Undeprecate a BSR module
    update       Update BSR module settings
  organization   Manage organizations
    create       Create a new BSR organization
    delete       Delete a BSR organization
    info         Show information about a BSR organization
    update       Update a BSR organization
```

Fixes #1431

---------

Co-authored-by: bufdev <[email protected]>
  • Loading branch information
oliversun9 and bufdev authored Aug 6, 2024
1 parent 72d6cc3 commit 2ff1b33
Show file tree
Hide file tree
Showing 62 changed files with 1,444 additions and 1,142 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,14 @@
- Fix git input handling of annotated tags.
- Update `buf registry login` to complete the login flow in the browser by default. This allows
users to login with their browser and have the token automatically provided to the CLI.
- Add `buf registry organization {create, delete, info, update}` commands to manage BSR
organizations. Remove `buf beta registry organization` commands.
- Add `buf registry module {create, delete, deprecate, info, undeprecate, update}` commands to
manage BSR modules. Remove `buf beta registry repository` commands.
- Add `buf registry label {archive, info, list, unarchive}` commands to manage BSR module labels.
Remove `buf beta registry label` commands and `buf beta registy {archive, unarchive}`.
- Add `buf registry commit {add-label, info, list, resolve}` to manage BSR module commits. Remove
`buf beta registry commit` commands.

## [v1.35.1] - 2024-07-24

Expand Down
14 changes: 7 additions & 7 deletions private/buf/bufcli/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,10 @@ func NewOrganizationNameAlreadyExistsError(name string) error {
return fmt.Errorf("an organization named %q already exists", name)
}

// NewRepositoryNameAlreadyExistsError informs the user that a repository
// NewModuleNameAlreadyExistsError informs the user that a module
// with that name already exists.
func NewRepositoryNameAlreadyExistsError(name string) error {
return fmt.Errorf("a repository named %q already exists", name)
func NewModuleNameAlreadyExistsError(name string) error {
return fmt.Errorf("a module named %q already exists", name)
}

// NewLabelNameAlreadyExistsError informs the user that a label
Expand All @@ -57,7 +57,7 @@ func NewLabelNameAlreadyExistsError(name string) error {
// NewOrganizationNotFoundError informs the user that an organization with
// that name does not exist.
func NewOrganizationNotFoundError(name string) error {
return fmt.Errorf(`an organization named %q does not exist, use "buf beta registry organization create" to create one`, name)
return fmt.Errorf(`an organization named %q does not exist, use "buf registry organization create" to create one`, name)
}

// NewOrganizationOrUserNotFoundError informs the user that an organization or user with
Expand All @@ -66,10 +66,10 @@ func NewOrganizationOrUserNotFoundError(name string) error {
return fmt.Errorf(`an organization or user named %q does not exist`, name)
}

// NewRepositoryNotFoundError informs the user that a repository with
// NewModuleNotFoundError informs the user that a module with
// that name does not exist.
func NewRepositoryNotFoundError(name string) error {
return fmt.Errorf(`a repository named %q does not exist, use "buf beta registry repository create" to create one`, name)
func NewModuleNotFoundError(name string) error {
return fmt.Errorf(`a module named %q does not exist, use "buf registry module create" to create one`, name)
}

// NewModuleRefNotFoundError informs the user that a ModuleRef does not exist.
Expand Down
48 changes: 48 additions & 0 deletions private/buf/bufcli/flag_args_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// 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 bufcli

import (
"testing"

"github.com/spf13/pflag"
"github.com/stretchr/testify/require"
)

func TestStringPointerFlagSet(t *testing.T) {
t.Parallel()
expected := "foo"
testParseStringPointer(t, "test-flag-name", &expected, "--test-flag-name", "foo")
}

func TestStringPointerFlagSetEmpty(t *testing.T) {
t.Parallel()
expected := ""
testParseStringPointer(t, "test-flag-name", &expected, "--test-flag-name", "")
}

func TestStringPointerFlagNotSet(t *testing.T) {
t.Parallel()
testParseStringPointer(t, "test-flag-name", nil)
}

func testParseStringPointer(t *testing.T, flagName string, expectedResult *string, args ...string) {
var stringPointer *string
flagSet := pflag.NewFlagSet("test flag set", pflag.ContinueOnError)
BindStringPointer(flagSet, flagName, &stringPointer, "test usage")
err := flagSet.Parse(args)
require.NoError(t, err)
require.Equal(t, expectedResult, stringPointer)
}
65 changes: 48 additions & 17 deletions private/buf/bufcli/flags_args.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ import (
)

const (
DefaultArchiveStatus = unarchivedArchiveStatus

inputHashtagFlagName = "__hashtag__"
inputHashtagFlagShortName = "#"

Expand Down Expand Up @@ -142,12 +144,16 @@ By default, symlinks are followed in this CLI, but never followed on the Buf Sch
}

// BindVisibility binds the visibility flag.
func BindVisibility(flagSet *pflag.FlagSet, addr *string, flagName string) {
func BindVisibility(flagSet *pflag.FlagSet, addr *string, flagName string, emptyDefault bool) {
defaultVisibility := privateVisibility
if emptyDefault {
defaultVisibility = ""
}
flagSet.StringVar(
addr,
flagName,
"",
fmt.Sprintf(`The repository's visibility setting. Must be one of %s`, stringutil.SliceToString(allVisibiltyStrings)),
defaultVisibility,
fmt.Sprintf(`The module's visibility setting. Must be one of %s`, stringutil.SliceToString(allVisibiltyStrings)),
)
}

Expand All @@ -158,7 +164,7 @@ func BindCreateVisibility(flagSet *pflag.FlagSet, addr *string, flagName string,
addr,
flagName,
privateVisibility,
fmt.Sprintf(`The repository's visibility setting, if created. Can only be set with --%s. Must be one of %s`, createFlagName, stringutil.SliceToString(allVisibiltyStrings)),
fmt.Sprintf(`The module's visibility setting, if created. Can only be set with --%s. Must be one of %s`, createFlagName, stringutil.SliceToString(allVisibiltyStrings)),
)
}

Expand All @@ -168,11 +174,48 @@ func BindArchiveStatus(flagSet *pflag.FlagSet, addr *string, flagName string) {
flagSet.StringVar(
addr,
flagName,
unarchivedArchiveStatus,
DefaultArchiveStatus,
fmt.Sprintf(`The archive status of the labels listed. Must be one of %s`, stringutil.SliceToString(allArchiveStatusStrings)),
)
}

// Binds a string pointer flag, which indicates flag presence, i.e. `--flag ""` is not the same as not passing the flag.
//
// This is useful for buf registry organization/module update, where we only modify the fields specified.
//
// Value must not be nil.
func BindStringPointer(flagSet *pflag.FlagSet, name string, value **string, usage string) {
flagSet.Var(
&stringPointerValue{
valuePointer: value,
},
name,
usage,
)
}

// Implements pflag.Value.
type stringPointerValue struct {
// This must not be nil at construction time.
valuePointer **string
}

func (b *stringPointerValue) Type() string {
return "string"
}

func (b *stringPointerValue) String() string {
if *b.valuePointer == nil {
return ""
}
return **b.valuePointer
}

func (b *stringPointerValue) Set(value string) error {
*b.valuePointer = &value
return nil
}

// GetInputLong gets the long command description for an input-based command.
func GetInputLong(inputArgDescription string) string {
return fmt.Sprintf(
Expand Down Expand Up @@ -245,18 +288,6 @@ func GetInputValue(
return defaultValue, nil
}

// VisibilityFlagToVisibility parses the given string as a modulev1.ModuleVisibility
func VisibilityFlagToVisibility(visibility string) (modulev1.ModuleVisibility, error) {
switch visibility {
case publicVisibility:
return modulev1.ModuleVisibility_MODULE_VISIBILITY_PUBLIC, nil
case privateVisibility:
return modulev1.ModuleVisibility_MODULE_VISIBILITY_PRIVATE, nil
default:
return 0, fmt.Errorf("invalid visibility: %s, expected one of %s", visibility, stringutil.SliceToString(allVisibiltyStrings))
}
}

// VisibilityFlagToVisibilityAllowUnspecified parses the given string as a modulev1.ModuleVisibility
// where an empty string will be parsed as unspecified
func VisibilityFlagToVisibilityAllowUnspecified(visibility string) (modulev1.ModuleVisibility, error) {
Expand Down
2 changes: 1 addition & 1 deletion private/buf/bufcli/module_owner.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import (
// ModuleOwner represents a module owner, consisting of a registry and owner.
//
// This concept used to live in bufmodule but it doesn't really make sense there, as it isn't
// use anywhere else. We only use this in buf beta registry organization commands at the moment.
// use anywhere else. We only use this in buf registry organization commands at the moment.
type ModuleOwner interface {
// String returns "registry/owner".
fmt.Stringer
Expand Down
52 changes: 28 additions & 24 deletions private/buf/bufprint/bufprint.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,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"
"github.com/bufbuild/buf/private/bufpkg/bufmodule"
registryv1alpha1 "github.com/bufbuild/buf/private/gen/proto/go/buf/alpha/registry/v1alpha1"
"github.com/bufbuild/buf/private/pkg/connectclient"
"github.com/bufbuild/buf/private/pkg/protoencoding"
Expand Down Expand Up @@ -85,50 +86,53 @@ func NewCuratedPluginPrinter(writer io.Writer) CuratedPluginPrinter {

// OrganizationPrinter is an organization printer.
type OrganizationPrinter interface {
PrintOrganization(ctx context.Context, format Format, organization *ownerv1.Organization) error
PrintOrganizationInfo(ctx context.Context, format Format, organization *ownerv1.Organization) error
}

// NewOrganizationPrinter returns a new OrganizationPrinter.
func NewOrganizationPrinter(address string, writer io.Writer) OrganizationPrinter {
return newOrganizationPrinter(address, writer)
}

// RepositoryPrinter is a repository printer.
type RepositoryPrinter interface {
PrintRepository(ctx context.Context, format Format, repository *modulev1.Module) error
PrintRepositories(ctx context.Context, format Format, nextPageToken string, repositories ...*modulev1.Module) error
// ModulePrinter is a module printer.
type ModulePrinter interface {
PrintModuleInfo(ctx context.Context, format Format, repository *modulev1.Module) error
}

// NewRepositoryPrinter returns a new RepositoryPrinter.
func NewRepositoryPrinter(
// NewModulePrinter returns a new ModulePrinter.
func NewModulePrinter(
clientConfig *connectclient.Config,
address string,
writer io.Writer,
) RepositoryPrinter {
return newRepositoryPrinter(clientConfig, address, writer)
) ModulePrinter {
return newModulePrinter(clientConfig, address, writer)
}

// RepositoryLabelPrinter is a repository label printer.
// TODO: perhaps rename this to LabelPrinter along with other printers
type RepositoryLabelPrinter interface {
PrintRepositoryLabel(ctx context.Context, format Format, label *modulev1.Label) error
PrintRepositoryLabels(ctx context.Context, format Format, nextPageToken string, labels ...*modulev1.Label) error
// LabelPrinter is a repository label printer.
type LabelPrinter interface {
// PrintLabels prints each label on a new line.
PrintLabels(ctx context.Context, format Format, label ...*modulev1.Label) error
// PrintLabels prints information about a label.
PrintLabelInfo(ctx context.Context, format Format, label *modulev1.Label) error
// PrintLabelPage prints a page of labels.
PrintLabelPage(ctx context.Context, format Format, nextPageCommand, nextPageToken string, labels []*modulev1.Label) error
}

// NewRepositoryLabelPrinter returns a new RepositoryLabelPrinter.
func NewRepositoryLabelPrinter(writer io.Writer) RepositoryLabelPrinter {
return newRepositoryLabelPrinter(writer)
// NewLabelPrinter returns a new RepositoryLabelPrinter.
func NewLabelPrinter(writer io.Writer, moduleFullName bufmodule.ModuleFullName) LabelPrinter {
return newLabelPrinter(writer, moduleFullName)
}

// RepositoryCommitPrinter is a repository commit printer.
type RepositoryCommitPrinter interface {
PrintRepositoryCommit(ctx context.Context, format Format, repositoryCommit *modulev1.Commit) error
PrintRepositoryCommits(ctx context.Context, format Format, nextPageToken string, repositoryCommits ...*modulev1.Commit) error
// CommitPrinter is a commit printer.
type CommitPrinter interface {
PrintCommitInfo(ctx context.Context, format Format, commit *modulev1.Commit) error
PrintCommits(ctx context.Context, format Format, commits ...*modulev1.Commit) error
PrintCommitPage(ctx context.Context, format Format, nextPageCommand, nextPageToken string, commits []*modulev1.Commit) error
}

// NewRepositoryCommitPrinter returns a new RepositoryCommitPrinter.
func NewRepositoryCommitPrinter(writer io.Writer) RepositoryCommitPrinter {
return newRepositoryCommitPrinter(writer)
// NewCommitPrinter returns a new RepositoryCommitPrinter.
func NewCommitPrinter(writer io.Writer, moduleFullName bufmodule.ModuleFullName) CommitPrinter {
return newCommitPrinter(writer, moduleFullName)
}

// TokenPrinter is a token printer.
Expand Down
Loading

0 comments on commit 2ff1b33

Please sign in to comment.