Skip to content

Commit

Permalink
fix(cli): Do not silently fail on find/List (#515)
Browse files Browse the repository at this point in the history
  • Loading branch information
Duologic authored Mar 18, 2021
1 parent 5149d1b commit 3cc514d
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 20 deletions.
5 changes: 3 additions & 2 deletions cmd/tk/args.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package main

import (
"errors"
"os"
"path/filepath"

Expand All @@ -25,7 +26,7 @@ var workflowArgs = cli.Args{
}

envs, err := tanka.FindEnvs(pwd, tanka.FindOpts{})
if err != nil {
if err != nil && !errors.As(err, &tanka.ErrParallel{}) {
return nil
}

Expand All @@ -42,6 +43,6 @@ var workflowArgs = cli.Args{
return reldirs
}

return complete.PredictDirs("*").Predict(args)
return complete.PredictFiles("*").Predict(args)
}),
}
6 changes: 3 additions & 3 deletions pkg/tanka/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,15 @@ func (e ErrMultipleEnvs) Error() string {
return fmt.Sprintf("found multiple Environments in '%s': \n - %s", e.path, strings.Join(e.names, "\n - "))
}

// ErrParallel is an array of errors collected while parsing environments in parallel
// ErrParallel is an array of errors collected while processing in parallel
type ErrParallel struct {
errors []error
}

func (e ErrParallel) Error() string {
returnErr := fmt.Sprintf("Unable to parse selected Environments:\n\n")
returnErr := fmt.Sprintf("Errors occured during parallel processing:\n\n")
for _, err := range e.errors {
returnErr = fmt.Sprintf("%s- %s\n", returnErr, err.Error())
returnErr = fmt.Sprintf("%s- %s\n\n", returnErr, err.Error())
}
return returnErr
}
43 changes: 28 additions & 15 deletions pkg/tanka/find.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
package tanka

import (
"fmt"
"io/ioutil"
"os"
"path/filepath"

"github.com/grafana/tanka/pkg/jsonnet/jpath"
"github.com/grafana/tanka/pkg/spec/v1alpha1"
"github.com/pkg/errors"
"k8s.io/apimachinery/pkg/labels"
)

Expand All @@ -21,9 +24,9 @@ type FindOpts struct {
// are not checked.
func FindEnvs(path string, opts FindOpts) ([]*v1alpha1.Environment, error) {
// find all environments at dir
envs, err := find(path, Opts{JsonnetOpts: opts.JsonnetOpts})
if err != nil {
return nil, err
envs, errs := find(path, Opts{JsonnetOpts: opts.JsonnetOpts})
if errs != nil {
return envs, ErrParallel{errors: errs}
}

// optionally filter
Expand All @@ -42,18 +45,28 @@ func FindEnvs(path string, opts FindOpts) ([]*v1alpha1.Environment, error) {
return filtered, nil
}

func findErr(path string, err error) []error {
return []error{fmt.Errorf("%s:\n %w", path, err)}
}

// find implements the actual functionality described at 'FindEnvs'
func find(path string, opts Opts) ([]*v1alpha1.Environment, error) {
func find(path string, opts Opts) ([]*v1alpha1.Environment, []error) {
// try if this has envs
list, err := List(path, opts)
if len(list) != 0 && err == nil {
if err != nil &&
// expected when looking for environments
!errors.As(err, &jpath.ErrorNoBase{}) &&
!errors.As(err, &jpath.ErrorFileNotFound{}) {
return nil, findErr(path, err)
}
if len(list) != 0 {
// it has. don't search deeper
return list, nil
}

stat, err := os.Stat(path)
if err != nil {
return nil, err
return nil, findErr(path, err)
}

// if path is a file, don't search deeper
Expand All @@ -64,7 +77,7 @@ func find(path string, opts Opts) ([]*v1alpha1.Environment, error) {
// list directory
files, err := ioutil.ReadDir(path)
if err != nil {
return nil, err
return nil, findErr(path, err)
}

// it's not one. Maybe subdirectories are?
Expand All @@ -82,31 +95,31 @@ func find(path string, opts Opts) ([]*v1alpha1.Environment, error) {
}

// collect parallel results
var lastErr error
var errs []error
var envs []*v1alpha1.Environment

for i := 0; i < routines; i++ {
out := <-ch
if out.err != nil {
lastErr = out.err
if out.errs != nil {
errs = append(errs, out.errs...)
}

envs = append(envs, out.envs...)
}

if lastErr != nil {
return nil, lastErr
if len(errs) != 0 {
return envs, errs
}

return envs, nil
}

type findOut struct {
envs []*v1alpha1.Environment
err error
errs []error
}

func findShim(dir string, opts Opts, ch chan findOut) {
envs, err := find(dir, opts)
ch <- findOut{envs: envs, err: err}
envs, errs := find(dir, opts)
ch <- findOut{envs: envs, errs: errs}
}

0 comments on commit 3cc514d

Please sign in to comment.