Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
小 白蛋
Nomad
Commits
763e315e
Commit
763e315e
authored
4 years ago
by
Seth Hoenig
Browse files
Options
Download
Email Patches
Plain Diff
wip work on ingress gateways
parent
fe91bdd0
Changes
167
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
api/services.go
+273
-0
api/services.go
api/services_test.go
+158
-0
api/services_test.go
api/vendor/github.com/davecgh/go-spew/LICENSE
+15
-0
api/vendor/github.com/davecgh/go-spew/LICENSE
api/vendor/github.com/davecgh/go-spew/spew/bypass.go
+145
-0
api/vendor/github.com/davecgh/go-spew/spew/bypass.go
api/vendor/github.com/davecgh/go-spew/spew/bypasssafe.go
+38
-0
api/vendor/github.com/davecgh/go-spew/spew/bypasssafe.go
api/vendor/github.com/davecgh/go-spew/spew/common.go
+341
-0
api/vendor/github.com/davecgh/go-spew/spew/common.go
api/vendor/github.com/davecgh/go-spew/spew/config.go
+306
-0
api/vendor/github.com/davecgh/go-spew/spew/config.go
api/vendor/github.com/davecgh/go-spew/spew/doc.go
+211
-0
api/vendor/github.com/davecgh/go-spew/spew/doc.go
api/vendor/github.com/davecgh/go-spew/spew/dump.go
+509
-0
api/vendor/github.com/davecgh/go-spew/spew/dump.go
api/vendor/github.com/davecgh/go-spew/spew/format.go
+419
-0
api/vendor/github.com/davecgh/go-spew/spew/format.go
api/vendor/github.com/davecgh/go-spew/spew/spew.go
+148
-0
api/vendor/github.com/davecgh/go-spew/spew/spew.go
api/vendor/github.com/docker/go-units/CONTRIBUTING.md
+67
-0
api/vendor/github.com/docker/go-units/CONTRIBUTING.md
api/vendor/github.com/docker/go-units/LICENSE
+191
-0
api/vendor/github.com/docker/go-units/LICENSE
api/vendor/github.com/docker/go-units/MAINTAINERS
+46
-0
api/vendor/github.com/docker/go-units/MAINTAINERS
api/vendor/github.com/docker/go-units/README.md
+16
-0
api/vendor/github.com/docker/go-units/README.md
api/vendor/github.com/docker/go-units/circle.yml
+11
-0
api/vendor/github.com/docker/go-units/circle.yml
api/vendor/github.com/docker/go-units/duration.go
+35
-0
api/vendor/github.com/docker/go-units/duration.go
api/vendor/github.com/docker/go-units/size.go
+108
-0
api/vendor/github.com/docker/go-units/size.go
api/vendor/github.com/docker/go-units/ulimit.go
+118
-0
api/vendor/github.com/docker/go-units/ulimit.go
api/vendor/github.com/gorilla/websocket/.gitignore
+25
-0
api/vendor/github.com/gorilla/websocket/.gitignore
with
3180 additions
and
0 deletions
+3180
-0
api/services.go
+
273
-
0
View file @
763e315e
...
...
@@ -152,6 +152,7 @@ func (s *Service) Canonicalize(t *Task, tg *TaskGroup, job *Job) {
// ConsulConnect represents a Consul Connect jobspec stanza.
type
ConsulConnect
struct
{
Native
bool
Gateway
*
ConsulGateway
SidecarService
*
ConsulSidecarService
`mapstructure:"sidecar_service"`
SidecarTask
*
SidecarTask
`mapstructure:"sidecar_task"`
}
...
...
@@ -163,6 +164,7 @@ func (cc *ConsulConnect) Canonicalize() {
cc
.
SidecarService
.
Canonicalize
()
cc
.
SidecarTask
.
Canonicalize
()
cc
.
Gateway
.
Canonicalize
()
}
// ConsulSidecarService represents a Consul Connect SidecarService jobspec
...
...
@@ -290,3 +292,274 @@ type ConsulExposePath struct {
LocalPathPort
int
`mapstructure:"local_path_port"`
ListenerPort
string
`mapstructure:"listener_port"`
}
// ConsulGateway is used to configure one of the Consul Connect Gateway types.
type
ConsulGateway
struct
{
// Proxy is used to configure the Envoy instance acting as the gateway.
Proxy
*
ConsulGatewayProxy
// Ingress represents the Consul Configuration Entry for an Ingress Gateway.
Ingress
*
ConsulIngressConfigEntry
// Terminating is not yet supported.
// Terminating *ConsulTerminatingConfigEntry
// Mesh is not yet supported.
// Mesh *ConsulMeshConfigEntry
}
func
(
g
*
ConsulGateway
)
Canonicalize
()
{
if
g
==
nil
{
return
}
g
.
Proxy
.
Canonicalize
()
g
.
Ingress
.
Canonicalize
()
}
func
(
g
*
ConsulGateway
)
Copy
()
*
ConsulGateway
{
if
g
==
nil
{
return
nil
}
return
&
ConsulGateway
{
Proxy
:
g
.
Proxy
.
Copy
(),
Ingress
:
g
.
Ingress
.
Copy
(),
}
}
type
ConsulGatewayBindAddress
struct
{
Address
string
`mapstructure:"address"`
Port
int
`mapstructure:"port"`
}
const
(
defaultDNSDiscoveryType
=
"LOGICAL_DNS"
)
var
(
defaultGatewayConnectTimeout
=
5
*
time
.
Second
)
// ConsulGatewayProxy is used to tune parameters of the proxy instance acting as
// one of the forms of Connect gateways that Consul supports.
//
// https://www.consul.io/docs/connect/proxies/envoy#gateway-options
type
ConsulGatewayProxy
struct
{
ConnectTimeout
*
time
.
Duration
`mapstructure:"connect_timeout"`
EnvoyGatewayBindTaggedAddresses
bool
`mapstructure:"envoy_gateway_bind_tagged_addresses"`
EnvoyGatewayBindAddresses
map
[
string
]
*
ConsulGatewayBindAddress
`mapstructure:"envoy_gateway_bind_addresses"`
EnvoyGatewayNoDefaultBind
bool
`mapstructure:"envoy_gateway_no_default_bind"`
EnvoyDNSDiscoveryType
string
`mapstructure:"envoy_dns_discovery_type"`
Config
map
[
string
]
interface
{}
// escape hatch envoy config
}
func
(
p
*
ConsulGatewayProxy
)
Canonicalize
()
{
if
p
==
nil
{
return
}
if
p
.
ConnectTimeout
==
nil
{
// same as the default from consul
p
.
ConnectTimeout
=
timeToPtr
(
defaultGatewayConnectTimeout
)
}
if
p
.
EnvoyDNSDiscoveryType
==
""
{
// same as default from consul
p
.
EnvoyDNSDiscoveryType
=
defaultDNSDiscoveryType
}
if
len
(
p
.
EnvoyGatewayBindAddresses
)
==
0
{
p
.
EnvoyGatewayBindAddresses
=
nil
}
if
len
(
p
.
Config
)
==
0
{
p
.
Config
=
nil
}
}
func
(
p
*
ConsulGatewayProxy
)
Copy
()
*
ConsulGatewayProxy
{
if
p
==
nil
{
return
nil
}
var
binds
map
[
string
]
*
ConsulGatewayBindAddress
=
nil
if
p
.
EnvoyGatewayBindAddresses
!=
nil
{
binds
=
make
(
map
[
string
]
*
ConsulGatewayBindAddress
,
len
(
p
.
EnvoyGatewayBindAddresses
))
for
k
,
v
:=
range
p
.
EnvoyGatewayBindAddresses
{
binds
[
k
]
=
v
}
}
var
config
map
[
string
]
interface
{}
=
nil
if
p
.
Config
!=
nil
{
config
=
make
(
map
[
string
]
interface
{},
len
(
p
.
Config
))
for
k
,
v
:=
range
p
.
Config
{
config
[
k
]
=
v
}
}
return
&
ConsulGatewayProxy
{
ConnectTimeout
:
timeToPtr
(
*
p
.
ConnectTimeout
),
EnvoyGatewayBindTaggedAddresses
:
p
.
EnvoyGatewayBindTaggedAddresses
,
EnvoyGatewayBindAddresses
:
binds
,
EnvoyGatewayNoDefaultBind
:
p
.
EnvoyGatewayNoDefaultBind
,
EnvoyDNSDiscoveryType
:
p
.
EnvoyDNSDiscoveryType
,
Config
:
config
,
}
}
// ConsulGatewayTLSConfig is used to configure TLS for a gateway.
type
ConsulGatewayTLSConfig
struct
{
Enabled
bool
}
func
(
tc
*
ConsulGatewayTLSConfig
)
Canonicalize
()
{
}
func
(
tc
*
ConsulGatewayTLSConfig
)
Copy
()
*
ConsulGatewayTLSConfig
{
if
tc
==
nil
{
return
nil
}
return
&
ConsulGatewayTLSConfig
{
Enabled
:
tc
.
Enabled
,
}
}
// ConsulIngressService is used to configure a service fronted by the ingress gateway.
type
ConsulIngressService
struct
{
// Namespace is not yet supported.
// Namespace string
Name
string
Hosts
[]
string
}
func
(
s
*
ConsulIngressService
)
Canonicalize
()
{
if
s
==
nil
{
return
}
if
len
(
s
.
Hosts
)
==
0
{
s
.
Hosts
=
nil
}
}
func
(
s
*
ConsulIngressService
)
Copy
()
*
ConsulIngressService
{
if
s
==
nil
{
return
nil
}
var
hosts
[]
string
=
nil
if
n
:=
len
(
s
.
Hosts
);
n
>
0
{
hosts
=
make
([]
string
,
n
)
copy
(
hosts
,
s
.
Hosts
)
}
return
&
ConsulIngressService
{
Name
:
s
.
Name
,
Hosts
:
hosts
,
}
}
const
(
defaultIngressListenerProtocol
=
"tcp"
)
// ConsulIngressListener is used to configure a listener on a Consul Ingress
// Gateway.
type
ConsulIngressListener
struct
{
Port
int
Protocol
string
Services
[]
*
ConsulIngressService
}
func
(
l
*
ConsulIngressListener
)
Canonicalize
()
{
if
l
==
nil
{
return
}
if
l
.
Protocol
==
""
{
// same as default from consul
l
.
Protocol
=
defaultIngressListenerProtocol
}
if
len
(
l
.
Services
)
==
0
{
l
.
Services
=
nil
}
}
func
(
l
*
ConsulIngressListener
)
Copy
()
*
ConsulIngressListener
{
if
l
==
nil
{
return
nil
}
var
services
[]
*
ConsulIngressService
=
nil
if
n
:=
len
(
l
.
Services
);
n
>
0
{
services
=
make
([]
*
ConsulIngressService
,
n
)
for
i
:=
0
;
i
<
n
;
i
++
{
services
[
i
]
=
l
.
Services
[
i
]
.
Copy
()
}
}
return
&
ConsulIngressListener
{
Port
:
l
.
Port
,
Protocol
:
l
.
Protocol
,
Services
:
services
,
}
}
// ConsulIngressConfigEntry represents the Consul Configuration Entry type for
// an Ingress Gateway.
//
// https://www.consul.io/docs/agent/config-entries/ingress-gateway#available-fields
type
ConsulIngressConfigEntry
struct
{
// Namespace is not yet supported.
// Namespace string
TLS
*
ConsulGatewayTLSConfig
Listeners
[]
*
ConsulIngressListener
}
func
(
e
*
ConsulIngressConfigEntry
)
Canonicalize
()
{
if
e
==
nil
{
return
}
e
.
TLS
.
Canonicalize
()
if
len
(
e
.
Listeners
)
==
0
{
e
.
Listeners
=
nil
}
for
_
,
listener
:=
range
e
.
Listeners
{
listener
.
Canonicalize
()
}
}
func
(
e
*
ConsulIngressConfigEntry
)
Copy
()
*
ConsulIngressConfigEntry
{
if
e
==
nil
{
return
nil
}
var
listeners
[]
*
ConsulIngressListener
=
nil
if
n
:=
len
(
e
.
Listeners
);
n
>
0
{
listeners
=
make
([]
*
ConsulIngressListener
,
n
)
for
i
:=
0
;
i
<
n
;
i
++
{
listeners
[
i
]
=
e
.
Listeners
[
i
]
.
Copy
()
}
}
return
&
ConsulIngressConfigEntry
{
TLS
:
e
.
TLS
.
Copy
(),
Listeners
:
listeners
,
}
}
// ConsulTerminatingConfigEntry is not yet supported.
// type ConsulTerminatingConfigEntry struct {
// }
// ConsulMeshConfigEntry is not yet supported.
// type ConsulMeshConfigEntry struct {
// }
This diff is collapsed.
Click to expand it.
api/services_test.go
+
158
-
0
View file @
763e315e
...
...
@@ -261,3 +261,161 @@ func TestService_Connect_SidecarTask_Canonicalize(t *testing.T) {
require
.
Equal
(
t
,
exp
,
st
.
Resources
)
})
}
func
TestService_ConsulGateway_Canonicalize
(
t
*
testing
.
T
)
{
t
.
Parallel
()
t
.
Run
(
"nil"
,
func
(
t
*
testing
.
T
)
{
cg
:=
(
*
ConsulGateway
)(
nil
)
cg
.
Canonicalize
()
require
.
Nil
(
t
,
cg
)
})
t
.
Run
(
"set defaults"
,
func
(
t
*
testing
.
T
)
{
cg
:=
&
ConsulGateway
{
Proxy
:
&
ConsulGatewayProxy
{
ConnectTimeout
:
nil
,
EnvoyGatewayBindTaggedAddresses
:
true
,
EnvoyGatewayBindAddresses
:
make
(
map
[
string
]
*
ConsulGatewayBindAddress
,
0
),
EnvoyGatewayNoDefaultBind
:
true
,
EnvoyDNSDiscoveryType
:
""
,
Config
:
make
(
map
[
string
]
interface
{},
0
),
},
Ingress
:
&
ConsulIngressConfigEntry
{
TLS
:
&
ConsulGatewayTLSConfig
{
Enabled
:
false
,
},
Listeners
:
make
([]
*
ConsulIngressListener
,
0
),
},
}
cg
.
Canonicalize
()
require
.
Equal
(
t
,
timeToPtr
(
5
*
time
.
Second
),
cg
.
Proxy
.
ConnectTimeout
)
require
.
Equal
(
t
,
"LOGICAL_DNS"
,
cg
.
Proxy
.
EnvoyDNSDiscoveryType
)
require
.
Nil
(
t
,
cg
.
Proxy
.
EnvoyGatewayBindAddresses
)
require
.
Nil
(
t
,
cg
.
Proxy
.
Config
)
require
.
Nil
(
t
,
cg
.
Ingress
.
Listeners
)
})
}
func
TestService_ConsulGateway_Copy
(
t
*
testing
.
T
)
{
t
.
Parallel
()
t
.
Run
(
"nil"
,
func
(
t
*
testing
.
T
)
{
result
:=
(
*
ConsulGateway
)(
nil
)
.
Copy
()
require
.
Nil
(
t
,
result
)
})
gateway
:=
&
ConsulGateway
{
Proxy
:
&
ConsulGatewayProxy
{
ConnectTimeout
:
timeToPtr
(
3
*
time
.
Second
),
EnvoyGatewayBindTaggedAddresses
:
true
,
EnvoyGatewayBindAddresses
:
map
[
string
]
*
ConsulGatewayBindAddress
{
"listener1"
:
{
Address
:
"10.0.0.1"
,
Port
:
2000
},
"listener2"
:
{
Address
:
"10.0.0.1"
,
Port
:
2001
},
},
EnvoyGatewayNoDefaultBind
:
true
,
EnvoyDNSDiscoveryType
:
"BAD_TYPE"
,
Config
:
map
[
string
]
interface
{}{
"foo"
:
"bar"
,
"baz"
:
3
,
},
},
Ingress
:
&
ConsulIngressConfigEntry
{
TLS
:
&
ConsulGatewayTLSConfig
{
Enabled
:
true
,
},
Listeners
:
[]
*
ConsulIngressListener
{{
Port
:
3333
,
Protocol
:
"tcp"
,
Services
:
[]
*
ConsulIngressService
{{
Name
:
"service1"
,
Hosts
:
[]
string
{
"127.0.0.1"
,
"127.0.0.1:3333"
,
}},
}},
},
},
}
t
.
Run
(
"complete"
,
func
(
t
*
testing
.
T
)
{
result
:=
gateway
.
Copy
()
require
.
Equal
(
t
,
gateway
,
result
)
})
}
func
TestService_ConsulIngressConfigEntry_Canonicalize
(
t
*
testing
.
T
)
{
t
.
Parallel
()
t
.
Run
(
"nil"
,
func
(
t
*
testing
.
T
)
{
c
:=
(
*
ConsulIngressConfigEntry
)(
nil
)
c
.
Canonicalize
()
require
.
Nil
(
t
,
c
)
})
t
.
Run
(
"empty fields"
,
func
(
t
*
testing
.
T
)
{
c
:=
&
ConsulIngressConfigEntry
{
TLS
:
nil
,
Listeners
:
[]
*
ConsulIngressListener
{},
}
c
.
Canonicalize
()
require
.
Nil
(
t
,
c
.
TLS
)
require
.
Nil
(
t
,
c
.
Listeners
)
})
t
.
Run
(
"complete"
,
func
(
t
*
testing
.
T
)
{
c
:=
&
ConsulIngressConfigEntry
{
TLS
:
&
ConsulGatewayTLSConfig
{
Enabled
:
true
},
Listeners
:
[]
*
ConsulIngressListener
{{
Port
:
9090
,
Protocol
:
"http"
,
Services
:
[]
*
ConsulIngressService
{{
Name
:
"service1"
,
Hosts
:
[]
string
{
"1.1.1.1"
},
}},
}},
}
c
.
Canonicalize
()
require
.
Equal
(
t
,
&
ConsulIngressConfigEntry
{
TLS
:
&
ConsulGatewayTLSConfig
{
Enabled
:
true
},
Listeners
:
[]
*
ConsulIngressListener
{{
Port
:
9090
,
Protocol
:
"http"
,
Services
:
[]
*
ConsulIngressService
{{
Name
:
"service1"
,
Hosts
:
[]
string
{
"1.1.1.1"
},
}},
}},
},
c
)
})
}
func
TestService_ConsulIngressConfigEntry_Copy
(
t
*
testing
.
T
)
{
t
.
Parallel
()
t
.
Run
(
"nil"
,
func
(
t
*
testing
.
T
)
{
result
:=
(
*
ConsulIngressConfigEntry
)(
nil
)
.
Copy
()
require
.
Nil
(
t
,
result
)
})
entry
:=
&
ConsulIngressConfigEntry
{
TLS
:
&
ConsulGatewayTLSConfig
{
Enabled
:
true
,
},
Listeners
:
[]
*
ConsulIngressListener
{{
Port
:
1111
,
Protocol
:
"http"
,
Services
:
[]
*
ConsulIngressService
{{
Name
:
"service1"
,
Hosts
:
[]
string
{
"1.1.1.1"
,
"1.1.1.1:9000"
},
},
{
Name
:
"service2"
,
Hosts
:
[]
string
{
"2.2.2.2"
},
}},
}},
}
t
.
Run
(
"complete"
,
func
(
t
*
testing
.
T
)
{
result
:=
entry
.
Copy
()
require
.
Equal
(
t
,
entry
,
result
)
})
}
This diff is collapsed.
Click to expand it.
api/vendor/github.com/davecgh/go-spew/LICENSE
0 → 100644
+
15
-
0
View file @
763e315e
ISC License
Copyright (c) 2012-2016 Dave Collins <dave@davec.name>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
This diff is collapsed.
Click to expand it.
api/vendor/github.com/davecgh/go-spew/spew/bypass.go
0 → 100644
+
145
-
0
View file @
763e315e
// Copyright (c) 2015-2016 Dave Collins <dave@davec.name>
//
// Permission to use, copy, modify, and distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
// NOTE: Due to the following build constraints, this file will only be compiled
// when the code is not running on Google App Engine, compiled by GopherJS, and
// "-tags safe" is not added to the go build command line. The "disableunsafe"
// tag is deprecated and thus should not be used.
// Go versions prior to 1.4 are disabled because they use a different layout
// for interfaces which make the implementation of unsafeReflectValue more complex.
// +build !js,!appengine,!safe,!disableunsafe,go1.4
package
spew
import
(
"reflect"
"unsafe"
)
const
(
// UnsafeDisabled is a build-time constant which specifies whether or
// not access to the unsafe package is available.
UnsafeDisabled
=
false
// ptrSize is the size of a pointer on the current arch.
ptrSize
=
unsafe
.
Sizeof
((
*
byte
)(
nil
))
)
type
flag
uintptr
var
(
// flagRO indicates whether the value field of a reflect.Value
// is read-only.
flagRO
flag
// flagAddr indicates whether the address of the reflect.Value's
// value may be taken.
flagAddr
flag
)
// flagKindMask holds the bits that make up the kind
// part of the flags field. In all the supported versions,
// it is in the lower 5 bits.
const
flagKindMask
=
flag
(
0x1f
)
// Different versions of Go have used different
// bit layouts for the flags type. This table
// records the known combinations.
var
okFlags
=
[]
struct
{
ro
,
addr
flag
}{{
// From Go 1.4 to 1.5
ro
:
1
<<
5
,
addr
:
1
<<
7
,
},
{
// Up to Go tip.
ro
:
1
<<
5
|
1
<<
6
,
addr
:
1
<<
8
,
}}
var
flagValOffset
=
func
()
uintptr
{
field
,
ok
:=
reflect
.
TypeOf
(
reflect
.
Value
{})
.
FieldByName
(
"flag"
)
if
!
ok
{
panic
(
"reflect.Value has no flag field"
)
}
return
field
.
Offset
}()
// flagField returns a pointer to the flag field of a reflect.Value.
func
flagField
(
v
*
reflect
.
Value
)
*
flag
{
return
(
*
flag
)(
unsafe
.
Pointer
(
uintptr
(
unsafe
.
Pointer
(
v
))
+
flagValOffset
))
}
// unsafeReflectValue converts the passed reflect.Value into a one that bypasses
// the typical safety restrictions preventing access to unaddressable and
// unexported data. It works by digging the raw pointer to the underlying
// value out of the protected value and generating a new unprotected (unsafe)
// reflect.Value to it.
//
// This allows us to check for implementations of the Stringer and error
// interfaces to be used for pretty printing ordinarily unaddressable and
// inaccessible values such as unexported struct fields.
func
unsafeReflectValue
(
v
reflect
.
Value
)
reflect
.
Value
{
if
!
v
.
IsValid
()
||
(
v
.
CanInterface
()
&&
v
.
CanAddr
())
{
return
v
}
flagFieldPtr
:=
flagField
(
&
v
)
*
flagFieldPtr
&^=
flagRO
*
flagFieldPtr
|=
flagAddr
return
v
}
// Sanity checks against future reflect package changes
// to the type or semantics of the Value.flag field.
func
init
()
{
field
,
ok
:=
reflect
.
TypeOf
(
reflect
.
Value
{})
.
FieldByName
(
"flag"
)
if
!
ok
{
panic
(
"reflect.Value has no flag field"
)
}
if
field
.
Type
.
Kind
()
!=
reflect
.
TypeOf
(
flag
(
0
))
.
Kind
()
{
panic
(
"reflect.Value flag field has changed kind"
)
}
type
t0
int
var
t
struct
{
A
t0
// t0 will have flagEmbedRO set.
t0
// a will have flagStickyRO set
a
t0
}
vA
:=
reflect
.
ValueOf
(
t
)
.
FieldByName
(
"A"
)
va
:=
reflect
.
ValueOf
(
t
)
.
FieldByName
(
"a"
)
vt0
:=
reflect
.
ValueOf
(
t
)
.
FieldByName
(
"t0"
)
// Infer flagRO from the difference between the flags
// for the (otherwise identical) fields in t.
flagPublic
:=
*
flagField
(
&
vA
)
flagWithRO
:=
*
flagField
(
&
va
)
|
*
flagField
(
&
vt0
)
flagRO
=
flagPublic
^
flagWithRO
// Infer flagAddr from the difference between a value
// taken from a pointer and not.
vPtrA
:=
reflect
.
ValueOf
(
&
t
)
.
Elem
()
.
FieldByName
(
"A"
)
flagNoPtr
:=
*
flagField
(
&
vA
)
flagPtr
:=
*
flagField
(
&
vPtrA
)
flagAddr
=
flagNoPtr
^
flagPtr
// Check that the inferred flags tally with one of the known versions.
for
_
,
f
:=
range
okFlags
{
if
flagRO
==
f
.
ro
&&
flagAddr
==
f
.
addr
{
return
}
}
panic
(
"reflect.Value read-only flag has changed semantics"
)
}
This diff is collapsed.
Click to expand it.
api/vendor/github.com/davecgh/go-spew/spew/bypasssafe.go
0 → 100644
+
38
-
0
View file @
763e315e
// Copyright (c) 2015-2016 Dave Collins <dave@davec.name>
//
// Permission to use, copy, modify, and distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
// NOTE: Due to the following build constraints, this file will only be compiled
// when the code is running on Google App Engine, compiled by GopherJS, or
// "-tags safe" is added to the go build command line. The "disableunsafe"
// tag is deprecated and thus should not be used.
// +build js appengine safe disableunsafe !go1.4
package
spew
import
"reflect"
const
(
// UnsafeDisabled is a build-time constant which specifies whether or
// not access to the unsafe package is available.
UnsafeDisabled
=
true
)
// unsafeReflectValue typically converts the passed reflect.Value into a one
// that bypasses the typical safety restrictions preventing access to
// unaddressable and unexported data. However, doing this relies on access to
// the unsafe package. This is a stub version which simply returns the passed
// reflect.Value when the unsafe package is not available.
func
unsafeReflectValue
(
v
reflect
.
Value
)
reflect
.
Value
{
return
v
}
This diff is collapsed.
Click to expand it.
api/vendor/github.com/davecgh/go-spew/spew/common.go
0 → 100644
+
341
-
0
View file @
763e315e
/*
* Copyright (c) 2013-2016 Dave Collins <dave@davec.name>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
package
spew
import
(
"bytes"
"fmt"
"io"
"reflect"
"sort"
"strconv"
)
// Some constants in the form of bytes to avoid string overhead. This mirrors
// the technique used in the fmt package.
var
(
panicBytes
=
[]
byte
(
"(PANIC="
)
plusBytes
=
[]
byte
(
"+"
)
iBytes
=
[]
byte
(
"i"
)
trueBytes
=
[]
byte
(
"true"
)
falseBytes
=
[]
byte
(
"false"
)
interfaceBytes
=
[]
byte
(
"(interface {})"
)
commaNewlineBytes
=
[]
byte
(
",
\n
"
)
newlineBytes
=
[]
byte
(
"
\n
"
)
openBraceBytes
=
[]
byte
(
"{"
)
openBraceNewlineBytes
=
[]
byte
(
"{
\n
"
)
closeBraceBytes
=
[]
byte
(
"}"
)
asteriskBytes
=
[]
byte
(
"*"
)
colonBytes
=
[]
byte
(
":"
)
colonSpaceBytes
=
[]
byte
(
": "
)
openParenBytes
=
[]
byte
(
"("
)
closeParenBytes
=
[]
byte
(
")"
)
spaceBytes
=
[]
byte
(
" "
)
pointerChainBytes
=
[]
byte
(
"->"
)
nilAngleBytes
=
[]
byte
(
"<nil>"
)
maxNewlineBytes
=
[]
byte
(
"<max depth reached>
\n
"
)
maxShortBytes
=
[]
byte
(
"<max>"
)
circularBytes
=
[]
byte
(
"<already shown>"
)
circularShortBytes
=
[]
byte
(
"<shown>"
)
invalidAngleBytes
=
[]
byte
(
"<invalid>"
)
openBracketBytes
=
[]
byte
(
"["
)
closeBracketBytes
=
[]
byte
(
"]"
)
percentBytes
=
[]
byte
(
"%"
)
precisionBytes
=
[]
byte
(
"."
)
openAngleBytes
=
[]
byte
(
"<"
)
closeAngleBytes
=
[]
byte
(
">"
)
openMapBytes
=
[]
byte
(
"map["
)
closeMapBytes
=
[]
byte
(
"]"
)
lenEqualsBytes
=
[]
byte
(
"len="
)
capEqualsBytes
=
[]
byte
(
"cap="
)
)
// hexDigits is used to map a decimal value to a hex digit.
var
hexDigits
=
"0123456789abcdef"
// catchPanic handles any panics that might occur during the handleMethods
// calls.
func
catchPanic
(
w
io
.
Writer
,
v
reflect
.
Value
)
{
if
err
:=
recover
();
err
!=
nil
{
w
.
Write
(
panicBytes
)
fmt
.
Fprintf
(
w
,
"%v"
,
err
)
w
.
Write
(
closeParenBytes
)
}
}
// handleMethods attempts to call the Error and String methods on the underlying
// type the passed reflect.Value represents and outputes the result to Writer w.
//
// It handles panics in any called methods by catching and displaying the error
// as the formatted value.
func
handleMethods
(
cs
*
ConfigState
,
w
io
.
Writer
,
v
reflect
.
Value
)
(
handled
bool
)
{
// We need an interface to check if the type implements the error or
// Stringer interface. However, the reflect package won't give us an
// interface on certain things like unexported struct fields in order
// to enforce visibility rules. We use unsafe, when it's available,
// to bypass these restrictions since this package does not mutate the
// values.
if
!
v
.
CanInterface
()
{
if
UnsafeDisabled
{
return
false
}
v
=
unsafeReflectValue
(
v
)
}
// Choose whether or not to do error and Stringer interface lookups against
// the base type or a pointer to the base type depending on settings.
// Technically calling one of these methods with a pointer receiver can
// mutate the value, however, types which choose to satisify an error or
// Stringer interface with a pointer receiver should not be mutating their
// state inside these interface methods.
if
!
cs
.
DisablePointerMethods
&&
!
UnsafeDisabled
&&
!
v
.
CanAddr
()
{
v
=
unsafeReflectValue
(
v
)
}
if
v
.
CanAddr
()
{
v
=
v
.
Addr
()
}
// Is it an error or Stringer?
switch
iface
:=
v
.
Interface
()
.
(
type
)
{
case
error
:
defer
catchPanic
(
w
,
v
)
if
cs
.
ContinueOnMethod
{
w
.
Write
(
openParenBytes
)
w
.
Write
([]
byte
(
iface
.
Error
()))
w
.
Write
(
closeParenBytes
)
w
.
Write
(
spaceBytes
)
return
false
}
w
.
Write
([]
byte
(
iface
.
Error
()))
return
true
case
fmt
.
Stringer
:
defer
catchPanic
(
w
,
v
)
if
cs
.
ContinueOnMethod
{
w
.
Write
(
openParenBytes
)
w
.
Write
([]
byte
(
iface
.
String
()))
w
.
Write
(
closeParenBytes
)
w
.
Write
(
spaceBytes
)
return
false
}
w
.
Write
([]
byte
(
iface
.
String
()))
return
true
}
return
false
}
// printBool outputs a boolean value as true or false to Writer w.
func
printBool
(
w
io
.
Writer
,
val
bool
)
{
if
val
{
w
.
Write
(
trueBytes
)
}
else
{
w
.
Write
(
falseBytes
)
}
}
// printInt outputs a signed integer value to Writer w.
func
printInt
(
w
io
.
Writer
,
val
int64
,
base
int
)
{
w
.
Write
([]
byte
(
strconv
.
FormatInt
(
val
,
base
)))
}
// printUint outputs an unsigned integer value to Writer w.
func
printUint
(
w
io
.
Writer
,
val
uint64
,
base
int
)
{
w
.
Write
([]
byte
(
strconv
.
FormatUint
(
val
,
base
)))
}
// printFloat outputs a floating point value using the specified precision,
// which is expected to be 32 or 64bit, to Writer w.
func
printFloat
(
w
io
.
Writer
,
val
float64
,
precision
int
)
{
w
.
Write
([]
byte
(
strconv
.
FormatFloat
(
val
,
'g'
,
-
1
,
precision
)))
}
// printComplex outputs a complex value using the specified float precision
// for the real and imaginary parts to Writer w.
func
printComplex
(
w
io
.
Writer
,
c
complex128
,
floatPrecision
int
)
{
r
:=
real
(
c
)
w
.
Write
(
openParenBytes
)
w
.
Write
([]
byte
(
strconv
.
FormatFloat
(
r
,
'g'
,
-
1
,
floatPrecision
)))
i
:=
imag
(
c
)
if
i
>=
0
{
w
.
Write
(
plusBytes
)
}
w
.
Write
([]
byte
(
strconv
.
FormatFloat
(
i
,
'g'
,
-
1
,
floatPrecision
)))
w
.
Write
(
iBytes
)
w
.
Write
(
closeParenBytes
)
}
// printHexPtr outputs a uintptr formatted as hexadecimal with a leading '0x'
// prefix to Writer w.
func
printHexPtr
(
w
io
.
Writer
,
p
uintptr
)
{
// Null pointer.
num
:=
uint64
(
p
)
if
num
==
0
{
w
.
Write
(
nilAngleBytes
)
return
}
// Max uint64 is 16 bytes in hex + 2 bytes for '0x' prefix
buf
:=
make
([]
byte
,
18
)
// It's simpler to construct the hex string right to left.
base
:=
uint64
(
16
)
i
:=
len
(
buf
)
-
1
for
num
>=
base
{
buf
[
i
]
=
hexDigits
[
num
%
base
]
num
/=
base
i
--
}
buf
[
i
]
=
hexDigits
[
num
]
// Add '0x' prefix.
i
--
buf
[
i
]
=
'x'
i
--
buf
[
i
]
=
'0'
// Strip unused leading bytes.
buf
=
buf
[
i
:
]
w
.
Write
(
buf
)
}
// valuesSorter implements sort.Interface to allow a slice of reflect.Value
// elements to be sorted.
type
valuesSorter
struct
{
values
[]
reflect
.
Value
strings
[]
string
// either nil or same len and values
cs
*
ConfigState
}
// newValuesSorter initializes a valuesSorter instance, which holds a set of
// surrogate keys on which the data should be sorted. It uses flags in
// ConfigState to decide if and how to populate those surrogate keys.
func
newValuesSorter
(
values
[]
reflect
.
Value
,
cs
*
ConfigState
)
sort
.
Interface
{
vs
:=
&
valuesSorter
{
values
:
values
,
cs
:
cs
}
if
canSortSimply
(
vs
.
values
[
0
]
.
Kind
())
{
return
vs
}
if
!
cs
.
DisableMethods
{
vs
.
strings
=
make
([]
string
,
len
(
values
))
for
i
:=
range
vs
.
values
{
b
:=
bytes
.
Buffer
{}
if
!
handleMethods
(
cs
,
&
b
,
vs
.
values
[
i
])
{
vs
.
strings
=
nil
break
}
vs
.
strings
[
i
]
=
b
.
String
()
}
}
if
vs
.
strings
==
nil
&&
cs
.
SpewKeys
{
vs
.
strings
=
make
([]
string
,
len
(
values
))
for
i
:=
range
vs
.
values
{
vs
.
strings
[
i
]
=
Sprintf
(
"%#v"
,
vs
.
values
[
i
]
.
Interface
())
}
}
return
vs
}
// canSortSimply tests whether a reflect.Kind is a primitive that can be sorted
// directly, or whether it should be considered for sorting by surrogate keys
// (if the ConfigState allows it).
func
canSortSimply
(
kind
reflect
.
Kind
)
bool
{
// This switch parallels valueSortLess, except for the default case.
switch
kind
{
case
reflect
.
Bool
:
return
true
case
reflect
.
Int8
,
reflect
.
Int16
,
reflect
.
Int32
,
reflect
.
Int64
,
reflect
.
Int
:
return
true
case
reflect
.
Uint8
,
reflect
.
Uint16
,
reflect
.
Uint32
,
reflect
.
Uint64
,
reflect
.
Uint
:
return
true
case
reflect
.
Float32
,
reflect
.
Float64
:
return
true
case
reflect
.
String
:
return
true
case
reflect
.
Uintptr
:
return
true
case
reflect
.
Array
:
return
true
}
return
false
}
// Len returns the number of values in the slice. It is part of the
// sort.Interface implementation.
func
(
s
*
valuesSorter
)
Len
()
int
{
return
len
(
s
.
values
)
}
// Swap swaps the values at the passed indices. It is part of the
// sort.Interface implementation.
func
(
s
*
valuesSorter
)
Swap
(
i
,
j
int
)
{
s
.
values
[
i
],
s
.
values
[
j
]
=
s
.
values
[
j
],
s
.
values
[
i
]
if
s
.
strings
!=
nil
{
s
.
strings
[
i
],
s
.
strings
[
j
]
=
s
.
strings
[
j
],
s
.
strings
[
i
]
}
}
// valueSortLess returns whether the first value should sort before the second
// value. It is used by valueSorter.Less as part of the sort.Interface
// implementation.
func
valueSortLess
(
a
,
b
reflect
.
Value
)
bool
{
switch
a
.
Kind
()
{
case
reflect
.
Bool
:
return
!
a
.
Bool
()
&&
b
.
Bool
()
case
reflect
.
Int8
,
reflect
.
Int16
,
reflect
.
Int32
,
reflect
.
Int64
,
reflect
.
Int
:
return
a
.
Int
()
<
b
.
Int
()
case
reflect
.
Uint8
,
reflect
.
Uint16
,
reflect
.
Uint32
,
reflect
.
Uint64
,
reflect
.
Uint
:
return
a
.
Uint
()
<
b
.
Uint
()
case
reflect
.
Float32
,
reflect
.
Float64
:
return
a
.
Float
()
<
b
.
Float
()
case
reflect
.
String
:
return
a
.
String
()
<
b
.
String
()
case
reflect
.
Uintptr
:
return
a
.
Uint
()
<
b
.
Uint
()
case
reflect
.
Array
:
// Compare the contents of both arrays.
l
:=
a
.
Len
()
for
i
:=
0
;
i
<
l
;
i
++
{
av
:=
a
.
Index
(
i
)
bv
:=
b
.
Index
(
i
)
if
av
.
Interface
()
==
bv
.
Interface
()
{
continue
}
return
valueSortLess
(
av
,
bv
)
}
}
return
a
.
String
()
<
b
.
String
()
}
// Less returns whether the value at index i should sort before the
// value at index j. It is part of the sort.Interface implementation.
func
(
s
*
valuesSorter
)
Less
(
i
,
j
int
)
bool
{
if
s
.
strings
==
nil
{
return
valueSortLess
(
s
.
values
[
i
],
s
.
values
[
j
])
}
return
s
.
strings
[
i
]
<
s
.
strings
[
j
]
}
// sortValues is a sort function that handles both native types and any type that
// can be converted to error or Stringer. Other inputs are sorted according to
// their Value.String() value to ensure display stability.
func
sortValues
(
values
[]
reflect
.
Value
,
cs
*
ConfigState
)
{
if
len
(
values
)
==
0
{
return
}
sort
.
Sort
(
newValuesSorter
(
values
,
cs
))
}
This diff is collapsed.
Click to expand it.
api/vendor/github.com/davecgh/go-spew/spew/config.go
0 → 100644
+
306
-
0
View file @
763e315e
/*
* Copyright (c) 2013-2016 Dave Collins <dave@davec.name>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
package
spew
import
(
"bytes"
"fmt"
"io"
"os"
)
// ConfigState houses the configuration options used by spew to format and
// display values. There is a global instance, Config, that is used to control
// all top-level Formatter and Dump functionality. Each ConfigState instance
// provides methods equivalent to the top-level functions.
//
// The zero value for ConfigState provides no indentation. You would typically
// want to set it to a space or a tab.
//
// Alternatively, you can use NewDefaultConfig to get a ConfigState instance
// with default settings. See the documentation of NewDefaultConfig for default
// values.
type
ConfigState
struct
{
// Indent specifies the string to use for each indentation level. The
// global config instance that all top-level functions use set this to a
// single space by default. If you would like more indentation, you might
// set this to a tab with "\t" or perhaps two spaces with " ".
Indent
string
// MaxDepth controls the maximum number of levels to descend into nested
// data structures. The default, 0, means there is no limit.
//
// NOTE: Circular data structures are properly detected, so it is not
// necessary to set this value unless you specifically want to limit deeply
// nested data structures.
MaxDepth
int
// DisableMethods specifies whether or not error and Stringer interfaces are
// invoked for types that implement them.
DisableMethods
bool
// DisablePointerMethods specifies whether or not to check for and invoke
// error and Stringer interfaces on types which only accept a pointer
// receiver when the current type is not a pointer.
//
// NOTE: This might be an unsafe action since calling one of these methods
// with a pointer receiver could technically mutate the value, however,
// in practice, types which choose to satisify an error or Stringer
// interface with a pointer receiver should not be mutating their state
// inside these interface methods. As a result, this option relies on
// access to the unsafe package, so it will not have any effect when
// running in environments without access to the unsafe package such as
// Google App Engine or with the "safe" build tag specified.
DisablePointerMethods
bool
// DisablePointerAddresses specifies whether to disable the printing of
// pointer addresses. This is useful when diffing data structures in tests.
DisablePointerAddresses
bool
// DisableCapacities specifies whether to disable the printing of capacities
// for arrays, slices, maps and channels. This is useful when diffing
// data structures in tests.
DisableCapacities
bool
// ContinueOnMethod specifies whether or not recursion should continue once
// a custom error or Stringer interface is invoked. The default, false,
// means it will print the results of invoking the custom error or Stringer
// interface and return immediately instead of continuing to recurse into
// the internals of the data type.
//
// NOTE: This flag does not have any effect if method invocation is disabled
// via the DisableMethods or DisablePointerMethods options.
ContinueOnMethod
bool
// SortKeys specifies map keys should be sorted before being printed. Use
// this to have a more deterministic, diffable output. Note that only
// native types (bool, int, uint, floats, uintptr and string) and types
// that support the error or Stringer interfaces (if methods are
// enabled) are supported, with other types sorted according to the
// reflect.Value.String() output which guarantees display stability.
SortKeys
bool
// SpewKeys specifies that, as a last resort attempt, map keys should
// be spewed to strings and sorted by those strings. This is only
// considered if SortKeys is true.
SpewKeys
bool
}
// Config is the active configuration of the top-level functions.
// The configuration can be changed by modifying the contents of spew.Config.
var
Config
=
ConfigState
{
Indent
:
" "
}
// Errorf is a wrapper for fmt.Errorf that treats each argument as if it were
// passed with a Formatter interface returned by c.NewFormatter. It returns
// the formatted string as a value that satisfies error. See NewFormatter
// for formatting details.
//
// This function is shorthand for the following syntax:
//
// fmt.Errorf(format, c.NewFormatter(a), c.NewFormatter(b))
func
(
c
*
ConfigState
)
Errorf
(
format
string
,
a
...
interface
{})
(
err
error
)
{
return
fmt
.
Errorf
(
format
,
c
.
convertArgs
(
a
)
...
)
}
// Fprint is a wrapper for fmt.Fprint that treats each argument as if it were
// passed with a Formatter interface returned by c.NewFormatter. It returns
// the number of bytes written and any write error encountered. See
// NewFormatter for formatting details.
//
// This function is shorthand for the following syntax:
//
// fmt.Fprint(w, c.NewFormatter(a), c.NewFormatter(b))
func
(
c
*
ConfigState
)
Fprint
(
w
io
.
Writer
,
a
...
interface
{})
(
n
int
,
err
error
)
{
return
fmt
.
Fprint
(
w
,
c
.
convertArgs
(
a
)
...
)
}
// Fprintf is a wrapper for fmt.Fprintf that treats each argument as if it were
// passed with a Formatter interface returned by c.NewFormatter. It returns
// the number of bytes written and any write error encountered. See
// NewFormatter for formatting details.
//
// This function is shorthand for the following syntax:
//
// fmt.Fprintf(w, format, c.NewFormatter(a), c.NewFormatter(b))
func
(
c
*
ConfigState
)
Fprintf
(
w
io
.
Writer
,
format
string
,
a
...
interface
{})
(
n
int
,
err
error
)
{
return
fmt
.
Fprintf
(
w
,
format
,
c
.
convertArgs
(
a
)
...
)
}
// Fprintln is a wrapper for fmt.Fprintln that treats each argument as if it
// passed with a Formatter interface returned by c.NewFormatter. See
// NewFormatter for formatting details.
//
// This function is shorthand for the following syntax:
//
// fmt.Fprintln(w, c.NewFormatter(a), c.NewFormatter(b))
func
(
c
*
ConfigState
)
Fprintln
(
w
io
.
Writer
,
a
...
interface
{})
(
n
int
,
err
error
)
{
return
fmt
.
Fprintln
(
w
,
c
.
convertArgs
(
a
)
...
)
}
// Print is a wrapper for fmt.Print that treats each argument as if it were
// passed with a Formatter interface returned by c.NewFormatter. It returns
// the number of bytes written and any write error encountered. See
// NewFormatter for formatting details.
//
// This function is shorthand for the following syntax:
//
// fmt.Print(c.NewFormatter(a), c.NewFormatter(b))
func
(
c
*
ConfigState
)
Print
(
a
...
interface
{})
(
n
int
,
err
error
)
{
return
fmt
.
Print
(
c
.
convertArgs
(
a
)
...
)
}
// Printf is a wrapper for fmt.Printf that treats each argument as if it were
// passed with a Formatter interface returned by c.NewFormatter. It returns
// the number of bytes written and any write error encountered. See
// NewFormatter for formatting details.
//
// This function is shorthand for the following syntax:
//
// fmt.Printf(format, c.NewFormatter(a), c.NewFormatter(b))
func
(
c
*
ConfigState
)
Printf
(
format
string
,
a
...
interface
{})
(
n
int
,
err
error
)
{
return
fmt
.
Printf
(
format
,
c
.
convertArgs
(
a
)
...
)
}
// Println is a wrapper for fmt.Println that treats each argument as if it were
// passed with a Formatter interface returned by c.NewFormatter. It returns
// the number of bytes written and any write error encountered. See
// NewFormatter for formatting details.
//
// This function is shorthand for the following syntax:
//
// fmt.Println(c.NewFormatter(a), c.NewFormatter(b))
func
(
c
*
ConfigState
)
Println
(
a
...
interface
{})
(
n
int
,
err
error
)
{
return
fmt
.
Println
(
c
.
convertArgs
(
a
)
...
)
}
// Sprint is a wrapper for fmt.Sprint that treats each argument as if it were
// passed with a Formatter interface returned by c.NewFormatter. It returns
// the resulting string. See NewFormatter for formatting details.
//
// This function is shorthand for the following syntax:
//
// fmt.Sprint(c.NewFormatter(a), c.NewFormatter(b))
func
(
c
*
ConfigState
)
Sprint
(
a
...
interface
{})
string
{
return
fmt
.
Sprint
(
c
.
convertArgs
(
a
)
...
)
}
// Sprintf is a wrapper for fmt.Sprintf that treats each argument as if it were
// passed with a Formatter interface returned by c.NewFormatter. It returns
// the resulting string. See NewFormatter for formatting details.
//
// This function is shorthand for the following syntax:
//
// fmt.Sprintf(format, c.NewFormatter(a), c.NewFormatter(b))
func
(
c
*
ConfigState
)
Sprintf
(
format
string
,
a
...
interface
{})
string
{
return
fmt
.
Sprintf
(
format
,
c
.
convertArgs
(
a
)
...
)
}
// Sprintln is a wrapper for fmt.Sprintln that treats each argument as if it
// were passed with a Formatter interface returned by c.NewFormatter. It
// returns the resulting string. See NewFormatter for formatting details.
//
// This function is shorthand for the following syntax:
//
// fmt.Sprintln(c.NewFormatter(a), c.NewFormatter(b))
func
(
c
*
ConfigState
)
Sprintln
(
a
...
interface
{})
string
{
return
fmt
.
Sprintln
(
c
.
convertArgs
(
a
)
...
)
}
/*
NewFormatter returns a custom formatter that satisfies the fmt.Formatter
interface. As a result, it integrates cleanly with standard fmt package
printing functions. The formatter is useful for inline printing of smaller data
types similar to the standard %v format specifier.
The custom formatter only responds to the %v (most compact), %+v (adds pointer
addresses), %#v (adds types), and %#+v (adds types and pointer addresses) verb
combinations. Any other verbs such as %x and %q will be sent to the the
standard fmt package for formatting. In addition, the custom formatter ignores
the width and precision arguments (however they will still work on the format
specifiers not handled by the custom formatter).
Typically this function shouldn't be called directly. It is much easier to make
use of the custom formatter by calling one of the convenience functions such as
c.Printf, c.Println, or c.Printf.
*/
func
(
c
*
ConfigState
)
NewFormatter
(
v
interface
{})
fmt
.
Formatter
{
return
newFormatter
(
c
,
v
)
}
// Fdump formats and displays the passed arguments to io.Writer w. It formats
// exactly the same as Dump.
func
(
c
*
ConfigState
)
Fdump
(
w
io
.
Writer
,
a
...
interface
{})
{
fdump
(
c
,
w
,
a
...
)
}
/*
Dump displays the passed parameters to standard out with newlines, customizable
indentation, and additional debug information such as complete types and all
pointer addresses used to indirect to the final value. It provides the
following features over the built-in printing facilities provided by the fmt
package:
* Pointers are dereferenced and followed
* Circular data structures are detected and handled properly
* Custom Stringer/error interfaces are optionally invoked, including
on unexported types
* Custom types which only implement the Stringer/error interfaces via
a pointer receiver are optionally invoked when passing non-pointer
variables
* Byte arrays and slices are dumped like the hexdump -C command which
includes offsets, byte values in hex, and ASCII output
The configuration options are controlled by modifying the public members
of c. See ConfigState for options documentation.
See Fdump if you would prefer dumping to an arbitrary io.Writer or Sdump to
get the formatted result as a string.
*/
func
(
c
*
ConfigState
)
Dump
(
a
...
interface
{})
{
fdump
(
c
,
os
.
Stdout
,
a
...
)
}
// Sdump returns a string with the passed arguments formatted exactly the same
// as Dump.
func
(
c
*
ConfigState
)
Sdump
(
a
...
interface
{})
string
{
var
buf
bytes
.
Buffer
fdump
(
c
,
&
buf
,
a
...
)
return
buf
.
String
()
}
// convertArgs accepts a slice of arguments and returns a slice of the same
// length with each argument converted to a spew Formatter interface using
// the ConfigState associated with s.
func
(
c
*
ConfigState
)
convertArgs
(
args
[]
interface
{})
(
formatters
[]
interface
{})
{
formatters
=
make
([]
interface
{},
len
(
args
))
for
index
,
arg
:=
range
args
{
formatters
[
index
]
=
newFormatter
(
c
,
arg
)
}
return
formatters
}
// NewDefaultConfig returns a ConfigState with the following default settings.
//
// Indent: " "
// MaxDepth: 0
// DisableMethods: false
// DisablePointerMethods: false
// ContinueOnMethod: false
// SortKeys: false
func
NewDefaultConfig
()
*
ConfigState
{
return
&
ConfigState
{
Indent
:
" "
}
}
This diff is collapsed.
Click to expand it.
api/vendor/github.com/davecgh/go-spew/spew/doc.go
0 → 100644
+
211
-
0
View file @
763e315e
/*
* Copyright (c) 2013-2016 Dave Collins <dave@davec.name>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*
Package spew implements a deep pretty printer for Go data structures to aid in
debugging.
A quick overview of the additional features spew provides over the built-in
printing facilities for Go data types are as follows:
* Pointers are dereferenced and followed
* Circular data structures are detected and handled properly
* Custom Stringer/error interfaces are optionally invoked, including
on unexported types
* Custom types which only implement the Stringer/error interfaces via
a pointer receiver are optionally invoked when passing non-pointer
variables
* Byte arrays and slices are dumped like the hexdump -C command which
includes offsets, byte values in hex, and ASCII output (only when using
Dump style)
There are two different approaches spew allows for dumping Go data structures:
* Dump style which prints with newlines, customizable indentation,
and additional debug information such as types and all pointer addresses
used to indirect to the final value
* A custom Formatter interface that integrates cleanly with the standard fmt
package and replaces %v, %+v, %#v, and %#+v to provide inline printing
similar to the default %v while providing the additional functionality
outlined above and passing unsupported format verbs such as %x and %q
along to fmt
Quick Start
This section demonstrates how to quickly get started with spew. See the
sections below for further details on formatting and configuration options.
To dump a variable with full newlines, indentation, type, and pointer
information use Dump, Fdump, or Sdump:
spew.Dump(myVar1, myVar2, ...)
spew.Fdump(someWriter, myVar1, myVar2, ...)
str := spew.Sdump(myVar1, myVar2, ...)
Alternatively, if you would prefer to use format strings with a compacted inline
printing style, use the convenience wrappers Printf, Fprintf, etc with
%v (most compact), %+v (adds pointer addresses), %#v (adds types), or
%#+v (adds types and pointer addresses):
spew.Printf("myVar1: %v -- myVar2: %+v", myVar1, myVar2)
spew.Printf("myVar3: %#v -- myVar4: %#+v", myVar3, myVar4)
spew.Fprintf(someWriter, "myVar1: %v -- myVar2: %+v", myVar1, myVar2)
spew.Fprintf(someWriter, "myVar3: %#v -- myVar4: %#+v", myVar3, myVar4)
Configuration Options
Configuration of spew is handled by fields in the ConfigState type. For
convenience, all of the top-level functions use a global state available
via the spew.Config global.
It is also possible to create a ConfigState instance that provides methods
equivalent to the top-level functions. This allows concurrent configuration
options. See the ConfigState documentation for more details.
The following configuration options are available:
* Indent
String to use for each indentation level for Dump functions.
It is a single space by default. A popular alternative is "\t".
* MaxDepth
Maximum number of levels to descend into nested data structures.
There is no limit by default.
* DisableMethods
Disables invocation of error and Stringer interface methods.
Method invocation is enabled by default.
* DisablePointerMethods
Disables invocation of error and Stringer interface methods on types
which only accept pointer receivers from non-pointer variables.
Pointer method invocation is enabled by default.
* DisablePointerAddresses
DisablePointerAddresses specifies whether to disable the printing of
pointer addresses. This is useful when diffing data structures in tests.
* DisableCapacities
DisableCapacities specifies whether to disable the printing of
capacities for arrays, slices, maps and channels. This is useful when
diffing data structures in tests.
* ContinueOnMethod
Enables recursion into types after invoking error and Stringer interface
methods. Recursion after method invocation is disabled by default.
* SortKeys
Specifies map keys should be sorted before being printed. Use
this to have a more deterministic, diffable output. Note that
only native types (bool, int, uint, floats, uintptr and string)
and types which implement error or Stringer interfaces are
supported with other types sorted according to the
reflect.Value.String() output which guarantees display
stability. Natural map order is used by default.
* SpewKeys
Specifies that, as a last resort attempt, map keys should be
spewed to strings and sorted by those strings. This is only
considered if SortKeys is true.
Dump Usage
Simply call spew.Dump with a list of variables you want to dump:
spew.Dump(myVar1, myVar2, ...)
You may also call spew.Fdump if you would prefer to output to an arbitrary
io.Writer. For example, to dump to standard error:
spew.Fdump(os.Stderr, myVar1, myVar2, ...)
A third option is to call spew.Sdump to get the formatted output as a string:
str := spew.Sdump(myVar1, myVar2, ...)
Sample Dump Output
See the Dump example for details on the setup of the types and variables being
shown here.
(main.Foo) {
unexportedField: (*main.Bar)(0xf84002e210)({
flag: (main.Flag) flagTwo,
data: (uintptr) <nil>
}),
ExportedField: (map[interface {}]interface {}) (len=1) {
(string) (len=3) "one": (bool) true
}
}
Byte (and uint8) arrays and slices are displayed uniquely like the hexdump -C
command as shown.
([]uint8) (len=32 cap=32) {
00000000 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 |............... |
00000010 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 |!"#$%&'()*+,-./0|
00000020 31 32 |12|
}
Custom Formatter
Spew provides a custom formatter that implements the fmt.Formatter interface
so that it integrates cleanly with standard fmt package printing functions. The
formatter is useful for inline printing of smaller data types similar to the
standard %v format specifier.
The custom formatter only responds to the %v (most compact), %+v (adds pointer
addresses), %#v (adds types), or %#+v (adds types and pointer addresses) verb
combinations. Any other verbs such as %x and %q will be sent to the the
standard fmt package for formatting. In addition, the custom formatter ignores
the width and precision arguments (however they will still work on the format
specifiers not handled by the custom formatter).
Custom Formatter Usage
The simplest way to make use of the spew custom formatter is to call one of the
convenience functions such as spew.Printf, spew.Println, or spew.Printf. The
functions have syntax you are most likely already familiar with:
spew.Printf("myVar1: %v -- myVar2: %+v", myVar1, myVar2)
spew.Printf("myVar3: %#v -- myVar4: %#+v", myVar3, myVar4)
spew.Println(myVar, myVar2)
spew.Fprintf(os.Stderr, "myVar1: %v -- myVar2: %+v", myVar1, myVar2)
spew.Fprintf(os.Stderr, "myVar3: %#v -- myVar4: %#+v", myVar3, myVar4)
See the Index for the full list convenience functions.
Sample Formatter Output
Double pointer to a uint8:
%v: <**>5
%+v: <**>(0xf8400420d0->0xf8400420c8)5
%#v: (**uint8)5
%#+v: (**uint8)(0xf8400420d0->0xf8400420c8)5
Pointer to circular struct with a uint8 field and a pointer to itself:
%v: <*>{1 <*><shown>}
%+v: <*>(0xf84003e260){ui8:1 c:<*>(0xf84003e260)<shown>}
%#v: (*main.circular){ui8:(uint8)1 c:(*main.circular)<shown>}
%#+v: (*main.circular)(0xf84003e260){ui8:(uint8)1 c:(*main.circular)(0xf84003e260)<shown>}
See the Printf example for details on the setup of variables being shown
here.
Errors
Since it is possible for custom Stringer/error interfaces to panic, spew
detects them and handles them internally by printing the panic information
inline with the output. Since spew is intended to provide deep pretty printing
capabilities on structures, it intentionally does not return any errors.
*/
package
spew
This diff is collapsed.
Click to expand it.
api/vendor/github.com/davecgh/go-spew/spew/dump.go
0 → 100644
+
509
-
0
View file @
763e315e
/*
* Copyright (c) 2013-2016 Dave Collins <dave@davec.name>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
package
spew
import
(
"bytes"
"encoding/hex"
"fmt"
"io"
"os"
"reflect"
"regexp"
"strconv"
"strings"
)
var
(
// uint8Type is a reflect.Type representing a uint8. It is used to
// convert cgo types to uint8 slices for hexdumping.
uint8Type
=
reflect
.
TypeOf
(
uint8
(
0
))
// cCharRE is a regular expression that matches a cgo char.
// It is used to detect character arrays to hexdump them.
cCharRE
=
regexp
.
MustCompile
(
`^.*\._Ctype_char$`
)
// cUnsignedCharRE is a regular expression that matches a cgo unsigned
// char. It is used to detect unsigned character arrays to hexdump
// them.
cUnsignedCharRE
=
regexp
.
MustCompile
(
`^.*\._Ctype_unsignedchar$`
)
// cUint8tCharRE is a regular expression that matches a cgo uint8_t.
// It is used to detect uint8_t arrays to hexdump them.
cUint8tCharRE
=
regexp
.
MustCompile
(
`^.*\._Ctype_uint8_t$`
)
)
// dumpState contains information about the state of a dump operation.
type
dumpState
struct
{
w
io
.
Writer
depth
int
pointers
map
[
uintptr
]
int
ignoreNextType
bool
ignoreNextIndent
bool
cs
*
ConfigState
}
// indent performs indentation according to the depth level and cs.Indent
// option.
func
(
d
*
dumpState
)
indent
()
{
if
d
.
ignoreNextIndent
{
d
.
ignoreNextIndent
=
false
return
}
d
.
w
.
Write
(
bytes
.
Repeat
([]
byte
(
d
.
cs
.
Indent
),
d
.
depth
))
}
// unpackValue returns values inside of non-nil interfaces when possible.
// This is useful for data types like structs, arrays, slices, and maps which
// can contain varying types packed inside an interface.
func
(
d
*
dumpState
)
unpackValue
(
v
reflect
.
Value
)
reflect
.
Value
{
if
v
.
Kind
()
==
reflect
.
Interface
&&
!
v
.
IsNil
()
{
v
=
v
.
Elem
()
}
return
v
}
// dumpPtr handles formatting of pointers by indirecting them as necessary.
func
(
d
*
dumpState
)
dumpPtr
(
v
reflect
.
Value
)
{
// Remove pointers at or below the current depth from map used to detect
// circular refs.
for
k
,
depth
:=
range
d
.
pointers
{
if
depth
>=
d
.
depth
{
delete
(
d
.
pointers
,
k
)
}
}
// Keep list of all dereferenced pointers to show later.
pointerChain
:=
make
([]
uintptr
,
0
)
// Figure out how many levels of indirection there are by dereferencing
// pointers and unpacking interfaces down the chain while detecting circular
// references.
nilFound
:=
false
cycleFound
:=
false
indirects
:=
0
ve
:=
v
for
ve
.
Kind
()
==
reflect
.
Ptr
{
if
ve
.
IsNil
()
{
nilFound
=
true
break
}
indirects
++
addr
:=
ve
.
Pointer
()
pointerChain
=
append
(
pointerChain
,
addr
)
if
pd
,
ok
:=
d
.
pointers
[
addr
];
ok
&&
pd
<
d
.
depth
{
cycleFound
=
true
indirects
--
break
}
d
.
pointers
[
addr
]
=
d
.
depth
ve
=
ve
.
Elem
()
if
ve
.
Kind
()
==
reflect
.
Interface
{
if
ve
.
IsNil
()
{
nilFound
=
true
break
}
ve
=
ve
.
Elem
()
}
}
// Display type information.
d
.
w
.
Write
(
openParenBytes
)
d
.
w
.
Write
(
bytes
.
Repeat
(
asteriskBytes
,
indirects
))
d
.
w
.
Write
([]
byte
(
ve
.
Type
()
.
String
()))
d
.
w
.
Write
(
closeParenBytes
)
// Display pointer information.
if
!
d
.
cs
.
DisablePointerAddresses
&&
len
(
pointerChain
)
>
0
{
d
.
w
.
Write
(
openParenBytes
)
for
i
,
addr
:=
range
pointerChain
{
if
i
>
0
{
d
.
w
.
Write
(
pointerChainBytes
)
}
printHexPtr
(
d
.
w
,
addr
)
}
d
.
w
.
Write
(
closeParenBytes
)
}
// Display dereferenced value.
d
.
w
.
Write
(
openParenBytes
)
switch
{
case
nilFound
:
d
.
w
.
Write
(
nilAngleBytes
)
case
cycleFound
:
d
.
w
.
Write
(
circularBytes
)
default
:
d
.
ignoreNextType
=
true
d
.
dump
(
ve
)
}
d
.
w
.
Write
(
closeParenBytes
)
}
// dumpSlice handles formatting of arrays and slices. Byte (uint8 under
// reflection) arrays and slices are dumped in hexdump -C fashion.
func
(
d
*
dumpState
)
dumpSlice
(
v
reflect
.
Value
)
{
// Determine whether this type should be hex dumped or not. Also,
// for types which should be hexdumped, try to use the underlying data
// first, then fall back to trying to convert them to a uint8 slice.
var
buf
[]
uint8
doConvert
:=
false
doHexDump
:=
false
numEntries
:=
v
.
Len
()
if
numEntries
>
0
{
vt
:=
v
.
Index
(
0
)
.
Type
()
vts
:=
vt
.
String
()
switch
{
// C types that need to be converted.
case
cCharRE
.
MatchString
(
vts
)
:
fallthrough
case
cUnsignedCharRE
.
MatchString
(
vts
)
:
fallthrough
case
cUint8tCharRE
.
MatchString
(
vts
)
:
doConvert
=
true
// Try to use existing uint8 slices and fall back to converting
// and copying if that fails.
case
vt
.
Kind
()
==
reflect
.
Uint8
:
// We need an addressable interface to convert the type
// to a byte slice. However, the reflect package won't
// give us an interface on certain things like
// unexported struct fields in order to enforce
// visibility rules. We use unsafe, when available, to
// bypass these restrictions since this package does not
// mutate the values.
vs
:=
v
if
!
vs
.
CanInterface
()
||
!
vs
.
CanAddr
()
{
vs
=
unsafeReflectValue
(
vs
)
}
if
!
UnsafeDisabled
{
vs
=
vs
.
Slice
(
0
,
numEntries
)
// Use the existing uint8 slice if it can be
// type asserted.
iface
:=
vs
.
Interface
()
if
slice
,
ok
:=
iface
.
([]
uint8
);
ok
{
buf
=
slice
doHexDump
=
true
break
}
}
// The underlying data needs to be converted if it can't
// be type asserted to a uint8 slice.
doConvert
=
true
}
// Copy and convert the underlying type if needed.
if
doConvert
&&
vt
.
ConvertibleTo
(
uint8Type
)
{
// Convert and copy each element into a uint8 byte
// slice.
buf
=
make
([]
uint8
,
numEntries
)
for
i
:=
0
;
i
<
numEntries
;
i
++
{
vv
:=
v
.
Index
(
i
)
buf
[
i
]
=
uint8
(
vv
.
Convert
(
uint8Type
)
.
Uint
())
}
doHexDump
=
true
}
}
// Hexdump the entire slice as needed.
if
doHexDump
{
indent
:=
strings
.
Repeat
(
d
.
cs
.
Indent
,
d
.
depth
)
str
:=
indent
+
hex
.
Dump
(
buf
)
str
=
strings
.
Replace
(
str
,
"
\n
"
,
"
\n
"
+
indent
,
-
1
)
str
=
strings
.
TrimRight
(
str
,
d
.
cs
.
Indent
)
d
.
w
.
Write
([]
byte
(
str
))
return
}
// Recursively call dump for each item.
for
i
:=
0
;
i
<
numEntries
;
i
++
{
d
.
dump
(
d
.
unpackValue
(
v
.
Index
(
i
)))
if
i
<
(
numEntries
-
1
)
{
d
.
w
.
Write
(
commaNewlineBytes
)
}
else
{
d
.
w
.
Write
(
newlineBytes
)
}
}
}
// dump is the main workhorse for dumping a value. It uses the passed reflect
// value to figure out what kind of object we are dealing with and formats it
// appropriately. It is a recursive function, however circular data structures
// are detected and handled properly.
func
(
d
*
dumpState
)
dump
(
v
reflect
.
Value
)
{
// Handle invalid reflect values immediately.
kind
:=
v
.
Kind
()
if
kind
==
reflect
.
Invalid
{
d
.
w
.
Write
(
invalidAngleBytes
)
return
}
// Handle pointers specially.
if
kind
==
reflect
.
Ptr
{
d
.
indent
()
d
.
dumpPtr
(
v
)
return
}
// Print type information unless already handled elsewhere.
if
!
d
.
ignoreNextType
{
d
.
indent
()
d
.
w
.
Write
(
openParenBytes
)
d
.
w
.
Write
([]
byte
(
v
.
Type
()
.
String
()))
d
.
w
.
Write
(
closeParenBytes
)
d
.
w
.
Write
(
spaceBytes
)
}
d
.
ignoreNextType
=
false
// Display length and capacity if the built-in len and cap functions
// work with the value's kind and the len/cap itself is non-zero.
valueLen
,
valueCap
:=
0
,
0
switch
v
.
Kind
()
{
case
reflect
.
Array
,
reflect
.
Slice
,
reflect
.
Chan
:
valueLen
,
valueCap
=
v
.
Len
(),
v
.
Cap
()
case
reflect
.
Map
,
reflect
.
String
:
valueLen
=
v
.
Len
()
}
if
valueLen
!=
0
||
!
d
.
cs
.
DisableCapacities
&&
valueCap
!=
0
{
d
.
w
.
Write
(
openParenBytes
)
if
valueLen
!=
0
{
d
.
w
.
Write
(
lenEqualsBytes
)
printInt
(
d
.
w
,
int64
(
valueLen
),
10
)
}
if
!
d
.
cs
.
DisableCapacities
&&
valueCap
!=
0
{
if
valueLen
!=
0
{
d
.
w
.
Write
(
spaceBytes
)
}
d
.
w
.
Write
(
capEqualsBytes
)
printInt
(
d
.
w
,
int64
(
valueCap
),
10
)
}
d
.
w
.
Write
(
closeParenBytes
)
d
.
w
.
Write
(
spaceBytes
)
}
// Call Stringer/error interfaces if they exist and the handle methods flag
// is enabled
if
!
d
.
cs
.
DisableMethods
{
if
(
kind
!=
reflect
.
Invalid
)
&&
(
kind
!=
reflect
.
Interface
)
{
if
handled
:=
handleMethods
(
d
.
cs
,
d
.
w
,
v
);
handled
{
return
}
}
}
switch
kind
{
case
reflect
.
Invalid
:
// Do nothing. We should never get here since invalid has already
// been handled above.
case
reflect
.
Bool
:
printBool
(
d
.
w
,
v
.
Bool
())
case
reflect
.
Int8
,
reflect
.
Int16
,
reflect
.
Int32
,
reflect
.
Int64
,
reflect
.
Int
:
printInt
(
d
.
w
,
v
.
Int
(),
10
)
case
reflect
.
Uint8
,
reflect
.
Uint16
,
reflect
.
Uint32
,
reflect
.
Uint64
,
reflect
.
Uint
:
printUint
(
d
.
w
,
v
.
Uint
(),
10
)
case
reflect
.
Float32
:
printFloat
(
d
.
w
,
v
.
Float
(),
32
)
case
reflect
.
Float64
:
printFloat
(
d
.
w
,
v
.
Float
(),
64
)
case
reflect
.
Complex64
:
printComplex
(
d
.
w
,
v
.
Complex
(),
32
)
case
reflect
.
Complex128
:
printComplex
(
d
.
w
,
v
.
Complex
(),
64
)
case
reflect
.
Slice
:
if
v
.
IsNil
()
{
d
.
w
.
Write
(
nilAngleBytes
)
break
}
fallthrough
case
reflect
.
Array
:
d
.
w
.
Write
(
openBraceNewlineBytes
)
d
.
depth
++
if
(
d
.
cs
.
MaxDepth
!=
0
)
&&
(
d
.
depth
>
d
.
cs
.
MaxDepth
)
{
d
.
indent
()
d
.
w
.
Write
(
maxNewlineBytes
)
}
else
{
d
.
dumpSlice
(
v
)
}
d
.
depth
--
d
.
indent
()
d
.
w
.
Write
(
closeBraceBytes
)
case
reflect
.
String
:
d
.
w
.
Write
([]
byte
(
strconv
.
Quote
(
v
.
String
())))
case
reflect
.
Interface
:
// The only time we should get here is for nil interfaces due to
// unpackValue calls.
if
v
.
IsNil
()
{
d
.
w
.
Write
(
nilAngleBytes
)
}
case
reflect
.
Ptr
:
// Do nothing. We should never get here since pointers have already
// been handled above.
case
reflect
.
Map
:
// nil maps should be indicated as different than empty maps
if
v
.
IsNil
()
{
d
.
w
.
Write
(
nilAngleBytes
)
break
}
d
.
w
.
Write
(
openBraceNewlineBytes
)
d
.
depth
++
if
(
d
.
cs
.
MaxDepth
!=
0
)
&&
(
d
.
depth
>
d
.
cs
.
MaxDepth
)
{
d
.
indent
()
d
.
w
.
Write
(
maxNewlineBytes
)
}
else
{
numEntries
:=
v
.
Len
()
keys
:=
v
.
MapKeys
()
if
d
.
cs
.
SortKeys
{
sortValues
(
keys
,
d
.
cs
)
}
for
i
,
key
:=
range
keys
{
d
.
dump
(
d
.
unpackValue
(
key
))
d
.
w
.
Write
(
colonSpaceBytes
)
d
.
ignoreNextIndent
=
true
d
.
dump
(
d
.
unpackValue
(
v
.
MapIndex
(
key
)))
if
i
<
(
numEntries
-
1
)
{
d
.
w
.
Write
(
commaNewlineBytes
)
}
else
{
d
.
w
.
Write
(
newlineBytes
)
}
}
}
d
.
depth
--
d
.
indent
()
d
.
w
.
Write
(
closeBraceBytes
)
case
reflect
.
Struct
:
d
.
w
.
Write
(
openBraceNewlineBytes
)
d
.
depth
++
if
(
d
.
cs
.
MaxDepth
!=
0
)
&&
(
d
.
depth
>
d
.
cs
.
MaxDepth
)
{
d
.
indent
()
d
.
w
.
Write
(
maxNewlineBytes
)
}
else
{
vt
:=
v
.
Type
()
numFields
:=
v
.
NumField
()
for
i
:=
0
;
i
<
numFields
;
i
++
{
d
.
indent
()
vtf
:=
vt
.
Field
(
i
)
d
.
w
.
Write
([]
byte
(
vtf
.
Name
))
d
.
w
.
Write
(
colonSpaceBytes
)
d
.
ignoreNextIndent
=
true
d
.
dump
(
d
.
unpackValue
(
v
.
Field
(
i
)))
if
i
<
(
numFields
-
1
)
{
d
.
w
.
Write
(
commaNewlineBytes
)
}
else
{
d
.
w
.
Write
(
newlineBytes
)
}
}
}
d
.
depth
--
d
.
indent
()
d
.
w
.
Write
(
closeBraceBytes
)
case
reflect
.
Uintptr
:
printHexPtr
(
d
.
w
,
uintptr
(
v
.
Uint
()))
case
reflect
.
UnsafePointer
,
reflect
.
Chan
,
reflect
.
Func
:
printHexPtr
(
d
.
w
,
v
.
Pointer
())
// There were not any other types at the time this code was written, but
// fall back to letting the default fmt package handle it in case any new
// types are added.
default
:
if
v
.
CanInterface
()
{
fmt
.
Fprintf
(
d
.
w
,
"%v"
,
v
.
Interface
())
}
else
{
fmt
.
Fprintf
(
d
.
w
,
"%v"
,
v
.
String
())
}
}
}
// fdump is a helper function to consolidate the logic from the various public
// methods which take varying writers and config states.
func
fdump
(
cs
*
ConfigState
,
w
io
.
Writer
,
a
...
interface
{})
{
for
_
,
arg
:=
range
a
{
if
arg
==
nil
{
w
.
Write
(
interfaceBytes
)
w
.
Write
(
spaceBytes
)
w
.
Write
(
nilAngleBytes
)
w
.
Write
(
newlineBytes
)
continue
}
d
:=
dumpState
{
w
:
w
,
cs
:
cs
}
d
.
pointers
=
make
(
map
[
uintptr
]
int
)
d
.
dump
(
reflect
.
ValueOf
(
arg
))
d
.
w
.
Write
(
newlineBytes
)
}
}
// Fdump formats and displays the passed arguments to io.Writer w. It formats
// exactly the same as Dump.
func
Fdump
(
w
io
.
Writer
,
a
...
interface
{})
{
fdump
(
&
Config
,
w
,
a
...
)
}
// Sdump returns a string with the passed arguments formatted exactly the same
// as Dump.
func
Sdump
(
a
...
interface
{})
string
{
var
buf
bytes
.
Buffer
fdump
(
&
Config
,
&
buf
,
a
...
)
return
buf
.
String
()
}
/*
Dump displays the passed parameters to standard out with newlines, customizable
indentation, and additional debug information such as complete types and all
pointer addresses used to indirect to the final value. It provides the
following features over the built-in printing facilities provided by the fmt
package:
* Pointers are dereferenced and followed
* Circular data structures are detected and handled properly
* Custom Stringer/error interfaces are optionally invoked, including
on unexported types
* Custom types which only implement the Stringer/error interfaces via
a pointer receiver are optionally invoked when passing non-pointer
variables
* Byte arrays and slices are dumped like the hexdump -C command which
includes offsets, byte values in hex, and ASCII output
The configuration options are controlled by an exported package global,
spew.Config. See ConfigState for options documentation.
See Fdump if you would prefer dumping to an arbitrary io.Writer or Sdump to
get the formatted result as a string.
*/
func
Dump
(
a
...
interface
{})
{
fdump
(
&
Config
,
os
.
Stdout
,
a
...
)
}
This diff is collapsed.
Click to expand it.
api/vendor/github.com/davecgh/go-spew/spew/format.go
0 → 100644
+
419
-
0
View file @
763e315e
/*
* Copyright (c) 2013-2016 Dave Collins <dave@davec.name>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
package
spew
import
(
"bytes"
"fmt"
"reflect"
"strconv"
"strings"
)
// supportedFlags is a list of all the character flags supported by fmt package.
const
supportedFlags
=
"0-+# "
// formatState implements the fmt.Formatter interface and contains information
// about the state of a formatting operation. The NewFormatter function can
// be used to get a new Formatter which can be used directly as arguments
// in standard fmt package printing calls.
type
formatState
struct
{
value
interface
{}
fs
fmt
.
State
depth
int
pointers
map
[
uintptr
]
int
ignoreNextType
bool
cs
*
ConfigState
}
// buildDefaultFormat recreates the original format string without precision
// and width information to pass in to fmt.Sprintf in the case of an
// unrecognized type. Unless new types are added to the language, this
// function won't ever be called.
func
(
f
*
formatState
)
buildDefaultFormat
()
(
format
string
)
{
buf
:=
bytes
.
NewBuffer
(
percentBytes
)
for
_
,
flag
:=
range
supportedFlags
{
if
f
.
fs
.
Flag
(
int
(
flag
))
{
buf
.
WriteRune
(
flag
)
}
}
buf
.
WriteRune
(
'v'
)
format
=
buf
.
String
()
return
format
}
// constructOrigFormat recreates the original format string including precision
// and width information to pass along to the standard fmt package. This allows
// automatic deferral of all format strings this package doesn't support.
func
(
f
*
formatState
)
constructOrigFormat
(
verb
rune
)
(
format
string
)
{
buf
:=
bytes
.
NewBuffer
(
percentBytes
)
for
_
,
flag
:=
range
supportedFlags
{
if
f
.
fs
.
Flag
(
int
(
flag
))
{
buf
.
WriteRune
(
flag
)
}
}
if
width
,
ok
:=
f
.
fs
.
Width
();
ok
{
buf
.
WriteString
(
strconv
.
Itoa
(
width
))
}
if
precision
,
ok
:=
f
.
fs
.
Precision
();
ok
{
buf
.
Write
(
precisionBytes
)
buf
.
WriteString
(
strconv
.
Itoa
(
precision
))
}
buf
.
WriteRune
(
verb
)
format
=
buf
.
String
()
return
format
}
// unpackValue returns values inside of non-nil interfaces when possible and
// ensures that types for values which have been unpacked from an interface
// are displayed when the show types flag is also set.
// This is useful for data types like structs, arrays, slices, and maps which
// can contain varying types packed inside an interface.
func
(
f
*
formatState
)
unpackValue
(
v
reflect
.
Value
)
reflect
.
Value
{
if
v
.
Kind
()
==
reflect
.
Interface
{
f
.
ignoreNextType
=
false
if
!
v
.
IsNil
()
{
v
=
v
.
Elem
()
}
}
return
v
}
// formatPtr handles formatting of pointers by indirecting them as necessary.
func
(
f
*
formatState
)
formatPtr
(
v
reflect
.
Value
)
{
// Display nil if top level pointer is nil.
showTypes
:=
f
.
fs
.
Flag
(
'#'
)
if
v
.
IsNil
()
&&
(
!
showTypes
||
f
.
ignoreNextType
)
{
f
.
fs
.
Write
(
nilAngleBytes
)
return
}
// Remove pointers at or below the current depth from map used to detect
// circular refs.
for
k
,
depth
:=
range
f
.
pointers
{
if
depth
>=
f
.
depth
{
delete
(
f
.
pointers
,
k
)
}
}
// Keep list of all dereferenced pointers to possibly show later.
pointerChain
:=
make
([]
uintptr
,
0
)
// Figure out how many levels of indirection there are by derferencing
// pointers and unpacking interfaces down the chain while detecting circular
// references.
nilFound
:=
false
cycleFound
:=
false
indirects
:=
0
ve
:=
v
for
ve
.
Kind
()
==
reflect
.
Ptr
{
if
ve
.
IsNil
()
{
nilFound
=
true
break
}
indirects
++
addr
:=
ve
.
Pointer
()
pointerChain
=
append
(
pointerChain
,
addr
)
if
pd
,
ok
:=
f
.
pointers
[
addr
];
ok
&&
pd
<
f
.
depth
{
cycleFound
=
true
indirects
--
break
}
f
.
pointers
[
addr
]
=
f
.
depth
ve
=
ve
.
Elem
()
if
ve
.
Kind
()
==
reflect
.
Interface
{
if
ve
.
IsNil
()
{
nilFound
=
true
break
}
ve
=
ve
.
Elem
()
}
}
// Display type or indirection level depending on flags.
if
showTypes
&&
!
f
.
ignoreNextType
{
f
.
fs
.
Write
(
openParenBytes
)
f
.
fs
.
Write
(
bytes
.
Repeat
(
asteriskBytes
,
indirects
))
f
.
fs
.
Write
([]
byte
(
ve
.
Type
()
.
String
()))
f
.
fs
.
Write
(
closeParenBytes
)
}
else
{
if
nilFound
||
cycleFound
{
indirects
+=
strings
.
Count
(
ve
.
Type
()
.
String
(),
"*"
)
}
f
.
fs
.
Write
(
openAngleBytes
)
f
.
fs
.
Write
([]
byte
(
strings
.
Repeat
(
"*"
,
indirects
)))
f
.
fs
.
Write
(
closeAngleBytes
)
}
// Display pointer information depending on flags.
if
f
.
fs
.
Flag
(
'+'
)
&&
(
len
(
pointerChain
)
>
0
)
{
f
.
fs
.
Write
(
openParenBytes
)
for
i
,
addr
:=
range
pointerChain
{
if
i
>
0
{
f
.
fs
.
Write
(
pointerChainBytes
)
}
printHexPtr
(
f
.
fs
,
addr
)
}
f
.
fs
.
Write
(
closeParenBytes
)
}
// Display dereferenced value.
switch
{
case
nilFound
:
f
.
fs
.
Write
(
nilAngleBytes
)
case
cycleFound
:
f
.
fs
.
Write
(
circularShortBytes
)
default
:
f
.
ignoreNextType
=
true
f
.
format
(
ve
)
}
}
// format is the main workhorse for providing the Formatter interface. It
// uses the passed reflect value to figure out what kind of object we are
// dealing with and formats it appropriately. It is a recursive function,
// however circular data structures are detected and handled properly.
func
(
f
*
formatState
)
format
(
v
reflect
.
Value
)
{
// Handle invalid reflect values immediately.
kind
:=
v
.
Kind
()
if
kind
==
reflect
.
Invalid
{
f
.
fs
.
Write
(
invalidAngleBytes
)
return
}
// Handle pointers specially.
if
kind
==
reflect
.
Ptr
{
f
.
formatPtr
(
v
)
return
}
// Print type information unless already handled elsewhere.
if
!
f
.
ignoreNextType
&&
f
.
fs
.
Flag
(
'#'
)
{
f
.
fs
.
Write
(
openParenBytes
)
f
.
fs
.
Write
([]
byte
(
v
.
Type
()
.
String
()))
f
.
fs
.
Write
(
closeParenBytes
)
}
f
.
ignoreNextType
=
false
// Call Stringer/error interfaces if they exist and the handle methods
// flag is enabled.
if
!
f
.
cs
.
DisableMethods
{
if
(
kind
!=
reflect
.
Invalid
)
&&
(
kind
!=
reflect
.
Interface
)
{
if
handled
:=
handleMethods
(
f
.
cs
,
f
.
fs
,
v
);
handled
{
return
}
}
}
switch
kind
{
case
reflect
.
Invalid
:
// Do nothing. We should never get here since invalid has already
// been handled above.
case
reflect
.
Bool
:
printBool
(
f
.
fs
,
v
.
Bool
())
case
reflect
.
Int8
,
reflect
.
Int16
,
reflect
.
Int32
,
reflect
.
Int64
,
reflect
.
Int
:
printInt
(
f
.
fs
,
v
.
Int
(),
10
)
case
reflect
.
Uint8
,
reflect
.
Uint16
,
reflect
.
Uint32
,
reflect
.
Uint64
,
reflect
.
Uint
:
printUint
(
f
.
fs
,
v
.
Uint
(),
10
)
case
reflect
.
Float32
:
printFloat
(
f
.
fs
,
v
.
Float
(),
32
)
case
reflect
.
Float64
:
printFloat
(
f
.
fs
,
v
.
Float
(),
64
)
case
reflect
.
Complex64
:
printComplex
(
f
.
fs
,
v
.
Complex
(),
32
)
case
reflect
.
Complex128
:
printComplex
(
f
.
fs
,
v
.
Complex
(),
64
)
case
reflect
.
Slice
:
if
v
.
IsNil
()
{
f
.
fs
.
Write
(
nilAngleBytes
)
break
}
fallthrough
case
reflect
.
Array
:
f
.
fs
.
Write
(
openBracketBytes
)
f
.
depth
++
if
(
f
.
cs
.
MaxDepth
!=
0
)
&&
(
f
.
depth
>
f
.
cs
.
MaxDepth
)
{
f
.
fs
.
Write
(
maxShortBytes
)
}
else
{
numEntries
:=
v
.
Len
()
for
i
:=
0
;
i
<
numEntries
;
i
++
{
if
i
>
0
{
f
.
fs
.
Write
(
spaceBytes
)
}
f
.
ignoreNextType
=
true
f
.
format
(
f
.
unpackValue
(
v
.
Index
(
i
)))
}
}
f
.
depth
--
f
.
fs
.
Write
(
closeBracketBytes
)
case
reflect
.
String
:
f
.
fs
.
Write
([]
byte
(
v
.
String
()))
case
reflect
.
Interface
:
// The only time we should get here is for nil interfaces due to
// unpackValue calls.
if
v
.
IsNil
()
{
f
.
fs
.
Write
(
nilAngleBytes
)
}
case
reflect
.
Ptr
:
// Do nothing. We should never get here since pointers have already
// been handled above.
case
reflect
.
Map
:
// nil maps should be indicated as different than empty maps
if
v
.
IsNil
()
{
f
.
fs
.
Write
(
nilAngleBytes
)
break
}
f
.
fs
.
Write
(
openMapBytes
)
f
.
depth
++
if
(
f
.
cs
.
MaxDepth
!=
0
)
&&
(
f
.
depth
>
f
.
cs
.
MaxDepth
)
{
f
.
fs
.
Write
(
maxShortBytes
)
}
else
{
keys
:=
v
.
MapKeys
()
if
f
.
cs
.
SortKeys
{
sortValues
(
keys
,
f
.
cs
)
}
for
i
,
key
:=
range
keys
{
if
i
>
0
{
f
.
fs
.
Write
(
spaceBytes
)
}
f
.
ignoreNextType
=
true
f
.
format
(
f
.
unpackValue
(
key
))
f
.
fs
.
Write
(
colonBytes
)
f
.
ignoreNextType
=
true
f
.
format
(
f
.
unpackValue
(
v
.
MapIndex
(
key
)))
}
}
f
.
depth
--
f
.
fs
.
Write
(
closeMapBytes
)
case
reflect
.
Struct
:
numFields
:=
v
.
NumField
()
f
.
fs
.
Write
(
openBraceBytes
)
f
.
depth
++
if
(
f
.
cs
.
MaxDepth
!=
0
)
&&
(
f
.
depth
>
f
.
cs
.
MaxDepth
)
{
f
.
fs
.
Write
(
maxShortBytes
)
}
else
{
vt
:=
v
.
Type
()
for
i
:=
0
;
i
<
numFields
;
i
++
{
if
i
>
0
{
f
.
fs
.
Write
(
spaceBytes
)
}
vtf
:=
vt
.
Field
(
i
)
if
f
.
fs
.
Flag
(
'+'
)
||
f
.
fs
.
Flag
(
'#'
)
{
f
.
fs
.
Write
([]
byte
(
vtf
.
Name
))
f
.
fs
.
Write
(
colonBytes
)
}
f
.
format
(
f
.
unpackValue
(
v
.
Field
(
i
)))
}
}
f
.
depth
--
f
.
fs
.
Write
(
closeBraceBytes
)
case
reflect
.
Uintptr
:
printHexPtr
(
f
.
fs
,
uintptr
(
v
.
Uint
()))
case
reflect
.
UnsafePointer
,
reflect
.
Chan
,
reflect
.
Func
:
printHexPtr
(
f
.
fs
,
v
.
Pointer
())
// There were not any other types at the time this code was written, but
// fall back to letting the default fmt package handle it if any get added.
default
:
format
:=
f
.
buildDefaultFormat
()
if
v
.
CanInterface
()
{
fmt
.
Fprintf
(
f
.
fs
,
format
,
v
.
Interface
())
}
else
{
fmt
.
Fprintf
(
f
.
fs
,
format
,
v
.
String
())
}
}
}
// Format satisfies the fmt.Formatter interface. See NewFormatter for usage
// details.
func
(
f
*
formatState
)
Format
(
fs
fmt
.
State
,
verb
rune
)
{
f
.
fs
=
fs
// Use standard formatting for verbs that are not v.
if
verb
!=
'v'
{
format
:=
f
.
constructOrigFormat
(
verb
)
fmt
.
Fprintf
(
fs
,
format
,
f
.
value
)
return
}
if
f
.
value
==
nil
{
if
fs
.
Flag
(
'#'
)
{
fs
.
Write
(
interfaceBytes
)
}
fs
.
Write
(
nilAngleBytes
)
return
}
f
.
format
(
reflect
.
ValueOf
(
f
.
value
))
}
// newFormatter is a helper function to consolidate the logic from the various
// public methods which take varying config states.
func
newFormatter
(
cs
*
ConfigState
,
v
interface
{})
fmt
.
Formatter
{
fs
:=
&
formatState
{
value
:
v
,
cs
:
cs
}
fs
.
pointers
=
make
(
map
[
uintptr
]
int
)
return
fs
}
/*
NewFormatter returns a custom formatter that satisfies the fmt.Formatter
interface. As a result, it integrates cleanly with standard fmt package
printing functions. The formatter is useful for inline printing of smaller data
types similar to the standard %v format specifier.
The custom formatter only responds to the %v (most compact), %+v (adds pointer
addresses), %#v (adds types), or %#+v (adds types and pointer addresses) verb
combinations. Any other verbs such as %x and %q will be sent to the the
standard fmt package for formatting. In addition, the custom formatter ignores
the width and precision arguments (however they will still work on the format
specifiers not handled by the custom formatter).
Typically this function shouldn't be called directly. It is much easier to make
use of the custom formatter by calling one of the convenience functions such as
Printf, Println, or Fprintf.
*/
func
NewFormatter
(
v
interface
{})
fmt
.
Formatter
{
return
newFormatter
(
&
Config
,
v
)
}
This diff is collapsed.
Click to expand it.
api/vendor/github.com/davecgh/go-spew/spew/spew.go
0 → 100644
+
148
-
0
View file @
763e315e
/*
* Copyright (c) 2013-2016 Dave Collins <dave@davec.name>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
package
spew
import
(
"fmt"
"io"
)
// Errorf is a wrapper for fmt.Errorf that treats each argument as if it were
// passed with a default Formatter interface returned by NewFormatter. It
// returns the formatted string as a value that satisfies error. See
// NewFormatter for formatting details.
//
// This function is shorthand for the following syntax:
//
// fmt.Errorf(format, spew.NewFormatter(a), spew.NewFormatter(b))
func
Errorf
(
format
string
,
a
...
interface
{})
(
err
error
)
{
return
fmt
.
Errorf
(
format
,
convertArgs
(
a
)
...
)
}
// Fprint is a wrapper for fmt.Fprint that treats each argument as if it were
// passed with a default Formatter interface returned by NewFormatter. It
// returns the number of bytes written and any write error encountered. See
// NewFormatter for formatting details.
//
// This function is shorthand for the following syntax:
//
// fmt.Fprint(w, spew.NewFormatter(a), spew.NewFormatter(b))
func
Fprint
(
w
io
.
Writer
,
a
...
interface
{})
(
n
int
,
err
error
)
{
return
fmt
.
Fprint
(
w
,
convertArgs
(
a
)
...
)
}
// Fprintf is a wrapper for fmt.Fprintf that treats each argument as if it were
// passed with a default Formatter interface returned by NewFormatter. It
// returns the number of bytes written and any write error encountered. See
// NewFormatter for formatting details.
//
// This function is shorthand for the following syntax:
//
// fmt.Fprintf(w, format, spew.NewFormatter(a), spew.NewFormatter(b))
func
Fprintf
(
w
io
.
Writer
,
format
string
,
a
...
interface
{})
(
n
int
,
err
error
)
{
return
fmt
.
Fprintf
(
w
,
format
,
convertArgs
(
a
)
...
)
}
// Fprintln is a wrapper for fmt.Fprintln that treats each argument as if it
// passed with a default Formatter interface returned by NewFormatter. See
// NewFormatter for formatting details.
//
// This function is shorthand for the following syntax:
//
// fmt.Fprintln(w, spew.NewFormatter(a), spew.NewFormatter(b))
func
Fprintln
(
w
io
.
Writer
,
a
...
interface
{})
(
n
int
,
err
error
)
{
return
fmt
.
Fprintln
(
w
,
convertArgs
(
a
)
...
)
}
// Print is a wrapper for fmt.Print that treats each argument as if it were
// passed with a default Formatter interface returned by NewFormatter. It
// returns the number of bytes written and any write error encountered. See
// NewFormatter for formatting details.
//
// This function is shorthand for the following syntax:
//
// fmt.Print(spew.NewFormatter(a), spew.NewFormatter(b))
func
Print
(
a
...
interface
{})
(
n
int
,
err
error
)
{
return
fmt
.
Print
(
convertArgs
(
a
)
...
)
}
// Printf is a wrapper for fmt.Printf that treats each argument as if it were
// passed with a default Formatter interface returned by NewFormatter. It
// returns the number of bytes written and any write error encountered. See
// NewFormatter for formatting details.
//
// This function is shorthand for the following syntax:
//
// fmt.Printf(format, spew.NewFormatter(a), spew.NewFormatter(b))
func
Printf
(
format
string
,
a
...
interface
{})
(
n
int
,
err
error
)
{
return
fmt
.
Printf
(
format
,
convertArgs
(
a
)
...
)
}
// Println is a wrapper for fmt.Println that treats each argument as if it were
// passed with a default Formatter interface returned by NewFormatter. It
// returns the number of bytes written and any write error encountered. See
// NewFormatter for formatting details.
//
// This function is shorthand for the following syntax:
//
// fmt.Println(spew.NewFormatter(a), spew.NewFormatter(b))
func
Println
(
a
...
interface
{})
(
n
int
,
err
error
)
{
return
fmt
.
Println
(
convertArgs
(
a
)
...
)
}
// Sprint is a wrapper for fmt.Sprint that treats each argument as if it were
// passed with a default Formatter interface returned by NewFormatter. It
// returns the resulting string. See NewFormatter for formatting details.
//
// This function is shorthand for the following syntax:
//
// fmt.Sprint(spew.NewFormatter(a), spew.NewFormatter(b))
func
Sprint
(
a
...
interface
{})
string
{
return
fmt
.
Sprint
(
convertArgs
(
a
)
...
)
}
// Sprintf is a wrapper for fmt.Sprintf that treats each argument as if it were
// passed with a default Formatter interface returned by NewFormatter. It
// returns the resulting string. See NewFormatter for formatting details.
//
// This function is shorthand for the following syntax:
//
// fmt.Sprintf(format, spew.NewFormatter(a), spew.NewFormatter(b))
func
Sprintf
(
format
string
,
a
...
interface
{})
string
{
return
fmt
.
Sprintf
(
format
,
convertArgs
(
a
)
...
)
}
// Sprintln is a wrapper for fmt.Sprintln that treats each argument as if it
// were passed with a default Formatter interface returned by NewFormatter. It
// returns the resulting string. See NewFormatter for formatting details.
//
// This function is shorthand for the following syntax:
//
// fmt.Sprintln(spew.NewFormatter(a), spew.NewFormatter(b))
func
Sprintln
(
a
...
interface
{})
string
{
return
fmt
.
Sprintln
(
convertArgs
(
a
)
...
)
}
// convertArgs accepts a slice of arguments and returns a slice of the same
// length with each argument converted to a default spew Formatter interface.
func
convertArgs
(
args
[]
interface
{})
(
formatters
[]
interface
{})
{
formatters
=
make
([]
interface
{},
len
(
args
))
for
index
,
arg
:=
range
args
{
formatters
[
index
]
=
NewFormatter
(
arg
)
}
return
formatters
}
This diff is collapsed.
Click to expand it.
api/vendor/github.com/docker/go-units/CONTRIBUTING.md
0 → 100644
+
67
-
0
View file @
763e315e
# Contributing to go-units
Want to hack on go-units? Awesome! Here are instructions to get you started.
go-units is a part of the
[
Docker
](
https://www.docker.com
)
project, and follows
the same rules and principles. If you're already familiar with the way
Docker does things, you'll feel right at home.
Otherwise, go read Docker's
[
contributions guidelines
](
https://github.com/docker/docker/blob/master/CONTRIBUTING.md
)
,
[
issue triaging
](
https://github.com/docker/docker/blob/master/project/ISSUE-TRIAGE.md
)
,
[
review process
](
https://github.com/docker/docker/blob/master/project/REVIEWING.md
)
and
[
branches and tags
](
https://github.com/docker/docker/blob/master/project/BRANCHES-AND-TAGS.md
)
.
### Sign your work
The sign-off is a simple line at the end of the explanation for the patch. Your
signature certifies that you wrote the patch or otherwise have the right to pass
it on as an open-source patch. The rules are pretty simple: if you can certify
the below (from
[
developercertificate.org
](
http://developercertificate.org/
)
):
```
Developer Certificate of Origin
Version 1.1
Copyright (C) 2004, 2006 The Linux Foundation and its contributors.
660 York Street, Suite 102,
San Francisco, CA 94110 USA
Everyone is permitted to copy and distribute verbatim copies of this
license document, but changing it is not allowed.
Developer's Certificate of Origin 1.1
By making a contribution to this project, I certify that:
(a) The contribution was created in whole or in part by me and I
have the right to submit it under the open source license
indicated in the file; or
(b) The contribution is based upon previous work that, to the best
of my knowledge, is covered under an appropriate open source
license and I have the right under that license to submit that
work with modifications, whether created in whole or in part
by me, under the same open source license (unless I am
permitted to submit under a different license), as indicated
in the file; or
(c) The contribution was provided directly to me by some other
person who certified (a), (b) or (c) and I have not modified
it.
(d) I understand and agree that this project and the contribution
are public and that a record of the contribution (including all
personal information I submit with it, including my sign-off) is
maintained indefinitely and may be redistributed consistent with
this project or the open source license(s) involved.
```
Then you just add a line to every git commit message:
Signed-off-by: Joe Smith <joe.smith@email.com>
Use your real name (sorry, no pseudonyms or anonymous contributions.)
If you set your
`user.name`
and
`user.email`
git configs, you can sign your
commit automatically with
`git commit -s`
.
This diff is collapsed.
Click to expand it.
api/vendor/github.com/docker/go-units/LICENSE
0 → 100644
+
191
-
0
View file @
763e315e
Apache License
Version 2.0, January 2004
https://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
Copyright 2015 Docker, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
This diff is collapsed.
Click to expand it.
api/vendor/github.com/docker/go-units/MAINTAINERS
0 → 100644
+
46
-
0
View file @
763e315e
# go-units maintainers file
#
# This file describes who runs the docker/go-units project and how.
# This is a living document - if you see something out of date or missing, speak up!
#
# It is structured to be consumable by both humans and programs.
# To extract its contents programmatically, use any TOML-compliant parser.
#
# This file is compiled into the MAINTAINERS file in docker/opensource.
#
[Org]
[Org."Core maintainers"]
people = [
"akihirosuda",
"dnephin",
"thajeztah",
"vdemeester",
]
[people]
# A reference list of all people associated with the project.
# All other sections should refer to people by their canonical key
# in the people section.
# ADD YOURSELF HERE IN ALPHABETICAL ORDER
[people.akihirosuda]
Name = "Akihiro Suda"
Email = "suda.akihiro@lab.ntt.co.jp"
GitHub = "AkihiroSuda"
[people.dnephin]
Name = "Daniel Nephin"
Email = "dnephin@gmail.com"
GitHub = "dnephin"
[people.thajeztah]
Name = "Sebastiaan van Stijn"
Email = "github@gone.nl"
GitHub = "thaJeztah"
[people.vdemeester]
Name = "Vincent Demeester"
Email = "vincent@sbr.pm"
GitHub = "vdemeester"
\ No newline at end of file
This diff is collapsed.
Click to expand it.
api/vendor/github.com/docker/go-units/README.md
0 → 100644
+
16
-
0
View file @
763e315e
[

](https://godoc.org/github.com/docker/go-units)
# Introduction
go-units is a library to transform human friendly measurements into machine friendly values.
## Usage
See the
[
docs in godoc
](
https://godoc.org/github.com/docker/go-units
)
for examples and documentation.
## Copyright and license
Copyright © 2015 Docker, Inc.
go-units is licensed under the Apache License, Version 2.0.
See
[
LICENSE
](
LICENSE
)
for the full text of the license.
This diff is collapsed.
Click to expand it.
api/vendor/github.com/docker/go-units/circle.yml
0 → 100644
+
11
-
0
View file @
763e315e
dependencies
:
post
:
# install golint
-
go get github.com/golang/lint/golint
test
:
pre
:
# run analysis before tests
-
go vet ./...
-
test -z "$(golint ./... | tee /dev/stderr)"
-
test -z "$(gofmt -s -l . | tee /dev/stderr)"
This diff is collapsed.
Click to expand it.
api/vendor/github.com/docker/go-units/duration.go
0 → 100644
+
35
-
0
View file @
763e315e
// Package units provides helper function to parse and print size and time units
// in human-readable format.
package
units
import
(
"fmt"
"time"
)
// HumanDuration returns a human-readable approximation of a duration
// (eg. "About a minute", "4 hours ago", etc.).
func
HumanDuration
(
d
time
.
Duration
)
string
{
if
seconds
:=
int
(
d
.
Seconds
());
seconds
<
1
{
return
"Less than a second"
}
else
if
seconds
==
1
{
return
"1 second"
}
else
if
seconds
<
60
{
return
fmt
.
Sprintf
(
"%d seconds"
,
seconds
)
}
else
if
minutes
:=
int
(
d
.
Minutes
());
minutes
==
1
{
return
"About a minute"
}
else
if
minutes
<
46
{
return
fmt
.
Sprintf
(
"%d minutes"
,
minutes
)
}
else
if
hours
:=
int
(
d
.
Hours
()
+
0.5
);
hours
==
1
{
return
"About an hour"
}
else
if
hours
<
48
{
return
fmt
.
Sprintf
(
"%d hours"
,
hours
)
}
else
if
hours
<
24
*
7
*
2
{
return
fmt
.
Sprintf
(
"%d days"
,
hours
/
24
)
}
else
if
hours
<
24
*
30
*
2
{
return
fmt
.
Sprintf
(
"%d weeks"
,
hours
/
24
/
7
)
}
else
if
hours
<
24
*
365
*
2
{
return
fmt
.
Sprintf
(
"%d months"
,
hours
/
24
/
30
)
}
return
fmt
.
Sprintf
(
"%d years"
,
int
(
d
.
Hours
())
/
24
/
365
)
}
This diff is collapsed.
Click to expand it.
api/vendor/github.com/docker/go-units/size.go
0 → 100644
+
108
-
0
View file @
763e315e
package
units
import
(
"fmt"
"regexp"
"strconv"
"strings"
)
// See: http://en.wikipedia.org/wiki/Binary_prefix
const
(
// Decimal
KB
=
1000
MB
=
1000
*
KB
GB
=
1000
*
MB
TB
=
1000
*
GB
PB
=
1000
*
TB
// Binary
KiB
=
1024
MiB
=
1024
*
KiB
GiB
=
1024
*
MiB
TiB
=
1024
*
GiB
PiB
=
1024
*
TiB
)
type
unitMap
map
[
string
]
int64
var
(
decimalMap
=
unitMap
{
"k"
:
KB
,
"m"
:
MB
,
"g"
:
GB
,
"t"
:
TB
,
"p"
:
PB
}
binaryMap
=
unitMap
{
"k"
:
KiB
,
"m"
:
MiB
,
"g"
:
GiB
,
"t"
:
TiB
,
"p"
:
PiB
}
sizeRegex
=
regexp
.
MustCompile
(
`^(\d+(\.\d+)*) ?([kKmMgGtTpP])?[iI]?[bB]?$`
)
)
var
decimapAbbrs
=
[]
string
{
"B"
,
"kB"
,
"MB"
,
"GB"
,
"TB"
,
"PB"
,
"EB"
,
"ZB"
,
"YB"
}
var
binaryAbbrs
=
[]
string
{
"B"
,
"KiB"
,
"MiB"
,
"GiB"
,
"TiB"
,
"PiB"
,
"EiB"
,
"ZiB"
,
"YiB"
}
func
getSizeAndUnit
(
size
float64
,
base
float64
,
_map
[]
string
)
(
float64
,
string
)
{
i
:=
0
unitsLimit
:=
len
(
_map
)
-
1
for
size
>=
base
&&
i
<
unitsLimit
{
size
=
size
/
base
i
++
}
return
size
,
_map
[
i
]
}
// CustomSize returns a human-readable approximation of a size
// using custom format.
func
CustomSize
(
format
string
,
size
float64
,
base
float64
,
_map
[]
string
)
string
{
size
,
unit
:=
getSizeAndUnit
(
size
,
base
,
_map
)
return
fmt
.
Sprintf
(
format
,
size
,
unit
)
}
// HumanSizeWithPrecision allows the size to be in any precision,
// instead of 4 digit precision used in units.HumanSize.
func
HumanSizeWithPrecision
(
size
float64
,
precision
int
)
string
{
size
,
unit
:=
getSizeAndUnit
(
size
,
1000.0
,
decimapAbbrs
)
return
fmt
.
Sprintf
(
"%.*g%s"
,
precision
,
size
,
unit
)
}
// HumanSize returns a human-readable approximation of a size
// capped at 4 valid numbers (eg. "2.746 MB", "796 KB").
func
HumanSize
(
size
float64
)
string
{
return
HumanSizeWithPrecision
(
size
,
4
)
}
// BytesSize returns a human-readable size in bytes, kibibytes,
// mebibytes, gibibytes, or tebibytes (eg. "44kiB", "17MiB").
func
BytesSize
(
size
float64
)
string
{
return
CustomSize
(
"%.4g%s"
,
size
,
1024.0
,
binaryAbbrs
)
}
// FromHumanSize returns an integer from a human-readable specification of a
// size using SI standard (eg. "44kB", "17MB").
func
FromHumanSize
(
size
string
)
(
int64
,
error
)
{
return
parseSize
(
size
,
decimalMap
)
}
// RAMInBytes parses a human-readable string representing an amount of RAM
// in bytes, kibibytes, mebibytes, gibibytes, or tebibytes and
// returns the number of bytes, or -1 if the string is unparseable.
// Units are case-insensitive, and the 'b' suffix is optional.
func
RAMInBytes
(
size
string
)
(
int64
,
error
)
{
return
parseSize
(
size
,
binaryMap
)
}
// Parses the human-readable size string into the amount it represents.
func
parseSize
(
sizeStr
string
,
uMap
unitMap
)
(
int64
,
error
)
{
matches
:=
sizeRegex
.
FindStringSubmatch
(
sizeStr
)
if
len
(
matches
)
!=
4
{
return
-
1
,
fmt
.
Errorf
(
"invalid size: '%s'"
,
sizeStr
)
}
size
,
err
:=
strconv
.
ParseFloat
(
matches
[
1
],
64
)
if
err
!=
nil
{
return
-
1
,
err
}
unitPrefix
:=
strings
.
ToLower
(
matches
[
3
])
if
mul
,
ok
:=
uMap
[
unitPrefix
];
ok
{
size
*=
float64
(
mul
)
}
return
int64
(
size
),
nil
}
This diff is collapsed.
Click to expand it.
api/vendor/github.com/docker/go-units/ulimit.go
0 → 100644
+
118
-
0
View file @
763e315e
package
units
import
(
"fmt"
"strconv"
"strings"
)
// Ulimit is a human friendly version of Rlimit.
type
Ulimit
struct
{
Name
string
Hard
int64
Soft
int64
}
// Rlimit specifies the resource limits, such as max open files.
type
Rlimit
struct
{
Type
int
`json:"type,omitempty"`
Hard
uint64
`json:"hard,omitempty"`
Soft
uint64
`json:"soft,omitempty"`
}
const
(
// magic numbers for making the syscall
// some of these are defined in the syscall package, but not all.
// Also since Windows client doesn't get access to the syscall package, need to
// define these here
rlimitAs
=
9
rlimitCore
=
4
rlimitCPU
=
0
rlimitData
=
2
rlimitFsize
=
1
rlimitLocks
=
10
rlimitMemlock
=
8
rlimitMsgqueue
=
12
rlimitNice
=
13
rlimitNofile
=
7
rlimitNproc
=
6
rlimitRss
=
5
rlimitRtprio
=
14
rlimitRttime
=
15
rlimitSigpending
=
11
rlimitStack
=
3
)
var
ulimitNameMapping
=
map
[
string
]
int
{
//"as": rlimitAs, // Disabled since this doesn't seem usable with the way Docker inits a container.
"core"
:
rlimitCore
,
"cpu"
:
rlimitCPU
,
"data"
:
rlimitData
,
"fsize"
:
rlimitFsize
,
"locks"
:
rlimitLocks
,
"memlock"
:
rlimitMemlock
,
"msgqueue"
:
rlimitMsgqueue
,
"nice"
:
rlimitNice
,
"nofile"
:
rlimitNofile
,
"nproc"
:
rlimitNproc
,
"rss"
:
rlimitRss
,
"rtprio"
:
rlimitRtprio
,
"rttime"
:
rlimitRttime
,
"sigpending"
:
rlimitSigpending
,
"stack"
:
rlimitStack
,
}
// ParseUlimit parses and returns a Ulimit from the specified string.
func
ParseUlimit
(
val
string
)
(
*
Ulimit
,
error
)
{
parts
:=
strings
.
SplitN
(
val
,
"="
,
2
)
if
len
(
parts
)
!=
2
{
return
nil
,
fmt
.
Errorf
(
"invalid ulimit argument: %s"
,
val
)
}
if
_
,
exists
:=
ulimitNameMapping
[
parts
[
0
]];
!
exists
{
return
nil
,
fmt
.
Errorf
(
"invalid ulimit type: %s"
,
parts
[
0
])
}
var
(
soft
int64
hard
=
&
soft
// default to soft in case no hard was set
temp
int64
err
error
)
switch
limitVals
:=
strings
.
Split
(
parts
[
1
],
":"
);
len
(
limitVals
)
{
case
2
:
temp
,
err
=
strconv
.
ParseInt
(
limitVals
[
1
],
10
,
64
)
if
err
!=
nil
{
return
nil
,
err
}
hard
=
&
temp
fallthrough
case
1
:
soft
,
err
=
strconv
.
ParseInt
(
limitVals
[
0
],
10
,
64
)
if
err
!=
nil
{
return
nil
,
err
}
default
:
return
nil
,
fmt
.
Errorf
(
"too many limit value arguments - %s, can only have up to two, `soft[:hard]`"
,
parts
[
1
])
}
if
soft
>
*
hard
{
return
nil
,
fmt
.
Errorf
(
"ulimit soft limit must be less than or equal to hard limit: %d > %d"
,
soft
,
*
hard
)
}
return
&
Ulimit
{
Name
:
parts
[
0
],
Soft
:
soft
,
Hard
:
*
hard
},
nil
}
// GetRlimit returns the RLimit corresponding to Ulimit.
func
(
u
*
Ulimit
)
GetRlimit
()
(
*
Rlimit
,
error
)
{
t
,
exists
:=
ulimitNameMapping
[
u
.
Name
]
if
!
exists
{
return
nil
,
fmt
.
Errorf
(
"invalid ulimit name %s"
,
u
.
Name
)
}
return
&
Rlimit
{
Type
:
t
,
Soft
:
uint64
(
u
.
Soft
),
Hard
:
uint64
(
u
.
Hard
)},
nil
}
func
(
u
*
Ulimit
)
String
()
string
{
return
fmt
.
Sprintf
(
"%s=%d:%d"
,
u
.
Name
,
u
.
Soft
,
u
.
Hard
)
}
This diff is collapsed.
Click to expand it.
api/vendor/github.com/gorilla/websocket/.gitignore
0 → 100644
+
25
-
0
View file @
763e315e
# Compiled Object files, Static and Dynamic libs (Shared Objects)
*.o
*.a
*.so
# Folders
_obj
_test
# Architecture specific extensions/prefixes
*.[568vq]
[568vq].out
*.cgo1.go
*.cgo2.c
_cgo_defun.c
_cgo_gotypes.go
_cgo_export.*
_testmain.go
*.exe
.idea/
*.iml
This diff is collapsed.
Click to expand it.
Prev
1
2
3
4
5
…
9
Next
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment