chore: tweak linter

pull/4016/head
Steven 9 months ago
parent f467f1d9f6
commit 43d13a3edc

@ -1,6 +1,7 @@
package cron package cron
import ( import (
"errors"
"fmt" "fmt"
"runtime" "runtime"
"sync" "sync"
@ -48,7 +49,7 @@ func Recover(logger Logger) JobWrapper {
buf = buf[:runtime.Stack(buf, false)] buf = buf[:runtime.Stack(buf, false)]
err, ok := r.(error) err, ok := r.(error)
if !ok { if !ok {
err = fmt.Errorf("%v", r) err = errors.New("panic: " + fmt.Sprint(r))
} }
logger.Error(err, "panic", "stack", "...\n"+string(buf)) logger.Error(err, "panic", "stack", "...\n"+string(buf))
} }

@ -46,7 +46,7 @@ func TestChainRecover(t *testing.T) {
panic("panickingJob panics") panic("panickingJob panics")
}) })
t.Run("panic exits job by default", func(t *testing.T) { t.Run("panic exits job by default", func(*testing.T) {
defer func() { defer func() {
if err := recover(); err == nil { if err := recover(); err == nil {
t.Errorf("panic expected, but none received") t.Errorf("panic expected, but none received")
@ -56,13 +56,13 @@ func TestChainRecover(t *testing.T) {
Run() Run()
}) })
t.Run("Recovering JobWrapper recovers", func(t *testing.T) { t.Run("Recovering JobWrapper recovers", func(*testing.T) {
NewChain(Recover(PrintfLogger(log.New(io.Discard, "", 0)))). NewChain(Recover(PrintfLogger(log.New(io.Discard, "", 0)))).
Then(panickingJob). Then(panickingJob).
Run() Run()
}) })
t.Run("composed with the *IfStillRunning wrappers", func(t *testing.T) { t.Run("composed with the *IfStillRunning wrappers", func(*testing.T) {
NewChain(Recover(PrintfLogger(log.New(io.Discard, "", 0)))). NewChain(Recover(PrintfLogger(log.New(io.Discard, "", 0)))).
Then(panickingJob). Then(panickingJob).
Run() Run()
@ -99,8 +99,7 @@ func (j *countJob) Done() int {
} }
func TestChainDelayIfStillRunning(t *testing.T) { func TestChainDelayIfStillRunning(t *testing.T) {
t.Run("runs immediately", func(*testing.T) {
t.Run("runs immediately", func(t *testing.T) {
var j countJob var j countJob
wrappedJob := NewChain(DelayIfStillRunning(DiscardLogger)).Then(&j) wrappedJob := NewChain(DelayIfStillRunning(DiscardLogger)).Then(&j)
go wrappedJob.Run() go wrappedJob.Run()
@ -110,7 +109,7 @@ func TestChainDelayIfStillRunning(t *testing.T) {
} }
}) })
t.Run("second run immediate if first done", func(t *testing.T) { t.Run("second run immediate if first done", func(*testing.T) {
var j countJob var j countJob
wrappedJob := NewChain(DelayIfStillRunning(DiscardLogger)).Then(&j) wrappedJob := NewChain(DelayIfStillRunning(DiscardLogger)).Then(&j)
go func() { go func() {
@ -124,7 +123,7 @@ func TestChainDelayIfStillRunning(t *testing.T) {
} }
}) })
t.Run("second run delayed if first not done", func(t *testing.T) { t.Run("second run delayed if first not done", func(*testing.T) {
var j countJob var j countJob
j.delay = 10 * time.Millisecond j.delay = 10 * time.Millisecond
wrappedJob := NewChain(DelayIfStillRunning(DiscardLogger)).Then(&j) wrappedJob := NewChain(DelayIfStillRunning(DiscardLogger)).Then(&j)
@ -149,12 +148,10 @@ func TestChainDelayIfStillRunning(t *testing.T) {
t.Error("expected both jobs done, got", started, done) t.Error("expected both jobs done, got", started, done)
} }
}) })
} }
func TestChainSkipIfStillRunning(t *testing.T) { func TestChainSkipIfStillRunning(t *testing.T) {
t.Run("runs immediately", func(*testing.T) {
t.Run("runs immediately", func(t *testing.T) {
var j countJob var j countJob
wrappedJob := NewChain(SkipIfStillRunning(DiscardLogger)).Then(&j) wrappedJob := NewChain(SkipIfStillRunning(DiscardLogger)).Then(&j)
go wrappedJob.Run() go wrappedJob.Run()
@ -164,7 +161,7 @@ func TestChainSkipIfStillRunning(t *testing.T) {
} }
}) })
t.Run("second run immediate if first done", func(t *testing.T) { t.Run("second run immediate if first done", func(*testing.T) {
var j countJob var j countJob
wrappedJob := NewChain(SkipIfStillRunning(DiscardLogger)).Then(&j) wrappedJob := NewChain(SkipIfStillRunning(DiscardLogger)).Then(&j)
go func() { go func() {
@ -178,7 +175,7 @@ func TestChainSkipIfStillRunning(t *testing.T) {
} }
}) })
t.Run("second run skipped if first not done", func(t *testing.T) { t.Run("second run skipped if first not done", func(*testing.T) {
var j countJob var j countJob
j.delay = 10 * time.Millisecond j.delay = 10 * time.Millisecond
wrappedJob := NewChain(SkipIfStillRunning(DiscardLogger)).Then(&j) wrappedJob := NewChain(SkipIfStillRunning(DiscardLogger)).Then(&j)
@ -204,7 +201,7 @@ func TestChainSkipIfStillRunning(t *testing.T) {
} }
}) })
t.Run("skip 10 jobs on rapid fire", func(t *testing.T) { t.Run("skip 10 jobs on rapid fire", func(*testing.T) {
var j countJob var j countJob
j.delay = 10 * time.Millisecond j.delay = 10 * time.Millisecond
wrappedJob := NewChain(SkipIfStillRunning(DiscardLogger)).Then(&j) wrappedJob := NewChain(SkipIfStillRunning(DiscardLogger)).Then(&j)
@ -218,7 +215,7 @@ func TestChainSkipIfStillRunning(t *testing.T) {
} }
}) })
t.Run("different jobs independent", func(t *testing.T) { t.Run("different jobs independent", func(*testing.T) {
var j1, j2 countJob var j1, j2 countJob
j1.delay = 10 * time.Millisecond j1.delay = 10 * time.Millisecond
j2.delay = 10 * time.Millisecond j2.delay = 10 * time.Millisecond
@ -238,5 +235,4 @@ func TestChainSkipIfStillRunning(t *testing.T) {
t.Error("expected both jobs executed once, got", done1, "and", done2) t.Error("expected both jobs executed once, got", done1, "and", done2)
} }
}) })
} }

@ -26,7 +26,7 @@ type Cron struct {
jobWaiter sync.WaitGroup jobWaiter sync.WaitGroup
} }
// ScheduleParser is an interface for schedule spec parsers that return a Schedule // ScheduleParser is an interface for schedule spec parsers that return a Schedule.
type ScheduleParser interface { type ScheduleParser interface {
Parse(spec string) (Schedule, error) Parse(spec string) (Schedule, error)
} }
@ -43,7 +43,7 @@ type Schedule interface {
Next(time.Time) time.Time Next(time.Time) time.Time
} }
// EntryID identifies an entry within a Cron instance // EntryID identifies an entry within a Cron instance.
type EntryID int type EntryID int
// Entry consists of a schedule and the func to execute on that schedule. // Entry consists of a schedule and the func to execute on that schedule.
@ -97,17 +97,17 @@ func (s byTime) Less(i, j int) bool {
// //
// Available Settings // Available Settings
// //
// Time Zone // Time Zone
// Description: The time zone in which schedules are interpreted // Description: The time zone in which schedules are interpreted
// Default: time.Local // Default: time.Local
// //
// Parser // Parser
// Description: Parser converts cron spec strings into cron.Schedules. // Description: Parser converts cron spec strings into cron.Schedules.
// Default: Accepts this spec: https://en.wikipedia.org/wiki/Cron // Default: Accepts this spec: https://en.wikipedia.org/wiki/Cron
// //
// Chain // Chain
// Description: Wrap submitted jobs to customize behavior. // Description: Wrap submitted jobs to customize behavior.
// Default: A chain that recovers panics and logs them to stderr. // Default: A chain that recovers panics and logs them to stderr.
// //
// See "cron.With*" to modify the default behavior. // See "cron.With*" to modify the default behavior.
func New(opts ...Option) *Cron { func New(opts ...Option) *Cron {
@ -130,7 +130,7 @@ func New(opts ...Option) *Cron {
return c return c
} }
// FuncJob is a wrapper that turns a func() into a cron.Job // FuncJob is a wrapper that turns a func() into a cron.Job.
type FuncJob func() type FuncJob func()
func (f FuncJob) Run() { f() } func (f FuncJob) Run() { f() }

@ -59,7 +59,7 @@ func TestFuncPanicRecovery(t *testing.T) {
type DummyJob struct{} type DummyJob struct{}
func (d DummyJob) Run() { func (DummyJob) Run() {
panic("YOLO") panic("YOLO")
} }
@ -556,7 +556,7 @@ func TestJobWithZeroTimeDoesNotRun(t *testing.T) {
} }
func TestStopAndWait(t *testing.T) { func TestStopAndWait(t *testing.T) {
t.Run("nothing running, returns immediately", func(t *testing.T) { t.Run("nothing running, returns immediately", func(*testing.T) {
cron := newWithSeconds() cron := newWithSeconds()
cron.Start() cron.Start()
ctx := cron.Stop() ctx := cron.Stop()
@ -567,7 +567,7 @@ func TestStopAndWait(t *testing.T) {
} }
}) })
t.Run("repeated calls to Stop", func(t *testing.T) { t.Run("repeated calls to Stop", func(*testing.T) {
cron := newWithSeconds() cron := newWithSeconds()
cron.Start() cron.Start()
_ = cron.Stop() _ = cron.Stop()
@ -580,7 +580,7 @@ func TestStopAndWait(t *testing.T) {
} }
}) })
t.Run("a couple fast jobs added, still returns immediately", func(t *testing.T) { t.Run("a couple fast jobs added, still returns immediately", func(*testing.T) {
cron := newWithSeconds() cron := newWithSeconds()
cron.AddFunc("* * * * * *", func() {}) cron.AddFunc("* * * * * *", func() {})
cron.Start() cron.Start()
@ -596,7 +596,7 @@ func TestStopAndWait(t *testing.T) {
} }
}) })
t.Run("a couple fast jobs and a slow job added, waits for slow job", func(t *testing.T) { t.Run("a couple fast jobs and a slow job added, waits for slow job", func(*testing.T) {
cron := newWithSeconds() cron := newWithSeconds()
cron.AddFunc("* * * * * *", func() {}) cron.AddFunc("* * * * * *", func() {})
cron.Start() cron.Start()
@ -623,7 +623,7 @@ func TestStopAndWait(t *testing.T) {
} }
}) })
t.Run("repeated calls to stop, waiting for completion and after", func(t *testing.T) { t.Run("repeated calls to stop, waiting for completion and after", func(*testing.T) {
cron := newWithSeconds() cron := newWithSeconds()
cron.AddFunc("* * * * * *", func() {}) cron.AddFunc("* * * * * *", func() {})
cron.AddFunc("* * * * * *", func() { time.Sleep(2 * time.Second) }) cron.AddFunc("* * * * * *", func() { time.Sleep(2 * time.Second) })

@ -1,11 +1,12 @@
package cron package cron
import ( import (
"fmt"
"math" "math"
"strconv" "strconv"
"strings" "strings"
"time" "time"
"github.com/pkg/errors"
) )
// Configuration options for creating a parser. Most options specify which // Configuration options for creating a parser. Most options specify which
@ -86,7 +87,7 @@ func NewParser(options ParseOption) Parser {
// It accepts crontab specs and features configured by NewParser. // It accepts crontab specs and features configured by NewParser.
func (p Parser) Parse(spec string) (Schedule, error) { func (p Parser) Parse(spec string) (Schedule, error) {
if len(spec) == 0 { if len(spec) == 0 {
return nil, fmt.Errorf("empty spec string") return nil, errors.New("empty spec string")
} }
// Extract timezone if present // Extract timezone if present
@ -96,7 +97,7 @@ func (p Parser) Parse(spec string) (Schedule, error) {
i := strings.Index(spec, " ") i := strings.Index(spec, " ")
eq := strings.Index(spec, "=") eq := strings.Index(spec, "=")
if loc, err = time.LoadLocation(spec[eq+1 : i]); err != nil { if loc, err = time.LoadLocation(spec[eq+1 : i]); err != nil {
return nil, fmt.Errorf("provided bad location %s: %v", spec[eq+1:i], err) return nil, errors.Wrap(err, "provided bad location")
} }
spec = strings.TrimSpace(spec[i:]) spec = strings.TrimSpace(spec[i:])
} }
@ -104,7 +105,7 @@ func (p Parser) Parse(spec string) (Schedule, error) {
// Handle named schedules (descriptors), if configured // Handle named schedules (descriptors), if configured
if strings.HasPrefix(spec, "@") { if strings.HasPrefix(spec, "@") {
if p.options&Descriptor == 0 { if p.options&Descriptor == 0 {
return nil, fmt.Errorf("parser does not accept descriptors: %v", spec) return nil, errors.New("descriptors not enabled")
} }
return parseDescriptor(spec, loc) return parseDescriptor(spec, loc)
} }
@ -168,7 +169,7 @@ func normalizeFields(fields []string, options ParseOption) ([]string, error) {
optionals++ optionals++
} }
if optionals > 1 { if optionals > 1 {
return nil, fmt.Errorf("multiple optionals may not be configured") return nil, errors.New("multiple optionals may not be configured")
} }
// Figure out how many fields we need // Figure out how many fields we need
@ -183,9 +184,9 @@ func normalizeFields(fields []string, options ParseOption) ([]string, error) {
// Validate number of fields // Validate number of fields
if count := len(fields); count < min || count > max { if count := len(fields); count < min || count > max {
if min == max { if min == max {
return nil, fmt.Errorf("expected exactly %d fields, found %d: %s", min, count, fields) return nil, errors.New("incorrect number of fields")
} }
return nil, fmt.Errorf("expected %d to %d fields, found %d: %s", min, max, count, fields) return nil, errors.New("incorrect number of fields, expected " + strconv.Itoa(min) + "-" + strconv.Itoa(max))
} }
// Populate the optional field if not provided // Populate the optional field if not provided
@ -196,7 +197,7 @@ func normalizeFields(fields []string, options ParseOption) ([]string, error) {
case options&SecondOptional > 0: case options&SecondOptional > 0:
fields = append([]string{defaults[0]}, fields...) fields = append([]string{defaults[0]}, fields...)
default: default:
return nil, fmt.Errorf("unknown optional field") return nil, errors.New("unexpected optional field")
} }
} }
@ -278,7 +279,7 @@ func getRange(expr string, r bounds) (uint64, error) {
return 0, err return 0, err
} }
default: default:
return 0, fmt.Errorf("too many hyphens: %s", expr) return 0, errors.New("too many hyphens: " + expr)
} }
} }
@ -299,20 +300,20 @@ func getRange(expr string, r bounds) (uint64, error) {
extra = 0 extra = 0
} }
default: default:
return 0, fmt.Errorf("too many slashes: %s", expr) return 0, errors.New("too many slashes: " + expr)
} }
if start < r.min { if start < r.min {
return 0, fmt.Errorf("beginning of range (%d) below minimum (%d): %s", start, r.min, expr) return 0, errors.New("beginning of range below minimum: " + expr)
} }
if end > r.max { if end > r.max {
return 0, fmt.Errorf("end of range (%d) above maximum (%d): %s", end, r.max, expr) return 0, errors.New("end of range above maximum: " + expr)
} }
if start > end { if start > end {
return 0, fmt.Errorf("beginning of range (%d) beyond end of range (%d): %s", start, end, expr) return 0, errors.New("beginning of range after end: " + expr)
} }
if step == 0 { if step == 0 {
return 0, fmt.Errorf("step of range should be a positive number: %s", expr) return 0, errors.New("step cannot be zero: " + expr)
} }
return getBits(start, end, step) | extra, nil return getBits(start, end, step) | extra, nil
@ -332,10 +333,10 @@ func parseIntOrName(expr string, names map[string]uint) (uint, error) {
func mustParseInt(expr string) (uint, error) { func mustParseInt(expr string) (uint, error) {
num, err := strconv.Atoi(expr) num, err := strconv.Atoi(expr)
if err != nil { if err != nil {
return 0, fmt.Errorf("failed to parse int from %s: %s", expr, err) return 0, errors.Wrap(err, "failed to parse number")
} }
if num < 0 { if num < 0 {
return 0, fmt.Errorf("negative number (%d) not allowed: %s", num, expr) return 0, errors.New("number must be positive")
} }
return uint(num), nil return uint(num), nil
@ -419,17 +420,16 @@ func parseDescriptor(descriptor string, loc *time.Location) (Schedule, error) {
Dow: all(dow), Dow: all(dow),
Location: loc, Location: loc,
}, nil }, nil
} }
const every = "@every " const every = "@every "
if strings.HasPrefix(descriptor, every) { if strings.HasPrefix(descriptor, every) {
duration, err := time.ParseDuration(descriptor[len(every):]) duration, err := time.ParseDuration(descriptor[len(every):])
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to parse duration %s: %s", descriptor, err) return nil, errors.Wrap(err, "failed to parse duration")
} }
return Every(duration), nil return Every(duration), nil
} }
return nil, fmt.Errorf("unrecognized descriptor: %s", descriptor) return nil, errors.New("unrecognized descriptor: " + descriptor)
} }

@ -255,7 +255,7 @@ func TestNormalizeFields(t *testing.T) {
} }
for _, test := range tests { for _, test := range tests {
t.Run(test.name, func(t *testing.T) { t.Run(test.name, func(*testing.T) {
actual, err := normalizeFields(test.input, test.options) actual, err := normalizeFields(test.input, test.options)
if err != nil { if err != nil {
t.Errorf("unexpected error: %v", err) t.Errorf("unexpected error: %v", err)
@ -300,7 +300,7 @@ func TestNormalizeFields_Errors(t *testing.T) {
}, },
} }
for _, test := range tests { for _, test := range tests {
t.Run(test.name, func(t *testing.T) { t.Run(test.name, func(*testing.T) {
actual, err := normalizeFields(test.input, test.options) actual, err := normalizeFields(test.input, test.options)
if err == nil { if err == nil {
t.Errorf("expected an error, got none. results: %v", actual) t.Errorf("expected an error, got none. results: %v", actual)

@ -67,7 +67,7 @@ func TestNewIdentityProvider(t *testing.T) {
}, },
} }
for _, test := range tests { for _, test := range tests {
t.Run(test.name, func(t *testing.T) { t.Run(test.name, func(*testing.T) {
_, err := NewIdentityProvider(test.config) _, err := NewIdentityProvider(test.config)
assert.ErrorContains(t, err, test.containsErr) assert.ErrorContains(t, err, test.containsErr)
}) })

@ -27,7 +27,7 @@ func TestUIDMatcher(t *testing.T) {
} }
for _, test := range tests { for _, test := range tests {
t.Run(test.input, func(t *testing.T) { t.Run(test.input, func(*testing.T) {
result := util.UIDMatcher.MatchString(test.input) result := util.UIDMatcher.MatchString(test.input)
if result != test.expected { if result != test.expected {
t.Errorf("For input '%s', expected %v but got %v", test.input, test.expected, result) t.Errorf("For input '%s', expected %v but got %v", test.input, test.expected, result)

Loading…
Cancel
Save