1
0
Fork 0

Update traefik dependencies (docker/docker and related) (#1823)

Update traefik dependencies (docker/docker and related)

- Update dependencies
- Fix compilation problems
- Remove vdemeester/docker-events (in docker api now)
- Remove `integration/vendor`
- Use `testImport`
- update some deps.
- regenerate the lock from scratch (after a `glide cc`)
This commit is contained in:
Vincent Demeester 2017-07-06 16:28:13 +02:00 committed by Ludovic Fernandez
parent 7d178f49b4
commit b7daa2f3a4
1301 changed files with 21476 additions and 150099 deletions

View file

@ -1,91 +0,0 @@
package events
import (
"encoding/json"
"io"
"golang.org/x/net/context"
"github.com/docker/engine-api/client"
"github.com/docker/engine-api/types"
eventtypes "github.com/docker/engine-api/types/events"
)
// Monitor subscribes to the docker events api using engine api and will execute the
// specified function on each message.
// It will pass the specified options to the underline method (i.e Events).
func Monitor(ctx context.Context, cli client.SystemAPIClient, options types.EventsOptions, fun func(m eventtypes.Message)) chan error {
handler := NewHandler(func(_ eventtypes.Message) string {
// Let's return always the same thing to not filter at all
return ""
})
handler.Handle("", fun)
return MonitorWithHandler(ctx, cli, options, handler)
}
// MonitorWithHandler subscribes to the docker events api using engine api and will pass the message
// to the specified Handler, that will take care of it.
// It will pass the specified options to the underline method (i.e Events).
func MonitorWithHandler(ctx context.Context, cli client.SystemAPIClient, options types.EventsOptions, handler *Handler) chan error {
eventChan := make(chan eventtypes.Message)
errChan := make(chan error)
started := make(chan struct{})
go handler.Watch(eventChan)
go monitorEvents(ctx, cli, options, started, eventChan, errChan)
go func() {
for {
select {
case <-ctx.Done():
// close(eventChan)
errChan <- nil
}
}
}()
<-started
return errChan
}
func monitorEvents(ctx context.Context, cli client.SystemAPIClient, options types.EventsOptions, started chan struct{}, eventChan chan eventtypes.Message, errChan chan error) {
body, err := cli.Events(ctx, options)
// Whether we successfully subscribed to events or not, we can now
// unblock the main goroutine.
close(started)
if err != nil {
errChan <- err
return
}
defer body.Close()
if err := decodeEvents(body, func(event eventtypes.Message, err error) error {
if err != nil {
return err
}
eventChan <- event
return nil
}); err != nil {
errChan <- err
return
}
}
type eventProcessor func(event eventtypes.Message, err error) error
func decodeEvents(input io.Reader, ep eventProcessor) error {
dec := json.NewDecoder(input)
for {
var event eventtypes.Message
err := dec.Decode(&event)
if err != nil && err == io.EOF {
break
}
if procErr := ep(event, err); procErr != nil {
return procErr
}
}
return nil
}

View file

@ -1,56 +0,0 @@
package events
import (
"sync"
eventtypes "github.com/docker/engine-api/types/events"
)
// NewHandler creates an event handler using the specified function to qualify the message
// and to route it to the correct handler.
func NewHandler(fun func(eventtypes.Message) string) *Handler {
return &Handler{
keyFunc: fun,
handlers: make(map[string]func(eventtypes.Message)),
}
}
// ByType is a qualify function based on message type.
func ByType(e eventtypes.Message) string {
return e.Type
}
// ByAction is a qualify function based on message action.
func ByAction(e eventtypes.Message) string {
return e.Action
}
// Handler is a struct holding the handlers by keys, and the function to get the
// key from the message.
type Handler struct {
keyFunc func(eventtypes.Message) string
handlers map[string]func(eventtypes.Message)
mu sync.Mutex
}
// Handle registers a function has handler for the specified key.
func (w *Handler) Handle(key string, h func(eventtypes.Message)) {
w.mu.Lock()
w.handlers[key] = h
w.mu.Unlock()
}
// Watch ranges over the passed in event chan and processes the events based on the
// handlers created for a given action.
// To stop watching, close the event chan.
func (w *Handler) Watch(c <-chan eventtypes.Message) {
for e := range c {
w.mu.Lock()
h, exists := w.handlers[w.keyFunc(e)]
w.mu.Unlock()
if !exists {
continue
}
go h(e)
}
}

46
vendor/github.com/vdemeester/shakers/bool.go generated vendored Normal file
View file

@ -0,0 +1,46 @@
package shakers
import (
"github.com/go-check/check"
)
// True checker verifies the obtained value is true
//
// c.Assert(myBool, True)
//
var True check.Checker = &boolChecker{
&check.CheckerInfo{
Name: "True",
Params: []string{"obtained"},
},
true,
}
// False checker verifies the obtained value is false
//
// c.Assert(myBool, False)
//
var False check.Checker = &boolChecker{
&check.CheckerInfo{
Name: "False",
Params: []string{"obtained"},
},
false,
}
type boolChecker struct {
*check.CheckerInfo
expected bool
}
func (checker *boolChecker) Check(params []interface{}, names []string) (bool, string) {
return is(checker.expected, params[0])
}
func is(expected bool, obtained interface{}) (bool, string) {
obtainedBool, ok := obtained.(bool)
if !ok {
return false, "obtained value must be a bool."
}
return obtainedBool == expected, ""
}

310
vendor/github.com/vdemeester/shakers/common.go generated vendored Normal file
View file

@ -0,0 +1,310 @@
package shakers
import (
"reflect"
"time"
"github.com/go-check/check"
)
// As a commodity, we bring all check.Checker variables into the current namespace to avoid having
// to think about check.X versus checker.X.
var (
DeepEquals = check.DeepEquals
ErrorMatches = check.ErrorMatches
FitsTypeOf = check.FitsTypeOf
HasLen = check.HasLen
Implements = check.Implements
IsNil = check.IsNil
Matches = check.Matches
Not = check.Not
NotNil = check.NotNil
PanicMatches = check.PanicMatches
Panics = check.Panics
)
// Equaler is an interface implemented if the type has a Equal method.
// This is used to compare struct using shakers.Equals.
type Equaler interface {
Equal(Equaler) bool
}
// Equals checker verifies the obtained value is equal to the specified one.
// It's is smart in a wait that it supports several *types* (built-in, Equaler,
// time.Time)
//
// c.Assert(myStruct, Equals, aStruct, check.Commentf("bouuuhh"))
// c.Assert(myTime, Equals, aTime, check.Commentf("bouuuhh"))
//
var Equals check.Checker = &equalChecker{
&check.CheckerInfo{
Name: "Equals",
Params: []string{"obtained", "expected"},
},
}
type equalChecker struct {
*check.CheckerInfo
}
func (checker *equalChecker) Check(params []interface{}, names []string) (bool, string) {
return isEqual(params[0], params[1])
}
func isEqual(obtained, expected interface{}) (bool, string) {
switch obtained.(type) {
case time.Time:
return timeEquals(obtained, expected)
case Equaler:
return equalerEquals(obtained, expected)
default:
if reflect.TypeOf(obtained) != reflect.TypeOf(expected) {
return false, "obtained value and expected value have not the same type."
}
return obtained == expected, ""
}
}
func equalerEquals(obtained, expected interface{}) (bool, string) {
expectedEqualer, ok := expected.(Equaler)
if !ok {
return false, "expected value must be an Equaler - implementing Equal(Equaler)."
}
obtainedEqualer, ok := obtained.(Equaler)
if !ok {
return false, "obtained value must be an Equaler - implementing Equal(Equaler)."
}
return obtainedEqualer.Equal(expectedEqualer), ""
}
// GreaterThan checker verifies the obtained value is greater than the specified one.
// It's is smart in a wait that it supports several *types* (built-in, time.Time)
//
// c.Assert(myTime, GreaterThan, aTime, check.Commentf("bouuuhh"))
// c.Assert(myInt, GreaterThan, 2, check.Commentf("bouuuhh"))
//
var GreaterThan check.Checker = &greaterThanChecker{
&check.CheckerInfo{
Name: "GreaterThan",
Params: []string{"obtained", "expected"},
},
}
type greaterThanChecker struct {
*check.CheckerInfo
}
func (checker *greaterThanChecker) Check(params []interface{}, names []string) (bool, string) {
return greaterThan(params[0], params[1])
}
func greaterThan(obtained, expected interface{}) (bool, string) {
if _, ok := obtained.(time.Time); ok {
return isAfter(obtained, expected)
}
if reflect.TypeOf(obtained) != reflect.TypeOf(expected) {
return false, "obtained value and expected value have not the same type."
}
switch v := obtained.(type) {
case float32:
return v > expected.(float32), ""
case float64:
return v > expected.(float64), ""
case int:
return v > expected.(int), ""
case int8:
return v > expected.(int8), ""
case int16:
return v > expected.(int16), ""
case int32:
return v > expected.(int32), ""
case int64:
return v > expected.(int64), ""
case uint:
return v > expected.(uint), ""
case uint8:
return v > expected.(uint8), ""
case uint16:
return v > expected.(uint16), ""
case uint32:
return v > expected.(uint32), ""
case uint64:
return v > expected.(uint64), ""
default:
return false, "obtained value type not supported."
}
}
// GreaterOrEqualThan checker verifies the obtained value is greater or equal than the specified one.
// It's is smart in a wait that it supports several *types* (built-in, time.Time)
//
// c.Assert(myTime, GreaterOrEqualThan, aTime, check.Commentf("bouuuhh"))
// c.Assert(myInt, GreaterOrEqualThan, 2, check.Commentf("bouuuhh"))
//
var GreaterOrEqualThan check.Checker = &greaterOrEqualThanChecker{
&check.CheckerInfo{
Name: "GreaterOrEqualThan",
Params: []string{"obtained", "expected"},
},
}
type greaterOrEqualThanChecker struct {
*check.CheckerInfo
}
func (checker *greaterOrEqualThanChecker) Check(params []interface{}, names []string) (bool, string) {
return greaterOrEqualThan(params[0], params[1])
}
func greaterOrEqualThan(obtained, expected interface{}) (bool, string) {
if _, ok := obtained.(time.Time); ok {
return isAfter(obtained, expected)
}
if reflect.TypeOf(obtained) != reflect.TypeOf(expected) {
return false, "obtained value and expected value have not the same type."
}
switch v := obtained.(type) {
case float32:
return v >= expected.(float32), ""
case float64:
return v >= expected.(float64), ""
case int:
return v >= expected.(int), ""
case int8:
return v >= expected.(int8), ""
case int16:
return v >= expected.(int16), ""
case int32:
return v >= expected.(int32), ""
case int64:
return v >= expected.(int64), ""
case uint:
return v >= expected.(uint), ""
case uint8:
return v >= expected.(uint8), ""
case uint16:
return v >= expected.(uint16), ""
case uint32:
return v >= expected.(uint32), ""
case uint64:
return v >= expected.(uint64), ""
default:
return false, "obtained value type not supported."
}
}
// LessThan checker verifies the obtained value is less than the specified one.
// It's is smart in a wait that it supports several *types* (built-in, time.Time)
//
// c.Assert(myTime, LessThan, aTime, check.Commentf("bouuuhh"))
// c.Assert(myInt, LessThan, 2, check.Commentf("bouuuhh"))
//
var LessThan check.Checker = &lessThanChecker{
&check.CheckerInfo{
Name: "LessThan",
Params: []string{"obtained", "expected"},
},
}
type lessThanChecker struct {
*check.CheckerInfo
}
func (checker *lessThanChecker) Check(params []interface{}, names []string) (bool, string) {
return lessThan(params[0], params[1])
}
func lessThan(obtained, expected interface{}) (bool, string) {
if _, ok := obtained.(time.Time); ok {
return isBefore(obtained, expected)
}
if reflect.TypeOf(obtained) != reflect.TypeOf(expected) {
return false, "obtained value and expected value have not the same type."
}
switch v := obtained.(type) {
case float32:
return v < expected.(float32), ""
case float64:
return v < expected.(float64), ""
case int:
return v < expected.(int), ""
case int8:
return v < expected.(int8), ""
case int16:
return v < expected.(int16), ""
case int32:
return v < expected.(int32), ""
case int64:
return v < expected.(int64), ""
case uint:
return v < expected.(uint), ""
case uint8:
return v < expected.(uint8), ""
case uint16:
return v < expected.(uint16), ""
case uint32:
return v < expected.(uint32), ""
case uint64:
return v < expected.(uint64), ""
default:
return false, "obtained value type not supported."
}
}
// LessOrEqualThan checker verifies the obtained value is less or equal than the specified one.
// It's is smart in a wait that it supports several *types* (built-in, time.Time)
//
// c.Assert(myTime, LessThan, aTime, check.Commentf("bouuuhh"))
// c.Assert(myInt, LessThan, 2, check.Commentf("bouuuhh"))
//
var LessOrEqualThan check.Checker = &lessOrEqualThanChecker{
&check.CheckerInfo{
Name: "LessOrEqualThan",
Params: []string{"obtained", "expected"},
},
}
type lessOrEqualThanChecker struct {
*check.CheckerInfo
}
func (checker *lessOrEqualThanChecker) Check(params []interface{}, names []string) (bool, string) {
return lessOrEqualThan(params[0], params[1])
}
func lessOrEqualThan(obtained, expected interface{}) (bool, string) {
if _, ok := obtained.(time.Time); ok {
return isBefore(obtained, expected)
}
if reflect.TypeOf(obtained) != reflect.TypeOf(expected) {
return false, "obtained value and expected value have not the same type."
}
switch v := obtained.(type) {
case float32:
return v <= expected.(float32), ""
case float64:
return v <= expected.(float64), ""
case int:
return v <= expected.(int), ""
case int8:
return v <= expected.(int8), ""
case int16:
return v <= expected.(int16), ""
case int32:
return v <= expected.(int32), ""
case int64:
return v <= expected.(int64), ""
case uint:
return v <= expected.(uint), ""
case uint8:
return v <= expected.(uint8), ""
case uint16:
return v <= expected.(uint16), ""
case uint32:
return v <= expected.(uint32), ""
case uint64:
return v <= expected.(uint64), ""
default:
return false, "obtained value type not supported."
}
}

168
vendor/github.com/vdemeester/shakers/string.go generated vendored Normal file
View file

@ -0,0 +1,168 @@
// Package shakers provide some checker implementation the go-check.Checker interface.
package shakers
import (
"fmt"
"strings"
"github.com/go-check/check"
)
// Contains checker verifies that obtained value contains a substring.
var Contains check.Checker = &substringChecker{
&check.CheckerInfo{
Name: "Contains",
Params: []string{"obtained", "substring"},
},
strings.Contains,
}
// ContainsAny checker verifies that any Unicode code points in chars
// are in the obtained string.
var ContainsAny check.Checker = &substringChecker{
&check.CheckerInfo{
Name: "ContainsAny",
Params: []string{"obtained", "chars"},
},
strings.ContainsAny,
}
// HasPrefix checker verifies that obtained value has the specified substring as prefix
var HasPrefix check.Checker = &substringChecker{
&check.CheckerInfo{
Name: "HasPrefix",
Params: []string{"obtained", "prefix"},
},
strings.HasPrefix,
}
// HasSuffix checker verifies that obtained value has the specified substring as prefix
var HasSuffix check.Checker = &substringChecker{
&check.CheckerInfo{
Name: "HasSuffix",
Params: []string{"obtained", "suffix"},
},
strings.HasSuffix,
}
// EqualFold checker verifies that obtained value is, interpreted as UTF-8 strings, are equal under Unicode case-folding.
var EqualFold check.Checker = &substringChecker{
&check.CheckerInfo{
Name: "EqualFold",
Params: []string{"obtained", "expected"},
},
strings.EqualFold,
}
type substringChecker struct {
*check.CheckerInfo
substringFunction func(string, string) bool
}
func (checker *substringChecker) Check(params []interface{}, names []string) (bool, string) {
obtained := params[0]
substring := params[1]
substringStr, ok := substring.(string)
if !ok {
return false, fmt.Sprintf("%s value must be a string.", names[1])
}
obtainedString, obtainedIsStr := obtained.(string)
if !obtainedIsStr {
if obtainedWithStringer, obtainedHasStringer := obtained.(fmt.Stringer); obtainedHasStringer {
obtainedString, obtainedIsStr = obtainedWithStringer.String(), true
}
}
if obtainedIsStr {
return checker.substringFunction(obtainedString, substringStr), ""
}
return false, "obtained value is not a string and has no .String()."
}
// IndexAny checker verifies that the index of the first instance of any Unicode code point from chars in the obtained value is equal to expected
var IndexAny check.Checker = &substringCountChecker{
&check.CheckerInfo{
Name: "IndexAny",
Params: []string{"obtained", "chars", "expected"},
},
strings.IndexAny,
}
// Index checker verifies that the index of the first instance of sep in the obtained value is equal to expected
var Index check.Checker = &substringCountChecker{
&check.CheckerInfo{
Name: "Index",
Params: []string{"obtained", "sep", "expected"},
},
strings.Index,
}
// Count checker verifies that obtained value has the specified number of non-overlapping instances of sep
var Count check.Checker = &substringCountChecker{
&check.CheckerInfo{
Name: "Count",
Params: []string{"obtained", "sep", "expected"},
},
strings.Count,
}
type substringCountChecker struct {
*check.CheckerInfo
substringFunction func(string, string) int
}
func (checker *substringCountChecker) Check(params []interface{}, names []string) (bool, string) {
obtained := params[0]
substring := params[1]
expected := params[2]
substringStr, ok := substring.(string)
if !ok {
return false, fmt.Sprintf("%s value must be a string.", names[1])
}
obtainedString, obtainedIsStr := obtained.(string)
if !obtainedIsStr {
if obtainedWithStringer, obtainedHasStringer := obtained.(fmt.Stringer); obtainedHasStringer {
obtainedString, obtainedIsStr = obtainedWithStringer.String(), true
}
}
if obtainedIsStr {
return checker.substringFunction(obtainedString, substringStr) == expected, ""
}
return false, "obtained value is not a string and has no .String()."
}
// IsLower checker verifies that the obtained value is in lower case
var IsLower check.Checker = &stringTransformChecker{
&check.CheckerInfo{
Name: "IsLower",
Params: []string{"obtained"},
},
strings.ToLower,
}
// IsUpper checker verifies that the obtained value is in lower case
var IsUpper check.Checker = &stringTransformChecker{
&check.CheckerInfo{
Name: "IsUpper",
Params: []string{"obtained"},
},
strings.ToUpper,
}
type stringTransformChecker struct {
*check.CheckerInfo
stringFunction func(string) string
}
func (checker *stringTransformChecker) Check(params []interface{}, names []string) (bool, string) {
obtained := params[0]
obtainedString, obtainedIsStr := obtained.(string)
if !obtainedIsStr {
if obtainedWithStringer, obtainedHasStringer := obtained.(fmt.Stringer); obtainedHasStringer {
obtainedString, obtainedIsStr = obtainedWithStringer.String(), true
}
}
if obtainedIsStr {
return checker.stringFunction(obtainedString) == obtainedString, ""
}
return false, "obtained value is not a string and has no .String()."
}

234
vendor/github.com/vdemeester/shakers/time.go generated vendored Normal file
View file

@ -0,0 +1,234 @@
package shakers
import (
"fmt"
"time"
"github.com/go-check/check"
)
// Default format when parsing (in addition to RFC and default time formats..)
const shortForm = "2006-01-02"
// IsBefore checker verifies the specified value is before the specified time.
// It is exclusive.
//
// c.Assert(myTime, IsBefore, theTime, check.Commentf("bouuuhhh"))
//
var IsBefore check.Checker = &isBeforeChecker{
&check.CheckerInfo{
Name: "IsBefore",
Params: []string{"obtained", "expected"},
},
}
type isBeforeChecker struct {
*check.CheckerInfo
}
func (checker *isBeforeChecker) Check(params []interface{}, names []string) (bool, string) {
return isBefore(params[0], params[1])
}
func isBefore(value, t interface{}) (bool, string) {
tTime, ok := parseTime(t)
if !ok {
return false, "expected must be a Time struct, or parseable."
}
valueTime, valueIsTime := parseTime(value)
if valueIsTime {
return valueTime.Before(tTime), ""
}
return false, "obtained value is not a time.Time struct or parseable as a time."
}
// IsAfter checker verifies the specified value is before the specified time.
// It is exclusive.
//
// c.Assert(myTime, IsAfter, theTime, check.Commentf("bouuuhhh"))
//
var IsAfter check.Checker = &isAfterChecker{
&check.CheckerInfo{
Name: "IsAfter",
Params: []string{"obtained", "expected"},
},
}
type isAfterChecker struct {
*check.CheckerInfo
}
func (checker *isAfterChecker) Check(params []interface{}, names []string) (bool, string) {
return isAfter(params[0], params[1])
}
func isAfter(value, t interface{}) (bool, string) {
tTime, ok := parseTime(t)
if !ok {
return false, "expected must be a Time struct, or parseable."
}
valueTime, valueIsTime := parseTime(value)
if valueIsTime {
return valueTime.After(tTime), ""
}
return false, "obtained value is not a time.Time struct or parseable as a time."
}
// IsBetween checker verifies the specified time is between the specified start
// and end. It's exclusive so if the specified time is at the tip of the interval.
//
// c.Assert(myTime, IsBetween, startTime, endTime, check.Commentf("bouuuhhh"))
//
var IsBetween check.Checker = &isBetweenChecker{
&check.CheckerInfo{
Name: "IsBetween",
Params: []string{"obtained", "start", "end"},
},
}
type isBetweenChecker struct {
*check.CheckerInfo
}
func (checker *isBetweenChecker) Check(params []interface{}, names []string) (bool, string) {
return isBetween(params[0], params[1], params[2])
}
func isBetween(value, start, end interface{}) (bool, string) {
startTime, ok := parseTime(start)
if !ok {
return false, "start must be a Time struct, or parseable."
}
endTime, ok := parseTime(end)
if !ok {
return false, "end must be a Time struct, or parseable."
}
valueTime, valueIsTime := parseTime(value)
if valueIsTime {
return valueTime.After(startTime) && valueTime.Before(endTime), ""
}
return false, "obtained value is not a time.Time struct or parseable as a time."
}
// TimeEquals checker verifies the specified time is the equal to the expected
// time.
//
// c.Assert(myTime, TimeEquals, expected, check.Commentf("bouhhh"))
//
// It's possible to ignore some part of the time (like hours, minutes, etc..) using
// the TimeIgnore checker with it.
//
// c.Assert(myTime, TimeIgnore(TimeEquals, time.Hour), expected, check.Commentf("... bouh.."))
//
var TimeEquals check.Checker = &timeEqualsChecker{
&check.CheckerInfo{
Name: "TimeEquals",
Params: []string{"obtained", "expected"},
},
}
type timeEqualsChecker struct {
*check.CheckerInfo
}
func (checker *timeEqualsChecker) Check(params []interface{}, names []string) (bool, string) {
return timeEquals(params[0], params[1])
}
func timeEquals(obtained, expected interface{}) (bool, string) {
expectedTime, ok := parseTime(expected)
if !ok {
return false, "expected must be a Time struct, or parseable."
}
valueTime, valueIsTime := parseTime(obtained)
if valueIsTime {
return valueTime.Equal(expectedTime), ""
}
return false, "obtained value is not a time.Time struct or parseable as a time."
}
// TimeIgnore checker will ignore some part of the time on the encapsulated checker.
//
// c.Assert(myTime, TimeIgnore(IsBetween, time.Second), start, end)
//
// FIXME use interface{} for ignore (to enable "Month", ..
func TimeIgnore(checker check.Checker, ignore time.Duration) check.Checker {
return &timeIgnoreChecker{
sub: checker,
ignore: ignore,
}
}
type timeIgnoreChecker struct {
sub check.Checker
ignore time.Duration
}
func (checker *timeIgnoreChecker) Info() *check.CheckerInfo {
info := *checker.sub.Info()
info.Name = fmt.Sprintf("TimeIgnore(%s, %v)", info.Name, checker.ignore)
return &info
}
func (checker *timeIgnoreChecker) Check(params []interface{}, names []string) (bool, string) {
// Naive implementation : all params are supposed to be date
mParams := make([]interface{}, len(params))
for index, param := range params {
paramTime, ok := parseTime(param)
if !ok {
return false, fmt.Sprintf("%s must be a Time struct, or parseable.", names[index])
}
year := paramTime.Year()
month := paramTime.Month()
day := paramTime.Day()
hour := paramTime.Hour()
min := paramTime.Minute()
sec := paramTime.Second()
nsec := paramTime.Nanosecond()
location := paramTime.Location()
switch checker.ignore {
case time.Hour:
hour = 0
fallthrough
case time.Minute:
min = 0
fallthrough
case time.Second:
sec = 0
fallthrough
case time.Millisecond:
fallthrough
case time.Microsecond:
fallthrough
case time.Nanosecond:
nsec = 0
}
mParams[index] = time.Date(year, month, day, hour, min, sec, nsec, location)
}
return checker.sub.Check(mParams, names)
}
func parseTime(datetime interface{}) (time.Time, bool) {
switch datetime.(type) {
case time.Time:
return datetime.(time.Time), true
case string:
return parseTimeAsString(datetime.(string))
default:
if datetimeWithStr, ok := datetime.(fmt.Stringer); ok {
return parseTimeAsString(datetimeWithStr.String())
}
return time.Time{}, false
}
}
func parseTimeAsString(timeAsStr string) (time.Time, bool) {
forms := []string{shortForm, time.RFC3339, time.RFC3339Nano, time.RFC822, time.RFC822Z}
for _, form := range forms {
datetime, err := time.Parse(form, timeAsStr)
if err == nil {
return datetime, true
}
}
return time.Time{}, false
}