Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Error wrapping from newer to older in the error chain #112

Merged
merged 22 commits into from
Nov 29, 2024
Merged
Show file tree
Hide file tree
Changes from 19 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion cmd/modulectl/create/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ type Service interface {

func NewCmd(service Service) (*cobra.Command, error) {
if service == nil {
return nil, fmt.Errorf("%w: service must not be nil", commonerrors.ErrInvalidArg)
return nil, fmt.Errorf("service must not be nil: %w", commonerrors.ErrInvalidArg)
}

opts := create.Options{}
Expand Down
2 changes: 1 addition & 1 deletion cmd/modulectl/scaffold/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ type Service interface {

func NewCmd(service Service) (*cobra.Command, error) {
if service == nil {
return nil, fmt.Errorf("%w: service must not be nil", commonerrors.ErrInvalidArg)
return nil, fmt.Errorf("service must not be nil: %w", commonerrors.ErrInvalidArg)
}

opts := scaffold.Options{}
Expand Down
35 changes: 17 additions & 18 deletions internal/common/validation/validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,17 @@ const (

func ValidateModuleName(name string) error {
if name == "" {
return fmt.Errorf("%w: opts.ModuleName must not be empty", commonerrors.ErrInvalidOption)
return fmt.Errorf("opts.ModuleName must not be empty: %w", commonerrors.ErrInvalidOption)
}

if len(name) > moduleNameMaxLength {
return fmt.Errorf("%w: opts.ModuleName length must not exceed %q characters", commonerrors.ErrInvalidOption,
moduleNameMaxLength)
return fmt.Errorf("opts.ModuleName length must not exceed %q characters: %w", moduleNameMaxLength, commonerrors.ErrInvalidOption)
}

if matched, err := regexp.MatchString(moduleNamePattern, name); err != nil {
return fmt.Errorf("%w: failed to evaluate regex pattern for opts.ModuleName", commonerrors.ErrInvalidOption)
return fmt.Errorf("failed to evaluate regex pattern for opts.ModuleName: %w", commonerrors.ErrInvalidOption)
} else if !matched {
return fmt.Errorf("%w: opts.ModuleName must match the required pattern, e.g: 'github.com/path-to/your-repo'",
return fmt.Errorf("opts.ModuleName must match the required pattern, e.g: 'github.com/path-to/your-repo': %w",
commonerrors.ErrInvalidOption)
}

Expand All @@ -41,7 +40,7 @@ func ValidateModuleName(name string) error {

func ValidateModuleVersion(version string) error {
if version == "" {
return fmt.Errorf("%w: opts.ModuleVersion must not be empty", commonerrors.ErrInvalidOption)
return fmt.Errorf("opts.ModuleVersion must not be empty: %w", commonerrors.ErrInvalidOption)
}

if err := validateSemanticVersion(version); err != nil {
Expand All @@ -53,7 +52,7 @@ func ValidateModuleVersion(version string) error {

func ValidateModuleNamespace(namespace string) error {
if namespace == "" {
return fmt.Errorf("%w: opts.ModuleNamespace must not be empty", commonerrors.ErrInvalidOption)
return fmt.Errorf("opts.ModuleNamespace must not be empty: %w", commonerrors.ErrInvalidOption)
}

if err := ValidateNamespace(namespace); err != nil {
Expand All @@ -65,15 +64,15 @@ func ValidateModuleNamespace(namespace string) error {

func ValidateNamespace(namespace string) error {
if len(namespace) > namespaceMaxLength {
return fmt.Errorf("%w: opts.ModuleNamespace length must not exceed %q characters",
commonerrors.ErrInvalidOption,
namespaceMaxLength)
return fmt.Errorf("opts.ModuleNamespace length must not exceed %q characters: %w",
namespaceMaxLength,
commonerrors.ErrInvalidOption)
}

if matched, err := regexp.MatchString(namespacePattern, namespace); err != nil {
return fmt.Errorf("failed to evaluate regex pattern for module namespace: %w", err)
} else if !matched {
return fmt.Errorf("%w: namespace must match the required pattern, only small alphanumeric characters and hyphens",
return fmt.Errorf("namespace must match the required pattern, only small alphanumeric characters and hyphens: %w",
commonerrors.ErrInvalidOption)
}

Expand All @@ -83,11 +82,11 @@ func ValidateNamespace(namespace string) error {
func ValidateMapEntries(nameLinkMap map[string]string) error {
for name, link := range nameLinkMap {
if name == "" {
return fmt.Errorf("%w: name must not be empty", commonerrors.ErrInvalidOption)
return fmt.Errorf("name must not be empty: %w", commonerrors.ErrInvalidOption)
}

if link == "" {
return fmt.Errorf("%w: link must not be empty", commonerrors.ErrInvalidOption)
return fmt.Errorf("link must not be empty: %w", commonerrors.ErrInvalidOption)
}

if err := ValidateIsValidHTTPSURL(link); err != nil {
Expand All @@ -100,16 +99,16 @@ func ValidateMapEntries(nameLinkMap map[string]string) error {

func ValidateIsValidHTTPSURL(input string) error {
if input == "" {
return fmt.Errorf("%w: must not be empty", commonerrors.ErrInvalidOption)
return fmt.Errorf("must not be empty: %w", commonerrors.ErrInvalidOption)
}

_url, err := url.Parse(input)
if err != nil {
return fmt.Errorf("%w: '%s' is not a valid URL", commonerrors.ErrInvalidOption, input)
return fmt.Errorf("'%s' is not a valid URL: %w", input, commonerrors.ErrInvalidOption)
}

if _url.Scheme != "https" {
return fmt.Errorf("%w: '%s' is not using https scheme", commonerrors.ErrInvalidOption, input)
return fmt.Errorf("'%s' is not using https scheme: %w", input, commonerrors.ErrInvalidOption)
}

return nil
Expand All @@ -118,8 +117,8 @@ func ValidateIsValidHTTPSURL(input string) error {
func validateSemanticVersion(version string) error {
_, err := semver.StrictNewVersion(strings.TrimSpace(version))
if err != nil {
return fmt.Errorf("%w: opts.ModuleVersion failed to parse as semantic version: %w",
commonerrors.ErrInvalidOption, err)
return fmt.Errorf("opts.ModuleVersion failed to be parsed as semantic version: %w",
commonerrors.ErrInvalidOption)
}

return nil
Expand Down
2 changes: 1 addition & 1 deletion internal/service/componentarchive/componentarchive.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ type Service struct {

func NewService(fileSystem ArchiveFileSystem) (*Service, error) {
if fileSystem == nil {
return nil, fmt.Errorf("%w: fileSystem must not be nil", commonerrors.ErrInvalidArg)
return nil, fmt.Errorf("fileSystem must not be nil: %w", commonerrors.ErrInvalidArg)
}

return &Service{
Expand Down
2 changes: 1 addition & 1 deletion internal/service/componentdescriptor/gitsources.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ type GitSourcesService struct {

func NewGitSourcesService(gitService GitService) (*GitSourcesService, error) {
if gitService == nil {
return nil, fmt.Errorf("%w: gitService must not be nil", commonerrors.ErrInvalidArg)
return nil, fmt.Errorf("gitService must not be nil: %w", commonerrors.ErrInvalidArg)
}

return &GitSourcesService{
Expand Down
6 changes: 3 additions & 3 deletions internal/service/componentdescriptor/securityconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ type SecurityConfigService struct {

func NewSecurityConfigService(fileReader FileReader) (*SecurityConfigService, error) {
if fileReader == nil {
return nil, fmt.Errorf("%w: fileReader must not be nil", commonerrors.ErrInvalidArg)
return nil, fmt.Errorf("fileReader must not be nil: %w", commonerrors.ErrInvalidArg)
}

return &SecurityConfigService{
Expand Down Expand Up @@ -193,12 +193,12 @@ func appendLabelToAccessor(labeled compdesc.LabelsAccessor, key, value, baseKey
func GetImageNameAndTag(imageURL string) (string, string, error) {
imageTag := strings.Split(imageURL, ":")
if len(imageTag) != imageTagSlicesLength {
return "", "", fmt.Errorf("%w: , image URL: %s", errInvalidURL, imageURL)
return "", "", fmt.Errorf("image URL: %s: %w", imageURL, errInvalidURL)
}

imageName := strings.Split(imageTag[0], "/")
if len(imageName) == 0 {
return "", "", fmt.Errorf("%w: , image URL: %s", errInvalidURL, imageURL)
return "", "", fmt.Errorf("image URL: %s: %w", imageURL, errInvalidURL)
}

return imageName[len(imageName)-1], imageTag[len(imageTag)-1], nil
Expand Down
12 changes: 6 additions & 6 deletions internal/service/contentprovider/moduleconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ type ModuleConfigProvider struct {

func NewModuleConfigProvider(yamlConverter ObjectToYAMLConverter) (*ModuleConfigProvider, error) {
if yamlConverter == nil {
return nil, fmt.Errorf("%w: yamlConverter must not be nil", commonerrors.ErrInvalidArg)
return nil, fmt.Errorf("yamlConverter must not be nil: %w", commonerrors.ErrInvalidArg)
}

return &ModuleConfigProvider{
Expand Down Expand Up @@ -48,19 +48,19 @@ func (s *ModuleConfigProvider) getModuleConfig(args types.KeyValueArgs) ModuleCo

func (s *ModuleConfigProvider) validateArgs(args types.KeyValueArgs) error {
if args == nil {
return fmt.Errorf("%w: args must not be nil", ErrInvalidArg)
return fmt.Errorf("args must not be nil: %w", ErrInvalidArg)
}

if value, ok := args[ArgModuleName]; !ok {
return fmt.Errorf("%w: %s", ErrMissingArg, ArgModuleName)
return fmt.Errorf("%s: %w", ArgModuleName, ErrMissingArg)
} else if value == "" {
return fmt.Errorf("%w: %s must not be empty", ErrInvalidArg, ArgModuleName)
return fmt.Errorf("%s must not be empty: %w", ArgModuleName, ErrInvalidArg)
}

if value, ok := args[ArgModuleVersion]; !ok {
return fmt.Errorf("%w: %s", ErrMissingArg, ArgModuleVersion)
return fmt.Errorf("%s: %w", ArgModuleVersion, ErrMissingArg)
} else if value == "" {
return fmt.Errorf("%w: %s must not be empty", ErrInvalidArg, ArgModuleVersion)
return fmt.Errorf("%s must not be empty: %w", ArgModuleVersion, ErrInvalidArg)
}

return nil
Expand Down
8 changes: 4 additions & 4 deletions internal/service/contentprovider/securityconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ type SecurityConfig struct {

func NewSecurityConfig(yamlConverter ObjectToYAMLConverter) (*SecurityConfig, error) {
if yamlConverter == nil {
return nil, fmt.Errorf("%w: yamlConverter must not be nil", commonerrors.ErrInvalidArg)
return nil, fmt.Errorf("yamlConverter must not be nil: %w", commonerrors.ErrInvalidArg)
}

return &SecurityConfig{
Expand All @@ -31,16 +31,16 @@ func (s *SecurityConfig) GetDefaultContent(args types.KeyValueArgs) (string, err

func (s *SecurityConfig) validateArgs(args types.KeyValueArgs) error {
if args == nil {
return fmt.Errorf("%w: args must not be nil", ErrInvalidArg)
return fmt.Errorf("args must not be nil: %w", ErrInvalidArg)
}

value, ok := args[ArgModuleName]
if !ok {
return fmt.Errorf("%w: %s", ErrMissingArg, ArgModuleName)
return fmt.Errorf("%s: %w", ArgModuleName, ErrMissingArg)
}

if value == "" {
return fmt.Errorf("%w: %s must not be empty", ErrInvalidArg, ArgModuleName)
return fmt.Errorf("%s must not be empty: %w", ArgModuleName, ErrInvalidArg)
}

return nil
Expand Down
2 changes: 1 addition & 1 deletion internal/service/crdparser/crdparser.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ type Service struct {

func NewService(fileSystem FileSystem) (*Service, error) {
if fileSystem == nil {
return nil, fmt.Errorf("%w: fileSystem must not be nil", commonerrors.ErrInvalidArg)
return nil, fmt.Errorf("fileSystem must not be nil: %w", commonerrors.ErrInvalidArg)
}

return &Service{
Expand Down
30 changes: 15 additions & 15 deletions internal/service/create/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,43 +86,43 @@ func NewService(moduleConfigService ModuleConfigService,
fileSystem FileSystem,
) (*Service, error) {
if moduleConfigService == nil {
return nil, fmt.Errorf("%w: moduleConfigService must not be nil", commonerrors.ErrInvalidArg)
return nil, fmt.Errorf("moduleConfigService must not be nil: %w", commonerrors.ErrInvalidArg)
}

if gitSourcesService == nil {
return nil, fmt.Errorf("%w: gitSourcesService must not be nil", commonerrors.ErrInvalidArg)
return nil, fmt.Errorf("gitSourcesService must not be nil: %w", commonerrors.ErrInvalidArg)
}

if securityConfigService == nil {
return nil, fmt.Errorf("%w: securityConfigService must not be nil", commonerrors.ErrInvalidArg)
return nil, fmt.Errorf("securityConfigService must not be nil: %w", commonerrors.ErrInvalidArg)
}

if componentArchiveService == nil {
return nil, fmt.Errorf("%w: componentArchiveService must not be nil", commonerrors.ErrInvalidArg)
return nil, fmt.Errorf("componentArchiveService must not be nil: %w", commonerrors.ErrInvalidArg)
}

if registryService == nil {
return nil, fmt.Errorf("%w: registryService must not be nil", commonerrors.ErrInvalidArg)
return nil, fmt.Errorf("registryService must not be nil: %w", commonerrors.ErrInvalidArg)
}

if moduleTemplateService == nil {
return nil, fmt.Errorf("%w: moduleTemplateService must not be nil", commonerrors.ErrInvalidArg)
return nil, fmt.Errorf("moduleTemplateService must not be nil: %w", commonerrors.ErrInvalidArg)
}

if crdParserService == nil {
return nil, fmt.Errorf("%w: crdParserService must not be nil", commonerrors.ErrInvalidArg)
return nil, fmt.Errorf("crdParserService must not be nil: %w", commonerrors.ErrInvalidArg)
}

if manifestFileResolver == nil {
return nil, fmt.Errorf("%w: manifestFileResolver must not be nil", commonerrors.ErrInvalidArg)
return nil, fmt.Errorf("manifestFileResolver must not be nil: %w", commonerrors.ErrInvalidArg)
}

if defaultCRFileResolver == nil {
return nil, fmt.Errorf("%w: defaultCRFileResolver must not be nil", commonerrors.ErrInvalidArg)
return nil, fmt.Errorf("defaultCRFileResolver must not be nil: %w", commonerrors.ErrInvalidArg)
}

if fileSystem == nil {
return nil, fmt.Errorf("%w: fileSystem must not be nil", commonerrors.ErrInvalidArg)
return nil, fmt.Errorf("fileSystem must not be nil: %w", commonerrors.ErrInvalidArg)
}

return &Service{
Expand Down Expand Up @@ -219,27 +219,27 @@ func (s *Service) pushImgAndCreateTemplate(archive *comparch.ComponentArchive, m

if err := s.registryService.PushComponentVersion(archive, opts.Insecure, opts.Credentials,
opts.RegistryURL); err != nil {
return fmt.Errorf("%w: failed to push component archive", err)
return fmt.Errorf("failed to push component archive: %w", err)
}

componentVersionAccess, err := s.registryService.GetComponentVersion(archive, opts.Insecure, opts.Credentials, opts.RegistryURL)
if err != nil {
return fmt.Errorf("%w: failed to get component version", err)
return fmt.Errorf("failed to get component version: %w", err)
}

var crData []byte
if defaultCRFilePath != "" {
crData, err = s.fileSystem.ReadFile(defaultCRFilePath)
if err != nil {
return fmt.Errorf("%w: failed to get default CR data", err)
return fmt.Errorf("failed to get default CR data: %w", err)
}
}

opts.Out.Write("- Generating ModuleTemplate\n")
descriptor := componentVersionAccess.GetDescriptor()
if err = s.moduleTemplateService.GenerateModuleTemplate(moduleConfig, descriptor,
crData, isCRDClusterScoped, opts.TemplateOutput); err != nil {
return fmt.Errorf("%w: failed to generate module template", err)
return fmt.Errorf("failed to generate module template: %w", err)
}
return nil
}
Expand All @@ -252,7 +252,7 @@ func (s *Service) configureSecScannerConf(descriptor *compdesc.ComponentDescript
}

if err = s.securityConfigService.AppendSecurityScanConfig(descriptor, *securityConfig); err != nil {
return fmt.Errorf("%w: failed to append security scan config", err)
return fmt.Errorf("failed to append security scan config: %w", err)
}
return nil
}
12 changes: 6 additions & 6 deletions internal/service/create/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,28 +21,28 @@ type Options struct {

func (opts Options) Validate() error {
if opts.Out == nil {
return fmt.Errorf("%w: opts.Out must not be nil", commonerrors.ErrInvalidOption)
return fmt.Errorf("opts.Out must not be nil: %w", commonerrors.ErrInvalidOption)
}

if opts.ConfigFile == "" {
return fmt.Errorf("%w: opts.ConfigFile must not be empty", commonerrors.ErrInvalidOption)
return fmt.Errorf("opts.ConfigFile must not be empty: %w", commonerrors.ErrInvalidOption)
}

if opts.Credentials != "" {
matched, err := regexp.MatchString("(.+):(.+)", opts.Credentials)
if err != nil {
return fmt.Errorf("%w: opts.Credentials could not be parsed: %w", commonerrors.ErrInvalidOption, err)
return fmt.Errorf("opts.Credentials could not be parsed: %w: %w", commonerrors.ErrInvalidOption, err)
} else if !matched {
return fmt.Errorf("%w: opts.Credentials is in invalid format", commonerrors.ErrInvalidOption)
return fmt.Errorf("opts.Credentials is in invalid format: %w", commonerrors.ErrInvalidOption)
}
}

if opts.TemplateOutput == "" {
return fmt.Errorf("%w: opts.TemplateOutput must not be empty", commonerrors.ErrInvalidOption)
return fmt.Errorf("opts.TemplateOutput must not be empty: %w", commonerrors.ErrInvalidOption)
}

if opts.RegistryURL != "" && !strings.HasPrefix(opts.RegistryURL, "http") {
return fmt.Errorf("%w: opts.RegistryURL does not start with http(s)", commonerrors.ErrInvalidOption)
return fmt.Errorf("opts.RegistryURL does not start with http(s): %w", commonerrors.ErrInvalidOption)
}

return nil
Expand Down
8 changes: 4 additions & 4 deletions internal/service/filegenerator/filegenerator.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,15 @@ type Service struct {

func NewService(kind string, fileSystem FileWriter, defaultContentProvider DefaultContentProvider) (*Service, error) {
if kind == "" {
return nil, fmt.Errorf("%w: kind must not be empty", commonerrors.ErrInvalidArg)
return nil, fmt.Errorf("kind must not be empty: %w", commonerrors.ErrInvalidArg)
}

if fileSystem == nil {
return nil, fmt.Errorf("%w: fileSystem must not be nil", commonerrors.ErrInvalidArg)
return nil, fmt.Errorf("fileSystem must not be nil: %w", commonerrors.ErrInvalidArg)
}

if defaultContentProvider == nil {
return nil, fmt.Errorf("%w: defaultContentProvider must not be nil", commonerrors.ErrInvalidArg)
return nil, fmt.Errorf("defaultContentProvider must not be nil: %w", commonerrors.ErrInvalidArg)
}

return &Service{
Expand All @@ -60,7 +60,7 @@ func (s *Service) GenerateFile(out iotools.Out, path string, args types.KeyValue

func (s *Service) writeFile(content, path string) error {
if err := s.fileWriter.WriteFile(path, content); err != nil {
return fmt.Errorf("%w %s: %w", ErrWritingFile, path, err)
return fmt.Errorf("file path: %s, %w: %w", path, err, ErrWritingFile)
}

return nil
Expand Down
Loading
Loading