Merge pull request #319 from sgotti/handle_wrapped_errors_comparison

*: use errors.Is/errors.As to handle wrapped error checking
This commit is contained in:
Simone Gotti 2022-02-25 09:00:28 +01:00 committed by GitHub
commit b357cdc4ed
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
36 changed files with 149 additions and 135 deletions

2
.golangci.yml Normal file
View File

@ -0,0 +1,2 @@
linters:
enable: errorlint

View File

@ -97,7 +97,7 @@ func directRunStart(cmd *cobra.Command, args []string) error {
for _, res := range directRunStartOpts.prRefRegexes { for _, res := range directRunStartOpts.prRefRegexes {
if _, err := regexp.Compile(res); err != nil { if _, err := regexp.Compile(res); err != nil {
return fmt.Errorf("wrong regular expression %q: %v", res, err) return fmt.Errorf("wrong regular expression %q: %w", res, err)
} }
} }
@ -145,7 +145,7 @@ func directRunStart(cmd *cobra.Command, args []string) error {
} }
if err := yaml.Unmarshal(data, &variables); err != nil { if err := yaml.Unmarshal(data, &variables); err != nil {
return errors.Errorf("failed to unmarshal values: %v", err) return errors.Errorf("failed to unmarshal values: %w", err)
} }
// TODO(sgotti) validate variable name // TODO(sgotti) validate variable name
@ -165,7 +165,7 @@ func directRunStart(cmd *cobra.Command, args []string) error {
if repoUUID == "" { if repoUUID == "" {
repoUUID = uuid.Must(uuid.NewV4()).String() repoUUID = uuid.Must(uuid.NewV4()).String()
if _, err := git.ConfigSet(context.Background(), "agola.repouuid", repoUUID); err != nil { if _, err := git.ConfigSet(context.Background(), "agola.repouuid", repoUUID); err != nil {
return fmt.Errorf("failed to set agola repo uid in git config: %v", err) return fmt.Errorf("failed to set agola repo uid in git config: %w", err)
} }
} }

View File

@ -15,6 +15,7 @@
package cmd package cmd
import ( import (
"errors"
"os" "os"
"os/signal" "os/signal"
"syscall" "syscall"
@ -41,7 +42,7 @@ func childsReaper() {
for range sigs { for range sigs {
for { for {
var wstatus syscall.WaitStatus var wstatus syscall.WaitStatus
if _, err := syscall.Wait4(-1, &wstatus, syscall.WNOHANG|syscall.WUNTRACED|syscall.WCONTINUED, nil); err == syscall.EINTR { if _, err := syscall.Wait4(-1, &wstatus, syscall.WNOHANG|syscall.WUNTRACED|syscall.WCONTINUED, nil); errors.Is(err, syscall.EINTR) {
continue continue
} }
break break

View File

@ -207,7 +207,8 @@ func TestParseConfig(t *testing.T) {
if tt.err == nil { if tt.err == nil {
t.Fatalf("got error: %v, expected no error", err) t.Fatalf("got error: %v, expected no error", err)
} }
if errs, ok := err.(*util.Errors); ok { var errs *util.Errors
if errors.As(err, &errs) {
if !errs.Equal(tt.err) { if !errs.Equal(tt.err) {
t.Fatalf("got error: %v, want error: %v", err, tt.err) t.Fatalf("got error: %v, want error: %v", err, tt.err)
} }

View File

@ -143,7 +143,7 @@ func (d *DataManager) applyWalChanges(ctx context.Context, walData *WalData, rev
var action *Action var action *Action
err := dec.Decode(&action) err := dec.Decode(&action)
if err == io.EOF { if errors.Is(err, io.EOF) {
// all done // all done
break break
} }
@ -261,7 +261,7 @@ func (d *DataManager) watcher(ctx context.Context) error {
for wresp := range wch { for wresp := range wch {
if wresp.Canceled { if wresp.Canceled {
err := wresp.Err() err := wresp.Err()
if err == etcdclientv3rpc.ErrCompacted { if errors.Is(err, etcdclientv3rpc.ErrCompacted) {
d.log.Errorf("required events already compacted, reinitializing watcher changes") d.log.Errorf("required events already compacted, reinitializing watcher changes")
d.changes.Lock() d.changes.Lock()
d.changes.initialized = false d.changes.initialized = false

View File

@ -111,7 +111,7 @@ func (d *DataManager) walIndex(ctx context.Context, wals []*WalData) (walIndex,
var action *Action var action *Action
err := dec.Decode(&action) err := dec.Decode(&action)
if err == io.EOF { if errors.Is(err, io.EOF) {
// all done // all done
break break
} }
@ -349,7 +349,7 @@ func (d *DataManager) writeDataType(ctx context.Context, wi walIndex, dataType s
var de *DataEntry var de *DataEntry
err := dec.Decode(&de) err := dec.Decode(&de)
if err == io.EOF { if errors.Is(err, io.EOF) {
// all done // all done
break break
} }
@ -743,7 +743,7 @@ func (d *DataManager) Import(ctx context.Context, r io.Reader) error {
var de *DataEntry var de *DataEntry
err := dec.Decode(&de) err := dec.Decode(&de)
if err == io.EOF { if errors.Is(err, io.EOF) {
dataFileID := d.dataFileID(dataSequence, uuid.Must(uuid.NewV4()).String()) dataFileID := d.dataFileID(dataSequence, uuid.Must(uuid.NewV4()).String())
if err := d.writeDataFile(ctx, &buf, int64(buf.Len()), dataFileIndex, dataFileID, curDataType); err != nil { if err := d.writeDataFile(ctx, &buf, int64(buf.Len()), dataFileIndex, dataFileID, curDataType); err != nil {
return err return err

View File

@ -371,7 +371,7 @@ func TestConcurrentUpdate(t *testing.T) {
// this must fail since we are using the old cgt // this must fail since we are using the old cgt
_, err = dm.WriteWal(ctx, actions, oldcgt) _, err = dm.WriteWal(ctx, actions, oldcgt)
if err != ErrConcurrency { if !errors.Is(err, ErrConcurrency) {
t.Fatalf("expected err: %v, got %v", ErrConcurrency, err) t.Fatalf("expected err: %v, got %v", ErrConcurrency, err)
} }
@ -384,7 +384,7 @@ func TestConcurrentUpdate(t *testing.T) {
// this must fail since we are using the old cgt // this must fail since we are using the old cgt
_, err = dm.WriteWal(ctx, actions, oldcgt) _, err = dm.WriteWal(ctx, actions, oldcgt)
if err != ErrConcurrency { if !errors.Is(err, ErrConcurrency) {
t.Fatalf("expected err: %v, got %v", ErrConcurrency, err) t.Fatalf("expected err: %v, got %v", ErrConcurrency, err)
} }
} }
@ -670,7 +670,7 @@ func checkDataFiles(ctx context.Context, t *testing.T, dm *DataManager, expected
var de *DataEntry var de *DataEntry
err := dec.Decode(&de) err := dec.Decode(&de)
if err == io.EOF { if errors.Is(err, io.EOF) {
// all done // all done
break break
} }

View File

@ -296,10 +296,10 @@ func (d *DataManager) FirstAvailableWalData(ctx context.Context) (*WalData, int6
func (d *DataManager) LastCommittedStorageWal(ctx context.Context) (string, int64, error) { func (d *DataManager) LastCommittedStorageWal(ctx context.Context) (string, int64, error) {
resp, err := d.e.Get(ctx, etcdLastCommittedStorageWalSeqKey, 0) resp, err := d.e.Get(ctx, etcdLastCommittedStorageWalSeqKey, 0)
if err != nil && err != etcd.ErrKeyNotFound { if err != nil && !errors.Is(err, etcd.ErrKeyNotFound) {
return "", 0, err return "", 0, err
} }
if err == etcd.ErrKeyNotFound { if errors.Is(err, etcd.ErrKeyNotFound) {
return "", 0, errors.Errorf("no last committedstorage wal on etcd") return "", 0, errors.Errorf("no last committedstorage wal on etcd")
} }
lastCommittedStorageWal := string(resp.Kvs[0].Value) lastCommittedStorageWal := string(resp.Kvs[0].Value)
@ -334,10 +334,9 @@ func (d *DataManager) Watch(ctx context.Context, revision int64) <-chan *WatchEl
if wresp.Canceled { if wresp.Canceled {
err := wresp.Err() err := wresp.Err()
switch err { if errors.Is(err, etcdclientv3rpc.ErrCompacted) {
case etcdclientv3rpc.ErrCompacted:
we.Err = ErrCompacted we.Err = ErrCompacted
default: } else {
we.Err = err we.Err = err
} }
@ -1054,7 +1053,7 @@ func (d *DataManager) InitEtcd(ctx context.Context, dataStatus *DataStatus) erro
} }
dec := json.NewDecoder(walFile) dec := json.NewDecoder(walFile)
var header *WalHeader var header *WalHeader
if err = dec.Decode(&header); err != nil && err != io.EOF { if err = dec.Decode(&header); err != nil && !errors.Is(err, io.EOF) {
walFile.Close() walFile.Close()
return err return err
} }
@ -1113,7 +1112,7 @@ func (d *DataManager) InitEtcd(ctx context.Context, dataStatus *DataStatus) erro
_, err = d.e.Get(ctx, etcdWalsDataKey, 0) _, err = d.e.Get(ctx, etcdWalsDataKey, 0)
if err != nil { if err != nil {
if err != etcd.ErrKeyNotFound { if !errors.Is(err, etcd.ErrKeyNotFound) {
return err return err
} }
mustInit = true mustInit = true

View File

@ -62,8 +62,7 @@ type Config struct {
} }
func FromEtcdError(err error) error { func FromEtcdError(err error) error {
switch err { if errors.Is(err, rpctypes.ErrKeyNotFound) {
case rpctypes.ErrKeyNotFound:
return ErrKeyNotFound return ErrKeyNotFound
} }
return err return err

View File

@ -166,7 +166,7 @@ func (h *GitSmartHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
repoAbsPath, exists, err := h.repoAbsPathFunc(h.reposDir, repoPath) repoAbsPath, exists, err := h.repoAbsPathFunc(h.reposDir, repoPath)
if err != nil { if err != nil {
if err == ErrWrongRepoPath { if errors.Is(err, ErrWrongRepoPath) {
http.Error(w, err.Error(), http.StatusBadRequest) http.Error(w, err.Error(), http.StatusBadRequest)
return return
} }
@ -257,7 +257,7 @@ func (h *FetchFileHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
repoAbsPath, _, err := h.repoAbsPathFunc(h.reposDir, fetchData.RepoPath) repoAbsPath, _, err := h.repoAbsPathFunc(h.reposDir, fetchData.RepoPath)
if err != nil { if err != nil {
if err == ErrWrongRepoPath { if errors.Is(err, ErrWrongRepoPath) {
http.Error(w, err.Error(), http.StatusBadRequest) http.Error(w, err.Error(), http.StatusBadRequest)
return return
} }

View File

@ -36,7 +36,7 @@ func New(level zap.AtomicLevel) *zap.Logger {
logger, err := config.Build() logger, err := config.Build()
if err != nil { if err != nil {
panic(fmt.Errorf("failed to initialize logger: %v", err)) panic(fmt.Errorf("failed to initialize logger: %w", err))
} }
return logger return logger

View File

@ -46,13 +46,13 @@ func (e *ErrNotExist) Error() string {
return e.err.Error() return e.err.Error()
} }
func (*ErrNotExist) Is(err error) bool { func (e *ErrNotExist) Unwrap() error {
_, ok := err.(*ErrNotExist) return e.err
return ok
} }
func IsNotExist(err error) bool { func IsNotExist(err error) bool {
return errors.Is(err, &ErrNotExist{}) var e *ErrNotExist
return errors.As(err, &e)
} }
type ReadSeekCloser interface { type ReadSeekCloser interface {

View File

@ -133,7 +133,7 @@ func (s *PosixStorage) DeleteObject(p string) error {
} }
_, err = f.Readdirnames(1) _, err = f.Readdirnames(1)
if err == io.EOF { if errors.Is(err, io.EOF) {
f.Close() f.Close()
if err := os.Remove(pdir); err != nil { if err := os.Remove(pdir); err != nil {
return nil return nil
@ -221,7 +221,7 @@ func (s *PosixStorage) List(prefix, startWith, delimiter string, doneCh <-chan s
return nil return nil
}) })
if err != nil && err != io.EOF { if err != nil && !errors.Is(err, io.EOF) {
objectCh <- ObjectInfo{ objectCh <- ObjectInfo{
Err: err, Err: err,
} }

View File

@ -307,7 +307,7 @@ func (s *PosixFlatStorage) DeleteObject(p string) error {
} }
_, err = f.Readdirnames(1) _, err = f.Readdirnames(1)
if err == io.EOF { if errors.Is(err, io.EOF) {
f.Close() f.Close()
if err := os.Remove(pdir); err != nil { if err := os.Remove(pdir); err != nil {
return nil return nil
@ -418,7 +418,7 @@ func (s *PosixFlatStorage) List(prefix, startWith, delimiter string, doneCh <-ch
return nil return nil
}) })
if err != nil && err != io.EOF { if err != nil && !errors.Is(err, io.EOF) {
objectCh <- ObjectInfo{ objectCh <- ObjectInfo{
Err: err, Err: err,
} }

View File

@ -20,6 +20,8 @@ import (
"os" "os"
"path/filepath" "path/filepath"
"testing" "testing"
errors "golang.org/x/xerrors"
) )
func TestEscapeUnescape(t *testing.T) { func TestEscapeUnescape(t *testing.T) {
@ -64,7 +66,7 @@ func TestEscapeUnescape(t *testing.T) {
if err != nil { if err != nil {
if tt.err == nil { if tt.err == nil {
t.Errorf("%d: unescape: expected no error got %v", i, err) t.Errorf("%d: unescape: expected no error got %v", i, err)
} else if tt.err != err { } else if !errors.Is(tt.err, err) {
t.Errorf("%d: unescape: expected error %v got %v", i, tt.err, err) t.Errorf("%d: unescape: expected error %v got %v", i, tt.err, err)
} }
} else { } else {

View File

@ -663,7 +663,8 @@ func TestCheckRunConfig(t *testing.T) {
} }
if err := CheckRunConfigTasks(inRcts); err != nil { if err := CheckRunConfigTasks(inRcts); err != nil {
if errs, ok := err.(*util.Errors); ok { var errs *util.Errors
if errors.As(err, &errs) {
if !errs.Equal(tt.err) { if !errs.Equal(tt.err) {
t.Fatalf("got error: %v, want error: %v", err, tt.err) t.Fatalf("got error: %v, want error: %v", err, tt.err)
} }

View File

@ -73,15 +73,15 @@ func (s *Sequence) EqualEpoch(s2 *Sequence) bool {
func CurSequence(ctx context.Context, e *etcd.Store, key string) (*Sequence, bool, error) { func CurSequence(ctx context.Context, e *etcd.Store, key string) (*Sequence, bool, error) {
resp, err := e.Get(ctx, key, 0) resp, err := e.Get(ctx, key, 0)
if err != nil && err != etcd.ErrKeyNotFound { if err != nil && !errors.Is(err, etcd.ErrKeyNotFound) {
return nil, false, err return nil, false, err
} }
if err == etcd.ErrKeyNotFound { if errors.Is(err, etcd.ErrKeyNotFound) {
return nil, false, nil return nil, false, nil
} }
seq := &Sequence{} seq := &Sequence{}
if err != etcd.ErrKeyNotFound { if !errors.Is(err, etcd.ErrKeyNotFound) {
kv := resp.Kvs[0] kv := resp.Kvs[0]
if err := json.Unmarshal(kv.Value, &seq); err != nil { if err := json.Unmarshal(kv.Value, &seq); err != nil {
return nil, false, err return nil, false, err
@ -92,13 +92,13 @@ func CurSequence(ctx context.Context, e *etcd.Store, key string) (*Sequence, boo
func IncSequence(ctx context.Context, e *etcd.Store, key string) (*Sequence, error) { func IncSequence(ctx context.Context, e *etcd.Store, key string) (*Sequence, error) {
resp, err := e.Get(ctx, key, 0) resp, err := e.Get(ctx, key, 0)
if err != nil && err != etcd.ErrKeyNotFound { if err != nil && !errors.Is(err, etcd.ErrKeyNotFound) {
return nil, err return nil, err
} }
var revision int64 var revision int64
seq := &Sequence{} seq := &Sequence{}
if err != etcd.ErrKeyNotFound { if !errors.Is(err, etcd.ErrKeyNotFound) {
kv := resp.Kvs[0] kv := resp.Kvs[0]
if err := json.Unmarshal(kv.Value, &seq); err != nil { if err := json.Unmarshal(kv.Value, &seq); err != nil {
return nil, err return nil, err

View File

@ -27,7 +27,7 @@ import (
func (h *ActionHandler) MaintenanceMode(ctx context.Context, enable bool) error { func (h *ActionHandler) MaintenanceMode(ctx context.Context, enable bool) error {
resp, err := h.e.Get(ctx, common.EtcdMaintenanceKey, 0) resp, err := h.e.Get(ctx, common.EtcdMaintenanceKey, 0)
if err != nil && err != etcd.ErrKeyNotFound { if err != nil && !errors.Is(err, etcd.ErrKeyNotFound) {
return err return err
} }

View File

@ -40,6 +40,7 @@ import (
"go.etcd.io/etcd/mvcc/mvccpb" "go.etcd.io/etcd/mvcc/mvccpb"
"go.uber.org/zap" "go.uber.org/zap"
"go.uber.org/zap/zapcore" "go.uber.org/zap/zapcore"
errors "golang.org/x/xerrors"
) )
var level = zap.NewAtomicLevelAt(zapcore.InfoLevel) var level = zap.NewAtomicLevelAt(zapcore.InfoLevel)
@ -67,7 +68,7 @@ func (s *Configstore) maintenanceModeWatcherLoop(ctx context.Context, runCtxCanc
func (s *Configstore) maintenanceModeWatcher(ctx context.Context, runCtxCancel context.CancelFunc, maintenanceModeEnabled bool) error { func (s *Configstore) maintenanceModeWatcher(ctx context.Context, runCtxCancel context.CancelFunc, maintenanceModeEnabled bool) error {
log.Infof("watcher: maintenance mode enabled: %t", maintenanceModeEnabled) log.Infof("watcher: maintenance mode enabled: %t", maintenanceModeEnabled)
resp, err := s.e.Get(ctx, common.EtcdMaintenanceKey, 0) resp, err := s.e.Get(ctx, common.EtcdMaintenanceKey, 0)
if err != nil && err != etcd.ErrKeyNotFound { if err != nil && !errors.Is(err, etcd.ErrKeyNotFound) {
return err return err
} }
@ -351,7 +352,7 @@ func (s *Configstore) run(ctx context.Context) error {
} }
resp, err := s.e.Get(ctx, common.EtcdMaintenanceKey, 0) resp, err := s.e.Get(ctx, common.EtcdMaintenanceKey, 0)
if err != nil && err != etcd.ErrKeyNotFound { if err != nil && !errors.Is(err, etcd.ErrKeyNotFound) {
return err return err
} }

View File

@ -144,7 +144,7 @@ func (r *ReadDB) SyncFromDump(ctx context.Context) (string, error) {
var de *datamanager.DataEntry var de *datamanager.DataEntry
err := dec.Decode(&de) err := dec.Decode(&de)
if err == io.EOF { if errors.Is(err, io.EOF) {
// all done // all done
break break
} }
@ -488,7 +488,7 @@ func (r *ReadDB) handleEvents(ctx context.Context) error {
err := r.rdb.Do(ctx, func(tx *db.Tx) error { err := r.rdb.Do(ctx, func(tx *db.Tx) error {
err := tx.QueryRow("select revision from revision order by revision desc limit 1").Scan(&revision) err := tx.QueryRow("select revision from revision order by revision desc limit 1").Scan(&revision)
if err != nil { if err != nil {
if err == sql.ErrNoRows { if errors.Is(err, sql.ErrNoRows) {
revision = 0 revision = 0
} else { } else {
return err return err
@ -508,7 +508,7 @@ func (r *ReadDB) handleEvents(ctx context.Context) error {
r.log.Debugf("we: %s", util.Dump(we)) r.log.Debugf("we: %s", util.Dump(we))
if we.Err != nil { if we.Err != nil {
err := we.Err err := we.Err
if err == datamanager.ErrCompacted { if errors.Is(err, datamanager.ErrCompacted) {
r.log.Warnf("required events already compacted, reinitializing readdb") r.log.Warnf("required events already compacted, reinitializing readdb")
r.Initialized = false r.Initialized = false
return nil return nil
@ -612,7 +612,7 @@ func (r *ReadDB) applyWal(tx *db.Tx, walDataFileID string) error {
var action *datamanager.Action var action *datamanager.Action
err := dec.Decode(&action) err := dec.Decode(&action)
if err == io.EOF { if errors.Is(err, io.EOF) {
// all done // all done
break break
} }
@ -755,7 +755,7 @@ func (r *ReadDB) getRevision(tx *db.Tx) (int64, error) {
} }
err = tx.QueryRow(q, args...).Scan(&revision) err = tx.QueryRow(q, args...).Scan(&revision)
if err == sql.ErrNoRows { if errors.Is(err, sql.ErrNoRows) {
return 0, nil return 0, nil
} }
return revision, err return revision, err
@ -787,7 +787,7 @@ func (r *ReadDB) GetCommittedWalSequence(tx *db.Tx) (string, error) {
} }
err = tx.QueryRow(q, args...).Scan(&seq) err = tx.QueryRow(q, args...).Scan(&seq)
if err == sql.ErrNoRows { if errors.Is(err, sql.ErrNoRows) {
return "", nil return "", nil
} }
return seq, err return seq, err

View File

@ -106,7 +106,7 @@ func NewK8sDriver(logger *zap.Logger, executorID, toolboxPath, initImage string,
} }
kubecli, err := kubernetes.NewForConfig(kubecfg) kubecli, err := kubernetes.NewForConfig(kubecfg)
if err != nil { if err != nil {
return nil, fmt.Errorf("cannot create kubernetes client: %v", err) return nil, fmt.Errorf("cannot create kubernetes client: %w", err)
} }
namespace, _, err := kubeClientConfig.Namespace() namespace, _, err := kubeClientConfig.Namespace()
@ -133,7 +133,7 @@ func NewK8sDriver(logger *zap.Logger, executorID, toolboxPath, initImage string,
sv, err := parseGitVersion(serverVersion.GitVersion) sv, err := parseGitVersion(serverVersion.GitVersion)
// if server version parsing fails just warn but ignore it // if server version parsing fails just warn but ignore it
if err != nil { if err != nil {
d.log.Warnf("failed to parse k8s server version: %v", err) d.log.Warnf("failed to parse k8s server version: %w", err)
} }
if sv != nil { if sv != nil {
// for k8s version < v1.14.x use old arch label // for k8s version < v1.14.x use old arch label
@ -800,10 +800,10 @@ func (e *K8sContainerExec) Wait(ctx context.Context) (int, error) {
var exitCode int var exitCode int
if err != nil { if err != nil {
switch err := err.(type) { var verr utilexec.ExitError
case utilexec.ExitError: if errors.As(err, &verr) {
exitCode = err.ExitStatus() exitCode = verr.ExitStatus()
default: } else {
return -1, err return -1, err
} }
} }

View File

@ -571,7 +571,7 @@ func (h *ActionHandler) HandleRemoteSourceAuth(ctx context.Context, remoteSource
tokenName := "agola-" + h.agolaID tokenName := "agola-" + h.agolaID
accessToken, err := passwordSource.LoginPassword(loginName, loginPassword, tokenName) accessToken, err := passwordSource.LoginPassword(loginName, loginPassword, tokenName)
if err != nil { if err != nil {
if err == gitsource.ErrUnauthorized { if errors.Is(err, gitsource.ErrUnauthorized) {
return nil, util.NewErrUnauthorized(errors.Errorf("failed to login to remotesource %q: %w", remoteSourceName, err)) return nil, util.NewErrUnauthorized(errors.Errorf("failed to login to remotesource %q: %w", remoteSourceName, err))
} }
return nil, errors.Errorf("failed to login to remote source %q with login name %q: %w", rs.Name, loginName, err) return nil, errors.Errorf("failed to login to remote source %q with login name %q: %w", rs.Name, loginName, err)
@ -836,7 +836,7 @@ func (h *ActionHandler) UserCreateRun(ctx context.Context, req *UserCreateRunReq
for _, res := range req.PullRequestRefRegexes { for _, res := range req.PullRequestRefRegexes {
re, err := regexp.Compile(res) re, err := regexp.Compile(res)
if err != nil { if err != nil {
return fmt.Errorf("wrong regular expression %q: %v", res, err) return fmt.Errorf("wrong regular expression %q: %w", res, err)
} }
prRefRegexes = append(prRefRegexes, re) prRefRegexes = append(prRefRegexes, re)
} }

View File

@ -591,7 +591,7 @@ func (h *ActionHandler) getRunCounter(ctx context.Context, group string) (uint64
func (h *ActionHandler) GetExecutorTask(ctx context.Context, etID string) (*types.ExecutorTask, error) { func (h *ActionHandler) GetExecutorTask(ctx context.Context, etID string) (*types.ExecutorTask, error) {
et, err := store.GetExecutorTask(ctx, h.e, etID) et, err := store.GetExecutorTask(ctx, h.e, etID)
if err != nil && err != etcd.ErrKeyNotFound { if err != nil && !errors.Is(err, etcd.ErrKeyNotFound) {
return nil, err return nil, err
} }
if et == nil { if et == nil {
@ -619,7 +619,7 @@ func (h *ActionHandler) GetExecutorTask(ctx context.Context, etID string) (*type
func (h *ActionHandler) GetExecutorTasks(ctx context.Context, executorID string) ([]*types.ExecutorTask, error) { func (h *ActionHandler) GetExecutorTasks(ctx context.Context, executorID string) ([]*types.ExecutorTask, error) {
ets, err := store.GetExecutorTasksForExecutor(ctx, h.e, executorID) ets, err := store.GetExecutorTasksForExecutor(ctx, h.e, executorID)
if err != nil && err != etcd.ErrKeyNotFound { if err != nil && !errors.Is(err, etcd.ErrKeyNotFound) {
return nil, err return nil, err
} }

View File

@ -27,7 +27,7 @@ import (
func (h *ActionHandler) MaintenanceMode(ctx context.Context, enable bool) error { func (h *ActionHandler) MaintenanceMode(ctx context.Context, enable bool) error {
resp, err := h.e.Get(ctx, common.EtcdMaintenanceKey, 0) resp, err := h.e.Get(ctx, common.EtcdMaintenanceKey, 0)
if err != nil && err != etcd.ErrKeyNotFound { if err != nil && !errors.Is(err, etcd.ErrKeyNotFound) {
return err return err
} }

View File

@ -241,14 +241,14 @@ func (h *LogsHandler) readTaskLogs(ctx context.Context, runID, taskID string, se
et, err := store.GetExecutorTask(ctx, h.e, task.ID) et, err := store.GetExecutorTask(ctx, h.e, task.ID)
if err != nil { if err != nil {
if err == etcd.ErrKeyNotFound { if errors.Is(err, etcd.ErrKeyNotFound) {
return util.NewErrNotExist(errors.Errorf("executor task with id %q doesn't exist", task.ID)), true return util.NewErrNotExist(errors.Errorf("executor task with id %q doesn't exist", task.ID)), true
} }
return err, true return err, true
} }
executor, err := store.GetExecutor(ctx, h.e, et.Spec.ExecutorID) executor, err := store.GetExecutor(ctx, h.e, et.Spec.ExecutorID)
if err != nil { if err != nil {
if err == etcd.ErrKeyNotFound { if errors.Is(err, etcd.ErrKeyNotFound) {
return util.NewErrNotExist(errors.Errorf("executor with id %q doesn't exist", et.Spec.ExecutorID)), true return util.NewErrNotExist(errors.Errorf("executor with id %q doesn't exist", et.Spec.ExecutorID)), true
} }
return err, true return err, true
@ -832,7 +832,7 @@ func (h *RunEventsHandler) sendRunEvents(ctx context.Context, startRunEventID st
for wresp := range wch { for wresp := range wch {
if wresp.Canceled { if wresp.Canceled {
err := wresp.Err() err := wresp.Err()
if err == etcdclientv3rpc.ErrCompacted { if errors.Is(err, etcdclientv3rpc.ErrCompacted) {
h.log.Errorf("required events already compacted") h.log.Errorf("required events already compacted")
} }
return errors.Errorf("watch error: %w", err) return errors.Errorf("watch error: %w", err)

View File

@ -400,7 +400,7 @@ func (r *ReadDB) handleEvents(ctx context.Context) error {
for wresp := range wch { for wresp := range wch {
if wresp.Canceled { if wresp.Canceled {
err = wresp.Err() err = wresp.Err()
if err == etcdclientv3rpc.ErrCompacted { if errors.Is(err, etcdclientv3rpc.ErrCompacted) {
r.log.Errorf("required events already compacted, reinitializing readdb") r.log.Errorf("required events already compacted, reinitializing readdb")
r.SetInitialized(false) r.SetInitialized(false)
} }
@ -682,7 +682,7 @@ func (r *ReadDB) SyncFromDump(ctx context.Context) (string, error) {
var de *datamanager.DataEntry var de *datamanager.DataEntry
err := dec.Decode(&de) err := dec.Decode(&de)
if err == io.EOF { if errors.Is(err, io.EOF) {
// all done // all done
break break
} }
@ -784,7 +784,7 @@ func (r *ReadDB) handleEventsOST(ctx context.Context) error {
err := r.rdb.Do(ctx, func(tx *db.Tx) error { err := r.rdb.Do(ctx, func(tx *db.Tx) error {
err := tx.QueryRow("select revision from revision order by revision desc limit 1").Scan(&revision) err := tx.QueryRow("select revision from revision order by revision desc limit 1").Scan(&revision)
if err != nil { if err != nil {
if err == sql.ErrNoRows { if errors.Is(err, sql.ErrNoRows) {
revision = 0 revision = 0
} else { } else {
return err return err
@ -804,7 +804,7 @@ func (r *ReadDB) handleEventsOST(ctx context.Context) error {
r.log.Debugf("we: %s", util.Dump(we)) r.log.Debugf("we: %s", util.Dump(we))
if we.Err != nil { if we.Err != nil {
err := we.Err err := we.Err
if err == datamanager.ErrCompacted { if errors.Is(err, datamanager.ErrCompacted) {
r.log.Warnf("required events already compacted, reinitializing readdb") r.log.Warnf("required events already compacted, reinitializing readdb")
r.Initialized = false r.Initialized = false
return nil return nil
@ -876,7 +876,7 @@ func (r *ReadDB) applyWal(tx *db.Tx, walDataFileID string) error {
var action *datamanager.Action var action *datamanager.Action
err := dec.Decode(&action) err := dec.Decode(&action)
if err == io.EOF { if errors.Is(err, io.EOF) {
// all done // all done
break break
} }
@ -1104,7 +1104,7 @@ func (r *ReadDB) getRevision(tx *db.Tx) (int64, error) {
} }
err = tx.QueryRow(q, args...).Scan(&revision) err = tx.QueryRow(q, args...).Scan(&revision)
if err == sql.ErrNoRows { if errors.Is(err, sql.ErrNoRows) {
return 0, nil return 0, nil
} }
return revision, err return revision, err
@ -1485,7 +1485,7 @@ func (r *ReadDB) GetCommittedWalSequenceOST(tx *db.Tx) (string, error) {
} }
err = tx.QueryRow(q, args...).Scan(&seq) err = tx.QueryRow(q, args...).Scan(&seq)
if err == sql.ErrNoRows { if errors.Is(err, sql.ErrNoRows) {
return "", nil return "", nil
} }
return seq, err return seq, err
@ -1593,7 +1593,7 @@ func (r *ReadDB) GetRunCounterOST(tx *db.Tx, group string) (uint64, error) {
} }
err = tx.QueryRow(q, args...).Scan(&g, &counter) err = tx.QueryRow(q, args...).Scan(&g, &counter)
if err == sql.ErrNoRows { if errors.Is(err, sql.ErrNoRows) {
return 0, nil return 0, nil
} }
return counter, err return counter, err

View File

@ -40,6 +40,7 @@ import (
"go.etcd.io/etcd/mvcc/mvccpb" "go.etcd.io/etcd/mvcc/mvccpb"
"go.uber.org/zap" "go.uber.org/zap"
"go.uber.org/zap/zapcore" "go.uber.org/zap/zapcore"
errors "golang.org/x/xerrors"
) )
var level = zap.NewAtomicLevelAt(zapcore.InfoLevel) var level = zap.NewAtomicLevelAt(zapcore.InfoLevel)
@ -94,7 +95,7 @@ func (s *Runservice) maintenanceModeWatcherLoop(ctx context.Context, runCtxCance
func (s *Runservice) maintenanceModeWatcher(ctx context.Context, runCtxCancel context.CancelFunc, maintenanceModeEnabled bool) error { func (s *Runservice) maintenanceModeWatcher(ctx context.Context, runCtxCancel context.CancelFunc, maintenanceModeEnabled bool) error {
log.Infof("watcher: maintenance mode enabled: %t", maintenanceModeEnabled) log.Infof("watcher: maintenance mode enabled: %t", maintenanceModeEnabled)
resp, err := s.e.Get(ctx, common.EtcdMaintenanceKey, 0) resp, err := s.e.Get(ctx, common.EtcdMaintenanceKey, 0)
if err != nil && err != etcd.ErrKeyNotFound { if err != nil && !errors.Is(err, etcd.ErrKeyNotFound) {
return err return err
} }
@ -330,7 +331,7 @@ func (s *Runservice) run(ctx context.Context) error {
} }
resp, err := s.e.Get(ctx, common.EtcdMaintenanceKey, 0) resp, err := s.e.Get(ctx, common.EtcdMaintenanceKey, 0)
if err != nil && err != etcd.ErrKeyNotFound { if err != nil && !errors.Is(err, etcd.ErrKeyNotFound) {
return err return err
} }

View File

@ -247,7 +247,7 @@ func (s *Runservice) submitRunTasks(ctx context.Context, r *types.Run, rc *types
// just a check but it's not really needed since the call to // just a check but it's not really needed since the call to
// atomicPutExecutorTask will fail if it already exists // atomicPutExecutorTask will fail if it already exists
tet, err := store.GetExecutorTask(ctx, s.e, et.ID) tet, err := store.GetExecutorTask(ctx, s.e, et.ID)
if err != nil && err != etcd.ErrKeyNotFound { if err != nil && !errors.Is(err, etcd.ErrKeyNotFound) {
return err return err
} }
if tet != nil { if tet != nil {
@ -335,7 +335,7 @@ func chooseExecutor(executors []*types.Executor, executorTasksCount map[string]i
// will periodically fetch the executortask anyway // will periodically fetch the executortask anyway
func (s *Runservice) sendExecutorTask(ctx context.Context, et *types.ExecutorTask) error { func (s *Runservice) sendExecutorTask(ctx context.Context, et *types.ExecutorTask) error {
executor, err := store.GetExecutor(ctx, s.e, et.Spec.ExecutorID) executor, err := store.GetExecutor(ctx, s.e, et.Spec.ExecutorID)
if err != nil && err != etcd.ErrKeyNotFound { if err != nil && !errors.Is(err, etcd.ErrKeyNotFound) {
return err return err
} }
if executor == nil { if executor == nil {
@ -768,7 +768,7 @@ func (s *Runservice) executorTaskCleaner(ctx context.Context, et *types.Executor
if et.Status.Phase.IsFinished() { if et.Status.Phase.IsFinished() {
r, _, err := store.GetRun(ctx, s.e, et.Spec.RunID) r, _, err := store.GetRun(ctx, s.e, et.Spec.RunID)
if err != nil { if err != nil {
if err == etcd.ErrKeyNotFound { if errors.Is(err, etcd.ErrKeyNotFound) {
// run doesn't exists, remove executor task // run doesn't exists, remove executor task
if err := store.DeleteExecutorTask(ctx, s.e, et.ID); err != nil { if err := store.DeleteExecutorTask(ctx, s.e, et.ID); err != nil {
log.Errorf("err: %+v", err) log.Errorf("err: %+v", err)
@ -798,7 +798,7 @@ func (s *Runservice) executorTaskCleaner(ctx context.Context, et *types.Executor
if !et.Status.Phase.IsFinished() { if !et.Status.Phase.IsFinished() {
// if the executor doesn't exists anymore mark the not finished executor tasks as failed // if the executor doesn't exists anymore mark the not finished executor tasks as failed
executor, err := store.GetExecutor(ctx, s.e, et.Spec.ExecutorID) executor, err := store.GetExecutor(ctx, s.e, et.Spec.ExecutorID)
if err != nil && err != etcd.ErrKeyNotFound { if err != nil && !errors.Is(err, etcd.ErrKeyNotFound) {
return err return err
} }
if executor == nil { if executor == nil {
@ -886,7 +886,7 @@ func (s *Runservice) OSTFileExists(path string) (bool, error) {
func (s *Runservice) fetchLog(ctx context.Context, rt *types.RunTask, setup bool, stepnum int) error { func (s *Runservice) fetchLog(ctx context.Context, rt *types.RunTask, setup bool, stepnum int) error {
et, err := store.GetExecutorTask(ctx, s.e, rt.ID) et, err := store.GetExecutorTask(ctx, s.e, rt.ID)
if err != nil && err != etcd.ErrKeyNotFound { if err != nil && !errors.Is(err, etcd.ErrKeyNotFound) {
return err return err
} }
if et == nil { if et == nil {
@ -896,7 +896,7 @@ func (s *Runservice) fetchLog(ctx context.Context, rt *types.RunTask, setup bool
return nil return nil
} }
executor, err := store.GetExecutor(ctx, s.e, et.Spec.ExecutorID) executor, err := store.GetExecutor(ctx, s.e, et.Spec.ExecutorID)
if err != nil && err != etcd.ErrKeyNotFound { if err != nil && !errors.Is(err, etcd.ErrKeyNotFound) {
return err return err
} }
if executor == nil { if executor == nil {
@ -1049,7 +1049,7 @@ func (s *Runservice) fetchTaskLogs(ctx context.Context, runID string, rt *types.
func (s *Runservice) fetchArchive(ctx context.Context, rt *types.RunTask, stepnum int) error { func (s *Runservice) fetchArchive(ctx context.Context, rt *types.RunTask, stepnum int) error {
et, err := store.GetExecutorTask(ctx, s.e, rt.ID) et, err := store.GetExecutorTask(ctx, s.e, rt.ID)
if err != nil && err != etcd.ErrKeyNotFound { if err != nil && !errors.Is(err, etcd.ErrKeyNotFound) {
return err return err
} }
if et == nil { if et == nil {
@ -1059,7 +1059,7 @@ func (s *Runservice) fetchArchive(ctx context.Context, rt *types.RunTask, stepnu
return nil return nil
} }
executor, err := store.GetExecutor(ctx, s.e, et.Spec.ExecutorID) executor, err := store.GetExecutor(ctx, s.e, et.Spec.ExecutorID)
if err != nil && err != etcd.ErrKeyNotFound { if err != nil && !errors.Is(err, etcd.ErrKeyNotFound) {
return err return err
} }
if executor == nil { if executor == nil {

View File

@ -420,10 +420,10 @@ func AtomicPutRun(ctx context.Context, e *etcd.Store, r *types.Run, runEvent *ty
// insert only if the run as changed // insert only if the run as changed
curRun, _, err := GetRun(ctx, e, r.ID) curRun, _, err := GetRun(ctx, e, r.ID)
if err != nil && err != etcd.ErrKeyNotFound { if err != nil && !errors.Is(err, etcd.ErrKeyNotFound) {
return nil, err return nil, err
} }
if err != etcd.ErrKeyNotFound { if !errors.Is(err, etcd.ErrKeyNotFound) {
if curRun.Revision != r.Revision { if curRun.Revision != r.Revision {
// fast fail path if the run was already updated // fast fail path if the run was already updated
return nil, errors.Errorf("run modified") return nil, errors.Errorf("run modified")
@ -522,7 +522,7 @@ func GetRuns(ctx context.Context, e *etcd.Store) ([]*types.Run, error) {
func GetRunEtcdOrOST(ctx context.Context, e *etcd.Store, dm *datamanager.DataManager, runID string) (*types.Run, error) { func GetRunEtcdOrOST(ctx context.Context, e *etcd.Store, dm *datamanager.DataManager, runID string) (*types.Run, error) {
r, _, err := GetRun(ctx, e, runID) r, _, err := GetRun(ctx, e, runID)
if err != nil && err != etcd.ErrKeyNotFound { if err != nil && !errors.Is(err, etcd.ErrKeyNotFound) {
return nil, err return nil, err
} }
if r == nil { if r == nil {

View File

@ -38,6 +38,7 @@ import (
"github.com/gofrs/uuid" "github.com/gofrs/uuid"
"github.com/sgotti/gexpect" "github.com/sgotti/gexpect"
errors "golang.org/x/xerrors"
) )
const ( const (
@ -193,7 +194,7 @@ func NewTestEmbeddedEtcd(t *testing.T, logger *zap.Logger, dir string, a ...stri
} }
e, err := etcd.New(storeConfig) e, err := etcd.New(storeConfig)
if err != nil { if err != nil {
return nil, fmt.Errorf("cannot create store: %v", err) return nil, fmt.Errorf("cannot create store: %w", err)
} }
tectd := &TestEmbeddedEtcd{ tectd := &TestEmbeddedEtcd{
@ -267,7 +268,7 @@ func NewTestExternalEtcd(t *testing.T, logger *zap.Logger, dir string, a ...stri
} }
e, err := etcd.New(storeConfig) e, err := etcd.New(storeConfig)
if err != nil { if err != nil {
return nil, fmt.Errorf("cannot create store: %v", err) return nil, fmt.Errorf("cannot create store: %w", err)
} }
bin := os.Getenv("ETCD_BIN") bin := os.Getenv("ETCD_BIN")
@ -303,7 +304,7 @@ func (te *TestEtcd) Compact() error {
ctx, cancel := context.WithTimeout(context.Background(), etcdTimeout) ctx, cancel := context.WithTimeout(context.Background(), etcdTimeout)
defer cancel() defer cancel()
resp, err := te.Get(ctx, "anykey", 0) resp, err := te.Get(ctx, "anykey", 0)
if err != nil && err != etcd.ErrKeyNotFound { if err != nil && !errors.Is(err, etcd.ErrKeyNotFound) {
return err return err
} }
@ -317,7 +318,7 @@ func (te *TestEtcd) WaitUp(timeout time.Duration) error {
ctx, cancel := context.WithTimeout(context.Background(), etcdTimeout) ctx, cancel := context.WithTimeout(context.Background(), etcdTimeout)
defer cancel() defer cancel()
_, err := te.Get(ctx, "anykey", 0) _, err := te.Get(ctx, "anykey", 0)
if err != nil && err == etcd.ErrKeyNotFound { if err != nil && errors.Is(err, etcd.ErrKeyNotFound) {
return nil return nil
} }
if err == nil { if err == nil {
@ -335,7 +336,7 @@ func (te *TestEtcd) WaitDown(timeout time.Duration) error {
ctx, cancel := context.WithTimeout(context.Background(), etcdTimeout) ctx, cancel := context.WithTimeout(context.Background(), etcdTimeout)
defer cancel() defer cancel()
_, err := te.Get(ctx, "anykey", 0) _, err := te.Get(ctx, "anykey", 0)
if err != nil && err != etcd.ErrKeyNotFound { if err != nil && !errors.Is(err, etcd.ErrKeyNotFound) {
return nil return nil
} }
time.Sleep(sleepInterval) time.Sleep(sleepInterval)
@ -567,7 +568,7 @@ func GetFreePort(tcp bool, udp bool) (string, string, error) {
} }
localhostIP, err := net.ResolveIPAddr("ip", "localhost") localhostIP, err := net.ResolveIPAddr("ip", "localhost")
if err != nil { if err != nil {
return "", "", fmt.Errorf("failed to resolve ip addr: %v", err) return "", "", fmt.Errorf("failed to resolve ip addr: %w", err)
} }
for { for {
curPort++ curPort++

View File

@ -50,7 +50,7 @@ func CreateTar(archiveInfos []*ArchiveInfo, w io.Writer) error {
sourceDirInfo, err := os.Stat(sourceDir) sourceDirInfo, err := os.Stat(sourceDir)
if err != nil { if err != nil {
return fmt.Errorf("%s: stat: %v", sourceDir, err) return fmt.Errorf("%s: stat: %w", sourceDir, err)
} }
if !sourceDirInfo.IsDir() { if !sourceDirInfo.IsDir() {
return fmt.Errorf("sourceDir %q is not a directory", sourceDir) return fmt.Errorf("sourceDir %q is not a directory", sourceDir)
@ -62,7 +62,7 @@ func CreateTar(archiveInfos []*ArchiveInfo, w io.Writer) error {
} }
if err != nil { if err != nil {
return fmt.Errorf("error accessing path %q: %v. Skipping.", path, err) return fmt.Errorf("error accessing path %q: %w. Skipping.", path, err)
} }
match := false match := false
for _, pattern := range ai.Paths { for _, pattern := range ai.Paths {
@ -104,19 +104,19 @@ func CreateTar(archiveInfos []*ArchiveInfo, w io.Writer) error {
var err error var err error
linkTarget, err = os.Readlink(path) linkTarget, err = os.Readlink(path)
if err != nil { if err != nil {
return fmt.Errorf("%s: readlink: %v", path, err) return fmt.Errorf("%s: readlink: %w", path, err)
} }
} }
hdr, err := tar.FileInfoHeader(fi, filepath.ToSlash(linkTarget)) hdr, err := tar.FileInfoHeader(fi, filepath.ToSlash(linkTarget))
if err != nil { if err != nil {
return fmt.Errorf("%s: making header: %v", path, err) return fmt.Errorf("%s: making header: %w", path, err)
} }
hdr.Name = destPath hdr.Name = destPath
err = tw.WriteHeader(hdr) err = tw.WriteHeader(hdr)
if err != nil { if err != nil {
return fmt.Errorf("%s: writing header: %v", hdr.Name, err) return fmt.Errorf("%s: writing header: %w", hdr.Name, err)
} }
if fi.IsDir() { if fi.IsDir() {
@ -130,14 +130,14 @@ func CreateTar(archiveInfos []*ArchiveInfo, w io.Writer) error {
} }
defer f.Close() defer f.Close()
if _, err := io.Copy(tw, f); err != nil { if _, err := io.Copy(tw, f); err != nil {
return fmt.Errorf("%s: copying contents: %v", f.Name(), err) return fmt.Errorf("%s: copying contents: %w", f.Name(), err)
} }
} }
return nil return nil
}) })
if err != nil { if err != nil {
return fmt.Errorf("error walking the path %q: %v\n", sourceDir, err) return fmt.Errorf("error walking the path %q: %w", sourceDir, err)
} }
} }

View File

@ -16,6 +16,7 @@ package unarchive
import ( import (
"archive/tar" "archive/tar"
"errors"
"fmt" "fmt"
"io" "io"
"log" "log"
@ -32,12 +33,12 @@ func Unarchive(source io.Reader, destDir string, overwrite, removeDestDir bool)
var err error var err error
destDir, err = filepath.Abs(destDir) destDir, err = filepath.Abs(destDir)
if err != nil { if err != nil {
return fmt.Errorf("failed to calculate destination dir absolute path: %v", err) return fmt.Errorf("failed to calculate destination dir absolute path: %w", err)
} }
// don't follow destdir if it's a symlink // don't follow destdir if it's a symlink
fi, err := os.Lstat(destDir) fi, err := os.Lstat(destDir)
if err != nil && !os.IsNotExist(err) { if err != nil && !os.IsNotExist(err) {
return fmt.Errorf("failed to lstat destination dir: %v", err) return fmt.Errorf("failed to lstat destination dir: %w", err)
} }
if fi != nil && !fi.IsDir() { if fi != nil && !fi.IsDir() {
return fmt.Errorf("destination path %q already exists and it's not a directory (mode: %q)", destDir, fi.Mode().String()) return fmt.Errorf("destination path %q already exists and it's not a directory (mode: %q)", destDir, fi.Mode().String())
@ -52,11 +53,11 @@ func Unarchive(source io.Reader, destDir string, overwrite, removeDestDir bool)
for { for {
err := untarNext(tr, destDir, overwrite) err := untarNext(tr, destDir, overwrite)
if err == io.EOF { if errors.Is(err, io.EOF) {
break break
} }
if err != nil { if err != nil {
return fmt.Errorf("error reading file in tar archive: %v", err) return fmt.Errorf("error reading file in tar archive: %w", err)
} }
} }
@ -132,7 +133,7 @@ func fileExists(name string) bool {
func mkdir(dirPath string, mode os.FileMode) error { func mkdir(dirPath string, mode os.FileMode) error {
err := os.MkdirAll(dirPath, mode) err := os.MkdirAll(dirPath, mode)
if err != nil { if err != nil {
return fmt.Errorf("%s: making directory: %v", dirPath, err) return fmt.Errorf("%s: making directory: %w", dirPath, err)
} }
return nil return nil
} }
@ -140,23 +141,23 @@ func mkdir(dirPath string, mode os.FileMode) error {
func writeNewFile(fpath string, in io.Reader, mode os.FileMode) error { func writeNewFile(fpath string, in io.Reader, mode os.FileMode) error {
err := os.MkdirAll(filepath.Dir(fpath), defaultDirPerm) err := os.MkdirAll(filepath.Dir(fpath), defaultDirPerm)
if err != nil { if err != nil {
return fmt.Errorf("%s: making directory for file: %v", fpath, err) return fmt.Errorf("%s: making directory for file: %w", fpath, err)
} }
out, err := os.Create(fpath) out, err := os.Create(fpath)
if err != nil { if err != nil {
return fmt.Errorf("%s: creating new file: %v", fpath, err) return fmt.Errorf("%s: creating new file: %w", fpath, err)
} }
defer out.Close() defer out.Close()
err = out.Chmod(mode) err = out.Chmod(mode)
if err != nil && runtime.GOOS != "windows" { if err != nil && runtime.GOOS != "windows" {
return fmt.Errorf("%s: changing file mode: %v", fpath, err) return fmt.Errorf("%s: changing file mode: %w", fpath, err)
} }
_, err = io.Copy(out, in) _, err = io.Copy(out, in)
if err != nil { if err != nil {
return fmt.Errorf("%s: writing file: %v", fpath, err) return fmt.Errorf("%s: writing file: %w", fpath, err)
} }
return nil return nil
} }
@ -164,11 +165,11 @@ func writeNewFile(fpath string, in io.Reader, mode os.FileMode) error {
func writeNewSymbolicLink(fpath string, target string) error { func writeNewSymbolicLink(fpath string, target string) error {
err := os.MkdirAll(filepath.Dir(fpath), defaultDirPerm) err := os.MkdirAll(filepath.Dir(fpath), defaultDirPerm)
if err != nil { if err != nil {
return fmt.Errorf("%s: making directory for file: %v", fpath, err) return fmt.Errorf("%s: making directory for file: %w", fpath, err)
} }
err = os.Symlink(target, fpath) err = os.Symlink(target, fpath)
if err != nil { if err != nil {
return fmt.Errorf("%s: making symbolic link for: %v", fpath, err) return fmt.Errorf("%s: making symbolic link for: %w", fpath, err)
} }
return nil return nil
} }
@ -176,11 +177,11 @@ func writeNewSymbolicLink(fpath string, target string) error {
func writeNewHardLink(fpath string, target string) error { func writeNewHardLink(fpath string, target string) error {
err := os.MkdirAll(filepath.Dir(fpath), defaultDirPerm) err := os.MkdirAll(filepath.Dir(fpath), defaultDirPerm)
if err != nil { if err != nil {
return fmt.Errorf("%s: making directory for file: %v", fpath, err) return fmt.Errorf("%s: making directory for file: %w", fpath, err)
} }
err = os.Link(target, fpath) err = os.Link(target, fpath)
if err != nil { if err != nil {
return fmt.Errorf("%s: making hard link for: %v", fpath, err) return fmt.Errorf("%s: making hard link for: %w", fpath, err)
} }
return nil return nil
} }

View File

@ -47,7 +47,8 @@ func (e *Errors) Equal(e2 error) bool {
for _, err := range e.Errs { for _, err := range e.Errs {
errs1 = append(errs1, err.Error()) errs1 = append(errs1, err.Error())
} }
if es2, ok := e2.(*Errors); ok { var es2 *Errors
if errors.As(e2, &es2) {
for _, err := range es2.Errs { for _, err := range es2.Errs {
errs2 = append(errs2, err.Error()) errs2 = append(errs2, err.Error())
} }
@ -72,13 +73,13 @@ func NewErrBadRequest(err error) *ErrBadRequest {
return &ErrBadRequest{Err: err} return &ErrBadRequest{Err: err}
} }
func (*ErrBadRequest) Is(err error) bool { func (e *ErrBadRequest) Unwrap() error {
_, ok := err.(*ErrBadRequest) return e.Err
return ok
} }
func IsBadRequest(err error) bool { func IsBadRequest(err error) bool {
return errors.Is(err, &ErrBadRequest{}) var e *ErrBadRequest
return errors.As(err, &e)
} }
// ErrNotExist represent a not exist error // ErrNotExist represent a not exist error
@ -95,13 +96,13 @@ func NewErrNotExist(err error) *ErrNotExist {
return &ErrNotExist{Err: err} return &ErrNotExist{Err: err}
} }
func (*ErrNotExist) Is(err error) bool { func (e *ErrNotExist) Unwrap() error {
_, ok := err.(*ErrNotExist) return e.Err
return ok
} }
func IsNotExist(err error) bool { func IsNotExist(err error) bool {
return errors.Is(err, &ErrNotExist{}) var e *ErrNotExist
return errors.As(err, &e)
} }
// ErrForbidden represent an error caused by an forbidden operation // ErrForbidden represent an error caused by an forbidden operation
@ -118,13 +119,13 @@ func NewErrForbidden(err error) *ErrForbidden {
return &ErrForbidden{Err: err} return &ErrForbidden{Err: err}
} }
func (*ErrForbidden) Is(err error) bool { func (e *ErrForbidden) Unwrap() error {
_, ok := err.(*ErrForbidden) return e.Err
return ok
} }
func IsForbidden(err error) bool { func IsForbidden(err error) bool {
return errors.Is(err, &ErrForbidden{}) var e *ErrForbidden
return errors.As(err, &e)
} }
// ErrUnauthorized represent an error caused by an unauthorized request // ErrUnauthorized represent an error caused by an unauthorized request
@ -141,13 +142,13 @@ func NewErrUnauthorized(err error) *ErrUnauthorized {
return &ErrUnauthorized{Err: err} return &ErrUnauthorized{Err: err}
} }
func (*ErrUnauthorized) Is(err error) bool { func (e *ErrUnauthorized) Unwrap() error {
_, ok := err.(*ErrUnauthorized) return e.Err
return ok
} }
func IsUnauthorized(err error) bool { func IsUnauthorized(err error) bool {
return errors.Is(err, &ErrUnauthorized{}) var e *ErrUnauthorized
return errors.As(err, &e)
} }
type ErrInternal struct { type ErrInternal struct {
@ -163,11 +164,11 @@ func NewErrInternal(err error) *ErrInternal {
return &ErrInternal{Err: err} return &ErrInternal{Err: err}
} }
func (*ErrInternal) Is(err error) bool { func (e *ErrInternal) Unwrap() error {
_, ok := err.(*ErrInternal) return e.Err
return ok
} }
func IsInternal(err error) bool { func IsInternal(err error) bool {
return errors.Is(err, &ErrInternal{}) var e *ErrInternal
return errors.As(err, &e)
} }

View File

@ -154,7 +154,8 @@ func (g *Git) ConfigGet(ctx context.Context, args ...string) (string, error) {
out, err := g.Output(ctx, nil, args...) out, err := g.Output(ctx, nil, args...)
if err != nil { if err != nil {
if exitError, ok := err.(*exec.ExitError); ok { var exitError *exec.ExitError
if errors.As(err, &exitError) {
if waitStatus, ok := exitError.Sys().(syscall.WaitStatus); ok { if waitStatus, ok := exitError.Sys().(syscall.WaitStatus); ok {
if waitStatus.ExitStatus() == 1 { if waitStatus.ExitStatus() == 1 {
return "", &ErrGitKeyNotFound{Key: args[len(args)-1]} return "", &ErrGitKeyNotFound{Key: args[len(args)-1]}
@ -172,7 +173,8 @@ func (g *Git) ConfigSet(ctx context.Context, args ...string) (string, error) {
out, err := g.Output(ctx, nil, args...) out, err := g.Output(ctx, nil, args...)
if err != nil { if err != nil {
if exitError, ok := err.(*exec.ExitError); ok { var exitError *exec.ExitError
if errors.As(err, &exitError) {
if waitStatus, ok := exitError.Sys().(syscall.WaitStatus); ok { if waitStatus, ok := exitError.Sys().(syscall.WaitStatus); ok {
if waitStatus.ExitStatus() == 1 { if waitStatus.ExitStatus() == 1 {
return "", &ErrGitKeyNotFound{Key: args[len(args)-1]} return "", &ErrGitKeyNotFound{Key: args[len(args)-1]}

View File

@ -16,6 +16,8 @@ package util
import ( import (
"golang.org/x/crypto/bcrypt" "golang.org/x/crypto/bcrypt"
errors "golang.org/x/xerrors"
) )
func PasswordHash(password string) (string, error) { func PasswordHash(password string) (string, error) {
@ -25,7 +27,7 @@ func PasswordHash(password string) (string, error) {
func CompareHashAndPassword(passwordHash, password string) (bool, error) { func CompareHashAndPassword(passwordHash, password string) (bool, error) {
if err := bcrypt.CompareHashAndPassword([]byte(passwordHash), []byte(password)); err != nil { if err := bcrypt.CompareHashAndPassword([]byte(passwordHash), []byte(password)); err != nil {
if err == bcrypt.ErrMismatchedHashAndPassword { if errors.Is(err, bcrypt.ErrMismatchedHashAndPassword) {
return false, nil return false, nil
} }
return false, err return false, err

View File

@ -359,7 +359,7 @@ func setup(ctx context.Context, t *testing.T, dir string) (*testutil.TestEmbedde
go func() { go func() {
err := <-errCh err := <-errCh
if err != nil { if err != nil {
panic(fmt.Errorf("agola component returned error: %+v", err)) panic(fmt.Errorf("agola component returned error: %w", err))
} }
}() }()