Skip to content

Commit

Permalink
Move name parsing to bufparse pkg
Browse files Browse the repository at this point in the history
  • Loading branch information
emcfarlane committed Oct 29, 2024
1 parent 225aeaf commit ee44f6e
Show file tree
Hide file tree
Showing 11 changed files with 187 additions and 122 deletions.
2 changes: 1 addition & 1 deletion private/bufpkg/bufmodule/commit.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import (
"time"
)

// Commit represents a Commit on the BSR.
// Commit represents a Commit for a Module on the BSR.
type Commit interface {
// ModuleKey returns the ModuleKey for the Commit.
ModuleKey() ModuleKey
Expand Down
43 changes: 22 additions & 21 deletions private/bufpkg/bufmodule/digest.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
"strings"

"github.com/bufbuild/buf/private/bufpkg/bufcas"
"github.com/bufbuild/buf/private/bufpkg/bufparse"
"github.com/bufbuild/buf/private/pkg/slicesext"
"github.com/bufbuild/buf/private/pkg/storage"
"github.com/bufbuild/buf/private/pkg/syserror"
Expand Down Expand Up @@ -75,15 +76,15 @@ func (d DigestType) String() string {
//
// This reverses DigestType.String().
//
// Returns an error of type *ParseError if thie string could not be parsed.
// Returns an error of type *bufparse.ParseError if thie string could not be parsed.
func ParseDigestType(s string) (DigestType, error) {
d, ok := stringToDigestType[s]
if !ok {
return 0, &ParseError{
typeString: "module digest type",
input: s,
err: fmt.Errorf("unknown type: %q", s),
}
return 0, bufparse.NewParseError(
"module digest type",
s,
fmt.Errorf("unknown type: %q", s),
)
}
return d, nil
}
Expand Down Expand Up @@ -137,27 +138,27 @@ func ParseDigest(s string) (Digest, error) {
}
digestTypeString, hexValue, ok := strings.Cut(s, ":")
if !ok {
return nil, &ParseError{
typeString: "module digest",
input: s,
err: errors.New(`must in the form "digest_type:digest_hex_value"`),
}
return nil, bufparse.NewParseError(
"module digest",
s,
errors.New(`must in the form "digest_type:digest_hex_value"`),
)
}
digestType, err := ParseDigestType(digestTypeString)
if err != nil {
return nil, &ParseError{
typeString: "module digest",
input: s,
err: err,
}
return nil, bufparse.NewParseError(
"module digest",
s,
err,
)
}
value, err := hex.DecodeString(hexValue)
if err != nil {
return nil, &ParseError{
typeString: "module digest",
input: s,
err: errors.New(`could not parse hex: must in the form "digest_type:digest_hex_value"`),
}
return nil, bufparse.NewParseError(
"module digest",
s,
errors.New(`could not parse hex: must in the form "digest_type:digest_hex_value"`),
)
}
switch digestType {
case DigestTypeB4, DigestTypeB5:
Expand Down
59 changes: 0 additions & 59 deletions private/bufpkg/bufmodule/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,65 +76,6 @@ func (i *ImportNotExistError) Unwrap() error {
return fs.ErrNotExist
}

// ParseError is an error that occurred during parsing.
//
// This is returned by all Parse.* functions in this package.
type ParseError struct {
// typeString is the user-consumable string representing of the type that was attempted to be parsed.
//
// Users cannot rely on this data being structured.
// Examples: "digest", "digest type".
typeString string
// input is the input string that was attempted to be parsed.
input string
// err is the underlying error.
//
// Err may be a *ParseError itself.
//
// This is an error we may give back to the user, use pretty strings that should
// be read.
err error
}

// Error implements the error interface.
func (p *ParseError) Error() string {
if p == nil {
return ""
}
var builder strings.Builder
_, _ = builder.WriteString(`could not parse`)
if p.typeString != "" {
_, _ = builder.WriteString(` `)
_, _ = builder.WriteString(p.typeString)
}
if p.input != "" {
_, _ = builder.WriteString(` "`)
_, _ = builder.WriteString(p.input)
_, _ = builder.WriteString(`"`)
}
if p.err != nil {
_, _ = builder.WriteString(`: `)
_, _ = builder.WriteString(p.err.Error())
}
return builder.String()
}

// Unwrap returns the underlying error.
func (p *ParseError) Unwrap() error {
if p == nil {
return nil
}
return p.err
}

// Input returns the input string that was attempted to be parsed.
func (p *ParseError) Input() string {
if p == nil {
return ""
}
return p.input
}

// ModuleCycleError is the error returned if a cycle is detected in module dependencies.
type ModuleCycleError struct {
// Descriptions are the module descriptions that represent the cycle.
Expand Down
13 changes: 7 additions & 6 deletions private/bufpkg/bufmodule/file_type.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"fmt"
"strconv"

"github.com/bufbuild/buf/private/bufpkg/bufparse"
"github.com/bufbuild/buf/private/pkg/normalpath"
)

Expand Down Expand Up @@ -54,15 +55,15 @@ func (c FileType) String() string {
//
// This reverses FileType.String().
//
// Returns an error of type *ParseError if thie string could not be parsed.
// Returns an error of type *bufparse.ParseError if thie string could not be parsed.
func ParseFileType(s string) (FileType, error) {
c, ok := stringToFileType[s]
if !ok {
return 0, &ParseError{
typeString: "module file type",
input: s,
err: fmt.Errorf("unknown type: %q", s),
}
return 0, bufparse.NewParseError(
"module file type",
s,
fmt.Errorf("unknown type: %q", s),
)
}
return c, nil
}
Expand Down
2 changes: 0 additions & 2 deletions private/bufpkg/bufmodule/module_data.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,6 @@ func NewModuleData(

// *** PRIVATE ***

// moduleData

type moduleData struct {
moduleKey ModuleKey
getBucket func() (storage.ReadBucket, error)
Expand Down
15 changes: 8 additions & 7 deletions private/bufpkg/bufmodule/module_full_name.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"fmt"
"strings"

"github.com/bufbuild/buf/private/bufpkg/bufparse"
"github.com/bufbuild/buf/private/pkg/netext"
)

Expand Down Expand Up @@ -52,17 +53,17 @@ func NewModuleFullName(

// ParseModuleFullName parses a ModuleFullName from a string in the form "registry/owner/name".
func ParseModuleFullName(moduleFullNameString string) (ModuleFullName, error) {
// parseModuleFullNameComponents returns ParseErrors.
registry, owner, name, err := parseModuleFullNameComponents(moduleFullNameString)
// bufparse.ParseFullNameComponents returns *bufparse.ParseErrors.
registry, owner, name, err := bufparse.ParseFullNameComponents(moduleFullNameString)
if err != nil {
return nil, err
}
if err := validateModuleFullNameParameters(registry, owner, name); err != nil {
return nil, &ParseError{
typeString: "module name",
input: moduleFullNameString,
err: err,
}
return nil, bufparse.NewParseError(
"module name",
moduleFullNameString,
err,
)
}
// We don't rely on constructors for ParseErrors.
return NewModuleFullName(registry, owner, name)
Expand Down
6 changes: 4 additions & 2 deletions private/bufpkg/bufmodule/module_ref.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ package bufmodule
import (
"errors"
"fmt"

"github.com/bufbuild/buf/private/bufpkg/bufparse"
)

// ModuleRef is an unresolved reference to a Module.
Expand Down Expand Up @@ -54,8 +56,8 @@ func NewModuleRef(

// ParseModuleRef parses a ModuleRef from a string in the form "registry/owner/name[:ref]".
func ParseModuleRef(moduleRefString string) (ModuleRef, error) {
// Returns ParseErrors.
registry, owner, name, ref, err := parseModuleRefComponents(moduleRefString)
// Returns *bufparse.ParseErrors.
registry, owner, name, ref, err := bufparse.ParseRefComponents(moduleRefString)
if err != nil {
return nil, err
}
Expand Down
15 changes: 15 additions & 0 deletions private/bufpkg/bufparse/bufparse.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// 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 bufparse
85 changes: 85 additions & 0 deletions private/bufpkg/bufparse/errors.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
// 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 bufparse

import "strings"

// ParseError is an error that occurred during parsing.
//
// This is returned by all Parse.* functions in this package.
type ParseError struct {
// typeString is the user-consumable string representing of the type that was attempted to be parsed.
//
// Users cannot rely on this data being structured.
// Examples: "digest", "digest type".
typeString string
// input is the input string that was attempted to be parsed.
input string
// err is the underlying error.
//
// Err may be a *ParseError itself.
//
// This is an error we may give back to the user, use pretty strings that should
// be read.
err error
}

// NewParseError returns a new ParseError.
func NewParseError(typeString string, input string, err error) *ParseError {
return &ParseError{
typeString: typeString,
input: input,
err: err,
}
}

// Error implements the error interface.
func (p *ParseError) Error() string {
if p == nil {
return ""
}
var builder strings.Builder
_, _ = builder.WriteString(`could not parse`)
if p.typeString != "" {
_, _ = builder.WriteString(` `)
_, _ = builder.WriteString(p.typeString)
}
if p.input != "" {
_, _ = builder.WriteString(` "`)
_, _ = builder.WriteString(p.input)
_, _ = builder.WriteString(`"`)
}
if p.err != nil {
_, _ = builder.WriteString(`: `)
_, _ = builder.WriteString(p.err.Error())
}
return builder.String()
}

// Unwrap returns the underlying error.
func (p *ParseError) Unwrap() error {
if p == nil {
return nil
}
return p.err
}

// Input returns the input string that was attempted to be parsed.
func (p *ParseError) Input() string {
if p == nil {
return ""
}
return p.input
}
Loading

0 comments on commit ee44f6e

Please sign in to comment.