Upgrade k8s.io/client-go to version 2
This commit is contained in:
parent
a3b95f798b
commit
6f4c5dd4ce
675 changed files with 109006 additions and 90744 deletions
255
glide.lock
generated
255
glide.lock
generated
|
@ -1,12 +1,13 @@
|
||||||
hash: fa4c40400ed94e105a9a1a0d163ac9c4ecea4598ad4ee4fef5237a39d4f28d0a
|
hash: b1cbcbd938a47a246b0d4d634037b76e63486c63e5867b339f92bcbd7453b75c
|
||||||
updated: 2017-04-07T10:50:34.091189379+01:00
|
updated: 2017-04-07T11:34:46.101385591+01:00
|
||||||
imports:
|
imports:
|
||||||
- name: bitbucket.org/ww/goautoneg
|
- name: bitbucket.org/ww/goautoneg
|
||||||
version: 75cd24fc2f2c2a2088577d12123ddee5f54e0675
|
version: 75cd24fc2f2c2a2088577d12123ddee5f54e0675
|
||||||
- name: cloud.google.com/go
|
- name: cloud.google.com/go
|
||||||
version: c116c7972ec94f148459a304d07a67ecbc770d4b
|
version: 2e6a95edb1071d750f6d7db777bf66cd2997af6c
|
||||||
subpackages:
|
subpackages:
|
||||||
- compute/metadata
|
- compute/metadata
|
||||||
|
- internal
|
||||||
- name: github.com/abbot/go-http-auth
|
- name: github.com/abbot/go-http-auth
|
||||||
version: cb4372376e1e00e9f6ab9ec142e029302c9e7140
|
version: cb4372376e1e00e9f6ab9ec142e029302c9e7140
|
||||||
- name: github.com/ArthurHlt/go-eureka-client
|
- name: github.com/ArthurHlt/go-eureka-client
|
||||||
|
@ -112,9 +113,8 @@ imports:
|
||||||
subpackages:
|
subpackages:
|
||||||
- daemon
|
- daemon
|
||||||
- name: github.com/coreos/pkg
|
- name: github.com/coreos/pkg
|
||||||
version: 2c77715c4df99b5420ffcae14ead08f52104065d
|
version: fa29b1d70f0beaddd4c7021607cc3c3be8ce94b8
|
||||||
subpackages:
|
subpackages:
|
||||||
- capnslog
|
|
||||||
- health
|
- health
|
||||||
- httputil
|
- httputil
|
||||||
- timeutil
|
- timeutil
|
||||||
|
@ -239,6 +239,8 @@ imports:
|
||||||
- query
|
- query
|
||||||
- name: github.com/google/gofuzz
|
- name: github.com/google/gofuzz
|
||||||
version: bbcb9da2d746f8bdbd6a936686a0a6067ada0ec5
|
version: bbcb9da2d746f8bdbd6a936686a0a6067ada0ec5
|
||||||
|
- name: github.com/googleapis/gax-go
|
||||||
|
version: 9af46dd5a1713e8b5cd71106287eba3cefdde50b
|
||||||
- name: github.com/gorilla/context
|
- name: github.com/gorilla/context
|
||||||
version: 1ea25387ff6f684839d82767c1733ff4d4d15d0a
|
version: 1ea25387ff6f684839d82767c1733ff4d4d15d0a
|
||||||
- name: github.com/gorilla/websocket
|
- name: github.com/gorilla/websocket
|
||||||
|
@ -369,7 +371,7 @@ imports:
|
||||||
- name: github.com/Sirupsen/logrus
|
- name: github.com/Sirupsen/logrus
|
||||||
version: a283a10442df8dc09befd873fab202bf8a253d6a
|
version: a283a10442df8dc09befd873fab202bf8a253d6a
|
||||||
- name: github.com/spf13/pflag
|
- name: github.com/spf13/pflag
|
||||||
version: 5644820622454e71517561946e3d94b9f9db6842
|
version: 5ccb023bc27df288a957c5e994cd44fd19619465
|
||||||
- name: github.com/streamrail/concurrent-map
|
- name: github.com/streamrail/concurrent-map
|
||||||
version: 65a174a3a4188c0b7099acbc6cfa0c53628d3287
|
version: 65a174a3a4188c0b7099acbc6cfa0c53628d3287
|
||||||
- name: github.com/stretchr/objx
|
- name: github.com/stretchr/objx
|
||||||
|
@ -457,11 +459,13 @@ imports:
|
||||||
- http2
|
- http2
|
||||||
- http2/hpack
|
- http2/hpack
|
||||||
- idna
|
- idna
|
||||||
|
- internal/timeseries
|
||||||
- lex/httplex
|
- lex/httplex
|
||||||
- proxy
|
- proxy
|
||||||
- publicsuffix
|
- publicsuffix
|
||||||
|
- trace
|
||||||
- name: golang.org/x/oauth2
|
- name: golang.org/x/oauth2
|
||||||
version: 3046bc76d6dfd7d3707f6640f85e42d9c4050f50
|
version: 7fdf09982454086d5570c7db3e11f360194830ca
|
||||||
subpackages:
|
subpackages:
|
||||||
- google
|
- google
|
||||||
- internal
|
- internal
|
||||||
|
@ -473,13 +477,9 @@ imports:
|
||||||
- unix
|
- unix
|
||||||
- windows
|
- windows
|
||||||
- name: golang.org/x/text
|
- name: golang.org/x/text
|
||||||
version: a49bea13b776691cb1b49873e5d8df96ec74831a
|
version: 2910a502d2bf9e43193af9d68ca516529614eed3
|
||||||
repo: https://github.com/golang/text.git
|
|
||||||
vcs: git
|
|
||||||
subpackages:
|
subpackages:
|
||||||
- .
|
|
||||||
- cases
|
- cases
|
||||||
- internal
|
|
||||||
- internal/tag
|
- internal/tag
|
||||||
- language
|
- language
|
||||||
- runes
|
- runes
|
||||||
|
@ -497,7 +497,7 @@ imports:
|
||||||
- googleapi
|
- googleapi
|
||||||
- googleapi/internal/uritemplates
|
- googleapi/internal/uritemplates
|
||||||
- name: google.golang.org/appengine
|
- name: google.golang.org/appengine
|
||||||
version: 12d5545dc1cfa6047a286d5e853841b6471f4c19
|
version: 4f7eeb5305a4ba1966344836ba4af9996b7b4e05
|
||||||
subpackages:
|
subpackages:
|
||||||
- internal
|
- internal
|
||||||
- internal/app_identity
|
- internal/app_identity
|
||||||
|
@ -508,11 +508,20 @@ imports:
|
||||||
- internal/remote_api
|
- internal/remote_api
|
||||||
- internal/urlfetch
|
- internal/urlfetch
|
||||||
- urlfetch
|
- urlfetch
|
||||||
- name: google.golang.org/cloud
|
- name: google.golang.org/grpc
|
||||||
version: f20d6dcccb44ed49de45ae3703312cb46e627db1
|
version: cdee119ee21e61eef7093a41ba148fa83585e143
|
||||||
subpackages:
|
subpackages:
|
||||||
- compute/metadata
|
- codes
|
||||||
|
- credentials
|
||||||
|
- grpclog
|
||||||
- internal
|
- internal
|
||||||
|
- keepalive
|
||||||
|
- metadata
|
||||||
|
- naming
|
||||||
|
- peer
|
||||||
|
- stats
|
||||||
|
- tap
|
||||||
|
- transport
|
||||||
- name: gopkg.in/fsnotify.v1
|
- name: gopkg.in/fsnotify.v1
|
||||||
version: a8a77c9133d2d6fd8334f3260d06f60e8d80a5fb
|
version: a8a77c9133d2d6fd8334f3260d06f60e8d80a5fb
|
||||||
- name: gopkg.in/inf.v0
|
- name: gopkg.in/inf.v0
|
||||||
|
@ -538,111 +547,115 @@ imports:
|
||||||
- cipher
|
- cipher
|
||||||
- json
|
- json
|
||||||
- name: gopkg.in/yaml.v2
|
- name: gopkg.in/yaml.v2
|
||||||
version: bef53efd0c76e49e6de55ead051f886bea7e9420
|
version: 53feefa2559fb8dfa8d81baad31be332c97d6c77
|
||||||
- name: k8s.io/client-go
|
- name: k8s.io/client-go
|
||||||
version: 1195e3a8ee1a529d53eed7c624527a68555ddf1f
|
version: e121606b0d09b2e1c467183ee46217fa85a6b672
|
||||||
subpackages:
|
subpackages:
|
||||||
- 1.5/discovery
|
- discovery
|
||||||
- 1.5/kubernetes
|
- kubernetes
|
||||||
- 1.5/kubernetes/typed/apps/v1alpha1
|
- kubernetes/typed/apps/v1beta1
|
||||||
- 1.5/kubernetes/typed/authentication/v1beta1
|
- kubernetes/typed/authentication/v1beta1
|
||||||
- 1.5/kubernetes/typed/authorization/v1beta1
|
- kubernetes/typed/authorization/v1beta1
|
||||||
- 1.5/kubernetes/typed/autoscaling/v1
|
- kubernetes/typed/autoscaling/v1
|
||||||
- 1.5/kubernetes/typed/batch/v1
|
- kubernetes/typed/batch/v1
|
||||||
- 1.5/kubernetes/typed/certificates/v1alpha1
|
- kubernetes/typed/batch/v2alpha1
|
||||||
- 1.5/kubernetes/typed/core/v1
|
- kubernetes/typed/certificates/v1alpha1
|
||||||
- 1.5/kubernetes/typed/extensions/v1beta1
|
- kubernetes/typed/core/v1
|
||||||
- 1.5/kubernetes/typed/policy/v1alpha1
|
- kubernetes/typed/extensions/v1beta1
|
||||||
- 1.5/kubernetes/typed/rbac/v1alpha1
|
- kubernetes/typed/policy/v1beta1
|
||||||
- 1.5/kubernetes/typed/storage/v1beta1
|
- kubernetes/typed/rbac/v1alpha1
|
||||||
- 1.5/pkg/api
|
- kubernetes/typed/storage/v1beta1
|
||||||
- 1.5/pkg/api/errors
|
- pkg/api
|
||||||
- 1.5/pkg/api/install
|
- pkg/api/errors
|
||||||
- 1.5/pkg/api/meta
|
- pkg/api/install
|
||||||
- 1.5/pkg/api/meta/metatypes
|
- pkg/api/meta
|
||||||
- 1.5/pkg/api/resource
|
- pkg/api/meta/metatypes
|
||||||
- 1.5/pkg/api/unversioned
|
- pkg/api/resource
|
||||||
- 1.5/pkg/api/v1
|
- pkg/api/unversioned
|
||||||
- 1.5/pkg/api/validation/path
|
- pkg/api/v1
|
||||||
- 1.5/pkg/apimachinery
|
- pkg/api/validation/path
|
||||||
- 1.5/pkg/apimachinery/announced
|
- pkg/apimachinery
|
||||||
- 1.5/pkg/apimachinery/registered
|
- pkg/apimachinery/announced
|
||||||
- 1.5/pkg/apis/apps
|
- pkg/apimachinery/registered
|
||||||
- 1.5/pkg/apis/apps/install
|
- pkg/apis/apps
|
||||||
- 1.5/pkg/apis/apps/v1alpha1
|
- pkg/apis/apps/install
|
||||||
- 1.5/pkg/apis/authentication
|
- pkg/apis/apps/v1beta1
|
||||||
- 1.5/pkg/apis/authentication/install
|
- pkg/apis/authentication
|
||||||
- 1.5/pkg/apis/authentication/v1beta1
|
- pkg/apis/authentication/install
|
||||||
- 1.5/pkg/apis/authorization
|
- pkg/apis/authentication/v1beta1
|
||||||
- 1.5/pkg/apis/authorization/install
|
- pkg/apis/authorization
|
||||||
- 1.5/pkg/apis/authorization/v1beta1
|
- pkg/apis/authorization/install
|
||||||
- 1.5/pkg/apis/autoscaling
|
- pkg/apis/authorization/v1beta1
|
||||||
- 1.5/pkg/apis/autoscaling/install
|
- pkg/apis/autoscaling
|
||||||
- 1.5/pkg/apis/autoscaling/v1
|
- pkg/apis/autoscaling/install
|
||||||
- 1.5/pkg/apis/batch
|
- pkg/apis/autoscaling/v1
|
||||||
- 1.5/pkg/apis/batch/install
|
- pkg/apis/batch
|
||||||
- 1.5/pkg/apis/batch/v1
|
- pkg/apis/batch/install
|
||||||
- 1.5/pkg/apis/batch/v2alpha1
|
- pkg/apis/batch/v1
|
||||||
- 1.5/pkg/apis/certificates
|
- pkg/apis/batch/v2alpha1
|
||||||
- 1.5/pkg/apis/certificates/install
|
- pkg/apis/certificates
|
||||||
- 1.5/pkg/apis/certificates/v1alpha1
|
- pkg/apis/certificates/install
|
||||||
- 1.5/pkg/apis/extensions
|
- pkg/apis/certificates/v1alpha1
|
||||||
- 1.5/pkg/apis/extensions/install
|
- pkg/apis/extensions
|
||||||
- 1.5/pkg/apis/extensions/v1beta1
|
- pkg/apis/extensions/install
|
||||||
- 1.5/pkg/apis/policy
|
- pkg/apis/extensions/v1beta1
|
||||||
- 1.5/pkg/apis/policy/install
|
- pkg/apis/policy
|
||||||
- 1.5/pkg/apis/policy/v1alpha1
|
- pkg/apis/policy/install
|
||||||
- 1.5/pkg/apis/rbac
|
- pkg/apis/policy/v1beta1
|
||||||
- 1.5/pkg/apis/rbac/install
|
- pkg/apis/rbac
|
||||||
- 1.5/pkg/apis/rbac/v1alpha1
|
- pkg/apis/rbac/install
|
||||||
- 1.5/pkg/apis/storage
|
- pkg/apis/rbac/v1alpha1
|
||||||
- 1.5/pkg/apis/storage/install
|
- pkg/apis/storage
|
||||||
- 1.5/pkg/apis/storage/v1beta1
|
- pkg/apis/storage/install
|
||||||
- 1.5/pkg/auth/user
|
- pkg/apis/storage/v1beta1
|
||||||
- 1.5/pkg/conversion
|
- pkg/auth/user
|
||||||
- 1.5/pkg/conversion/queryparams
|
- pkg/conversion
|
||||||
- 1.5/pkg/fields
|
- pkg/conversion/queryparams
|
||||||
- 1.5/pkg/genericapiserver/openapi/common
|
- pkg/fields
|
||||||
- 1.5/pkg/labels
|
- pkg/genericapiserver/openapi/common
|
||||||
- 1.5/pkg/runtime
|
- pkg/labels
|
||||||
- 1.5/pkg/runtime/serializer
|
- pkg/runtime
|
||||||
- 1.5/pkg/runtime/serializer/json
|
- pkg/runtime/serializer
|
||||||
- 1.5/pkg/runtime/serializer/protobuf
|
- pkg/runtime/serializer/json
|
||||||
- 1.5/pkg/runtime/serializer/recognizer
|
- pkg/runtime/serializer/protobuf
|
||||||
- 1.5/pkg/runtime/serializer/streaming
|
- pkg/runtime/serializer/recognizer
|
||||||
- 1.5/pkg/runtime/serializer/versioning
|
- pkg/runtime/serializer/streaming
|
||||||
- 1.5/pkg/selection
|
- pkg/runtime/serializer/versioning
|
||||||
- 1.5/pkg/third_party/forked/golang/reflect
|
- pkg/selection
|
||||||
- 1.5/pkg/types
|
- pkg/third_party/forked/golang/reflect
|
||||||
- 1.5/pkg/util
|
- pkg/third_party/forked/golang/template
|
||||||
- 1.5/pkg/util/cert
|
- pkg/types
|
||||||
- 1.5/pkg/util/clock
|
- pkg/util
|
||||||
- 1.5/pkg/util/errors
|
- pkg/util/cert
|
||||||
- 1.5/pkg/util/flowcontrol
|
- pkg/util/clock
|
||||||
- 1.5/pkg/util/framer
|
- pkg/util/diff
|
||||||
- 1.5/pkg/util/integer
|
- pkg/util/errors
|
||||||
- 1.5/pkg/util/intstr
|
- pkg/util/flowcontrol
|
||||||
- 1.5/pkg/util/json
|
- pkg/util/framer
|
||||||
- 1.5/pkg/util/labels
|
- pkg/util/integer
|
||||||
- 1.5/pkg/util/net
|
- pkg/util/intstr
|
||||||
- 1.5/pkg/util/parsers
|
- pkg/util/json
|
||||||
- 1.5/pkg/util/rand
|
- pkg/util/jsonpath
|
||||||
- 1.5/pkg/util/runtime
|
- pkg/util/labels
|
||||||
- 1.5/pkg/util/sets
|
- pkg/util/net
|
||||||
- 1.5/pkg/util/uuid
|
- pkg/util/parsers
|
||||||
- 1.5/pkg/util/validation
|
- pkg/util/rand
|
||||||
- 1.5/pkg/util/validation/field
|
- pkg/util/runtime
|
||||||
- 1.5/pkg/util/wait
|
- pkg/util/sets
|
||||||
- 1.5/pkg/util/yaml
|
- pkg/util/uuid
|
||||||
- 1.5/pkg/version
|
- pkg/util/validation
|
||||||
- 1.5/pkg/watch
|
- pkg/util/validation/field
|
||||||
- 1.5/pkg/watch/versioned
|
- pkg/util/wait
|
||||||
- 1.5/plugin/pkg/client/auth
|
- pkg/util/yaml
|
||||||
- 1.5/plugin/pkg/client/auth/gcp
|
- pkg/version
|
||||||
- 1.5/plugin/pkg/client/auth/oidc
|
- pkg/watch
|
||||||
- 1.5/rest
|
- pkg/watch/versioned
|
||||||
- 1.5/tools/cache
|
- plugin/pkg/client/auth
|
||||||
- 1.5/tools/clientcmd/api
|
- plugin/pkg/client/auth/gcp
|
||||||
- 1.5/tools/metrics
|
- plugin/pkg/client/auth/oidc
|
||||||
- 1.5/transport
|
- rest
|
||||||
|
- tools/cache
|
||||||
|
- tools/clientcmd/api
|
||||||
|
- tools/metrics
|
||||||
|
- transport
|
||||||
testImports: []
|
testImports: []
|
||||||
|
|
10
glide.yaml
10
glide.yaml
|
@ -89,7 +89,7 @@ import:
|
||||||
- package: github.com/satori/go.uuid
|
- package: github.com/satori/go.uuid
|
||||||
version: ^1.1.0
|
version: ^1.1.0
|
||||||
- package: k8s.io/client-go
|
- package: k8s.io/client-go
|
||||||
version: ^v1.5.0
|
version: v2.0.0
|
||||||
- package: github.com/gambol99/go-marathon
|
- package: github.com/gambol99/go-marathon
|
||||||
version: ^0.5.1
|
version: ^0.5.1
|
||||||
- package: github.com/ArthurHlt/go-eureka-client
|
- package: github.com/ArthurHlt/go-eureka-client
|
||||||
|
@ -131,7 +131,7 @@ import:
|
||||||
- service/ec2
|
- service/ec2
|
||||||
- service/ecs
|
- service/ecs
|
||||||
- package: cloud.google.com/go
|
- package: cloud.google.com/go
|
||||||
version: v0.6.0
|
version: v0.7.0
|
||||||
subpackages:
|
subpackages:
|
||||||
- compute/metadata
|
- compute/metadata
|
||||||
- package: github.com/gogo/protobuf
|
- package: github.com/gogo/protobuf
|
||||||
|
@ -140,3 +140,9 @@ import:
|
||||||
- proto
|
- proto
|
||||||
- package: github.com/rancher/go-rancher
|
- package: github.com/rancher/go-rancher
|
||||||
version: 2c43ff300f3eafcbd7d0b89b10427fc630efdc1e
|
version: 2c43ff300f3eafcbd7d0b89b10427fc630efdc1e
|
||||||
|
- package: golang.org/x/oauth2/google
|
||||||
|
version: 7fdf09982454086d5570c7db3e11f360194830ca
|
||||||
|
- package: github.com/googleapis/gax-go
|
||||||
|
version: 9af46dd5a1713e8b5cd71106287eba3cefdde50b
|
||||||
|
- package: google.golang.org/grpc
|
||||||
|
version: v1.2.0
|
||||||
|
|
|
@ -6,16 +6,16 @@ import (
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"k8s.io/client-go/1.5/kubernetes"
|
"k8s.io/client-go/kubernetes"
|
||||||
"k8s.io/client-go/1.5/pkg/api"
|
"k8s.io/client-go/pkg/api"
|
||||||
"k8s.io/client-go/1.5/pkg/api/v1"
|
"k8s.io/client-go/pkg/api/v1"
|
||||||
"k8s.io/client-go/1.5/pkg/apis/extensions/v1beta1"
|
"k8s.io/client-go/pkg/apis/extensions/v1beta1"
|
||||||
"k8s.io/client-go/1.5/pkg/fields"
|
"k8s.io/client-go/pkg/fields"
|
||||||
"k8s.io/client-go/1.5/pkg/labels"
|
"k8s.io/client-go/pkg/labels"
|
||||||
"k8s.io/client-go/1.5/pkg/runtime"
|
"k8s.io/client-go/pkg/runtime"
|
||||||
"k8s.io/client-go/1.5/pkg/watch"
|
"k8s.io/client-go/pkg/watch"
|
||||||
"k8s.io/client-go/1.5/rest"
|
"k8s.io/client-go/rest"
|
||||||
"k8s.io/client-go/1.5/tools/cache"
|
"k8s.io/client-go/tools/cache"
|
||||||
)
|
)
|
||||||
|
|
||||||
const resyncPeriod = time.Minute * 5
|
const resyncPeriod = time.Minute * 5
|
||||||
|
@ -111,7 +111,7 @@ func (c *clientImpl) GetIngresses(namespaces Namespaces) []*v1beta1.Ingress {
|
||||||
// WatchIngresses starts the watch of Kubernetes Ingresses resources and updates the corresponding store
|
// WatchIngresses starts the watch of Kubernetes Ingresses resources and updates the corresponding store
|
||||||
func (c *clientImpl) WatchIngresses(labelSelector labels.Selector, watchCh chan<- interface{}, stopCh <-chan struct{}) {
|
func (c *clientImpl) WatchIngresses(labelSelector labels.Selector, watchCh chan<- interface{}, stopCh <-chan struct{}) {
|
||||||
source := NewListWatchFromClient(
|
source := NewListWatchFromClient(
|
||||||
c.clientset.ExtensionsClient,
|
c.clientset.ExtensionsV1beta1().RESTClient(),
|
||||||
"ingresses",
|
"ingresses",
|
||||||
api.NamespaceAll,
|
api.NamespaceAll,
|
||||||
fields.Everything(),
|
fields.Everything(),
|
||||||
|
@ -157,7 +157,7 @@ func (c *clientImpl) GetService(namespace, name string) (*v1.Service, bool, erro
|
||||||
// WatchServices starts the watch of Kubernetes Service resources and updates the corresponding store
|
// WatchServices starts the watch of Kubernetes Service resources and updates the corresponding store
|
||||||
func (c *clientImpl) WatchServices(watchCh chan<- interface{}, stopCh <-chan struct{}) {
|
func (c *clientImpl) WatchServices(watchCh chan<- interface{}, stopCh <-chan struct{}) {
|
||||||
source := cache.NewListWatchFromClient(
|
source := cache.NewListWatchFromClient(
|
||||||
c.clientset.CoreClient,
|
c.clientset.CoreV1().RESTClient(),
|
||||||
"services",
|
"services",
|
||||||
api.NamespaceAll,
|
api.NamespaceAll,
|
||||||
fields.Everything())
|
fields.Everything())
|
||||||
|
@ -186,7 +186,7 @@ func (c *clientImpl) GetEndpoints(namespace, name string) (*v1.Endpoints, bool,
|
||||||
// WatchEndpoints starts the watch of Kubernetes Endpoints resources and updates the corresponding store
|
// WatchEndpoints starts the watch of Kubernetes Endpoints resources and updates the corresponding store
|
||||||
func (c *clientImpl) WatchEndpoints(watchCh chan<- interface{}, stopCh <-chan struct{}) {
|
func (c *clientImpl) WatchEndpoints(watchCh chan<- interface{}, stopCh <-chan struct{}) {
|
||||||
source := cache.NewListWatchFromClient(
|
source := cache.NewListWatchFromClient(
|
||||||
c.clientset.CoreClient,
|
c.clientset.CoreV1().RESTClient(),
|
||||||
"endpoints",
|
"endpoints",
|
||||||
api.NamespaceAll,
|
api.NamespaceAll,
|
||||||
fields.Everything())
|
fields.Everything())
|
||||||
|
|
|
@ -15,8 +15,8 @@ import (
|
||||||
"github.com/containous/traefik/provider/k8s"
|
"github.com/containous/traefik/provider/k8s"
|
||||||
"github.com/containous/traefik/safe"
|
"github.com/containous/traefik/safe"
|
||||||
"github.com/containous/traefik/types"
|
"github.com/containous/traefik/types"
|
||||||
"k8s.io/client-go/1.5/pkg/api/v1"
|
"k8s.io/client-go/pkg/api/v1"
|
||||||
"k8s.io/client-go/1.5/pkg/util/intstr"
|
"k8s.io/client-go/pkg/util/intstr"
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ Provider = (*Kubernetes)(nil)
|
var _ Provider = (*Kubernetes)(nil)
|
||||||
|
|
|
@ -9,9 +9,9 @@ import (
|
||||||
|
|
||||||
"github.com/containous/traefik/provider/k8s"
|
"github.com/containous/traefik/provider/k8s"
|
||||||
"github.com/containous/traefik/types"
|
"github.com/containous/traefik/types"
|
||||||
"k8s.io/client-go/1.5/pkg/api/v1"
|
"k8s.io/client-go/pkg/api/v1"
|
||||||
"k8s.io/client-go/1.5/pkg/apis/extensions/v1beta1"
|
"k8s.io/client-go/pkg/apis/extensions/v1beta1"
|
||||||
"k8s.io/client-go/1.5/pkg/util/intstr"
|
"k8s.io/client-go/pkg/util/intstr"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestLoadIngresses(t *testing.T) {
|
func TestLoadIngresses(t *testing.T) {
|
||||||
|
|
64
vendor/cloud.google.com/go/internal/cloud.go
generated
vendored
Normal file
64
vendor/cloud.google.com/go/internal/cloud.go
generated
vendored
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
// Copyright 2014 Google Inc. All Rights Reserved.
|
||||||
|
//
|
||||||
|
// 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
|
||||||
|
//
|
||||||
|
// http://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.
|
||||||
|
|
||||||
|
// Package internal provides support for the cloud packages.
|
||||||
|
//
|
||||||
|
// Users should not import this package directly.
|
||||||
|
package internal
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
const userAgent = "gcloud-golang/0.1"
|
||||||
|
|
||||||
|
// Transport is an http.RoundTripper that appends Google Cloud client's
|
||||||
|
// user-agent to the original request's user-agent header.
|
||||||
|
type Transport struct {
|
||||||
|
// TODO(bradfitz): delete internal.Transport. It's too wrappy for what it does.
|
||||||
|
// Do User-Agent some other way.
|
||||||
|
|
||||||
|
// Base is the actual http.RoundTripper
|
||||||
|
// requests will use. It must not be nil.
|
||||||
|
Base http.RoundTripper
|
||||||
|
}
|
||||||
|
|
||||||
|
// RoundTrip appends a user-agent to the existing user-agent
|
||||||
|
// header and delegates the request to the base http.RoundTripper.
|
||||||
|
func (t *Transport) RoundTrip(req *http.Request) (*http.Response, error) {
|
||||||
|
req = cloneRequest(req)
|
||||||
|
ua := req.Header.Get("User-Agent")
|
||||||
|
if ua == "" {
|
||||||
|
ua = userAgent
|
||||||
|
} else {
|
||||||
|
ua = fmt.Sprintf("%s %s", ua, userAgent)
|
||||||
|
}
|
||||||
|
req.Header.Set("User-Agent", ua)
|
||||||
|
return t.Base.RoundTrip(req)
|
||||||
|
}
|
||||||
|
|
||||||
|
// cloneRequest returns a clone of the provided *http.Request.
|
||||||
|
// The clone is a shallow copy of the struct and its Header map.
|
||||||
|
func cloneRequest(r *http.Request) *http.Request {
|
||||||
|
// shallow copy of the struct
|
||||||
|
r2 := new(http.Request)
|
||||||
|
*r2 = *r
|
||||||
|
// deep copy of the Header
|
||||||
|
r2.Header = make(http.Header)
|
||||||
|
for k, s := range r.Header {
|
||||||
|
r2.Header[k] = s
|
||||||
|
}
|
||||||
|
return r2
|
||||||
|
}
|
55
vendor/cloud.google.com/go/internal/retry.go
generated
vendored
Normal file
55
vendor/cloud.google.com/go/internal/retry.go
generated
vendored
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
// Copyright 2016 Google Inc. All Rights Reserved.
|
||||||
|
//
|
||||||
|
// 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
|
||||||
|
//
|
||||||
|
// http://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.
|
||||||
|
|
||||||
|
package internal
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
gax "github.com/googleapis/gax-go"
|
||||||
|
|
||||||
|
"golang.org/x/net/context"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Retry calls the supplied function f repeatedly according to the provided
|
||||||
|
// backoff parameters. It returns when one of the following occurs:
|
||||||
|
// When f's first return value is true, Retry immediately returns with f's second
|
||||||
|
// return value.
|
||||||
|
// When the provided context is done, Retry returns with ctx.Err().
|
||||||
|
func Retry(ctx context.Context, bo gax.Backoff, f func() (stop bool, err error)) error {
|
||||||
|
return retry(ctx, bo, f, gax.Sleep)
|
||||||
|
}
|
||||||
|
|
||||||
|
func retry(ctx context.Context, bo gax.Backoff, f func() (stop bool, err error),
|
||||||
|
sleep func(context.Context, time.Duration) error) error {
|
||||||
|
var lastErr error
|
||||||
|
for {
|
||||||
|
stop, err := f()
|
||||||
|
if stop {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// Remember the last "real" error from f.
|
||||||
|
if err != nil && err != context.Canceled && err != context.DeadlineExceeded {
|
||||||
|
lastErr = err
|
||||||
|
}
|
||||||
|
p := bo.Pause()
|
||||||
|
if cerr := sleep(ctx, p); cerr != nil {
|
||||||
|
if lastErr != nil {
|
||||||
|
return fmt.Errorf("%v; last function err: %v", cerr, lastErr)
|
||||||
|
}
|
||||||
|
return cerr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
106
vendor/github.com/coreos/pkg/capnslog/formatters.go
generated
vendored
106
vendor/github.com/coreos/pkg/capnslog/formatters.go
generated
vendored
|
@ -1,106 +0,0 @@
|
||||||
// Copyright 2015 CoreOS, 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
|
|
||||||
//
|
|
||||||
// http://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.
|
|
||||||
|
|
||||||
package capnslog
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bufio"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"runtime"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Formatter interface {
|
|
||||||
Format(pkg string, level LogLevel, depth int, entries ...interface{})
|
|
||||||
Flush()
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewStringFormatter(w io.Writer) *StringFormatter {
|
|
||||||
return &StringFormatter{
|
|
||||||
w: bufio.NewWriter(w),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type StringFormatter struct {
|
|
||||||
w *bufio.Writer
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *StringFormatter) Format(pkg string, l LogLevel, i int, entries ...interface{}) {
|
|
||||||
now := time.Now().UTC()
|
|
||||||
s.w.WriteString(now.Format(time.RFC3339))
|
|
||||||
s.w.WriteByte(' ')
|
|
||||||
writeEntries(s.w, pkg, l, i, entries...)
|
|
||||||
s.Flush()
|
|
||||||
}
|
|
||||||
|
|
||||||
func writeEntries(w *bufio.Writer, pkg string, _ LogLevel, _ int, entries ...interface{}) {
|
|
||||||
if pkg != "" {
|
|
||||||
w.WriteString(pkg + ": ")
|
|
||||||
}
|
|
||||||
str := fmt.Sprint(entries...)
|
|
||||||
endsInNL := strings.HasSuffix(str, "\n")
|
|
||||||
w.WriteString(str)
|
|
||||||
if !endsInNL {
|
|
||||||
w.WriteString("\n")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *StringFormatter) Flush() {
|
|
||||||
s.w.Flush()
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewPrettyFormatter(w io.Writer, debug bool) Formatter {
|
|
||||||
return &PrettyFormatter{
|
|
||||||
w: bufio.NewWriter(w),
|
|
||||||
debug: debug,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type PrettyFormatter struct {
|
|
||||||
w *bufio.Writer
|
|
||||||
debug bool
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *PrettyFormatter) Format(pkg string, l LogLevel, depth int, entries ...interface{}) {
|
|
||||||
now := time.Now()
|
|
||||||
ts := now.Format("2006-01-02 15:04:05")
|
|
||||||
c.w.WriteString(ts)
|
|
||||||
ms := now.Nanosecond() / 1000
|
|
||||||
c.w.WriteString(fmt.Sprintf(".%06d", ms))
|
|
||||||
if c.debug {
|
|
||||||
_, file, line, ok := runtime.Caller(depth) // It's always the same number of frames to the user's call.
|
|
||||||
if !ok {
|
|
||||||
file = "???"
|
|
||||||
line = 1
|
|
||||||
} else {
|
|
||||||
slash := strings.LastIndex(file, "/")
|
|
||||||
if slash >= 0 {
|
|
||||||
file = file[slash+1:]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if line < 0 {
|
|
||||||
line = 0 // not a real line number
|
|
||||||
}
|
|
||||||
c.w.WriteString(fmt.Sprintf(" [%s:%d]", file, line))
|
|
||||||
}
|
|
||||||
c.w.WriteString(fmt.Sprint(" ", l.Char(), " | "))
|
|
||||||
writeEntries(c.w, pkg, l, depth, entries...)
|
|
||||||
c.Flush()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *PrettyFormatter) Flush() {
|
|
||||||
c.w.Flush()
|
|
||||||
}
|
|
96
vendor/github.com/coreos/pkg/capnslog/glog_formatter.go
generated
vendored
96
vendor/github.com/coreos/pkg/capnslog/glog_formatter.go
generated
vendored
|
@ -1,96 +0,0 @@
|
||||||
// Copyright 2015 CoreOS, 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
|
|
||||||
//
|
|
||||||
// http://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.
|
|
||||||
|
|
||||||
package capnslog
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bufio"
|
|
||||||
"bytes"
|
|
||||||
"io"
|
|
||||||
"os"
|
|
||||||
"runtime"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
var pid = os.Getpid()
|
|
||||||
|
|
||||||
type GlogFormatter struct {
|
|
||||||
StringFormatter
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewGlogFormatter(w io.Writer) *GlogFormatter {
|
|
||||||
g := &GlogFormatter{}
|
|
||||||
g.w = bufio.NewWriter(w)
|
|
||||||
return g
|
|
||||||
}
|
|
||||||
|
|
||||||
func (g GlogFormatter) Format(pkg string, level LogLevel, depth int, entries ...interface{}) {
|
|
||||||
g.w.Write(GlogHeader(level, depth+1))
|
|
||||||
g.StringFormatter.Format(pkg, level, depth+1, entries...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func GlogHeader(level LogLevel, depth int) []byte {
|
|
||||||
// Lmmdd hh:mm:ss.uuuuuu threadid file:line]
|
|
||||||
now := time.Now().UTC()
|
|
||||||
_, file, line, ok := runtime.Caller(depth) // It's always the same number of frames to the user's call.
|
|
||||||
if !ok {
|
|
||||||
file = "???"
|
|
||||||
line = 1
|
|
||||||
} else {
|
|
||||||
slash := strings.LastIndex(file, "/")
|
|
||||||
if slash >= 0 {
|
|
||||||
file = file[slash+1:]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if line < 0 {
|
|
||||||
line = 0 // not a real line number
|
|
||||||
}
|
|
||||||
buf := &bytes.Buffer{}
|
|
||||||
buf.Grow(30)
|
|
||||||
_, month, day := now.Date()
|
|
||||||
hour, minute, second := now.Clock()
|
|
||||||
buf.WriteString(level.Char())
|
|
||||||
twoDigits(buf, int(month))
|
|
||||||
twoDigits(buf, day)
|
|
||||||
buf.WriteByte(' ')
|
|
||||||
twoDigits(buf, hour)
|
|
||||||
buf.WriteByte(':')
|
|
||||||
twoDigits(buf, minute)
|
|
||||||
buf.WriteByte(':')
|
|
||||||
twoDigits(buf, second)
|
|
||||||
buf.WriteByte('.')
|
|
||||||
buf.WriteString(strconv.Itoa(now.Nanosecond() / 1000))
|
|
||||||
buf.WriteByte('Z')
|
|
||||||
buf.WriteByte(' ')
|
|
||||||
buf.WriteString(strconv.Itoa(pid))
|
|
||||||
buf.WriteByte(' ')
|
|
||||||
buf.WriteString(file)
|
|
||||||
buf.WriteByte(':')
|
|
||||||
buf.WriteString(strconv.Itoa(line))
|
|
||||||
buf.WriteByte(']')
|
|
||||||
buf.WriteByte(' ')
|
|
||||||
return buf.Bytes()
|
|
||||||
}
|
|
||||||
|
|
||||||
const digits = "0123456789"
|
|
||||||
|
|
||||||
func twoDigits(b *bytes.Buffer, d int) {
|
|
||||||
c2 := digits[d%10]
|
|
||||||
d /= 10
|
|
||||||
c1 := digits[d%10]
|
|
||||||
b.WriteByte(c1)
|
|
||||||
b.WriteByte(c2)
|
|
||||||
}
|
|
49
vendor/github.com/coreos/pkg/capnslog/init.go
generated
vendored
49
vendor/github.com/coreos/pkg/capnslog/init.go
generated
vendored
|
@ -1,49 +0,0 @@
|
||||||
// Copyright 2015 CoreOS, 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
|
|
||||||
//
|
|
||||||
// http://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.
|
|
||||||
//
|
|
||||||
// +build !windows
|
|
||||||
|
|
||||||
package capnslog
|
|
||||||
|
|
||||||
import (
|
|
||||||
"io"
|
|
||||||
"os"
|
|
||||||
"syscall"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Here's where the opinionation comes in. We need some sensible defaults,
|
|
||||||
// especially after taking over the log package. Your project (whatever it may
|
|
||||||
// be) may see things differently. That's okay; there should be no defaults in
|
|
||||||
// the main package that cannot be controlled or overridden programatically,
|
|
||||||
// otherwise it's a bug. Doing so is creating your own init_log.go file much
|
|
||||||
// like this one.
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
initHijack()
|
|
||||||
|
|
||||||
// Go `log` pacakge uses os.Stderr.
|
|
||||||
SetFormatter(NewDefaultFormatter(os.Stderr))
|
|
||||||
SetGlobalLogLevel(INFO)
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewDefaultFormatter(out io.Writer) Formatter {
|
|
||||||
if syscall.Getppid() == 1 {
|
|
||||||
// We're running under init, which may be systemd.
|
|
||||||
f, err := NewJournaldFormatter()
|
|
||||||
if err == nil {
|
|
||||||
return f
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return NewPrettyFormatter(out, false)
|
|
||||||
}
|
|
25
vendor/github.com/coreos/pkg/capnslog/init_windows.go
generated
vendored
25
vendor/github.com/coreos/pkg/capnslog/init_windows.go
generated
vendored
|
@ -1,25 +0,0 @@
|
||||||
// Copyright 2015 CoreOS, 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
|
|
||||||
//
|
|
||||||
// http://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.
|
|
||||||
|
|
||||||
package capnslog
|
|
||||||
|
|
||||||
import "os"
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
initHijack()
|
|
||||||
|
|
||||||
// Go `log` package uses os.Stderr.
|
|
||||||
SetFormatter(NewPrettyFormatter(os.Stderr, false))
|
|
||||||
SetGlobalLogLevel(INFO)
|
|
||||||
}
|
|
68
vendor/github.com/coreos/pkg/capnslog/journald_formatter.go
generated
vendored
68
vendor/github.com/coreos/pkg/capnslog/journald_formatter.go
generated
vendored
|
@ -1,68 +0,0 @@
|
||||||
// Copyright 2015 CoreOS, 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
|
|
||||||
//
|
|
||||||
// http://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.
|
|
||||||
//
|
|
||||||
// +build !windows
|
|
||||||
|
|
||||||
package capnslog
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
"path/filepath"
|
|
||||||
|
|
||||||
"github.com/coreos/go-systemd/journal"
|
|
||||||
)
|
|
||||||
|
|
||||||
func NewJournaldFormatter() (Formatter, error) {
|
|
||||||
if !journal.Enabled() {
|
|
||||||
return nil, errors.New("No systemd detected")
|
|
||||||
}
|
|
||||||
return &journaldFormatter{}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type journaldFormatter struct{}
|
|
||||||
|
|
||||||
func (j *journaldFormatter) Format(pkg string, l LogLevel, _ int, entries ...interface{}) {
|
|
||||||
var pri journal.Priority
|
|
||||||
switch l {
|
|
||||||
case CRITICAL:
|
|
||||||
pri = journal.PriCrit
|
|
||||||
case ERROR:
|
|
||||||
pri = journal.PriErr
|
|
||||||
case WARNING:
|
|
||||||
pri = journal.PriWarning
|
|
||||||
case NOTICE:
|
|
||||||
pri = journal.PriNotice
|
|
||||||
case INFO:
|
|
||||||
pri = journal.PriInfo
|
|
||||||
case DEBUG:
|
|
||||||
pri = journal.PriDebug
|
|
||||||
case TRACE:
|
|
||||||
pri = journal.PriDebug
|
|
||||||
default:
|
|
||||||
panic("Unhandled loglevel")
|
|
||||||
}
|
|
||||||
msg := fmt.Sprint(entries...)
|
|
||||||
tags := map[string]string{
|
|
||||||
"PACKAGE": pkg,
|
|
||||||
"SYSLOG_IDENTIFIER": filepath.Base(os.Args[0]),
|
|
||||||
}
|
|
||||||
err := journal.Send(msg, pri, tags)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintln(os.Stderr, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (j *journaldFormatter) Flush() {}
|
|
39
vendor/github.com/coreos/pkg/capnslog/log_hijack.go
generated
vendored
39
vendor/github.com/coreos/pkg/capnslog/log_hijack.go
generated
vendored
|
@ -1,39 +0,0 @@
|
||||||
// Copyright 2015 CoreOS, 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
|
|
||||||
//
|
|
||||||
// http://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.
|
|
||||||
|
|
||||||
package capnslog
|
|
||||||
|
|
||||||
import (
|
|
||||||
"log"
|
|
||||||
)
|
|
||||||
|
|
||||||
func initHijack() {
|
|
||||||
pkg := NewPackageLogger("log", "")
|
|
||||||
w := packageWriter{pkg}
|
|
||||||
log.SetFlags(0)
|
|
||||||
log.SetPrefix("")
|
|
||||||
log.SetOutput(w)
|
|
||||||
}
|
|
||||||
|
|
||||||
type packageWriter struct {
|
|
||||||
pl *PackageLogger
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p packageWriter) Write(b []byte) (int, error) {
|
|
||||||
if p.pl.level < INFO {
|
|
||||||
return 0, nil
|
|
||||||
}
|
|
||||||
p.pl.internalLog(calldepth+2, INFO, string(b))
|
|
||||||
return len(b), nil
|
|
||||||
}
|
|
240
vendor/github.com/coreos/pkg/capnslog/logmap.go
generated
vendored
240
vendor/github.com/coreos/pkg/capnslog/logmap.go
generated
vendored
|
@ -1,240 +0,0 @@
|
||||||
// Copyright 2015 CoreOS, 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
|
|
||||||
//
|
|
||||||
// http://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.
|
|
||||||
|
|
||||||
package capnslog
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"strings"
|
|
||||||
"sync"
|
|
||||||
)
|
|
||||||
|
|
||||||
// LogLevel is the set of all log levels.
|
|
||||||
type LogLevel int8
|
|
||||||
|
|
||||||
const (
|
|
||||||
// CRITICAL is the lowest log level; only errors which will end the program will be propagated.
|
|
||||||
CRITICAL LogLevel = iota - 1
|
|
||||||
// ERROR is for errors that are not fatal but lead to troubling behavior.
|
|
||||||
ERROR
|
|
||||||
// WARNING is for errors which are not fatal and not errors, but are unusual. Often sourced from misconfigurations.
|
|
||||||
WARNING
|
|
||||||
// NOTICE is for normal but significant conditions.
|
|
||||||
NOTICE
|
|
||||||
// INFO is a log level for common, everyday log updates.
|
|
||||||
INFO
|
|
||||||
// DEBUG is the default hidden level for more verbose updates about internal processes.
|
|
||||||
DEBUG
|
|
||||||
// TRACE is for (potentially) call by call tracing of programs.
|
|
||||||
TRACE
|
|
||||||
)
|
|
||||||
|
|
||||||
// Char returns a single-character representation of the log level.
|
|
||||||
func (l LogLevel) Char() string {
|
|
||||||
switch l {
|
|
||||||
case CRITICAL:
|
|
||||||
return "C"
|
|
||||||
case ERROR:
|
|
||||||
return "E"
|
|
||||||
case WARNING:
|
|
||||||
return "W"
|
|
||||||
case NOTICE:
|
|
||||||
return "N"
|
|
||||||
case INFO:
|
|
||||||
return "I"
|
|
||||||
case DEBUG:
|
|
||||||
return "D"
|
|
||||||
case TRACE:
|
|
||||||
return "T"
|
|
||||||
default:
|
|
||||||
panic("Unhandled loglevel")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// String returns a multi-character representation of the log level.
|
|
||||||
func (l LogLevel) String() string {
|
|
||||||
switch l {
|
|
||||||
case CRITICAL:
|
|
||||||
return "CRITICAL"
|
|
||||||
case ERROR:
|
|
||||||
return "ERROR"
|
|
||||||
case WARNING:
|
|
||||||
return "WARNING"
|
|
||||||
case NOTICE:
|
|
||||||
return "NOTICE"
|
|
||||||
case INFO:
|
|
||||||
return "INFO"
|
|
||||||
case DEBUG:
|
|
||||||
return "DEBUG"
|
|
||||||
case TRACE:
|
|
||||||
return "TRACE"
|
|
||||||
default:
|
|
||||||
panic("Unhandled loglevel")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update using the given string value. Fulfills the flag.Value interface.
|
|
||||||
func (l *LogLevel) Set(s string) error {
|
|
||||||
value, err := ParseLevel(s)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
*l = value
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ParseLevel translates some potential loglevel strings into their corresponding levels.
|
|
||||||
func ParseLevel(s string) (LogLevel, error) {
|
|
||||||
switch s {
|
|
||||||
case "CRITICAL", "C":
|
|
||||||
return CRITICAL, nil
|
|
||||||
case "ERROR", "0", "E":
|
|
||||||
return ERROR, nil
|
|
||||||
case "WARNING", "1", "W":
|
|
||||||
return WARNING, nil
|
|
||||||
case "NOTICE", "2", "N":
|
|
||||||
return NOTICE, nil
|
|
||||||
case "INFO", "3", "I":
|
|
||||||
return INFO, nil
|
|
||||||
case "DEBUG", "4", "D":
|
|
||||||
return DEBUG, nil
|
|
||||||
case "TRACE", "5", "T":
|
|
||||||
return TRACE, nil
|
|
||||||
}
|
|
||||||
return CRITICAL, errors.New("couldn't parse log level " + s)
|
|
||||||
}
|
|
||||||
|
|
||||||
type RepoLogger map[string]*PackageLogger
|
|
||||||
|
|
||||||
type loggerStruct struct {
|
|
||||||
sync.Mutex
|
|
||||||
repoMap map[string]RepoLogger
|
|
||||||
formatter Formatter
|
|
||||||
}
|
|
||||||
|
|
||||||
// logger is the global logger
|
|
||||||
var logger = new(loggerStruct)
|
|
||||||
|
|
||||||
// SetGlobalLogLevel sets the log level for all packages in all repositories
|
|
||||||
// registered with capnslog.
|
|
||||||
func SetGlobalLogLevel(l LogLevel) {
|
|
||||||
logger.Lock()
|
|
||||||
defer logger.Unlock()
|
|
||||||
for _, r := range logger.repoMap {
|
|
||||||
r.setRepoLogLevelInternal(l)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetRepoLogger may return the handle to the repository's set of packages' loggers.
|
|
||||||
func GetRepoLogger(repo string) (RepoLogger, error) {
|
|
||||||
logger.Lock()
|
|
||||||
defer logger.Unlock()
|
|
||||||
r, ok := logger.repoMap[repo]
|
|
||||||
if !ok {
|
|
||||||
return nil, errors.New("no packages registered for repo " + repo)
|
|
||||||
}
|
|
||||||
return r, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// MustRepoLogger returns the handle to the repository's packages' loggers.
|
|
||||||
func MustRepoLogger(repo string) RepoLogger {
|
|
||||||
r, err := GetRepoLogger(repo)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
return r
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetRepoLogLevel sets the log level for all packages in the repository.
|
|
||||||
func (r RepoLogger) SetRepoLogLevel(l LogLevel) {
|
|
||||||
logger.Lock()
|
|
||||||
defer logger.Unlock()
|
|
||||||
r.setRepoLogLevelInternal(l)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r RepoLogger) setRepoLogLevelInternal(l LogLevel) {
|
|
||||||
for _, v := range r {
|
|
||||||
v.level = l
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ParseLogLevelConfig parses a comma-separated string of "package=loglevel", in
|
|
||||||
// order, and returns a map of the results, for use in SetLogLevel.
|
|
||||||
func (r RepoLogger) ParseLogLevelConfig(conf string) (map[string]LogLevel, error) {
|
|
||||||
setlist := strings.Split(conf, ",")
|
|
||||||
out := make(map[string]LogLevel)
|
|
||||||
for _, setstring := range setlist {
|
|
||||||
setting := strings.Split(setstring, "=")
|
|
||||||
if len(setting) != 2 {
|
|
||||||
return nil, errors.New("oddly structured `pkg=level` option: " + setstring)
|
|
||||||
}
|
|
||||||
l, err := ParseLevel(setting[1])
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
out[setting[0]] = l
|
|
||||||
}
|
|
||||||
return out, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetLogLevel takes a map of package names within a repository to their desired
|
|
||||||
// loglevel, and sets the levels appropriately. Unknown packages are ignored.
|
|
||||||
// "*" is a special package name that corresponds to all packages, and will be
|
|
||||||
// processed first.
|
|
||||||
func (r RepoLogger) SetLogLevel(m map[string]LogLevel) {
|
|
||||||
logger.Lock()
|
|
||||||
defer logger.Unlock()
|
|
||||||
if l, ok := m["*"]; ok {
|
|
||||||
r.setRepoLogLevelInternal(l)
|
|
||||||
}
|
|
||||||
for k, v := range m {
|
|
||||||
l, ok := r[k]
|
|
||||||
if !ok {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
l.level = v
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetFormatter sets the formatting function for all logs.
|
|
||||||
func SetFormatter(f Formatter) {
|
|
||||||
logger.Lock()
|
|
||||||
defer logger.Unlock()
|
|
||||||
logger.formatter = f
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewPackageLogger creates a package logger object.
|
|
||||||
// This should be defined as a global var in your package, referencing your repo.
|
|
||||||
func NewPackageLogger(repo string, pkg string) (p *PackageLogger) {
|
|
||||||
logger.Lock()
|
|
||||||
defer logger.Unlock()
|
|
||||||
if logger.repoMap == nil {
|
|
||||||
logger.repoMap = make(map[string]RepoLogger)
|
|
||||||
}
|
|
||||||
r, rok := logger.repoMap[repo]
|
|
||||||
if !rok {
|
|
||||||
logger.repoMap[repo] = make(RepoLogger)
|
|
||||||
r = logger.repoMap[repo]
|
|
||||||
}
|
|
||||||
p, pok := r[pkg]
|
|
||||||
if !pok {
|
|
||||||
r[pkg] = &PackageLogger{
|
|
||||||
pkg: pkg,
|
|
||||||
level: INFO,
|
|
||||||
}
|
|
||||||
p = r[pkg]
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
158
vendor/github.com/coreos/pkg/capnslog/pkg_logger.go
generated
vendored
158
vendor/github.com/coreos/pkg/capnslog/pkg_logger.go
generated
vendored
|
@ -1,158 +0,0 @@
|
||||||
// Copyright 2015 CoreOS, 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
|
|
||||||
//
|
|
||||||
// http://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.
|
|
||||||
|
|
||||||
package capnslog
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
)
|
|
||||||
|
|
||||||
type PackageLogger struct {
|
|
||||||
pkg string
|
|
||||||
level LogLevel
|
|
||||||
}
|
|
||||||
|
|
||||||
const calldepth = 2
|
|
||||||
|
|
||||||
func (p *PackageLogger) internalLog(depth int, inLevel LogLevel, entries ...interface{}) {
|
|
||||||
if inLevel != CRITICAL && p.level < inLevel {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
logger.Lock()
|
|
||||||
defer logger.Unlock()
|
|
||||||
if logger.formatter != nil {
|
|
||||||
logger.formatter.Format(p.pkg, inLevel, depth+1, entries...)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *PackageLogger) LevelAt(l LogLevel) bool {
|
|
||||||
return p.level >= l
|
|
||||||
}
|
|
||||||
|
|
||||||
// Log a formatted string at any level between ERROR and TRACE
|
|
||||||
func (p *PackageLogger) Logf(l LogLevel, format string, args ...interface{}) {
|
|
||||||
p.internalLog(calldepth, l, fmt.Sprintf(format, args...))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Log a message at any level between ERROR and TRACE
|
|
||||||
func (p *PackageLogger) Log(l LogLevel, args ...interface{}) {
|
|
||||||
p.internalLog(calldepth, l, fmt.Sprint(args...))
|
|
||||||
}
|
|
||||||
|
|
||||||
// log stdlib compatibility
|
|
||||||
|
|
||||||
func (p *PackageLogger) Println(args ...interface{}) {
|
|
||||||
p.internalLog(calldepth, INFO, fmt.Sprintln(args...))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *PackageLogger) Printf(format string, args ...interface{}) {
|
|
||||||
p.internalLog(calldepth, INFO, fmt.Sprintf(format, args...))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *PackageLogger) Print(args ...interface{}) {
|
|
||||||
p.internalLog(calldepth, INFO, fmt.Sprint(args...))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Panic and fatal
|
|
||||||
|
|
||||||
func (p *PackageLogger) Panicf(format string, args ...interface{}) {
|
|
||||||
s := fmt.Sprintf(format, args...)
|
|
||||||
p.internalLog(calldepth, CRITICAL, s)
|
|
||||||
panic(s)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *PackageLogger) Panic(args ...interface{}) {
|
|
||||||
s := fmt.Sprint(args...)
|
|
||||||
p.internalLog(calldepth, CRITICAL, s)
|
|
||||||
panic(s)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *PackageLogger) Fatalf(format string, args ...interface{}) {
|
|
||||||
s := fmt.Sprintf(format, args...)
|
|
||||||
p.internalLog(calldepth, CRITICAL, s)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *PackageLogger) Fatal(args ...interface{}) {
|
|
||||||
s := fmt.Sprint(args...)
|
|
||||||
p.internalLog(calldepth, CRITICAL, s)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Error Functions
|
|
||||||
|
|
||||||
func (p *PackageLogger) Errorf(format string, args ...interface{}) {
|
|
||||||
p.internalLog(calldepth, ERROR, fmt.Sprintf(format, args...))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *PackageLogger) Error(entries ...interface{}) {
|
|
||||||
p.internalLog(calldepth, ERROR, entries...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Warning Functions
|
|
||||||
|
|
||||||
func (p *PackageLogger) Warningf(format string, args ...interface{}) {
|
|
||||||
p.internalLog(calldepth, WARNING, fmt.Sprintf(format, args...))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *PackageLogger) Warning(entries ...interface{}) {
|
|
||||||
p.internalLog(calldepth, WARNING, entries...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Notice Functions
|
|
||||||
|
|
||||||
func (p *PackageLogger) Noticef(format string, args ...interface{}) {
|
|
||||||
p.internalLog(calldepth, NOTICE, fmt.Sprintf(format, args...))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *PackageLogger) Notice(entries ...interface{}) {
|
|
||||||
p.internalLog(calldepth, NOTICE, entries...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Info Functions
|
|
||||||
|
|
||||||
func (p *PackageLogger) Infof(format string, args ...interface{}) {
|
|
||||||
p.internalLog(calldepth, INFO, fmt.Sprintf(format, args...))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *PackageLogger) Info(entries ...interface{}) {
|
|
||||||
p.internalLog(calldepth, INFO, entries...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Debug Functions
|
|
||||||
|
|
||||||
func (p *PackageLogger) Debugf(format string, args ...interface{}) {
|
|
||||||
p.internalLog(calldepth, DEBUG, fmt.Sprintf(format, args...))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *PackageLogger) Debug(entries ...interface{}) {
|
|
||||||
p.internalLog(calldepth, DEBUG, entries...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Trace Functions
|
|
||||||
|
|
||||||
func (p *PackageLogger) Tracef(format string, args ...interface{}) {
|
|
||||||
p.internalLog(calldepth, TRACE, fmt.Sprintf(format, args...))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *PackageLogger) Trace(entries ...interface{}) {
|
|
||||||
p.internalLog(calldepth, TRACE, entries...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *PackageLogger) Flush() {
|
|
||||||
logger.Lock()
|
|
||||||
defer logger.Unlock()
|
|
||||||
logger.formatter.Flush()
|
|
||||||
}
|
|
65
vendor/github.com/coreos/pkg/capnslog/syslog_formatter.go
generated
vendored
65
vendor/github.com/coreos/pkg/capnslog/syslog_formatter.go
generated
vendored
|
@ -1,65 +0,0 @@
|
||||||
// Copyright 2015 CoreOS, 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
|
|
||||||
//
|
|
||||||
// http://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.
|
|
||||||
//
|
|
||||||
// +build !windows
|
|
||||||
|
|
||||||
package capnslog
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"log/syslog"
|
|
||||||
)
|
|
||||||
|
|
||||||
func NewSyslogFormatter(w *syslog.Writer) Formatter {
|
|
||||||
return &syslogFormatter{w}
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewDefaultSyslogFormatter(tag string) (Formatter, error) {
|
|
||||||
w, err := syslog.New(syslog.LOG_DEBUG, tag)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return NewSyslogFormatter(w), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type syslogFormatter struct {
|
|
||||||
w *syslog.Writer
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *syslogFormatter) Format(pkg string, l LogLevel, _ int, entries ...interface{}) {
|
|
||||||
for _, entry := range entries {
|
|
||||||
str := fmt.Sprint(entry)
|
|
||||||
switch l {
|
|
||||||
case CRITICAL:
|
|
||||||
s.w.Crit(str)
|
|
||||||
case ERROR:
|
|
||||||
s.w.Err(str)
|
|
||||||
case WARNING:
|
|
||||||
s.w.Warning(str)
|
|
||||||
case NOTICE:
|
|
||||||
s.w.Notice(str)
|
|
||||||
case INFO:
|
|
||||||
s.w.Info(str)
|
|
||||||
case DEBUG:
|
|
||||||
s.w.Debug(str)
|
|
||||||
case TRACE:
|
|
||||||
s.w.Debug(str)
|
|
||||||
default:
|
|
||||||
panic("Unhandled loglevel")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *syslogFormatter) Flush() {
|
|
||||||
}
|
|
27
vendor/github.com/googleapis/gax-go/LICENSE
generated
vendored
Normal file
27
vendor/github.com/googleapis/gax-go/LICENSE
generated
vendored
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
Copyright 2016, Google Inc.
|
||||||
|
All rights reserved.
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are
|
||||||
|
met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
copyright notice, this list of conditions and the following disclaimer
|
||||||
|
in the documentation and/or other materials provided with the
|
||||||
|
distribution.
|
||||||
|
* Neither the name of Google Inc. nor the names of its
|
||||||
|
contributors may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
149
vendor/github.com/googleapis/gax-go/call_option.go
generated
vendored
Normal file
149
vendor/github.com/googleapis/gax-go/call_option.go
generated
vendored
Normal file
|
@ -0,0 +1,149 @@
|
||||||
|
// Copyright 2016, Google Inc.
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
package gax
|
||||||
|
|
||||||
|
import (
|
||||||
|
"math/rand"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"google.golang.org/grpc"
|
||||||
|
"google.golang.org/grpc/codes"
|
||||||
|
)
|
||||||
|
|
||||||
|
// CallOption is an option used by Invoke to control behaviors of RPC calls.
|
||||||
|
// CallOption works by modifying relevant fields of CallSettings.
|
||||||
|
type CallOption interface {
|
||||||
|
// Resolve applies the option by modifying cs.
|
||||||
|
Resolve(cs *CallSettings)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Retryer is used by Invoke to determine retry behavior.
|
||||||
|
type Retryer interface {
|
||||||
|
// Retry reports whether a request should be retriedand how long to pause before retrying
|
||||||
|
// if the previous attempt returned with err. Invoke never calls Retry with nil error.
|
||||||
|
Retry(err error) (pause time.Duration, shouldRetry bool)
|
||||||
|
}
|
||||||
|
|
||||||
|
type retryerOption func() Retryer
|
||||||
|
|
||||||
|
func (o retryerOption) Resolve(s *CallSettings) {
|
||||||
|
s.Retry = o
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithRetry sets CallSettings.Retry to fn.
|
||||||
|
func WithRetry(fn func() Retryer) CallOption {
|
||||||
|
return retryerOption(fn)
|
||||||
|
}
|
||||||
|
|
||||||
|
// OnCodes returns a Retryer that retries if and only if
|
||||||
|
// the previous attempt returns a GRPC error whose error code is stored in cc.
|
||||||
|
// Pause times between retries are specified by bo.
|
||||||
|
//
|
||||||
|
// bo is only used for its parameters; each Retryer has its own copy.
|
||||||
|
func OnCodes(cc []codes.Code, bo Backoff) Retryer {
|
||||||
|
return &boRetryer{
|
||||||
|
backoff: bo,
|
||||||
|
codes: append([]codes.Code(nil), cc...),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type boRetryer struct {
|
||||||
|
backoff Backoff
|
||||||
|
codes []codes.Code
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *boRetryer) Retry(err error) (time.Duration, bool) {
|
||||||
|
c := grpc.Code(err)
|
||||||
|
for _, rc := range r.codes {
|
||||||
|
if c == rc {
|
||||||
|
return r.backoff.Pause(), true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0, false
|
||||||
|
}
|
||||||
|
|
||||||
|
// Backoff implements exponential backoff.
|
||||||
|
// The wait time between retries is a random value between 0 and the "retry envelope".
|
||||||
|
// The envelope starts at Initial and increases by the factor of Multiplier every retry,
|
||||||
|
// but is capped at Max.
|
||||||
|
type Backoff struct {
|
||||||
|
// Initial is the initial value of the retry envelope, defaults to 1 second.
|
||||||
|
Initial time.Duration
|
||||||
|
|
||||||
|
// Max is the maximum value of the retry envelope, defaults to 30 seconds.
|
||||||
|
Max time.Duration
|
||||||
|
|
||||||
|
// Multiplier is the factor by which the retry envelope increases.
|
||||||
|
// It should be greater than 1 and defaults to 2.
|
||||||
|
Multiplier float64
|
||||||
|
|
||||||
|
// cur is the current retry envelope
|
||||||
|
cur time.Duration
|
||||||
|
}
|
||||||
|
|
||||||
|
func (bo *Backoff) Pause() time.Duration {
|
||||||
|
if bo.Initial == 0 {
|
||||||
|
bo.Initial = time.Second
|
||||||
|
}
|
||||||
|
if bo.cur == 0 {
|
||||||
|
bo.cur = bo.Initial
|
||||||
|
}
|
||||||
|
if bo.Max == 0 {
|
||||||
|
bo.Max = 30 * time.Second
|
||||||
|
}
|
||||||
|
if bo.Multiplier < 1 {
|
||||||
|
bo.Multiplier = 2
|
||||||
|
}
|
||||||
|
d := time.Duration(rand.Int63n(int64(bo.cur)))
|
||||||
|
bo.cur = time.Duration(float64(bo.cur) * bo.Multiplier)
|
||||||
|
if bo.cur > bo.Max {
|
||||||
|
bo.cur = bo.Max
|
||||||
|
}
|
||||||
|
return d
|
||||||
|
}
|
||||||
|
|
||||||
|
type grpcOpt []grpc.CallOption
|
||||||
|
|
||||||
|
func (o grpcOpt) Resolve(s *CallSettings) {
|
||||||
|
s.GRPC = o
|
||||||
|
}
|
||||||
|
|
||||||
|
func WithGRPCOptions(opt ...grpc.CallOption) CallOption {
|
||||||
|
return grpcOpt(append([]grpc.CallOption(nil), opt...))
|
||||||
|
}
|
||||||
|
|
||||||
|
type CallSettings struct {
|
||||||
|
// Retry returns a Retryer to be used to control retry logic of a method call.
|
||||||
|
// If Retry is nil or the returned Retryer is nil, the call will not be retried.
|
||||||
|
Retry func() Retryer
|
||||||
|
|
||||||
|
// CallOptions to be forwarded to GRPC.
|
||||||
|
GRPC []grpc.CallOption
|
||||||
|
}
|
40
vendor/github.com/googleapis/gax-go/gax.go
generated
vendored
Normal file
40
vendor/github.com/googleapis/gax-go/gax.go
generated
vendored
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
// Copyright 2016, Google Inc.
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
// Package gax contains a set of modules which aid the development of APIs
|
||||||
|
// for clients and servers based on gRPC and Google API conventions.
|
||||||
|
//
|
||||||
|
// Application code will rarely need to use this library directly.
|
||||||
|
// However, code generated automatically from API definition files can use it
|
||||||
|
// to simplify code generation and to provide more convenient and idiomatic API surfaces.
|
||||||
|
//
|
||||||
|
// This project is currently experimental and not supported.
|
||||||
|
package gax
|
||||||
|
|
||||||
|
const Version = "0.1.0"
|
24
vendor/github.com/googleapis/gax-go/header.go
generated
vendored
Normal file
24
vendor/github.com/googleapis/gax-go/header.go
generated
vendored
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
package gax
|
||||||
|
|
||||||
|
import "bytes"
|
||||||
|
|
||||||
|
// XGoogHeader is for use by the Google Cloud Libraries only.
|
||||||
|
//
|
||||||
|
// XGoogHeader formats key-value pairs.
|
||||||
|
// The resulting string is suitable for x-goog-api-client header.
|
||||||
|
func XGoogHeader(keyval ...string) string {
|
||||||
|
if len(keyval) == 0 {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
if len(keyval)%2 != 0 {
|
||||||
|
panic("gax.Header: odd argument count")
|
||||||
|
}
|
||||||
|
var buf bytes.Buffer
|
||||||
|
for i := 0; i < len(keyval); i += 2 {
|
||||||
|
buf.WriteByte(' ')
|
||||||
|
buf.WriteString(keyval[i])
|
||||||
|
buf.WriteByte('/')
|
||||||
|
buf.WriteString(keyval[i+1])
|
||||||
|
}
|
||||||
|
return buf.String()[1:]
|
||||||
|
}
|
90
vendor/github.com/googleapis/gax-go/invoke.go
generated
vendored
Normal file
90
vendor/github.com/googleapis/gax-go/invoke.go
generated
vendored
Normal file
|
@ -0,0 +1,90 @@
|
||||||
|
// Copyright 2016, Google Inc.
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
package gax
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"golang.org/x/net/context"
|
||||||
|
)
|
||||||
|
|
||||||
|
// A user defined call stub.
|
||||||
|
type APICall func(context.Context, CallSettings) error
|
||||||
|
|
||||||
|
// Invoke calls the given APICall,
|
||||||
|
// performing retries as specified by opts, if any.
|
||||||
|
func Invoke(ctx context.Context, call APICall, opts ...CallOption) error {
|
||||||
|
var settings CallSettings
|
||||||
|
for _, opt := range opts {
|
||||||
|
opt.Resolve(&settings)
|
||||||
|
}
|
||||||
|
return invoke(ctx, call, settings, Sleep)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sleep is similar to time.Sleep, but it can be interrupted by ctx.Done() closing.
|
||||||
|
// If interrupted, Sleep returns ctx.Err().
|
||||||
|
func Sleep(ctx context.Context, d time.Duration) error {
|
||||||
|
t := time.NewTimer(d)
|
||||||
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
t.Stop()
|
||||||
|
return ctx.Err()
|
||||||
|
case <-t.C:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type sleeper func(ctx context.Context, d time.Duration) error
|
||||||
|
|
||||||
|
// invoke implements Invoke, taking an additional sleeper argument for testing.
|
||||||
|
func invoke(ctx context.Context, call APICall, settings CallSettings, sp sleeper) error {
|
||||||
|
var retryer Retryer
|
||||||
|
for {
|
||||||
|
err := call(ctx, settings)
|
||||||
|
if err == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if settings.Retry == nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if retryer == nil {
|
||||||
|
if r := settings.Retry(); r != nil {
|
||||||
|
retryer = r
|
||||||
|
} else {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if d, ok := retryer.Retry(err); !ok {
|
||||||
|
return err
|
||||||
|
} else if err = sp(ctx, d); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
176
vendor/github.com/googleapis/gax-go/path_template.go
generated
vendored
Normal file
176
vendor/github.com/googleapis/gax-go/path_template.go
generated
vendored
Normal file
|
@ -0,0 +1,176 @@
|
||||||
|
// Copyright 2016, Google Inc.
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
package gax
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
type matcher interface {
|
||||||
|
match([]string) (int, error)
|
||||||
|
String() string
|
||||||
|
}
|
||||||
|
|
||||||
|
type segment struct {
|
||||||
|
matcher
|
||||||
|
name string
|
||||||
|
}
|
||||||
|
|
||||||
|
type labelMatcher string
|
||||||
|
|
||||||
|
func (ls labelMatcher) match(segments []string) (int, error) {
|
||||||
|
if len(segments) == 0 {
|
||||||
|
return 0, fmt.Errorf("expected %s but no more segments found", ls)
|
||||||
|
}
|
||||||
|
if segments[0] != string(ls) {
|
||||||
|
return 0, fmt.Errorf("expected %s but got %s", ls, segments[0])
|
||||||
|
}
|
||||||
|
return 1, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ls labelMatcher) String() string {
|
||||||
|
return string(ls)
|
||||||
|
}
|
||||||
|
|
||||||
|
type wildcardMatcher int
|
||||||
|
|
||||||
|
func (wm wildcardMatcher) match(segments []string) (int, error) {
|
||||||
|
if len(segments) == 0 {
|
||||||
|
return 0, errors.New("no more segments found")
|
||||||
|
}
|
||||||
|
return 1, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (wm wildcardMatcher) String() string {
|
||||||
|
return "*"
|
||||||
|
}
|
||||||
|
|
||||||
|
type pathWildcardMatcher int
|
||||||
|
|
||||||
|
func (pwm pathWildcardMatcher) match(segments []string) (int, error) {
|
||||||
|
length := len(segments) - int(pwm)
|
||||||
|
if length <= 0 {
|
||||||
|
return 0, errors.New("not sufficient segments are supplied for path wildcard")
|
||||||
|
}
|
||||||
|
return length, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pwm pathWildcardMatcher) String() string {
|
||||||
|
return "**"
|
||||||
|
}
|
||||||
|
|
||||||
|
type ParseError struct {
|
||||||
|
Pos int
|
||||||
|
Template string
|
||||||
|
Message string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pe ParseError) Error() string {
|
||||||
|
return fmt.Sprintf("at %d of template '%s', %s", pe.Pos, pe.Template, pe.Message)
|
||||||
|
}
|
||||||
|
|
||||||
|
// PathTemplate manages the template to build and match with paths used
|
||||||
|
// by API services. It holds a template and variable names in it, and
|
||||||
|
// it can extract matched patterns from a path string or build a path
|
||||||
|
// string from a binding.
|
||||||
|
//
|
||||||
|
// See http.proto in github.com/googleapis/googleapis/ for the details of
|
||||||
|
// the template syntax.
|
||||||
|
type PathTemplate struct {
|
||||||
|
segments []segment
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewPathTemplate parses a path template, and returns a PathTemplate
|
||||||
|
// instance if successful.
|
||||||
|
func NewPathTemplate(template string) (*PathTemplate, error) {
|
||||||
|
return parsePathTemplate(template)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MustCompilePathTemplate is like NewPathTemplate but panics if the
|
||||||
|
// expression cannot be parsed. It simplifies safe initialization of
|
||||||
|
// global variables holding compiled regular expressions.
|
||||||
|
func MustCompilePathTemplate(template string) *PathTemplate {
|
||||||
|
pt, err := NewPathTemplate(template)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return pt
|
||||||
|
}
|
||||||
|
|
||||||
|
// Match attempts to match the given path with the template, and returns
|
||||||
|
// the mapping of the variable name to the matched pattern string.
|
||||||
|
func (pt *PathTemplate) Match(path string) (map[string]string, error) {
|
||||||
|
paths := strings.Split(path, "/")
|
||||||
|
values := map[string]string{}
|
||||||
|
for _, segment := range pt.segments {
|
||||||
|
length, err := segment.match(paths)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if segment.name != "" {
|
||||||
|
value := strings.Join(paths[:length], "/")
|
||||||
|
if oldValue, ok := values[segment.name]; ok {
|
||||||
|
values[segment.name] = oldValue + "/" + value
|
||||||
|
} else {
|
||||||
|
values[segment.name] = value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
paths = paths[length:]
|
||||||
|
}
|
||||||
|
if len(paths) != 0 {
|
||||||
|
return nil, fmt.Errorf("Trailing path %s remains after the matching", strings.Join(paths, "/"))
|
||||||
|
}
|
||||||
|
return values, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Render creates a path string from its template and the binding from
|
||||||
|
// the variable name to the value.
|
||||||
|
func (pt *PathTemplate) Render(binding map[string]string) (string, error) {
|
||||||
|
result := make([]string, 0, len(pt.segments))
|
||||||
|
var lastVariableName string
|
||||||
|
for _, segment := range pt.segments {
|
||||||
|
name := segment.name
|
||||||
|
if lastVariableName != "" && name == lastVariableName {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
lastVariableName = name
|
||||||
|
if name == "" {
|
||||||
|
result = append(result, segment.String())
|
||||||
|
} else if value, ok := binding[name]; ok {
|
||||||
|
result = append(result, value)
|
||||||
|
} else {
|
||||||
|
return "", fmt.Errorf("%s is not found", name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
built := strings.Join(result, "/")
|
||||||
|
return built, nil
|
||||||
|
}
|
227
vendor/github.com/googleapis/gax-go/path_template_parser.go
generated
vendored
Normal file
227
vendor/github.com/googleapis/gax-go/path_template_parser.go
generated
vendored
Normal file
|
@ -0,0 +1,227 @@
|
||||||
|
// Copyright 2016, Google Inc.
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
package gax
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// This parser follows the syntax of path templates, from
|
||||||
|
// https://github.com/googleapis/googleapis/blob/master/google/api/http.proto.
|
||||||
|
// The differences are that there is no custom verb, we allow the initial slash
|
||||||
|
// to be absent, and that we are not strict as
|
||||||
|
// https://tools.ietf.org/html/rfc6570 about the characters in identifiers and
|
||||||
|
// literals.
|
||||||
|
|
||||||
|
type pathTemplateParser struct {
|
||||||
|
r *strings.Reader
|
||||||
|
runeCount int // the number of the current rune in the original string
|
||||||
|
nextVar int // the number to use for the next unnamed variable
|
||||||
|
seenName map[string]bool // names we've seen already
|
||||||
|
seenPathWildcard bool // have we seen "**" already?
|
||||||
|
}
|
||||||
|
|
||||||
|
func parsePathTemplate(template string) (pt *PathTemplate, err error) {
|
||||||
|
p := &pathTemplateParser{
|
||||||
|
r: strings.NewReader(template),
|
||||||
|
seenName: map[string]bool{},
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle panics with strings like errors.
|
||||||
|
// See pathTemplateParser.error, below.
|
||||||
|
defer func() {
|
||||||
|
if x := recover(); x != nil {
|
||||||
|
errmsg, ok := x.(errString)
|
||||||
|
if !ok {
|
||||||
|
panic(x)
|
||||||
|
}
|
||||||
|
pt = nil
|
||||||
|
err = ParseError{p.runeCount, template, string(errmsg)}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
segs := p.template()
|
||||||
|
// If there is a path wildcard, set its length. We can't do this
|
||||||
|
// until we know how many segments we've got all together.
|
||||||
|
for i, seg := range segs {
|
||||||
|
if _, ok := seg.matcher.(pathWildcardMatcher); ok {
|
||||||
|
segs[i].matcher = pathWildcardMatcher(len(segs) - i - 1)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return &PathTemplate{segments: segs}, nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Used to indicate errors "thrown" by this parser. We don't use string because
|
||||||
|
// many parts of the standard library panic with strings.
|
||||||
|
type errString string
|
||||||
|
|
||||||
|
// Terminates parsing immediately with an error.
|
||||||
|
func (p *pathTemplateParser) error(msg string) {
|
||||||
|
panic(errString(msg))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Template = [ "/" ] Segments
|
||||||
|
func (p *pathTemplateParser) template() []segment {
|
||||||
|
var segs []segment
|
||||||
|
if p.consume('/') {
|
||||||
|
// Initial '/' needs an initial empty matcher.
|
||||||
|
segs = append(segs, segment{matcher: labelMatcher("")})
|
||||||
|
}
|
||||||
|
return append(segs, p.segments("")...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Segments = Segment { "/" Segment }
|
||||||
|
func (p *pathTemplateParser) segments(name string) []segment {
|
||||||
|
var segs []segment
|
||||||
|
for {
|
||||||
|
subsegs := p.segment(name)
|
||||||
|
segs = append(segs, subsegs...)
|
||||||
|
if !p.consume('/') {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return segs
|
||||||
|
}
|
||||||
|
|
||||||
|
// Segment = "*" | "**" | LITERAL | Variable
|
||||||
|
func (p *pathTemplateParser) segment(name string) []segment {
|
||||||
|
if p.consume('*') {
|
||||||
|
if name == "" {
|
||||||
|
name = fmt.Sprintf("$%d", p.nextVar)
|
||||||
|
p.nextVar++
|
||||||
|
}
|
||||||
|
if p.consume('*') {
|
||||||
|
if p.seenPathWildcard {
|
||||||
|
p.error("multiple '**' disallowed")
|
||||||
|
}
|
||||||
|
p.seenPathWildcard = true
|
||||||
|
// We'll change 0 to the right number at the end.
|
||||||
|
return []segment{{name: name, matcher: pathWildcardMatcher(0)}}
|
||||||
|
}
|
||||||
|
return []segment{{name: name, matcher: wildcardMatcher(0)}}
|
||||||
|
}
|
||||||
|
if p.consume('{') {
|
||||||
|
if name != "" {
|
||||||
|
p.error("recursive named bindings are not allowed")
|
||||||
|
}
|
||||||
|
return p.variable()
|
||||||
|
}
|
||||||
|
return []segment{{name: name, matcher: labelMatcher(p.literal())}}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Variable = "{" FieldPath [ "=" Segments ] "}"
|
||||||
|
// "{" is already consumed.
|
||||||
|
func (p *pathTemplateParser) variable() []segment {
|
||||||
|
// Simplification: treat FieldPath as LITERAL, instead of IDENT { '.' IDENT }
|
||||||
|
name := p.literal()
|
||||||
|
if p.seenName[name] {
|
||||||
|
p.error(name + " appears multiple times")
|
||||||
|
}
|
||||||
|
p.seenName[name] = true
|
||||||
|
var segs []segment
|
||||||
|
if p.consume('=') {
|
||||||
|
segs = p.segments(name)
|
||||||
|
} else {
|
||||||
|
// "{var}" is equivalent to "{var=*}"
|
||||||
|
segs = []segment{{name: name, matcher: wildcardMatcher(0)}}
|
||||||
|
}
|
||||||
|
if !p.consume('}') {
|
||||||
|
p.error("expected '}'")
|
||||||
|
}
|
||||||
|
return segs
|
||||||
|
}
|
||||||
|
|
||||||
|
// A literal is any sequence of characters other than a few special ones.
|
||||||
|
// The list of stop characters is not quite the same as in the template RFC.
|
||||||
|
func (p *pathTemplateParser) literal() string {
|
||||||
|
lit := p.consumeUntil("/*}{=")
|
||||||
|
if lit == "" {
|
||||||
|
p.error("empty literal")
|
||||||
|
}
|
||||||
|
return lit
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read runes until EOF or one of the runes in stopRunes is encountered.
|
||||||
|
// If the latter, unread the stop rune. Return the accumulated runes as a string.
|
||||||
|
func (p *pathTemplateParser) consumeUntil(stopRunes string) string {
|
||||||
|
var runes []rune
|
||||||
|
for {
|
||||||
|
r, ok := p.readRune()
|
||||||
|
if !ok {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if strings.IndexRune(stopRunes, r) >= 0 {
|
||||||
|
p.unreadRune()
|
||||||
|
break
|
||||||
|
}
|
||||||
|
runes = append(runes, r)
|
||||||
|
}
|
||||||
|
return string(runes)
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the next rune is r, consume it and return true.
|
||||||
|
// Otherwise, leave the input unchanged and return false.
|
||||||
|
func (p *pathTemplateParser) consume(r rune) bool {
|
||||||
|
rr, ok := p.readRune()
|
||||||
|
if !ok {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if r == rr {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
p.unreadRune()
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read the next rune from the input. Return it.
|
||||||
|
// The second return value is false at EOF.
|
||||||
|
func (p *pathTemplateParser) readRune() (rune, bool) {
|
||||||
|
r, _, err := p.r.ReadRune()
|
||||||
|
if err == io.EOF {
|
||||||
|
return r, false
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
p.error(err.Error())
|
||||||
|
}
|
||||||
|
p.runeCount++
|
||||||
|
return r, true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Put the last rune that was read back on the input.
|
||||||
|
func (p *pathTemplateParser) unreadRune() {
|
||||||
|
if err := p.r.UnreadRune(); err != nil {
|
||||||
|
p.error(err.Error())
|
||||||
|
}
|
||||||
|
p.runeCount--
|
||||||
|
}
|
47
vendor/github.com/spf13/pflag/bool.go
generated
vendored
47
vendor/github.com/spf13/pflag/bool.go
generated
vendored
|
@ -1,9 +1,6 @@
|
||||||
package pflag
|
package pflag
|
||||||
|
|
||||||
import (
|
import "strconv"
|
||||||
"fmt"
|
|
||||||
"strconv"
|
|
||||||
)
|
|
||||||
|
|
||||||
// optional interface to indicate boolean flags that can be
|
// optional interface to indicate boolean flags that can be
|
||||||
// supplied without "=value" text
|
// supplied without "=value" text
|
||||||
|
@ -30,41 +27,54 @@ func (b *boolValue) Type() string {
|
||||||
return "bool"
|
return "bool"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *boolValue) String() string { return fmt.Sprintf("%v", *b) }
|
func (b *boolValue) String() string { return strconv.FormatBool(bool(*b)) }
|
||||||
|
|
||||||
func (b *boolValue) IsBoolFlag() bool { return true }
|
func (b *boolValue) IsBoolFlag() bool { return true }
|
||||||
|
|
||||||
|
func boolConv(sval string) (interface{}, error) {
|
||||||
|
return strconv.ParseBool(sval)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetBool return the bool value of a flag with the given name
|
||||||
|
func (f *FlagSet) GetBool(name string) (bool, error) {
|
||||||
|
val, err := f.getFlagType(name, "bool", boolConv)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
return val.(bool), nil
|
||||||
|
}
|
||||||
|
|
||||||
// BoolVar defines a bool flag with specified name, default value, and usage string.
|
// BoolVar defines a bool flag with specified name, default value, and usage string.
|
||||||
// The argument p points to a bool variable in which to store the value of the flag.
|
// The argument p points to a bool variable in which to store the value of the flag.
|
||||||
func (f *FlagSet) BoolVar(p *bool, name string, value bool, usage string) {
|
func (f *FlagSet) BoolVar(p *bool, name string, value bool, usage string) {
|
||||||
f.VarP(newBoolValue(value, p), name, "", usage)
|
f.BoolVarP(p, name, "", value, usage)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Like BoolVar, but accepts a shorthand letter that can be used after a single dash.
|
// BoolVarP is like BoolVar, but accepts a shorthand letter that can be used after a single dash.
|
||||||
func (f *FlagSet) BoolVarP(p *bool, name, shorthand string, value bool, usage string) {
|
func (f *FlagSet) BoolVarP(p *bool, name, shorthand string, value bool, usage string) {
|
||||||
f.VarP(newBoolValue(value, p), name, shorthand, usage)
|
flag := f.VarPF(newBoolValue(value, p), name, shorthand, usage)
|
||||||
|
flag.NoOptDefVal = "true"
|
||||||
}
|
}
|
||||||
|
|
||||||
// BoolVar defines a bool flag with specified name, default value, and usage string.
|
// BoolVar defines a bool flag with specified name, default value, and usage string.
|
||||||
// The argument p points to a bool variable in which to store the value of the flag.
|
// The argument p points to a bool variable in which to store the value of the flag.
|
||||||
func BoolVar(p *bool, name string, value bool, usage string) {
|
func BoolVar(p *bool, name string, value bool, usage string) {
|
||||||
CommandLine.VarP(newBoolValue(value, p), name, "", usage)
|
BoolVarP(p, name, "", value, usage)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Like BoolVar, but accepts a shorthand letter that can be used after a single dash.
|
// BoolVarP is like BoolVar, but accepts a shorthand letter that can be used after a single dash.
|
||||||
func BoolVarP(p *bool, name, shorthand string, value bool, usage string) {
|
func BoolVarP(p *bool, name, shorthand string, value bool, usage string) {
|
||||||
CommandLine.VarP(newBoolValue(value, p), name, shorthand, usage)
|
flag := CommandLine.VarPF(newBoolValue(value, p), name, shorthand, usage)
|
||||||
|
flag.NoOptDefVal = "true"
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bool defines a bool flag with specified name, default value, and usage string.
|
// Bool defines a bool flag with specified name, default value, and usage string.
|
||||||
// The return value is the address of a bool variable that stores the value of the flag.
|
// The return value is the address of a bool variable that stores the value of the flag.
|
||||||
func (f *FlagSet) Bool(name string, value bool, usage string) *bool {
|
func (f *FlagSet) Bool(name string, value bool, usage string) *bool {
|
||||||
p := new(bool)
|
return f.BoolP(name, "", value, usage)
|
||||||
f.BoolVarP(p, name, "", value, usage)
|
|
||||||
return p
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Like Bool, but accepts a shorthand letter that can be used after a single dash.
|
// BoolP is like Bool, but accepts a shorthand letter that can be used after a single dash.
|
||||||
func (f *FlagSet) BoolP(name, shorthand string, value bool, usage string) *bool {
|
func (f *FlagSet) BoolP(name, shorthand string, value bool, usage string) *bool {
|
||||||
p := new(bool)
|
p := new(bool)
|
||||||
f.BoolVarP(p, name, shorthand, value, usage)
|
f.BoolVarP(p, name, shorthand, value, usage)
|
||||||
|
@ -74,10 +84,11 @@ func (f *FlagSet) BoolP(name, shorthand string, value bool, usage string) *bool
|
||||||
// Bool defines a bool flag with specified name, default value, and usage string.
|
// Bool defines a bool flag with specified name, default value, and usage string.
|
||||||
// The return value is the address of a bool variable that stores the value of the flag.
|
// The return value is the address of a bool variable that stores the value of the flag.
|
||||||
func Bool(name string, value bool, usage string) *bool {
|
func Bool(name string, value bool, usage string) *bool {
|
||||||
return CommandLine.BoolP(name, "", value, usage)
|
return BoolP(name, "", value, usage)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Like Bool, but accepts a shorthand letter that can be used after a single dash.
|
// BoolP is like Bool, but accepts a shorthand letter that can be used after a single dash.
|
||||||
func BoolP(name, shorthand string, value bool, usage string) *bool {
|
func BoolP(name, shorthand string, value bool, usage string) *bool {
|
||||||
return CommandLine.BoolP(name, shorthand, value, usage)
|
b := CommandLine.BoolP(name, shorthand, value, usage)
|
||||||
|
return b
|
||||||
}
|
}
|
||||||
|
|
94
vendor/github.com/spf13/pflag/count.go
generated
vendored
Normal file
94
vendor/github.com/spf13/pflag/count.go
generated
vendored
Normal file
|
@ -0,0 +1,94 @@
|
||||||
|
package pflag
|
||||||
|
|
||||||
|
import "strconv"
|
||||||
|
|
||||||
|
// -- count Value
|
||||||
|
type countValue int
|
||||||
|
|
||||||
|
func newCountValue(val int, p *int) *countValue {
|
||||||
|
*p = val
|
||||||
|
return (*countValue)(p)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *countValue) Set(s string) error {
|
||||||
|
v, err := strconv.ParseInt(s, 0, 64)
|
||||||
|
// -1 means that no specific value was passed, so increment
|
||||||
|
if v == -1 {
|
||||||
|
*i = countValue(*i + 1)
|
||||||
|
} else {
|
||||||
|
*i = countValue(v)
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *countValue) Type() string {
|
||||||
|
return "count"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *countValue) String() string { return strconv.Itoa(int(*i)) }
|
||||||
|
|
||||||
|
func countConv(sval string) (interface{}, error) {
|
||||||
|
i, err := strconv.Atoi(sval)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return i, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetCount return the int value of a flag with the given name
|
||||||
|
func (f *FlagSet) GetCount(name string) (int, error) {
|
||||||
|
val, err := f.getFlagType(name, "count", countConv)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
return val.(int), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CountVar defines a count flag with specified name, default value, and usage string.
|
||||||
|
// The argument p points to an int variable in which to store the value of the flag.
|
||||||
|
// A count flag will add 1 to its value evey time it is found on the command line
|
||||||
|
func (f *FlagSet) CountVar(p *int, name string, usage string) {
|
||||||
|
f.CountVarP(p, name, "", usage)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CountVarP is like CountVar only take a shorthand for the flag name.
|
||||||
|
func (f *FlagSet) CountVarP(p *int, name, shorthand string, usage string) {
|
||||||
|
flag := f.VarPF(newCountValue(0, p), name, shorthand, usage)
|
||||||
|
flag.NoOptDefVal = "-1"
|
||||||
|
}
|
||||||
|
|
||||||
|
// CountVar like CountVar only the flag is placed on the CommandLine instead of a given flag set
|
||||||
|
func CountVar(p *int, name string, usage string) {
|
||||||
|
CommandLine.CountVar(p, name, usage)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CountVarP is like CountVar only take a shorthand for the flag name.
|
||||||
|
func CountVarP(p *int, name, shorthand string, usage string) {
|
||||||
|
CommandLine.CountVarP(p, name, shorthand, usage)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Count defines a count flag with specified name, default value, and usage string.
|
||||||
|
// The return value is the address of an int variable that stores the value of the flag.
|
||||||
|
// A count flag will add 1 to its value evey time it is found on the command line
|
||||||
|
func (f *FlagSet) Count(name string, usage string) *int {
|
||||||
|
p := new(int)
|
||||||
|
f.CountVarP(p, name, "", usage)
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
|
||||||
|
// CountP is like Count only takes a shorthand for the flag name.
|
||||||
|
func (f *FlagSet) CountP(name, shorthand string, usage string) *int {
|
||||||
|
p := new(int)
|
||||||
|
f.CountVarP(p, name, shorthand, usage)
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
|
||||||
|
// Count like Count only the flag is placed on the CommandLine isntead of a given flag set
|
||||||
|
func Count(name string, usage string) *int {
|
||||||
|
return CommandLine.CountP(name, "", usage)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CountP is like Count only takes a shorthand for the flag name.
|
||||||
|
func CountP(name, shorthand string, usage string) *int {
|
||||||
|
return CommandLine.CountP(name, shorthand, usage)
|
||||||
|
}
|
25
vendor/github.com/spf13/pflag/duration.go
generated
vendored
25
vendor/github.com/spf13/pflag/duration.go
generated
vendored
|
@ -1,6 +1,8 @@
|
||||||
package pflag
|
package pflag
|
||||||
|
|
||||||
import "time"
|
import (
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
// -- time.Duration Value
|
// -- time.Duration Value
|
||||||
type durationValue time.Duration
|
type durationValue time.Duration
|
||||||
|
@ -22,13 +24,26 @@ func (d *durationValue) Type() string {
|
||||||
|
|
||||||
func (d *durationValue) String() string { return (*time.Duration)(d).String() }
|
func (d *durationValue) String() string { return (*time.Duration)(d).String() }
|
||||||
|
|
||||||
|
func durationConv(sval string) (interface{}, error) {
|
||||||
|
return time.ParseDuration(sval)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetDuration return the duration value of a flag with the given name
|
||||||
|
func (f *FlagSet) GetDuration(name string) (time.Duration, error) {
|
||||||
|
val, err := f.getFlagType(name, "duration", durationConv)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
return val.(time.Duration), nil
|
||||||
|
}
|
||||||
|
|
||||||
// DurationVar defines a time.Duration flag with specified name, default value, and usage string.
|
// DurationVar defines a time.Duration flag with specified name, default value, and usage string.
|
||||||
// The argument p points to a time.Duration variable in which to store the value of the flag.
|
// The argument p points to a time.Duration variable in which to store the value of the flag.
|
||||||
func (f *FlagSet) DurationVar(p *time.Duration, name string, value time.Duration, usage string) {
|
func (f *FlagSet) DurationVar(p *time.Duration, name string, value time.Duration, usage string) {
|
||||||
f.VarP(newDurationValue(value, p), name, "", usage)
|
f.VarP(newDurationValue(value, p), name, "", usage)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Like DurationVar, but accepts a shorthand letter that can be used after a single dash.
|
// DurationVarP is like DurationVar, but accepts a shorthand letter that can be used after a single dash.
|
||||||
func (f *FlagSet) DurationVarP(p *time.Duration, name, shorthand string, value time.Duration, usage string) {
|
func (f *FlagSet) DurationVarP(p *time.Duration, name, shorthand string, value time.Duration, usage string) {
|
||||||
f.VarP(newDurationValue(value, p), name, shorthand, usage)
|
f.VarP(newDurationValue(value, p), name, shorthand, usage)
|
||||||
}
|
}
|
||||||
|
@ -39,7 +54,7 @@ func DurationVar(p *time.Duration, name string, value time.Duration, usage strin
|
||||||
CommandLine.VarP(newDurationValue(value, p), name, "", usage)
|
CommandLine.VarP(newDurationValue(value, p), name, "", usage)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Like DurationVar, but accepts a shorthand letter that can be used after a single dash.
|
// DurationVarP is like DurationVar, but accepts a shorthand letter that can be used after a single dash.
|
||||||
func DurationVarP(p *time.Duration, name, shorthand string, value time.Duration, usage string) {
|
func DurationVarP(p *time.Duration, name, shorthand string, value time.Duration, usage string) {
|
||||||
CommandLine.VarP(newDurationValue(value, p), name, shorthand, usage)
|
CommandLine.VarP(newDurationValue(value, p), name, shorthand, usage)
|
||||||
}
|
}
|
||||||
|
@ -52,7 +67,7 @@ func (f *FlagSet) Duration(name string, value time.Duration, usage string) *time
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
// Like Duration, but accepts a shorthand letter that can be used after a single dash.
|
// DurationP is like Duration, but accepts a shorthand letter that can be used after a single dash.
|
||||||
func (f *FlagSet) DurationP(name, shorthand string, value time.Duration, usage string) *time.Duration {
|
func (f *FlagSet) DurationP(name, shorthand string, value time.Duration, usage string) *time.Duration {
|
||||||
p := new(time.Duration)
|
p := new(time.Duration)
|
||||||
f.DurationVarP(p, name, shorthand, value, usage)
|
f.DurationVarP(p, name, shorthand, value, usage)
|
||||||
|
@ -65,7 +80,7 @@ func Duration(name string, value time.Duration, usage string) *time.Duration {
|
||||||
return CommandLine.DurationP(name, "", value, usage)
|
return CommandLine.DurationP(name, "", value, usage)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Like Duration, but accepts a shorthand letter that can be used after a single dash.
|
// DurationP is like Duration, but accepts a shorthand letter that can be used after a single dash.
|
||||||
func DurationP(name, shorthand string, value time.Duration, usage string) *time.Duration {
|
func DurationP(name, shorthand string, value time.Duration, usage string) *time.Duration {
|
||||||
return CommandLine.DurationP(name, shorthand, value, usage)
|
return CommandLine.DurationP(name, shorthand, value, usage)
|
||||||
}
|
}
|
||||||
|
|
428
vendor/github.com/spf13/pflag/flag.go
generated
vendored
428
vendor/github.com/spf13/pflag/flag.go
generated
vendored
|
@ -3,73 +3,73 @@
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
/*
|
/*
|
||||||
pflag is a drop-in replacement for Go's flag package, implementing
|
Package pflag is a drop-in replacement for Go's flag package, implementing
|
||||||
POSIX/GNU-style --flags.
|
POSIX/GNU-style --flags.
|
||||||
|
|
||||||
pflag is compatible with the GNU extensions to the POSIX recommendations
|
pflag is compatible with the GNU extensions to the POSIX recommendations
|
||||||
for command-line options. See
|
for command-line options. See
|
||||||
http://www.gnu.org/software/libc/manual/html_node/Argument-Syntax.html
|
http://www.gnu.org/software/libc/manual/html_node/Argument-Syntax.html
|
||||||
|
|
||||||
Usage:
|
Usage:
|
||||||
|
|
||||||
pflag is a drop-in replacement of Go's native flag package. If you import
|
pflag is a drop-in replacement of Go's native flag package. If you import
|
||||||
pflag under the name "flag" then all code should continue to function
|
pflag under the name "flag" then all code should continue to function
|
||||||
with no changes.
|
with no changes.
|
||||||
|
|
||||||
import flag "github.com/ogier/pflag"
|
import flag "github.com/ogier/pflag"
|
||||||
|
|
||||||
There is one exception to this: if you directly instantiate the Flag struct
|
There is one exception to this: if you directly instantiate the Flag struct
|
||||||
there is one more field "Shorthand" that you will need to set.
|
there is one more field "Shorthand" that you will need to set.
|
||||||
Most code never instantiates this struct directly, and instead uses
|
Most code never instantiates this struct directly, and instead uses
|
||||||
functions such as String(), BoolVar(), and Var(), and is therefore
|
functions such as String(), BoolVar(), and Var(), and is therefore
|
||||||
unaffected.
|
unaffected.
|
||||||
|
|
||||||
Define flags using flag.String(), Bool(), Int(), etc.
|
Define flags using flag.String(), Bool(), Int(), etc.
|
||||||
|
|
||||||
This declares an integer flag, -flagname, stored in the pointer ip, with type *int.
|
This declares an integer flag, -flagname, stored in the pointer ip, with type *int.
|
||||||
var ip = flag.Int("flagname", 1234, "help message for flagname")
|
var ip = flag.Int("flagname", 1234, "help message for flagname")
|
||||||
If you like, you can bind the flag to a variable using the Var() functions.
|
If you like, you can bind the flag to a variable using the Var() functions.
|
||||||
var flagvar int
|
var flagvar int
|
||||||
func init() {
|
func init() {
|
||||||
flag.IntVar(&flagvar, "flagname", 1234, "help message for flagname")
|
flag.IntVar(&flagvar, "flagname", 1234, "help message for flagname")
|
||||||
}
|
}
|
||||||
Or you can create custom flags that satisfy the Value interface (with
|
Or you can create custom flags that satisfy the Value interface (with
|
||||||
pointer receivers) and couple them to flag parsing by
|
pointer receivers) and couple them to flag parsing by
|
||||||
flag.Var(&flagVal, "name", "help message for flagname")
|
flag.Var(&flagVal, "name", "help message for flagname")
|
||||||
For such flags, the default value is just the initial value of the variable.
|
For such flags, the default value is just the initial value of the variable.
|
||||||
|
|
||||||
After all flags are defined, call
|
After all flags are defined, call
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
to parse the command line into the defined flags.
|
to parse the command line into the defined flags.
|
||||||
|
|
||||||
Flags may then be used directly. If you're using the flags themselves,
|
Flags may then be used directly. If you're using the flags themselves,
|
||||||
they are all pointers; if you bind to variables, they're values.
|
they are all pointers; if you bind to variables, they're values.
|
||||||
fmt.Println("ip has value ", *ip)
|
fmt.Println("ip has value ", *ip)
|
||||||
fmt.Println("flagvar has value ", flagvar)
|
fmt.Println("flagvar has value ", flagvar)
|
||||||
|
|
||||||
After parsing, the arguments after the flag are available as the
|
After parsing, the arguments after the flag are available as the
|
||||||
slice flag.Args() or individually as flag.Arg(i).
|
slice flag.Args() or individually as flag.Arg(i).
|
||||||
The arguments are indexed from 0 through flag.NArg()-1.
|
The arguments are indexed from 0 through flag.NArg()-1.
|
||||||
|
|
||||||
The pflag package also defines some new functions that are not in flag,
|
The pflag package also defines some new functions that are not in flag,
|
||||||
that give one-letter shorthands for flags. You can use these by appending
|
that give one-letter shorthands for flags. You can use these by appending
|
||||||
'P' to the name of any function that defines a flag.
|
'P' to the name of any function that defines a flag.
|
||||||
var ip = flag.IntP("flagname", "f", 1234, "help message")
|
var ip = flag.IntP("flagname", "f", 1234, "help message")
|
||||||
var flagvar bool
|
var flagvar bool
|
||||||
func init() {
|
func init() {
|
||||||
flag.BoolVarP("boolname", "b", true, "help message")
|
flag.BoolVarP("boolname", "b", true, "help message")
|
||||||
}
|
}
|
||||||
flag.VarP(&flagVar, "varname", "v", 1234, "help message")
|
flag.VarP(&flagVar, "varname", "v", 1234, "help message")
|
||||||
Shorthand letters can be used with single dashes on the command line.
|
Shorthand letters can be used with single dashes on the command line.
|
||||||
Boolean shorthand flags can be combined with other shorthand flags.
|
Boolean shorthand flags can be combined with other shorthand flags.
|
||||||
|
|
||||||
Command line flag syntax:
|
Command line flag syntax:
|
||||||
--flag // boolean flags only
|
--flag // boolean flags only
|
||||||
--flag=x
|
--flag=x
|
||||||
|
|
||||||
Unlike the flag package, a single dash before an option means something
|
Unlike the flag package, a single dash before an option means something
|
||||||
different than a double dash. Single dashes signify a series of shorthand
|
different than a double dash. Single dashes signify a series of shorthand
|
||||||
letters for flags. All but the last shorthand letter must be boolean flags.
|
letters for flags. All but the last shorthand letter must be boolean flags.
|
||||||
// boolean flags
|
// boolean flags
|
||||||
-f
|
-f
|
||||||
-abc
|
-abc
|
||||||
|
@ -80,21 +80,21 @@
|
||||||
-abcs "hello"
|
-abcs "hello"
|
||||||
-abcn1234
|
-abcn1234
|
||||||
|
|
||||||
Flag parsing stops after the terminator "--". Unlike the flag package,
|
Flag parsing stops after the terminator "--". Unlike the flag package,
|
||||||
flags can be interspersed with arguments anywhere on the command line
|
flags can be interspersed with arguments anywhere on the command line
|
||||||
before this terminator.
|
before this terminator.
|
||||||
|
|
||||||
Integer flags accept 1234, 0664, 0x1234 and may be negative.
|
Integer flags accept 1234, 0664, 0x1234 and may be negative.
|
||||||
Boolean flags (in their long form) accept 1, 0, t, f, true, false,
|
Boolean flags (in their long form) accept 1, 0, t, f, true, false,
|
||||||
TRUE, FALSE, True, False.
|
TRUE, FALSE, True, False.
|
||||||
Duration flags accept any input valid for time.ParseDuration.
|
Duration flags accept any input valid for time.ParseDuration.
|
||||||
|
|
||||||
The default set of command-line flags is controlled by
|
The default set of command-line flags is controlled by
|
||||||
top-level functions. The FlagSet type allows one to define
|
top-level functions. The FlagSet type allows one to define
|
||||||
independent sets of flags, such as to implement subcommands
|
independent sets of flags, such as to implement subcommands
|
||||||
in a command-line interface. The methods of FlagSet are
|
in a command-line interface. The methods of FlagSet are
|
||||||
analogous to the top-level functions for the command-line
|
analogous to the top-level functions for the command-line
|
||||||
flag set.
|
flag set.
|
||||||
*/
|
*/
|
||||||
package pflag
|
package pflag
|
||||||
|
|
||||||
|
@ -115,8 +115,11 @@ var ErrHelp = errors.New("pflag: help requested")
|
||||||
type ErrorHandling int
|
type ErrorHandling int
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
// ContinueOnError will return an err from Parse() if an error is found
|
||||||
ContinueOnError ErrorHandling = iota
|
ContinueOnError ErrorHandling = iota
|
||||||
|
// ExitOnError will call os.Exit(2) if an error is found when parsing
|
||||||
ExitOnError
|
ExitOnError
|
||||||
|
// PanicOnError will panic() if an error is found when parsing flags
|
||||||
PanicOnError
|
PanicOnError
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -137,6 +140,7 @@ type FlagSet struct {
|
||||||
formal map[NormalizedName]*Flag
|
formal map[NormalizedName]*Flag
|
||||||
shorthands map[byte]*Flag
|
shorthands map[byte]*Flag
|
||||||
args []string // arguments after flags
|
args []string // arguments after flags
|
||||||
|
argsLenAtDash int // len(args) when a '--' was located when parsing, or -1 if no --
|
||||||
exitOnError bool // does the program exit if there's an error?
|
exitOnError bool // does the program exit if there's an error?
|
||||||
errorHandling ErrorHandling
|
errorHandling ErrorHandling
|
||||||
output io.Writer // nil means stderr; use out() accessor
|
output io.Writer // nil means stderr; use out() accessor
|
||||||
|
@ -152,7 +156,10 @@ type Flag struct {
|
||||||
Value Value // value as set
|
Value Value // value as set
|
||||||
DefValue string // default value (as text); for usage message
|
DefValue string // default value (as text); for usage message
|
||||||
Changed bool // If the user set the value (or if left to default)
|
Changed bool // If the user set the value (or if left to default)
|
||||||
|
NoOptDefVal string //default value (as text); if the flag is on the command line without any options
|
||||||
Deprecated string // If this flag is deprecated, this string is the new or now thing to use
|
Deprecated string // If this flag is deprecated, this string is the new or now thing to use
|
||||||
|
Hidden bool // used by cobra.Command to allow flags to be hidden from help/usage text
|
||||||
|
ShorthandDeprecated string // If the shorthand of this flag is deprecated, this string is the new or now thing to use
|
||||||
Annotations map[string][]string // used by cobra.Command bash autocomple code
|
Annotations map[string][]string // used by cobra.Command bash autocomple code
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -180,6 +187,11 @@ func sortFlags(flags map[NormalizedName]*Flag) []*Flag {
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetNormalizeFunc allows you to add a function which can translate flag names.
|
||||||
|
// Flags added to the FlagSet will be translated and then when anything tries to
|
||||||
|
// look up the flag that will also be translated. So it would be possible to create
|
||||||
|
// a flag named "getURL" and have it translated to "geturl". A user could then pass
|
||||||
|
// "--getUrl" which may also be translated to "geturl" and everything will work.
|
||||||
func (f *FlagSet) SetNormalizeFunc(n func(f *FlagSet, name string) NormalizedName) {
|
func (f *FlagSet) SetNormalizeFunc(n func(f *FlagSet, name string) NormalizedName) {
|
||||||
f.normalizeNameFunc = n
|
f.normalizeNameFunc = n
|
||||||
for k, v := range f.formal {
|
for k, v := range f.formal {
|
||||||
|
@ -190,6 +202,8 @@ func (f *FlagSet) SetNormalizeFunc(n func(f *FlagSet, name string) NormalizedNam
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetNormalizeFunc returns the previously set NormalizeFunc of a function which
|
||||||
|
// does no translation, if not set previously.
|
||||||
func (f *FlagSet) GetNormalizeFunc() func(f *FlagSet, name string) NormalizedName {
|
func (f *FlagSet) GetNormalizeFunc() func(f *FlagSet, name string) NormalizedName {
|
||||||
if f.normalizeNameFunc != nil {
|
if f.normalizeNameFunc != nil {
|
||||||
return f.normalizeNameFunc
|
return f.normalizeNameFunc
|
||||||
|
@ -223,10 +237,22 @@ func (f *FlagSet) VisitAll(fn func(*Flag)) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// HasFlags returns a bool to indicate if the FlagSet has any flags definied.
|
||||||
func (f *FlagSet) HasFlags() bool {
|
func (f *FlagSet) HasFlags() bool {
|
||||||
return len(f.formal) > 0
|
return len(f.formal) > 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// HasAvailableFlags returns a bool to indicate if the FlagSet has any flags
|
||||||
|
// definied that are not hidden or deprecated.
|
||||||
|
func (f *FlagSet) HasAvailableFlags() bool {
|
||||||
|
for _, flag := range f.formal {
|
||||||
|
if !flag.Hidden && len(flag.Deprecated) == 0 {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
// VisitAll visits the command-line flags in lexicographical order, calling
|
// VisitAll visits the command-line flags in lexicographical order, calling
|
||||||
// fn for each. It visits all flags, even those not set.
|
// fn for each. It visits all flags, even those not set.
|
||||||
func VisitAll(fn func(*Flag)) {
|
func VisitAll(fn func(*Flag)) {
|
||||||
|
@ -257,16 +283,75 @@ func (f *FlagSet) lookup(name NormalizedName) *Flag {
|
||||||
return f.formal[name]
|
return f.formal[name]
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mark a flag deprecated in your program
|
// func to return a given type for a given flag name
|
||||||
|
func (f *FlagSet) getFlagType(name string, ftype string, convFunc func(sval string) (interface{}, error)) (interface{}, error) {
|
||||||
|
flag := f.Lookup(name)
|
||||||
|
if flag == nil {
|
||||||
|
err := fmt.Errorf("flag accessed but not defined: %s", name)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if flag.Value.Type() != ftype {
|
||||||
|
err := fmt.Errorf("trying to get %s value of flag of type %s", ftype, flag.Value.Type())
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
sval := flag.Value.String()
|
||||||
|
result, err := convFunc(sval)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ArgsLenAtDash will return the length of f.Args at the moment when a -- was
|
||||||
|
// found during arg parsing. This allows your program to know which args were
|
||||||
|
// before the -- and which came after.
|
||||||
|
func (f *FlagSet) ArgsLenAtDash() int {
|
||||||
|
return f.argsLenAtDash
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarkDeprecated indicated that a flag is deprecated in your program. It will
|
||||||
|
// continue to function but will not show up in help or usage messages. Using
|
||||||
|
// this flag will also print the given usageMessage.
|
||||||
func (f *FlagSet) MarkDeprecated(name string, usageMessage string) error {
|
func (f *FlagSet) MarkDeprecated(name string, usageMessage string) error {
|
||||||
flag := f.Lookup(name)
|
flag := f.Lookup(name)
|
||||||
if flag == nil {
|
if flag == nil {
|
||||||
return fmt.Errorf("flag %q does not exist", name)
|
return fmt.Errorf("flag %q does not exist", name)
|
||||||
}
|
}
|
||||||
|
if len(usageMessage) == 0 {
|
||||||
|
return fmt.Errorf("deprecated message for flag %q must be set", name)
|
||||||
|
}
|
||||||
flag.Deprecated = usageMessage
|
flag.Deprecated = usageMessage
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MarkShorthandDeprecated will mark the shorthand of a flag deprecated in your
|
||||||
|
// program. It will continue to function but will not show up in help or usage
|
||||||
|
// messages. Using this flag will also print the given usageMessage.
|
||||||
|
func (f *FlagSet) MarkShorthandDeprecated(name string, usageMessage string) error {
|
||||||
|
flag := f.Lookup(name)
|
||||||
|
if flag == nil {
|
||||||
|
return fmt.Errorf("flag %q does not exist", name)
|
||||||
|
}
|
||||||
|
if len(usageMessage) == 0 {
|
||||||
|
return fmt.Errorf("deprecated message for flag %q must be set", name)
|
||||||
|
}
|
||||||
|
flag.ShorthandDeprecated = usageMessage
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarkHidden sets a flag to 'hidden' in your program. It will continue to
|
||||||
|
// function but will not show up in help or usage messages.
|
||||||
|
func (f *FlagSet) MarkHidden(name string) error {
|
||||||
|
flag := f.Lookup(name)
|
||||||
|
if flag == nil {
|
||||||
|
return fmt.Errorf("flag %q does not exist", name)
|
||||||
|
}
|
||||||
|
flag.Hidden = true
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// Lookup returns the Flag structure of the named command-line flag,
|
// Lookup returns the Flag structure of the named command-line flag,
|
||||||
// returning nil if none exists.
|
// returning nil if none exists.
|
||||||
func Lookup(name string) *Flag {
|
func Lookup(name string) *Flag {
|
||||||
|
@ -295,6 +380,33 @@ func (f *FlagSet) Set(name, value string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetAnnotation allows one to set arbitrary annotations on a flag in the FlagSet.
|
||||||
|
// This is sometimes used by spf13/cobra programs which want to generate additional
|
||||||
|
// bash completion information.
|
||||||
|
func (f *FlagSet) SetAnnotation(name, key string, values []string) error {
|
||||||
|
normalName := f.normalizeFlagName(name)
|
||||||
|
flag, ok := f.formal[normalName]
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("no such flag -%v", name)
|
||||||
|
}
|
||||||
|
if flag.Annotations == nil {
|
||||||
|
flag.Annotations = map[string][]string{}
|
||||||
|
}
|
||||||
|
flag.Annotations[key] = values
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Changed returns true if the flag was explicitly set during Parse() and false
|
||||||
|
// otherwise
|
||||||
|
func (f *FlagSet) Changed(name string) bool {
|
||||||
|
flag := f.Lookup(name)
|
||||||
|
// If a flag doesn't exist, it wasn't changed....
|
||||||
|
if flag == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return flag.Changed
|
||||||
|
}
|
||||||
|
|
||||||
// Set sets the value of the named command-line flag.
|
// Set sets the value of the named command-line flag.
|
||||||
func Set(name, value string) error {
|
func Set(name, value string) error {
|
||||||
return CommandLine.Set(name, value)
|
return CommandLine.Set(name, value)
|
||||||
|
@ -303,44 +415,140 @@ func Set(name, value string) error {
|
||||||
// PrintDefaults prints, to standard error unless configured
|
// PrintDefaults prints, to standard error unless configured
|
||||||
// otherwise, the default values of all defined flags in the set.
|
// otherwise, the default values of all defined flags in the set.
|
||||||
func (f *FlagSet) PrintDefaults() {
|
func (f *FlagSet) PrintDefaults() {
|
||||||
f.VisitAll(func(flag *Flag) {
|
usages := f.FlagUsages()
|
||||||
if len(flag.Deprecated) > 0 {
|
fmt.Fprint(f.out(), usages)
|
||||||
return
|
|
||||||
}
|
|
||||||
format := "--%s=%s: %s\n"
|
|
||||||
if _, ok := flag.Value.(*stringValue); ok {
|
|
||||||
// put quotes on the value
|
|
||||||
format = "--%s=%q: %s\n"
|
|
||||||
}
|
|
||||||
if len(flag.Shorthand) > 0 {
|
|
||||||
format = " -%s, " + format
|
|
||||||
} else {
|
|
||||||
format = " %s " + format
|
|
||||||
}
|
|
||||||
fmt.Fprintf(f.out(), format, flag.Shorthand, flag.Name, flag.DefValue, flag.Usage)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// defaultIsZeroValue returns true if the default value for this flag represents
|
||||||
|
// a zero value.
|
||||||
|
func (f *Flag) defaultIsZeroValue() bool {
|
||||||
|
switch f.Value.(type) {
|
||||||
|
case boolFlag:
|
||||||
|
return f.DefValue == "false"
|
||||||
|
case *durationValue:
|
||||||
|
// Beginning in Go 1.7, duration zero values are "0s"
|
||||||
|
return f.DefValue == "0" || f.DefValue == "0s"
|
||||||
|
case *intValue, *int8Value, *int32Value, *int64Value, *uintValue, *uint8Value, *uint16Value, *uint32Value, *uint64Value, *countValue, *float32Value, *float64Value:
|
||||||
|
return f.DefValue == "0"
|
||||||
|
case *stringValue:
|
||||||
|
return f.DefValue == ""
|
||||||
|
case *ipValue, *ipMaskValue, *ipNetValue:
|
||||||
|
return f.DefValue == "<nil>"
|
||||||
|
case *intSliceValue, *stringSliceValue, *stringArrayValue:
|
||||||
|
return f.DefValue == "[]"
|
||||||
|
default:
|
||||||
|
switch f.Value.String() {
|
||||||
|
case "false":
|
||||||
|
return true
|
||||||
|
case "<nil>":
|
||||||
|
return true
|
||||||
|
case "":
|
||||||
|
return true
|
||||||
|
case "0":
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnquoteUsage extracts a back-quoted name from the usage
|
||||||
|
// string for a flag and returns it and the un-quoted usage.
|
||||||
|
// Given "a `name` to show" it returns ("name", "a name to show").
|
||||||
|
// If there are no back quotes, the name is an educated guess of the
|
||||||
|
// type of the flag's value, or the empty string if the flag is boolean.
|
||||||
|
func UnquoteUsage(flag *Flag) (name string, usage string) {
|
||||||
|
// Look for a back-quoted name, but avoid the strings package.
|
||||||
|
usage = flag.Usage
|
||||||
|
for i := 0; i < len(usage); i++ {
|
||||||
|
if usage[i] == '`' {
|
||||||
|
for j := i + 1; j < len(usage); j++ {
|
||||||
|
if usage[j] == '`' {
|
||||||
|
name = usage[i+1 : j]
|
||||||
|
usage = usage[:i] + name + usage[j+1:]
|
||||||
|
return name, usage
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break // Only one back quote; use type name.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
name = flag.Value.Type()
|
||||||
|
switch name {
|
||||||
|
case "bool":
|
||||||
|
name = ""
|
||||||
|
case "float64":
|
||||||
|
name = "float"
|
||||||
|
case "int64":
|
||||||
|
name = "int"
|
||||||
|
case "uint64":
|
||||||
|
name = "uint"
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// FlagUsages Returns a string containing the usage information for all flags in
|
||||||
|
// the FlagSet
|
||||||
func (f *FlagSet) FlagUsages() string {
|
func (f *FlagSet) FlagUsages() string {
|
||||||
x := new(bytes.Buffer)
|
x := new(bytes.Buffer)
|
||||||
|
|
||||||
|
lines := make([]string, 0, len(f.formal))
|
||||||
|
|
||||||
|
maxlen := 0
|
||||||
f.VisitAll(func(flag *Flag) {
|
f.VisitAll(func(flag *Flag) {
|
||||||
if len(flag.Deprecated) > 0 {
|
if len(flag.Deprecated) > 0 || flag.Hidden {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
format := "--%s=%s: %s\n"
|
|
||||||
if _, ok := flag.Value.(*stringValue); ok {
|
line := ""
|
||||||
// put quotes on the value
|
if len(flag.Shorthand) > 0 && len(flag.ShorthandDeprecated) == 0 {
|
||||||
format = "--%s=%q: %s\n"
|
line = fmt.Sprintf(" -%s, --%s", flag.Shorthand, flag.Name)
|
||||||
}
|
|
||||||
if len(flag.Shorthand) > 0 {
|
|
||||||
format = " -%s, " + format
|
|
||||||
} else {
|
} else {
|
||||||
format = " %s " + format
|
line = fmt.Sprintf(" --%s", flag.Name)
|
||||||
}
|
}
|
||||||
fmt.Fprintf(x, format, flag.Shorthand, flag.Name, flag.DefValue, flag.Usage)
|
|
||||||
|
varname, usage := UnquoteUsage(flag)
|
||||||
|
if len(varname) > 0 {
|
||||||
|
line += " " + varname
|
||||||
|
}
|
||||||
|
if len(flag.NoOptDefVal) > 0 {
|
||||||
|
switch flag.Value.Type() {
|
||||||
|
case "string":
|
||||||
|
line += fmt.Sprintf("[=\"%s\"]", flag.NoOptDefVal)
|
||||||
|
case "bool":
|
||||||
|
if flag.NoOptDefVal != "true" {
|
||||||
|
line += fmt.Sprintf("[=%s]", flag.NoOptDefVal)
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
line += fmt.Sprintf("[=%s]", flag.NoOptDefVal)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// This special character will be replaced with spacing once the
|
||||||
|
// correct alignment is calculated
|
||||||
|
line += "\x00"
|
||||||
|
if len(line) > maxlen {
|
||||||
|
maxlen = len(line)
|
||||||
|
}
|
||||||
|
|
||||||
|
line += usage
|
||||||
|
if !flag.defaultIsZeroValue() {
|
||||||
|
if flag.Value.Type() == "string" {
|
||||||
|
line += fmt.Sprintf(" (default \"%s\")", flag.DefValue)
|
||||||
|
} else {
|
||||||
|
line += fmt.Sprintf(" (default %s)", flag.DefValue)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lines = append(lines, line)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
for _, line := range lines {
|
||||||
|
sidx := strings.Index(line, "\x00")
|
||||||
|
spacing := strings.Repeat(" ", maxlen-sidx)
|
||||||
|
fmt.Fprintln(x, line[:sidx], spacing, line[sidx+1:])
|
||||||
|
}
|
||||||
|
|
||||||
return x.String()
|
return x.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -361,6 +569,8 @@ func defaultUsage(f *FlagSet) {
|
||||||
|
|
||||||
// Usage prints to standard error a usage message documenting all defined command-line flags.
|
// Usage prints to standard error a usage message documenting all defined command-line flags.
|
||||||
// The function is a variable that may be changed to point to a custom function.
|
// The function is a variable that may be changed to point to a custom function.
|
||||||
|
// By default it prints a simple header and calls PrintDefaults; for details about the
|
||||||
|
// format of the output and how to control it, see the documentation for PrintDefaults.
|
||||||
var Usage = func() {
|
var Usage = func() {
|
||||||
fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0])
|
fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0])
|
||||||
PrintDefaults()
|
PrintDefaults()
|
||||||
|
@ -409,8 +619,8 @@ func (f *FlagSet) Var(value Value, name string, usage string) {
|
||||||
f.VarP(value, name, "", usage)
|
f.VarP(value, name, "", usage)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Like Var, but accepts a shorthand letter that can be used after a single dash.
|
// VarPF is like VarP, but returns the flag created
|
||||||
func (f *FlagSet) VarP(value Value, name, shorthand, usage string) {
|
func (f *FlagSet) VarPF(value Value, name, shorthand, usage string) *Flag {
|
||||||
// Remember the default value as a string; it won't change.
|
// Remember the default value as a string; it won't change.
|
||||||
flag := &Flag{
|
flag := &Flag{
|
||||||
Name: name,
|
Name: name,
|
||||||
|
@ -420,11 +630,18 @@ func (f *FlagSet) VarP(value Value, name, shorthand, usage string) {
|
||||||
DefValue: value.String(),
|
DefValue: value.String(),
|
||||||
}
|
}
|
||||||
f.AddFlag(flag)
|
f.AddFlag(flag)
|
||||||
|
return flag
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// VarP is like Var, but accepts a shorthand letter that can be used after a single dash.
|
||||||
|
func (f *FlagSet) VarP(value Value, name, shorthand, usage string) {
|
||||||
|
_ = f.VarPF(value, name, shorthand, usage)
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddFlag will add the flag to the FlagSet
|
||||||
func (f *FlagSet) AddFlag(flag *Flag) {
|
func (f *FlagSet) AddFlag(flag *Flag) {
|
||||||
// Call normalizeFlagName function only once
|
// Call normalizeFlagName function only once
|
||||||
var normalizedFlagName NormalizedName = f.normalizeFlagName(flag.Name)
|
normalizedFlagName := f.normalizeFlagName(flag.Name)
|
||||||
|
|
||||||
_, alreadythere := f.formal[normalizedFlagName]
|
_, alreadythere := f.formal[normalizedFlagName]
|
||||||
if alreadythere {
|
if alreadythere {
|
||||||
|
@ -458,6 +675,19 @@ func (f *FlagSet) AddFlag(flag *Flag) {
|
||||||
f.shorthands[c] = flag
|
f.shorthands[c] = flag
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AddFlagSet adds one FlagSet to another. If a flag is already present in f
|
||||||
|
// the flag from newSet will be ignored
|
||||||
|
func (f *FlagSet) AddFlagSet(newSet *FlagSet) {
|
||||||
|
if newSet == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
newSet.VisitAll(func(flag *Flag) {
|
||||||
|
if f.Lookup(flag.Name) == nil {
|
||||||
|
f.AddFlag(flag)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// Var defines a flag with the specified name and usage string. The type and
|
// Var defines a flag with the specified name and usage string. The type and
|
||||||
// value of the flag are represented by the first argument, of type Value, which
|
// value of the flag are represented by the first argument, of type Value, which
|
||||||
// typically holds a user-defined implementation of Value. For instance, the
|
// typically holds a user-defined implementation of Value. For instance, the
|
||||||
|
@ -468,7 +698,7 @@ func Var(value Value, name string, usage string) {
|
||||||
CommandLine.VarP(value, name, "", usage)
|
CommandLine.VarP(value, name, "", usage)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Like Var, but accepts a shorthand letter that can be used after a single dash.
|
// VarP is like Var, but accepts a shorthand letter that can be used after a single dash.
|
||||||
func VarP(value Value, name, shorthand, usage string) {
|
func VarP(value Value, name, shorthand, usage string) {
|
||||||
CommandLine.VarP(value, name, shorthand, usage)
|
CommandLine.VarP(value, name, shorthand, usage)
|
||||||
}
|
}
|
||||||
|
@ -507,9 +737,21 @@ func (f *FlagSet) setFlag(flag *Flag, value string, origArg string) error {
|
||||||
if len(flag.Deprecated) > 0 {
|
if len(flag.Deprecated) > 0 {
|
||||||
fmt.Fprintf(os.Stderr, "Flag --%s has been deprecated, %s\n", flag.Name, flag.Deprecated)
|
fmt.Fprintf(os.Stderr, "Flag --%s has been deprecated, %s\n", flag.Name, flag.Deprecated)
|
||||||
}
|
}
|
||||||
|
if len(flag.ShorthandDeprecated) > 0 && containsShorthand(origArg, flag.Shorthand) {
|
||||||
|
fmt.Fprintf(os.Stderr, "Flag shorthand -%s has been deprecated, %s\n", flag.Shorthand, flag.ShorthandDeprecated)
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func containsShorthand(arg, shorthand string) bool {
|
||||||
|
// filter out flags --<flag_name>
|
||||||
|
if strings.HasPrefix(arg, "-") {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
arg = strings.SplitN(arg, "=", 2)[0]
|
||||||
|
return strings.Contains(arg, shorthand)
|
||||||
|
}
|
||||||
|
|
||||||
func (f *FlagSet) parseLongArg(s string, args []string) (a []string, err error) {
|
func (f *FlagSet) parseLongArg(s string, args []string) (a []string, err error) {
|
||||||
a = args
|
a = args
|
||||||
name := s[2:]
|
name := s[2:]
|
||||||
|
@ -532,11 +774,15 @@ func (f *FlagSet) parseLongArg(s string, args []string) (a []string, err error)
|
||||||
if len(split) == 2 {
|
if len(split) == 2 {
|
||||||
// '--flag=arg'
|
// '--flag=arg'
|
||||||
value = split[1]
|
value = split[1]
|
||||||
} else if bv, ok := flag.Value.(boolFlag); ok && bv.IsBoolFlag() {
|
} else if len(flag.NoOptDefVal) > 0 {
|
||||||
// '--flag' (where flag is a bool)
|
// '--flag' (arg was optional)
|
||||||
value = "true"
|
value = flag.NoOptDefVal
|
||||||
|
} else if len(a) > 0 {
|
||||||
|
// '--flag arg'
|
||||||
|
value = a[0]
|
||||||
|
a = a[1:]
|
||||||
} else {
|
} else {
|
||||||
// '--flag' (where flag was not a bool)
|
// '--flag' (arg was required)
|
||||||
err = f.failf("flag needs an argument: %s", s)
|
err = f.failf("flag needs an argument: %s", s)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -545,6 +791,9 @@ func (f *FlagSet) parseLongArg(s string, args []string) (a []string, err error)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *FlagSet) parseSingleShortArg(shorthands string, args []string) (outShorts string, outArgs []string, err error) {
|
func (f *FlagSet) parseSingleShortArg(shorthands string, args []string) (outShorts string, outArgs []string, err error) {
|
||||||
|
if strings.HasPrefix(shorthands, "test.") {
|
||||||
|
return
|
||||||
|
}
|
||||||
outArgs = args
|
outArgs = args
|
||||||
outShorts = shorthands[1:]
|
outShorts = shorthands[1:]
|
||||||
c := shorthands[0]
|
c := shorthands[0]
|
||||||
|
@ -564,8 +813,8 @@ func (f *FlagSet) parseSingleShortArg(shorthands string, args []string) (outShor
|
||||||
if len(shorthands) > 2 && shorthands[1] == '=' {
|
if len(shorthands) > 2 && shorthands[1] == '=' {
|
||||||
value = shorthands[2:]
|
value = shorthands[2:]
|
||||||
outShorts = ""
|
outShorts = ""
|
||||||
} else if bv, ok := flag.Value.(boolFlag); ok && bv.IsBoolFlag() {
|
} else if len(flag.NoOptDefVal) > 0 {
|
||||||
value = "true"
|
value = flag.NoOptDefVal
|
||||||
} else if len(shorthands) > 1 {
|
} else if len(shorthands) > 1 {
|
||||||
value = shorthands[1:]
|
value = shorthands[1:]
|
||||||
outShorts = ""
|
outShorts = ""
|
||||||
|
@ -610,6 +859,7 @@ func (f *FlagSet) parseArgs(args []string) (err error) {
|
||||||
|
|
||||||
if s[1] == '-' {
|
if s[1] == '-' {
|
||||||
if len(s) == 2 { // "--" terminates the flags
|
if len(s) == 2 { // "--" terminates the flags
|
||||||
|
f.argsLenAtDash = len(f.args)
|
||||||
f.args = append(f.args, args...)
|
f.args = append(f.args, args...)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
@ -657,7 +907,7 @@ func Parse() {
|
||||||
CommandLine.Parse(os.Args[1:])
|
CommandLine.Parse(os.Args[1:])
|
||||||
}
|
}
|
||||||
|
|
||||||
// Whether to support interspersed option/non-option arguments.
|
// SetInterspersed sets whether to support interspersed option/non-option arguments.
|
||||||
func SetInterspersed(interspersed bool) {
|
func SetInterspersed(interspersed bool) {
|
||||||
CommandLine.SetInterspersed(interspersed)
|
CommandLine.SetInterspersed(interspersed)
|
||||||
}
|
}
|
||||||
|
@ -667,7 +917,7 @@ func Parsed() bool {
|
||||||
return CommandLine.Parsed()
|
return CommandLine.Parsed()
|
||||||
}
|
}
|
||||||
|
|
||||||
// The default set of command-line flags, parsed from os.Args.
|
// CommandLine is the default set of command-line flags, parsed from os.Args.
|
||||||
var CommandLine = NewFlagSet(os.Args[0], ExitOnError)
|
var CommandLine = NewFlagSet(os.Args[0], ExitOnError)
|
||||||
|
|
||||||
// NewFlagSet returns a new, empty flag set with the specified name and
|
// NewFlagSet returns a new, empty flag set with the specified name and
|
||||||
|
@ -676,12 +926,13 @@ func NewFlagSet(name string, errorHandling ErrorHandling) *FlagSet {
|
||||||
f := &FlagSet{
|
f := &FlagSet{
|
||||||
name: name,
|
name: name,
|
||||||
errorHandling: errorHandling,
|
errorHandling: errorHandling,
|
||||||
|
argsLenAtDash: -1,
|
||||||
interspersed: true,
|
interspersed: true,
|
||||||
}
|
}
|
||||||
return f
|
return f
|
||||||
}
|
}
|
||||||
|
|
||||||
// Whether to support interspersed option/non-option arguments.
|
// SetInterspersed sets whether to support interspersed option/non-option arguments.
|
||||||
func (f *FlagSet) SetInterspersed(interspersed bool) {
|
func (f *FlagSet) SetInterspersed(interspersed bool) {
|
||||||
f.interspersed = interspersed
|
f.interspersed = interspersed
|
||||||
}
|
}
|
||||||
|
@ -692,4 +943,5 @@ func (f *FlagSet) SetInterspersed(interspersed bool) {
|
||||||
func (f *FlagSet) Init(name string, errorHandling ErrorHandling) {
|
func (f *FlagSet) Init(name string, errorHandling ErrorHandling) {
|
||||||
f.name = name
|
f.name = name
|
||||||
f.errorHandling = errorHandling
|
f.errorHandling = errorHandling
|
||||||
|
f.argsLenAtDash = -1
|
||||||
}
|
}
|
||||||
|
|
32
vendor/github.com/spf13/pflag/float32.go
generated
vendored
32
vendor/github.com/spf13/pflag/float32.go
generated
vendored
|
@ -1,9 +1,6 @@
|
||||||
package pflag
|
package pflag
|
||||||
|
|
||||||
import (
|
import "strconv"
|
||||||
"fmt"
|
|
||||||
"strconv"
|
|
||||||
)
|
|
||||||
|
|
||||||
// -- float32 Value
|
// -- float32 Value
|
||||||
type float32Value float32
|
type float32Value float32
|
||||||
|
@ -23,7 +20,24 @@ func (f *float32Value) Type() string {
|
||||||
return "float32"
|
return "float32"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *float32Value) String() string { return fmt.Sprintf("%v", *f) }
|
func (f *float32Value) String() string { return strconv.FormatFloat(float64(*f), 'g', -1, 32) }
|
||||||
|
|
||||||
|
func float32Conv(sval string) (interface{}, error) {
|
||||||
|
v, err := strconv.ParseFloat(sval, 32)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
return float32(v), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetFloat32 return the float32 value of a flag with the given name
|
||||||
|
func (f *FlagSet) GetFloat32(name string) (float32, error) {
|
||||||
|
val, err := f.getFlagType(name, "float32", float32Conv)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
return val.(float32), nil
|
||||||
|
}
|
||||||
|
|
||||||
// Float32Var defines a float32 flag with specified name, default value, and usage string.
|
// Float32Var defines a float32 flag with specified name, default value, and usage string.
|
||||||
// The argument p points to a float32 variable in which to store the value of the flag.
|
// The argument p points to a float32 variable in which to store the value of the flag.
|
||||||
|
@ -31,7 +45,7 @@ func (f *FlagSet) Float32Var(p *float32, name string, value float32, usage strin
|
||||||
f.VarP(newFloat32Value(value, p), name, "", usage)
|
f.VarP(newFloat32Value(value, p), name, "", usage)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Like Float32Var, but accepts a shorthand letter that can be used after a single dash.
|
// Float32VarP is like Float32Var, but accepts a shorthand letter that can be used after a single dash.
|
||||||
func (f *FlagSet) Float32VarP(p *float32, name, shorthand string, value float32, usage string) {
|
func (f *FlagSet) Float32VarP(p *float32, name, shorthand string, value float32, usage string) {
|
||||||
f.VarP(newFloat32Value(value, p), name, shorthand, usage)
|
f.VarP(newFloat32Value(value, p), name, shorthand, usage)
|
||||||
}
|
}
|
||||||
|
@ -42,7 +56,7 @@ func Float32Var(p *float32, name string, value float32, usage string) {
|
||||||
CommandLine.VarP(newFloat32Value(value, p), name, "", usage)
|
CommandLine.VarP(newFloat32Value(value, p), name, "", usage)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Like Float32Var, but accepts a shorthand letter that can be used after a single dash.
|
// Float32VarP is like Float32Var, but accepts a shorthand letter that can be used after a single dash.
|
||||||
func Float32VarP(p *float32, name, shorthand string, value float32, usage string) {
|
func Float32VarP(p *float32, name, shorthand string, value float32, usage string) {
|
||||||
CommandLine.VarP(newFloat32Value(value, p), name, shorthand, usage)
|
CommandLine.VarP(newFloat32Value(value, p), name, shorthand, usage)
|
||||||
}
|
}
|
||||||
|
@ -55,7 +69,7 @@ func (f *FlagSet) Float32(name string, value float32, usage string) *float32 {
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
// Like Float32, but accepts a shorthand letter that can be used after a single dash.
|
// Float32P is like Float32, but accepts a shorthand letter that can be used after a single dash.
|
||||||
func (f *FlagSet) Float32P(name, shorthand string, value float32, usage string) *float32 {
|
func (f *FlagSet) Float32P(name, shorthand string, value float32, usage string) *float32 {
|
||||||
p := new(float32)
|
p := new(float32)
|
||||||
f.Float32VarP(p, name, shorthand, value, usage)
|
f.Float32VarP(p, name, shorthand, value, usage)
|
||||||
|
@ -68,7 +82,7 @@ func Float32(name string, value float32, usage string) *float32 {
|
||||||
return CommandLine.Float32P(name, "", value, usage)
|
return CommandLine.Float32P(name, "", value, usage)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Like Float32, but accepts a shorthand letter that can be used after a single dash.
|
// Float32P is like Float32, but accepts a shorthand letter that can be used after a single dash.
|
||||||
func Float32P(name, shorthand string, value float32, usage string) *float32 {
|
func Float32P(name, shorthand string, value float32, usage string) *float32 {
|
||||||
return CommandLine.Float32P(name, shorthand, value, usage)
|
return CommandLine.Float32P(name, shorthand, value, usage)
|
||||||
}
|
}
|
||||||
|
|
28
vendor/github.com/spf13/pflag/float64.go
generated
vendored
28
vendor/github.com/spf13/pflag/float64.go
generated
vendored
|
@ -1,9 +1,6 @@
|
||||||
package pflag
|
package pflag
|
||||||
|
|
||||||
import (
|
import "strconv"
|
||||||
"fmt"
|
|
||||||
"strconv"
|
|
||||||
)
|
|
||||||
|
|
||||||
// -- float64 Value
|
// -- float64 Value
|
||||||
type float64Value float64
|
type float64Value float64
|
||||||
|
@ -23,7 +20,20 @@ func (f *float64Value) Type() string {
|
||||||
return "float64"
|
return "float64"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *float64Value) String() string { return fmt.Sprintf("%v", *f) }
|
func (f *float64Value) String() string { return strconv.FormatFloat(float64(*f), 'g', -1, 64) }
|
||||||
|
|
||||||
|
func float64Conv(sval string) (interface{}, error) {
|
||||||
|
return strconv.ParseFloat(sval, 64)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetFloat64 return the float64 value of a flag with the given name
|
||||||
|
func (f *FlagSet) GetFloat64(name string) (float64, error) {
|
||||||
|
val, err := f.getFlagType(name, "float64", float64Conv)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
return val.(float64), nil
|
||||||
|
}
|
||||||
|
|
||||||
// Float64Var defines a float64 flag with specified name, default value, and usage string.
|
// Float64Var defines a float64 flag with specified name, default value, and usage string.
|
||||||
// The argument p points to a float64 variable in which to store the value of the flag.
|
// The argument p points to a float64 variable in which to store the value of the flag.
|
||||||
|
@ -31,7 +41,7 @@ func (f *FlagSet) Float64Var(p *float64, name string, value float64, usage strin
|
||||||
f.VarP(newFloat64Value(value, p), name, "", usage)
|
f.VarP(newFloat64Value(value, p), name, "", usage)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Like Float64Var, but accepts a shorthand letter that can be used after a single dash.
|
// Float64VarP is like Float64Var, but accepts a shorthand letter that can be used after a single dash.
|
||||||
func (f *FlagSet) Float64VarP(p *float64, name, shorthand string, value float64, usage string) {
|
func (f *FlagSet) Float64VarP(p *float64, name, shorthand string, value float64, usage string) {
|
||||||
f.VarP(newFloat64Value(value, p), name, shorthand, usage)
|
f.VarP(newFloat64Value(value, p), name, shorthand, usage)
|
||||||
}
|
}
|
||||||
|
@ -42,7 +52,7 @@ func Float64Var(p *float64, name string, value float64, usage string) {
|
||||||
CommandLine.VarP(newFloat64Value(value, p), name, "", usage)
|
CommandLine.VarP(newFloat64Value(value, p), name, "", usage)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Like Float64Var, but accepts a shorthand letter that can be used after a single dash.
|
// Float64VarP is like Float64Var, but accepts a shorthand letter that can be used after a single dash.
|
||||||
func Float64VarP(p *float64, name, shorthand string, value float64, usage string) {
|
func Float64VarP(p *float64, name, shorthand string, value float64, usage string) {
|
||||||
CommandLine.VarP(newFloat64Value(value, p), name, shorthand, usage)
|
CommandLine.VarP(newFloat64Value(value, p), name, shorthand, usage)
|
||||||
}
|
}
|
||||||
|
@ -55,7 +65,7 @@ func (f *FlagSet) Float64(name string, value float64, usage string) *float64 {
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
// Like Float64, but accepts a shorthand letter that can be used after a single dash.
|
// Float64P is like Float64, but accepts a shorthand letter that can be used after a single dash.
|
||||||
func (f *FlagSet) Float64P(name, shorthand string, value float64, usage string) *float64 {
|
func (f *FlagSet) Float64P(name, shorthand string, value float64, usage string) *float64 {
|
||||||
p := new(float64)
|
p := new(float64)
|
||||||
f.Float64VarP(p, name, shorthand, value, usage)
|
f.Float64VarP(p, name, shorthand, value, usage)
|
||||||
|
@ -68,7 +78,7 @@ func Float64(name string, value float64, usage string) *float64 {
|
||||||
return CommandLine.Float64P(name, "", value, usage)
|
return CommandLine.Float64P(name, "", value, usage)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Like Float64, but accepts a shorthand letter that can be used after a single dash.
|
// Float64P is like Float64, but accepts a shorthand letter that can be used after a single dash.
|
||||||
func Float64P(name, shorthand string, value float64, usage string) *float64 {
|
func Float64P(name, shorthand string, value float64, usage string) *float64 {
|
||||||
return CommandLine.Float64P(name, shorthand, value, usage)
|
return CommandLine.Float64P(name, shorthand, value, usage)
|
||||||
}
|
}
|
||||||
|
|
104
vendor/github.com/spf13/pflag/golangflag.go
generated
vendored
Normal file
104
vendor/github.com/spf13/pflag/golangflag.go
generated
vendored
Normal file
|
@ -0,0 +1,104 @@
|
||||||
|
// Copyright 2009 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package pflag
|
||||||
|
|
||||||
|
import (
|
||||||
|
goflag "flag"
|
||||||
|
"fmt"
|
||||||
|
"reflect"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ = fmt.Print
|
||||||
|
|
||||||
|
// flagValueWrapper implements pflag.Value around a flag.Value. The main
|
||||||
|
// difference here is the addition of the Type method that returns a string
|
||||||
|
// name of the type. As this is generally unknown, we approximate that with
|
||||||
|
// reflection.
|
||||||
|
type flagValueWrapper struct {
|
||||||
|
inner goflag.Value
|
||||||
|
flagType string
|
||||||
|
}
|
||||||
|
|
||||||
|
// We are just copying the boolFlag interface out of goflag as that is what
|
||||||
|
// they use to decide if a flag should get "true" when no arg is given.
|
||||||
|
type goBoolFlag interface {
|
||||||
|
goflag.Value
|
||||||
|
IsBoolFlag() bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func wrapFlagValue(v goflag.Value) Value {
|
||||||
|
// If the flag.Value happens to also be a pflag.Value, just use it directly.
|
||||||
|
if pv, ok := v.(Value); ok {
|
||||||
|
return pv
|
||||||
|
}
|
||||||
|
|
||||||
|
pv := &flagValueWrapper{
|
||||||
|
inner: v,
|
||||||
|
}
|
||||||
|
|
||||||
|
t := reflect.TypeOf(v)
|
||||||
|
if t.Kind() == reflect.Interface || t.Kind() == reflect.Ptr {
|
||||||
|
t = t.Elem()
|
||||||
|
}
|
||||||
|
|
||||||
|
pv.flagType = strings.TrimSuffix(t.Name(), "Value")
|
||||||
|
return pv
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *flagValueWrapper) String() string {
|
||||||
|
return v.inner.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *flagValueWrapper) Set(s string) error {
|
||||||
|
return v.inner.Set(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *flagValueWrapper) Type() string {
|
||||||
|
return v.flagType
|
||||||
|
}
|
||||||
|
|
||||||
|
// PFlagFromGoFlag will return a *pflag.Flag given a *flag.Flag
|
||||||
|
// If the *flag.Flag.Name was a single character (ex: `v`) it will be accessiblei
|
||||||
|
// with both `-v` and `--v` in flags. If the golang flag was more than a single
|
||||||
|
// character (ex: `verbose`) it will only be accessible via `--verbose`
|
||||||
|
func PFlagFromGoFlag(goflag *goflag.Flag) *Flag {
|
||||||
|
// Remember the default value as a string; it won't change.
|
||||||
|
flag := &Flag{
|
||||||
|
Name: goflag.Name,
|
||||||
|
Usage: goflag.Usage,
|
||||||
|
Value: wrapFlagValue(goflag.Value),
|
||||||
|
// Looks like golang flags don't set DefValue correctly :-(
|
||||||
|
//DefValue: goflag.DefValue,
|
||||||
|
DefValue: goflag.Value.String(),
|
||||||
|
}
|
||||||
|
// Ex: if the golang flag was -v, allow both -v and --v to work
|
||||||
|
if len(flag.Name) == 1 {
|
||||||
|
flag.Shorthand = flag.Name
|
||||||
|
}
|
||||||
|
if fv, ok := goflag.Value.(goBoolFlag); ok && fv.IsBoolFlag() {
|
||||||
|
flag.NoOptDefVal = "true"
|
||||||
|
}
|
||||||
|
return flag
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddGoFlag will add the given *flag.Flag to the pflag.FlagSet
|
||||||
|
func (f *FlagSet) AddGoFlag(goflag *goflag.Flag) {
|
||||||
|
if f.Lookup(goflag.Name) != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
newflag := PFlagFromGoFlag(goflag)
|
||||||
|
f.AddFlag(newflag)
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddGoFlagSet will add the given *flag.FlagSet to the pflag.FlagSet
|
||||||
|
func (f *FlagSet) AddGoFlagSet(newSet *goflag.FlagSet) {
|
||||||
|
if newSet == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
newSet.VisitAll(func(goflag *goflag.Flag) {
|
||||||
|
f.AddGoFlag(goflag)
|
||||||
|
})
|
||||||
|
}
|
28
vendor/github.com/spf13/pflag/int.go
generated
vendored
28
vendor/github.com/spf13/pflag/int.go
generated
vendored
|
@ -1,9 +1,6 @@
|
||||||
package pflag
|
package pflag
|
||||||
|
|
||||||
import (
|
import "strconv"
|
||||||
"fmt"
|
|
||||||
"strconv"
|
|
||||||
)
|
|
||||||
|
|
||||||
// -- int Value
|
// -- int Value
|
||||||
type intValue int
|
type intValue int
|
||||||
|
@ -23,7 +20,20 @@ func (i *intValue) Type() string {
|
||||||
return "int"
|
return "int"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *intValue) String() string { return fmt.Sprintf("%v", *i) }
|
func (i *intValue) String() string { return strconv.Itoa(int(*i)) }
|
||||||
|
|
||||||
|
func intConv(sval string) (interface{}, error) {
|
||||||
|
return strconv.Atoi(sval)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetInt return the int value of a flag with the given name
|
||||||
|
func (f *FlagSet) GetInt(name string) (int, error) {
|
||||||
|
val, err := f.getFlagType(name, "int", intConv)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
return val.(int), nil
|
||||||
|
}
|
||||||
|
|
||||||
// IntVar defines an int flag with specified name, default value, and usage string.
|
// IntVar defines an int flag with specified name, default value, and usage string.
|
||||||
// The argument p points to an int variable in which to store the value of the flag.
|
// The argument p points to an int variable in which to store the value of the flag.
|
||||||
|
@ -31,7 +41,7 @@ func (f *FlagSet) IntVar(p *int, name string, value int, usage string) {
|
||||||
f.VarP(newIntValue(value, p), name, "", usage)
|
f.VarP(newIntValue(value, p), name, "", usage)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Like IntVar, but accepts a shorthand letter that can be used after a single dash.
|
// IntVarP is like IntVar, but accepts a shorthand letter that can be used after a single dash.
|
||||||
func (f *FlagSet) IntVarP(p *int, name, shorthand string, value int, usage string) {
|
func (f *FlagSet) IntVarP(p *int, name, shorthand string, value int, usage string) {
|
||||||
f.VarP(newIntValue(value, p), name, shorthand, usage)
|
f.VarP(newIntValue(value, p), name, shorthand, usage)
|
||||||
}
|
}
|
||||||
|
@ -42,7 +52,7 @@ func IntVar(p *int, name string, value int, usage string) {
|
||||||
CommandLine.VarP(newIntValue(value, p), name, "", usage)
|
CommandLine.VarP(newIntValue(value, p), name, "", usage)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Like IntVar, but accepts a shorthand letter that can be used after a single dash.
|
// IntVarP is like IntVar, but accepts a shorthand letter that can be used after a single dash.
|
||||||
func IntVarP(p *int, name, shorthand string, value int, usage string) {
|
func IntVarP(p *int, name, shorthand string, value int, usage string) {
|
||||||
CommandLine.VarP(newIntValue(value, p), name, shorthand, usage)
|
CommandLine.VarP(newIntValue(value, p), name, shorthand, usage)
|
||||||
}
|
}
|
||||||
|
@ -55,7 +65,7 @@ func (f *FlagSet) Int(name string, value int, usage string) *int {
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
// Like Int, but accepts a shorthand letter that can be used after a single dash.
|
// IntP is like Int, but accepts a shorthand letter that can be used after a single dash.
|
||||||
func (f *FlagSet) IntP(name, shorthand string, value int, usage string) *int {
|
func (f *FlagSet) IntP(name, shorthand string, value int, usage string) *int {
|
||||||
p := new(int)
|
p := new(int)
|
||||||
f.IntVarP(p, name, shorthand, value, usage)
|
f.IntVarP(p, name, shorthand, value, usage)
|
||||||
|
@ -68,7 +78,7 @@ func Int(name string, value int, usage string) *int {
|
||||||
return CommandLine.IntP(name, "", value, usage)
|
return CommandLine.IntP(name, "", value, usage)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Like Int, but accepts a shorthand letter that can be used after a single dash.
|
// IntP is like Int, but accepts a shorthand letter that can be used after a single dash.
|
||||||
func IntP(name, shorthand string, value int, usage string) *int {
|
func IntP(name, shorthand string, value int, usage string) *int {
|
||||||
return CommandLine.IntP(name, shorthand, value, usage)
|
return CommandLine.IntP(name, shorthand, value, usage)
|
||||||
}
|
}
|
||||||
|
|
32
vendor/github.com/spf13/pflag/int32.go
generated
vendored
32
vendor/github.com/spf13/pflag/int32.go
generated
vendored
|
@ -1,9 +1,6 @@
|
||||||
package pflag
|
package pflag
|
||||||
|
|
||||||
import (
|
import "strconv"
|
||||||
"fmt"
|
|
||||||
"strconv"
|
|
||||||
)
|
|
||||||
|
|
||||||
// -- int32 Value
|
// -- int32 Value
|
||||||
type int32Value int32
|
type int32Value int32
|
||||||
|
@ -23,7 +20,24 @@ func (i *int32Value) Type() string {
|
||||||
return "int32"
|
return "int32"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *int32Value) String() string { return fmt.Sprintf("%v", *i) }
|
func (i *int32Value) String() string { return strconv.FormatInt(int64(*i), 10) }
|
||||||
|
|
||||||
|
func int32Conv(sval string) (interface{}, error) {
|
||||||
|
v, err := strconv.ParseInt(sval, 0, 32)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
return int32(v), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetInt32 return the int32 value of a flag with the given name
|
||||||
|
func (f *FlagSet) GetInt32(name string) (int32, error) {
|
||||||
|
val, err := f.getFlagType(name, "int32", int32Conv)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
return val.(int32), nil
|
||||||
|
}
|
||||||
|
|
||||||
// Int32Var defines an int32 flag with specified name, default value, and usage string.
|
// Int32Var defines an int32 flag with specified name, default value, and usage string.
|
||||||
// The argument p points to an int32 variable in which to store the value of the flag.
|
// The argument p points to an int32 variable in which to store the value of the flag.
|
||||||
|
@ -31,7 +45,7 @@ func (f *FlagSet) Int32Var(p *int32, name string, value int32, usage string) {
|
||||||
f.VarP(newInt32Value(value, p), name, "", usage)
|
f.VarP(newInt32Value(value, p), name, "", usage)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Like Int32Var, but accepts a shorthand letter that can be used after a single dash.
|
// Int32VarP is like Int32Var, but accepts a shorthand letter that can be used after a single dash.
|
||||||
func (f *FlagSet) Int32VarP(p *int32, name, shorthand string, value int32, usage string) {
|
func (f *FlagSet) Int32VarP(p *int32, name, shorthand string, value int32, usage string) {
|
||||||
f.VarP(newInt32Value(value, p), name, shorthand, usage)
|
f.VarP(newInt32Value(value, p), name, shorthand, usage)
|
||||||
}
|
}
|
||||||
|
@ -42,7 +56,7 @@ func Int32Var(p *int32, name string, value int32, usage string) {
|
||||||
CommandLine.VarP(newInt32Value(value, p), name, "", usage)
|
CommandLine.VarP(newInt32Value(value, p), name, "", usage)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Like Int32Var, but accepts a shorthand letter that can be used after a single dash.
|
// Int32VarP is like Int32Var, but accepts a shorthand letter that can be used after a single dash.
|
||||||
func Int32VarP(p *int32, name, shorthand string, value int32, usage string) {
|
func Int32VarP(p *int32, name, shorthand string, value int32, usage string) {
|
||||||
CommandLine.VarP(newInt32Value(value, p), name, shorthand, usage)
|
CommandLine.VarP(newInt32Value(value, p), name, shorthand, usage)
|
||||||
}
|
}
|
||||||
|
@ -55,7 +69,7 @@ func (f *FlagSet) Int32(name string, value int32, usage string) *int32 {
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
// Like Int32, but accepts a shorthand letter that can be used after a single dash.
|
// Int32P is like Int32, but accepts a shorthand letter that can be used after a single dash.
|
||||||
func (f *FlagSet) Int32P(name, shorthand string, value int32, usage string) *int32 {
|
func (f *FlagSet) Int32P(name, shorthand string, value int32, usage string) *int32 {
|
||||||
p := new(int32)
|
p := new(int32)
|
||||||
f.Int32VarP(p, name, shorthand, value, usage)
|
f.Int32VarP(p, name, shorthand, value, usage)
|
||||||
|
@ -68,7 +82,7 @@ func Int32(name string, value int32, usage string) *int32 {
|
||||||
return CommandLine.Int32P(name, "", value, usage)
|
return CommandLine.Int32P(name, "", value, usage)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Like Int32, but accepts a shorthand letter that can be used after a single dash.
|
// Int32P is like Int32, but accepts a shorthand letter that can be used after a single dash.
|
||||||
func Int32P(name, shorthand string, value int32, usage string) *int32 {
|
func Int32P(name, shorthand string, value int32, usage string) *int32 {
|
||||||
return CommandLine.Int32P(name, shorthand, value, usage)
|
return CommandLine.Int32P(name, shorthand, value, usage)
|
||||||
}
|
}
|
||||||
|
|
28
vendor/github.com/spf13/pflag/int64.go
generated
vendored
28
vendor/github.com/spf13/pflag/int64.go
generated
vendored
|
@ -1,9 +1,6 @@
|
||||||
package pflag
|
package pflag
|
||||||
|
|
||||||
import (
|
import "strconv"
|
||||||
"fmt"
|
|
||||||
"strconv"
|
|
||||||
)
|
|
||||||
|
|
||||||
// -- int64 Value
|
// -- int64 Value
|
||||||
type int64Value int64
|
type int64Value int64
|
||||||
|
@ -23,7 +20,20 @@ func (i *int64Value) Type() string {
|
||||||
return "int64"
|
return "int64"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *int64Value) String() string { return fmt.Sprintf("%v", *i) }
|
func (i *int64Value) String() string { return strconv.FormatInt(int64(*i), 10) }
|
||||||
|
|
||||||
|
func int64Conv(sval string) (interface{}, error) {
|
||||||
|
return strconv.ParseInt(sval, 0, 64)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetInt64 return the int64 value of a flag with the given name
|
||||||
|
func (f *FlagSet) GetInt64(name string) (int64, error) {
|
||||||
|
val, err := f.getFlagType(name, "int64", int64Conv)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
return val.(int64), nil
|
||||||
|
}
|
||||||
|
|
||||||
// Int64Var defines an int64 flag with specified name, default value, and usage string.
|
// Int64Var defines an int64 flag with specified name, default value, and usage string.
|
||||||
// The argument p points to an int64 variable in which to store the value of the flag.
|
// The argument p points to an int64 variable in which to store the value of the flag.
|
||||||
|
@ -31,7 +41,7 @@ func (f *FlagSet) Int64Var(p *int64, name string, value int64, usage string) {
|
||||||
f.VarP(newInt64Value(value, p), name, "", usage)
|
f.VarP(newInt64Value(value, p), name, "", usage)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Like Int64Var, but accepts a shorthand letter that can be used after a single dash.
|
// Int64VarP is like Int64Var, but accepts a shorthand letter that can be used after a single dash.
|
||||||
func (f *FlagSet) Int64VarP(p *int64, name, shorthand string, value int64, usage string) {
|
func (f *FlagSet) Int64VarP(p *int64, name, shorthand string, value int64, usage string) {
|
||||||
f.VarP(newInt64Value(value, p), name, shorthand, usage)
|
f.VarP(newInt64Value(value, p), name, shorthand, usage)
|
||||||
}
|
}
|
||||||
|
@ -42,7 +52,7 @@ func Int64Var(p *int64, name string, value int64, usage string) {
|
||||||
CommandLine.VarP(newInt64Value(value, p), name, "", usage)
|
CommandLine.VarP(newInt64Value(value, p), name, "", usage)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Like Int64Var, but accepts a shorthand letter that can be used after a single dash.
|
// Int64VarP is like Int64Var, but accepts a shorthand letter that can be used after a single dash.
|
||||||
func Int64VarP(p *int64, name, shorthand string, value int64, usage string) {
|
func Int64VarP(p *int64, name, shorthand string, value int64, usage string) {
|
||||||
CommandLine.VarP(newInt64Value(value, p), name, shorthand, usage)
|
CommandLine.VarP(newInt64Value(value, p), name, shorthand, usage)
|
||||||
}
|
}
|
||||||
|
@ -55,7 +65,7 @@ func (f *FlagSet) Int64(name string, value int64, usage string) *int64 {
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
// Like Int64, but accepts a shorthand letter that can be used after a single dash.
|
// Int64P is like Int64, but accepts a shorthand letter that can be used after a single dash.
|
||||||
func (f *FlagSet) Int64P(name, shorthand string, value int64, usage string) *int64 {
|
func (f *FlagSet) Int64P(name, shorthand string, value int64, usage string) *int64 {
|
||||||
p := new(int64)
|
p := new(int64)
|
||||||
f.Int64VarP(p, name, shorthand, value, usage)
|
f.Int64VarP(p, name, shorthand, value, usage)
|
||||||
|
@ -68,7 +78,7 @@ func Int64(name string, value int64, usage string) *int64 {
|
||||||
return CommandLine.Int64P(name, "", value, usage)
|
return CommandLine.Int64P(name, "", value, usage)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Like Int64, but accepts a shorthand letter that can be used after a single dash.
|
// Int64P is like Int64, but accepts a shorthand letter that can be used after a single dash.
|
||||||
func Int64P(name, shorthand string, value int64, usage string) *int64 {
|
func Int64P(name, shorthand string, value int64, usage string) *int64 {
|
||||||
return CommandLine.Int64P(name, shorthand, value, usage)
|
return CommandLine.Int64P(name, shorthand, value, usage)
|
||||||
}
|
}
|
||||||
|
|
32
vendor/github.com/spf13/pflag/int8.go
generated
vendored
32
vendor/github.com/spf13/pflag/int8.go
generated
vendored
|
@ -1,9 +1,6 @@
|
||||||
package pflag
|
package pflag
|
||||||
|
|
||||||
import (
|
import "strconv"
|
||||||
"fmt"
|
|
||||||
"strconv"
|
|
||||||
)
|
|
||||||
|
|
||||||
// -- int8 Value
|
// -- int8 Value
|
||||||
type int8Value int8
|
type int8Value int8
|
||||||
|
@ -23,7 +20,24 @@ func (i *int8Value) Type() string {
|
||||||
return "int8"
|
return "int8"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *int8Value) String() string { return fmt.Sprintf("%v", *i) }
|
func (i *int8Value) String() string { return strconv.FormatInt(int64(*i), 10) }
|
||||||
|
|
||||||
|
func int8Conv(sval string) (interface{}, error) {
|
||||||
|
v, err := strconv.ParseInt(sval, 0, 8)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
return int8(v), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetInt8 return the int8 value of a flag with the given name
|
||||||
|
func (f *FlagSet) GetInt8(name string) (int8, error) {
|
||||||
|
val, err := f.getFlagType(name, "int8", int8Conv)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
return val.(int8), nil
|
||||||
|
}
|
||||||
|
|
||||||
// Int8Var defines an int8 flag with specified name, default value, and usage string.
|
// Int8Var defines an int8 flag with specified name, default value, and usage string.
|
||||||
// The argument p points to an int8 variable in which to store the value of the flag.
|
// The argument p points to an int8 variable in which to store the value of the flag.
|
||||||
|
@ -31,7 +45,7 @@ func (f *FlagSet) Int8Var(p *int8, name string, value int8, usage string) {
|
||||||
f.VarP(newInt8Value(value, p), name, "", usage)
|
f.VarP(newInt8Value(value, p), name, "", usage)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Like Int8Var, but accepts a shorthand letter that can be used after a single dash.
|
// Int8VarP is like Int8Var, but accepts a shorthand letter that can be used after a single dash.
|
||||||
func (f *FlagSet) Int8VarP(p *int8, name, shorthand string, value int8, usage string) {
|
func (f *FlagSet) Int8VarP(p *int8, name, shorthand string, value int8, usage string) {
|
||||||
f.VarP(newInt8Value(value, p), name, shorthand, usage)
|
f.VarP(newInt8Value(value, p), name, shorthand, usage)
|
||||||
}
|
}
|
||||||
|
@ -42,7 +56,7 @@ func Int8Var(p *int8, name string, value int8, usage string) {
|
||||||
CommandLine.VarP(newInt8Value(value, p), name, "", usage)
|
CommandLine.VarP(newInt8Value(value, p), name, "", usage)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Like Int8Var, but accepts a shorthand letter that can be used after a single dash.
|
// Int8VarP is like Int8Var, but accepts a shorthand letter that can be used after a single dash.
|
||||||
func Int8VarP(p *int8, name, shorthand string, value int8, usage string) {
|
func Int8VarP(p *int8, name, shorthand string, value int8, usage string) {
|
||||||
CommandLine.VarP(newInt8Value(value, p), name, shorthand, usage)
|
CommandLine.VarP(newInt8Value(value, p), name, shorthand, usage)
|
||||||
}
|
}
|
||||||
|
@ -55,7 +69,7 @@ func (f *FlagSet) Int8(name string, value int8, usage string) *int8 {
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
// Like Int8, but accepts a shorthand letter that can be used after a single dash.
|
// Int8P is like Int8, but accepts a shorthand letter that can be used after a single dash.
|
||||||
func (f *FlagSet) Int8P(name, shorthand string, value int8, usage string) *int8 {
|
func (f *FlagSet) Int8P(name, shorthand string, value int8, usage string) *int8 {
|
||||||
p := new(int8)
|
p := new(int8)
|
||||||
f.Int8VarP(p, name, shorthand, value, usage)
|
f.Int8VarP(p, name, shorthand, value, usage)
|
||||||
|
@ -68,7 +82,7 @@ func Int8(name string, value int8, usage string) *int8 {
|
||||||
return CommandLine.Int8P(name, "", value, usage)
|
return CommandLine.Int8P(name, "", value, usage)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Like Int8, but accepts a shorthand letter that can be used after a single dash.
|
// Int8P is like Int8, but accepts a shorthand letter that can be used after a single dash.
|
||||||
func Int8P(name, shorthand string, value int8, usage string) *int8 {
|
func Int8P(name, shorthand string, value int8, usage string) *int8 {
|
||||||
return CommandLine.Int8P(name, shorthand, value, usage)
|
return CommandLine.Int8P(name, shorthand, value, usage)
|
||||||
}
|
}
|
||||||
|
|
128
vendor/github.com/spf13/pflag/int_slice.go
generated
vendored
Normal file
128
vendor/github.com/spf13/pflag/int_slice.go
generated
vendored
Normal file
|
@ -0,0 +1,128 @@
|
||||||
|
package pflag
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// -- intSlice Value
|
||||||
|
type intSliceValue struct {
|
||||||
|
value *[]int
|
||||||
|
changed bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func newIntSliceValue(val []int, p *[]int) *intSliceValue {
|
||||||
|
isv := new(intSliceValue)
|
||||||
|
isv.value = p
|
||||||
|
*isv.value = val
|
||||||
|
return isv
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *intSliceValue) Set(val string) error {
|
||||||
|
ss := strings.Split(val, ",")
|
||||||
|
out := make([]int, len(ss))
|
||||||
|
for i, d := range ss {
|
||||||
|
var err error
|
||||||
|
out[i], err = strconv.Atoi(d)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
if !s.changed {
|
||||||
|
*s.value = out
|
||||||
|
} else {
|
||||||
|
*s.value = append(*s.value, out...)
|
||||||
|
}
|
||||||
|
s.changed = true
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *intSliceValue) Type() string {
|
||||||
|
return "intSlice"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *intSliceValue) String() string {
|
||||||
|
out := make([]string, len(*s.value))
|
||||||
|
for i, d := range *s.value {
|
||||||
|
out[i] = fmt.Sprintf("%d", d)
|
||||||
|
}
|
||||||
|
return "[" + strings.Join(out, ",") + "]"
|
||||||
|
}
|
||||||
|
|
||||||
|
func intSliceConv(val string) (interface{}, error) {
|
||||||
|
val = strings.Trim(val, "[]")
|
||||||
|
// Empty string would cause a slice with one (empty) entry
|
||||||
|
if len(val) == 0 {
|
||||||
|
return []int{}, nil
|
||||||
|
}
|
||||||
|
ss := strings.Split(val, ",")
|
||||||
|
out := make([]int, len(ss))
|
||||||
|
for i, d := range ss {
|
||||||
|
var err error
|
||||||
|
out[i], err = strconv.Atoi(d)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return out, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetIntSlice return the []int value of a flag with the given name
|
||||||
|
func (f *FlagSet) GetIntSlice(name string) ([]int, error) {
|
||||||
|
val, err := f.getFlagType(name, "intSlice", intSliceConv)
|
||||||
|
if err != nil {
|
||||||
|
return []int{}, err
|
||||||
|
}
|
||||||
|
return val.([]int), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// IntSliceVar defines a intSlice flag with specified name, default value, and usage string.
|
||||||
|
// The argument p points to a []int variable in which to store the value of the flag.
|
||||||
|
func (f *FlagSet) IntSliceVar(p *[]int, name string, value []int, usage string) {
|
||||||
|
f.VarP(newIntSliceValue(value, p), name, "", usage)
|
||||||
|
}
|
||||||
|
|
||||||
|
// IntSliceVarP is like IntSliceVar, but accepts a shorthand letter that can be used after a single dash.
|
||||||
|
func (f *FlagSet) IntSliceVarP(p *[]int, name, shorthand string, value []int, usage string) {
|
||||||
|
f.VarP(newIntSliceValue(value, p), name, shorthand, usage)
|
||||||
|
}
|
||||||
|
|
||||||
|
// IntSliceVar defines a int[] flag with specified name, default value, and usage string.
|
||||||
|
// The argument p points to a int[] variable in which to store the value of the flag.
|
||||||
|
func IntSliceVar(p *[]int, name string, value []int, usage string) {
|
||||||
|
CommandLine.VarP(newIntSliceValue(value, p), name, "", usage)
|
||||||
|
}
|
||||||
|
|
||||||
|
// IntSliceVarP is like IntSliceVar, but accepts a shorthand letter that can be used after a single dash.
|
||||||
|
func IntSliceVarP(p *[]int, name, shorthand string, value []int, usage string) {
|
||||||
|
CommandLine.VarP(newIntSliceValue(value, p), name, shorthand, usage)
|
||||||
|
}
|
||||||
|
|
||||||
|
// IntSlice defines a []int flag with specified name, default value, and usage string.
|
||||||
|
// The return value is the address of a []int variable that stores the value of the flag.
|
||||||
|
func (f *FlagSet) IntSlice(name string, value []int, usage string) *[]int {
|
||||||
|
p := []int{}
|
||||||
|
f.IntSliceVarP(&p, name, "", value, usage)
|
||||||
|
return &p
|
||||||
|
}
|
||||||
|
|
||||||
|
// IntSliceP is like IntSlice, but accepts a shorthand letter that can be used after a single dash.
|
||||||
|
func (f *FlagSet) IntSliceP(name, shorthand string, value []int, usage string) *[]int {
|
||||||
|
p := []int{}
|
||||||
|
f.IntSliceVarP(&p, name, shorthand, value, usage)
|
||||||
|
return &p
|
||||||
|
}
|
||||||
|
|
||||||
|
// IntSlice defines a []int flag with specified name, default value, and usage string.
|
||||||
|
// The return value is the address of a []int variable that stores the value of the flag.
|
||||||
|
func IntSlice(name string, value []int, usage string) *[]int {
|
||||||
|
return CommandLine.IntSliceP(name, "", value, usage)
|
||||||
|
}
|
||||||
|
|
||||||
|
// IntSliceP is like IntSlice, but accepts a shorthand letter that can be used after a single dash.
|
||||||
|
func IntSliceP(name, shorthand string, value []int, usage string) *[]int {
|
||||||
|
return CommandLine.IntSliceP(name, shorthand, value, usage)
|
||||||
|
}
|
30
vendor/github.com/spf13/pflag/ip.go
generated
vendored
30
vendor/github.com/spf13/pflag/ip.go
generated
vendored
|
@ -3,8 +3,11 @@ package pflag
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var _ = strings.TrimSpace
|
||||||
|
|
||||||
// -- net.IP value
|
// -- net.IP value
|
||||||
type ipValue net.IP
|
type ipValue net.IP
|
||||||
|
|
||||||
|
@ -15,7 +18,7 @@ func newIPValue(val net.IP, p *net.IP) *ipValue {
|
||||||
|
|
||||||
func (i *ipValue) String() string { return net.IP(*i).String() }
|
func (i *ipValue) String() string { return net.IP(*i).String() }
|
||||||
func (i *ipValue) Set(s string) error {
|
func (i *ipValue) Set(s string) error {
|
||||||
ip := net.ParseIP(s)
|
ip := net.ParseIP(strings.TrimSpace(s))
|
||||||
if ip == nil {
|
if ip == nil {
|
||||||
return fmt.Errorf("failed to parse IP: %q", s)
|
return fmt.Errorf("failed to parse IP: %q", s)
|
||||||
}
|
}
|
||||||
|
@ -27,13 +30,30 @@ func (i *ipValue) Type() string {
|
||||||
return "ip"
|
return "ip"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ipConv(sval string) (interface{}, error) {
|
||||||
|
ip := net.ParseIP(sval)
|
||||||
|
if ip != nil {
|
||||||
|
return ip, nil
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("invalid string being converted to IP address: %s", sval)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetIP return the net.IP value of a flag with the given name
|
||||||
|
func (f *FlagSet) GetIP(name string) (net.IP, error) {
|
||||||
|
val, err := f.getFlagType(name, "ip", ipConv)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return val.(net.IP), nil
|
||||||
|
}
|
||||||
|
|
||||||
// IPVar defines an net.IP flag with specified name, default value, and usage string.
|
// IPVar defines an net.IP flag with specified name, default value, and usage string.
|
||||||
// The argument p points to an net.IP variable in which to store the value of the flag.
|
// The argument p points to an net.IP variable in which to store the value of the flag.
|
||||||
func (f *FlagSet) IPVar(p *net.IP, name string, value net.IP, usage string) {
|
func (f *FlagSet) IPVar(p *net.IP, name string, value net.IP, usage string) {
|
||||||
f.VarP(newIPValue(value, p), name, "", usage)
|
f.VarP(newIPValue(value, p), name, "", usage)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Like IPVar, but accepts a shorthand letter that can be used after a single dash.
|
// IPVarP is like IPVar, but accepts a shorthand letter that can be used after a single dash.
|
||||||
func (f *FlagSet) IPVarP(p *net.IP, name, shorthand string, value net.IP, usage string) {
|
func (f *FlagSet) IPVarP(p *net.IP, name, shorthand string, value net.IP, usage string) {
|
||||||
f.VarP(newIPValue(value, p), name, shorthand, usage)
|
f.VarP(newIPValue(value, p), name, shorthand, usage)
|
||||||
}
|
}
|
||||||
|
@ -44,7 +64,7 @@ func IPVar(p *net.IP, name string, value net.IP, usage string) {
|
||||||
CommandLine.VarP(newIPValue(value, p), name, "", usage)
|
CommandLine.VarP(newIPValue(value, p), name, "", usage)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Like IPVar, but accepts a shorthand letter that can be used after a single dash.
|
// IPVarP is like IPVar, but accepts a shorthand letter that can be used after a single dash.
|
||||||
func IPVarP(p *net.IP, name, shorthand string, value net.IP, usage string) {
|
func IPVarP(p *net.IP, name, shorthand string, value net.IP, usage string) {
|
||||||
CommandLine.VarP(newIPValue(value, p), name, shorthand, usage)
|
CommandLine.VarP(newIPValue(value, p), name, shorthand, usage)
|
||||||
}
|
}
|
||||||
|
@ -57,7 +77,7 @@ func (f *FlagSet) IP(name string, value net.IP, usage string) *net.IP {
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
// Like IP, but accepts a shorthand letter that can be used after a single dash.
|
// IPP is like IP, but accepts a shorthand letter that can be used after a single dash.
|
||||||
func (f *FlagSet) IPP(name, shorthand string, value net.IP, usage string) *net.IP {
|
func (f *FlagSet) IPP(name, shorthand string, value net.IP, usage string) *net.IP {
|
||||||
p := new(net.IP)
|
p := new(net.IP)
|
||||||
f.IPVarP(p, name, shorthand, value, usage)
|
f.IPVarP(p, name, shorthand, value, usage)
|
||||||
|
@ -70,7 +90,7 @@ func IP(name string, value net.IP, usage string) *net.IP {
|
||||||
return CommandLine.IPP(name, "", value, usage)
|
return CommandLine.IPP(name, "", value, usage)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Like IP, but accepts a shorthand letter that can be used after a single dash.
|
// IPP is like IP, but accepts a shorthand letter that can be used after a single dash.
|
||||||
func IPP(name, shorthand string, value net.IP, usage string) *net.IP {
|
func IPP(name, shorthand string, value net.IP, usage string) *net.IP {
|
||||||
return CommandLine.IPP(name, shorthand, value, usage)
|
return CommandLine.IPP(name, shorthand, value, usage)
|
||||||
}
|
}
|
||||||
|
|
46
vendor/github.com/spf13/pflag/ipmask.go
generated
vendored
46
vendor/github.com/spf13/pflag/ipmask.go
generated
vendored
|
@ -3,6 +3,7 @@ package pflag
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
|
"strconv"
|
||||||
)
|
)
|
||||||
|
|
||||||
// -- net.IPMask value
|
// -- net.IPMask value
|
||||||
|
@ -27,23 +28,58 @@ func (i *ipMaskValue) Type() string {
|
||||||
return "ipMask"
|
return "ipMask"
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse IPv4 netmask written in IP form (e.g. 255.255.255.0).
|
// ParseIPv4Mask written in IP form (e.g. 255.255.255.0).
|
||||||
// This function should really belong to the net package.
|
// This function should really belong to the net package.
|
||||||
func ParseIPv4Mask(s string) net.IPMask {
|
func ParseIPv4Mask(s string) net.IPMask {
|
||||||
mask := net.ParseIP(s)
|
mask := net.ParseIP(s)
|
||||||
if mask == nil {
|
if mask == nil {
|
||||||
|
if len(s) != 8 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
// net.IPMask.String() actually outputs things like ffffff00
|
||||||
|
// so write a horrible parser for that as well :-(
|
||||||
|
m := []int{}
|
||||||
|
for i := 0; i < 4; i++ {
|
||||||
|
b := "0x" + s[2*i:2*i+2]
|
||||||
|
d, err := strconv.ParseInt(b, 0, 0)
|
||||||
|
if err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
m = append(m, int(d))
|
||||||
|
}
|
||||||
|
s := fmt.Sprintf("%d.%d.%d.%d", m[0], m[1], m[2], m[3])
|
||||||
|
mask = net.ParseIP(s)
|
||||||
|
if mask == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
return net.IPv4Mask(mask[12], mask[13], mask[14], mask[15])
|
return net.IPv4Mask(mask[12], mask[13], mask[14], mask[15])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func parseIPv4Mask(sval string) (interface{}, error) {
|
||||||
|
mask := ParseIPv4Mask(sval)
|
||||||
|
if mask == nil {
|
||||||
|
return nil, fmt.Errorf("unable to parse %s as net.IPMask", sval)
|
||||||
|
}
|
||||||
|
return mask, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetIPv4Mask return the net.IPv4Mask value of a flag with the given name
|
||||||
|
func (f *FlagSet) GetIPv4Mask(name string) (net.IPMask, error) {
|
||||||
|
val, err := f.getFlagType(name, "ipMask", parseIPv4Mask)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return val.(net.IPMask), nil
|
||||||
|
}
|
||||||
|
|
||||||
// IPMaskVar defines an net.IPMask flag with specified name, default value, and usage string.
|
// IPMaskVar defines an net.IPMask flag with specified name, default value, and usage string.
|
||||||
// The argument p points to an net.IPMask variable in which to store the value of the flag.
|
// The argument p points to an net.IPMask variable in which to store the value of the flag.
|
||||||
func (f *FlagSet) IPMaskVar(p *net.IPMask, name string, value net.IPMask, usage string) {
|
func (f *FlagSet) IPMaskVar(p *net.IPMask, name string, value net.IPMask, usage string) {
|
||||||
f.VarP(newIPMaskValue(value, p), name, "", usage)
|
f.VarP(newIPMaskValue(value, p), name, "", usage)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Like IPMaskVar, but accepts a shorthand letter that can be used after a single dash.
|
// IPMaskVarP is like IPMaskVar, but accepts a shorthand letter that can be used after a single dash.
|
||||||
func (f *FlagSet) IPMaskVarP(p *net.IPMask, name, shorthand string, value net.IPMask, usage string) {
|
func (f *FlagSet) IPMaskVarP(p *net.IPMask, name, shorthand string, value net.IPMask, usage string) {
|
||||||
f.VarP(newIPMaskValue(value, p), name, shorthand, usage)
|
f.VarP(newIPMaskValue(value, p), name, shorthand, usage)
|
||||||
}
|
}
|
||||||
|
@ -54,7 +90,7 @@ func IPMaskVar(p *net.IPMask, name string, value net.IPMask, usage string) {
|
||||||
CommandLine.VarP(newIPMaskValue(value, p), name, "", usage)
|
CommandLine.VarP(newIPMaskValue(value, p), name, "", usage)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Like IPMaskVar, but accepts a shorthand letter that can be used after a single dash.
|
// IPMaskVarP is like IPMaskVar, but accepts a shorthand letter that can be used after a single dash.
|
||||||
func IPMaskVarP(p *net.IPMask, name, shorthand string, value net.IPMask, usage string) {
|
func IPMaskVarP(p *net.IPMask, name, shorthand string, value net.IPMask, usage string) {
|
||||||
CommandLine.VarP(newIPMaskValue(value, p), name, shorthand, usage)
|
CommandLine.VarP(newIPMaskValue(value, p), name, shorthand, usage)
|
||||||
}
|
}
|
||||||
|
@ -67,7 +103,7 @@ func (f *FlagSet) IPMask(name string, value net.IPMask, usage string) *net.IPMas
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
// Like IPMask, but accepts a shorthand letter that can be used after a single dash.
|
// IPMaskP is like IPMask, but accepts a shorthand letter that can be used after a single dash.
|
||||||
func (f *FlagSet) IPMaskP(name, shorthand string, value net.IPMask, usage string) *net.IPMask {
|
func (f *FlagSet) IPMaskP(name, shorthand string, value net.IPMask, usage string) *net.IPMask {
|
||||||
p := new(net.IPMask)
|
p := new(net.IPMask)
|
||||||
f.IPMaskVarP(p, name, shorthand, value, usage)
|
f.IPMaskVarP(p, name, shorthand, value, usage)
|
||||||
|
@ -80,7 +116,7 @@ func IPMask(name string, value net.IPMask, usage string) *net.IPMask {
|
||||||
return CommandLine.IPMaskP(name, "", value, usage)
|
return CommandLine.IPMaskP(name, "", value, usage)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Like IP, but accepts a shorthand letter that can be used after a single dash.
|
// IPMaskP is like IP, but accepts a shorthand letter that can be used after a single dash.
|
||||||
func IPMaskP(name, shorthand string, value net.IPMask, usage string) *net.IPMask {
|
func IPMaskP(name, shorthand string, value net.IPMask, usage string) *net.IPMask {
|
||||||
return CommandLine.IPMaskP(name, shorthand, value, usage)
|
return CommandLine.IPMaskP(name, shorthand, value, usage)
|
||||||
}
|
}
|
||||||
|
|
100
vendor/github.com/spf13/pflag/ipnet.go
generated
vendored
Normal file
100
vendor/github.com/spf13/pflag/ipnet.go
generated
vendored
Normal file
|
@ -0,0 +1,100 @@
|
||||||
|
package pflag
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// IPNet adapts net.IPNet for use as a flag.
|
||||||
|
type ipNetValue net.IPNet
|
||||||
|
|
||||||
|
func (ipnet ipNetValue) String() string {
|
||||||
|
n := net.IPNet(ipnet)
|
||||||
|
return n.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ipnet *ipNetValue) Set(value string) error {
|
||||||
|
_, n, err := net.ParseCIDR(strings.TrimSpace(value))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
*ipnet = ipNetValue(*n)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*ipNetValue) Type() string {
|
||||||
|
return "ipNet"
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ = strings.TrimSpace
|
||||||
|
|
||||||
|
func newIPNetValue(val net.IPNet, p *net.IPNet) *ipNetValue {
|
||||||
|
*p = val
|
||||||
|
return (*ipNetValue)(p)
|
||||||
|
}
|
||||||
|
|
||||||
|
func ipNetConv(sval string) (interface{}, error) {
|
||||||
|
_, n, err := net.ParseCIDR(strings.TrimSpace(sval))
|
||||||
|
if err == nil {
|
||||||
|
return *n, nil
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("invalid string being converted to IPNet: %s", sval)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetIPNet return the net.IPNet value of a flag with the given name
|
||||||
|
func (f *FlagSet) GetIPNet(name string) (net.IPNet, error) {
|
||||||
|
val, err := f.getFlagType(name, "ipNet", ipNetConv)
|
||||||
|
if err != nil {
|
||||||
|
return net.IPNet{}, err
|
||||||
|
}
|
||||||
|
return val.(net.IPNet), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// IPNetVar defines an net.IPNet flag with specified name, default value, and usage string.
|
||||||
|
// The argument p points to an net.IPNet variable in which to store the value of the flag.
|
||||||
|
func (f *FlagSet) IPNetVar(p *net.IPNet, name string, value net.IPNet, usage string) {
|
||||||
|
f.VarP(newIPNetValue(value, p), name, "", usage)
|
||||||
|
}
|
||||||
|
|
||||||
|
// IPNetVarP is like IPNetVar, but accepts a shorthand letter that can be used after a single dash.
|
||||||
|
func (f *FlagSet) IPNetVarP(p *net.IPNet, name, shorthand string, value net.IPNet, usage string) {
|
||||||
|
f.VarP(newIPNetValue(value, p), name, shorthand, usage)
|
||||||
|
}
|
||||||
|
|
||||||
|
// IPNetVar defines an net.IPNet flag with specified name, default value, and usage string.
|
||||||
|
// The argument p points to an net.IPNet variable in which to store the value of the flag.
|
||||||
|
func IPNetVar(p *net.IPNet, name string, value net.IPNet, usage string) {
|
||||||
|
CommandLine.VarP(newIPNetValue(value, p), name, "", usage)
|
||||||
|
}
|
||||||
|
|
||||||
|
// IPNetVarP is like IPNetVar, but accepts a shorthand letter that can be used after a single dash.
|
||||||
|
func IPNetVarP(p *net.IPNet, name, shorthand string, value net.IPNet, usage string) {
|
||||||
|
CommandLine.VarP(newIPNetValue(value, p), name, shorthand, usage)
|
||||||
|
}
|
||||||
|
|
||||||
|
// IPNet defines an net.IPNet flag with specified name, default value, and usage string.
|
||||||
|
// The return value is the address of an net.IPNet variable that stores the value of the flag.
|
||||||
|
func (f *FlagSet) IPNet(name string, value net.IPNet, usage string) *net.IPNet {
|
||||||
|
p := new(net.IPNet)
|
||||||
|
f.IPNetVarP(p, name, "", value, usage)
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
|
||||||
|
// IPNetP is like IPNet, but accepts a shorthand letter that can be used after a single dash.
|
||||||
|
func (f *FlagSet) IPNetP(name, shorthand string, value net.IPNet, usage string) *net.IPNet {
|
||||||
|
p := new(net.IPNet)
|
||||||
|
f.IPNetVarP(p, name, shorthand, value, usage)
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
|
||||||
|
// IPNet defines an net.IPNet flag with specified name, default value, and usage string.
|
||||||
|
// The return value is the address of an net.IPNet variable that stores the value of the flag.
|
||||||
|
func IPNet(name string, value net.IPNet, usage string) *net.IPNet {
|
||||||
|
return CommandLine.IPNetP(name, "", value, usage)
|
||||||
|
}
|
||||||
|
|
||||||
|
// IPNetP is like IPNet, but accepts a shorthand letter that can be used after a single dash.
|
||||||
|
func IPNetP(name, shorthand string, value net.IPNet, usage string) *net.IPNet {
|
||||||
|
return CommandLine.IPNetP(name, shorthand, value, usage)
|
||||||
|
}
|
25
vendor/github.com/spf13/pflag/string.go
generated
vendored
25
vendor/github.com/spf13/pflag/string.go
generated
vendored
|
@ -1,7 +1,5 @@
|
||||||
package pflag
|
package pflag
|
||||||
|
|
||||||
import "fmt"
|
|
||||||
|
|
||||||
// -- string Value
|
// -- string Value
|
||||||
type stringValue string
|
type stringValue string
|
||||||
|
|
||||||
|
@ -18,7 +16,20 @@ func (s *stringValue) Type() string {
|
||||||
return "string"
|
return "string"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *stringValue) String() string { return fmt.Sprintf("%s", *s) }
|
func (s *stringValue) String() string { return string(*s) }
|
||||||
|
|
||||||
|
func stringConv(sval string) (interface{}, error) {
|
||||||
|
return sval, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetString return the string value of a flag with the given name
|
||||||
|
func (f *FlagSet) GetString(name string) (string, error) {
|
||||||
|
val, err := f.getFlagType(name, "string", stringConv)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return val.(string), nil
|
||||||
|
}
|
||||||
|
|
||||||
// StringVar defines a string flag with specified name, default value, and usage string.
|
// StringVar defines a string flag with specified name, default value, and usage string.
|
||||||
// The argument p points to a string variable in which to store the value of the flag.
|
// The argument p points to a string variable in which to store the value of the flag.
|
||||||
|
@ -26,7 +37,7 @@ func (f *FlagSet) StringVar(p *string, name string, value string, usage string)
|
||||||
f.VarP(newStringValue(value, p), name, "", usage)
|
f.VarP(newStringValue(value, p), name, "", usage)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Like StringVar, but accepts a shorthand letter that can be used after a single dash.
|
// StringVarP is like StringVar, but accepts a shorthand letter that can be used after a single dash.
|
||||||
func (f *FlagSet) StringVarP(p *string, name, shorthand string, value string, usage string) {
|
func (f *FlagSet) StringVarP(p *string, name, shorthand string, value string, usage string) {
|
||||||
f.VarP(newStringValue(value, p), name, shorthand, usage)
|
f.VarP(newStringValue(value, p), name, shorthand, usage)
|
||||||
}
|
}
|
||||||
|
@ -37,7 +48,7 @@ func StringVar(p *string, name string, value string, usage string) {
|
||||||
CommandLine.VarP(newStringValue(value, p), name, "", usage)
|
CommandLine.VarP(newStringValue(value, p), name, "", usage)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Like StringVar, but accepts a shorthand letter that can be used after a single dash.
|
// StringVarP is like StringVar, but accepts a shorthand letter that can be used after a single dash.
|
||||||
func StringVarP(p *string, name, shorthand string, value string, usage string) {
|
func StringVarP(p *string, name, shorthand string, value string, usage string) {
|
||||||
CommandLine.VarP(newStringValue(value, p), name, shorthand, usage)
|
CommandLine.VarP(newStringValue(value, p), name, shorthand, usage)
|
||||||
}
|
}
|
||||||
|
@ -50,7 +61,7 @@ func (f *FlagSet) String(name string, value string, usage string) *string {
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
// Like String, but accepts a shorthand letter that can be used after a single dash.
|
// StringP is like String, but accepts a shorthand letter that can be used after a single dash.
|
||||||
func (f *FlagSet) StringP(name, shorthand string, value string, usage string) *string {
|
func (f *FlagSet) StringP(name, shorthand string, value string, usage string) *string {
|
||||||
p := new(string)
|
p := new(string)
|
||||||
f.StringVarP(p, name, shorthand, value, usage)
|
f.StringVarP(p, name, shorthand, value, usage)
|
||||||
|
@ -63,7 +74,7 @@ func String(name string, value string, usage string) *string {
|
||||||
return CommandLine.StringP(name, "", value, usage)
|
return CommandLine.StringP(name, "", value, usage)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Like String, but accepts a shorthand letter that can be used after a single dash.
|
// StringP is like String, but accepts a shorthand letter that can be used after a single dash.
|
||||||
func StringP(name, shorthand string, value string, usage string) *string {
|
func StringP(name, shorthand string, value string, usage string) *string {
|
||||||
return CommandLine.StringP(name, shorthand, value, usage)
|
return CommandLine.StringP(name, shorthand, value, usage)
|
||||||
}
|
}
|
||||||
|
|
109
vendor/github.com/spf13/pflag/string_array.go
generated
vendored
Normal file
109
vendor/github.com/spf13/pflag/string_array.go
generated
vendored
Normal file
|
@ -0,0 +1,109 @@
|
||||||
|
package pflag
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ = fmt.Fprint
|
||||||
|
|
||||||
|
// -- stringArray Value
|
||||||
|
type stringArrayValue struct {
|
||||||
|
value *[]string
|
||||||
|
changed bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func newStringArrayValue(val []string, p *[]string) *stringArrayValue {
|
||||||
|
ssv := new(stringArrayValue)
|
||||||
|
ssv.value = p
|
||||||
|
*ssv.value = val
|
||||||
|
return ssv
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *stringArrayValue) Set(val string) error {
|
||||||
|
if !s.changed {
|
||||||
|
*s.value = []string{val}
|
||||||
|
s.changed = true
|
||||||
|
} else {
|
||||||
|
*s.value = append(*s.value, val)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *stringArrayValue) Type() string {
|
||||||
|
return "stringArray"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *stringArrayValue) String() string {
|
||||||
|
str, _ := writeAsCSV(*s.value)
|
||||||
|
return "[" + str + "]"
|
||||||
|
}
|
||||||
|
|
||||||
|
func stringArrayConv(sval string) (interface{}, error) {
|
||||||
|
sval = sval[1 : len(sval)-1]
|
||||||
|
// An empty string would cause a array with one (empty) string
|
||||||
|
if len(sval) == 0 {
|
||||||
|
return []string{}, nil
|
||||||
|
}
|
||||||
|
return readAsCSV(sval)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetStringArray return the []string value of a flag with the given name
|
||||||
|
func (f *FlagSet) GetStringArray(name string) ([]string, error) {
|
||||||
|
val, err := f.getFlagType(name, "stringArray", stringArrayConv)
|
||||||
|
if err != nil {
|
||||||
|
return []string{}, err
|
||||||
|
}
|
||||||
|
return val.([]string), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// StringArrayVar defines a string flag with specified name, default value, and usage string.
|
||||||
|
// The argument p points to a []string variable in which to store the values of the multiple flags.
|
||||||
|
// The value of each argument will not try to be separated by comma
|
||||||
|
func (f *FlagSet) StringArrayVar(p *[]string, name string, value []string, usage string) {
|
||||||
|
f.VarP(newStringArrayValue(value, p), name, "", usage)
|
||||||
|
}
|
||||||
|
|
||||||
|
// StringArrayVarP is like StringArrayVar, but accepts a shorthand letter that can be used after a single dash.
|
||||||
|
func (f *FlagSet) StringArrayVarP(p *[]string, name, shorthand string, value []string, usage string) {
|
||||||
|
f.VarP(newStringArrayValue(value, p), name, shorthand, usage)
|
||||||
|
}
|
||||||
|
|
||||||
|
// StringArrayVar defines a string flag with specified name, default value, and usage string.
|
||||||
|
// The argument p points to a []string variable in which to store the value of the flag.
|
||||||
|
// The value of each argument will not try to be separated by comma
|
||||||
|
func StringArrayVar(p *[]string, name string, value []string, usage string) {
|
||||||
|
CommandLine.VarP(newStringArrayValue(value, p), name, "", usage)
|
||||||
|
}
|
||||||
|
|
||||||
|
// StringArrayVarP is like StringArrayVar, but accepts a shorthand letter that can be used after a single dash.
|
||||||
|
func StringArrayVarP(p *[]string, name, shorthand string, value []string, usage string) {
|
||||||
|
CommandLine.VarP(newStringArrayValue(value, p), name, shorthand, usage)
|
||||||
|
}
|
||||||
|
|
||||||
|
// StringArray defines a string flag with specified name, default value, and usage string.
|
||||||
|
// The return value is the address of a []string variable that stores the value of the flag.
|
||||||
|
// The value of each argument will not try to be separated by comma
|
||||||
|
func (f *FlagSet) StringArray(name string, value []string, usage string) *[]string {
|
||||||
|
p := []string{}
|
||||||
|
f.StringArrayVarP(&p, name, "", value, usage)
|
||||||
|
return &p
|
||||||
|
}
|
||||||
|
|
||||||
|
// StringArrayP is like StringArray, but accepts a shorthand letter that can be used after a single dash.
|
||||||
|
func (f *FlagSet) StringArrayP(name, shorthand string, value []string, usage string) *[]string {
|
||||||
|
p := []string{}
|
||||||
|
f.StringArrayVarP(&p, name, shorthand, value, usage)
|
||||||
|
return &p
|
||||||
|
}
|
||||||
|
|
||||||
|
// StringArray defines a string flag with specified name, default value, and usage string.
|
||||||
|
// The return value is the address of a []string variable that stores the value of the flag.
|
||||||
|
// The value of each argument will not try to be separated by comma
|
||||||
|
func StringArray(name string, value []string, usage string) *[]string {
|
||||||
|
return CommandLine.StringArrayP(name, "", value, usage)
|
||||||
|
}
|
||||||
|
|
||||||
|
// StringArrayP is like StringArray, but accepts a shorthand letter that can be used after a single dash.
|
||||||
|
func StringArrayP(name, shorthand string, value []string, usage string) *[]string {
|
||||||
|
return CommandLine.StringArrayP(name, shorthand, value, usage)
|
||||||
|
}
|
132
vendor/github.com/spf13/pflag/string_slice.go
generated
vendored
Normal file
132
vendor/github.com/spf13/pflag/string_slice.go
generated
vendored
Normal file
|
@ -0,0 +1,132 @@
|
||||||
|
package pflag
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/csv"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ = fmt.Fprint
|
||||||
|
|
||||||
|
// -- stringSlice Value
|
||||||
|
type stringSliceValue struct {
|
||||||
|
value *[]string
|
||||||
|
changed bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func newStringSliceValue(val []string, p *[]string) *stringSliceValue {
|
||||||
|
ssv := new(stringSliceValue)
|
||||||
|
ssv.value = p
|
||||||
|
*ssv.value = val
|
||||||
|
return ssv
|
||||||
|
}
|
||||||
|
|
||||||
|
func readAsCSV(val string) ([]string, error) {
|
||||||
|
if val == "" {
|
||||||
|
return []string{}, nil
|
||||||
|
}
|
||||||
|
stringReader := strings.NewReader(val)
|
||||||
|
csvReader := csv.NewReader(stringReader)
|
||||||
|
return csvReader.Read()
|
||||||
|
}
|
||||||
|
|
||||||
|
func writeAsCSV(vals []string) (string, error) {
|
||||||
|
b := &bytes.Buffer{}
|
||||||
|
w := csv.NewWriter(b)
|
||||||
|
err := w.Write(vals)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
w.Flush()
|
||||||
|
return strings.TrimSuffix(b.String(), fmt.Sprintln()), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *stringSliceValue) Set(val string) error {
|
||||||
|
v, err := readAsCSV(val)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if !s.changed {
|
||||||
|
*s.value = v
|
||||||
|
} else {
|
||||||
|
*s.value = append(*s.value, v...)
|
||||||
|
}
|
||||||
|
s.changed = true
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *stringSliceValue) Type() string {
|
||||||
|
return "stringSlice"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *stringSliceValue) String() string {
|
||||||
|
str, _ := writeAsCSV(*s.value)
|
||||||
|
return "[" + str + "]"
|
||||||
|
}
|
||||||
|
|
||||||
|
func stringSliceConv(sval string) (interface{}, error) {
|
||||||
|
sval = sval[1 : len(sval)-1]
|
||||||
|
// An empty string would cause a slice with one (empty) string
|
||||||
|
if len(sval) == 0 {
|
||||||
|
return []string{}, nil
|
||||||
|
}
|
||||||
|
return readAsCSV(sval)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetStringSlice return the []string value of a flag with the given name
|
||||||
|
func (f *FlagSet) GetStringSlice(name string) ([]string, error) {
|
||||||
|
val, err := f.getFlagType(name, "stringSlice", stringSliceConv)
|
||||||
|
if err != nil {
|
||||||
|
return []string{}, err
|
||||||
|
}
|
||||||
|
return val.([]string), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// StringSliceVar defines a string flag with specified name, default value, and usage string.
|
||||||
|
// The argument p points to a []string variable in which to store the value of the flag.
|
||||||
|
func (f *FlagSet) StringSliceVar(p *[]string, name string, value []string, usage string) {
|
||||||
|
f.VarP(newStringSliceValue(value, p), name, "", usage)
|
||||||
|
}
|
||||||
|
|
||||||
|
// StringSliceVarP is like StringSliceVar, but accepts a shorthand letter that can be used after a single dash.
|
||||||
|
func (f *FlagSet) StringSliceVarP(p *[]string, name, shorthand string, value []string, usage string) {
|
||||||
|
f.VarP(newStringSliceValue(value, p), name, shorthand, usage)
|
||||||
|
}
|
||||||
|
|
||||||
|
// StringSliceVar defines a string flag with specified name, default value, and usage string.
|
||||||
|
// The argument p points to a []string variable in which to store the value of the flag.
|
||||||
|
func StringSliceVar(p *[]string, name string, value []string, usage string) {
|
||||||
|
CommandLine.VarP(newStringSliceValue(value, p), name, "", usage)
|
||||||
|
}
|
||||||
|
|
||||||
|
// StringSliceVarP is like StringSliceVar, but accepts a shorthand letter that can be used after a single dash.
|
||||||
|
func StringSliceVarP(p *[]string, name, shorthand string, value []string, usage string) {
|
||||||
|
CommandLine.VarP(newStringSliceValue(value, p), name, shorthand, usage)
|
||||||
|
}
|
||||||
|
|
||||||
|
// StringSlice defines a string flag with specified name, default value, and usage string.
|
||||||
|
// The return value is the address of a []string variable that stores the value of the flag.
|
||||||
|
func (f *FlagSet) StringSlice(name string, value []string, usage string) *[]string {
|
||||||
|
p := []string{}
|
||||||
|
f.StringSliceVarP(&p, name, "", value, usage)
|
||||||
|
return &p
|
||||||
|
}
|
||||||
|
|
||||||
|
// StringSliceP is like StringSlice, but accepts a shorthand letter that can be used after a single dash.
|
||||||
|
func (f *FlagSet) StringSliceP(name, shorthand string, value []string, usage string) *[]string {
|
||||||
|
p := []string{}
|
||||||
|
f.StringSliceVarP(&p, name, shorthand, value, usage)
|
||||||
|
return &p
|
||||||
|
}
|
||||||
|
|
||||||
|
// StringSlice defines a string flag with specified name, default value, and usage string.
|
||||||
|
// The return value is the address of a []string variable that stores the value of the flag.
|
||||||
|
func StringSlice(name string, value []string, usage string) *[]string {
|
||||||
|
return CommandLine.StringSliceP(name, "", value, usage)
|
||||||
|
}
|
||||||
|
|
||||||
|
// StringSliceP is like StringSlice, but accepts a shorthand letter that can be used after a single dash.
|
||||||
|
func StringSliceP(name, shorthand string, value []string, usage string) *[]string {
|
||||||
|
return CommandLine.StringSliceP(name, shorthand, value, usage)
|
||||||
|
}
|
32
vendor/github.com/spf13/pflag/uint.go
generated
vendored
32
vendor/github.com/spf13/pflag/uint.go
generated
vendored
|
@ -1,9 +1,6 @@
|
||||||
package pflag
|
package pflag
|
||||||
|
|
||||||
import (
|
import "strconv"
|
||||||
"fmt"
|
|
||||||
"strconv"
|
|
||||||
)
|
|
||||||
|
|
||||||
// -- uint Value
|
// -- uint Value
|
||||||
type uintValue uint
|
type uintValue uint
|
||||||
|
@ -23,7 +20,24 @@ func (i *uintValue) Type() string {
|
||||||
return "uint"
|
return "uint"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *uintValue) String() string { return fmt.Sprintf("%v", *i) }
|
func (i *uintValue) String() string { return strconv.FormatUint(uint64(*i), 10) }
|
||||||
|
|
||||||
|
func uintConv(sval string) (interface{}, error) {
|
||||||
|
v, err := strconv.ParseUint(sval, 0, 0)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
return uint(v), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetUint return the uint value of a flag with the given name
|
||||||
|
func (f *FlagSet) GetUint(name string) (uint, error) {
|
||||||
|
val, err := f.getFlagType(name, "uint", uintConv)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
return val.(uint), nil
|
||||||
|
}
|
||||||
|
|
||||||
// UintVar defines a uint flag with specified name, default value, and usage string.
|
// UintVar defines a uint flag with specified name, default value, and usage string.
|
||||||
// The argument p points to a uint variable in which to store the value of the flag.
|
// The argument p points to a uint variable in which to store the value of the flag.
|
||||||
|
@ -31,7 +45,7 @@ func (f *FlagSet) UintVar(p *uint, name string, value uint, usage string) {
|
||||||
f.VarP(newUintValue(value, p), name, "", usage)
|
f.VarP(newUintValue(value, p), name, "", usage)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Like UintVar, but accepts a shorthand letter that can be used after a single dash.
|
// UintVarP is like UintVar, but accepts a shorthand letter that can be used after a single dash.
|
||||||
func (f *FlagSet) UintVarP(p *uint, name, shorthand string, value uint, usage string) {
|
func (f *FlagSet) UintVarP(p *uint, name, shorthand string, value uint, usage string) {
|
||||||
f.VarP(newUintValue(value, p), name, shorthand, usage)
|
f.VarP(newUintValue(value, p), name, shorthand, usage)
|
||||||
}
|
}
|
||||||
|
@ -42,7 +56,7 @@ func UintVar(p *uint, name string, value uint, usage string) {
|
||||||
CommandLine.VarP(newUintValue(value, p), name, "", usage)
|
CommandLine.VarP(newUintValue(value, p), name, "", usage)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Like UintVar, but accepts a shorthand letter that can be used after a single dash.
|
// UintVarP is like UintVar, but accepts a shorthand letter that can be used after a single dash.
|
||||||
func UintVarP(p *uint, name, shorthand string, value uint, usage string) {
|
func UintVarP(p *uint, name, shorthand string, value uint, usage string) {
|
||||||
CommandLine.VarP(newUintValue(value, p), name, shorthand, usage)
|
CommandLine.VarP(newUintValue(value, p), name, shorthand, usage)
|
||||||
}
|
}
|
||||||
|
@ -55,7 +69,7 @@ func (f *FlagSet) Uint(name string, value uint, usage string) *uint {
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
// Like Uint, but accepts a shorthand letter that can be used after a single dash.
|
// UintP is like Uint, but accepts a shorthand letter that can be used after a single dash.
|
||||||
func (f *FlagSet) UintP(name, shorthand string, value uint, usage string) *uint {
|
func (f *FlagSet) UintP(name, shorthand string, value uint, usage string) *uint {
|
||||||
p := new(uint)
|
p := new(uint)
|
||||||
f.UintVarP(p, name, shorthand, value, usage)
|
f.UintVarP(p, name, shorthand, value, usage)
|
||||||
|
@ -68,7 +82,7 @@ func Uint(name string, value uint, usage string) *uint {
|
||||||
return CommandLine.UintP(name, "", value, usage)
|
return CommandLine.UintP(name, "", value, usage)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Like Uint, but accepts a shorthand letter that can be used after a single dash.
|
// UintP is like Uint, but accepts a shorthand letter that can be used after a single dash.
|
||||||
func UintP(name, shorthand string, value uint, usage string) *uint {
|
func UintP(name, shorthand string, value uint, usage string) *uint {
|
||||||
return CommandLine.UintP(name, shorthand, value, usage)
|
return CommandLine.UintP(name, shorthand, value, usage)
|
||||||
}
|
}
|
||||||
|
|
34
vendor/github.com/spf13/pflag/uint16.go
generated
vendored
34
vendor/github.com/spf13/pflag/uint16.go
generated
vendored
|
@ -1,9 +1,6 @@
|
||||||
package pflag
|
package pflag
|
||||||
|
|
||||||
import (
|
import "strconv"
|
||||||
"fmt"
|
|
||||||
"strconv"
|
|
||||||
)
|
|
||||||
|
|
||||||
// -- uint16 value
|
// -- uint16 value
|
||||||
type uint16Value uint16
|
type uint16Value uint16
|
||||||
|
@ -12,7 +9,7 @@ func newUint16Value(val uint16, p *uint16) *uint16Value {
|
||||||
*p = val
|
*p = val
|
||||||
return (*uint16Value)(p)
|
return (*uint16Value)(p)
|
||||||
}
|
}
|
||||||
func (i *uint16Value) String() string { return fmt.Sprintf("%d", *i) }
|
|
||||||
func (i *uint16Value) Set(s string) error {
|
func (i *uint16Value) Set(s string) error {
|
||||||
v, err := strconv.ParseUint(s, 0, 16)
|
v, err := strconv.ParseUint(s, 0, 16)
|
||||||
*i = uint16Value(v)
|
*i = uint16Value(v)
|
||||||
|
@ -23,13 +20,32 @@ func (i *uint16Value) Type() string {
|
||||||
return "uint16"
|
return "uint16"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (i *uint16Value) String() string { return strconv.FormatUint(uint64(*i), 10) }
|
||||||
|
|
||||||
|
func uint16Conv(sval string) (interface{}, error) {
|
||||||
|
v, err := strconv.ParseUint(sval, 0, 16)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
return uint16(v), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetUint16 return the uint16 value of a flag with the given name
|
||||||
|
func (f *FlagSet) GetUint16(name string) (uint16, error) {
|
||||||
|
val, err := f.getFlagType(name, "uint16", uint16Conv)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
return val.(uint16), nil
|
||||||
|
}
|
||||||
|
|
||||||
// Uint16Var defines a uint flag with specified name, default value, and usage string.
|
// Uint16Var defines a uint flag with specified name, default value, and usage string.
|
||||||
// The argument p points to a uint variable in which to store the value of the flag.
|
// The argument p points to a uint variable in which to store the value of the flag.
|
||||||
func (f *FlagSet) Uint16Var(p *uint16, name string, value uint16, usage string) {
|
func (f *FlagSet) Uint16Var(p *uint16, name string, value uint16, usage string) {
|
||||||
f.VarP(newUint16Value(value, p), name, "", usage)
|
f.VarP(newUint16Value(value, p), name, "", usage)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Like Uint16Var, but accepts a shorthand letter that can be used after a single dash.
|
// Uint16VarP is like Uint16Var, but accepts a shorthand letter that can be used after a single dash.
|
||||||
func (f *FlagSet) Uint16VarP(p *uint16, name, shorthand string, value uint16, usage string) {
|
func (f *FlagSet) Uint16VarP(p *uint16, name, shorthand string, value uint16, usage string) {
|
||||||
f.VarP(newUint16Value(value, p), name, shorthand, usage)
|
f.VarP(newUint16Value(value, p), name, shorthand, usage)
|
||||||
}
|
}
|
||||||
|
@ -40,7 +56,7 @@ func Uint16Var(p *uint16, name string, value uint16, usage string) {
|
||||||
CommandLine.VarP(newUint16Value(value, p), name, "", usage)
|
CommandLine.VarP(newUint16Value(value, p), name, "", usage)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Like Uint16Var, but accepts a shorthand letter that can be used after a single dash.
|
// Uint16VarP is like Uint16Var, but accepts a shorthand letter that can be used after a single dash.
|
||||||
func Uint16VarP(p *uint16, name, shorthand string, value uint16, usage string) {
|
func Uint16VarP(p *uint16, name, shorthand string, value uint16, usage string) {
|
||||||
CommandLine.VarP(newUint16Value(value, p), name, shorthand, usage)
|
CommandLine.VarP(newUint16Value(value, p), name, shorthand, usage)
|
||||||
}
|
}
|
||||||
|
@ -53,7 +69,7 @@ func (f *FlagSet) Uint16(name string, value uint16, usage string) *uint16 {
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
// Like Uint16, but accepts a shorthand letter that can be used after a single dash.
|
// Uint16P is like Uint16, but accepts a shorthand letter that can be used after a single dash.
|
||||||
func (f *FlagSet) Uint16P(name, shorthand string, value uint16, usage string) *uint16 {
|
func (f *FlagSet) Uint16P(name, shorthand string, value uint16, usage string) *uint16 {
|
||||||
p := new(uint16)
|
p := new(uint16)
|
||||||
f.Uint16VarP(p, name, shorthand, value, usage)
|
f.Uint16VarP(p, name, shorthand, value, usage)
|
||||||
|
@ -66,7 +82,7 @@ func Uint16(name string, value uint16, usage string) *uint16 {
|
||||||
return CommandLine.Uint16P(name, "", value, usage)
|
return CommandLine.Uint16P(name, "", value, usage)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Like Uint16, but accepts a shorthand letter that can be used after a single dash.
|
// Uint16P is like Uint16, but accepts a shorthand letter that can be used after a single dash.
|
||||||
func Uint16P(name, shorthand string, value uint16, usage string) *uint16 {
|
func Uint16P(name, shorthand string, value uint16, usage string) *uint16 {
|
||||||
return CommandLine.Uint16P(name, shorthand, value, usage)
|
return CommandLine.Uint16P(name, shorthand, value, usage)
|
||||||
}
|
}
|
||||||
|
|
36
vendor/github.com/spf13/pflag/uint32.go
generated
vendored
36
vendor/github.com/spf13/pflag/uint32.go
generated
vendored
|
@ -1,18 +1,15 @@
|
||||||
package pflag
|
package pflag
|
||||||
|
|
||||||
import (
|
import "strconv"
|
||||||
"fmt"
|
|
||||||
"strconv"
|
|
||||||
)
|
|
||||||
|
|
||||||
// -- uint16 value
|
// -- uint32 value
|
||||||
type uint32Value uint32
|
type uint32Value uint32
|
||||||
|
|
||||||
func newUint32Value(val uint32, p *uint32) *uint32Value {
|
func newUint32Value(val uint32, p *uint32) *uint32Value {
|
||||||
*p = val
|
*p = val
|
||||||
return (*uint32Value)(p)
|
return (*uint32Value)(p)
|
||||||
}
|
}
|
||||||
func (i *uint32Value) String() string { return fmt.Sprintf("%d", *i) }
|
|
||||||
func (i *uint32Value) Set(s string) error {
|
func (i *uint32Value) Set(s string) error {
|
||||||
v, err := strconv.ParseUint(s, 0, 32)
|
v, err := strconv.ParseUint(s, 0, 32)
|
||||||
*i = uint32Value(v)
|
*i = uint32Value(v)
|
||||||
|
@ -23,13 +20,32 @@ func (i *uint32Value) Type() string {
|
||||||
return "uint32"
|
return "uint32"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (i *uint32Value) String() string { return strconv.FormatUint(uint64(*i), 10) }
|
||||||
|
|
||||||
|
func uint32Conv(sval string) (interface{}, error) {
|
||||||
|
v, err := strconv.ParseUint(sval, 0, 32)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
return uint32(v), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetUint32 return the uint32 value of a flag with the given name
|
||||||
|
func (f *FlagSet) GetUint32(name string) (uint32, error) {
|
||||||
|
val, err := f.getFlagType(name, "uint32", uint32Conv)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
return val.(uint32), nil
|
||||||
|
}
|
||||||
|
|
||||||
// Uint32Var defines a uint32 flag with specified name, default value, and usage string.
|
// Uint32Var defines a uint32 flag with specified name, default value, and usage string.
|
||||||
// The argument p points to a uint32 variable in which to store the value of the flag.
|
// The argument p points to a uint32 variable in which to store the value of the flag.
|
||||||
func (f *FlagSet) Uint32Var(p *uint32, name string, value uint32, usage string) {
|
func (f *FlagSet) Uint32Var(p *uint32, name string, value uint32, usage string) {
|
||||||
f.VarP(newUint32Value(value, p), name, "", usage)
|
f.VarP(newUint32Value(value, p), name, "", usage)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Like Uint32Var, but accepts a shorthand letter that can be used after a single dash.
|
// Uint32VarP is like Uint32Var, but accepts a shorthand letter that can be used after a single dash.
|
||||||
func (f *FlagSet) Uint32VarP(p *uint32, name, shorthand string, value uint32, usage string) {
|
func (f *FlagSet) Uint32VarP(p *uint32, name, shorthand string, value uint32, usage string) {
|
||||||
f.VarP(newUint32Value(value, p), name, shorthand, usage)
|
f.VarP(newUint32Value(value, p), name, shorthand, usage)
|
||||||
}
|
}
|
||||||
|
@ -40,7 +56,7 @@ func Uint32Var(p *uint32, name string, value uint32, usage string) {
|
||||||
CommandLine.VarP(newUint32Value(value, p), name, "", usage)
|
CommandLine.VarP(newUint32Value(value, p), name, "", usage)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Like Uint32Var, but accepts a shorthand letter that can be used after a single dash.
|
// Uint32VarP is like Uint32Var, but accepts a shorthand letter that can be used after a single dash.
|
||||||
func Uint32VarP(p *uint32, name, shorthand string, value uint32, usage string) {
|
func Uint32VarP(p *uint32, name, shorthand string, value uint32, usage string) {
|
||||||
CommandLine.VarP(newUint32Value(value, p), name, shorthand, usage)
|
CommandLine.VarP(newUint32Value(value, p), name, shorthand, usage)
|
||||||
}
|
}
|
||||||
|
@ -53,7 +69,7 @@ func (f *FlagSet) Uint32(name string, value uint32, usage string) *uint32 {
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
// Like Uint32, but accepts a shorthand letter that can be used after a single dash.
|
// Uint32P is like Uint32, but accepts a shorthand letter that can be used after a single dash.
|
||||||
func (f *FlagSet) Uint32P(name, shorthand string, value uint32, usage string) *uint32 {
|
func (f *FlagSet) Uint32P(name, shorthand string, value uint32, usage string) *uint32 {
|
||||||
p := new(uint32)
|
p := new(uint32)
|
||||||
f.Uint32VarP(p, name, shorthand, value, usage)
|
f.Uint32VarP(p, name, shorthand, value, usage)
|
||||||
|
@ -66,7 +82,7 @@ func Uint32(name string, value uint32, usage string) *uint32 {
|
||||||
return CommandLine.Uint32P(name, "", value, usage)
|
return CommandLine.Uint32P(name, "", value, usage)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Like Uint32, but accepts a shorthand letter that can be used after a single dash.
|
// Uint32P is like Uint32, but accepts a shorthand letter that can be used after a single dash.
|
||||||
func Uint32P(name, shorthand string, value uint32, usage string) *uint32 {
|
func Uint32P(name, shorthand string, value uint32, usage string) *uint32 {
|
||||||
return CommandLine.Uint32P(name, shorthand, value, usage)
|
return CommandLine.Uint32P(name, shorthand, value, usage)
|
||||||
}
|
}
|
||||||
|
|
32
vendor/github.com/spf13/pflag/uint64.go
generated
vendored
32
vendor/github.com/spf13/pflag/uint64.go
generated
vendored
|
@ -1,9 +1,6 @@
|
||||||
package pflag
|
package pflag
|
||||||
|
|
||||||
import (
|
import "strconv"
|
||||||
"fmt"
|
|
||||||
"strconv"
|
|
||||||
)
|
|
||||||
|
|
||||||
// -- uint64 Value
|
// -- uint64 Value
|
||||||
type uint64Value uint64
|
type uint64Value uint64
|
||||||
|
@ -23,7 +20,24 @@ func (i *uint64Value) Type() string {
|
||||||
return "uint64"
|
return "uint64"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *uint64Value) String() string { return fmt.Sprintf("%v", *i) }
|
func (i *uint64Value) String() string { return strconv.FormatUint(uint64(*i), 10) }
|
||||||
|
|
||||||
|
func uint64Conv(sval string) (interface{}, error) {
|
||||||
|
v, err := strconv.ParseUint(sval, 0, 64)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
return uint64(v), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetUint64 return the uint64 value of a flag with the given name
|
||||||
|
func (f *FlagSet) GetUint64(name string) (uint64, error) {
|
||||||
|
val, err := f.getFlagType(name, "uint64", uint64Conv)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
return val.(uint64), nil
|
||||||
|
}
|
||||||
|
|
||||||
// Uint64Var defines a uint64 flag with specified name, default value, and usage string.
|
// Uint64Var defines a uint64 flag with specified name, default value, and usage string.
|
||||||
// The argument p points to a uint64 variable in which to store the value of the flag.
|
// The argument p points to a uint64 variable in which to store the value of the flag.
|
||||||
|
@ -31,7 +45,7 @@ func (f *FlagSet) Uint64Var(p *uint64, name string, value uint64, usage string)
|
||||||
f.VarP(newUint64Value(value, p), name, "", usage)
|
f.VarP(newUint64Value(value, p), name, "", usage)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Like Uint64Var, but accepts a shorthand letter that can be used after a single dash.
|
// Uint64VarP is like Uint64Var, but accepts a shorthand letter that can be used after a single dash.
|
||||||
func (f *FlagSet) Uint64VarP(p *uint64, name, shorthand string, value uint64, usage string) {
|
func (f *FlagSet) Uint64VarP(p *uint64, name, shorthand string, value uint64, usage string) {
|
||||||
f.VarP(newUint64Value(value, p), name, shorthand, usage)
|
f.VarP(newUint64Value(value, p), name, shorthand, usage)
|
||||||
}
|
}
|
||||||
|
@ -42,7 +56,7 @@ func Uint64Var(p *uint64, name string, value uint64, usage string) {
|
||||||
CommandLine.VarP(newUint64Value(value, p), name, "", usage)
|
CommandLine.VarP(newUint64Value(value, p), name, "", usage)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Like Uint64Var, but accepts a shorthand letter that can be used after a single dash.
|
// Uint64VarP is like Uint64Var, but accepts a shorthand letter that can be used after a single dash.
|
||||||
func Uint64VarP(p *uint64, name, shorthand string, value uint64, usage string) {
|
func Uint64VarP(p *uint64, name, shorthand string, value uint64, usage string) {
|
||||||
CommandLine.VarP(newUint64Value(value, p), name, shorthand, usage)
|
CommandLine.VarP(newUint64Value(value, p), name, shorthand, usage)
|
||||||
}
|
}
|
||||||
|
@ -55,7 +69,7 @@ func (f *FlagSet) Uint64(name string, value uint64, usage string) *uint64 {
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
// Like Uint64, but accepts a shorthand letter that can be used after a single dash.
|
// Uint64P is like Uint64, but accepts a shorthand letter that can be used after a single dash.
|
||||||
func (f *FlagSet) Uint64P(name, shorthand string, value uint64, usage string) *uint64 {
|
func (f *FlagSet) Uint64P(name, shorthand string, value uint64, usage string) *uint64 {
|
||||||
p := new(uint64)
|
p := new(uint64)
|
||||||
f.Uint64VarP(p, name, shorthand, value, usage)
|
f.Uint64VarP(p, name, shorthand, value, usage)
|
||||||
|
@ -68,7 +82,7 @@ func Uint64(name string, value uint64, usage string) *uint64 {
|
||||||
return CommandLine.Uint64P(name, "", value, usage)
|
return CommandLine.Uint64P(name, "", value, usage)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Like Uint64, but accepts a shorthand letter that can be used after a single dash.
|
// Uint64P is like Uint64, but accepts a shorthand letter that can be used after a single dash.
|
||||||
func Uint64P(name, shorthand string, value uint64, usage string) *uint64 {
|
func Uint64P(name, shorthand string, value uint64, usage string) *uint64 {
|
||||||
return CommandLine.Uint64P(name, shorthand, value, usage)
|
return CommandLine.Uint64P(name, shorthand, value, usage)
|
||||||
}
|
}
|
||||||
|
|
32
vendor/github.com/spf13/pflag/uint8.go
generated
vendored
32
vendor/github.com/spf13/pflag/uint8.go
generated
vendored
|
@ -1,9 +1,6 @@
|
||||||
package pflag
|
package pflag
|
||||||
|
|
||||||
import (
|
import "strconv"
|
||||||
"fmt"
|
|
||||||
"strconv"
|
|
||||||
)
|
|
||||||
|
|
||||||
// -- uint8 Value
|
// -- uint8 Value
|
||||||
type uint8Value uint8
|
type uint8Value uint8
|
||||||
|
@ -23,7 +20,24 @@ func (i *uint8Value) Type() string {
|
||||||
return "uint8"
|
return "uint8"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *uint8Value) String() string { return fmt.Sprintf("%v", *i) }
|
func (i *uint8Value) String() string { return strconv.FormatUint(uint64(*i), 10) }
|
||||||
|
|
||||||
|
func uint8Conv(sval string) (interface{}, error) {
|
||||||
|
v, err := strconv.ParseUint(sval, 0, 8)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
return uint8(v), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetUint8 return the uint8 value of a flag with the given name
|
||||||
|
func (f *FlagSet) GetUint8(name string) (uint8, error) {
|
||||||
|
val, err := f.getFlagType(name, "uint8", uint8Conv)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
return val.(uint8), nil
|
||||||
|
}
|
||||||
|
|
||||||
// Uint8Var defines a uint8 flag with specified name, default value, and usage string.
|
// Uint8Var defines a uint8 flag with specified name, default value, and usage string.
|
||||||
// The argument p points to a uint8 variable in which to store the value of the flag.
|
// The argument p points to a uint8 variable in which to store the value of the flag.
|
||||||
|
@ -31,7 +45,7 @@ func (f *FlagSet) Uint8Var(p *uint8, name string, value uint8, usage string) {
|
||||||
f.VarP(newUint8Value(value, p), name, "", usage)
|
f.VarP(newUint8Value(value, p), name, "", usage)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Like Uint8Var, but accepts a shorthand letter that can be used after a single dash.
|
// Uint8VarP is like Uint8Var, but accepts a shorthand letter that can be used after a single dash.
|
||||||
func (f *FlagSet) Uint8VarP(p *uint8, name, shorthand string, value uint8, usage string) {
|
func (f *FlagSet) Uint8VarP(p *uint8, name, shorthand string, value uint8, usage string) {
|
||||||
f.VarP(newUint8Value(value, p), name, shorthand, usage)
|
f.VarP(newUint8Value(value, p), name, shorthand, usage)
|
||||||
}
|
}
|
||||||
|
@ -42,7 +56,7 @@ func Uint8Var(p *uint8, name string, value uint8, usage string) {
|
||||||
CommandLine.VarP(newUint8Value(value, p), name, "", usage)
|
CommandLine.VarP(newUint8Value(value, p), name, "", usage)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Like Uint8Var, but accepts a shorthand letter that can be used after a single dash.
|
// Uint8VarP is like Uint8Var, but accepts a shorthand letter that can be used after a single dash.
|
||||||
func Uint8VarP(p *uint8, name, shorthand string, value uint8, usage string) {
|
func Uint8VarP(p *uint8, name, shorthand string, value uint8, usage string) {
|
||||||
CommandLine.VarP(newUint8Value(value, p), name, shorthand, usage)
|
CommandLine.VarP(newUint8Value(value, p), name, shorthand, usage)
|
||||||
}
|
}
|
||||||
|
@ -55,7 +69,7 @@ func (f *FlagSet) Uint8(name string, value uint8, usage string) *uint8 {
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
// Like Uint8, but accepts a shorthand letter that can be used after a single dash.
|
// Uint8P is like Uint8, but accepts a shorthand letter that can be used after a single dash.
|
||||||
func (f *FlagSet) Uint8P(name, shorthand string, value uint8, usage string) *uint8 {
|
func (f *FlagSet) Uint8P(name, shorthand string, value uint8, usage string) *uint8 {
|
||||||
p := new(uint8)
|
p := new(uint8)
|
||||||
f.Uint8VarP(p, name, shorthand, value, usage)
|
f.Uint8VarP(p, name, shorthand, value, usage)
|
||||||
|
@ -68,7 +82,7 @@ func Uint8(name string, value uint8, usage string) *uint8 {
|
||||||
return CommandLine.Uint8P(name, "", value, usage)
|
return CommandLine.Uint8P(name, "", value, usage)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Like Uint8, but accepts a shorthand letter that can be used after a single dash.
|
// Uint8P is like Uint8, but accepts a shorthand letter that can be used after a single dash.
|
||||||
func Uint8P(name, shorthand string, value uint8, usage string) *uint8 {
|
func Uint8P(name, shorthand string, value uint8, usage string) *uint8 {
|
||||||
return CommandLine.Uint8P(name, shorthand, value, usage)
|
return CommandLine.Uint8P(name, shorthand, value, usage)
|
||||||
}
|
}
|
||||||
|
|
525
vendor/golang.org/x/net/internal/timeseries/timeseries.go
generated
vendored
Normal file
525
vendor/golang.org/x/net/internal/timeseries/timeseries.go
generated
vendored
Normal file
|
@ -0,0 +1,525 @@
|
||||||
|
// Copyright 2015 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// Package timeseries implements a time series structure for stats collection.
|
||||||
|
package timeseries // import "golang.org/x/net/internal/timeseries"
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
timeSeriesNumBuckets = 64
|
||||||
|
minuteHourSeriesNumBuckets = 60
|
||||||
|
)
|
||||||
|
|
||||||
|
var timeSeriesResolutions = []time.Duration{
|
||||||
|
1 * time.Second,
|
||||||
|
10 * time.Second,
|
||||||
|
1 * time.Minute,
|
||||||
|
10 * time.Minute,
|
||||||
|
1 * time.Hour,
|
||||||
|
6 * time.Hour,
|
||||||
|
24 * time.Hour, // 1 day
|
||||||
|
7 * 24 * time.Hour, // 1 week
|
||||||
|
4 * 7 * 24 * time.Hour, // 4 weeks
|
||||||
|
16 * 7 * 24 * time.Hour, // 16 weeks
|
||||||
|
}
|
||||||
|
|
||||||
|
var minuteHourSeriesResolutions = []time.Duration{
|
||||||
|
1 * time.Second,
|
||||||
|
1 * time.Minute,
|
||||||
|
}
|
||||||
|
|
||||||
|
// An Observable is a kind of data that can be aggregated in a time series.
|
||||||
|
type Observable interface {
|
||||||
|
Multiply(ratio float64) // Multiplies the data in self by a given ratio
|
||||||
|
Add(other Observable) // Adds the data from a different observation to self
|
||||||
|
Clear() // Clears the observation so it can be reused.
|
||||||
|
CopyFrom(other Observable) // Copies the contents of a given observation to self
|
||||||
|
}
|
||||||
|
|
||||||
|
// Float attaches the methods of Observable to a float64.
|
||||||
|
type Float float64
|
||||||
|
|
||||||
|
// NewFloat returns a Float.
|
||||||
|
func NewFloat() Observable {
|
||||||
|
f := Float(0)
|
||||||
|
return &f
|
||||||
|
}
|
||||||
|
|
||||||
|
// String returns the float as a string.
|
||||||
|
func (f *Float) String() string { return fmt.Sprintf("%g", f.Value()) }
|
||||||
|
|
||||||
|
// Value returns the float's value.
|
||||||
|
func (f *Float) Value() float64 { return float64(*f) }
|
||||||
|
|
||||||
|
func (f *Float) Multiply(ratio float64) { *f *= Float(ratio) }
|
||||||
|
|
||||||
|
func (f *Float) Add(other Observable) {
|
||||||
|
o := other.(*Float)
|
||||||
|
*f += *o
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Float) Clear() { *f = 0 }
|
||||||
|
|
||||||
|
func (f *Float) CopyFrom(other Observable) {
|
||||||
|
o := other.(*Float)
|
||||||
|
*f = *o
|
||||||
|
}
|
||||||
|
|
||||||
|
// A Clock tells the current time.
|
||||||
|
type Clock interface {
|
||||||
|
Time() time.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
type defaultClock int
|
||||||
|
|
||||||
|
var defaultClockInstance defaultClock
|
||||||
|
|
||||||
|
func (defaultClock) Time() time.Time { return time.Now() }
|
||||||
|
|
||||||
|
// Information kept per level. Each level consists of a circular list of
|
||||||
|
// observations. The start of the level may be derived from end and the
|
||||||
|
// len(buckets) * sizeInMillis.
|
||||||
|
type tsLevel struct {
|
||||||
|
oldest int // index to oldest bucketed Observable
|
||||||
|
newest int // index to newest bucketed Observable
|
||||||
|
end time.Time // end timestamp for this level
|
||||||
|
size time.Duration // duration of the bucketed Observable
|
||||||
|
buckets []Observable // collections of observations
|
||||||
|
provider func() Observable // used for creating new Observable
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *tsLevel) Clear() {
|
||||||
|
l.oldest = 0
|
||||||
|
l.newest = len(l.buckets) - 1
|
||||||
|
l.end = time.Time{}
|
||||||
|
for i := range l.buckets {
|
||||||
|
if l.buckets[i] != nil {
|
||||||
|
l.buckets[i].Clear()
|
||||||
|
l.buckets[i] = nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *tsLevel) InitLevel(size time.Duration, numBuckets int, f func() Observable) {
|
||||||
|
l.size = size
|
||||||
|
l.provider = f
|
||||||
|
l.buckets = make([]Observable, numBuckets)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Keeps a sequence of levels. Each level is responsible for storing data at
|
||||||
|
// a given resolution. For example, the first level stores data at a one
|
||||||
|
// minute resolution while the second level stores data at a one hour
|
||||||
|
// resolution.
|
||||||
|
|
||||||
|
// Each level is represented by a sequence of buckets. Each bucket spans an
|
||||||
|
// interval equal to the resolution of the level. New observations are added
|
||||||
|
// to the last bucket.
|
||||||
|
type timeSeries struct {
|
||||||
|
provider func() Observable // make more Observable
|
||||||
|
numBuckets int // number of buckets in each level
|
||||||
|
levels []*tsLevel // levels of bucketed Observable
|
||||||
|
lastAdd time.Time // time of last Observable tracked
|
||||||
|
total Observable // convenient aggregation of all Observable
|
||||||
|
clock Clock // Clock for getting current time
|
||||||
|
pending Observable // observations not yet bucketed
|
||||||
|
pendingTime time.Time // what time are we keeping in pending
|
||||||
|
dirty bool // if there are pending observations
|
||||||
|
}
|
||||||
|
|
||||||
|
// init initializes a level according to the supplied criteria.
|
||||||
|
func (ts *timeSeries) init(resolutions []time.Duration, f func() Observable, numBuckets int, clock Clock) {
|
||||||
|
ts.provider = f
|
||||||
|
ts.numBuckets = numBuckets
|
||||||
|
ts.clock = clock
|
||||||
|
ts.levels = make([]*tsLevel, len(resolutions))
|
||||||
|
|
||||||
|
for i := range resolutions {
|
||||||
|
if i > 0 && resolutions[i-1] >= resolutions[i] {
|
||||||
|
log.Print("timeseries: resolutions must be monotonically increasing")
|
||||||
|
break
|
||||||
|
}
|
||||||
|
newLevel := new(tsLevel)
|
||||||
|
newLevel.InitLevel(resolutions[i], ts.numBuckets, ts.provider)
|
||||||
|
ts.levels[i] = newLevel
|
||||||
|
}
|
||||||
|
|
||||||
|
ts.Clear()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear removes all observations from the time series.
|
||||||
|
func (ts *timeSeries) Clear() {
|
||||||
|
ts.lastAdd = time.Time{}
|
||||||
|
ts.total = ts.resetObservation(ts.total)
|
||||||
|
ts.pending = ts.resetObservation(ts.pending)
|
||||||
|
ts.pendingTime = time.Time{}
|
||||||
|
ts.dirty = false
|
||||||
|
|
||||||
|
for i := range ts.levels {
|
||||||
|
ts.levels[i].Clear()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add records an observation at the current time.
|
||||||
|
func (ts *timeSeries) Add(observation Observable) {
|
||||||
|
ts.AddWithTime(observation, ts.clock.Time())
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddWithTime records an observation at the specified time.
|
||||||
|
func (ts *timeSeries) AddWithTime(observation Observable, t time.Time) {
|
||||||
|
|
||||||
|
smallBucketDuration := ts.levels[0].size
|
||||||
|
|
||||||
|
if t.After(ts.lastAdd) {
|
||||||
|
ts.lastAdd = t
|
||||||
|
}
|
||||||
|
|
||||||
|
if t.After(ts.pendingTime) {
|
||||||
|
ts.advance(t)
|
||||||
|
ts.mergePendingUpdates()
|
||||||
|
ts.pendingTime = ts.levels[0].end
|
||||||
|
ts.pending.CopyFrom(observation)
|
||||||
|
ts.dirty = true
|
||||||
|
} else if t.After(ts.pendingTime.Add(-1 * smallBucketDuration)) {
|
||||||
|
// The observation is close enough to go into the pending bucket.
|
||||||
|
// This compensates for clock skewing and small scheduling delays
|
||||||
|
// by letting the update stay in the fast path.
|
||||||
|
ts.pending.Add(observation)
|
||||||
|
ts.dirty = true
|
||||||
|
} else {
|
||||||
|
ts.mergeValue(observation, t)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// mergeValue inserts the observation at the specified time in the past into all levels.
|
||||||
|
func (ts *timeSeries) mergeValue(observation Observable, t time.Time) {
|
||||||
|
for _, level := range ts.levels {
|
||||||
|
index := (ts.numBuckets - 1) - int(level.end.Sub(t)/level.size)
|
||||||
|
if 0 <= index && index < ts.numBuckets {
|
||||||
|
bucketNumber := (level.oldest + index) % ts.numBuckets
|
||||||
|
if level.buckets[bucketNumber] == nil {
|
||||||
|
level.buckets[bucketNumber] = level.provider()
|
||||||
|
}
|
||||||
|
level.buckets[bucketNumber].Add(observation)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ts.total.Add(observation)
|
||||||
|
}
|
||||||
|
|
||||||
|
// mergePendingUpdates applies the pending updates into all levels.
|
||||||
|
func (ts *timeSeries) mergePendingUpdates() {
|
||||||
|
if ts.dirty {
|
||||||
|
ts.mergeValue(ts.pending, ts.pendingTime)
|
||||||
|
ts.pending = ts.resetObservation(ts.pending)
|
||||||
|
ts.dirty = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// advance cycles the buckets at each level until the latest bucket in
|
||||||
|
// each level can hold the time specified.
|
||||||
|
func (ts *timeSeries) advance(t time.Time) {
|
||||||
|
if !t.After(ts.levels[0].end) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
for i := 0; i < len(ts.levels); i++ {
|
||||||
|
level := ts.levels[i]
|
||||||
|
if !level.end.Before(t) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the time is sufficiently far, just clear the level and advance
|
||||||
|
// directly.
|
||||||
|
if !t.Before(level.end.Add(level.size * time.Duration(ts.numBuckets))) {
|
||||||
|
for _, b := range level.buckets {
|
||||||
|
ts.resetObservation(b)
|
||||||
|
}
|
||||||
|
level.end = time.Unix(0, (t.UnixNano()/level.size.Nanoseconds())*level.size.Nanoseconds())
|
||||||
|
}
|
||||||
|
|
||||||
|
for t.After(level.end) {
|
||||||
|
level.end = level.end.Add(level.size)
|
||||||
|
level.newest = level.oldest
|
||||||
|
level.oldest = (level.oldest + 1) % ts.numBuckets
|
||||||
|
ts.resetObservation(level.buckets[level.newest])
|
||||||
|
}
|
||||||
|
|
||||||
|
t = level.end
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Latest returns the sum of the num latest buckets from the level.
|
||||||
|
func (ts *timeSeries) Latest(level, num int) Observable {
|
||||||
|
now := ts.clock.Time()
|
||||||
|
if ts.levels[0].end.Before(now) {
|
||||||
|
ts.advance(now)
|
||||||
|
}
|
||||||
|
|
||||||
|
ts.mergePendingUpdates()
|
||||||
|
|
||||||
|
result := ts.provider()
|
||||||
|
l := ts.levels[level]
|
||||||
|
index := l.newest
|
||||||
|
|
||||||
|
for i := 0; i < num; i++ {
|
||||||
|
if l.buckets[index] != nil {
|
||||||
|
result.Add(l.buckets[index])
|
||||||
|
}
|
||||||
|
if index == 0 {
|
||||||
|
index = ts.numBuckets
|
||||||
|
}
|
||||||
|
index--
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
// LatestBuckets returns a copy of the num latest buckets from level.
|
||||||
|
func (ts *timeSeries) LatestBuckets(level, num int) []Observable {
|
||||||
|
if level < 0 || level > len(ts.levels) {
|
||||||
|
log.Print("timeseries: bad level argument: ", level)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if num < 0 || num >= ts.numBuckets {
|
||||||
|
log.Print("timeseries: bad num argument: ", num)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
results := make([]Observable, num)
|
||||||
|
now := ts.clock.Time()
|
||||||
|
if ts.levels[0].end.Before(now) {
|
||||||
|
ts.advance(now)
|
||||||
|
}
|
||||||
|
|
||||||
|
ts.mergePendingUpdates()
|
||||||
|
|
||||||
|
l := ts.levels[level]
|
||||||
|
index := l.newest
|
||||||
|
|
||||||
|
for i := 0; i < num; i++ {
|
||||||
|
result := ts.provider()
|
||||||
|
results[i] = result
|
||||||
|
if l.buckets[index] != nil {
|
||||||
|
result.CopyFrom(l.buckets[index])
|
||||||
|
}
|
||||||
|
|
||||||
|
if index == 0 {
|
||||||
|
index = ts.numBuckets
|
||||||
|
}
|
||||||
|
index -= 1
|
||||||
|
}
|
||||||
|
return results
|
||||||
|
}
|
||||||
|
|
||||||
|
// ScaleBy updates observations by scaling by factor.
|
||||||
|
func (ts *timeSeries) ScaleBy(factor float64) {
|
||||||
|
for _, l := range ts.levels {
|
||||||
|
for i := 0; i < ts.numBuckets; i++ {
|
||||||
|
l.buckets[i].Multiply(factor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ts.total.Multiply(factor)
|
||||||
|
ts.pending.Multiply(factor)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Range returns the sum of observations added over the specified time range.
|
||||||
|
// If start or finish times don't fall on bucket boundaries of the same
|
||||||
|
// level, then return values are approximate answers.
|
||||||
|
func (ts *timeSeries) Range(start, finish time.Time) Observable {
|
||||||
|
return ts.ComputeRange(start, finish, 1)[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Recent returns the sum of observations from the last delta.
|
||||||
|
func (ts *timeSeries) Recent(delta time.Duration) Observable {
|
||||||
|
now := ts.clock.Time()
|
||||||
|
return ts.Range(now.Add(-delta), now)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Total returns the total of all observations.
|
||||||
|
func (ts *timeSeries) Total() Observable {
|
||||||
|
ts.mergePendingUpdates()
|
||||||
|
return ts.total
|
||||||
|
}
|
||||||
|
|
||||||
|
// ComputeRange computes a specified number of values into a slice using
|
||||||
|
// the observations recorded over the specified time period. The return
|
||||||
|
// values are approximate if the start or finish times don't fall on the
|
||||||
|
// bucket boundaries at the same level or if the number of buckets spanning
|
||||||
|
// the range is not an integral multiple of num.
|
||||||
|
func (ts *timeSeries) ComputeRange(start, finish time.Time, num int) []Observable {
|
||||||
|
if start.After(finish) {
|
||||||
|
log.Printf("timeseries: start > finish, %v>%v", start, finish)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if num < 0 {
|
||||||
|
log.Printf("timeseries: num < 0, %v", num)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
results := make([]Observable, num)
|
||||||
|
|
||||||
|
for _, l := range ts.levels {
|
||||||
|
if !start.Before(l.end.Add(-l.size * time.Duration(ts.numBuckets))) {
|
||||||
|
ts.extract(l, start, finish, num, results)
|
||||||
|
return results
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Failed to find a level that covers the desired range. So just
|
||||||
|
// extract from the last level, even if it doesn't cover the entire
|
||||||
|
// desired range.
|
||||||
|
ts.extract(ts.levels[len(ts.levels)-1], start, finish, num, results)
|
||||||
|
|
||||||
|
return results
|
||||||
|
}
|
||||||
|
|
||||||
|
// RecentList returns the specified number of values in slice over the most
|
||||||
|
// recent time period of the specified range.
|
||||||
|
func (ts *timeSeries) RecentList(delta time.Duration, num int) []Observable {
|
||||||
|
if delta < 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
now := ts.clock.Time()
|
||||||
|
return ts.ComputeRange(now.Add(-delta), now, num)
|
||||||
|
}
|
||||||
|
|
||||||
|
// extract returns a slice of specified number of observations from a given
|
||||||
|
// level over a given range.
|
||||||
|
func (ts *timeSeries) extract(l *tsLevel, start, finish time.Time, num int, results []Observable) {
|
||||||
|
ts.mergePendingUpdates()
|
||||||
|
|
||||||
|
srcInterval := l.size
|
||||||
|
dstInterval := finish.Sub(start) / time.Duration(num)
|
||||||
|
dstStart := start
|
||||||
|
srcStart := l.end.Add(-srcInterval * time.Duration(ts.numBuckets))
|
||||||
|
|
||||||
|
srcIndex := 0
|
||||||
|
|
||||||
|
// Where should scanning start?
|
||||||
|
if dstStart.After(srcStart) {
|
||||||
|
advance := dstStart.Sub(srcStart) / srcInterval
|
||||||
|
srcIndex += int(advance)
|
||||||
|
srcStart = srcStart.Add(advance * srcInterval)
|
||||||
|
}
|
||||||
|
|
||||||
|
// The i'th value is computed as show below.
|
||||||
|
// interval = (finish/start)/num
|
||||||
|
// i'th value = sum of observation in range
|
||||||
|
// [ start + i * interval,
|
||||||
|
// start + (i + 1) * interval )
|
||||||
|
for i := 0; i < num; i++ {
|
||||||
|
results[i] = ts.resetObservation(results[i])
|
||||||
|
dstEnd := dstStart.Add(dstInterval)
|
||||||
|
for srcIndex < ts.numBuckets && srcStart.Before(dstEnd) {
|
||||||
|
srcEnd := srcStart.Add(srcInterval)
|
||||||
|
if srcEnd.After(ts.lastAdd) {
|
||||||
|
srcEnd = ts.lastAdd
|
||||||
|
}
|
||||||
|
|
||||||
|
if !srcEnd.Before(dstStart) {
|
||||||
|
srcValue := l.buckets[(srcIndex+l.oldest)%ts.numBuckets]
|
||||||
|
if !srcStart.Before(dstStart) && !srcEnd.After(dstEnd) {
|
||||||
|
// dst completely contains src.
|
||||||
|
if srcValue != nil {
|
||||||
|
results[i].Add(srcValue)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// dst partially overlaps src.
|
||||||
|
overlapStart := maxTime(srcStart, dstStart)
|
||||||
|
overlapEnd := minTime(srcEnd, dstEnd)
|
||||||
|
base := srcEnd.Sub(srcStart)
|
||||||
|
fraction := overlapEnd.Sub(overlapStart).Seconds() / base.Seconds()
|
||||||
|
|
||||||
|
used := ts.provider()
|
||||||
|
if srcValue != nil {
|
||||||
|
used.CopyFrom(srcValue)
|
||||||
|
}
|
||||||
|
used.Multiply(fraction)
|
||||||
|
results[i].Add(used)
|
||||||
|
}
|
||||||
|
|
||||||
|
if srcEnd.After(dstEnd) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
srcIndex++
|
||||||
|
srcStart = srcStart.Add(srcInterval)
|
||||||
|
}
|
||||||
|
dstStart = dstStart.Add(dstInterval)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// resetObservation clears the content so the struct may be reused.
|
||||||
|
func (ts *timeSeries) resetObservation(observation Observable) Observable {
|
||||||
|
if observation == nil {
|
||||||
|
observation = ts.provider()
|
||||||
|
} else {
|
||||||
|
observation.Clear()
|
||||||
|
}
|
||||||
|
return observation
|
||||||
|
}
|
||||||
|
|
||||||
|
// TimeSeries tracks data at granularities from 1 second to 16 weeks.
|
||||||
|
type TimeSeries struct {
|
||||||
|
timeSeries
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewTimeSeries creates a new TimeSeries using the function provided for creating new Observable.
|
||||||
|
func NewTimeSeries(f func() Observable) *TimeSeries {
|
||||||
|
return NewTimeSeriesWithClock(f, defaultClockInstance)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewTimeSeriesWithClock creates a new TimeSeries using the function provided for creating new Observable and the clock for
|
||||||
|
// assigning timestamps.
|
||||||
|
func NewTimeSeriesWithClock(f func() Observable, clock Clock) *TimeSeries {
|
||||||
|
ts := new(TimeSeries)
|
||||||
|
ts.timeSeries.init(timeSeriesResolutions, f, timeSeriesNumBuckets, clock)
|
||||||
|
return ts
|
||||||
|
}
|
||||||
|
|
||||||
|
// MinuteHourSeries tracks data at granularities of 1 minute and 1 hour.
|
||||||
|
type MinuteHourSeries struct {
|
||||||
|
timeSeries
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewMinuteHourSeries creates a new MinuteHourSeries using the function provided for creating new Observable.
|
||||||
|
func NewMinuteHourSeries(f func() Observable) *MinuteHourSeries {
|
||||||
|
return NewMinuteHourSeriesWithClock(f, defaultClockInstance)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewMinuteHourSeriesWithClock creates a new MinuteHourSeries using the function provided for creating new Observable and the clock for
|
||||||
|
// assigning timestamps.
|
||||||
|
func NewMinuteHourSeriesWithClock(f func() Observable, clock Clock) *MinuteHourSeries {
|
||||||
|
ts := new(MinuteHourSeries)
|
||||||
|
ts.timeSeries.init(minuteHourSeriesResolutions, f,
|
||||||
|
minuteHourSeriesNumBuckets, clock)
|
||||||
|
return ts
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ts *MinuteHourSeries) Minute() Observable {
|
||||||
|
return ts.timeSeries.Latest(0, 60)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ts *MinuteHourSeries) Hour() Observable {
|
||||||
|
return ts.timeSeries.Latest(1, 60)
|
||||||
|
}
|
||||||
|
|
||||||
|
func minTime(a, b time.Time) time.Time {
|
||||||
|
if a.Before(b) {
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
func maxTime(a, b time.Time) time.Time {
|
||||||
|
if a.After(b) {
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
return b
|
||||||
|
}
|
524
vendor/golang.org/x/net/trace/events.go
generated
vendored
Normal file
524
vendor/golang.org/x/net/trace/events.go
generated
vendored
Normal file
|
@ -0,0 +1,524 @@
|
||||||
|
// Copyright 2015 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package trace
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"html/template"
|
||||||
|
"io"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
"runtime"
|
||||||
|
"sort"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"sync"
|
||||||
|
"sync/atomic"
|
||||||
|
"text/tabwriter"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
var eventsTmpl = template.Must(template.New("events").Funcs(template.FuncMap{
|
||||||
|
"elapsed": elapsed,
|
||||||
|
"trimSpace": strings.TrimSpace,
|
||||||
|
}).Parse(eventsHTML))
|
||||||
|
|
||||||
|
const maxEventsPerLog = 100
|
||||||
|
|
||||||
|
type bucket struct {
|
||||||
|
MaxErrAge time.Duration
|
||||||
|
String string
|
||||||
|
}
|
||||||
|
|
||||||
|
var buckets = []bucket{
|
||||||
|
{0, "total"},
|
||||||
|
{10 * time.Second, "errs<10s"},
|
||||||
|
{1 * time.Minute, "errs<1m"},
|
||||||
|
{10 * time.Minute, "errs<10m"},
|
||||||
|
{1 * time.Hour, "errs<1h"},
|
||||||
|
{10 * time.Hour, "errs<10h"},
|
||||||
|
{24000 * time.Hour, "errors"},
|
||||||
|
}
|
||||||
|
|
||||||
|
// RenderEvents renders the HTML page typically served at /debug/events.
|
||||||
|
// It does not do any auth checking; see AuthRequest for the default auth check
|
||||||
|
// used by the handler registered on http.DefaultServeMux.
|
||||||
|
// req may be nil.
|
||||||
|
func RenderEvents(w http.ResponseWriter, req *http.Request, sensitive bool) {
|
||||||
|
now := time.Now()
|
||||||
|
data := &struct {
|
||||||
|
Families []string // family names
|
||||||
|
Buckets []bucket
|
||||||
|
Counts [][]int // eventLog count per family/bucket
|
||||||
|
|
||||||
|
// Set when a bucket has been selected.
|
||||||
|
Family string
|
||||||
|
Bucket int
|
||||||
|
EventLogs eventLogs
|
||||||
|
Expanded bool
|
||||||
|
}{
|
||||||
|
Buckets: buckets,
|
||||||
|
}
|
||||||
|
|
||||||
|
data.Families = make([]string, 0, len(families))
|
||||||
|
famMu.RLock()
|
||||||
|
for name := range families {
|
||||||
|
data.Families = append(data.Families, name)
|
||||||
|
}
|
||||||
|
famMu.RUnlock()
|
||||||
|
sort.Strings(data.Families)
|
||||||
|
|
||||||
|
// Count the number of eventLogs in each family for each error age.
|
||||||
|
data.Counts = make([][]int, len(data.Families))
|
||||||
|
for i, name := range data.Families {
|
||||||
|
// TODO(sameer): move this loop under the family lock.
|
||||||
|
f := getEventFamily(name)
|
||||||
|
data.Counts[i] = make([]int, len(data.Buckets))
|
||||||
|
for j, b := range data.Buckets {
|
||||||
|
data.Counts[i][j] = f.Count(now, b.MaxErrAge)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if req != nil {
|
||||||
|
var ok bool
|
||||||
|
data.Family, data.Bucket, ok = parseEventsArgs(req)
|
||||||
|
if !ok {
|
||||||
|
// No-op
|
||||||
|
} else {
|
||||||
|
data.EventLogs = getEventFamily(data.Family).Copy(now, buckets[data.Bucket].MaxErrAge)
|
||||||
|
}
|
||||||
|
if data.EventLogs != nil {
|
||||||
|
defer data.EventLogs.Free()
|
||||||
|
sort.Sort(data.EventLogs)
|
||||||
|
}
|
||||||
|
if exp, err := strconv.ParseBool(req.FormValue("exp")); err == nil {
|
||||||
|
data.Expanded = exp
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
famMu.RLock()
|
||||||
|
defer famMu.RUnlock()
|
||||||
|
if err := eventsTmpl.Execute(w, data); err != nil {
|
||||||
|
log.Printf("net/trace: Failed executing template: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseEventsArgs(req *http.Request) (fam string, b int, ok bool) {
|
||||||
|
fam, bStr := req.FormValue("fam"), req.FormValue("b")
|
||||||
|
if fam == "" || bStr == "" {
|
||||||
|
return "", 0, false
|
||||||
|
}
|
||||||
|
b, err := strconv.Atoi(bStr)
|
||||||
|
if err != nil || b < 0 || b >= len(buckets) {
|
||||||
|
return "", 0, false
|
||||||
|
}
|
||||||
|
return fam, b, true
|
||||||
|
}
|
||||||
|
|
||||||
|
// An EventLog provides a log of events associated with a specific object.
|
||||||
|
type EventLog interface {
|
||||||
|
// Printf formats its arguments with fmt.Sprintf and adds the
|
||||||
|
// result to the event log.
|
||||||
|
Printf(format string, a ...interface{})
|
||||||
|
|
||||||
|
// Errorf is like Printf, but it marks this event as an error.
|
||||||
|
Errorf(format string, a ...interface{})
|
||||||
|
|
||||||
|
// Finish declares that this event log is complete.
|
||||||
|
// The event log should not be used after calling this method.
|
||||||
|
Finish()
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewEventLog returns a new EventLog with the specified family name
|
||||||
|
// and title.
|
||||||
|
func NewEventLog(family, title string) EventLog {
|
||||||
|
el := newEventLog()
|
||||||
|
el.ref()
|
||||||
|
el.Family, el.Title = family, title
|
||||||
|
el.Start = time.Now()
|
||||||
|
el.events = make([]logEntry, 0, maxEventsPerLog)
|
||||||
|
el.stack = make([]uintptr, 32)
|
||||||
|
n := runtime.Callers(2, el.stack)
|
||||||
|
el.stack = el.stack[:n]
|
||||||
|
|
||||||
|
getEventFamily(family).add(el)
|
||||||
|
return el
|
||||||
|
}
|
||||||
|
|
||||||
|
func (el *eventLog) Finish() {
|
||||||
|
getEventFamily(el.Family).remove(el)
|
||||||
|
el.unref() // matches ref in New
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
famMu sync.RWMutex
|
||||||
|
families = make(map[string]*eventFamily) // family name => family
|
||||||
|
)
|
||||||
|
|
||||||
|
func getEventFamily(fam string) *eventFamily {
|
||||||
|
famMu.Lock()
|
||||||
|
defer famMu.Unlock()
|
||||||
|
f := families[fam]
|
||||||
|
if f == nil {
|
||||||
|
f = &eventFamily{}
|
||||||
|
families[fam] = f
|
||||||
|
}
|
||||||
|
return f
|
||||||
|
}
|
||||||
|
|
||||||
|
type eventFamily struct {
|
||||||
|
mu sync.RWMutex
|
||||||
|
eventLogs eventLogs
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *eventFamily) add(el *eventLog) {
|
||||||
|
f.mu.Lock()
|
||||||
|
f.eventLogs = append(f.eventLogs, el)
|
||||||
|
f.mu.Unlock()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *eventFamily) remove(el *eventLog) {
|
||||||
|
f.mu.Lock()
|
||||||
|
defer f.mu.Unlock()
|
||||||
|
for i, el0 := range f.eventLogs {
|
||||||
|
if el == el0 {
|
||||||
|
copy(f.eventLogs[i:], f.eventLogs[i+1:])
|
||||||
|
f.eventLogs = f.eventLogs[:len(f.eventLogs)-1]
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *eventFamily) Count(now time.Time, maxErrAge time.Duration) (n int) {
|
||||||
|
f.mu.RLock()
|
||||||
|
defer f.mu.RUnlock()
|
||||||
|
for _, el := range f.eventLogs {
|
||||||
|
if el.hasRecentError(now, maxErrAge) {
|
||||||
|
n++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *eventFamily) Copy(now time.Time, maxErrAge time.Duration) (els eventLogs) {
|
||||||
|
f.mu.RLock()
|
||||||
|
defer f.mu.RUnlock()
|
||||||
|
els = make(eventLogs, 0, len(f.eventLogs))
|
||||||
|
for _, el := range f.eventLogs {
|
||||||
|
if el.hasRecentError(now, maxErrAge) {
|
||||||
|
el.ref()
|
||||||
|
els = append(els, el)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
type eventLogs []*eventLog
|
||||||
|
|
||||||
|
// Free calls unref on each element of the list.
|
||||||
|
func (els eventLogs) Free() {
|
||||||
|
for _, el := range els {
|
||||||
|
el.unref()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// eventLogs may be sorted in reverse chronological order.
|
||||||
|
func (els eventLogs) Len() int { return len(els) }
|
||||||
|
func (els eventLogs) Less(i, j int) bool { return els[i].Start.After(els[j].Start) }
|
||||||
|
func (els eventLogs) Swap(i, j int) { els[i], els[j] = els[j], els[i] }
|
||||||
|
|
||||||
|
// A logEntry is a timestamped log entry in an event log.
|
||||||
|
type logEntry struct {
|
||||||
|
When time.Time
|
||||||
|
Elapsed time.Duration // since previous event in log
|
||||||
|
NewDay bool // whether this event is on a different day to the previous event
|
||||||
|
What string
|
||||||
|
IsErr bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// WhenString returns a string representation of the elapsed time of the event.
|
||||||
|
// It will include the date if midnight was crossed.
|
||||||
|
func (e logEntry) WhenString() string {
|
||||||
|
if e.NewDay {
|
||||||
|
return e.When.Format("2006/01/02 15:04:05.000000")
|
||||||
|
}
|
||||||
|
return e.When.Format("15:04:05.000000")
|
||||||
|
}
|
||||||
|
|
||||||
|
// An eventLog represents an active event log.
|
||||||
|
type eventLog struct {
|
||||||
|
// Family is the top-level grouping of event logs to which this belongs.
|
||||||
|
Family string
|
||||||
|
|
||||||
|
// Title is the title of this event log.
|
||||||
|
Title string
|
||||||
|
|
||||||
|
// Timing information.
|
||||||
|
Start time.Time
|
||||||
|
|
||||||
|
// Call stack where this event log was created.
|
||||||
|
stack []uintptr
|
||||||
|
|
||||||
|
// Append-only sequence of events.
|
||||||
|
//
|
||||||
|
// TODO(sameer): change this to a ring buffer to avoid the array copy
|
||||||
|
// when we hit maxEventsPerLog.
|
||||||
|
mu sync.RWMutex
|
||||||
|
events []logEntry
|
||||||
|
LastErrorTime time.Time
|
||||||
|
discarded int
|
||||||
|
|
||||||
|
refs int32 // how many buckets this is in
|
||||||
|
}
|
||||||
|
|
||||||
|
func (el *eventLog) reset() {
|
||||||
|
// Clear all but the mutex. Mutexes may not be copied, even when unlocked.
|
||||||
|
el.Family = ""
|
||||||
|
el.Title = ""
|
||||||
|
el.Start = time.Time{}
|
||||||
|
el.stack = nil
|
||||||
|
el.events = nil
|
||||||
|
el.LastErrorTime = time.Time{}
|
||||||
|
el.discarded = 0
|
||||||
|
el.refs = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (el *eventLog) hasRecentError(now time.Time, maxErrAge time.Duration) bool {
|
||||||
|
if maxErrAge == 0 {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
el.mu.RLock()
|
||||||
|
defer el.mu.RUnlock()
|
||||||
|
return now.Sub(el.LastErrorTime) < maxErrAge
|
||||||
|
}
|
||||||
|
|
||||||
|
// delta returns the elapsed time since the last event or the log start,
|
||||||
|
// and whether it spans midnight.
|
||||||
|
// L >= el.mu
|
||||||
|
func (el *eventLog) delta(t time.Time) (time.Duration, bool) {
|
||||||
|
if len(el.events) == 0 {
|
||||||
|
return t.Sub(el.Start), false
|
||||||
|
}
|
||||||
|
prev := el.events[len(el.events)-1].When
|
||||||
|
return t.Sub(prev), prev.Day() != t.Day()
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (el *eventLog) Printf(format string, a ...interface{}) {
|
||||||
|
el.printf(false, format, a...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (el *eventLog) Errorf(format string, a ...interface{}) {
|
||||||
|
el.printf(true, format, a...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (el *eventLog) printf(isErr bool, format string, a ...interface{}) {
|
||||||
|
e := logEntry{When: time.Now(), IsErr: isErr, What: fmt.Sprintf(format, a...)}
|
||||||
|
el.mu.Lock()
|
||||||
|
e.Elapsed, e.NewDay = el.delta(e.When)
|
||||||
|
if len(el.events) < maxEventsPerLog {
|
||||||
|
el.events = append(el.events, e)
|
||||||
|
} else {
|
||||||
|
// Discard the oldest event.
|
||||||
|
if el.discarded == 0 {
|
||||||
|
// el.discarded starts at two to count for the event it
|
||||||
|
// is replacing, plus the next one that we are about to
|
||||||
|
// drop.
|
||||||
|
el.discarded = 2
|
||||||
|
} else {
|
||||||
|
el.discarded++
|
||||||
|
}
|
||||||
|
// TODO(sameer): if this causes allocations on a critical path,
|
||||||
|
// change eventLog.What to be a fmt.Stringer, as in trace.go.
|
||||||
|
el.events[0].What = fmt.Sprintf("(%d events discarded)", el.discarded)
|
||||||
|
// The timestamp of the discarded meta-event should be
|
||||||
|
// the time of the last event it is representing.
|
||||||
|
el.events[0].When = el.events[1].When
|
||||||
|
copy(el.events[1:], el.events[2:])
|
||||||
|
el.events[maxEventsPerLog-1] = e
|
||||||
|
}
|
||||||
|
if e.IsErr {
|
||||||
|
el.LastErrorTime = e.When
|
||||||
|
}
|
||||||
|
el.mu.Unlock()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (el *eventLog) ref() {
|
||||||
|
atomic.AddInt32(&el.refs, 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (el *eventLog) unref() {
|
||||||
|
if atomic.AddInt32(&el.refs, -1) == 0 {
|
||||||
|
freeEventLog(el)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (el *eventLog) When() string {
|
||||||
|
return el.Start.Format("2006/01/02 15:04:05.000000")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (el *eventLog) ElapsedTime() string {
|
||||||
|
elapsed := time.Since(el.Start)
|
||||||
|
return fmt.Sprintf("%.6f", elapsed.Seconds())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (el *eventLog) Stack() string {
|
||||||
|
buf := new(bytes.Buffer)
|
||||||
|
tw := tabwriter.NewWriter(buf, 1, 8, 1, '\t', 0)
|
||||||
|
printStackRecord(tw, el.stack)
|
||||||
|
tw.Flush()
|
||||||
|
return buf.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
// printStackRecord prints the function + source line information
|
||||||
|
// for a single stack trace.
|
||||||
|
// Adapted from runtime/pprof/pprof.go.
|
||||||
|
func printStackRecord(w io.Writer, stk []uintptr) {
|
||||||
|
for _, pc := range stk {
|
||||||
|
f := runtime.FuncForPC(pc)
|
||||||
|
if f == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
file, line := f.FileLine(pc)
|
||||||
|
name := f.Name()
|
||||||
|
// Hide runtime.goexit and any runtime functions at the beginning.
|
||||||
|
if strings.HasPrefix(name, "runtime.") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
fmt.Fprintf(w, "# %s\t%s:%d\n", name, file, line)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (el *eventLog) Events() []logEntry {
|
||||||
|
el.mu.RLock()
|
||||||
|
defer el.mu.RUnlock()
|
||||||
|
return el.events
|
||||||
|
}
|
||||||
|
|
||||||
|
// freeEventLogs is a freelist of *eventLog
|
||||||
|
var freeEventLogs = make(chan *eventLog, 1000)
|
||||||
|
|
||||||
|
// newEventLog returns a event log ready to use.
|
||||||
|
func newEventLog() *eventLog {
|
||||||
|
select {
|
||||||
|
case el := <-freeEventLogs:
|
||||||
|
return el
|
||||||
|
default:
|
||||||
|
return new(eventLog)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// freeEventLog adds el to freeEventLogs if there's room.
|
||||||
|
// This is non-blocking.
|
||||||
|
func freeEventLog(el *eventLog) {
|
||||||
|
el.reset()
|
||||||
|
select {
|
||||||
|
case freeEventLogs <- el:
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const eventsHTML = `
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>events</title>
|
||||||
|
</head>
|
||||||
|
<style type="text/css">
|
||||||
|
body {
|
||||||
|
font-family: sans-serif;
|
||||||
|
}
|
||||||
|
table#req-status td.family {
|
||||||
|
padding-right: 2em;
|
||||||
|
}
|
||||||
|
table#req-status td.active {
|
||||||
|
padding-right: 1em;
|
||||||
|
}
|
||||||
|
table#req-status td.empty {
|
||||||
|
color: #aaa;
|
||||||
|
}
|
||||||
|
table#reqs {
|
||||||
|
margin-top: 1em;
|
||||||
|
}
|
||||||
|
table#reqs tr.first {
|
||||||
|
{{if $.Expanded}}font-weight: bold;{{end}}
|
||||||
|
}
|
||||||
|
table#reqs td {
|
||||||
|
font-family: monospace;
|
||||||
|
}
|
||||||
|
table#reqs td.when {
|
||||||
|
text-align: right;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
table#reqs td.elapsed {
|
||||||
|
padding: 0 0.5em;
|
||||||
|
text-align: right;
|
||||||
|
white-space: pre;
|
||||||
|
width: 10em;
|
||||||
|
}
|
||||||
|
address {
|
||||||
|
font-size: smaller;
|
||||||
|
margin-top: 5em;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<h1>/debug/events</h1>
|
||||||
|
|
||||||
|
<table id="req-status">
|
||||||
|
{{range $i, $fam := .Families}}
|
||||||
|
<tr>
|
||||||
|
<td class="family">{{$fam}}</td>
|
||||||
|
|
||||||
|
{{range $j, $bucket := $.Buckets}}
|
||||||
|
{{$n := index $.Counts $i $j}}
|
||||||
|
<td class="{{if not $bucket.MaxErrAge}}active{{end}}{{if not $n}}empty{{end}}">
|
||||||
|
{{if $n}}<a href="?fam={{$fam}}&b={{$j}}{{if $.Expanded}}&exp=1{{end}}">{{end}}
|
||||||
|
[{{$n}} {{$bucket.String}}]
|
||||||
|
{{if $n}}</a>{{end}}
|
||||||
|
</td>
|
||||||
|
{{end}}
|
||||||
|
|
||||||
|
</tr>{{end}}
|
||||||
|
</table>
|
||||||
|
|
||||||
|
{{if $.EventLogs}}
|
||||||
|
<hr />
|
||||||
|
<h3>Family: {{$.Family}}</h3>
|
||||||
|
|
||||||
|
{{if $.Expanded}}<a href="?fam={{$.Family}}&b={{$.Bucket}}">{{end}}
|
||||||
|
[Summary]{{if $.Expanded}}</a>{{end}}
|
||||||
|
|
||||||
|
{{if not $.Expanded}}<a href="?fam={{$.Family}}&b={{$.Bucket}}&exp=1">{{end}}
|
||||||
|
[Expanded]{{if not $.Expanded}}</a>{{end}}
|
||||||
|
|
||||||
|
<table id="reqs">
|
||||||
|
<tr><th>When</th><th>Elapsed</th></tr>
|
||||||
|
{{range $el := $.EventLogs}}
|
||||||
|
<tr class="first">
|
||||||
|
<td class="when">{{$el.When}}</td>
|
||||||
|
<td class="elapsed">{{$el.ElapsedTime}}</td>
|
||||||
|
<td>{{$el.Title}}
|
||||||
|
</tr>
|
||||||
|
{{if $.Expanded}}
|
||||||
|
<tr>
|
||||||
|
<td class="when"></td>
|
||||||
|
<td class="elapsed"></td>
|
||||||
|
<td><pre>{{$el.Stack|trimSpace}}</pre></td>
|
||||||
|
</tr>
|
||||||
|
{{range $el.Events}}
|
||||||
|
<tr>
|
||||||
|
<td class="when">{{.WhenString}}</td>
|
||||||
|
<td class="elapsed">{{elapsed .Elapsed}}</td>
|
||||||
|
<td>.{{if .IsErr}}E{{else}}.{{end}}. {{.What}}</td>
|
||||||
|
</tr>
|
||||||
|
{{end}}
|
||||||
|
{{end}}
|
||||||
|
{{end}}
|
||||||
|
</table>
|
||||||
|
{{end}}
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
`
|
356
vendor/golang.org/x/net/trace/histogram.go
generated
vendored
Normal file
356
vendor/golang.org/x/net/trace/histogram.go
generated
vendored
Normal file
|
@ -0,0 +1,356 @@
|
||||||
|
// Copyright 2015 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package trace
|
||||||
|
|
||||||
|
// This file implements histogramming for RPC statistics collection.
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"html/template"
|
||||||
|
"log"
|
||||||
|
"math"
|
||||||
|
|
||||||
|
"golang.org/x/net/internal/timeseries"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
bucketCount = 38
|
||||||
|
)
|
||||||
|
|
||||||
|
// histogram keeps counts of values in buckets that are spaced
|
||||||
|
// out in powers of 2: 0-1, 2-3, 4-7...
|
||||||
|
// histogram implements timeseries.Observable
|
||||||
|
type histogram struct {
|
||||||
|
sum int64 // running total of measurements
|
||||||
|
sumOfSquares float64 // square of running total
|
||||||
|
buckets []int64 // bucketed values for histogram
|
||||||
|
value int // holds a single value as an optimization
|
||||||
|
valueCount int64 // number of values recorded for single value
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddMeasurement records a value measurement observation to the histogram.
|
||||||
|
func (h *histogram) addMeasurement(value int64) {
|
||||||
|
// TODO: assert invariant
|
||||||
|
h.sum += value
|
||||||
|
h.sumOfSquares += float64(value) * float64(value)
|
||||||
|
|
||||||
|
bucketIndex := getBucket(value)
|
||||||
|
|
||||||
|
if h.valueCount == 0 || (h.valueCount > 0 && h.value == bucketIndex) {
|
||||||
|
h.value = bucketIndex
|
||||||
|
h.valueCount++
|
||||||
|
} else {
|
||||||
|
h.allocateBuckets()
|
||||||
|
h.buckets[bucketIndex]++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *histogram) allocateBuckets() {
|
||||||
|
if h.buckets == nil {
|
||||||
|
h.buckets = make([]int64, bucketCount)
|
||||||
|
h.buckets[h.value] = h.valueCount
|
||||||
|
h.value = 0
|
||||||
|
h.valueCount = -1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func log2(i int64) int {
|
||||||
|
n := 0
|
||||||
|
for ; i >= 0x100; i >>= 8 {
|
||||||
|
n += 8
|
||||||
|
}
|
||||||
|
for ; i > 0; i >>= 1 {
|
||||||
|
n += 1
|
||||||
|
}
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
|
||||||
|
func getBucket(i int64) (index int) {
|
||||||
|
index = log2(i) - 1
|
||||||
|
if index < 0 {
|
||||||
|
index = 0
|
||||||
|
}
|
||||||
|
if index >= bucketCount {
|
||||||
|
index = bucketCount - 1
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Total returns the number of recorded observations.
|
||||||
|
func (h *histogram) total() (total int64) {
|
||||||
|
if h.valueCount >= 0 {
|
||||||
|
total = h.valueCount
|
||||||
|
}
|
||||||
|
for _, val := range h.buckets {
|
||||||
|
total += int64(val)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Average returns the average value of recorded observations.
|
||||||
|
func (h *histogram) average() float64 {
|
||||||
|
t := h.total()
|
||||||
|
if t == 0 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
return float64(h.sum) / float64(t)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Variance returns the variance of recorded observations.
|
||||||
|
func (h *histogram) variance() float64 {
|
||||||
|
t := float64(h.total())
|
||||||
|
if t == 0 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
s := float64(h.sum) / t
|
||||||
|
return h.sumOfSquares/t - s*s
|
||||||
|
}
|
||||||
|
|
||||||
|
// StandardDeviation returns the standard deviation of recorded observations.
|
||||||
|
func (h *histogram) standardDeviation() float64 {
|
||||||
|
return math.Sqrt(h.variance())
|
||||||
|
}
|
||||||
|
|
||||||
|
// PercentileBoundary estimates the value that the given fraction of recorded
|
||||||
|
// observations are less than.
|
||||||
|
func (h *histogram) percentileBoundary(percentile float64) int64 {
|
||||||
|
total := h.total()
|
||||||
|
|
||||||
|
// Corner cases (make sure result is strictly less than Total())
|
||||||
|
if total == 0 {
|
||||||
|
return 0
|
||||||
|
} else if total == 1 {
|
||||||
|
return int64(h.average())
|
||||||
|
}
|
||||||
|
|
||||||
|
percentOfTotal := round(float64(total) * percentile)
|
||||||
|
var runningTotal int64
|
||||||
|
|
||||||
|
for i := range h.buckets {
|
||||||
|
value := h.buckets[i]
|
||||||
|
runningTotal += value
|
||||||
|
if runningTotal == percentOfTotal {
|
||||||
|
// We hit an exact bucket boundary. If the next bucket has data, it is a
|
||||||
|
// good estimate of the value. If the bucket is empty, we interpolate the
|
||||||
|
// midpoint between the next bucket's boundary and the next non-zero
|
||||||
|
// bucket. If the remaining buckets are all empty, then we use the
|
||||||
|
// boundary for the next bucket as the estimate.
|
||||||
|
j := uint8(i + 1)
|
||||||
|
min := bucketBoundary(j)
|
||||||
|
if runningTotal < total {
|
||||||
|
for h.buckets[j] == 0 {
|
||||||
|
j++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
max := bucketBoundary(j)
|
||||||
|
return min + round(float64(max-min)/2)
|
||||||
|
} else if runningTotal > percentOfTotal {
|
||||||
|
// The value is in this bucket. Interpolate the value.
|
||||||
|
delta := runningTotal - percentOfTotal
|
||||||
|
percentBucket := float64(value-delta) / float64(value)
|
||||||
|
bucketMin := bucketBoundary(uint8(i))
|
||||||
|
nextBucketMin := bucketBoundary(uint8(i + 1))
|
||||||
|
bucketSize := nextBucketMin - bucketMin
|
||||||
|
return bucketMin + round(percentBucket*float64(bucketSize))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return bucketBoundary(bucketCount - 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Median returns the estimated median of the observed values.
|
||||||
|
func (h *histogram) median() int64 {
|
||||||
|
return h.percentileBoundary(0.5)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add adds other to h.
|
||||||
|
func (h *histogram) Add(other timeseries.Observable) {
|
||||||
|
o := other.(*histogram)
|
||||||
|
if o.valueCount == 0 {
|
||||||
|
// Other histogram is empty
|
||||||
|
} else if h.valueCount >= 0 && o.valueCount > 0 && h.value == o.value {
|
||||||
|
// Both have a single bucketed value, aggregate them
|
||||||
|
h.valueCount += o.valueCount
|
||||||
|
} else {
|
||||||
|
// Two different values necessitate buckets in this histogram
|
||||||
|
h.allocateBuckets()
|
||||||
|
if o.valueCount >= 0 {
|
||||||
|
h.buckets[o.value] += o.valueCount
|
||||||
|
} else {
|
||||||
|
for i := range h.buckets {
|
||||||
|
h.buckets[i] += o.buckets[i]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
h.sumOfSquares += o.sumOfSquares
|
||||||
|
h.sum += o.sum
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear resets the histogram to an empty state, removing all observed values.
|
||||||
|
func (h *histogram) Clear() {
|
||||||
|
h.buckets = nil
|
||||||
|
h.value = 0
|
||||||
|
h.valueCount = 0
|
||||||
|
h.sum = 0
|
||||||
|
h.sumOfSquares = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// CopyFrom copies from other, which must be a *histogram, into h.
|
||||||
|
func (h *histogram) CopyFrom(other timeseries.Observable) {
|
||||||
|
o := other.(*histogram)
|
||||||
|
if o.valueCount == -1 {
|
||||||
|
h.allocateBuckets()
|
||||||
|
copy(h.buckets, o.buckets)
|
||||||
|
}
|
||||||
|
h.sum = o.sum
|
||||||
|
h.sumOfSquares = o.sumOfSquares
|
||||||
|
h.value = o.value
|
||||||
|
h.valueCount = o.valueCount
|
||||||
|
}
|
||||||
|
|
||||||
|
// Multiply scales the histogram by the specified ratio.
|
||||||
|
func (h *histogram) Multiply(ratio float64) {
|
||||||
|
if h.valueCount == -1 {
|
||||||
|
for i := range h.buckets {
|
||||||
|
h.buckets[i] = int64(float64(h.buckets[i]) * ratio)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
h.valueCount = int64(float64(h.valueCount) * ratio)
|
||||||
|
}
|
||||||
|
h.sum = int64(float64(h.sum) * ratio)
|
||||||
|
h.sumOfSquares = h.sumOfSquares * ratio
|
||||||
|
}
|
||||||
|
|
||||||
|
// New creates a new histogram.
|
||||||
|
func (h *histogram) New() timeseries.Observable {
|
||||||
|
r := new(histogram)
|
||||||
|
r.Clear()
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *histogram) String() string {
|
||||||
|
return fmt.Sprintf("%d, %f, %d, %d, %v",
|
||||||
|
h.sum, h.sumOfSquares, h.value, h.valueCount, h.buckets)
|
||||||
|
}
|
||||||
|
|
||||||
|
// round returns the closest int64 to the argument
|
||||||
|
func round(in float64) int64 {
|
||||||
|
return int64(math.Floor(in + 0.5))
|
||||||
|
}
|
||||||
|
|
||||||
|
// bucketBoundary returns the first value in the bucket.
|
||||||
|
func bucketBoundary(bucket uint8) int64 {
|
||||||
|
if bucket == 0 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
return 1 << bucket
|
||||||
|
}
|
||||||
|
|
||||||
|
// bucketData holds data about a specific bucket for use in distTmpl.
|
||||||
|
type bucketData struct {
|
||||||
|
Lower, Upper int64
|
||||||
|
N int64
|
||||||
|
Pct, CumulativePct float64
|
||||||
|
GraphWidth int
|
||||||
|
}
|
||||||
|
|
||||||
|
// data holds data about a Distribution for use in distTmpl.
|
||||||
|
type data struct {
|
||||||
|
Buckets []*bucketData
|
||||||
|
Count, Median int64
|
||||||
|
Mean, StandardDeviation float64
|
||||||
|
}
|
||||||
|
|
||||||
|
// maxHTMLBarWidth is the maximum width of the HTML bar for visualizing buckets.
|
||||||
|
const maxHTMLBarWidth = 350.0
|
||||||
|
|
||||||
|
// newData returns data representing h for use in distTmpl.
|
||||||
|
func (h *histogram) newData() *data {
|
||||||
|
// Force the allocation of buckets to simplify the rendering implementation
|
||||||
|
h.allocateBuckets()
|
||||||
|
// We scale the bars on the right so that the largest bar is
|
||||||
|
// maxHTMLBarWidth pixels in width.
|
||||||
|
maxBucket := int64(0)
|
||||||
|
for _, n := range h.buckets {
|
||||||
|
if n > maxBucket {
|
||||||
|
maxBucket = n
|
||||||
|
}
|
||||||
|
}
|
||||||
|
total := h.total()
|
||||||
|
barsizeMult := maxHTMLBarWidth / float64(maxBucket)
|
||||||
|
var pctMult float64
|
||||||
|
if total == 0 {
|
||||||
|
pctMult = 1.0
|
||||||
|
} else {
|
||||||
|
pctMult = 100.0 / float64(total)
|
||||||
|
}
|
||||||
|
|
||||||
|
buckets := make([]*bucketData, len(h.buckets))
|
||||||
|
runningTotal := int64(0)
|
||||||
|
for i, n := range h.buckets {
|
||||||
|
if n == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
runningTotal += n
|
||||||
|
var upperBound int64
|
||||||
|
if i < bucketCount-1 {
|
||||||
|
upperBound = bucketBoundary(uint8(i + 1))
|
||||||
|
} else {
|
||||||
|
upperBound = math.MaxInt64
|
||||||
|
}
|
||||||
|
buckets[i] = &bucketData{
|
||||||
|
Lower: bucketBoundary(uint8(i)),
|
||||||
|
Upper: upperBound,
|
||||||
|
N: n,
|
||||||
|
Pct: float64(n) * pctMult,
|
||||||
|
CumulativePct: float64(runningTotal) * pctMult,
|
||||||
|
GraphWidth: int(float64(n) * barsizeMult),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return &data{
|
||||||
|
Buckets: buckets,
|
||||||
|
Count: total,
|
||||||
|
Median: h.median(),
|
||||||
|
Mean: h.average(),
|
||||||
|
StandardDeviation: h.standardDeviation(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *histogram) html() template.HTML {
|
||||||
|
buf := new(bytes.Buffer)
|
||||||
|
if err := distTmpl.Execute(buf, h.newData()); err != nil {
|
||||||
|
buf.Reset()
|
||||||
|
log.Printf("net/trace: couldn't execute template: %v", err)
|
||||||
|
}
|
||||||
|
return template.HTML(buf.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Input: data
|
||||||
|
var distTmpl = template.Must(template.New("distTmpl").Parse(`
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<td style="padding:0.25em">Count: {{.Count}}</td>
|
||||||
|
<td style="padding:0.25em">Mean: {{printf "%.0f" .Mean}}</td>
|
||||||
|
<td style="padding:0.25em">StdDev: {{printf "%.0f" .StandardDeviation}}</td>
|
||||||
|
<td style="padding:0.25em">Median: {{.Median}}</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<hr>
|
||||||
|
<table>
|
||||||
|
{{range $b := .Buckets}}
|
||||||
|
{{if $b}}
|
||||||
|
<tr>
|
||||||
|
<td style="padding:0 0 0 0.25em">[</td>
|
||||||
|
<td style="text-align:right;padding:0 0.25em">{{.Lower}},</td>
|
||||||
|
<td style="text-align:right;padding:0 0.25em">{{.Upper}})</td>
|
||||||
|
<td style="text-align:right;padding:0 0.25em">{{.N}}</td>
|
||||||
|
<td style="text-align:right;padding:0 0.25em">{{printf "%#.3f" .Pct}}%</td>
|
||||||
|
<td style="text-align:right;padding:0 0.25em">{{printf "%#.3f" .CumulativePct}}%</td>
|
||||||
|
<td><div style="background-color: blue; height: 1em; width: {{.GraphWidth}};"></div></td>
|
||||||
|
</tr>
|
||||||
|
{{end}}
|
||||||
|
{{end}}
|
||||||
|
</table>
|
||||||
|
`))
|
1071
vendor/golang.org/x/net/trace/trace.go
generated
vendored
Normal file
1071
vendor/golang.org/x/net/trace/trace.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
7
vendor/golang.org/x/oauth2/client_appengine.go
generated
vendored
7
vendor/golang.org/x/oauth2/client_appengine.go
generated
vendored
|
@ -1,8 +1,8 @@
|
||||||
// Copyright 2014 The oauth2 Authors. All rights reserved.
|
// Copyright 2014 The Go Authors. All rights reserved.
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
// +build appengine appenginevm
|
// +build appengine
|
||||||
|
|
||||||
// App Engine hooks.
|
// App Engine hooks.
|
||||||
|
|
||||||
|
@ -12,11 +12,12 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
|
"golang.org/x/oauth2/internal"
|
||||||
"google.golang.org/appengine/urlfetch"
|
"google.golang.org/appengine/urlfetch"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
registerContextClientFunc(contextClientAppEngine)
|
internal.RegisterContextClientFunc(contextClientAppEngine)
|
||||||
}
|
}
|
||||||
|
|
||||||
func contextClientAppEngine(ctx context.Context) (*http.Client, error) {
|
func contextClientAppEngine(ctx context.Context) (*http.Client, error) {
|
||||||
|
|
8
vendor/golang.org/x/oauth2/google/appengine.go
generated
vendored
8
vendor/golang.org/x/oauth2/google/appengine.go
generated
vendored
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2014 The oauth2 Authors. All rights reserved.
|
// Copyright 2014 The Go Authors. All rights reserved.
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
@ -14,9 +14,15 @@ import (
|
||||||
"golang.org/x/oauth2"
|
"golang.org/x/oauth2"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// appengineFlex is set at init time by appengineflex_hook.go. If true, we are on App Engine Flex.
|
||||||
|
var appengineFlex bool
|
||||||
|
|
||||||
// Set at init time by appengine_hook.go. If nil, we're not on App Engine.
|
// Set at init time by appengine_hook.go. If nil, we're not on App Engine.
|
||||||
var appengineTokenFunc func(c context.Context, scopes ...string) (token string, expiry time.Time, err error)
|
var appengineTokenFunc func(c context.Context, scopes ...string) (token string, expiry time.Time, err error)
|
||||||
|
|
||||||
|
// Set at init time by appengine_hook.go. If nil, we're not on App Engine.
|
||||||
|
var appengineAppIDFunc func(c context.Context) string
|
||||||
|
|
||||||
// AppEngineTokenSource returns a token source that fetches tokens
|
// AppEngineTokenSource returns a token source that fetches tokens
|
||||||
// issued to the current App Engine application's service account.
|
// issued to the current App Engine application's service account.
|
||||||
// If you are implementing a 3-legged OAuth 2.0 flow on App Engine
|
// If you are implementing a 3-legged OAuth 2.0 flow on App Engine
|
||||||
|
|
3
vendor/golang.org/x/oauth2/google/appengine_hook.go
generated
vendored
3
vendor/golang.org/x/oauth2/google/appengine_hook.go
generated
vendored
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2015 The oauth2 Authors. All rights reserved.
|
// Copyright 2015 The Go Authors. All rights reserved.
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
@ -10,4 +10,5 @@ import "google.golang.org/appengine"
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
appengineTokenFunc = appengine.AccessToken
|
appengineTokenFunc = appengine.AccessToken
|
||||||
|
appengineAppIDFunc = appengine.AppID
|
||||||
}
|
}
|
||||||
|
|
11
vendor/golang.org/x/oauth2/google/appengineflex_hook.go
generated
vendored
Normal file
11
vendor/golang.org/x/oauth2/google/appengineflex_hook.go
generated
vendored
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
// Copyright 2015 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build appenginevm
|
||||||
|
|
||||||
|
package google
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
appengineFlex = true // Flex doesn't support appengine.AccessToken; depend on metadata server.
|
||||||
|
}
|
124
vendor/golang.org/x/oauth2/google/default.go
generated
vendored
124
vendor/golang.org/x/oauth2/google/default.go
generated
vendored
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2015 The oauth2 Authors. All rights reserved.
|
// Copyright 2015 The Go Authors. All rights reserved.
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
@ -6,7 +6,6 @@ package google
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
@ -14,22 +13,21 @@ import (
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
|
||||||
|
"cloud.google.com/go/compute/metadata"
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
"golang.org/x/oauth2"
|
"golang.org/x/oauth2"
|
||||||
"golang.org/x/oauth2/jwt"
|
|
||||||
"google.golang.org/cloud/compute/metadata"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// DefaultCredentials holds "Application Default Credentials".
|
||||||
|
// For more details, see:
|
||||||
|
// https://developers.google.com/accounts/docs/application-default-credentials
|
||||||
|
type DefaultCredentials struct {
|
||||||
|
ProjectID string // may be empty
|
||||||
|
TokenSource oauth2.TokenSource
|
||||||
|
}
|
||||||
|
|
||||||
// DefaultClient returns an HTTP Client that uses the
|
// DefaultClient returns an HTTP Client that uses the
|
||||||
// DefaultTokenSource to obtain authentication credentials.
|
// DefaultTokenSource to obtain authentication credentials.
|
||||||
//
|
|
||||||
// This client should be used when developing services
|
|
||||||
// that run on Google App Engine or Google Compute Engine
|
|
||||||
// and use "Application Default Credentials."
|
|
||||||
//
|
|
||||||
// For more details, see:
|
|
||||||
// https://developers.google.com/accounts/application-default-credentials
|
|
||||||
//
|
|
||||||
func DefaultClient(ctx context.Context, scope ...string) (*http.Client, error) {
|
func DefaultClient(ctx context.Context, scope ...string) (*http.Client, error) {
|
||||||
ts, err := DefaultTokenSource(ctx, scope...)
|
ts, err := DefaultTokenSource(ctx, scope...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -38,8 +36,18 @@ func DefaultClient(ctx context.Context, scope ...string) (*http.Client, error) {
|
||||||
return oauth2.NewClient(ctx, ts), nil
|
return oauth2.NewClient(ctx, ts), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// DefaultTokenSource is a token source that uses
|
// DefaultTokenSource returns the token source for
|
||||||
// "Application Default Credentials".
|
// "Application Default Credentials".
|
||||||
|
// It is a shortcut for FindDefaultCredentials(ctx, scope).TokenSource.
|
||||||
|
func DefaultTokenSource(ctx context.Context, scope ...string) (oauth2.TokenSource, error) {
|
||||||
|
creds, err := FindDefaultCredentials(ctx, scope...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return creds.TokenSource, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindDefaultCredentials searches for "Application Default Credentials".
|
||||||
//
|
//
|
||||||
// It looks for credentials in the following places,
|
// It looks for credentials in the following places,
|
||||||
// preferring the first location found:
|
// preferring the first location found:
|
||||||
|
@ -50,51 +58,47 @@ func DefaultClient(ctx context.Context, scope ...string) (*http.Client, error) {
|
||||||
// On Windows, this is %APPDATA%/gcloud/application_default_credentials.json.
|
// On Windows, this is %APPDATA%/gcloud/application_default_credentials.json.
|
||||||
// On other systems, $HOME/.config/gcloud/application_default_credentials.json.
|
// On other systems, $HOME/.config/gcloud/application_default_credentials.json.
|
||||||
// 3. On Google App Engine it uses the appengine.AccessToken function.
|
// 3. On Google App Engine it uses the appengine.AccessToken function.
|
||||||
// 4. On Google Compute Engine, it fetches credentials from the metadata server.
|
// 4. On Google Compute Engine and Google App Engine Managed VMs, it fetches
|
||||||
|
// credentials from the metadata server.
|
||||||
// (In this final case any provided scopes are ignored.)
|
// (In this final case any provided scopes are ignored.)
|
||||||
//
|
func FindDefaultCredentials(ctx context.Context, scope ...string) (*DefaultCredentials, error) {
|
||||||
// For more details, see:
|
|
||||||
// https://developers.google.com/accounts/application-default-credentials
|
|
||||||
//
|
|
||||||
func DefaultTokenSource(ctx context.Context, scope ...string) (oauth2.TokenSource, error) {
|
|
||||||
// First, try the environment variable.
|
// First, try the environment variable.
|
||||||
const envVar = "GOOGLE_APPLICATION_CREDENTIALS"
|
const envVar = "GOOGLE_APPLICATION_CREDENTIALS"
|
||||||
if filename := os.Getenv(envVar); filename != "" {
|
if filename := os.Getenv(envVar); filename != "" {
|
||||||
ts, err := tokenSourceFromFile(ctx, filename, scope)
|
creds, err := readCredentialsFile(ctx, filename, scope)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("google: error getting credentials using %v environment variable: %v", envVar, err)
|
return nil, fmt.Errorf("google: error getting credentials using %v environment variable: %v", envVar, err)
|
||||||
}
|
}
|
||||||
return ts, nil
|
return creds, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Second, try a well-known file.
|
// Second, try a well-known file.
|
||||||
filename := wellKnownFile()
|
filename := wellKnownFile()
|
||||||
_, err := os.Stat(filename)
|
if creds, err := readCredentialsFile(ctx, filename, scope); err == nil {
|
||||||
if err == nil {
|
return creds, nil
|
||||||
ts, err2 := tokenSourceFromFile(ctx, filename, scope)
|
} else if !os.IsNotExist(err) {
|
||||||
if err2 == nil {
|
|
||||||
return ts, nil
|
|
||||||
}
|
|
||||||
err = err2
|
|
||||||
} else if os.IsNotExist(err) {
|
|
||||||
err = nil // ignore this error
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("google: error getting credentials using well-known file (%v): %v", filename, err)
|
return nil, fmt.Errorf("google: error getting credentials using well-known file (%v): %v", filename, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Third, if we're on Google App Engine use those credentials.
|
// Third, if we're on Google App Engine use those credentials.
|
||||||
if appengineTokenFunc != nil {
|
if appengineTokenFunc != nil && !appengineFlex {
|
||||||
return AppEngineTokenSource(ctx, scope...), nil
|
return &DefaultCredentials{
|
||||||
|
ProjectID: appengineAppIDFunc(ctx),
|
||||||
|
TokenSource: AppEngineTokenSource(ctx, scope...),
|
||||||
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fourth, if we're on Google Compute Engine use the metadata server.
|
// Fourth, if we're on Google Compute Engine use the metadata server.
|
||||||
if metadata.OnGCE() {
|
if metadata.OnGCE() {
|
||||||
return ComputeTokenSource(""), nil
|
id, _ := metadata.ProjectID()
|
||||||
|
return &DefaultCredentials{
|
||||||
|
ProjectID: id,
|
||||||
|
TokenSource: ComputeTokenSource(""),
|
||||||
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// None are found; return helpful error.
|
// None are found; return helpful error.
|
||||||
const url = "https://developers.google.com/accounts/application-default-credentials"
|
const url = "https://developers.google.com/accounts/docs/application-default-credentials"
|
||||||
return nil, fmt.Errorf("google: could not find default credentials. See %v for more information.", url)
|
return nil, fmt.Errorf("google: could not find default credentials. See %v for more information.", url)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,49 +110,21 @@ func wellKnownFile() string {
|
||||||
return filepath.Join(guessUnixHomeDir(), ".config", "gcloud", f)
|
return filepath.Join(guessUnixHomeDir(), ".config", "gcloud", f)
|
||||||
}
|
}
|
||||||
|
|
||||||
func tokenSourceFromFile(ctx context.Context, filename string, scopes []string) (oauth2.TokenSource, error) {
|
func readCredentialsFile(ctx context.Context, filename string, scopes []string) (*DefaultCredentials, error) {
|
||||||
b, err := ioutil.ReadFile(filename)
|
b, err := ioutil.ReadFile(filename)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
var d struct {
|
var f credentialsFile
|
||||||
// Common fields
|
if err := json.Unmarshal(b, &f); err != nil {
|
||||||
Type string
|
|
||||||
ClientID string `json:"client_id"`
|
|
||||||
|
|
||||||
// User Credential fields
|
|
||||||
ClientSecret string `json:"client_secret"`
|
|
||||||
RefreshToken string `json:"refresh_token"`
|
|
||||||
|
|
||||||
// Service Account fields
|
|
||||||
ClientEmail string `json:"client_email"`
|
|
||||||
PrivateKeyID string `json:"private_key_id"`
|
|
||||||
PrivateKey string `json:"private_key"`
|
|
||||||
}
|
|
||||||
if err := json.Unmarshal(b, &d); err != nil {
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
switch d.Type {
|
ts, err := f.tokenSource(ctx, append([]string(nil), scopes...))
|
||||||
case "authorized_user":
|
if err != nil {
|
||||||
cfg := &oauth2.Config{
|
return nil, err
|
||||||
ClientID: d.ClientID,
|
|
||||||
ClientSecret: d.ClientSecret,
|
|
||||||
Scopes: append([]string{}, scopes...), // copy
|
|
||||||
Endpoint: Endpoint,
|
|
||||||
}
|
|
||||||
tok := &oauth2.Token{RefreshToken: d.RefreshToken}
|
|
||||||
return cfg.TokenSource(ctx, tok), nil
|
|
||||||
case "service_account":
|
|
||||||
cfg := &jwt.Config{
|
|
||||||
Email: d.ClientEmail,
|
|
||||||
PrivateKey: []byte(d.PrivateKey),
|
|
||||||
Scopes: append([]string{}, scopes...), // copy
|
|
||||||
TokenURL: JWTTokenURL,
|
|
||||||
}
|
|
||||||
return cfg.TokenSource(ctx), nil
|
|
||||||
case "":
|
|
||||||
return nil, errors.New("missing 'type' field in credentials")
|
|
||||||
default:
|
|
||||||
return nil, fmt.Errorf("unknown credential type: %q", d.Type)
|
|
||||||
}
|
}
|
||||||
|
return &DefaultCredentials{
|
||||||
|
ProjectID: f.ProjectID,
|
||||||
|
TokenSource: ts,
|
||||||
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
95
vendor/golang.org/x/oauth2/google/google.go
generated
vendored
95
vendor/golang.org/x/oauth2/google/google.go
generated
vendored
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2014 The oauth2 Authors. All rights reserved.
|
// Copyright 2014 The Go Authors. All rights reserved.
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@
|
||||||
// For more information, please read
|
// For more information, please read
|
||||||
// https://developers.google.com/accounts/docs/OAuth2
|
// https://developers.google.com/accounts/docs/OAuth2
|
||||||
// and
|
// and
|
||||||
// https://developers.google.com/accounts/application-default-credentials.
|
// https://developers.google.com/accounts/docs/application-default-credentials.
|
||||||
package google // import "golang.org/x/oauth2/google"
|
package google // import "golang.org/x/oauth2/google"
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@ -21,9 +21,10 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"cloud.google.com/go/compute/metadata"
|
||||||
|
"golang.org/x/net/context"
|
||||||
"golang.org/x/oauth2"
|
"golang.org/x/oauth2"
|
||||||
"golang.org/x/oauth2/jwt"
|
"golang.org/x/oauth2/jwt"
|
||||||
"google.golang.org/cloud/compute/metadata"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Endpoint is Google's OAuth 2.0 endpoint.
|
// Endpoint is Google's OAuth 2.0 endpoint.
|
||||||
|
@ -37,9 +38,10 @@ const JWTTokenURL = "https://accounts.google.com/o/oauth2/token"
|
||||||
|
|
||||||
// ConfigFromJSON uses a Google Developers Console client_credentials.json
|
// ConfigFromJSON uses a Google Developers Console client_credentials.json
|
||||||
// file to construct a config.
|
// file to construct a config.
|
||||||
// client_credentials.json can be downloadable from https://console.developers.google.com,
|
// client_credentials.json can be downloaded from
|
||||||
// under "APIs & Auth" > "Credentials". Download the Web application credentials in the
|
// https://console.developers.google.com, under "Credentials". Download the Web
|
||||||
// JSON format and provide the contents of the file as jsonKey.
|
// application credentials in the JSON format and provide the contents of the
|
||||||
|
// file as jsonKey.
|
||||||
func ConfigFromJSON(jsonKey []byte, scope ...string) (*oauth2.Config, error) {
|
func ConfigFromJSON(jsonKey []byte, scope ...string) (*oauth2.Config, error) {
|
||||||
type cred struct {
|
type cred struct {
|
||||||
ClientID string `json:"client_id"`
|
ClientID string `json:"client_id"`
|
||||||
|
@ -81,22 +83,77 @@ func ConfigFromJSON(jsonKey []byte, scope ...string) (*oauth2.Config, error) {
|
||||||
|
|
||||||
// JWTConfigFromJSON uses a Google Developers service account JSON key file to read
|
// JWTConfigFromJSON uses a Google Developers service account JSON key file to read
|
||||||
// the credentials that authorize and authenticate the requests.
|
// the credentials that authorize and authenticate the requests.
|
||||||
// Create a service account on "Credentials" page under "APIs & Auth" for your
|
// Create a service account on "Credentials" for your project at
|
||||||
// project at https://console.developers.google.com to download a JSON key file.
|
// https://console.developers.google.com to download a JSON key file.
|
||||||
func JWTConfigFromJSON(jsonKey []byte, scope ...string) (*jwt.Config, error) {
|
func JWTConfigFromJSON(jsonKey []byte, scope ...string) (*jwt.Config, error) {
|
||||||
var key struct {
|
var f credentialsFile
|
||||||
Email string `json:"client_email"`
|
if err := json.Unmarshal(jsonKey, &f); err != nil {
|
||||||
PrivateKey string `json:"private_key"`
|
|
||||||
}
|
|
||||||
if err := json.Unmarshal(jsonKey, &key); err != nil {
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &jwt.Config{
|
if f.Type != serviceAccountKey {
|
||||||
Email: key.Email,
|
return nil, fmt.Errorf("google: read JWT from JSON credentials: 'type' field is %q (expected %q)", f.Type, serviceAccountKey)
|
||||||
PrivateKey: []byte(key.PrivateKey),
|
}
|
||||||
Scopes: scope,
|
scope = append([]string(nil), scope...) // copy
|
||||||
TokenURL: JWTTokenURL,
|
return f.jwtConfig(scope), nil
|
||||||
}, nil
|
}
|
||||||
|
|
||||||
|
// JSON key file types.
|
||||||
|
const (
|
||||||
|
serviceAccountKey = "service_account"
|
||||||
|
userCredentialsKey = "authorized_user"
|
||||||
|
)
|
||||||
|
|
||||||
|
// credentialsFile is the unmarshalled representation of a credentials file.
|
||||||
|
type credentialsFile struct {
|
||||||
|
Type string `json:"type"` // serviceAccountKey or userCredentialsKey
|
||||||
|
|
||||||
|
// Service Account fields
|
||||||
|
ClientEmail string `json:"client_email"`
|
||||||
|
PrivateKeyID string `json:"private_key_id"`
|
||||||
|
PrivateKey string `json:"private_key"`
|
||||||
|
TokenURL string `json:"token_uri"`
|
||||||
|
ProjectID string `json:"project_id"`
|
||||||
|
|
||||||
|
// User Credential fields
|
||||||
|
// (These typically come from gcloud auth.)
|
||||||
|
ClientSecret string `json:"client_secret"`
|
||||||
|
ClientID string `json:"client_id"`
|
||||||
|
RefreshToken string `json:"refresh_token"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *credentialsFile) jwtConfig(scopes []string) *jwt.Config {
|
||||||
|
cfg := &jwt.Config{
|
||||||
|
Email: f.ClientEmail,
|
||||||
|
PrivateKey: []byte(f.PrivateKey),
|
||||||
|
PrivateKeyID: f.PrivateKeyID,
|
||||||
|
Scopes: scopes,
|
||||||
|
TokenURL: f.TokenURL,
|
||||||
|
}
|
||||||
|
if cfg.TokenURL == "" {
|
||||||
|
cfg.TokenURL = JWTTokenURL
|
||||||
|
}
|
||||||
|
return cfg
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *credentialsFile) tokenSource(ctx context.Context, scopes []string) (oauth2.TokenSource, error) {
|
||||||
|
switch f.Type {
|
||||||
|
case serviceAccountKey:
|
||||||
|
cfg := f.jwtConfig(scopes)
|
||||||
|
return cfg.TokenSource(ctx), nil
|
||||||
|
case userCredentialsKey:
|
||||||
|
cfg := &oauth2.Config{
|
||||||
|
ClientID: f.ClientID,
|
||||||
|
ClientSecret: f.ClientSecret,
|
||||||
|
Scopes: scopes,
|
||||||
|
Endpoint: Endpoint,
|
||||||
|
}
|
||||||
|
tok := &oauth2.Token{RefreshToken: f.RefreshToken}
|
||||||
|
return cfg.TokenSource(ctx, tok), nil
|
||||||
|
case "":
|
||||||
|
return nil, errors.New("missing 'type' field in credentials")
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("unknown credential type: %q", f.Type)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ComputeTokenSource returns a token source that fetches access tokens
|
// ComputeTokenSource returns a token source that fetches access tokens
|
||||||
|
|
74
vendor/golang.org/x/oauth2/google/jwt.go
generated
vendored
Normal file
74
vendor/golang.org/x/oauth2/google/jwt.go
generated
vendored
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
// Copyright 2015 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package google
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/rsa"
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"golang.org/x/oauth2"
|
||||||
|
"golang.org/x/oauth2/internal"
|
||||||
|
"golang.org/x/oauth2/jws"
|
||||||
|
)
|
||||||
|
|
||||||
|
// JWTAccessTokenSourceFromJSON uses a Google Developers service account JSON
|
||||||
|
// key file to read the credentials that authorize and authenticate the
|
||||||
|
// requests, and returns a TokenSource that does not use any OAuth2 flow but
|
||||||
|
// instead creates a JWT and sends that as the access token.
|
||||||
|
// The audience is typically a URL that specifies the scope of the credentials.
|
||||||
|
//
|
||||||
|
// Note that this is not a standard OAuth flow, but rather an
|
||||||
|
// optimization supported by a few Google services.
|
||||||
|
// Unless you know otherwise, you should use JWTConfigFromJSON instead.
|
||||||
|
func JWTAccessTokenSourceFromJSON(jsonKey []byte, audience string) (oauth2.TokenSource, error) {
|
||||||
|
cfg, err := JWTConfigFromJSON(jsonKey)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("google: could not parse JSON key: %v", err)
|
||||||
|
}
|
||||||
|
pk, err := internal.ParseKey(cfg.PrivateKey)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("google: could not parse key: %v", err)
|
||||||
|
}
|
||||||
|
ts := &jwtAccessTokenSource{
|
||||||
|
email: cfg.Email,
|
||||||
|
audience: audience,
|
||||||
|
pk: pk,
|
||||||
|
pkID: cfg.PrivateKeyID,
|
||||||
|
}
|
||||||
|
tok, err := ts.Token()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return oauth2.ReuseTokenSource(tok, ts), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type jwtAccessTokenSource struct {
|
||||||
|
email, audience string
|
||||||
|
pk *rsa.PrivateKey
|
||||||
|
pkID string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ts *jwtAccessTokenSource) Token() (*oauth2.Token, error) {
|
||||||
|
iat := time.Now()
|
||||||
|
exp := iat.Add(time.Hour)
|
||||||
|
cs := &jws.ClaimSet{
|
||||||
|
Iss: ts.email,
|
||||||
|
Sub: ts.email,
|
||||||
|
Aud: ts.audience,
|
||||||
|
Iat: iat.Unix(),
|
||||||
|
Exp: exp.Unix(),
|
||||||
|
}
|
||||||
|
hdr := &jws.Header{
|
||||||
|
Algorithm: "RS256",
|
||||||
|
Typ: "JWT",
|
||||||
|
KeyID: string(ts.pkID),
|
||||||
|
}
|
||||||
|
msg, err := jws.Encode(hdr, cs, ts.pk)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("google: could not encode JWT: %v", err)
|
||||||
|
}
|
||||||
|
return &oauth2.Token{AccessToken: msg, TokenType: "Bearer", Expiry: exp}, nil
|
||||||
|
}
|
14
vendor/golang.org/x/oauth2/google/sdk.go
generated
vendored
14
vendor/golang.org/x/oauth2/google/sdk.go
generated
vendored
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2015 The oauth2 Authors. All rights reserved.
|
// Copyright 2015 The Go Authors. All rights reserved.
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
@ -160,9 +160,13 @@ var sdkConfigPath = func() (string, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func guessUnixHomeDir() string {
|
func guessUnixHomeDir() string {
|
||||||
usr, err := user.Current()
|
// Prefer $HOME over user.Current due to glibc bug: golang.org/issue/13470
|
||||||
if err == nil {
|
if v := os.Getenv("HOME"); v != "" {
|
||||||
return usr.HomeDir
|
return v
|
||||||
}
|
}
|
||||||
return os.Getenv("HOME")
|
// Else, fall back to user.Current:
|
||||||
|
if u, err := user.Current(); err == nil {
|
||||||
|
return u.HomeDir
|
||||||
|
}
|
||||||
|
return ""
|
||||||
}
|
}
|
||||||
|
|
11
vendor/golang.org/x/oauth2/internal/oauth2.go
generated
vendored
11
vendor/golang.org/x/oauth2/internal/oauth2.go
generated
vendored
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2014 The oauth2 Authors. All rights reserved.
|
// Copyright 2014 The Go Authors. All rights reserved.
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ func ParseKey(key []byte) (*rsa.PrivateKey, error) {
|
||||||
|
|
||||||
func ParseINI(ini io.Reader) (map[string]map[string]string, error) {
|
func ParseINI(ini io.Reader) (map[string]map[string]string, error) {
|
||||||
result := map[string]map[string]string{
|
result := map[string]map[string]string{
|
||||||
"": map[string]string{}, // root section
|
"": {}, // root section
|
||||||
}
|
}
|
||||||
scanner := bufio.NewScanner(ini)
|
scanner := bufio.NewScanner(ini)
|
||||||
currentSection := ""
|
currentSection := ""
|
||||||
|
@ -67,3 +67,10 @@ func ParseINI(ini io.Reader) (map[string]map[string]string, error) {
|
||||||
}
|
}
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func CondVal(v string) []string {
|
||||||
|
if v == "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return []string{v}
|
||||||
|
}
|
||||||
|
|
247
vendor/golang.org/x/oauth2/internal/token.go
generated
vendored
Normal file
247
vendor/golang.org/x/oauth2/internal/token.go
generated
vendored
Normal file
|
@ -0,0 +1,247 @@
|
||||||
|
// Copyright 2014 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// Package internal contains support packages for oauth2 package.
|
||||||
|
package internal
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
|
"mime"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"golang.org/x/net/context"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Token represents the crendentials used to authorize
|
||||||
|
// the requests to access protected resources on the OAuth 2.0
|
||||||
|
// provider's backend.
|
||||||
|
//
|
||||||
|
// This type is a mirror of oauth2.Token and exists to break
|
||||||
|
// an otherwise-circular dependency. Other internal packages
|
||||||
|
// should convert this Token into an oauth2.Token before use.
|
||||||
|
type Token struct {
|
||||||
|
// AccessToken is the token that authorizes and authenticates
|
||||||
|
// the requests.
|
||||||
|
AccessToken string
|
||||||
|
|
||||||
|
// TokenType is the type of token.
|
||||||
|
// The Type method returns either this or "Bearer", the default.
|
||||||
|
TokenType string
|
||||||
|
|
||||||
|
// RefreshToken is a token that's used by the application
|
||||||
|
// (as opposed to the user) to refresh the access token
|
||||||
|
// if it expires.
|
||||||
|
RefreshToken string
|
||||||
|
|
||||||
|
// Expiry is the optional expiration time of the access token.
|
||||||
|
//
|
||||||
|
// If zero, TokenSource implementations will reuse the same
|
||||||
|
// token forever and RefreshToken or equivalent
|
||||||
|
// mechanisms for that TokenSource will not be used.
|
||||||
|
Expiry time.Time
|
||||||
|
|
||||||
|
// Raw optionally contains extra metadata from the server
|
||||||
|
// when updating a token.
|
||||||
|
Raw interface{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// tokenJSON is the struct representing the HTTP response from OAuth2
|
||||||
|
// providers returning a token in JSON form.
|
||||||
|
type tokenJSON struct {
|
||||||
|
AccessToken string `json:"access_token"`
|
||||||
|
TokenType string `json:"token_type"`
|
||||||
|
RefreshToken string `json:"refresh_token"`
|
||||||
|
ExpiresIn expirationTime `json:"expires_in"` // at least PayPal returns string, while most return number
|
||||||
|
Expires expirationTime `json:"expires"` // broken Facebook spelling of expires_in
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *tokenJSON) expiry() (t time.Time) {
|
||||||
|
if v := e.ExpiresIn; v != 0 {
|
||||||
|
return time.Now().Add(time.Duration(v) * time.Second)
|
||||||
|
}
|
||||||
|
if v := e.Expires; v != 0 {
|
||||||
|
return time.Now().Add(time.Duration(v) * time.Second)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
type expirationTime int32
|
||||||
|
|
||||||
|
func (e *expirationTime) UnmarshalJSON(b []byte) error {
|
||||||
|
var n json.Number
|
||||||
|
err := json.Unmarshal(b, &n)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
i, err := n.Int64()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
*e = expirationTime(i)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var brokenAuthHeaderProviders = []string{
|
||||||
|
"https://accounts.google.com/",
|
||||||
|
"https://api.codeswholesale.com/oauth/token",
|
||||||
|
"https://api.dropbox.com/",
|
||||||
|
"https://api.dropboxapi.com/",
|
||||||
|
"https://api.instagram.com/",
|
||||||
|
"https://api.netatmo.net/",
|
||||||
|
"https://api.odnoklassniki.ru/",
|
||||||
|
"https://api.pushbullet.com/",
|
||||||
|
"https://api.soundcloud.com/",
|
||||||
|
"https://api.twitch.tv/",
|
||||||
|
"https://app.box.com/",
|
||||||
|
"https://connect.stripe.com/",
|
||||||
|
"https://graph.facebook.com", // see https://github.com/golang/oauth2/issues/214
|
||||||
|
"https://login.microsoftonline.com/",
|
||||||
|
"https://login.salesforce.com/",
|
||||||
|
"https://oauth.sandbox.trainingpeaks.com/",
|
||||||
|
"https://oauth.trainingpeaks.com/",
|
||||||
|
"https://oauth.vk.com/",
|
||||||
|
"https://openapi.baidu.com/",
|
||||||
|
"https://slack.com/",
|
||||||
|
"https://test-sandbox.auth.corp.google.com",
|
||||||
|
"https://test.salesforce.com/",
|
||||||
|
"https://user.gini.net/",
|
||||||
|
"https://www.douban.com/",
|
||||||
|
"https://www.googleapis.com/",
|
||||||
|
"https://www.linkedin.com/",
|
||||||
|
"https://www.strava.com/oauth/",
|
||||||
|
"https://www.wunderlist.com/oauth/",
|
||||||
|
"https://api.patreon.com/",
|
||||||
|
"https://sandbox.codeswholesale.com/oauth/token",
|
||||||
|
}
|
||||||
|
|
||||||
|
// brokenAuthHeaderDomains lists broken providers that issue dynamic endpoints.
|
||||||
|
var brokenAuthHeaderDomains = []string{
|
||||||
|
".force.com",
|
||||||
|
".okta.com",
|
||||||
|
".oktapreview.com",
|
||||||
|
}
|
||||||
|
|
||||||
|
func RegisterBrokenAuthHeaderProvider(tokenURL string) {
|
||||||
|
brokenAuthHeaderProviders = append(brokenAuthHeaderProviders, tokenURL)
|
||||||
|
}
|
||||||
|
|
||||||
|
// providerAuthHeaderWorks reports whether the OAuth2 server identified by the tokenURL
|
||||||
|
// implements the OAuth2 spec correctly
|
||||||
|
// See https://code.google.com/p/goauth2/issues/detail?id=31 for background.
|
||||||
|
// In summary:
|
||||||
|
// - Reddit only accepts client secret in the Authorization header
|
||||||
|
// - Dropbox accepts either it in URL param or Auth header, but not both.
|
||||||
|
// - Google only accepts URL param (not spec compliant?), not Auth header
|
||||||
|
// - Stripe only accepts client secret in Auth header with Bearer method, not Basic
|
||||||
|
func providerAuthHeaderWorks(tokenURL string) bool {
|
||||||
|
for _, s := range brokenAuthHeaderProviders {
|
||||||
|
if strings.HasPrefix(tokenURL, s) {
|
||||||
|
// Some sites fail to implement the OAuth2 spec fully.
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if u, err := url.Parse(tokenURL); err == nil {
|
||||||
|
for _, s := range brokenAuthHeaderDomains {
|
||||||
|
if strings.HasSuffix(u.Host, s) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assume the provider implements the spec properly
|
||||||
|
// otherwise. We can add more exceptions as they're
|
||||||
|
// discovered. We will _not_ be adding configurable hooks
|
||||||
|
// to this package to let users select server bugs.
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func RetrieveToken(ctx context.Context, clientID, clientSecret, tokenURL string, v url.Values) (*Token, error) {
|
||||||
|
hc, err := ContextClient(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
bustedAuth := !providerAuthHeaderWorks(tokenURL)
|
||||||
|
if bustedAuth {
|
||||||
|
if clientID != "" {
|
||||||
|
v.Set("client_id", clientID)
|
||||||
|
}
|
||||||
|
if clientSecret != "" {
|
||||||
|
v.Set("client_secret", clientSecret)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
req, err := http.NewRequest("POST", tokenURL, strings.NewReader(v.Encode()))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
||||||
|
if !bustedAuth {
|
||||||
|
req.SetBasicAuth(clientID, clientSecret)
|
||||||
|
}
|
||||||
|
r, err := hc.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer r.Body.Close()
|
||||||
|
body, err := ioutil.ReadAll(io.LimitReader(r.Body, 1<<20))
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("oauth2: cannot fetch token: %v", err)
|
||||||
|
}
|
||||||
|
if code := r.StatusCode; code < 200 || code > 299 {
|
||||||
|
return nil, fmt.Errorf("oauth2: cannot fetch token: %v\nResponse: %s", r.Status, body)
|
||||||
|
}
|
||||||
|
|
||||||
|
var token *Token
|
||||||
|
content, _, _ := mime.ParseMediaType(r.Header.Get("Content-Type"))
|
||||||
|
switch content {
|
||||||
|
case "application/x-www-form-urlencoded", "text/plain":
|
||||||
|
vals, err := url.ParseQuery(string(body))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
token = &Token{
|
||||||
|
AccessToken: vals.Get("access_token"),
|
||||||
|
TokenType: vals.Get("token_type"),
|
||||||
|
RefreshToken: vals.Get("refresh_token"),
|
||||||
|
Raw: vals,
|
||||||
|
}
|
||||||
|
e := vals.Get("expires_in")
|
||||||
|
if e == "" {
|
||||||
|
// TODO(jbd): Facebook's OAuth2 implementation is broken and
|
||||||
|
// returns expires_in field in expires. Remove the fallback to expires,
|
||||||
|
// when Facebook fixes their implementation.
|
||||||
|
e = vals.Get("expires")
|
||||||
|
}
|
||||||
|
expires, _ := strconv.Atoi(e)
|
||||||
|
if expires != 0 {
|
||||||
|
token.Expiry = time.Now().Add(time.Duration(expires) * time.Second)
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
var tj tokenJSON
|
||||||
|
if err = json.Unmarshal(body, &tj); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
token = &Token{
|
||||||
|
AccessToken: tj.AccessToken,
|
||||||
|
TokenType: tj.TokenType,
|
||||||
|
RefreshToken: tj.RefreshToken,
|
||||||
|
Expiry: tj.expiry(),
|
||||||
|
Raw: make(map[string]interface{}),
|
||||||
|
}
|
||||||
|
json.Unmarshal(body, &token.Raw) // no error checks for optional fields
|
||||||
|
}
|
||||||
|
// Don't overwrite `RefreshToken` with an empty value
|
||||||
|
// if this was a token refreshing request.
|
||||||
|
if token.RefreshToken == "" {
|
||||||
|
token.RefreshToken = v.Get("refresh_token")
|
||||||
|
}
|
||||||
|
return token, nil
|
||||||
|
}
|
69
vendor/golang.org/x/oauth2/internal/transport.go
generated
vendored
Normal file
69
vendor/golang.org/x/oauth2/internal/transport.go
generated
vendored
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
// Copyright 2014 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// Package internal contains support packages for oauth2 package.
|
||||||
|
package internal
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"golang.org/x/net/context"
|
||||||
|
)
|
||||||
|
|
||||||
|
// HTTPClient is the context key to use with golang.org/x/net/context's
|
||||||
|
// WithValue function to associate an *http.Client value with a context.
|
||||||
|
var HTTPClient ContextKey
|
||||||
|
|
||||||
|
// ContextKey is just an empty struct. It exists so HTTPClient can be
|
||||||
|
// an immutable public variable with a unique type. It's immutable
|
||||||
|
// because nobody else can create a ContextKey, being unexported.
|
||||||
|
type ContextKey struct{}
|
||||||
|
|
||||||
|
// ContextClientFunc is a func which tries to return an *http.Client
|
||||||
|
// given a Context value. If it returns an error, the search stops
|
||||||
|
// with that error. If it returns (nil, nil), the search continues
|
||||||
|
// down the list of registered funcs.
|
||||||
|
type ContextClientFunc func(context.Context) (*http.Client, error)
|
||||||
|
|
||||||
|
var contextClientFuncs []ContextClientFunc
|
||||||
|
|
||||||
|
func RegisterContextClientFunc(fn ContextClientFunc) {
|
||||||
|
contextClientFuncs = append(contextClientFuncs, fn)
|
||||||
|
}
|
||||||
|
|
||||||
|
func ContextClient(ctx context.Context) (*http.Client, error) {
|
||||||
|
if ctx != nil {
|
||||||
|
if hc, ok := ctx.Value(HTTPClient).(*http.Client); ok {
|
||||||
|
return hc, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for _, fn := range contextClientFuncs {
|
||||||
|
c, err := fn(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if c != nil {
|
||||||
|
return c, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return http.DefaultClient, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func ContextTransport(ctx context.Context) http.RoundTripper {
|
||||||
|
hc, err := ContextClient(ctx)
|
||||||
|
// This is a rare error case (somebody using nil on App Engine).
|
||||||
|
if err != nil {
|
||||||
|
return ErrorTransport{err}
|
||||||
|
}
|
||||||
|
return hc.Transport
|
||||||
|
}
|
||||||
|
|
||||||
|
// ErrorTransport returns the specified error on RoundTrip.
|
||||||
|
// This RoundTripper should be used in rare error cases where
|
||||||
|
// error handling can be postponed to response handling time.
|
||||||
|
type ErrorTransport struct{ Err error }
|
||||||
|
|
||||||
|
func (t ErrorTransport) RoundTrip(*http.Request) (*http.Response, error) {
|
||||||
|
return nil, t.Err
|
||||||
|
}
|
102
vendor/golang.org/x/oauth2/jws/jws.go
generated
vendored
102
vendor/golang.org/x/oauth2/jws/jws.go
generated
vendored
|
@ -1,9 +1,17 @@
|
||||||
// Copyright 2014 The oauth2 Authors. All rights reserved.
|
// Copyright 2014 The Go Authors. All rights reserved.
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
// Package jws provides encoding and decoding utilities for
|
// Package jws provides a partial implementation
|
||||||
// signed JWS messages.
|
// of JSON Web Signature encoding and decoding.
|
||||||
|
// It exists to support the golang.org/x/oauth2 package.
|
||||||
|
//
|
||||||
|
// See RFC 7515.
|
||||||
|
//
|
||||||
|
// Deprecated: this package is not intended for public use and might be
|
||||||
|
// removed in the future. It exists for internal use only.
|
||||||
|
// Please switch to another JWS package or copy this package into your own
|
||||||
|
// source tree.
|
||||||
package jws // import "golang.org/x/oauth2/jws"
|
package jws // import "golang.org/x/oauth2/jws"
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@ -27,8 +35,8 @@ type ClaimSet struct {
|
||||||
Iss string `json:"iss"` // email address of the client_id of the application making the access token request
|
Iss string `json:"iss"` // email address of the client_id of the application making the access token request
|
||||||
Scope string `json:"scope,omitempty"` // space-delimited list of the permissions the application requests
|
Scope string `json:"scope,omitempty"` // space-delimited list of the permissions the application requests
|
||||||
Aud string `json:"aud"` // descriptor of the intended target of the assertion (Optional).
|
Aud string `json:"aud"` // descriptor of the intended target of the assertion (Optional).
|
||||||
Exp int64 `json:"exp"` // the expiration time of the assertion
|
Exp int64 `json:"exp"` // the expiration time of the assertion (seconds since Unix epoch)
|
||||||
Iat int64 `json:"iat"` // the time the assertion was issued.
|
Iat int64 `json:"iat"` // the time the assertion was issued (seconds since Unix epoch)
|
||||||
Typ string `json:"typ,omitempty"` // token type (Optional).
|
Typ string `json:"typ,omitempty"` // token type (Optional).
|
||||||
|
|
||||||
// Email for which the application is requesting delegated access (Optional).
|
// Email for which the application is requesting delegated access (Optional).
|
||||||
|
@ -41,23 +49,22 @@ type ClaimSet struct {
|
||||||
// See http://tools.ietf.org/html/draft-jones-json-web-token-10#section-4.3
|
// See http://tools.ietf.org/html/draft-jones-json-web-token-10#section-4.3
|
||||||
// This array is marshalled using custom code (see (c *ClaimSet) encode()).
|
// This array is marshalled using custom code (see (c *ClaimSet) encode()).
|
||||||
PrivateClaims map[string]interface{} `json:"-"`
|
PrivateClaims map[string]interface{} `json:"-"`
|
||||||
|
|
||||||
exp time.Time
|
|
||||||
iat time.Time
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *ClaimSet) encode() (string, error) {
|
func (c *ClaimSet) encode() (string, error) {
|
||||||
if c.exp.IsZero() || c.iat.IsZero() {
|
|
||||||
// Reverting time back for machines whose time is not perfectly in sync.
|
// Reverting time back for machines whose time is not perfectly in sync.
|
||||||
// If client machine's time is in the future according
|
// If client machine's time is in the future according
|
||||||
// to Google servers, an access token will not be issued.
|
// to Google servers, an access token will not be issued.
|
||||||
now := time.Now().Add(-10 * time.Second)
|
now := time.Now().Add(-10 * time.Second)
|
||||||
c.iat = now
|
if c.Iat == 0 {
|
||||||
c.exp = now.Add(time.Hour)
|
c.Iat = now.Unix()
|
||||||
|
}
|
||||||
|
if c.Exp == 0 {
|
||||||
|
c.Exp = now.Add(time.Hour).Unix()
|
||||||
|
}
|
||||||
|
if c.Exp < c.Iat {
|
||||||
|
return "", fmt.Errorf("jws: invalid Exp = %v; must be later than Iat = %v", c.Exp, c.Iat)
|
||||||
}
|
}
|
||||||
|
|
||||||
c.Exp = c.exp.Unix()
|
|
||||||
c.Iat = c.iat.Unix()
|
|
||||||
|
|
||||||
b, err := json.Marshal(c)
|
b, err := json.Marshal(c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -65,7 +72,7 @@ func (c *ClaimSet) encode() (string, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(c.PrivateClaims) == 0 {
|
if len(c.PrivateClaims) == 0 {
|
||||||
return base64Encode(b), nil
|
return base64.RawURLEncoding.EncodeToString(b), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Marshal private claim set and then append it to b.
|
// Marshal private claim set and then append it to b.
|
||||||
|
@ -83,7 +90,7 @@ func (c *ClaimSet) encode() (string, error) {
|
||||||
}
|
}
|
||||||
b[len(b)-1] = ',' // Replace closing curly brace with a comma.
|
b[len(b)-1] = ',' // Replace closing curly brace with a comma.
|
||||||
b = append(b, prv[1:]...) // Append private claims.
|
b = append(b, prv[1:]...) // Append private claims.
|
||||||
return base64Encode(b), nil
|
return base64.RawURLEncoding.EncodeToString(b), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Header represents the header for the signed JWS payloads.
|
// Header represents the header for the signed JWS payloads.
|
||||||
|
@ -93,6 +100,9 @@ type Header struct {
|
||||||
|
|
||||||
// Represents the token type.
|
// Represents the token type.
|
||||||
Typ string `json:"typ"`
|
Typ string `json:"typ"`
|
||||||
|
|
||||||
|
// The optional hint of which key is being used.
|
||||||
|
KeyID string `json:"kid,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *Header) encode() (string, error) {
|
func (h *Header) encode() (string, error) {
|
||||||
|
@ -100,7 +110,7 @@ func (h *Header) encode() (string, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
return base64Encode(b), nil
|
return base64.RawURLEncoding.EncodeToString(b), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decode decodes a claim set from a JWS payload.
|
// Decode decodes a claim set from a JWS payload.
|
||||||
|
@ -111,7 +121,7 @@ func Decode(payload string) (*ClaimSet, error) {
|
||||||
// TODO(jbd): Provide more context about the error.
|
// TODO(jbd): Provide more context about the error.
|
||||||
return nil, errors.New("jws: invalid token received")
|
return nil, errors.New("jws: invalid token received")
|
||||||
}
|
}
|
||||||
decoded, err := base64Decode(s[1])
|
decoded, err := base64.RawURLEncoding.DecodeString(s[1])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -120,8 +130,11 @@ func Decode(payload string) (*ClaimSet, error) {
|
||||||
return c, err
|
return c, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Encode encodes a signed JWS with provided header and claim set.
|
// Signer returns a signature for the given data.
|
||||||
func Encode(header *Header, c *ClaimSet, signature *rsa.PrivateKey) (string, error) {
|
type Signer func(data []byte) (sig []byte, err error)
|
||||||
|
|
||||||
|
// EncodeWithSigner encodes a header and claim set with the provided signer.
|
||||||
|
func EncodeWithSigner(header *Header, c *ClaimSet, sg Signer) (string, error) {
|
||||||
head, err := header.encode()
|
head, err := header.encode()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
|
@ -131,30 +144,39 @@ func Encode(header *Header, c *ClaimSet, signature *rsa.PrivateKey) (string, err
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
ss := fmt.Sprintf("%s.%s", head, cs)
|
ss := fmt.Sprintf("%s.%s", head, cs)
|
||||||
h := sha256.New()
|
sig, err := sg([]byte(ss))
|
||||||
h.Write([]byte(ss))
|
|
||||||
b, err := rsa.SignPKCS1v15(rand.Reader, signature, crypto.SHA256, h.Sum(nil))
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
sig := base64Encode(b)
|
return fmt.Sprintf("%s.%s", ss, base64.RawURLEncoding.EncodeToString(sig)), nil
|
||||||
return fmt.Sprintf("%s.%s", ss, sig), nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// base64Encode returns and Base64url encoded version of the input string with any
|
// Encode encodes a signed JWS with provided header and claim set.
|
||||||
// trailing "=" stripped.
|
// This invokes EncodeWithSigner using crypto/rsa.SignPKCS1v15 with the given RSA private key.
|
||||||
func base64Encode(b []byte) string {
|
func Encode(header *Header, c *ClaimSet, key *rsa.PrivateKey) (string, error) {
|
||||||
return strings.TrimRight(base64.URLEncoding.EncodeToString(b), "=")
|
sg := func(data []byte) (sig []byte, err error) {
|
||||||
}
|
h := sha256.New()
|
||||||
|
h.Write(data)
|
||||||
// base64Decode decodes the Base64url encoded string
|
return rsa.SignPKCS1v15(rand.Reader, key, crypto.SHA256, h.Sum(nil))
|
||||||
func base64Decode(s string) ([]byte, error) {
|
|
||||||
// add back missing padding
|
|
||||||
switch len(s) % 4 {
|
|
||||||
case 2:
|
|
||||||
s += "=="
|
|
||||||
case 3:
|
|
||||||
s += "="
|
|
||||||
}
|
}
|
||||||
return base64.URLEncoding.DecodeString(s)
|
return EncodeWithSigner(header, c, sg)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify tests whether the provided JWT token's signature was produced by the private key
|
||||||
|
// associated with the supplied public key.
|
||||||
|
func Verify(token string, key *rsa.PublicKey) error {
|
||||||
|
parts := strings.Split(token, ".")
|
||||||
|
if len(parts) != 3 {
|
||||||
|
return errors.New("jws: invalid token received, token must have 3 parts")
|
||||||
|
}
|
||||||
|
|
||||||
|
signedContent := parts[0] + "." + parts[1]
|
||||||
|
signatureString, err := base64.RawURLEncoding.DecodeString(parts[2])
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
h := sha256.New()
|
||||||
|
h.Write([]byte(signedContent))
|
||||||
|
return rsa.VerifyPKCS1v15(key, crypto.SHA256, h.Sum(nil), []byte(signatureString))
|
||||||
}
|
}
|
||||||
|
|
16
vendor/golang.org/x/oauth2/jwt/jwt.go
generated
vendored
16
vendor/golang.org/x/oauth2/jwt/jwt.go
generated
vendored
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2014 The oauth2 Authors. All rights reserved.
|
// Copyright 2014 The Go Authors. All rights reserved.
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
@ -46,6 +46,10 @@ type Config struct {
|
||||||
//
|
//
|
||||||
PrivateKey []byte
|
PrivateKey []byte
|
||||||
|
|
||||||
|
// PrivateKeyID contains an optional hint indicating which key is being
|
||||||
|
// used.
|
||||||
|
PrivateKeyID string
|
||||||
|
|
||||||
// Subject is the optional user to impersonate.
|
// Subject is the optional user to impersonate.
|
||||||
Subject string
|
Subject string
|
||||||
|
|
||||||
|
@ -54,6 +58,9 @@ type Config struct {
|
||||||
|
|
||||||
// TokenURL is the endpoint required to complete the 2-legged JWT flow.
|
// TokenURL is the endpoint required to complete the 2-legged JWT flow.
|
||||||
TokenURL string
|
TokenURL string
|
||||||
|
|
||||||
|
// Expires optionally specifies how long the token is valid for.
|
||||||
|
Expires time.Duration
|
||||||
}
|
}
|
||||||
|
|
||||||
// TokenSource returns a JWT TokenSource using the configuration
|
// TokenSource returns a JWT TokenSource using the configuration
|
||||||
|
@ -95,7 +102,12 @@ func (js jwtSource) Token() (*oauth2.Token, error) {
|
||||||
// to be compatible with legacy OAuth 2.0 providers.
|
// to be compatible with legacy OAuth 2.0 providers.
|
||||||
claimSet.Prn = subject
|
claimSet.Prn = subject
|
||||||
}
|
}
|
||||||
payload, err := jws.Encode(defaultHeader, claimSet, pk)
|
if t := js.conf.Expires; t > 0 {
|
||||||
|
claimSet.Exp = time.Now().Add(t).Unix()
|
||||||
|
}
|
||||||
|
h := *defaultHeader
|
||||||
|
h.KeyID = js.conf.PrivateKeyID
|
||||||
|
payload, err := jws.Encode(&h, claimSet, pk)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
267
vendor/golang.org/x/oauth2/oauth2.go
generated
vendored
267
vendor/golang.org/x/oauth2/oauth2.go
generated
vendored
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2014 The oauth2 Authors. All rights reserved.
|
// Copyright 2014 The Go Authors. All rights reserved.
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
@ -9,28 +9,38 @@ package oauth2 // import "golang.org/x/oauth2"
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/json"
|
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"io/ioutil"
|
|
||||||
"mime"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"strconv"
|
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
|
||||||
|
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
|
"golang.org/x/oauth2/internal"
|
||||||
)
|
)
|
||||||
|
|
||||||
// NoContext is the default context you should supply if not using
|
// NoContext is the default context you should supply if not using
|
||||||
// your own context.Context (see https://golang.org/x/net/context).
|
// your own context.Context (see https://golang.org/x/net/context).
|
||||||
|
//
|
||||||
|
// Deprecated: Use context.Background() or context.TODO() instead.
|
||||||
var NoContext = context.TODO()
|
var NoContext = context.TODO()
|
||||||
|
|
||||||
|
// RegisterBrokenAuthHeaderProvider registers an OAuth2 server
|
||||||
|
// identified by the tokenURL prefix as an OAuth2 implementation
|
||||||
|
// which doesn't support the HTTP Basic authentication
|
||||||
|
// scheme to authenticate with the authorization server.
|
||||||
|
// Once a server is registered, credentials (client_id and client_secret)
|
||||||
|
// will be passed as query parameters rather than being present
|
||||||
|
// in the Authorization header.
|
||||||
|
// See https://code.google.com/p/goauth2/issues/detail?id=31 for background.
|
||||||
|
func RegisterBrokenAuthHeaderProvider(tokenURL string) {
|
||||||
|
internal.RegisterBrokenAuthHeaderProvider(tokenURL)
|
||||||
|
}
|
||||||
|
|
||||||
// Config describes a typical 3-legged OAuth2 flow, with both the
|
// Config describes a typical 3-legged OAuth2 flow, with both the
|
||||||
// client application information and the server's endpoint URLs.
|
// client application information and the server's endpoint URLs.
|
||||||
|
// For the client credentials 2-legged OAuth2 flow, see the clientcredentials
|
||||||
|
// package (https://golang.org/x/oauth2/clientcredentials).
|
||||||
type Config struct {
|
type Config struct {
|
||||||
// ClientID is the application's ID.
|
// ClientID is the application's ID.
|
||||||
ClientID string
|
ClientID string
|
||||||
|
@ -79,13 +89,13 @@ var (
|
||||||
// result in your application obtaining a refresh token the
|
// result in your application obtaining a refresh token the
|
||||||
// first time your application exchanges an authorization
|
// first time your application exchanges an authorization
|
||||||
// code for a user.
|
// code for a user.
|
||||||
AccessTypeOnline AuthCodeOption = SetParam("access_type", "online")
|
AccessTypeOnline AuthCodeOption = SetAuthURLParam("access_type", "online")
|
||||||
AccessTypeOffline AuthCodeOption = SetParam("access_type", "offline")
|
AccessTypeOffline AuthCodeOption = SetAuthURLParam("access_type", "offline")
|
||||||
|
|
||||||
// ApprovalForce forces the users to view the consent dialog
|
// ApprovalForce forces the users to view the consent dialog
|
||||||
// and confirm the permissions request at the URL returned
|
// and confirm the permissions request at the URL returned
|
||||||
// from AuthCodeURL, even if they've already done so.
|
// from AuthCodeURL, even if they've already done so.
|
||||||
ApprovalForce AuthCodeOption = SetParam("approval_prompt", "force")
|
ApprovalForce AuthCodeOption = SetAuthURLParam("approval_prompt", "force")
|
||||||
)
|
)
|
||||||
|
|
||||||
// An AuthCodeOption is passed to Config.AuthCodeURL.
|
// An AuthCodeOption is passed to Config.AuthCodeURL.
|
||||||
|
@ -97,9 +107,9 @@ type setParam struct{ k, v string }
|
||||||
|
|
||||||
func (p setParam) setValue(m url.Values) { m.Set(p.k, p.v) }
|
func (p setParam) setValue(m url.Values) { m.Set(p.k, p.v) }
|
||||||
|
|
||||||
// SetParam builds an AuthCodeOption which passes key/value parameters
|
// SetAuthURLParam builds an AuthCodeOption which passes key/value parameters
|
||||||
// to a provider's authorization endpoint.
|
// to a provider's authorization endpoint.
|
||||||
func SetParam(key, value string) AuthCodeOption {
|
func SetAuthURLParam(key, value string) AuthCodeOption {
|
||||||
return setParam{key, value}
|
return setParam{key, value}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -119,9 +129,9 @@ func (c *Config) AuthCodeURL(state string, opts ...AuthCodeOption) string {
|
||||||
v := url.Values{
|
v := url.Values{
|
||||||
"response_type": {"code"},
|
"response_type": {"code"},
|
||||||
"client_id": {c.ClientID},
|
"client_id": {c.ClientID},
|
||||||
"redirect_uri": condVal(c.RedirectURL),
|
"redirect_uri": internal.CondVal(c.RedirectURL),
|
||||||
"scope": condVal(strings.Join(c.Scopes, " ")),
|
"scope": internal.CondVal(strings.Join(c.Scopes, " ")),
|
||||||
"state": condVal(state),
|
"state": internal.CondVal(state),
|
||||||
}
|
}
|
||||||
for _, opt := range opts {
|
for _, opt := range opts {
|
||||||
opt.setValue(v)
|
opt.setValue(v)
|
||||||
|
@ -151,7 +161,7 @@ func (c *Config) PasswordCredentialsToken(ctx context.Context, username, passwor
|
||||||
"grant_type": {"password"},
|
"grant_type": {"password"},
|
||||||
"username": {username},
|
"username": {username},
|
||||||
"password": {password},
|
"password": {password},
|
||||||
"scope": condVal(strings.Join(c.Scopes, " ")),
|
"scope": internal.CondVal(strings.Join(c.Scopes, " ")),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -169,51 +179,10 @@ func (c *Config) Exchange(ctx context.Context, code string) (*Token, error) {
|
||||||
return retrieveToken(ctx, c, url.Values{
|
return retrieveToken(ctx, c, url.Values{
|
||||||
"grant_type": {"authorization_code"},
|
"grant_type": {"authorization_code"},
|
||||||
"code": {code},
|
"code": {code},
|
||||||
"redirect_uri": condVal(c.RedirectURL),
|
"redirect_uri": internal.CondVal(c.RedirectURL),
|
||||||
"scope": condVal(strings.Join(c.Scopes, " ")),
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// contextClientFunc is a func which tries to return an *http.Client
|
|
||||||
// given a Context value. If it returns an error, the search stops
|
|
||||||
// with that error. If it returns (nil, nil), the search continues
|
|
||||||
// down the list of registered funcs.
|
|
||||||
type contextClientFunc func(context.Context) (*http.Client, error)
|
|
||||||
|
|
||||||
var contextClientFuncs []contextClientFunc
|
|
||||||
|
|
||||||
func registerContextClientFunc(fn contextClientFunc) {
|
|
||||||
contextClientFuncs = append(contextClientFuncs, fn)
|
|
||||||
}
|
|
||||||
|
|
||||||
func contextClient(ctx context.Context) (*http.Client, error) {
|
|
||||||
for _, fn := range contextClientFuncs {
|
|
||||||
c, err := fn(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if c != nil {
|
|
||||||
return c, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if hc, ok := ctx.Value(HTTPClient).(*http.Client); ok {
|
|
||||||
return hc, nil
|
|
||||||
}
|
|
||||||
return http.DefaultClient, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func contextTransport(ctx context.Context) http.RoundTripper {
|
|
||||||
hc, err := contextClient(ctx)
|
|
||||||
if err != nil {
|
|
||||||
// This is a rare error case (somebody using nil on App Engine),
|
|
||||||
// so I'd rather not everybody do an error check on this Client
|
|
||||||
// method. They can get the error that they're doing it wrong
|
|
||||||
// later, at client.Get/PostForm time.
|
|
||||||
return errorTransport{err}
|
|
||||||
}
|
|
||||||
return hc.Transport
|
|
||||||
}
|
|
||||||
|
|
||||||
// Client returns an HTTP client using the provided token.
|
// Client returns an HTTP client using the provided token.
|
||||||
// The token will auto-refresh as necessary. The underlying
|
// The token will auto-refresh as necessary. The underlying
|
||||||
// HTTP transport will be obtained using the provided context.
|
// HTTP transport will be obtained using the provided context.
|
||||||
|
@ -299,177 +268,25 @@ func (s *reuseTokenSource) Token() (*Token, error) {
|
||||||
return t, nil
|
return t, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func retrieveToken(ctx context.Context, c *Config, v url.Values) (*Token, error) {
|
// StaticTokenSource returns a TokenSource that always returns the same token.
|
||||||
hc, err := contextClient(ctx)
|
// Because the provided token t is never refreshed, StaticTokenSource is only
|
||||||
if err != nil {
|
// useful for tokens that never expire.
|
||||||
return nil, err
|
func StaticTokenSource(t *Token) TokenSource {
|
||||||
}
|
return staticTokenSource{t}
|
||||||
v.Set("client_id", c.ClientID)
|
|
||||||
bustedAuth := !providerAuthHeaderWorks(c.Endpoint.TokenURL)
|
|
||||||
if bustedAuth && c.ClientSecret != "" {
|
|
||||||
v.Set("client_secret", c.ClientSecret)
|
|
||||||
}
|
|
||||||
req, err := http.NewRequest("POST", c.Endpoint.TokenURL, strings.NewReader(v.Encode()))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
|
||||||
if !bustedAuth {
|
|
||||||
req.SetBasicAuth(c.ClientID, c.ClientSecret)
|
|
||||||
}
|
|
||||||
r, err := hc.Do(req)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
defer r.Body.Close()
|
|
||||||
body, err := ioutil.ReadAll(io.LimitReader(r.Body, 1<<20))
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("oauth2: cannot fetch token: %v", err)
|
|
||||||
}
|
|
||||||
if code := r.StatusCode; code < 200 || code > 299 {
|
|
||||||
return nil, fmt.Errorf("oauth2: cannot fetch token: %v\nResponse: %s", r.Status, body)
|
|
||||||
}
|
|
||||||
|
|
||||||
var token *Token
|
|
||||||
content, _, _ := mime.ParseMediaType(r.Header.Get("Content-Type"))
|
|
||||||
switch content {
|
|
||||||
case "application/x-www-form-urlencoded", "text/plain":
|
|
||||||
vals, err := url.ParseQuery(string(body))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
token = &Token{
|
|
||||||
AccessToken: vals.Get("access_token"),
|
|
||||||
TokenType: vals.Get("token_type"),
|
|
||||||
RefreshToken: vals.Get("refresh_token"),
|
|
||||||
raw: vals,
|
|
||||||
}
|
|
||||||
e := vals.Get("expires_in")
|
|
||||||
if e == "" {
|
|
||||||
// TODO(jbd): Facebook's OAuth2 implementation is broken and
|
|
||||||
// returns expires_in field in expires. Remove the fallback to expires,
|
|
||||||
// when Facebook fixes their implementation.
|
|
||||||
e = vals.Get("expires")
|
|
||||||
}
|
|
||||||
expires, _ := strconv.Atoi(e)
|
|
||||||
if expires != 0 {
|
|
||||||
token.Expiry = time.Now().Add(time.Duration(expires) * time.Second)
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
var tj tokenJSON
|
|
||||||
if err = json.Unmarshal(body, &tj); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
token = &Token{
|
|
||||||
AccessToken: tj.AccessToken,
|
|
||||||
TokenType: tj.TokenType,
|
|
||||||
RefreshToken: tj.RefreshToken,
|
|
||||||
Expiry: tj.expiry(),
|
|
||||||
raw: make(map[string]interface{}),
|
|
||||||
}
|
|
||||||
json.Unmarshal(body, &token.raw) // no error checks for optional fields
|
|
||||||
}
|
|
||||||
// Don't overwrite `RefreshToken` with an empty value
|
|
||||||
// if this was a token refreshing request.
|
|
||||||
if token.RefreshToken == "" {
|
|
||||||
token.RefreshToken = v.Get("refresh_token")
|
|
||||||
}
|
|
||||||
return token, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// tokenJSON is the struct representing the HTTP response from OAuth2
|
// staticTokenSource is a TokenSource that always returns the same Token.
|
||||||
// providers returning a token in JSON form.
|
type staticTokenSource struct {
|
||||||
type tokenJSON struct {
|
t *Token
|
||||||
AccessToken string `json:"access_token"`
|
|
||||||
TokenType string `json:"token_type"`
|
|
||||||
RefreshToken string `json:"refresh_token"`
|
|
||||||
ExpiresIn expirationTime `json:"expires_in"` // at least PayPal returns string, while most return number
|
|
||||||
Expires expirationTime `json:"expires"` // broken Facebook spelling of expires_in
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *tokenJSON) expiry() (t time.Time) {
|
func (s staticTokenSource) Token() (*Token, error) {
|
||||||
if v := e.ExpiresIn; v != 0 {
|
return s.t, nil
|
||||||
return time.Now().Add(time.Duration(v) * time.Second)
|
|
||||||
}
|
|
||||||
if v := e.Expires; v != 0 {
|
|
||||||
return time.Now().Add(time.Duration(v) * time.Second)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
type expirationTime int32
|
|
||||||
|
|
||||||
func (e *expirationTime) UnmarshalJSON(b []byte) error {
|
|
||||||
var n json.Number
|
|
||||||
err := json.Unmarshal(b, &n)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
i, err := n.Int64()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
*e = expirationTime(i)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func condVal(v string) []string {
|
|
||||||
if v == "" {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return []string{v}
|
|
||||||
}
|
|
||||||
|
|
||||||
var brokenAuthHeaderProviders = []string{
|
|
||||||
"https://accounts.google.com/",
|
|
||||||
"https://www.googleapis.com/",
|
|
||||||
"https://github.com/",
|
|
||||||
"https://api.instagram.com/",
|
|
||||||
"https://www.douban.com/",
|
|
||||||
"https://api.dropbox.com/",
|
|
||||||
"https://api.soundcloud.com/",
|
|
||||||
"https://www.linkedin.com/",
|
|
||||||
"https://api.twitch.tv/",
|
|
||||||
"https://oauth.vk.com/",
|
|
||||||
"https://api.odnoklassniki.ru/",
|
|
||||||
"https://connect.stripe.com/",
|
|
||||||
"https://api.pushbullet.com/",
|
|
||||||
"https://oauth.sandbox.trainingpeaks.com/",
|
|
||||||
"https://oauth.trainingpeaks.com/",
|
|
||||||
"https://www.strava.com/oauth/",
|
|
||||||
}
|
|
||||||
|
|
||||||
// providerAuthHeaderWorks reports whether the OAuth2 server identified by the tokenURL
|
|
||||||
// implements the OAuth2 spec correctly
|
|
||||||
// See https://code.google.com/p/goauth2/issues/detail?id=31 for background.
|
|
||||||
// In summary:
|
|
||||||
// - Reddit only accepts client secret in the Authorization header
|
|
||||||
// - Dropbox accepts either it in URL param or Auth header, but not both.
|
|
||||||
// - Google only accepts URL param (not spec compliant?), not Auth header
|
|
||||||
// - Stripe only accepts client secret in Auth header with Bearer method, not Basic
|
|
||||||
func providerAuthHeaderWorks(tokenURL string) bool {
|
|
||||||
for _, s := range brokenAuthHeaderProviders {
|
|
||||||
if strings.HasPrefix(tokenURL, s) {
|
|
||||||
// Some sites fail to implement the OAuth2 spec fully.
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Assume the provider implements the spec properly
|
|
||||||
// otherwise. We can add more exceptions as they're
|
|
||||||
// discovered. We will _not_ be adding configurable hooks
|
|
||||||
// to this package to let users select server bugs.
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// HTTPClient is the context key to use with golang.org/x/net/context's
|
// HTTPClient is the context key to use with golang.org/x/net/context's
|
||||||
// WithValue function to associate an *http.Client value with a context.
|
// WithValue function to associate an *http.Client value with a context.
|
||||||
var HTTPClient contextKey
|
var HTTPClient internal.ContextKey
|
||||||
|
|
||||||
// contextKey is just an empty struct. It exists so HTTPClient can be
|
|
||||||
// an immutable public variable with a unique type. It's immutable
|
|
||||||
// because nobody else can create a contextKey, being unexported.
|
|
||||||
type contextKey struct{}
|
|
||||||
|
|
||||||
// NewClient creates an *http.Client from a Context and TokenSource.
|
// NewClient creates an *http.Client from a Context and TokenSource.
|
||||||
// The returned client is not valid beyond the lifetime of the context.
|
// The returned client is not valid beyond the lifetime of the context.
|
||||||
|
@ -479,15 +296,15 @@ type contextKey struct{}
|
||||||
// packages.
|
// packages.
|
||||||
func NewClient(ctx context.Context, src TokenSource) *http.Client {
|
func NewClient(ctx context.Context, src TokenSource) *http.Client {
|
||||||
if src == nil {
|
if src == nil {
|
||||||
c, err := contextClient(ctx)
|
c, err := internal.ContextClient(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return &http.Client{Transport: errorTransport{err}}
|
return &http.Client{Transport: internal.ErrorTransport{Err: err}}
|
||||||
}
|
}
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
return &http.Client{
|
return &http.Client{
|
||||||
Transport: &Transport{
|
Transport: &Transport{
|
||||||
Base: contextTransport(ctx),
|
Base: internal.ContextTransport(ctx),
|
||||||
Source: ReuseTokenSource(nil, src),
|
Source: ReuseTokenSource(nil, src),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
64
vendor/golang.org/x/oauth2/token.go
generated
vendored
64
vendor/golang.org/x/oauth2/token.go
generated
vendored
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2014 The oauth2 Authors. All rights reserved.
|
// Copyright 2014 The Go Authors. All rights reserved.
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
@ -7,7 +7,12 @@ package oauth2
|
||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"golang.org/x/net/context"
|
||||||
|
"golang.org/x/oauth2/internal"
|
||||||
)
|
)
|
||||||
|
|
||||||
// expiryDelta determines how earlier a token should be considered
|
// expiryDelta determines how earlier a token should be considered
|
||||||
|
@ -50,6 +55,15 @@ type Token struct {
|
||||||
|
|
||||||
// Type returns t.TokenType if non-empty, else "Bearer".
|
// Type returns t.TokenType if non-empty, else "Bearer".
|
||||||
func (t *Token) Type() string {
|
func (t *Token) Type() string {
|
||||||
|
if strings.EqualFold(t.TokenType, "bearer") {
|
||||||
|
return "Bearer"
|
||||||
|
}
|
||||||
|
if strings.EqualFold(t.TokenType, "mac") {
|
||||||
|
return "MAC"
|
||||||
|
}
|
||||||
|
if strings.EqualFold(t.TokenType, "basic") {
|
||||||
|
return "Basic"
|
||||||
|
}
|
||||||
if t.TokenType != "" {
|
if t.TokenType != "" {
|
||||||
return t.TokenType
|
return t.TokenType
|
||||||
}
|
}
|
||||||
|
@ -79,14 +93,28 @@ func (t *Token) WithExtra(extra interface{}) *Token {
|
||||||
// Extra fields are key-value pairs returned by the server as a
|
// Extra fields are key-value pairs returned by the server as a
|
||||||
// part of the token retrieval response.
|
// part of the token retrieval response.
|
||||||
func (t *Token) Extra(key string) interface{} {
|
func (t *Token) Extra(key string) interface{} {
|
||||||
if vals, ok := t.raw.(url.Values); ok {
|
|
||||||
// TODO(jbd): Cast numeric values to int64 or float64.
|
|
||||||
return vals.Get(key)
|
|
||||||
}
|
|
||||||
if raw, ok := t.raw.(map[string]interface{}); ok {
|
if raw, ok := t.raw.(map[string]interface{}); ok {
|
||||||
return raw[key]
|
return raw[key]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vals, ok := t.raw.(url.Values)
|
||||||
|
if !ok {
|
||||||
return nil
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
v := vals.Get(key)
|
||||||
|
switch s := strings.TrimSpace(v); strings.Count(s, ".") {
|
||||||
|
case 0: // Contains no "."; try to parse as int
|
||||||
|
if i, err := strconv.ParseInt(s, 10, 64); err == nil {
|
||||||
|
return i
|
||||||
|
}
|
||||||
|
case 1: // Contains a single "."; try to parse as float
|
||||||
|
if f, err := strconv.ParseFloat(s, 64); err == nil {
|
||||||
|
return f
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return v
|
||||||
}
|
}
|
||||||
|
|
||||||
// expired reports whether the token is expired.
|
// expired reports whether the token is expired.
|
||||||
|
@ -102,3 +130,29 @@ func (t *Token) expired() bool {
|
||||||
func (t *Token) Valid() bool {
|
func (t *Token) Valid() bool {
|
||||||
return t != nil && t.AccessToken != "" && !t.expired()
|
return t != nil && t.AccessToken != "" && !t.expired()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// tokenFromInternal maps an *internal.Token struct into
|
||||||
|
// a *Token struct.
|
||||||
|
func tokenFromInternal(t *internal.Token) *Token {
|
||||||
|
if t == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return &Token{
|
||||||
|
AccessToken: t.AccessToken,
|
||||||
|
TokenType: t.TokenType,
|
||||||
|
RefreshToken: t.RefreshToken,
|
||||||
|
Expiry: t.Expiry,
|
||||||
|
raw: t.Raw,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// retrieveToken takes a *Config and uses that to retrieve an *internal.Token.
|
||||||
|
// This token is then mapped from *internal.Token into an *oauth2.Token which is returned along
|
||||||
|
// with an error..
|
||||||
|
func retrieveToken(ctx context.Context, c *Config, v url.Values) (*Token, error) {
|
||||||
|
tk, err := internal.RetrieveToken(ctx, c.ClientID, c.ClientSecret, c.Endpoint.TokenURL, v)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return tokenFromInternal(tk), nil
|
||||||
|
}
|
||||||
|
|
8
vendor/golang.org/x/oauth2/transport.go
generated
vendored
8
vendor/golang.org/x/oauth2/transport.go
generated
vendored
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2014 The oauth2 Authors. All rights reserved.
|
// Copyright 2014 The Go Authors. All rights reserved.
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
@ -130,9 +130,3 @@ func (r *onEOFReader) runFunc() {
|
||||||
r.fn = nil
|
r.fn = nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type errorTransport struct{ err error }
|
|
||||||
|
|
||||||
func (t errorTransport) RoundTrip(*http.Request) (*http.Response, error) {
|
|
||||||
return nil, t.err
|
|
||||||
}
|
|
||||||
|
|
49
vendor/golang.org/x/text/cases/cases.go
generated
vendored
49
vendor/golang.org/x/text/cases/cases.go
generated
vendored
|
@ -35,7 +35,7 @@ import (
|
||||||
// A Caser may be stateful and should therefore not be shared between
|
// A Caser may be stateful and should therefore not be shared between
|
||||||
// goroutines.
|
// goroutines.
|
||||||
type Caser struct {
|
type Caser struct {
|
||||||
t transform.SpanningTransformer
|
t transform.Transformer
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bytes returns a new byte slice with the result of converting b to the case
|
// Bytes returns a new byte slice with the result of converting b to the case
|
||||||
|
@ -56,17 +56,12 @@ func (c Caser) String(s string) string {
|
||||||
// Transform.
|
// Transform.
|
||||||
func (c Caser) Reset() { c.t.Reset() }
|
func (c Caser) Reset() { c.t.Reset() }
|
||||||
|
|
||||||
// Transform implements the transform.Transformer interface and transforms the
|
// Transform implements the Transformer interface and transforms the given input
|
||||||
// given input to the case form implemented by c.
|
// to the case form implemented by c.
|
||||||
func (c Caser) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
|
func (c Caser) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
|
||||||
return c.t.Transform(dst, src, atEOF)
|
return c.t.Transform(dst, src, atEOF)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Span implements the transform.SpanningTransformer interface.
|
|
||||||
func (c Caser) Span(src []byte, atEOF bool) (n int, err error) {
|
|
||||||
return c.t.Span(src, atEOF)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Upper returns a Caser for language-specific uppercasing.
|
// Upper returns a Caser for language-specific uppercasing.
|
||||||
func Upper(t language.Tag, opts ...Option) Caser {
|
func Upper(t language.Tag, opts ...Option) Caser {
|
||||||
return Caser{makeUpper(t, getOpts(opts...))}
|
return Caser{makeUpper(t, getOpts(opts...))}
|
||||||
|
@ -95,13 +90,7 @@ func Fold(opts ...Option) Caser {
|
||||||
}
|
}
|
||||||
|
|
||||||
// An Option is used to modify the behavior of a Caser.
|
// An Option is used to modify the behavior of a Caser.
|
||||||
type Option func(o options) options
|
type Option func(o *options)
|
||||||
|
|
||||||
// TODO: consider these options to take a boolean as well, like FinalSigma.
|
|
||||||
// The advantage of using this approach is that other providers of a lower-case
|
|
||||||
// algorithm could set different defaults by prefixing a user-provided slice
|
|
||||||
// of options with their own. This is handy, for instance, for the precis
|
|
||||||
// package which would override the default to not handle the Greek final sigma.
|
|
||||||
|
|
||||||
var (
|
var (
|
||||||
// NoLower disables the lowercasing of non-leading letters for a title
|
// NoLower disables the lowercasing of non-leading letters for a title
|
||||||
|
@ -121,42 +110,20 @@ type options struct {
|
||||||
|
|
||||||
// TODO: segmenter, max ignorable, alternative versions, etc.
|
// TODO: segmenter, max ignorable, alternative versions, etc.
|
||||||
|
|
||||||
ignoreFinalSigma bool
|
noFinalSigma bool // Only used for testing.
|
||||||
}
|
}
|
||||||
|
|
||||||
func getOpts(o ...Option) (res options) {
|
func getOpts(o ...Option) (res options) {
|
||||||
for _, f := range o {
|
for _, f := range o {
|
||||||
res = f(res)
|
f(&res)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func noLower(o options) options {
|
func noLower(o *options) {
|
||||||
o.noLower = true
|
o.noLower = true
|
||||||
return o
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func compact(o options) options {
|
func compact(o *options) {
|
||||||
o.simple = true
|
o.simple = true
|
||||||
return o
|
|
||||||
}
|
|
||||||
|
|
||||||
// HandleFinalSigma specifies whether the special handling of Greek final sigma
|
|
||||||
// should be enabled. Unicode prescribes handling the Greek final sigma for all
|
|
||||||
// locales, but standards like IDNA and PRECIS override this default.
|
|
||||||
func HandleFinalSigma(enable bool) Option {
|
|
||||||
if enable {
|
|
||||||
return handleFinalSigma
|
|
||||||
}
|
|
||||||
return ignoreFinalSigma
|
|
||||||
}
|
|
||||||
|
|
||||||
func ignoreFinalSigma(o options) options {
|
|
||||||
o.ignoreFinalSigma = true
|
|
||||||
return o
|
|
||||||
}
|
|
||||||
|
|
||||||
func handleFinalSigma(o options) options {
|
|
||||||
o.ignoreFinalSigma = false
|
|
||||||
return o
|
|
||||||
}
|
}
|
||||||
|
|
101
vendor/golang.org/x/text/cases/context.go
generated
vendored
101
vendor/golang.org/x/text/cases/context.go
generated
vendored
|
@ -4,7 +4,9 @@
|
||||||
|
|
||||||
package cases
|
package cases
|
||||||
|
|
||||||
import "golang.org/x/text/transform"
|
import (
|
||||||
|
"golang.org/x/text/transform"
|
||||||
|
)
|
||||||
|
|
||||||
// A context is used for iterating over source bytes, fetching case info and
|
// A context is used for iterating over source bytes, fetching case info and
|
||||||
// writing to a destination buffer.
|
// writing to a destination buffer.
|
||||||
|
@ -54,14 +56,6 @@ func (c *context) ret() (nDst, nSrc int, err error) {
|
||||||
return c.nDst, c.nSrc, transform.ErrShortSrc
|
return c.nDst, c.nSrc, transform.ErrShortSrc
|
||||||
}
|
}
|
||||||
|
|
||||||
// retSpan returns the return values for the Span method. It checks whether
|
|
||||||
// there were insufficient bytes in src to complete and introduces an error
|
|
||||||
// accordingly, if necessary.
|
|
||||||
func (c *context) retSpan() (n int, err error) {
|
|
||||||
_, nSrc, err := c.ret()
|
|
||||||
return nSrc, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// checkpoint sets the return value buffer points for Transform to the current
|
// checkpoint sets the return value buffer points for Transform to the current
|
||||||
// positions.
|
// positions.
|
||||||
func (c *context) checkpoint() {
|
func (c *context) checkpoint() {
|
||||||
|
@ -206,23 +200,6 @@ func lower(c *context) bool {
|
||||||
return c.copy()
|
return c.copy()
|
||||||
}
|
}
|
||||||
|
|
||||||
func isLower(c *context) bool {
|
|
||||||
ct := c.caseType()
|
|
||||||
if c.info&hasMappingMask == 0 || ct == cLower {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
if c.info&exceptionBit == 0 {
|
|
||||||
c.err = transform.ErrEndOfSpan
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
e := exceptions[c.info>>exceptionShift:]
|
|
||||||
if nLower := (e[1] >> lengthBits) & lengthMask; nLower != noChange {
|
|
||||||
c.err = transform.ErrEndOfSpan
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// upper writes the uppercase version of the current rune to dst.
|
// upper writes the uppercase version of the current rune to dst.
|
||||||
func upper(c *context) bool {
|
func upper(c *context) bool {
|
||||||
ct := c.caseType()
|
ct := c.caseType()
|
||||||
|
@ -249,29 +226,6 @@ func upper(c *context) bool {
|
||||||
return c.copy()
|
return c.copy()
|
||||||
}
|
}
|
||||||
|
|
||||||
// isUpper writes the isUppercase version of the current rune to dst.
|
|
||||||
func isUpper(c *context) bool {
|
|
||||||
ct := c.caseType()
|
|
||||||
if c.info&hasMappingMask == 0 || ct == cUpper {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
if c.info&exceptionBit == 0 {
|
|
||||||
c.err = transform.ErrEndOfSpan
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
e := exceptions[c.info>>exceptionShift:]
|
|
||||||
// Get length of first special case mapping.
|
|
||||||
n := (e[1] >> lengthBits) & lengthMask
|
|
||||||
if ct == cTitle {
|
|
||||||
n = e[1] & lengthMask
|
|
||||||
}
|
|
||||||
if n != noChange {
|
|
||||||
c.err = transform.ErrEndOfSpan
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// title writes the title case version of the current rune to dst.
|
// title writes the title case version of the current rune to dst.
|
||||||
func title(c *context) bool {
|
func title(c *context) bool {
|
||||||
ct := c.caseType()
|
ct := c.caseType()
|
||||||
|
@ -303,33 +257,6 @@ func title(c *context) bool {
|
||||||
return c.copy()
|
return c.copy()
|
||||||
}
|
}
|
||||||
|
|
||||||
// isTitle reports whether the current rune is in title case.
|
|
||||||
func isTitle(c *context) bool {
|
|
||||||
ct := c.caseType()
|
|
||||||
if c.info&hasMappingMask == 0 || ct == cTitle {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
if c.info&exceptionBit == 0 {
|
|
||||||
if ct == cLower {
|
|
||||||
c.err = transform.ErrEndOfSpan
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
// Get the exception data.
|
|
||||||
e := exceptions[c.info>>exceptionShift:]
|
|
||||||
if nTitle := e[1] & lengthMask; nTitle != noChange {
|
|
||||||
c.err = transform.ErrEndOfSpan
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
nFirst := (e[1] >> lengthBits) & lengthMask
|
|
||||||
if ct == cLower && nFirst != noChange {
|
|
||||||
c.err = transform.ErrEndOfSpan
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// foldFull writes the foldFull version of the current rune to dst.
|
// foldFull writes the foldFull version of the current rune to dst.
|
||||||
func foldFull(c *context) bool {
|
func foldFull(c *context) bool {
|
||||||
if c.info&hasMappingMask == 0 {
|
if c.info&hasMappingMask == 0 {
|
||||||
|
@ -352,25 +279,3 @@ func foldFull(c *context) bool {
|
||||||
}
|
}
|
||||||
return c.writeString(e[2 : 2+n])
|
return c.writeString(e[2 : 2+n])
|
||||||
}
|
}
|
||||||
|
|
||||||
// isFoldFull reports whether the current run is mapped to foldFull
|
|
||||||
func isFoldFull(c *context) bool {
|
|
||||||
if c.info&hasMappingMask == 0 {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
ct := c.caseType()
|
|
||||||
if c.info&exceptionBit == 0 {
|
|
||||||
if ct != cLower || c.info&inverseFoldBit != 0 {
|
|
||||||
c.err = transform.ErrEndOfSpan
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
e := exceptions[c.info>>exceptionShift:]
|
|
||||||
n := e[0] & lengthMask
|
|
||||||
if n == 0 && ct == cLower {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
c.err = transform.ErrEndOfSpan
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
10
vendor/golang.org/x/text/cases/fold.go
generated
vendored
10
vendor/golang.org/x/text/cases/fold.go
generated
vendored
|
@ -18,15 +18,7 @@ func (t *caseFolder) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err
|
||||||
return c.ret()
|
return c.ret()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *caseFolder) Span(src []byte, atEOF bool) (n int, err error) {
|
func makeFold(o options) transform.Transformer {
|
||||||
c := context{src: src, atEOF: atEOF}
|
|
||||||
for c.next() && isFoldFull(&c) {
|
|
||||||
c.checkpoint()
|
|
||||||
}
|
|
||||||
return c.retSpan()
|
|
||||||
}
|
|
||||||
|
|
||||||
func makeFold(o options) transform.SpanningTransformer {
|
|
||||||
// TODO: Special case folding, through option Language, Special/Turkic, or
|
// TODO: Special case folding, through option Language, Special/Turkic, or
|
||||||
// both.
|
// both.
|
||||||
// TODO: Implement Compact options.
|
// TODO: Implement Compact options.
|
||||||
|
|
20
vendor/golang.org/x/text/cases/gen.go
generated
vendored
20
vendor/golang.org/x/text/cases/gen.go
generated
vendored
|
@ -76,7 +76,7 @@ type breakCategory int
|
||||||
const (
|
const (
|
||||||
breakBreak breakCategory = iota
|
breakBreak breakCategory = iota
|
||||||
breakLetter
|
breakLetter
|
||||||
breakMid
|
breakIgnored
|
||||||
)
|
)
|
||||||
|
|
||||||
// mapping returns the case mapping for the given case type.
|
// mapping returns the case mapping for the given case type.
|
||||||
|
@ -162,14 +162,9 @@ func parseUCD() []runeInfo {
|
||||||
|
|
||||||
// We collapse the word breaking properties onto the categories we need.
|
// We collapse the word breaking properties onto the categories we need.
|
||||||
switch p.String(1) { // TODO: officially we need to canonicalize.
|
switch p.String(1) { // TODO: officially we need to canonicalize.
|
||||||
case "MidLetter", "MidNumLet", "Single_Quote":
|
case "Format", "MidLetter", "MidNumLet", "Single_Quote":
|
||||||
ri.BreakCat = breakMid
|
ri.BreakCat = breakIgnored
|
||||||
if !ri.CaseIgnorable {
|
case "ALetter", "Hebrew_Letter", "Numeric", "Extend", "ExtendNumLet":
|
||||||
// finalSigma relies on the fact that all breakMid runes are
|
|
||||||
// also a Case_Ignorable. Revisit this code when this changes.
|
|
||||||
log.Fatalf("Rune %U, which has a break category mid, is not a case ignorable", ri)
|
|
||||||
}
|
|
||||||
case "ALetter", "Hebrew_Letter", "Numeric", "Extend", "ExtendNumLet", "Format", "ZWJ":
|
|
||||||
ri.BreakCat = breakLetter
|
ri.BreakCat = breakLetter
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -245,11 +240,8 @@ func makeEntry(ri *runeInfo) {
|
||||||
case above: // Above
|
case above: // Above
|
||||||
ccc = cccAbove
|
ccc = cccAbove
|
||||||
}
|
}
|
||||||
switch ri.BreakCat {
|
if ri.BreakCat == breakBreak {
|
||||||
case breakBreak:
|
|
||||||
ccc = cccBreak
|
ccc = cccBreak
|
||||||
case breakMid:
|
|
||||||
ri.entry |= isMidBit
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ri.entry |= ccc
|
ri.entry |= ccc
|
||||||
|
@ -698,7 +690,7 @@ func genTablesTest() {
|
||||||
parse("auxiliary/WordBreakProperty.txt", func(p *ucd.Parser) {
|
parse("auxiliary/WordBreakProperty.txt", func(p *ucd.Parser) {
|
||||||
switch p.String(1) {
|
switch p.String(1) {
|
||||||
case "Extend", "Format", "MidLetter", "MidNumLet", "Single_Quote",
|
case "Extend", "Format", "MidLetter", "MidNumLet", "Single_Quote",
|
||||||
"ALetter", "Hebrew_Letter", "Numeric", "ExtendNumLet", "ZWJ":
|
"ALetter", "Hebrew_Letter", "Numeric", "ExtendNumLet":
|
||||||
notBreak[p.Rune(0)] = true
|
notBreak[p.Rune(0)] = true
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
12
vendor/golang.org/x/text/cases/gen_trieval.go
generated
vendored
12
vendor/golang.org/x/text/cases/gen_trieval.go
generated
vendored
|
@ -26,7 +26,6 @@ package main
|
||||||
// Only 13..8 are used for XOR patterns.
|
// Only 13..8 are used for XOR patterns.
|
||||||
// 7 inverseFold (fold to upper, not to lower)
|
// 7 inverseFold (fold to upper, not to lower)
|
||||||
// 6 index: interpret the XOR pattern as an index
|
// 6 index: interpret the XOR pattern as an index
|
||||||
// or isMid if case mode is cIgnorableUncased.
|
|
||||||
// 5..4 CCC: zero (normal or break), above or other
|
// 5..4 CCC: zero (normal or break), above or other
|
||||||
// }
|
// }
|
||||||
// 3 exception: interpret this value as an exception index
|
// 3 exception: interpret this value as an exception index
|
||||||
|
@ -49,7 +48,6 @@ const (
|
||||||
ignorableValue = 0x0004
|
ignorableValue = 0x0004
|
||||||
|
|
||||||
inverseFoldBit = 1 << 7
|
inverseFoldBit = 1 << 7
|
||||||
isMidBit = 1 << 6
|
|
||||||
|
|
||||||
exceptionBit = 1 << 3
|
exceptionBit = 1 << 3
|
||||||
exceptionShift = 5
|
exceptionShift = 5
|
||||||
|
@ -59,7 +57,7 @@ const (
|
||||||
xorShift = 8
|
xorShift = 8
|
||||||
|
|
||||||
// There is no mapping if all xor bits and the exception bit are zero.
|
// There is no mapping if all xor bits and the exception bit are zero.
|
||||||
hasMappingMask = 0xff80 | exceptionBit
|
hasMappingMask = 0xffc0 | exceptionBit
|
||||||
)
|
)
|
||||||
|
|
||||||
// The case mode bits encodes the case type of a rune. This includes uncased,
|
// The case mode bits encodes the case type of a rune. This includes uncased,
|
||||||
|
@ -97,6 +95,10 @@ func (c info) isCaseIgnorable() bool {
|
||||||
return c&ignorableMask == ignorableValue
|
return c&ignorableMask == ignorableValue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c info) isCaseIgnorableAndNonBreakStarter() bool {
|
||||||
|
return c&(fullCasedMask|cccMask) == (ignorableValue | cccZero)
|
||||||
|
}
|
||||||
|
|
||||||
func (c info) isNotCasedAndNotCaseIgnorable() bool {
|
func (c info) isNotCasedAndNotCaseIgnorable() bool {
|
||||||
return c&fullCasedMask == 0
|
return c&fullCasedMask == 0
|
||||||
}
|
}
|
||||||
|
@ -105,10 +107,6 @@ func (c info) isCaseIgnorableAndNotCased() bool {
|
||||||
return c&fullCasedMask == cIgnorableUncased
|
return c&fullCasedMask == cIgnorableUncased
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c info) isMid() bool {
|
|
||||||
return c&(fullCasedMask|isMidBit) == isMidBit|cIgnorableUncased
|
|
||||||
}
|
|
||||||
|
|
||||||
// The case mapping implementation will need to know about various Canonical
|
// The case mapping implementation will need to know about various Canonical
|
||||||
// Combining Class (CCC) values. We encode two of these in the trie value:
|
// Combining Class (CCC) values. We encode two of these in the trie value:
|
||||||
// cccZero (0) and cccAbove (230). If the value is cccOther, it means that
|
// cccZero (0) and cccAbove (230). If the value is cccOther, it means that
|
||||||
|
|
61
vendor/golang.org/x/text/cases/icu.go
generated
vendored
61
vendor/golang.org/x/text/cases/icu.go
generated
vendored
|
@ -1,61 +0,0 @@
|
||||||
// Copyright 2016 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build icu
|
|
||||||
|
|
||||||
package cases
|
|
||||||
|
|
||||||
// Ideally these functions would be defined in a test file, but go test doesn't
|
|
||||||
// allow CGO in tests. The build tag should ensure either way that these
|
|
||||||
// functions will not end up in the package.
|
|
||||||
|
|
||||||
// TODO: Ensure that the correct ICU version is set.
|
|
||||||
|
|
||||||
/*
|
|
||||||
#cgo LDFLAGS: -licui18n.57 -licuuc.57
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <unicode/ustring.h>
|
|
||||||
#include <unicode/utypes.h>
|
|
||||||
#include <unicode/localpointer.h>
|
|
||||||
#include <unicode/ucasemap.h>
|
|
||||||
*/
|
|
||||||
import "C"
|
|
||||||
|
|
||||||
import "unsafe"
|
|
||||||
|
|
||||||
func doICU(tag, caser, input string) string {
|
|
||||||
err := C.UErrorCode(0)
|
|
||||||
loc := C.CString(tag)
|
|
||||||
cm := C.ucasemap_open(loc, C.uint32_t(0), &err)
|
|
||||||
|
|
||||||
buf := make([]byte, len(input)*4)
|
|
||||||
dst := (*C.char)(unsafe.Pointer(&buf[0]))
|
|
||||||
src := C.CString(input)
|
|
||||||
|
|
||||||
cn := C.int32_t(0)
|
|
||||||
|
|
||||||
switch caser {
|
|
||||||
case "fold":
|
|
||||||
cn = C.ucasemap_utf8FoldCase(cm,
|
|
||||||
dst, C.int32_t(len(buf)),
|
|
||||||
src, C.int32_t(len(input)),
|
|
||||||
&err)
|
|
||||||
case "lower":
|
|
||||||
cn = C.ucasemap_utf8ToLower(cm,
|
|
||||||
dst, C.int32_t(len(buf)),
|
|
||||||
src, C.int32_t(len(input)),
|
|
||||||
&err)
|
|
||||||
case "upper":
|
|
||||||
cn = C.ucasemap_utf8ToUpper(cm,
|
|
||||||
dst, C.int32_t(len(buf)),
|
|
||||||
src, C.int32_t(len(input)),
|
|
||||||
&err)
|
|
||||||
case "title":
|
|
||||||
cn = C.ucasemap_utf8ToTitle(cm,
|
|
||||||
dst, C.int32_t(len(buf)),
|
|
||||||
src, C.int32_t(len(input)),
|
|
||||||
&err)
|
|
||||||
}
|
|
||||||
return string(buf[:cn])
|
|
||||||
}
|
|
15
vendor/golang.org/x/text/cases/info.go
generated
vendored
15
vendor/golang.org/x/text/cases/info.go
generated
vendored
|
@ -28,6 +28,9 @@ func (c info) cccType() info {
|
||||||
// only makes sense, though, if the performance and/or space penalty of using
|
// only makes sense, though, if the performance and/or space penalty of using
|
||||||
// the generic breaker is big. Extra data will only be needed for non-cased
|
// the generic breaker is big. Extra data will only be needed for non-cased
|
||||||
// runes, which means there are sufficient bits left in the caseType.
|
// runes, which means there are sufficient bits left in the caseType.
|
||||||
|
// Also note that the standard breaking algorithm doesn't always make sense
|
||||||
|
// for title casing. For example, a4a -> A4a, but a"4a -> A"4A (where " stands
|
||||||
|
// for modifier \u0308).
|
||||||
// ICU prohibits breaking in such cases as well.
|
// ICU prohibits breaking in such cases as well.
|
||||||
|
|
||||||
// For the purpose of title casing we use an approximation of the Unicode Word
|
// For the purpose of title casing we use an approximation of the Unicode Word
|
||||||
|
@ -38,19 +41,17 @@ func (c info) cccType() info {
|
||||||
// categories, with associated rules:
|
// categories, with associated rules:
|
||||||
//
|
//
|
||||||
// 1) Letter:
|
// 1) Letter:
|
||||||
// ALetter, Hebrew_Letter, Numeric, ExtendNumLet, Extend, Format_FE, ZWJ.
|
// ALetter, Hebrew_Letter, Numeric, ExtendNumLet, Extend.
|
||||||
// Rule: Never break between consecutive runes of this category.
|
// Rule: Never break between consecutive runes of this category.
|
||||||
//
|
//
|
||||||
// 2) Mid:
|
// 2) Mid:
|
||||||
// MidLetter, MidNumLet, Single_Quote.
|
// Format, MidLetter, MidNumLet, Single_Quote.
|
||||||
// (Cf. case-ignorable: MidLetter, MidNumLet, Single_Quote or cat is Mn,
|
// (Cf. case-ignorable: MidLetter, MidNumLet or cat is Mn, Me, Cf, Lm or Sk).
|
||||||
// Me, Cf, Lm or Sk).
|
|
||||||
// Rule: Don't break between Letter and Mid, but break between two Mids.
|
// Rule: Don't break between Letter and Mid, but break between two Mids.
|
||||||
//
|
//
|
||||||
// 3) Break:
|
// 3) Break:
|
||||||
// Any other category: NewLine, MidNum, CR, LF, Double_Quote, Katakana, and
|
// Any other category, including NewLine, CR, LF and Double_Quote. These
|
||||||
// Other.
|
// categories should always result in a break between two cased letters.
|
||||||
// These categories should always result in a break between two cased letters.
|
|
||||||
// Rule: Always break.
|
// Rule: Always break.
|
||||||
//
|
//
|
||||||
// Note 1: the Katakana and MidNum categories can, in esoteric cases, result in
|
// Note 1: the Katakana and MidNum categories can, in esoteric cases, result in
|
||||||
|
|
331
vendor/golang.org/x/text/cases/map.go
generated
vendored
331
vendor/golang.org/x/text/cases/map.go
generated
vendored
|
@ -13,7 +13,6 @@ import (
|
||||||
"unicode"
|
"unicode"
|
||||||
"unicode/utf8"
|
"unicode/utf8"
|
||||||
|
|
||||||
"golang.org/x/text/internal"
|
|
||||||
"golang.org/x/text/language"
|
"golang.org/x/text/language"
|
||||||
"golang.org/x/text/transform"
|
"golang.org/x/text/transform"
|
||||||
"golang.org/x/text/unicode/norm"
|
"golang.org/x/text/unicode/norm"
|
||||||
|
@ -25,11 +24,6 @@ import (
|
||||||
// dst so far won't need changing as we see more source bytes.
|
// dst so far won't need changing as we see more source bytes.
|
||||||
type mapFunc func(*context) bool
|
type mapFunc func(*context) bool
|
||||||
|
|
||||||
// A spanFunc takes a context set to the current rune and returns whether this
|
|
||||||
// rune would be altered when written to the output. It may advance the context
|
|
||||||
// to the next rune. It returns whether a checkpoint is possible.
|
|
||||||
type spanFunc func(*context) bool
|
|
||||||
|
|
||||||
// maxIgnorable defines the maximum number of ignorables to consider for
|
// maxIgnorable defines the maximum number of ignorables to consider for
|
||||||
// lookahead operations.
|
// lookahead operations.
|
||||||
const maxIgnorable = 30
|
const maxIgnorable = 30
|
||||||
|
@ -42,12 +36,12 @@ func init() {
|
||||||
for _, s := range strings.Split(supported, " ") {
|
for _, s := range strings.Split(supported, " ") {
|
||||||
tags = append(tags, language.MustParse(s))
|
tags = append(tags, language.MustParse(s))
|
||||||
}
|
}
|
||||||
matcher = internal.NewInheritanceMatcher(tags)
|
matcher = language.NewMatcher(tags)
|
||||||
Supported = language.NewCoverage(tags)
|
Supported = language.NewCoverage(tags)
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
matcher *internal.InheritanceMatcher
|
matcher language.Matcher
|
||||||
|
|
||||||
Supported language.Coverage
|
Supported language.Coverage
|
||||||
|
|
||||||
|
@ -56,69 +50,56 @@ var (
|
||||||
|
|
||||||
// Some uppercase mappers are stateless, so we can precompute the
|
// Some uppercase mappers are stateless, so we can precompute the
|
||||||
// Transformers and save a bit on runtime allocations.
|
// Transformers and save a bit on runtime allocations.
|
||||||
upperFunc = []struct {
|
upperFunc = []mapFunc{
|
||||||
upper mapFunc
|
|
||||||
span spanFunc
|
|
||||||
}{
|
|
||||||
{nil, nil}, // und
|
|
||||||
{nil, nil}, // af
|
|
||||||
{aztrUpper(upper), isUpper}, // az
|
|
||||||
{elUpper, noSpan}, // el
|
|
||||||
{ltUpper(upper), noSpan}, // lt
|
|
||||||
{nil, nil}, // nl
|
|
||||||
{aztrUpper(upper), isUpper}, // tr
|
|
||||||
}
|
|
||||||
|
|
||||||
undUpper transform.SpanningTransformer = &undUpperCaser{}
|
|
||||||
undLower transform.SpanningTransformer = &undLowerCaser{}
|
|
||||||
undLowerIgnoreSigma transform.SpanningTransformer = &undLowerIgnoreSigmaCaser{}
|
|
||||||
|
|
||||||
lowerFunc = []mapFunc{
|
|
||||||
nil, // und
|
nil, // und
|
||||||
nil, // af
|
nil, // af
|
||||||
aztrLower, // az
|
aztrUpper(upper), // az
|
||||||
nil, // el
|
elUpper, // el
|
||||||
ltLower, // lt
|
ltUpper(upper), // lt
|
||||||
nil, // nl
|
nil, // nl
|
||||||
|
aztrUpper(upper), // tr
|
||||||
|
}
|
||||||
|
|
||||||
|
undUpper transform.Transformer = &undUpperCaser{}
|
||||||
|
|
||||||
|
lowerFunc = []mapFunc{
|
||||||
|
lower, // und
|
||||||
|
lower, // af
|
||||||
|
aztrLower, // az
|
||||||
|
lower, // el
|
||||||
|
ltLower, // lt
|
||||||
|
lower, // nl
|
||||||
aztrLower, // tr
|
aztrLower, // tr
|
||||||
}
|
}
|
||||||
|
|
||||||
titleInfos = []struct {
|
titleInfos = []struct {
|
||||||
title mapFunc
|
title, lower mapFunc
|
||||||
lower mapFunc
|
|
||||||
titleSpan spanFunc
|
|
||||||
rewrite func(*context)
|
rewrite func(*context)
|
||||||
}{
|
}{
|
||||||
{title, lower, isTitle, nil}, // und
|
{title, lower, nil}, // und
|
||||||
{title, lower, isTitle, afnlRewrite}, // af
|
{title, lower, afnlRewrite}, // af
|
||||||
{aztrUpper(title), aztrLower, isTitle, nil}, // az
|
{aztrUpper(title), aztrLower, nil}, // az
|
||||||
{title, lower, isTitle, nil}, // el
|
{title, lower, nil}, // el
|
||||||
{ltUpper(title), ltLower, noSpan, nil}, // lt
|
{ltUpper(title), ltLower, nil}, // lt
|
||||||
{nlTitle, lower, nlTitleSpan, afnlRewrite}, // nl
|
{nlTitle, lower, afnlRewrite}, // nl
|
||||||
{aztrUpper(title), aztrLower, isTitle, nil}, // tr
|
{aztrUpper(title), aztrLower, nil}, // tr
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
func makeUpper(t language.Tag, o options) transform.SpanningTransformer {
|
func makeUpper(t language.Tag, o options) transform.Transformer {
|
||||||
_, i, _ := matcher.Match(t)
|
_, i, _ := matcher.Match(t)
|
||||||
f := upperFunc[i].upper
|
f := upperFunc[i]
|
||||||
if f == nil {
|
if f == nil {
|
||||||
return undUpper
|
return undUpper
|
||||||
}
|
}
|
||||||
return &simpleCaser{f: f, span: upperFunc[i].span}
|
return &simpleCaser{f: f}
|
||||||
}
|
}
|
||||||
|
|
||||||
func makeLower(t language.Tag, o options) transform.SpanningTransformer {
|
func makeLower(t language.Tag, o options) transform.Transformer {
|
||||||
_, i, _ := matcher.Match(t)
|
_, i, _ := matcher.Match(t)
|
||||||
f := lowerFunc[i]
|
f := lowerFunc[i]
|
||||||
if f == nil {
|
if o.noFinalSigma {
|
||||||
if o.ignoreFinalSigma {
|
return &simpleCaser{f: f}
|
||||||
return undLowerIgnoreSigma
|
|
||||||
}
|
|
||||||
return undLower
|
|
||||||
}
|
|
||||||
if o.ignoreFinalSigma {
|
|
||||||
return &simpleCaser{f: f, span: isLower}
|
|
||||||
}
|
}
|
||||||
return &lowerCaser{
|
return &lowerCaser{
|
||||||
first: f,
|
first: f,
|
||||||
|
@ -126,28 +107,22 @@ func makeLower(t language.Tag, o options) transform.SpanningTransformer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func makeTitle(t language.Tag, o options) transform.SpanningTransformer {
|
func makeTitle(t language.Tag, o options) transform.Transformer {
|
||||||
_, i, _ := matcher.Match(t)
|
_, i, _ := matcher.Match(t)
|
||||||
x := &titleInfos[i]
|
x := &titleInfos[i]
|
||||||
lower := x.lower
|
lower := x.lower
|
||||||
if o.noLower {
|
if o.noLower {
|
||||||
lower = (*context).copy
|
lower = (*context).copy
|
||||||
} else if !o.ignoreFinalSigma {
|
} else if !o.noFinalSigma {
|
||||||
lower = finalSigma(lower)
|
lower = finalSigma(lower)
|
||||||
}
|
}
|
||||||
return &titleCaser{
|
return &titleCaser{
|
||||||
title: x.title,
|
title: x.title,
|
||||||
lower: lower,
|
lower: lower,
|
||||||
titleSpan: x.titleSpan,
|
|
||||||
rewrite: x.rewrite,
|
rewrite: x.rewrite,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func noSpan(c *context) bool {
|
|
||||||
c.err = transform.ErrEndOfSpan
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: consider a similar special case for the fast majority lower case. This
|
// TODO: consider a similar special case for the fast majority lower case. This
|
||||||
// is a bit more involved so will require some more precise benchmarking to
|
// is a bit more involved so will require some more precise benchmarking to
|
||||||
// justify it.
|
// justify it.
|
||||||
|
@ -157,7 +132,7 @@ type undUpperCaser struct{ transform.NopResetter }
|
||||||
// undUpperCaser implements the Transformer interface for doing an upper case
|
// undUpperCaser implements the Transformer interface for doing an upper case
|
||||||
// mapping for the root locale (und). It eliminates the need for an allocation
|
// mapping for the root locale (und). It eliminates the need for an allocation
|
||||||
// as it prevents escaping by not using function pointers.
|
// as it prevents escaping by not using function pointers.
|
||||||
func (t undUpperCaser) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
|
func (t *undUpperCaser) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
|
||||||
c := context{dst: dst, src: src, atEOF: atEOF}
|
c := context{dst: dst, src: src, atEOF: atEOF}
|
||||||
for c.next() {
|
for c.next() {
|
||||||
upper(&c)
|
upper(&c)
|
||||||
|
@ -166,117 +141,26 @@ func (t undUpperCaser) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, e
|
||||||
return c.ret()
|
return c.ret()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t undUpperCaser) Span(src []byte, atEOF bool) (n int, err error) {
|
|
||||||
c := context{src: src, atEOF: atEOF}
|
|
||||||
for c.next() && isUpper(&c) {
|
|
||||||
c.checkpoint()
|
|
||||||
}
|
|
||||||
return c.retSpan()
|
|
||||||
}
|
|
||||||
|
|
||||||
// undLowerIgnoreSigmaCaser implements the Transformer interface for doing
|
|
||||||
// a lower case mapping for the root locale (und) ignoring final sigma
|
|
||||||
// handling. This casing algorithm is used in some performance-critical packages
|
|
||||||
// like secure/precis and x/net/http/idna, which warrants its special-casing.
|
|
||||||
type undLowerIgnoreSigmaCaser struct{ transform.NopResetter }
|
|
||||||
|
|
||||||
func (t undLowerIgnoreSigmaCaser) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
|
|
||||||
c := context{dst: dst, src: src, atEOF: atEOF}
|
|
||||||
for c.next() && lower(&c) {
|
|
||||||
c.checkpoint()
|
|
||||||
}
|
|
||||||
return c.ret()
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Span implements a generic lower-casing. This is possible as isLower works
|
|
||||||
// for all lowercasing variants. All lowercase variants only vary in how they
|
|
||||||
// transform a non-lowercase letter. They will never change an already lowercase
|
|
||||||
// letter. In addition, there is no state.
|
|
||||||
func (t undLowerIgnoreSigmaCaser) Span(src []byte, atEOF bool) (n int, err error) {
|
|
||||||
c := context{src: src, atEOF: atEOF}
|
|
||||||
for c.next() && isLower(&c) {
|
|
||||||
c.checkpoint()
|
|
||||||
}
|
|
||||||
return c.retSpan()
|
|
||||||
}
|
|
||||||
|
|
||||||
type simpleCaser struct {
|
type simpleCaser struct {
|
||||||
context
|
context
|
||||||
f mapFunc
|
f mapFunc
|
||||||
span spanFunc
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// simpleCaser implements the Transformer interface for doing a case operation
|
// simpleCaser implements the Transformer interface for doing a case operation
|
||||||
// on a rune-by-rune basis.
|
// on a rune-by-rune basis.
|
||||||
func (t *simpleCaser) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
|
func (t *simpleCaser) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
|
||||||
c := context{dst: dst, src: src, atEOF: atEOF}
|
t.context = context{dst: dst, src: src, atEOF: atEOF}
|
||||||
for c.next() && t.f(&c) {
|
c := &t.context
|
||||||
|
for c.next() && t.f(c) {
|
||||||
c.checkpoint()
|
c.checkpoint()
|
||||||
}
|
}
|
||||||
return c.ret()
|
return c.ret()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *simpleCaser) Span(src []byte, atEOF bool) (n int, err error) {
|
|
||||||
c := context{src: src, atEOF: atEOF}
|
|
||||||
for c.next() && t.span(&c) {
|
|
||||||
c.checkpoint()
|
|
||||||
}
|
|
||||||
return c.retSpan()
|
|
||||||
}
|
|
||||||
|
|
||||||
// undLowerCaser implements the Transformer interface for doing a lower case
|
|
||||||
// mapping for the root locale (und) ignoring final sigma handling. This casing
|
|
||||||
// algorithm is used in some performance-critical packages like secure/precis
|
|
||||||
// and x/net/http/idna, which warrants its special-casing.
|
|
||||||
type undLowerCaser struct{ transform.NopResetter }
|
|
||||||
|
|
||||||
func (t undLowerCaser) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
|
|
||||||
c := context{dst: dst, src: src, atEOF: atEOF}
|
|
||||||
|
|
||||||
for isInterWord := true; c.next(); {
|
|
||||||
if isInterWord {
|
|
||||||
if c.info.isCased() {
|
|
||||||
if !lower(&c) {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
isInterWord = false
|
|
||||||
} else if !c.copy() {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if c.info.isNotCasedAndNotCaseIgnorable() {
|
|
||||||
if !c.copy() {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
isInterWord = true
|
|
||||||
} else if !c.hasPrefix("Σ") {
|
|
||||||
if !lower(&c) {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
} else if !finalSigmaBody(&c) {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
c.checkpoint()
|
|
||||||
}
|
|
||||||
return c.ret()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t undLowerCaser) Span(src []byte, atEOF bool) (n int, err error) {
|
|
||||||
c := context{src: src, atEOF: atEOF}
|
|
||||||
for c.next() && isLower(&c) {
|
|
||||||
c.checkpoint()
|
|
||||||
}
|
|
||||||
return c.retSpan()
|
|
||||||
}
|
|
||||||
|
|
||||||
// lowerCaser implements the Transformer interface. The default Unicode lower
|
// lowerCaser implements the Transformer interface. The default Unicode lower
|
||||||
// casing requires different treatment for the first and subsequent characters
|
// casing requires different treatment for the first and subsequent characters
|
||||||
// of a word, most notably to handle the Greek final Sigma.
|
// of a word, most notably to handle the Greek final Sigma.
|
||||||
type lowerCaser struct {
|
type lowerCaser struct {
|
||||||
undLowerIgnoreSigmaCaser
|
|
||||||
|
|
||||||
context
|
context
|
||||||
|
|
||||||
first, midWord mapFunc
|
first, midWord mapFunc
|
||||||
|
@ -318,9 +202,7 @@ type titleCaser struct {
|
||||||
context
|
context
|
||||||
|
|
||||||
// rune mappings used by the actual casing algorithms.
|
// rune mappings used by the actual casing algorithms.
|
||||||
title mapFunc
|
title, lower mapFunc
|
||||||
lower mapFunc
|
|
||||||
titleSpan spanFunc
|
|
||||||
|
|
||||||
rewrite func(*context)
|
rewrite func(*context)
|
||||||
}
|
}
|
||||||
|
@ -346,10 +228,10 @@ func (t *titleCaser) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err
|
||||||
t.rewrite(c)
|
t.rewrite(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
wasMid := p.isMid()
|
wasMid := p.isCaseIgnorableAndNonBreakStarter()
|
||||||
// Break out of this loop on failure to ensure we do not modify the
|
// Break out of this loop on failure to ensure we do not modify the
|
||||||
// state incorrectly.
|
// state incorrectly.
|
||||||
if p.isCased() {
|
if p.isCased() && !p.isCaseIgnorableAndNotCased() {
|
||||||
if !c.isMidWord {
|
if !c.isMidWord {
|
||||||
if !t.title(c) {
|
if !t.title(c) {
|
||||||
break
|
break
|
||||||
|
@ -360,86 +242,33 @@ func (t *titleCaser) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err
|
||||||
}
|
}
|
||||||
} else if !c.copy() {
|
} else if !c.copy() {
|
||||||
break
|
break
|
||||||
} else if p.isBreak() {
|
}
|
||||||
|
|
||||||
|
// TODO: make this an "else if" if we can prove that no rune that does
|
||||||
|
// not match the first condition of the if statement can be a break.
|
||||||
|
if p.isBreak() {
|
||||||
c.isMidWord = false
|
c.isMidWord = false
|
||||||
}
|
}
|
||||||
|
|
||||||
// As we save the state of the transformer, it is safe to call
|
// As we save the state of the transformer, it is safe to call
|
||||||
// checkpoint after any successful write.
|
// checkpoint after any successful write.
|
||||||
if !(c.isMidWord && wasMid) {
|
|
||||||
c.checkpoint()
|
c.checkpoint()
|
||||||
}
|
|
||||||
|
|
||||||
if !c.next() {
|
if !c.next() {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
if wasMid && c.info.isMid() {
|
if wasMid && c.info.isCaseIgnorableAndNonBreakStarter() {
|
||||||
c.isMidWord = false
|
c.isMidWord = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return c.ret()
|
return c.ret()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *titleCaser) Span(src []byte, atEOF bool) (n int, err error) {
|
|
||||||
t.context = context{src: src, atEOF: atEOF, isMidWord: t.isMidWord}
|
|
||||||
c := &t.context
|
|
||||||
|
|
||||||
if !c.next() {
|
|
||||||
return c.retSpan()
|
|
||||||
}
|
|
||||||
|
|
||||||
for {
|
|
||||||
p := c.info
|
|
||||||
if t.rewrite != nil {
|
|
||||||
t.rewrite(c)
|
|
||||||
}
|
|
||||||
|
|
||||||
wasMid := p.isMid()
|
|
||||||
// Break out of this loop on failure to ensure we do not modify the
|
|
||||||
// state incorrectly.
|
|
||||||
if p.isCased() {
|
|
||||||
if !c.isMidWord {
|
|
||||||
if !t.titleSpan(c) {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
c.isMidWord = true
|
|
||||||
} else if !isLower(c) {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
} else if p.isBreak() {
|
|
||||||
c.isMidWord = false
|
|
||||||
}
|
|
||||||
// As we save the state of the transformer, it is safe to call
|
|
||||||
// checkpoint after any successful write.
|
|
||||||
if !(c.isMidWord && wasMid) {
|
|
||||||
c.checkpoint()
|
|
||||||
}
|
|
||||||
|
|
||||||
if !c.next() {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
if wasMid && c.info.isMid() {
|
|
||||||
c.isMidWord = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return c.retSpan()
|
|
||||||
}
|
|
||||||
|
|
||||||
// finalSigma adds Greek final Sigma handing to another casing function. It
|
// finalSigma adds Greek final Sigma handing to another casing function. It
|
||||||
// determines whether a lowercased sigma should be σ or ς, by looking ahead for
|
// determines whether a lowercased sigma should be σ or ς, by looking ahead for
|
||||||
// case-ignorables and a cased letters.
|
// case-ignorables and a cased letters.
|
||||||
func finalSigma(f mapFunc) mapFunc {
|
func finalSigma(f mapFunc) mapFunc {
|
||||||
return func(c *context) bool {
|
return func(c *context) bool {
|
||||||
if !c.hasPrefix("Σ") {
|
|
||||||
return f(c)
|
|
||||||
}
|
|
||||||
return finalSigmaBody(c)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func finalSigmaBody(c *context) bool {
|
|
||||||
// Current rune must be ∑.
|
|
||||||
|
|
||||||
// ::NFD();
|
// ::NFD();
|
||||||
// # 03A3; 03C2; 03A3; 03A3; Final_Sigma; # GREEK CAPITAL LETTER SIGMA
|
// # 03A3; 03C2; 03A3; 03A3; Final_Sigma; # GREEK CAPITAL LETTER SIGMA
|
||||||
// Σ } [:case-ignorable:]* [:cased:] → σ;
|
// Σ } [:case-ignorable:]* [:cased:] → σ;
|
||||||
|
@ -447,29 +276,19 @@ func finalSigmaBody(c *context) bool {
|
||||||
// ::Any-Lower;
|
// ::Any-Lower;
|
||||||
// ::NFC();
|
// ::NFC();
|
||||||
|
|
||||||
|
if !c.hasPrefix("Σ") {
|
||||||
|
return f(c)
|
||||||
|
}
|
||||||
|
|
||||||
p := c.pDst
|
p := c.pDst
|
||||||
c.writeString("ς")
|
c.writeString("ς")
|
||||||
|
|
||||||
// TODO: we should do this here, but right now this will never have an
|
|
||||||
// effect as this is called when the prefix is Sigma, whereas Dutch and
|
|
||||||
// Afrikaans only test for an apostrophe.
|
|
||||||
//
|
|
||||||
// if t.rewrite != nil {
|
|
||||||
// t.rewrite(c)
|
|
||||||
// }
|
|
||||||
|
|
||||||
// We need to do one more iteration after maxIgnorable, as a cased
|
// We need to do one more iteration after maxIgnorable, as a cased
|
||||||
// letter is not an ignorable and may modify the result.
|
// letter is not an ignorable and may modify the result.
|
||||||
wasMid := false
|
|
||||||
for i := 0; i < maxIgnorable+1; i++ {
|
for i := 0; i < maxIgnorable+1; i++ {
|
||||||
if !c.next() {
|
if !c.next() {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if !c.info.isCaseIgnorable() {
|
if !c.info.isCaseIgnorable() {
|
||||||
// All Midword runes are also case ignorable, so we are
|
|
||||||
// guaranteed to have a letter or word break here. As we are
|
|
||||||
// unreading the run, there is no need to unset c.isMidWord;
|
|
||||||
// the title caser will handle this.
|
|
||||||
if c.info.isCased() {
|
if c.info.isCased() {
|
||||||
// p+1 is guaranteed to be in bounds: if writing ς was
|
// p+1 is guaranteed to be in bounds: if writing ς was
|
||||||
// successful, p+1 will contain the second byte of ς. If not,
|
// successful, p+1 will contain the second byte of ς. If not,
|
||||||
|
@ -481,18 +300,13 @@ func finalSigmaBody(c *context) bool {
|
||||||
}
|
}
|
||||||
// A case ignorable may also introduce a word break, so we may need
|
// A case ignorable may also introduce a word break, so we may need
|
||||||
// to continue searching even after detecting a break.
|
// to continue searching even after detecting a break.
|
||||||
isMid := c.info.isMid()
|
c.isMidWord = c.isMidWord && !c.info.isBreak()
|
||||||
if (wasMid && isMid) || c.info.isBreak() {
|
|
||||||
c.isMidWord = false
|
|
||||||
}
|
|
||||||
wasMid = isMid
|
|
||||||
c.copy()
|
c.copy()
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// finalSigmaSpan would be the same as isLower.
|
|
||||||
|
|
||||||
// elUpper implements Greek upper casing, which entails removing a predefined
|
// elUpper implements Greek upper casing, which entails removing a predefined
|
||||||
// set of non-blocked modifiers. Note that these accents should not be removed
|
// set of non-blocked modifiers. Note that these accents should not be removed
|
||||||
// for title casing!
|
// for title casing!
|
||||||
|
@ -562,8 +376,6 @@ func elUpper(c *context) bool {
|
||||||
return i == maxIgnorable
|
return i == maxIgnorable
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: implement elUpperSpan (low-priority: complex and infrequent).
|
|
||||||
|
|
||||||
func ltLower(c *context) bool {
|
func ltLower(c *context) bool {
|
||||||
// From CLDR:
|
// From CLDR:
|
||||||
// # Introduce an explicit dot above when lowercasing capital I's and J's
|
// # Introduce an explicit dot above when lowercasing capital I's and J's
|
||||||
|
@ -578,10 +390,10 @@ func ltLower(c *context) bool {
|
||||||
// ::NFD();
|
// ::NFD();
|
||||||
// I } [^[:ccc=Not_Reordered:][:ccc=Above:]]* [:ccc=Above:] → i \u0307;
|
// I } [^[:ccc=Not_Reordered:][:ccc=Above:]]* [:ccc=Above:] → i \u0307;
|
||||||
// J } [^[:ccc=Not_Reordered:][:ccc=Above:]]* [:ccc=Above:] → j \u0307;
|
// J } [^[:ccc=Not_Reordered:][:ccc=Above:]]* [:ccc=Above:] → j \u0307;
|
||||||
// I \u0328 (Į) } [^[:ccc=Not_Reordered:][:ccc=Above:]]* [:ccc=Above:] → i \u0328 \u0307;
|
// Į } [^[:ccc=Not_Reordered:][:ccc=Above:]]* [:ccc=Above:] → į \u0307;
|
||||||
// I \u0300 (Ì) → i \u0307 \u0300;
|
// Ì → i \u0307 \u0300;
|
||||||
// I \u0301 (Í) → i \u0307 \u0301;
|
// Í → i \u0307 \u0301;
|
||||||
// I \u0303 (Ĩ) → i \u0307 \u0303;
|
// Ĩ → i \u0307 \u0303;
|
||||||
// ::Any-Lower();
|
// ::Any-Lower();
|
||||||
// ::NFC();
|
// ::NFC();
|
||||||
|
|
||||||
|
@ -633,16 +445,9 @@ func ltLower(c *context) bool {
|
||||||
return i == maxIgnorable
|
return i == maxIgnorable
|
||||||
}
|
}
|
||||||
|
|
||||||
// ltLowerSpan would be the same as isLower.
|
|
||||||
|
|
||||||
func ltUpper(f mapFunc) mapFunc {
|
func ltUpper(f mapFunc) mapFunc {
|
||||||
return func(c *context) bool {
|
return func(c *context) bool {
|
||||||
// Unicode:
|
|
||||||
// 0307; 0307; ; ; lt After_Soft_Dotted; # COMBINING DOT ABOVE
|
|
||||||
//
|
|
||||||
// From CLDR:
|
// From CLDR:
|
||||||
// # Remove \u0307 following soft-dotteds (i, j, and the like), with possible
|
|
||||||
// # intervening non-230 marks.
|
|
||||||
// ::NFD();
|
// ::NFD();
|
||||||
// [:Soft_Dotted:] [^[:ccc=Not_Reordered:][:ccc=Above:]]* { \u0307 → ;
|
// [:Soft_Dotted:] [^[:ccc=Not_Reordered:][:ccc=Above:]]* { \u0307 → ;
|
||||||
// ::Any-Upper();
|
// ::Any-Upper();
|
||||||
|
@ -706,8 +511,6 @@ func ltUpper(f mapFunc) mapFunc {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: implement ltUpperSpan (low priority: complex and infrequent).
|
|
||||||
|
|
||||||
func aztrUpper(f mapFunc) mapFunc {
|
func aztrUpper(f mapFunc) mapFunc {
|
||||||
return func(c *context) bool {
|
return func(c *context) bool {
|
||||||
// i→İ;
|
// i→İ;
|
||||||
|
@ -768,8 +571,6 @@ Loop:
|
||||||
return c.writeString("ı") && c.writeBytes(c.src[start:c.pSrc+c.sz]) && done
|
return c.writeString("ı") && c.writeBytes(c.src[start:c.pSrc+c.sz]) && done
|
||||||
}
|
}
|
||||||
|
|
||||||
// aztrLowerSpan would be the same as isLower.
|
|
||||||
|
|
||||||
func nlTitle(c *context) bool {
|
func nlTitle(c *context) bool {
|
||||||
// From CLDR:
|
// From CLDR:
|
||||||
// # Special titlecasing for Dutch initial "ij".
|
// # Special titlecasing for Dutch initial "ij".
|
||||||
|
@ -790,24 +591,6 @@ func nlTitle(c *context) bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func nlTitleSpan(c *context) bool {
|
|
||||||
// From CLDR:
|
|
||||||
// # Special titlecasing for Dutch initial "ij".
|
|
||||||
// ::Any-Title();
|
|
||||||
// # Fix up Ij at the beginning of a "word" (per Any-Title, notUAX #29)
|
|
||||||
// [:^WB=ALetter:] [:WB=Extend:]* [[:WB=MidLetter:][:WB=MidNumLet:]]? { Ij } → IJ ;
|
|
||||||
if c.src[c.pSrc] != 'I' {
|
|
||||||
return isTitle(c)
|
|
||||||
}
|
|
||||||
if !c.next() || c.src[c.pSrc] == 'j' {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if c.src[c.pSrc] != 'J' {
|
|
||||||
c.unreadRune()
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// Not part of CLDR, but see http://unicode.org/cldr/trac/ticket/7078.
|
// Not part of CLDR, but see http://unicode.org/cldr/trac/ticket/7078.
|
||||||
func afnlRewrite(c *context) {
|
func afnlRewrite(c *context) {
|
||||||
if c.hasPrefix("'") || c.hasPrefix("’") {
|
if c.hasPrefix("'") || c.hasPrefix("’") {
|
||||||
|
|
388
vendor/golang.org/x/text/cases/tables.go
generated
vendored
388
vendor/golang.org/x/text/cases/tables.go
generated
vendored
File diff suppressed because it is too large
Load diff
12
vendor/golang.org/x/text/cases/trieval.go
generated
vendored
12
vendor/golang.org/x/text/cases/trieval.go
generated
vendored
|
@ -22,7 +22,6 @@ package cases
|
||||||
// Only 13..8 are used for XOR patterns.
|
// Only 13..8 are used for XOR patterns.
|
||||||
// 7 inverseFold (fold to upper, not to lower)
|
// 7 inverseFold (fold to upper, not to lower)
|
||||||
// 6 index: interpret the XOR pattern as an index
|
// 6 index: interpret the XOR pattern as an index
|
||||||
// or isMid if case mode is cIgnorableUncased.
|
|
||||||
// 5..4 CCC: zero (normal or break), above or other
|
// 5..4 CCC: zero (normal or break), above or other
|
||||||
// }
|
// }
|
||||||
// 3 exception: interpret this value as an exception index
|
// 3 exception: interpret this value as an exception index
|
||||||
|
@ -45,7 +44,6 @@ const (
|
||||||
ignorableValue = 0x0004
|
ignorableValue = 0x0004
|
||||||
|
|
||||||
inverseFoldBit = 1 << 7
|
inverseFoldBit = 1 << 7
|
||||||
isMidBit = 1 << 6
|
|
||||||
|
|
||||||
exceptionBit = 1 << 3
|
exceptionBit = 1 << 3
|
||||||
exceptionShift = 5
|
exceptionShift = 5
|
||||||
|
@ -55,7 +53,7 @@ const (
|
||||||
xorShift = 8
|
xorShift = 8
|
||||||
|
|
||||||
// There is no mapping if all xor bits and the exception bit are zero.
|
// There is no mapping if all xor bits and the exception bit are zero.
|
||||||
hasMappingMask = 0xff80 | exceptionBit
|
hasMappingMask = 0xffc0 | exceptionBit
|
||||||
)
|
)
|
||||||
|
|
||||||
// The case mode bits encodes the case type of a rune. This includes uncased,
|
// The case mode bits encodes the case type of a rune. This includes uncased,
|
||||||
|
@ -93,6 +91,10 @@ func (c info) isCaseIgnorable() bool {
|
||||||
return c&ignorableMask == ignorableValue
|
return c&ignorableMask == ignorableValue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c info) isCaseIgnorableAndNonBreakStarter() bool {
|
||||||
|
return c&(fullCasedMask|cccMask) == (ignorableValue | cccZero)
|
||||||
|
}
|
||||||
|
|
||||||
func (c info) isNotCasedAndNotCaseIgnorable() bool {
|
func (c info) isNotCasedAndNotCaseIgnorable() bool {
|
||||||
return c&fullCasedMask == 0
|
return c&fullCasedMask == 0
|
||||||
}
|
}
|
||||||
|
@ -101,10 +103,6 @@ func (c info) isCaseIgnorableAndNotCased() bool {
|
||||||
return c&fullCasedMask == cIgnorableUncased
|
return c&fullCasedMask == cIgnorableUncased
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c info) isMid() bool {
|
|
||||||
return c&(fullCasedMask|isMidBit) == isMidBit|cIgnorableUncased
|
|
||||||
}
|
|
||||||
|
|
||||||
// The case mapping implementation will need to know about various Canonical
|
// The case mapping implementation will need to know about various Canonical
|
||||||
// Combining Class (CCC) values. We encode two of these in the trie value:
|
// Combining Class (CCC) values. We encode two of these in the trie value:
|
||||||
// cccZero (0) and cccAbove (230). If the value is cccOther, it means that
|
// cccZero (0) and cccAbove (230). If the value is cccOther, it means that
|
||||||
|
|
77
vendor/golang.org/x/text/gen.go
generated
vendored
77
vendor/golang.org/x/text/gen.go
generated
vendored
|
@ -12,8 +12,6 @@ import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"go/build"
|
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
@ -28,7 +26,6 @@ import (
|
||||||
var (
|
var (
|
||||||
verbose = flag.Bool("v", false, "verbose output")
|
verbose = flag.Bool("v", false, "verbose output")
|
||||||
force = flag.Bool("force", false, "ignore failing dependencies")
|
force = flag.Bool("force", false, "ignore failing dependencies")
|
||||||
doCore = flag.Bool("core", false, "force an update to core")
|
|
||||||
excludeList = flag.String("exclude", "",
|
excludeList = flag.String("exclude", "",
|
||||||
"comma-separated list of packages to exclude")
|
"comma-separated list of packages to exclude")
|
||||||
|
|
||||||
|
@ -64,7 +61,6 @@ func main() {
|
||||||
// variable. This will prevent duplicate downloads and also will enable long
|
// variable. This will prevent duplicate downloads and also will enable long
|
||||||
// tests, which really need to be run after each generated package.
|
// tests, which really need to be run after each generated package.
|
||||||
|
|
||||||
updateCore := *doCore
|
|
||||||
if gen.UnicodeVersion() != unicode.Version {
|
if gen.UnicodeVersion() != unicode.Version {
|
||||||
fmt.Printf("Requested Unicode version %s; core unicode version is %s.\n",
|
fmt.Printf("Requested Unicode version %s; core unicode version is %s.\n",
|
||||||
gen.UnicodeVersion(),
|
gen.UnicodeVersion(),
|
||||||
|
@ -76,44 +72,24 @@ func main() {
|
||||||
if gen.UnicodeVersion() < unicode.Version && !*force {
|
if gen.UnicodeVersion() < unicode.Version && !*force {
|
||||||
os.Exit(2)
|
os.Exit(2)
|
||||||
}
|
}
|
||||||
updateCore = true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var unicode = &dependency{}
|
|
||||||
if updateCore {
|
|
||||||
fmt.Printf("Updating core to version %s...\n", gen.UnicodeVersion())
|
|
||||||
unicode = generate("unicode")
|
|
||||||
|
|
||||||
// Test some users of the unicode packages, especially the ones that
|
|
||||||
// keep a mirrored table. These may need to be corrected by hand.
|
|
||||||
generate("regexp", unicode)
|
|
||||||
generate("strconv", unicode) // mimics Unicode table
|
|
||||||
generate("strings", unicode)
|
|
||||||
generate("testing", unicode) // mimics Unicode table
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
var (
|
||||||
cldr = generate("./unicode/cldr", unicode)
|
cldr = generate("unicode/cldr")
|
||||||
language = generate("./language", cldr)
|
language = generate("language", cldr)
|
||||||
internal = generate("./internal", unicode, language)
|
internal = generate("internal", language)
|
||||||
norm = generate("./unicode/norm", unicode)
|
norm = generate("unicode/norm")
|
||||||
rangetable = generate("./unicode/rangetable", unicode)
|
rangetable = generate("unicode/rangetable")
|
||||||
cases = generate("./cases", unicode, norm, language, rangetable)
|
cases = generate("cases", norm, language, rangetable)
|
||||||
width = generate("./width", unicode)
|
width = generate("width")
|
||||||
bidi = generate("./unicode/bidi", unicode, norm, rangetable)
|
bidi = generate("unicode/bidi", norm, rangetable)
|
||||||
_ = generate("./secure/precis", unicode, norm, rangetable, cases, width, bidi)
|
_ = generate("secure/precis", norm, rangetable, cases, width, bidi)
|
||||||
_ = generate("./encoding/htmlindex", unicode, language)
|
_ = generate("encoding/htmlindex", language)
|
||||||
_ = generate("./currency", unicode, cldr, language, internal)
|
_ = generate("currency", cldr, language, internal)
|
||||||
_ = generate("./internal/number", unicode, cldr, language, internal)
|
_ = generate("internal/number", cldr, language, internal)
|
||||||
_ = generate("./language/display", unicode, cldr, language, internal)
|
_ = generate("language/display", cldr, language)
|
||||||
_ = generate("./collate", unicode, norm, cldr, language, rangetable)
|
_ = generate("collate", norm, cldr, language, rangetable)
|
||||||
_ = generate("./search", unicode, norm, cldr, language, rangetable)
|
_ = generate("search", norm, cldr, language, rangetable)
|
||||||
)
|
)
|
||||||
|
|
||||||
if updateCore {
|
|
||||||
copyVendored()
|
|
||||||
generate("vendor/golang_org/x/net/idna", unicode, norm, width, cases)
|
|
||||||
}
|
|
||||||
all.Wait()
|
all.Wait()
|
||||||
|
|
||||||
if hasErrors {
|
if hasErrors {
|
||||||
|
@ -157,7 +133,7 @@ func generate(pkg string, deps ...*dependency) *dependency {
|
||||||
if *verbose {
|
if *verbose {
|
||||||
args = append(args, "-v")
|
args = append(args, "-v")
|
||||||
}
|
}
|
||||||
args = append(args, pkg)
|
args = append(args, "./"+pkg)
|
||||||
cmd := exec.Command(filepath.Join(runtime.GOROOT(), "bin", "go"), args...)
|
cmd := exec.Command(filepath.Join(runtime.GOROOT(), "bin", "go"), args...)
|
||||||
w := &bytes.Buffer{}
|
w := &bytes.Buffer{}
|
||||||
cmd.Stderr = w
|
cmd.Stderr = w
|
||||||
|
@ -187,27 +163,6 @@ func generate(pkg string, deps ...*dependency) *dependency {
|
||||||
return &wg
|
return &wg
|
||||||
}
|
}
|
||||||
|
|
||||||
func copyVendored() {
|
|
||||||
// Copy the vendored files. Some more may need to be copied in by hand.
|
|
||||||
dir := filepath.Join(build.Default.GOROOT, "src/vendor/golang_org/x/text")
|
|
||||||
err := filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
|
|
||||||
if info.IsDir() {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
b, err := ioutil.ReadFile(path[len(dir)+1:])
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
vprintf("=== COPY %s\n", path)
|
|
||||||
b = bytes.Replace(b, []byte("golang.org"), []byte("golang_org"), -1)
|
|
||||||
return ioutil.WriteFile(path, b, 0666)
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println("Copying vendored files failed:", err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func contains(a []string, s string) bool {
|
func contains(a []string, s string) bool {
|
||||||
for _, e := range a {
|
for _, e := range a {
|
||||||
if s == e {
|
if s == e {
|
||||||
|
|
52
vendor/golang.org/x/text/internal/gen.go
generated
vendored
52
vendor/golang.org/x/text/internal/gen.go
generated
vendored
|
@ -1,52 +0,0 @@
|
||||||
// Copyright 2015 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build ignore
|
|
||||||
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"log"
|
|
||||||
|
|
||||||
"golang.org/x/text/internal/gen"
|
|
||||||
"golang.org/x/text/language"
|
|
||||||
"golang.org/x/text/unicode/cldr"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
r := gen.OpenCLDRCoreZip()
|
|
||||||
defer r.Close()
|
|
||||||
|
|
||||||
d := &cldr.Decoder{}
|
|
||||||
data, err := d.DecodeZip(r)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("DecodeZip: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
w := gen.NewCodeWriter()
|
|
||||||
defer w.WriteGoFile("tables.go", "internal")
|
|
||||||
|
|
||||||
// Create parents table.
|
|
||||||
parents := make([]uint16, language.NumCompactTags)
|
|
||||||
for _, loc := range data.Locales() {
|
|
||||||
tag := language.MustParse(loc)
|
|
||||||
index, ok := language.CompactIndex(tag)
|
|
||||||
if !ok {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
parentIndex := 0 // und
|
|
||||||
for p := tag.Parent(); p != language.Und; p = p.Parent() {
|
|
||||||
if x, ok := language.CompactIndex(p); ok {
|
|
||||||
parentIndex = x
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
parents[index] = uint16(parentIndex)
|
|
||||||
}
|
|
||||||
|
|
||||||
w.WriteComment(`
|
|
||||||
Parent maps a compact index of a tag to the compact index of the parent of
|
|
||||||
this tag.`)
|
|
||||||
w.WriteVar("Parent", parents)
|
|
||||||
}
|
|
51
vendor/golang.org/x/text/internal/internal.go
generated
vendored
51
vendor/golang.org/x/text/internal/internal.go
generated
vendored
|
@ -1,51 +0,0 @@
|
||||||
// Copyright 2015 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
//go:generate go run gen.go
|
|
||||||
|
|
||||||
// Package internal contains non-exported functionality that are used by
|
|
||||||
// packages in the text repository.
|
|
||||||
package internal // import "golang.org/x/text/internal"
|
|
||||||
|
|
||||||
import (
|
|
||||||
"sort"
|
|
||||||
|
|
||||||
"golang.org/x/text/language"
|
|
||||||
)
|
|
||||||
|
|
||||||
// SortTags sorts tags in place.
|
|
||||||
func SortTags(tags []language.Tag) {
|
|
||||||
sort.Sort(sorter(tags))
|
|
||||||
}
|
|
||||||
|
|
||||||
type sorter []language.Tag
|
|
||||||
|
|
||||||
func (s sorter) Len() int {
|
|
||||||
return len(s)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s sorter) Swap(i, j int) {
|
|
||||||
s[i], s[j] = s[j], s[i]
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s sorter) Less(i, j int) bool {
|
|
||||||
return s[i].String() < s[j].String()
|
|
||||||
}
|
|
||||||
|
|
||||||
// UniqueTags sorts and filters duplicate tags in place and returns a slice with
|
|
||||||
// only unique tags.
|
|
||||||
func UniqueTags(tags []language.Tag) []language.Tag {
|
|
||||||
if len(tags) <= 1 {
|
|
||||||
return tags
|
|
||||||
}
|
|
||||||
SortTags(tags)
|
|
||||||
k := 0
|
|
||||||
for i := 1; i < len(tags); i++ {
|
|
||||||
if tags[k].String() < tags[i].String() {
|
|
||||||
k++
|
|
||||||
tags[k] = tags[i]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return tags[:k+1]
|
|
||||||
}
|
|
67
vendor/golang.org/x/text/internal/match.go
generated
vendored
67
vendor/golang.org/x/text/internal/match.go
generated
vendored
|
@ -1,67 +0,0 @@
|
||||||
// Copyright 2015 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package internal
|
|
||||||
|
|
||||||
// This file contains matchers that implement CLDR inheritance.
|
|
||||||
//
|
|
||||||
// See http://unicode.org/reports/tr35/#Locale_Inheritance.
|
|
||||||
//
|
|
||||||
// Some of the inheritance described in this document is already handled by
|
|
||||||
// the cldr package.
|
|
||||||
|
|
||||||
import (
|
|
||||||
"golang.org/x/text/language"
|
|
||||||
)
|
|
||||||
|
|
||||||
// TODO: consider if (some of the) matching algorithm needs to be public after
|
|
||||||
// getting some feel about what is generic and what is specific.
|
|
||||||
|
|
||||||
// NewInheritanceMatcher returns a matcher that matches based on the inheritance
|
|
||||||
// chain.
|
|
||||||
//
|
|
||||||
// The matcher uses canonicalization and the parent relationship to find a
|
|
||||||
// match. The resulting match will always be either Und or a language with the
|
|
||||||
// same language and script as the requested language. It will not match
|
|
||||||
// languages for which there is understood to be mutual or one-directional
|
|
||||||
// intelligibility.
|
|
||||||
//
|
|
||||||
// A Match will indicate an Exact match if the language matches after
|
|
||||||
// canonicalization and High if the matched tag is a parent.
|
|
||||||
func NewInheritanceMatcher(t []language.Tag) *InheritanceMatcher {
|
|
||||||
tags := &InheritanceMatcher{make(map[language.Tag]int)}
|
|
||||||
for i, tag := range t {
|
|
||||||
ct, err := language.All.Canonicalize(tag)
|
|
||||||
if err != nil {
|
|
||||||
ct = tag
|
|
||||||
}
|
|
||||||
tags.index[ct] = i
|
|
||||||
}
|
|
||||||
return tags
|
|
||||||
}
|
|
||||||
|
|
||||||
type InheritanceMatcher struct {
|
|
||||||
index map[language.Tag]int
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m InheritanceMatcher) Match(want ...language.Tag) (language.Tag, int, language.Confidence) {
|
|
||||||
for _, t := range want {
|
|
||||||
ct, err := language.All.Canonicalize(t)
|
|
||||||
if err != nil {
|
|
||||||
ct = t
|
|
||||||
}
|
|
||||||
conf := language.Exact
|
|
||||||
for {
|
|
||||||
if index, ok := m.index[ct]; ok {
|
|
||||||
return ct, index, conf
|
|
||||||
}
|
|
||||||
if ct == language.Und {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
ct = ct.Parent()
|
|
||||||
conf = language.High
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return language.Und, 0, language.No
|
|
||||||
}
|
|
116
vendor/golang.org/x/text/internal/tables.go
generated
vendored
116
vendor/golang.org/x/text/internal/tables.go
generated
vendored
|
@ -1,116 +0,0 @@
|
||||||
// This file was generated by go generate; DO NOT EDIT
|
|
||||||
|
|
||||||
package internal
|
|
||||||
|
|
||||||
// Parent maps a compact index of a tag to the compact index of the parent of
|
|
||||||
// this tag.
|
|
||||||
var Parent = []uint16{ // 752 elements
|
|
||||||
// Entry 0 - 3F
|
|
||||||
0x0000, 0x0053, 0x00e5, 0x0000, 0x0003, 0x0003, 0x0000, 0x0006,
|
|
||||||
0x0000, 0x0008, 0x0000, 0x000a, 0x0000, 0x000c, 0x000c, 0x000c,
|
|
||||||
0x000c, 0x000c, 0x000c, 0x000c, 0x000c, 0x000c, 0x000c, 0x000c,
|
|
||||||
0x000c, 0x000c, 0x000c, 0x000c, 0x000c, 0x000c, 0x000c, 0x000c,
|
|
||||||
0x000c, 0x000c, 0x000c, 0x000c, 0x000c, 0x000c, 0x000c, 0x000c,
|
|
||||||
0x000c, 0x0000, 0x0000, 0x002a, 0x0000, 0x002c, 0x0000, 0x002e,
|
|
||||||
0x0000, 0x0000, 0x0031, 0x0030, 0x0030, 0x0000, 0x0035, 0x0000,
|
|
||||||
0x0037, 0x0000, 0x0039, 0x0000, 0x003b, 0x0000, 0x003d, 0x0000,
|
|
||||||
// Entry 40 - 7F
|
|
||||||
0x0000, 0x0040, 0x0000, 0x0042, 0x0042, 0x0000, 0x0045, 0x0045,
|
|
||||||
0x0000, 0x0048, 0x0000, 0x004a, 0x0000, 0x0000, 0x004d, 0x004c,
|
|
||||||
0x004c, 0x0000, 0x0051, 0x0051, 0x0051, 0x0051, 0x0000, 0x0056,
|
|
||||||
0x0000, 0x0058, 0x0000, 0x005a, 0x0000, 0x005c, 0x005c, 0x0000,
|
|
||||||
0x005f, 0x0000, 0x0061, 0x0000, 0x0063, 0x0000, 0x0065, 0x0065,
|
|
||||||
0x0000, 0x0068, 0x0000, 0x006a, 0x006a, 0x006a, 0x006a, 0x006a,
|
|
||||||
0x006a, 0x006a, 0x0000, 0x0072, 0x0000, 0x0074, 0x0000, 0x0076,
|
|
||||||
0x0000, 0x0000, 0x0079, 0x0000, 0x007b, 0x0000, 0x007d, 0x0000,
|
|
||||||
// Entry 80 - BF
|
|
||||||
0x007f, 0x007f, 0x0000, 0x0082, 0x0082, 0x0000, 0x0085, 0x0086,
|
|
||||||
0x0086, 0x0086, 0x0085, 0x0087, 0x0086, 0x0086, 0x0086, 0x0085,
|
|
||||||
0x0086, 0x0086, 0x0086, 0x0086, 0x0086, 0x0086, 0x0087, 0x0086,
|
|
||||||
0x0086, 0x0086, 0x0086, 0x0087, 0x0086, 0x0087, 0x0086, 0x0086,
|
|
||||||
0x0087, 0x0086, 0x0086, 0x0086, 0x0086, 0x0086, 0x0086, 0x0086,
|
|
||||||
0x0086, 0x0086, 0x0085, 0x0086, 0x0086, 0x0086, 0x0086, 0x0086,
|
|
||||||
0x0086, 0x0086, 0x0086, 0x0086, 0x0086, 0x0086, 0x0086, 0x0086,
|
|
||||||
0x0086, 0x0086, 0x0086, 0x0086, 0x0085, 0x0086, 0x0085, 0x0086,
|
|
||||||
// Entry C0 - FF
|
|
||||||
0x0086, 0x0086, 0x0086, 0x0086, 0x0086, 0x0086, 0x0086, 0x0087,
|
|
||||||
0x0086, 0x0086, 0x0086, 0x0086, 0x0086, 0x0086, 0x0086, 0x0085,
|
|
||||||
0x0086, 0x0086, 0x0086, 0x0086, 0x0086, 0x0087, 0x0086, 0x0086,
|
|
||||||
0x0087, 0x0086, 0x0086, 0x0086, 0x0086, 0x0086, 0x0086, 0x0086,
|
|
||||||
0x0086, 0x0086, 0x0086, 0x0086, 0x0085, 0x0085, 0x0086, 0x0086,
|
|
||||||
0x0085, 0x0086, 0x0086, 0x0086, 0x0086, 0x0086, 0x0000, 0x00ee,
|
|
||||||
0x0000, 0x00f0, 0x00f1, 0x00f1, 0x00f1, 0x00f1, 0x00f1, 0x00f1,
|
|
||||||
0x00f1, 0x00f1, 0x00f0, 0x00f1, 0x00f0, 0x00f0, 0x00f1, 0x00f1,
|
|
||||||
// Entry 100 - 13F
|
|
||||||
0x00f0, 0x00f1, 0x00f1, 0x00f1, 0x00f1, 0x00f0, 0x00f1, 0x00f1,
|
|
||||||
0x00f1, 0x00f1, 0x00f1, 0x00f1, 0x0000, 0x010c, 0x0000, 0x010e,
|
|
||||||
0x0000, 0x0110, 0x0000, 0x0112, 0x0112, 0x0000, 0x0115, 0x0115,
|
|
||||||
0x0115, 0x0115, 0x0000, 0x011a, 0x0000, 0x011c, 0x0000, 0x011e,
|
|
||||||
0x011e, 0x0000, 0x0121, 0x0121, 0x0121, 0x0121, 0x0121, 0x0121,
|
|
||||||
0x0121, 0x0121, 0x0121, 0x0121, 0x0121, 0x0121, 0x0121, 0x0121,
|
|
||||||
0x0121, 0x0121, 0x0121, 0x0121, 0x0121, 0x0121, 0x0121, 0x0121,
|
|
||||||
0x0121, 0x0121, 0x0121, 0x0121, 0x0121, 0x0121, 0x0121, 0x0121,
|
|
||||||
// Entry 140 - 17F
|
|
||||||
0x0121, 0x0121, 0x0121, 0x0121, 0x0121, 0x0121, 0x0121, 0x0121,
|
|
||||||
0x0121, 0x0121, 0x0121, 0x0121, 0x0121, 0x0121, 0x0121, 0x0121,
|
|
||||||
0x0000, 0x0150, 0x0000, 0x0152, 0x0000, 0x0154, 0x0000, 0x0156,
|
|
||||||
0x0000, 0x0158, 0x0000, 0x015a, 0x015a, 0x015a, 0x0000, 0x015e,
|
|
||||||
0x0000, 0x0000, 0x0161, 0x0000, 0x0163, 0x0000, 0x0165, 0x0165,
|
|
||||||
0x0165, 0x0000, 0x0169, 0x0000, 0x016b, 0x0000, 0x016d, 0x0000,
|
|
||||||
0x016f, 0x016f, 0x0000, 0x0172, 0x0000, 0x0174, 0x0000, 0x0176,
|
|
||||||
0x0000, 0x0178, 0x0000, 0x017a, 0x0000, 0x017c, 0x0000, 0x017e,
|
|
||||||
// Entry 180 - 1BF
|
|
||||||
0x0000, 0x0180, 0x0180, 0x0180, 0x0000, 0x0000, 0x0185, 0x0000,
|
|
||||||
0x0000, 0x0188, 0x0000, 0x018a, 0x0000, 0x0000, 0x018d, 0x0000,
|
|
||||||
0x018f, 0x0000, 0x0000, 0x0192, 0x0000, 0x0000, 0x0195, 0x0000,
|
|
||||||
0x0197, 0x0000, 0x0199, 0x0000, 0x019b, 0x0000, 0x019d, 0x0000,
|
|
||||||
0x019f, 0x0000, 0x01a1, 0x0000, 0x01a3, 0x0000, 0x01a5, 0x0000,
|
|
||||||
0x01a7, 0x0000, 0x01a9, 0x01a9, 0x0000, 0x01ac, 0x0000, 0x01ae,
|
|
||||||
0x0000, 0x01b0, 0x0000, 0x01b2, 0x0000, 0x01b4, 0x0000, 0x0000,
|
|
||||||
0x01b7, 0x0000, 0x01b9, 0x0000, 0x01bb, 0x0000, 0x01bd, 0x0000,
|
|
||||||
// Entry 1C0 - 1FF
|
|
||||||
0x01bf, 0x0000, 0x01c1, 0x0000, 0x01c3, 0x01c3, 0x01c3, 0x01c3,
|
|
||||||
0x0000, 0x01c8, 0x0000, 0x01ca, 0x01ca, 0x0000, 0x01cd, 0x0000,
|
|
||||||
0x01cf, 0x0000, 0x01d1, 0x0000, 0x01d3, 0x0000, 0x01d5, 0x0000,
|
|
||||||
0x01d7, 0x01d7, 0x0000, 0x01da, 0x0000, 0x01dc, 0x0000, 0x01de,
|
|
||||||
0x0000, 0x01e0, 0x0000, 0x01e2, 0x0000, 0x01e4, 0x0000, 0x01e6,
|
|
||||||
0x0000, 0x01e8, 0x0000, 0x01ea, 0x0000, 0x01ec, 0x01ec, 0x01ec,
|
|
||||||
0x0000, 0x01f0, 0x0000, 0x01f2, 0x0000, 0x01f4, 0x0000, 0x01f6,
|
|
||||||
0x0000, 0x0000, 0x01f9, 0x0000, 0x01fb, 0x01fb, 0x0000, 0x01fe,
|
|
||||||
// Entry 200 - 23F
|
|
||||||
0x0000, 0x0200, 0x0200, 0x0000, 0x0203, 0x0203, 0x0000, 0x0206,
|
|
||||||
0x0206, 0x0206, 0x0206, 0x0206, 0x0206, 0x0206, 0x0000, 0x020e,
|
|
||||||
0x0000, 0x0210, 0x0000, 0x0212, 0x0000, 0x0000, 0x0000, 0x0000,
|
|
||||||
0x0000, 0x0218, 0x0000, 0x0000, 0x021b, 0x0000, 0x021d, 0x021d,
|
|
||||||
0x0000, 0x0220, 0x0000, 0x0222, 0x0222, 0x0000, 0x0000, 0x0226,
|
|
||||||
0x0225, 0x0225, 0x0000, 0x0000, 0x022b, 0x0000, 0x022d, 0x0000,
|
|
||||||
0x022f, 0x0000, 0x023b, 0x0231, 0x023b, 0x023b, 0x023b, 0x023b,
|
|
||||||
0x023b, 0x023b, 0x023b, 0x0231, 0x023b, 0x023b, 0x0000, 0x023e,
|
|
||||||
// Entry 240 - 27F
|
|
||||||
0x023e, 0x023e, 0x0000, 0x0242, 0x0000, 0x0244, 0x0000, 0x0246,
|
|
||||||
0x0246, 0x0000, 0x0249, 0x0000, 0x024b, 0x024b, 0x024b, 0x024b,
|
|
||||||
0x024b, 0x024b, 0x0000, 0x0252, 0x0000, 0x0254, 0x0000, 0x0256,
|
|
||||||
0x0000, 0x0258, 0x0000, 0x025a, 0x0000, 0x0000, 0x025d, 0x025d,
|
|
||||||
0x025d, 0x0000, 0x0261, 0x0000, 0x0263, 0x0000, 0x0265, 0x0000,
|
|
||||||
0x0000, 0x0268, 0x0267, 0x0267, 0x0000, 0x026c, 0x0000, 0x026e,
|
|
||||||
0x0000, 0x0270, 0x0000, 0x0000, 0x0000, 0x0000, 0x0275, 0x0000,
|
|
||||||
0x0000, 0x0278, 0x0000, 0x027a, 0x027a, 0x027a, 0x027a, 0x0000,
|
|
||||||
// Entry 280 - 2BF
|
|
||||||
0x027f, 0x027f, 0x027f, 0x0000, 0x0283, 0x0283, 0x0283, 0x0283,
|
|
||||||
0x0283, 0x0000, 0x0289, 0x0289, 0x0289, 0x0289, 0x0000, 0x0000,
|
|
||||||
0x0000, 0x0000, 0x0291, 0x0291, 0x0291, 0x0000, 0x0295, 0x0295,
|
|
||||||
0x0295, 0x0295, 0x0000, 0x0000, 0x029b, 0x029b, 0x029b, 0x029b,
|
|
||||||
0x0000, 0x02a0, 0x0000, 0x02a2, 0x02a2, 0x0000, 0x02a5, 0x0000,
|
|
||||||
0x02a7, 0x02a7, 0x0000, 0x0000, 0x02ab, 0x0000, 0x0000, 0x02ae,
|
|
||||||
0x0000, 0x02b0, 0x02b0, 0x0000, 0x0000, 0x02b4, 0x0000, 0x02b6,
|
|
||||||
0x0000, 0x02b8, 0x0000, 0x02ba, 0x0000, 0x02bc, 0x02bc, 0x0000,
|
|
||||||
// Entry 2C0 - 2FF
|
|
||||||
0x0000, 0x02c0, 0x0000, 0x02c2, 0x02bf, 0x02bf, 0x0000, 0x0000,
|
|
||||||
0x02c7, 0x02c6, 0x02c6, 0x0000, 0x0000, 0x02cc, 0x0000, 0x02ce,
|
|
||||||
0x0000, 0x02d0, 0x0000, 0x0000, 0x02d3, 0x0000, 0x0000, 0x0000,
|
|
||||||
0x02d7, 0x0000, 0x02d9, 0x0000, 0x02db, 0x0000, 0x02dd, 0x02dd,
|
|
||||||
0x0000, 0x02e0, 0x0000, 0x02e2, 0x0000, 0x02e4, 0x02e4, 0x02e4,
|
|
||||||
0x02e4, 0x02e4, 0x0000, 0x02ea, 0x02eb, 0x02ea, 0x0000, 0x02ee,
|
|
||||||
} // Size: 1528 bytes
|
|
||||||
|
|
||||||
// Total table size 1528 bytes (1KiB); checksum: B99CF952
|
|
1501
vendor/golang.org/x/text/language/index.go
generated
vendored
1501
vendor/golang.org/x/text/language/index.go
generated
vendored
File diff suppressed because it is too large
Load diff
2
vendor/golang.org/x/text/language/language.go
generated
vendored
2
vendor/golang.org/x/text/language/language.go
generated
vendored
|
@ -593,7 +593,7 @@ func (t Tag) Extension(x byte) (ext Extension, ok bool) {
|
||||||
return Extension{ext}, true
|
return Extension{ext}, true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Extension{}, false
|
return Extension{string(x)}, false
|
||||||
}
|
}
|
||||||
|
|
||||||
// Extensions returns all extensions of t.
|
// Extensions returns all extensions of t.
|
||||||
|
|
13
vendor/golang.org/x/text/language/maketables.go
generated
vendored
13
vendor/golang.org/x/text/language/maketables.go
generated
vendored
|
@ -678,8 +678,6 @@ func (b *builder) parseIndices() {
|
||||||
b.locale.parse(meta.DefaultContent.Locales)
|
b.locale.parse(meta.DefaultContent.Locales)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: region inclusion data will probably not be use used in future matchers.
|
|
||||||
|
|
||||||
func (b *builder) computeRegionGroups() {
|
func (b *builder) computeRegionGroups() {
|
||||||
b.groups = make(map[int]index)
|
b.groups = make(map[int]index)
|
||||||
|
|
||||||
|
@ -688,11 +686,6 @@ func (b *builder) computeRegionGroups() {
|
||||||
b.groups[i] = index(len(b.groups))
|
b.groups[i] = index(len(b.groups))
|
||||||
}
|
}
|
||||||
for _, g := range b.supp.TerritoryContainment.Group {
|
for _, g := range b.supp.TerritoryContainment.Group {
|
||||||
// Skip UN and EURO zone as they are flattening the containment
|
|
||||||
// relationship.
|
|
||||||
if g.Type == "EZ" || g.Type == "UN" {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
group := b.region.index(g.Type)
|
group := b.region.index(g.Type)
|
||||||
if _, ok := b.groups[group]; !ok {
|
if _, ok := b.groups[group]; !ok {
|
||||||
b.groups[group] = index(len(b.groups))
|
b.groups[group] = index(len(b.groups))
|
||||||
|
@ -789,7 +782,6 @@ func (b *builder) writeLanguage() {
|
||||||
lang.updateLater("tw", "twi")
|
lang.updateLater("tw", "twi")
|
||||||
lang.updateLater("nb", "nob")
|
lang.updateLater("nb", "nob")
|
||||||
lang.updateLater("ak", "aka")
|
lang.updateLater("ak", "aka")
|
||||||
lang.updateLater("bh", "bih")
|
|
||||||
|
|
||||||
// Ensure that each 2-letter code is matched with a 3-letter code.
|
// Ensure that each 2-letter code is matched with a 3-letter code.
|
||||||
for _, v := range lang.s[1:] {
|
for _, v := range lang.s[1:] {
|
||||||
|
@ -1490,11 +1482,6 @@ func (b *builder) writeRegionInclusionData() {
|
||||||
containment = make(map[index][]index)
|
containment = make(map[index][]index)
|
||||||
)
|
)
|
||||||
for _, g := range b.supp.TerritoryContainment.Group {
|
for _, g := range b.supp.TerritoryContainment.Group {
|
||||||
// Skip UN and EURO zone as they are flattening the containment
|
|
||||||
// relationship.
|
|
||||||
if g.Type == "EZ" || g.Type == "UN" {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
group := b.region.index(g.Type)
|
group := b.region.index(g.Type)
|
||||||
groupIdx := b.groups[group]
|
groupIdx := b.groups[group]
|
||||||
for _, mem := range strings.Split(g.Contains, " ") {
|
for _, mem := range strings.Split(g.Contains, " ") {
|
||||||
|
|
21
vendor/golang.org/x/text/language/match.go
generated
vendored
21
vendor/golang.org/x/text/language/match.go
generated
vendored
|
@ -396,8 +396,8 @@ type matcher struct {
|
||||||
// matchHeader has the lists of tags for exact matches and matches based on
|
// matchHeader has the lists of tags for exact matches and matches based on
|
||||||
// maximized and canonicalized tags for a given language.
|
// maximized and canonicalized tags for a given language.
|
||||||
type matchHeader struct {
|
type matchHeader struct {
|
||||||
exact []*haveTag
|
exact []haveTag
|
||||||
max []*haveTag
|
max []haveTag
|
||||||
}
|
}
|
||||||
|
|
||||||
// haveTag holds a supported Tag and its maximized script and region. The maximized
|
// haveTag holds a supported Tag and its maximized script and region. The maximized
|
||||||
|
@ -457,7 +457,7 @@ func (h *matchHeader) addIfNew(n haveTag, exact bool) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if exact {
|
if exact {
|
||||||
h.exact = append(h.exact, &n)
|
h.exact = append(h.exact, n)
|
||||||
}
|
}
|
||||||
// Allow duplicate maximized tags, but create a linked list to allow quickly
|
// Allow duplicate maximized tags, but create a linked list to allow quickly
|
||||||
// comparing the equivalents and bail out.
|
// comparing the equivalents and bail out.
|
||||||
|
@ -472,7 +472,7 @@ func (h *matchHeader) addIfNew(n haveTag, exact bool) {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
h.max = append(h.max, &n)
|
h.max = append(h.max, n)
|
||||||
}
|
}
|
||||||
|
|
||||||
// header returns the matchHeader for the given language. It creates one if
|
// header returns the matchHeader for the given language. It creates one if
|
||||||
|
@ -503,7 +503,7 @@ func newMatcher(supported []Tag) *matcher {
|
||||||
pair, _ := makeHaveTag(tag, i)
|
pair, _ := makeHaveTag(tag, i)
|
||||||
m.header(tag.lang).addIfNew(pair, true)
|
m.header(tag.lang).addIfNew(pair, true)
|
||||||
}
|
}
|
||||||
m.default_ = m.header(supported[0].lang).exact[0]
|
m.default_ = &m.header(supported[0].lang).exact[0]
|
||||||
for i, tag := range supported {
|
for i, tag := range supported {
|
||||||
pair, max := makeHaveTag(tag, i)
|
pair, max := makeHaveTag(tag, i)
|
||||||
if max != tag.lang {
|
if max != tag.lang {
|
||||||
|
@ -520,8 +520,7 @@ func newMatcher(supported []Tag) *matcher {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
hw := m.header(langID(want))
|
hw := m.header(langID(want))
|
||||||
for _, ht := range hh.max {
|
for _, v := range hh.max {
|
||||||
v := *ht
|
|
||||||
if conf < v.conf {
|
if conf < v.conf {
|
||||||
v.conf = conf
|
v.conf = conf
|
||||||
}
|
}
|
||||||
|
@ -581,7 +580,7 @@ func (m *matcher) getBest(want ...Tag) (got *haveTag, orig Tag, c Confidence) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
for i := range h.exact {
|
for i := range h.exact {
|
||||||
have := h.exact[i]
|
have := &h.exact[i]
|
||||||
if have.tag.equalsRest(w) {
|
if have.tag.equalsRest(w) {
|
||||||
return have, w, Exact
|
return have, w, Exact
|
||||||
}
|
}
|
||||||
|
@ -592,7 +591,7 @@ func (m *matcher) getBest(want ...Tag) (got *haveTag, orig Tag, c Confidence) {
|
||||||
// Base language is not defined.
|
// Base language is not defined.
|
||||||
if h != nil {
|
if h != nil {
|
||||||
for i := range h.exact {
|
for i := range h.exact {
|
||||||
have := h.exact[i]
|
have := &h.exact[i]
|
||||||
if have.tag.equalsRest(w) {
|
if have.tag.equalsRest(w) {
|
||||||
return have, w, Exact
|
return have, w, Exact
|
||||||
}
|
}
|
||||||
|
@ -610,11 +609,11 @@ func (m *matcher) getBest(want ...Tag) (got *haveTag, orig Tag, c Confidence) {
|
||||||
}
|
}
|
||||||
// Check for match based on maximized tag.
|
// Check for match based on maximized tag.
|
||||||
for i := range h.max {
|
for i := range h.max {
|
||||||
have := h.max[i]
|
have := &h.max[i]
|
||||||
best.update(have, w, max.script, max.region)
|
best.update(have, w, max.script, max.region)
|
||||||
if best.conf == Exact {
|
if best.conf == Exact {
|
||||||
for have.nextMax != 0 {
|
for have.nextMax != 0 {
|
||||||
have = h.max[have.nextMax]
|
have = &h.max[have.nextMax]
|
||||||
best.update(have, w, max.script, max.region)
|
best.update(have, w, max.script, max.region)
|
||||||
}
|
}
|
||||||
return best.have, best.want, High
|
return best.have, best.want, High
|
||||||
|
|
5042
vendor/golang.org/x/text/language/tables.go
generated
vendored
5042
vendor/golang.org/x/text/language/tables.go
generated
vendored
File diff suppressed because it is too large
Load diff
75
vendor/golang.org/x/text/runes/cond.go
generated
vendored
75
vendor/golang.org/x/text/runes/cond.go
generated
vendored
|
@ -41,35 +41,20 @@ func If(s Set, tIn, tNotIn transform.Transformer) Transformer {
|
||||||
if tNotIn == nil {
|
if tNotIn == nil {
|
||||||
tNotIn = transform.Nop
|
tNotIn = transform.Nop
|
||||||
}
|
}
|
||||||
sIn, ok := tIn.(transform.SpanningTransformer)
|
|
||||||
if !ok {
|
|
||||||
sIn = dummySpan{tIn}
|
|
||||||
}
|
|
||||||
sNotIn, ok := tNotIn.(transform.SpanningTransformer)
|
|
||||||
if !ok {
|
|
||||||
sNotIn = dummySpan{tNotIn}
|
|
||||||
}
|
|
||||||
|
|
||||||
a := &cond{
|
a := &cond{
|
||||||
tIn: sIn,
|
tIn: tIn,
|
||||||
tNotIn: sNotIn,
|
tNotIn: tNotIn,
|
||||||
f: s.Contains,
|
f: s.Contains,
|
||||||
}
|
}
|
||||||
a.Reset()
|
a.Reset()
|
||||||
return Transformer{a}
|
return Transformer{a}
|
||||||
}
|
}
|
||||||
|
|
||||||
type dummySpan struct{ transform.Transformer }
|
|
||||||
|
|
||||||
func (d dummySpan) Span(src []byte, atEOF bool) (n int, err error) {
|
|
||||||
return 0, transform.ErrEndOfSpan
|
|
||||||
}
|
|
||||||
|
|
||||||
type cond struct {
|
type cond struct {
|
||||||
tIn, tNotIn transform.SpanningTransformer
|
tIn, tNotIn transform.Transformer
|
||||||
f func(rune) bool
|
f func(rune) bool
|
||||||
check func(rune) bool // current check to perform
|
check func(rune) bool // current check to perform
|
||||||
t transform.SpanningTransformer // current transformer to use
|
t transform.Transformer // current transformer to use
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset implements transform.Transformer.
|
// Reset implements transform.Transformer.
|
||||||
|
@ -99,51 +84,6 @@ func (t *cond) isNot(r rune) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// This implementation of Span doesn't help all too much, but it needs to be
|
|
||||||
// there to satisfy this package's Transformer interface.
|
|
||||||
// TODO: there are certainly room for improvements, though. For example, if
|
|
||||||
// t.t == transform.Nop (which will a common occurrence) it will save a bundle
|
|
||||||
// to special-case that loop.
|
|
||||||
func (t *cond) Span(src []byte, atEOF bool) (n int, err error) {
|
|
||||||
p := 0
|
|
||||||
for n < len(src) && err == nil {
|
|
||||||
// Don't process too much at a time as the Spanner that will be
|
|
||||||
// called on this block may terminate early.
|
|
||||||
const maxChunk = 4096
|
|
||||||
max := len(src)
|
|
||||||
if v := n + maxChunk; v < max {
|
|
||||||
max = v
|
|
||||||
}
|
|
||||||
atEnd := false
|
|
||||||
size := 0
|
|
||||||
current := t.t
|
|
||||||
for ; p < max; p += size {
|
|
||||||
r := rune(src[p])
|
|
||||||
if r < utf8.RuneSelf {
|
|
||||||
size = 1
|
|
||||||
} else if r, size = utf8.DecodeRune(src[p:]); size == 1 {
|
|
||||||
if !atEOF && !utf8.FullRune(src[p:]) {
|
|
||||||
err = transform.ErrShortSrc
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if !t.check(r) {
|
|
||||||
// The next rune will be the start of a new run.
|
|
||||||
atEnd = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
n2, err2 := current.Span(src[n:p], atEnd || (atEOF && p == len(src)))
|
|
||||||
n += n2
|
|
||||||
if err2 != nil {
|
|
||||||
return n, err2
|
|
||||||
}
|
|
||||||
// At this point either err != nil or t.check will pass for the rune at p.
|
|
||||||
p = n + size
|
|
||||||
}
|
|
||||||
return n, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *cond) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
|
func (t *cond) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
|
||||||
p := 0
|
p := 0
|
||||||
for nSrc < len(src) && err == nil {
|
for nSrc < len(src) && err == nil {
|
||||||
|
@ -159,10 +99,9 @@ func (t *cond) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error
|
||||||
size := 0
|
size := 0
|
||||||
current := t.t
|
current := t.t
|
||||||
for ; p < max; p += size {
|
for ; p < max; p += size {
|
||||||
r := rune(src[p])
|
var r rune
|
||||||
if r < utf8.RuneSelf {
|
r, size = utf8.DecodeRune(src[p:])
|
||||||
size = 1
|
if r == utf8.RuneError && size == 1 {
|
||||||
} else if r, size = utf8.DecodeRune(src[p:]); size == 1 {
|
|
||||||
if !atEOF && !utf8.FullRune(src[p:]) {
|
if !atEOF && !utf8.FullRune(src[p:]) {
|
||||||
err = transform.ErrShortSrc
|
err = transform.ErrShortSrc
|
||||||
break
|
break
|
||||||
|
|
103
vendor/golang.org/x/text/runes/runes.go
generated
vendored
103
vendor/golang.org/x/text/runes/runes.go
generated
vendored
|
@ -46,19 +46,9 @@ func Predicate(f func(rune) bool) Set {
|
||||||
|
|
||||||
// Transformer implements the transform.Transformer interface.
|
// Transformer implements the transform.Transformer interface.
|
||||||
type Transformer struct {
|
type Transformer struct {
|
||||||
t transform.SpanningTransformer
|
transform.Transformer
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t Transformer) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
|
|
||||||
return t.t.Transform(dst, src, atEOF)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t Transformer) Span(b []byte, atEOF bool) (n int, err error) {
|
|
||||||
return t.t.Span(b, atEOF)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t Transformer) Reset() { t.t.Reset() }
|
|
||||||
|
|
||||||
// Bytes returns a new byte slice with the result of converting b using t. It
|
// Bytes returns a new byte slice with the result of converting b using t. It
|
||||||
// calls Reset on t. It returns nil if any error was found. This can only happen
|
// calls Reset on t. It returns nil if any error was found. This can only happen
|
||||||
// if an error-producing Transformer is passed to If.
|
// if an error-producing Transformer is passed to If.
|
||||||
|
@ -106,35 +96,15 @@ type remove func(r rune) bool
|
||||||
|
|
||||||
func (remove) Reset() {}
|
func (remove) Reset() {}
|
||||||
|
|
||||||
// Span implements transform.Spanner.
|
|
||||||
func (t remove) Span(src []byte, atEOF bool) (n int, err error) {
|
|
||||||
for r, size := rune(0), 0; n < len(src); {
|
|
||||||
if r = rune(src[n]); r < utf8.RuneSelf {
|
|
||||||
size = 1
|
|
||||||
} else if r, size = utf8.DecodeRune(src[n:]); size == 1 {
|
|
||||||
// Invalid rune.
|
|
||||||
if !atEOF && !utf8.FullRune(src[n:]) {
|
|
||||||
err = transform.ErrShortSrc
|
|
||||||
} else {
|
|
||||||
err = transform.ErrEndOfSpan
|
|
||||||
}
|
|
||||||
break
|
|
||||||
}
|
|
||||||
if t(r) {
|
|
||||||
err = transform.ErrEndOfSpan
|
|
||||||
break
|
|
||||||
}
|
|
||||||
n += size
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Transform implements transform.Transformer.
|
// Transform implements transform.Transformer.
|
||||||
func (t remove) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
|
func (t remove) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
|
||||||
for r, size := rune(0), 0; nSrc < len(src); {
|
for r, size := rune(0), 0; nSrc < len(src); {
|
||||||
if r = rune(src[nSrc]); r < utf8.RuneSelf {
|
if r = rune(src[nSrc]); r < utf8.RuneSelf {
|
||||||
size = 1
|
size = 1
|
||||||
} else if r, size = utf8.DecodeRune(src[nSrc:]); size == 1 {
|
} else {
|
||||||
|
r, size = utf8.DecodeRune(src[nSrc:])
|
||||||
|
|
||||||
|
if size == 1 {
|
||||||
// Invalid rune.
|
// Invalid rune.
|
||||||
if !atEOF && !utf8.FullRune(src[nSrc:]) {
|
if !atEOF && !utf8.FullRune(src[nSrc:]) {
|
||||||
err = transform.ErrShortSrc
|
err = transform.ErrShortSrc
|
||||||
|
@ -157,6 +127,8 @@ func (t remove) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err erro
|
||||||
nSrc++
|
nSrc++
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if t(r) {
|
if t(r) {
|
||||||
nSrc += size
|
nSrc += size
|
||||||
continue
|
continue
|
||||||
|
@ -185,28 +157,6 @@ type mapper func(rune) rune
|
||||||
|
|
||||||
func (mapper) Reset() {}
|
func (mapper) Reset() {}
|
||||||
|
|
||||||
// Span implements transform.Spanner.
|
|
||||||
func (t mapper) Span(src []byte, atEOF bool) (n int, err error) {
|
|
||||||
for r, size := rune(0), 0; n < len(src); n += size {
|
|
||||||
if r = rune(src[n]); r < utf8.RuneSelf {
|
|
||||||
size = 1
|
|
||||||
} else if r, size = utf8.DecodeRune(src[n:]); size == 1 {
|
|
||||||
// Invalid rune.
|
|
||||||
if !atEOF && !utf8.FullRune(src[n:]) {
|
|
||||||
err = transform.ErrShortSrc
|
|
||||||
} else {
|
|
||||||
err = transform.ErrEndOfSpan
|
|
||||||
}
|
|
||||||
break
|
|
||||||
}
|
|
||||||
if t(r) != r {
|
|
||||||
err = transform.ErrEndOfSpan
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return n, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Transform implements transform.Transformer.
|
// Transform implements transform.Transformer.
|
||||||
func (t mapper) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
|
func (t mapper) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
|
||||||
var replacement rune
|
var replacement rune
|
||||||
|
@ -280,51 +230,24 @@ func ReplaceIllFormed() Transformer {
|
||||||
|
|
||||||
type replaceIllFormed struct{ transform.NopResetter }
|
type replaceIllFormed struct{ transform.NopResetter }
|
||||||
|
|
||||||
func (t replaceIllFormed) Span(src []byte, atEOF bool) (n int, err error) {
|
|
||||||
for n < len(src) {
|
|
||||||
// ASCII fast path.
|
|
||||||
if src[n] < utf8.RuneSelf {
|
|
||||||
n++
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
r, size := utf8.DecodeRune(src[n:])
|
|
||||||
|
|
||||||
// Look for a valid non-ASCII rune.
|
|
||||||
if r != utf8.RuneError || size != 1 {
|
|
||||||
n += size
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// Look for short source data.
|
|
||||||
if !atEOF && !utf8.FullRune(src[n:]) {
|
|
||||||
err = transform.ErrShortSrc
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
// We have an invalid rune.
|
|
||||||
err = transform.ErrEndOfSpan
|
|
||||||
break
|
|
||||||
}
|
|
||||||
return n, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t replaceIllFormed) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
|
func (t replaceIllFormed) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
|
||||||
for nSrc < len(src) {
|
for nSrc < len(src) {
|
||||||
// ASCII fast path.
|
r, size := utf8.DecodeRune(src[nSrc:])
|
||||||
if r := src[nSrc]; r < utf8.RuneSelf {
|
|
||||||
|
// Look for an ASCII rune.
|
||||||
|
if r < utf8.RuneSelf {
|
||||||
if nDst == len(dst) {
|
if nDst == len(dst) {
|
||||||
err = transform.ErrShortDst
|
err = transform.ErrShortDst
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
dst[nDst] = r
|
dst[nDst] = byte(r)
|
||||||
nDst++
|
nDst++
|
||||||
nSrc++
|
nSrc++
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// Look for a valid non-ASCII rune.
|
// Look for a valid non-ASCII rune.
|
||||||
if _, size := utf8.DecodeRune(src[nSrc:]); size != 1 {
|
if r != utf8.RuneError || size != 1 {
|
||||||
if size != copy(dst[nDst:], src[nSrc:nSrc+size]) {
|
if size != copy(dst[nDst:], src[nSrc:nSrc+size]) {
|
||||||
err = transform.ErrShortDst
|
err = transform.ErrShortDst
|
||||||
break
|
break
|
||||||
|
|
102
vendor/golang.org/x/text/secure/bidirule/bidirule.go
generated
vendored
102
vendor/golang.org/x/text/secure/bidirule/bidirule.go
generated
vendored
|
@ -123,64 +123,34 @@ var transitions = [...][2]ruleTransition{
|
||||||
// vice versa.
|
// vice versa.
|
||||||
const exclusiveRTL = uint16(1<<bidi.EN | 1<<bidi.AN)
|
const exclusiveRTL = uint16(1<<bidi.EN | 1<<bidi.AN)
|
||||||
|
|
||||||
// From RFC 5893
|
// Direction reports the direction of the given label as defined by RFC 5893 or
|
||||||
// An RTL label is a label that contains at least one character of type
|
// an error if b is not a valid label according to the Bidi Rule.
|
||||||
// R, AL, or AN.
|
func Direction(b []byte) (bidi.Direction, error) {
|
||||||
//
|
t := Transformer{}
|
||||||
// An LTR label is any label that is not an RTL label.
|
if n, ok := t.advance(b); ok && n == len(b) {
|
||||||
|
switch t.state {
|
||||||
// Direction reports the direction of the given label as defined by RFC 5893.
|
case ruleLTRFinal, ruleInitial:
|
||||||
// The Bidi Rule does not have to be applied to labels of the category
|
return bidi.LeftToRight, nil
|
||||||
// LeftToRight.
|
case ruleRTLFinal:
|
||||||
func Direction(b []byte) bidi.Direction {
|
return bidi.RightToLeft, nil
|
||||||
for i := 0; i < len(b); {
|
|
||||||
e, sz := bidi.Lookup(b[i:])
|
|
||||||
if sz == 0 {
|
|
||||||
i++
|
|
||||||
}
|
}
|
||||||
c := e.Class()
|
|
||||||
if c == bidi.R || c == bidi.AL || c == bidi.AN {
|
|
||||||
return bidi.RightToLeft
|
|
||||||
}
|
}
|
||||||
i += sz
|
return bidi.Neutral, ErrInvalid
|
||||||
}
|
|
||||||
return bidi.LeftToRight
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// DirectionString reports the direction of the given label as defined by RFC
|
// DirectionString reports the direction of the given label as defined by RFC
|
||||||
// 5893. The Bidi Rule does not have to be applied to labels of the category
|
// 5893 or an error if s is not a valid label according to the Bidi Rule.
|
||||||
// LeftToRight.
|
func DirectionString(s string) (bidi.Direction, error) {
|
||||||
func DirectionString(s string) bidi.Direction {
|
t := Transformer{}
|
||||||
for i := 0; i < len(s); {
|
if n, ok := t.advanceString(s); ok && n == len(s) {
|
||||||
e, sz := bidi.LookupString(s[i:])
|
switch t.state {
|
||||||
if sz == 0 {
|
case ruleLTRFinal, ruleInitial:
|
||||||
i++
|
return bidi.LeftToRight, nil
|
||||||
|
case ruleRTLFinal:
|
||||||
|
return bidi.RightToLeft, nil
|
||||||
}
|
}
|
||||||
c := e.Class()
|
|
||||||
if c == bidi.R || c == bidi.AL || c == bidi.AN {
|
|
||||||
return bidi.RightToLeft
|
|
||||||
}
|
}
|
||||||
i += sz
|
return bidi.Neutral, ErrInvalid
|
||||||
}
|
|
||||||
return bidi.LeftToRight
|
|
||||||
}
|
|
||||||
|
|
||||||
// Valid reports whether b conforms to the BiDi rule.
|
|
||||||
func Valid(b []byte) bool {
|
|
||||||
var t Transformer
|
|
||||||
if n, ok := t.advance(b); !ok || n < len(b) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return t.isFinal()
|
|
||||||
}
|
|
||||||
|
|
||||||
// ValidString reports whether s conforms to the BiDi rule.
|
|
||||||
func ValidString(s string) bool {
|
|
||||||
var t Transformer
|
|
||||||
if n, ok := t.advanceString(s); !ok || n < len(s) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return t.isFinal()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// New returns a Transformer that verifies that input adheres to the Bidi Rule.
|
// New returns a Transformer that verifies that input adheres to the Bidi Rule.
|
||||||
|
@ -191,24 +161,9 @@ func New() *Transformer {
|
||||||
// Transformer implements transform.Transform.
|
// Transformer implements transform.Transform.
|
||||||
type Transformer struct {
|
type Transformer struct {
|
||||||
state ruleState
|
state ruleState
|
||||||
hasRTL bool
|
|
||||||
seen uint16
|
seen uint16
|
||||||
}
|
}
|
||||||
|
|
||||||
// A rule can only be violated for "Bidi Domain names", meaning if one of the
|
|
||||||
// following categories has been observed.
|
|
||||||
func (t *Transformer) isRTL() bool {
|
|
||||||
const isRTL = 1<<bidi.R | 1<<bidi.AL | 1<<bidi.AN
|
|
||||||
return t.seen&isRTL != 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *Transformer) isFinal() bool {
|
|
||||||
if !t.isRTL() {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return t.state == ruleLTRFinal || t.state == ruleRTLFinal || t.state == ruleInitial
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reset implements transform.Transformer.
|
// Reset implements transform.Transformer.
|
||||||
func (t *Transformer) Reset() { *t = Transformer{} }
|
func (t *Transformer) Reset() { *t = Transformer{} }
|
||||||
|
|
||||||
|
@ -230,7 +185,7 @@ func (t *Transformer) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, er
|
||||||
|
|
||||||
// Span returns the first n bytes of src that conform to the Bidi rule.
|
// Span returns the first n bytes of src that conform to the Bidi rule.
|
||||||
func (t *Transformer) Span(src []byte, atEOF bool) (n int, err error) {
|
func (t *Transformer) Span(src []byte, atEOF bool) (n int, err error) {
|
||||||
if t.state == ruleInvalid && t.isRTL() {
|
if t.state == ruleInvalid {
|
||||||
return 0, ErrInvalid
|
return 0, ErrInvalid
|
||||||
}
|
}
|
||||||
n, ok := t.advance(src)
|
n, ok := t.advance(src)
|
||||||
|
@ -243,7 +198,7 @@ func (t *Transformer) Span(src []byte, atEOF bool) (n int, err error) {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
err = ErrInvalid
|
err = ErrInvalid
|
||||||
case !t.isFinal():
|
case t.state != ruleLTRFinal && t.state != ruleRTLFinal && t.state != ruleInitial:
|
||||||
err = ErrInvalid
|
err = ErrInvalid
|
||||||
}
|
}
|
||||||
return n, err
|
return n, err
|
||||||
|
@ -270,15 +225,12 @@ func (t *Transformer) advance(s []byte) (n int, ok bool) {
|
||||||
e, sz = bidi.Lookup(s[n:])
|
e, sz = bidi.Lookup(s[n:])
|
||||||
if sz <= 1 {
|
if sz <= 1 {
|
||||||
if sz == 1 {
|
if sz == 1 {
|
||||||
// We always consider invalid UTF-8 to be invalid, even if
|
return n, false // invalid UTF-8
|
||||||
// the string has not yet been determined to be RTL.
|
|
||||||
// TODO: is this correct?
|
|
||||||
return n, false
|
|
||||||
}
|
}
|
||||||
return n, true // incomplete UTF-8 encoding
|
return n, true // incomplete UTF-8 encoding
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// TODO: using CompactClass would result in noticeable speedup.
|
// TODO: using CompactClass results in noticeable speedup.
|
||||||
// See unicode/bidi/prop.go:Properties.CompactClass.
|
// See unicode/bidi/prop.go:Properties.CompactClass.
|
||||||
c := uint16(1 << e.Class())
|
c := uint16(1 << e.Class())
|
||||||
t.seen |= c
|
t.seen |= c
|
||||||
|
@ -293,10 +245,8 @@ func (t *Transformer) advance(s []byte) (n int, ok bool) {
|
||||||
t.state = tr[1].next
|
t.state = tr[1].next
|
||||||
default:
|
default:
|
||||||
t.state = ruleInvalid
|
t.state = ruleInvalid
|
||||||
if t.isRTL() {
|
|
||||||
return n, false
|
return n, false
|
||||||
}
|
}
|
||||||
}
|
|
||||||
n += sz
|
n += sz
|
||||||
}
|
}
|
||||||
return n, true
|
return n, true
|
||||||
|
@ -332,10 +282,8 @@ func (t *Transformer) advanceString(s string) (n int, ok bool) {
|
||||||
t.state = tr[1].next
|
t.state = tr[1].next
|
||||||
default:
|
default:
|
||||||
t.state = ruleInvalid
|
t.state = ruleInvalid
|
||||||
if t.isRTL() {
|
|
||||||
return n, false
|
return n, false
|
||||||
}
|
}
|
||||||
}
|
|
||||||
n += sz
|
n += sz
|
||||||
}
|
}
|
||||||
return n, true
|
return n, true
|
||||||
|
|
59
vendor/golang.org/x/text/secure/precis/options.go
generated
vendored
59
vendor/golang.org/x/text/secure/precis/options.go
generated
vendored
|
@ -6,10 +6,10 @@ package precis
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"golang.org/x/text/cases"
|
"golang.org/x/text/cases"
|
||||||
"golang.org/x/text/language"
|
|
||||||
"golang.org/x/text/runes"
|
"golang.org/x/text/runes"
|
||||||
"golang.org/x/text/transform"
|
"golang.org/x/text/transform"
|
||||||
"golang.org/x/text/unicode/norm"
|
"golang.org/x/text/unicode/norm"
|
||||||
|
"golang.org/x/text/width"
|
||||||
)
|
)
|
||||||
|
|
||||||
// An Option is used to define the behavior and rules of a Profile.
|
// An Option is used to define the behavior and rules of a Profile.
|
||||||
|
@ -20,12 +20,11 @@ type options struct {
|
||||||
foldWidth bool
|
foldWidth bool
|
||||||
|
|
||||||
// Enforcement options
|
// Enforcement options
|
||||||
asciiLower bool
|
cases transform.Transformer
|
||||||
cases transform.SpanningTransformer
|
|
||||||
disallow runes.Set
|
disallow runes.Set
|
||||||
norm transform.SpanningTransformer
|
norm norm.Form
|
||||||
additional []func() transform.SpanningTransformer
|
additional []func() transform.Transformer
|
||||||
width transform.SpanningTransformer
|
width *width.Transformer
|
||||||
disallowEmpty bool
|
disallowEmpty bool
|
||||||
bidiRule bool
|
bidiRule bool
|
||||||
|
|
||||||
|
@ -37,11 +36,6 @@ func getOpts(o ...Option) (res options) {
|
||||||
for _, f := range o {
|
for _, f := range o {
|
||||||
f(&res)
|
f(&res)
|
||||||
}
|
}
|
||||||
// Using a SpanningTransformer, instead of norm.Form prevents an allocation
|
|
||||||
// down the road.
|
|
||||||
if res.norm == nil {
|
|
||||||
res.norm = norm.NFC
|
|
||||||
}
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,36 +74,11 @@ var (
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
// TODO: move this logic to package transform
|
|
||||||
|
|
||||||
type spanWrap struct{ transform.Transformer }
|
|
||||||
|
|
||||||
func (s spanWrap) Span(src []byte, atEOF bool) (n int, err error) {
|
|
||||||
return 0, transform.ErrEndOfSpan
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: allow different types? For instance:
|
|
||||||
// func() transform.Transformer
|
|
||||||
// func() transform.SpanningTransformer
|
|
||||||
// func([]byte) bool // validation only
|
|
||||||
//
|
|
||||||
// Also, would be great if we could detect if a transformer is reentrant.
|
|
||||||
|
|
||||||
// The AdditionalMapping option defines the additional mapping rule for the
|
// The AdditionalMapping option defines the additional mapping rule for the
|
||||||
// Profile by applying Transformer's in sequence.
|
// Profile by applying Transformer's in sequence.
|
||||||
func AdditionalMapping(t ...func() transform.Transformer) Option {
|
func AdditionalMapping(t ...func() transform.Transformer) Option {
|
||||||
return func(o *options) {
|
return func(o *options) {
|
||||||
for _, f := range t {
|
o.additional = t
|
||||||
sf := func() transform.SpanningTransformer {
|
|
||||||
return f().(transform.SpanningTransformer)
|
|
||||||
}
|
|
||||||
if _, ok := f().(transform.SpanningTransformer); !ok {
|
|
||||||
sf = func() transform.SpanningTransformer {
|
|
||||||
return spanWrap{f()}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
o.additional = append(o.additional, sf)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,26 +93,10 @@ func Norm(f norm.Form) Option {
|
||||||
// provided to determine the type of case folding used.
|
// provided to determine the type of case folding used.
|
||||||
func FoldCase(opts ...cases.Option) Option {
|
func FoldCase(opts ...cases.Option) Option {
|
||||||
return func(o *options) {
|
return func(o *options) {
|
||||||
o.asciiLower = true
|
|
||||||
o.cases = cases.Fold(opts...)
|
o.cases = cases.Fold(opts...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// The LowerCase option defines a Profile's case mapping rule. Options can be
|
|
||||||
// provided to determine the type of case folding used.
|
|
||||||
func LowerCase(opts ...cases.Option) Option {
|
|
||||||
return func(o *options) {
|
|
||||||
o.asciiLower = true
|
|
||||||
if len(opts) == 0 {
|
|
||||||
o.cases = cases.Lower(language.Und, cases.HandleFinalSigma(false))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
opts = append([]cases.Option{cases.HandleFinalSigma(false)}, opts...)
|
|
||||||
o.cases = cases.Lower(language.Und, opts...)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// The Disallow option further restricts a Profile's allowed characters beyond
|
// The Disallow option further restricts a Profile's allowed characters beyond
|
||||||
// what is disallowed by the underlying string class.
|
// what is disallowed by the underlying string class.
|
||||||
func Disallow(set runes.Set) Option {
|
func Disallow(set runes.Set) Option {
|
||||||
|
|
168
vendor/golang.org/x/text/secure/precis/profile.go
generated
vendored
168
vendor/golang.org/x/text/secure/precis/profile.go
generated
vendored
|
@ -5,12 +5,9 @@
|
||||||
package precis
|
package precis
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"errors"
|
"errors"
|
||||||
"unicode/utf8"
|
"unicode/utf8"
|
||||||
|
|
||||||
"golang.org/x/text/cases"
|
|
||||||
"golang.org/x/text/language"
|
|
||||||
"golang.org/x/text/runes"
|
"golang.org/x/text/runes"
|
||||||
"golang.org/x/text/secure/bidirule"
|
"golang.org/x/text/secure/bidirule"
|
||||||
"golang.org/x/text/transform"
|
"golang.org/x/text/transform"
|
||||||
|
@ -93,80 +90,32 @@ type buffers struct {
|
||||||
next int
|
next int
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *buffers) apply(t transform.SpanningTransformer) (err error) {
|
func (b *buffers) init(n int) {
|
||||||
n, err := t.Span(b.src, true)
|
b.buf[0] = make([]byte, 0, n)
|
||||||
if err != transform.ErrEndOfSpan {
|
b.buf[1] = make([]byte, 0, n)
|
||||||
return err
|
}
|
||||||
}
|
|
||||||
|
func (b *buffers) apply(t transform.Transformer) (err error) {
|
||||||
|
// TODO: use Span, once available.
|
||||||
x := b.next & 1
|
x := b.next & 1
|
||||||
if b.buf[x] == nil {
|
b.src, _, err = transform.Append(t, b.buf[x][:0], b.src)
|
||||||
b.buf[x] = make([]byte, 0, 8+len(b.src)+len(b.src)>>2)
|
|
||||||
}
|
|
||||||
span := append(b.buf[x][:0], b.src[:n]...)
|
|
||||||
b.src, _, err = transform.Append(t, span, b.src[n:])
|
|
||||||
b.buf[x] = b.src
|
b.buf[x] = b.src
|
||||||
b.next++
|
b.next++
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pre-allocate transformers when possible. In some cases this avoids allocation.
|
func (b *buffers) enforce(p *Profile, src []byte) (str []byte, err error) {
|
||||||
var (
|
|
||||||
foldWidthT transform.SpanningTransformer = width.Fold
|
|
||||||
lowerCaseT transform.SpanningTransformer = cases.Lower(language.Und, cases.HandleFinalSigma(false))
|
|
||||||
)
|
|
||||||
|
|
||||||
// TODO: make this a method on profile.
|
|
||||||
|
|
||||||
func (b *buffers) enforce(p *Profile, src []byte, comparing bool) (str []byte, err error) {
|
|
||||||
b.src = src
|
b.src = src
|
||||||
|
|
||||||
ascii := true
|
|
||||||
for _, c := range src {
|
|
||||||
if c >= utf8.RuneSelf {
|
|
||||||
ascii = false
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// ASCII fast path.
|
|
||||||
if ascii {
|
|
||||||
for _, f := range p.options.additional {
|
|
||||||
if err = b.apply(f()); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
switch {
|
|
||||||
case p.options.asciiLower || (comparing && p.options.ignorecase):
|
|
||||||
for i, c := range b.src {
|
|
||||||
if 'A' <= c && c <= 'Z' {
|
|
||||||
b.src[i] = c ^ 1<<5
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case p.options.cases != nil:
|
|
||||||
b.apply(p.options.cases)
|
|
||||||
}
|
|
||||||
c := checker{p: p}
|
|
||||||
if _, err := c.span(b.src, true); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if p.disallow != nil {
|
|
||||||
for _, c := range b.src {
|
|
||||||
if p.disallow.Contains(rune(c)) {
|
|
||||||
return nil, errDisallowedRune
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if p.options.disallowEmpty && len(b.src) == 0 {
|
|
||||||
return nil, errEmptyString
|
|
||||||
}
|
|
||||||
return b.src, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// These transforms are applied in the order defined in
|
// These transforms are applied in the order defined in
|
||||||
// https://tools.ietf.org/html/rfc7564#section-7
|
// https://tools.ietf.org/html/rfc7564#section-7
|
||||||
|
|
||||||
// TODO: allow different width transforms options.
|
// TODO: allow different width transforms options.
|
||||||
if p.options.foldWidth || (p.options.ignorecase && comparing) {
|
if p.options.foldWidth {
|
||||||
b.apply(foldWidthT)
|
// TODO: use Span, once available.
|
||||||
|
if err = b.apply(width.Fold); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
for _, f := range p.options.additional {
|
for _, f := range p.options.additional {
|
||||||
if err = b.apply(f()); err != nil {
|
if err = b.apply(f()); err != nil {
|
||||||
|
@ -174,14 +123,24 @@ func (b *buffers) enforce(p *Profile, src []byte, comparing bool) (str []byte, e
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if p.options.cases != nil {
|
if p.options.cases != nil {
|
||||||
b.apply(p.options.cases)
|
if err = b.apply(p.options.cases); err != nil {
|
||||||
|
return nil, err
|
||||||
}
|
}
|
||||||
if comparing && p.options.ignorecase {
|
|
||||||
b.apply(lowerCaseT)
|
|
||||||
}
|
}
|
||||||
b.apply(p.norm)
|
if n := p.norm.QuickSpan(b.src); n < len(b.src) {
|
||||||
if p.options.bidiRule && !bidirule.Valid(b.src) {
|
x := b.next & 1
|
||||||
return nil, bidirule.ErrInvalid
|
n = copy(b.buf[x], b.src[:n])
|
||||||
|
b.src, _, err = transform.Append(p.norm, b.buf[x][:n], b.src[n:])
|
||||||
|
b.buf[x] = b.src
|
||||||
|
b.next++
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if p.options.bidiRule {
|
||||||
|
if err := b.apply(bidirule.New()); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
c := checker{p: p}
|
c := checker{p: p}
|
||||||
if _, err := c.span(b.src, true); err != nil {
|
if _, err := c.span(b.src, true); err != nil {
|
||||||
|
@ -196,6 +155,9 @@ func (b *buffers) enforce(p *Profile, src []byte, comparing bool) (str []byte, e
|
||||||
i += size
|
i += size
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Add the disallow empty rule with a dummy transformer?
|
||||||
|
|
||||||
if p.options.disallowEmpty && len(b.src) == 0 {
|
if p.options.disallowEmpty && len(b.src) == 0 {
|
||||||
return nil, errEmptyString
|
return nil, errEmptyString
|
||||||
}
|
}
|
||||||
|
@ -206,16 +168,19 @@ func (b *buffers) enforce(p *Profile, src []byte, comparing bool) (str []byte, e
|
||||||
// It returns an error if the input string is invalid.
|
// It returns an error if the input string is invalid.
|
||||||
func (p *Profile) Append(dst, src []byte) ([]byte, error) {
|
func (p *Profile) Append(dst, src []byte) ([]byte, error) {
|
||||||
var buf buffers
|
var buf buffers
|
||||||
b, err := buf.enforce(p, src, false)
|
buf.init(8 + len(src) + len(src)>>2)
|
||||||
|
b, err := buf.enforce(p, src)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return append(dst, b...), nil
|
return append(dst, b...), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func processBytes(p *Profile, b []byte, key bool) ([]byte, error) {
|
// Bytes returns a new byte slice with the result of applying the profile to b.
|
||||||
|
func (p *Profile) Bytes(b []byte) ([]byte, error) {
|
||||||
var buf buffers
|
var buf buffers
|
||||||
b, err := buf.enforce(p, b, key)
|
buf.init(8 + len(b) + len(b)>>2)
|
||||||
|
b, err := buf.enforce(p, b)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -227,62 +192,39 @@ func processBytes(p *Profile, b []byte, key bool) ([]byte, error) {
|
||||||
return b, nil
|
return b, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bytes returns a new byte slice with the result of applying the profile to b.
|
// String returns a string with the result of applying the profile to s.
|
||||||
func (p *Profile) Bytes(b []byte) ([]byte, error) {
|
func (p *Profile) String(s string) (string, error) {
|
||||||
return processBytes(p, b, false)
|
|
||||||
}
|
|
||||||
|
|
||||||
// AppendCompareKey appends the result of applying p to src (including any
|
|
||||||
// optional rules to make strings comparable or useful in a map key such as
|
|
||||||
// applying lowercasing) writing the result to dst. It returns an error if the
|
|
||||||
// input string is invalid.
|
|
||||||
func (p *Profile) AppendCompareKey(dst, src []byte) ([]byte, error) {
|
|
||||||
var buf buffers
|
var buf buffers
|
||||||
b, err := buf.enforce(p, src, true)
|
buf.init(8 + len(s) + len(s)>>2)
|
||||||
if err != nil {
|
b, err := buf.enforce(p, []byte(s))
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return append(dst, b...), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func processString(p *Profile, s string, key bool) (string, error) {
|
|
||||||
var buf buffers
|
|
||||||
b, err := buf.enforce(p, []byte(s), key)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
return string(b), nil
|
return string(b), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// String returns a string with the result of applying the profile to s.
|
|
||||||
func (p *Profile) String(s string) (string, error) {
|
|
||||||
return processString(p, s, false)
|
|
||||||
}
|
|
||||||
|
|
||||||
// CompareKey returns a string that can be used for comparison, hashing, or
|
|
||||||
// collation.
|
|
||||||
func (p *Profile) CompareKey(s string) (string, error) {
|
|
||||||
return processString(p, s, true)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compare enforces both strings, and then compares them for bit-string identity
|
// Compare enforces both strings, and then compares them for bit-string identity
|
||||||
// (byte-for-byte equality). If either string cannot be enforced, the comparison
|
// (byte-for-byte equality). If either string cannot be enforced, the comparison
|
||||||
// is false.
|
// is false.
|
||||||
func (p *Profile) Compare(a, b string) bool {
|
func (p *Profile) Compare(a, b string) bool {
|
||||||
var buf buffers
|
a, err := p.String(a)
|
||||||
|
if err != nil {
|
||||||
akey, err := buf.enforce(p, []byte(a), true)
|
return false
|
||||||
|
}
|
||||||
|
b, err = p.String(b)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
buf = buffers{}
|
// TODO: This is out of order. Need to extract the transformation logic and
|
||||||
bkey, err := buf.enforce(p, []byte(b), true)
|
// put this in where the normal case folding would go (but only for
|
||||||
if err != nil {
|
// comparison).
|
||||||
return false
|
if p.options.ignorecase {
|
||||||
|
a = width.Fold.String(a)
|
||||||
|
b = width.Fold.String(a)
|
||||||
}
|
}
|
||||||
|
|
||||||
return bytes.Compare(akey, bkey) == 0
|
return a == b
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allowed returns a runes.Set containing every rune that is a member of the
|
// Allowed returns a runes.Set containing every rune that is a member of the
|
||||||
|
|
47
vendor/golang.org/x/text/secure/precis/profiles.go
generated
vendored
47
vendor/golang.org/x/text/secure/precis/profiles.go
generated
vendored
|
@ -19,51 +19,38 @@ var (
|
||||||
OpaqueString *Profile = opaquestring // Implements the OpaqueString profile defined in RFC 7613 for passwords and other secure labels.
|
OpaqueString *Profile = opaquestring // Implements the OpaqueString profile defined in RFC 7613 for passwords and other secure labels.
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// TODO: mvl: "Ultimately, I would manually define the structs for the internal
|
||||||
|
// profiles. This avoid pulling in unneeded tables when they are not used."
|
||||||
var (
|
var (
|
||||||
nickname = &Profile{
|
nickname = NewFreeform(
|
||||||
options: getOpts(
|
|
||||||
AdditionalMapping(func() transform.Transformer {
|
AdditionalMapping(func() transform.Transformer {
|
||||||
return &nickAdditionalMapping{}
|
return &nickAdditionalMapping{}
|
||||||
}),
|
}),
|
||||||
IgnoreCase,
|
IgnoreCase,
|
||||||
Norm(norm.NFKC),
|
Norm(norm.NFKC),
|
||||||
DisallowEmpty,
|
DisallowEmpty,
|
||||||
),
|
)
|
||||||
class: freeform,
|
usernameCaseMap = NewIdentifier(
|
||||||
}
|
|
||||||
usernameCaseMap = &Profile{
|
|
||||||
options: getOpts(
|
|
||||||
FoldWidth,
|
FoldWidth,
|
||||||
LowerCase(),
|
FoldCase(),
|
||||||
Norm(norm.NFC),
|
Norm(norm.NFC),
|
||||||
BidiRule,
|
BidiRule,
|
||||||
),
|
)
|
||||||
class: identifier,
|
usernameNoCaseMap = NewIdentifier(
|
||||||
}
|
|
||||||
usernameNoCaseMap = &Profile{
|
|
||||||
options: getOpts(
|
|
||||||
FoldWidth,
|
FoldWidth,
|
||||||
Norm(norm.NFC),
|
Norm(norm.NFC),
|
||||||
BidiRule,
|
BidiRule,
|
||||||
),
|
)
|
||||||
class: identifier,
|
opaquestring = NewFreeform(
|
||||||
}
|
|
||||||
opaquestring = &Profile{
|
|
||||||
options: getOpts(
|
|
||||||
AdditionalMapping(func() transform.Transformer {
|
AdditionalMapping(func() transform.Transformer {
|
||||||
return mapSpaces
|
return runes.Map(func(r rune) rune {
|
||||||
}),
|
|
||||||
Norm(norm.NFC),
|
|
||||||
DisallowEmpty,
|
|
||||||
),
|
|
||||||
class: freeform,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
// mapSpaces is a shared value of a runes.Map transformer.
|
|
||||||
var mapSpaces transform.Transformer = runes.Map(func(r rune) rune {
|
|
||||||
if unicode.Is(unicode.Zs, r) {
|
if unicode.Is(unicode.Zs, r) {
|
||||||
return ' '
|
return ' '
|
||||||
}
|
}
|
||||||
return r
|
return r
|
||||||
})
|
})
|
||||||
|
}),
|
||||||
|
Norm(norm.NFC),
|
||||||
|
DisallowEmpty,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
52
vendor/golang.org/x/text/transform/transform.go
generated
vendored
52
vendor/golang.org/x/text/transform/transform.go
generated
vendored
|
@ -24,10 +24,6 @@ var (
|
||||||
// complete the transformation.
|
// complete the transformation.
|
||||||
ErrShortSrc = errors.New("transform: short source buffer")
|
ErrShortSrc = errors.New("transform: short source buffer")
|
||||||
|
|
||||||
// ErrEndOfSpan means that the input and output (the transformed input)
|
|
||||||
// are not identical.
|
|
||||||
ErrEndOfSpan = errors.New("transform: input and output are not identical")
|
|
||||||
|
|
||||||
// errInconsistentByteCount means that Transform returned success (nil
|
// errInconsistentByteCount means that Transform returned success (nil
|
||||||
// error) but also returned nSrc inconsistent with the src argument.
|
// error) but also returned nSrc inconsistent with the src argument.
|
||||||
errInconsistentByteCount = errors.New("transform: inconsistent byte count returned")
|
errInconsistentByteCount = errors.New("transform: inconsistent byte count returned")
|
||||||
|
@ -64,41 +60,6 @@ type Transformer interface {
|
||||||
Reset()
|
Reset()
|
||||||
}
|
}
|
||||||
|
|
||||||
// SpanningTransformer extends the Transformer interface with a Span method
|
|
||||||
// that determines how much of the input already conforms to the Transformer.
|
|
||||||
type SpanningTransformer interface {
|
|
||||||
Transformer
|
|
||||||
|
|
||||||
// Span returns a position in src such that transforming src[:n] results in
|
|
||||||
// identical output src[:n] for these bytes. It does not necessarily return
|
|
||||||
// the largest such n. The atEOF argument tells whether src represents the
|
|
||||||
// last bytes of the input.
|
|
||||||
//
|
|
||||||
// Callers should always account for the n bytes consumed before
|
|
||||||
// considering the error err.
|
|
||||||
//
|
|
||||||
// A nil error means that all input bytes are known to be identical to the
|
|
||||||
// output produced by the Transformer. A nil error can be be returned
|
|
||||||
// regardless of whether atEOF is true. If err is nil, then then n must
|
|
||||||
// equal len(src); the converse is not necessarily true.
|
|
||||||
//
|
|
||||||
// ErrEndOfSpan means that the Transformer output may differ from the
|
|
||||||
// input after n bytes. Note that n may be len(src), meaning that the output
|
|
||||||
// would contain additional bytes after otherwise identical output.
|
|
||||||
// ErrShortSrc means that src had insufficient data to determine whether the
|
|
||||||
// remaining bytes would change. Other than the error conditions listed
|
|
||||||
// here, implementations are free to report other errors that arise.
|
|
||||||
//
|
|
||||||
// Calling Span can modify the Transformer state as a side effect. In
|
|
||||||
// effect, it does the transformation just as calling Transform would, only
|
|
||||||
// without copying to a destination buffer and only up to a point it can
|
|
||||||
// determine the input and output bytes are the same. This is obviously more
|
|
||||||
// limited than calling Transform, but can be more efficient in terms of
|
|
||||||
// copying and allocating buffers. Calls to Span and Transform may be
|
|
||||||
// interleaved.
|
|
||||||
Span(src []byte, atEOF bool) (n int, err error)
|
|
||||||
}
|
|
||||||
|
|
||||||
// NopResetter can be embedded by implementations of Transformer to add a nop
|
// NopResetter can be embedded by implementations of Transformer to add a nop
|
||||||
// Reset method.
|
// Reset method.
|
||||||
type NopResetter struct{}
|
type NopResetter struct{}
|
||||||
|
@ -317,10 +278,6 @@ func (nop) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
|
||||||
return n, n, err
|
return n, n, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (nop) Span(src []byte, atEOF bool) (n int, err error) {
|
|
||||||
return len(src), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type discard struct{ NopResetter }
|
type discard struct{ NopResetter }
|
||||||
|
|
||||||
func (discard) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
|
func (discard) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
|
||||||
|
@ -332,8 +289,8 @@ var (
|
||||||
// by consuming all bytes and writing nothing.
|
// by consuming all bytes and writing nothing.
|
||||||
Discard Transformer = discard{}
|
Discard Transformer = discard{}
|
||||||
|
|
||||||
// Nop is a SpanningTransformer that copies src to dst.
|
// Nop is a Transformer that copies src to dst.
|
||||||
Nop SpanningTransformer = nop{}
|
Nop Transformer = nop{}
|
||||||
)
|
)
|
||||||
|
|
||||||
// chain is a sequence of links. A chain with N Transformers has N+1 links and
|
// chain is a sequence of links. A chain with N Transformers has N+1 links and
|
||||||
|
@ -401,8 +358,6 @@ func (c *chain) Reset() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: make chain use Span (is going to be fun to implement!)
|
|
||||||
|
|
||||||
// Transform applies the transformers of c in sequence.
|
// Transform applies the transformers of c in sequence.
|
||||||
func (c *chain) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
|
func (c *chain) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
|
||||||
// Set up src and dst in the chain.
|
// Set up src and dst in the chain.
|
||||||
|
@ -493,7 +448,8 @@ func (c *chain) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err erro
|
||||||
return dstL.n, srcL.p, err
|
return dstL.n, srcL.p, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Deprecated: use runes.Remove instead.
|
// RemoveFunc returns a Transformer that removes from the input all runes r for
|
||||||
|
// which f(r) is true. Illegal bytes in the input are replaced by RuneError.
|
||||||
func RemoveFunc(f func(r rune) bool) Transformer {
|
func RemoveFunc(f func(r rune) bool) Transformer {
|
||||||
return removeF(f)
|
return removeF(f)
|
||||||
}
|
}
|
||||||
|
|
42
vendor/golang.org/x/text/unicode/bidi/bracket.go
generated
vendored
42
vendor/golang.org/x/text/unicode/bidi/bracket.go
generated
vendored
|
@ -84,7 +84,7 @@ func resolvePairedBrackets(s *isolatingRunSequence) {
|
||||||
dirEmbed = R
|
dirEmbed = R
|
||||||
}
|
}
|
||||||
p.locateBrackets(s.p.pairTypes, s.p.pairValues)
|
p.locateBrackets(s.p.pairTypes, s.p.pairValues)
|
||||||
p.resolveBrackets(dirEmbed, s.p.initialTypes)
|
p.resolveBrackets(dirEmbed)
|
||||||
}
|
}
|
||||||
|
|
||||||
type bracketPairer struct {
|
type bracketPairer struct {
|
||||||
|
@ -125,8 +125,6 @@ func (p *bracketPairer) matchOpener(pairValues []rune, opener, closer int) bool
|
||||||
return pairValues[p.indexes[opener]] == pairValues[p.indexes[closer]]
|
return pairValues[p.indexes[opener]] == pairValues[p.indexes[closer]]
|
||||||
}
|
}
|
||||||
|
|
||||||
const maxPairingDepth = 63
|
|
||||||
|
|
||||||
// locateBrackets locates matching bracket pairs according to BD16.
|
// locateBrackets locates matching bracket pairs according to BD16.
|
||||||
//
|
//
|
||||||
// This implementation uses a linked list instead of a stack, because, while
|
// This implementation uses a linked list instead of a stack, because, while
|
||||||
|
@ -138,17 +136,11 @@ func (p *bracketPairer) locateBrackets(pairTypes []bracketType, pairValues []run
|
||||||
for i, index := range p.indexes {
|
for i, index := range p.indexes {
|
||||||
|
|
||||||
// look at the bracket type for each character
|
// look at the bracket type for each character
|
||||||
if pairTypes[index] == bpNone || p.codesIsolatedRun[i] != ON {
|
|
||||||
// continue scanning
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
switch pairTypes[index] {
|
switch pairTypes[index] {
|
||||||
|
case bpNone:
|
||||||
|
// continue scanning
|
||||||
|
|
||||||
case bpOpen:
|
case bpOpen:
|
||||||
// check if maximum pairing depth reached
|
|
||||||
if p.openers.Len() == maxPairingDepth {
|
|
||||||
p.openers.Init()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// remember opener location, most recent first
|
// remember opener location, most recent first
|
||||||
p.openers.PushFront(i)
|
p.openers.PushFront(i)
|
||||||
|
|
||||||
|
@ -278,7 +270,7 @@ func (p *bracketPairer) classBeforePair(loc bracketPair) Class {
|
||||||
}
|
}
|
||||||
|
|
||||||
// assignBracketType implements rule N0 for a single bracket pair.
|
// assignBracketType implements rule N0 for a single bracket pair.
|
||||||
func (p *bracketPairer) assignBracketType(loc bracketPair, dirEmbed Class, initialTypes []Class) {
|
func (p *bracketPairer) assignBracketType(loc bracketPair, dirEmbed Class) {
|
||||||
// rule "N0, a", inspect contents of pair
|
// rule "N0, a", inspect contents of pair
|
||||||
dirPair := p.classifyPairContent(loc, dirEmbed)
|
dirPair := p.classifyPairContent(loc, dirEmbed)
|
||||||
|
|
||||||
|
@ -303,33 +295,13 @@ func (p *bracketPairer) assignBracketType(loc bracketPair, dirEmbed Class, initi
|
||||||
// direction
|
// direction
|
||||||
|
|
||||||
// set the bracket types to the type found
|
// set the bracket types to the type found
|
||||||
p.setBracketsToType(loc, dirPair, initialTypes)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *bracketPairer) setBracketsToType(loc bracketPair, dirPair Class, initialTypes []Class) {
|
|
||||||
p.codesIsolatedRun[loc.opener] = dirPair
|
p.codesIsolatedRun[loc.opener] = dirPair
|
||||||
p.codesIsolatedRun[loc.closer] = dirPair
|
p.codesIsolatedRun[loc.closer] = dirPair
|
||||||
|
|
||||||
for i := loc.opener + 1; i < loc.closer; i++ {
|
|
||||||
index := p.indexes[i]
|
|
||||||
if initialTypes[index] != NSM {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
p.codesIsolatedRun[i] = dirPair
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := loc.closer + 1; i < len(p.indexes); i++ {
|
|
||||||
index := p.indexes[i]
|
|
||||||
if initialTypes[index] != NSM {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
p.codesIsolatedRun[i] = dirPair
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// resolveBrackets implements rule N0 for a list of pairs.
|
// resolveBrackets implements rule N0 for a list of pairs.
|
||||||
func (p *bracketPairer) resolveBrackets(dirEmbed Class, initialTypes []Class) {
|
func (p *bracketPairer) resolveBrackets(dirEmbed Class) {
|
||||||
for _, loc := range p.pairPositions {
|
for _, loc := range p.pairPositions {
|
||||||
p.assignBracketType(loc, dirEmbed, initialTypes)
|
p.assignBracketType(loc, dirEmbed)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
3
vendor/golang.org/x/text/unicode/bidi/core.go
generated
vendored
3
vendor/golang.org/x/text/unicode/bidi/core.go
generated
vendored
|
@ -309,9 +309,6 @@ func (p *paragraph) determineExplicitEmbeddingLevels() {
|
||||||
}
|
}
|
||||||
if isIsolate {
|
if isIsolate {
|
||||||
p.resultLevels[i] = stack.lastEmbeddingLevel()
|
p.resultLevels[i] = stack.lastEmbeddingLevel()
|
||||||
if stack.lastDirectionalOverrideStatus() != ON {
|
|
||||||
p.resultTypes[i] = stack.lastDirectionalOverrideStatus()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var newLevel level
|
var newLevel level
|
||||||
|
|
36
vendor/golang.org/x/text/unicode/norm/normalize.go
generated
vendored
36
vendor/golang.org/x/text/unicode/norm/normalize.go
generated
vendored
|
@ -8,11 +8,7 @@
|
||||||
// Package norm contains types and functions for normalizing Unicode strings.
|
// Package norm contains types and functions for normalizing Unicode strings.
|
||||||
package norm // import "golang.org/x/text/unicode/norm"
|
package norm // import "golang.org/x/text/unicode/norm"
|
||||||
|
|
||||||
import (
|
import "unicode/utf8"
|
||||||
"unicode/utf8"
|
|
||||||
|
|
||||||
"golang.org/x/text/transform"
|
|
||||||
)
|
|
||||||
|
|
||||||
// A Form denotes a canonical representation of Unicode code points.
|
// A Form denotes a canonical representation of Unicode code points.
|
||||||
// The Unicode-defined normalization and equivalence forms are:
|
// The Unicode-defined normalization and equivalence forms are:
|
||||||
|
@ -267,34 +263,6 @@ func (f Form) QuickSpan(b []byte) int {
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
// Span implements transform.SpanningTransformer. It returns a boundary n such
|
|
||||||
// that b[0:n] == f(b[0:n]). It is not guaranteed to return the largest such n.
|
|
||||||
func (f Form) Span(b []byte, atEOF bool) (n int, err error) {
|
|
||||||
n, ok := formTable[f].quickSpan(inputBytes(b), 0, len(b), atEOF)
|
|
||||||
if n < len(b) {
|
|
||||||
if !ok {
|
|
||||||
err = transform.ErrEndOfSpan
|
|
||||||
} else {
|
|
||||||
err = transform.ErrShortSrc
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return n, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// SpanString returns a boundary n such that s[0:n] == f(s[0:n]).
|
|
||||||
// It is not guaranteed to return the largest such n.
|
|
||||||
func (f Form) SpanString(s string, atEOF bool) (n int, err error) {
|
|
||||||
n, ok := formTable[f].quickSpan(inputString(s), 0, len(s), atEOF)
|
|
||||||
if n < len(s) {
|
|
||||||
if !ok {
|
|
||||||
err = transform.ErrEndOfSpan
|
|
||||||
} else {
|
|
||||||
err = transform.ErrShortSrc
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return n, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// quickSpan returns a boundary n such that src[0:n] == f(src[0:n]) and
|
// quickSpan returns a boundary n such that src[0:n] == f(src[0:n]) and
|
||||||
// whether any non-normalized parts were found. If atEOF is false, n will
|
// whether any non-normalized parts were found. If atEOF is false, n will
|
||||||
// not point past the last segment if this segment might be become
|
// not point past the last segment if this segment might be become
|
||||||
|
@ -353,7 +321,7 @@ func (f *formInfo) quickSpan(src input, i, end int, atEOF bool) (n int, ok bool)
|
||||||
return lastSegStart, false
|
return lastSegStart, false
|
||||||
}
|
}
|
||||||
|
|
||||||
// QuickSpanString returns a boundary n such that s[0:n] == f(s[0:n]).
|
// QuickSpanString returns a boundary n such that b[0:n] == f(s[0:n]).
|
||||||
// It is not guaranteed to return the largest such n.
|
// It is not guaranteed to return the largest such n.
|
||||||
func (f Form) QuickSpanString(s string) int {
|
func (f Form) QuickSpanString(s string) int {
|
||||||
n, _ := formTable[f].quickSpan(inputString(s), 0, len(s), true)
|
n, _ := formTable[f].quickSpan(inputString(s), 0, len(s), true)
|
||||||
|
|
1
vendor/golang.org/x/text/unicode/norm/readwriter.go
generated
vendored
1
vendor/golang.org/x/text/unicode/norm/readwriter.go
generated
vendored
|
@ -112,6 +112,7 @@ func (r *normReader) Read(p []byte) (int, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
panic("should not reach here")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reader returns a new reader that implements Read
|
// Reader returns a new reader that implements Read
|
||||||
|
|
77
vendor/golang.org/x/text/width/transform.go
generated
vendored
77
vendor/golang.org/x/text/width/transform.go
generated
vendored
|
@ -14,32 +14,6 @@ type foldTransform struct {
|
||||||
transform.NopResetter
|
transform.NopResetter
|
||||||
}
|
}
|
||||||
|
|
||||||
func (foldTransform) Span(src []byte, atEOF bool) (n int, err error) {
|
|
||||||
for n < len(src) {
|
|
||||||
if src[n] < utf8.RuneSelf {
|
|
||||||
// ASCII fast path.
|
|
||||||
for n++; n < len(src) && src[n] < utf8.RuneSelf; n++ {
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
v, size := trie.lookup(src[n:])
|
|
||||||
if size == 0 { // incomplete UTF-8 encoding
|
|
||||||
if !atEOF {
|
|
||||||
err = transform.ErrShortSrc
|
|
||||||
} else {
|
|
||||||
n = len(src)
|
|
||||||
}
|
|
||||||
break
|
|
||||||
}
|
|
||||||
if elem(v)&tagNeedsFold != 0 {
|
|
||||||
err = transform.ErrEndOfSpan
|
|
||||||
break
|
|
||||||
}
|
|
||||||
n += size
|
|
||||||
}
|
|
||||||
return n, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (foldTransform) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
|
func (foldTransform) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
|
||||||
for nSrc < len(src) {
|
for nSrc < len(src) {
|
||||||
if src[nSrc] < utf8.RuneSelf {
|
if src[nSrc] < utf8.RuneSelf {
|
||||||
|
@ -96,33 +70,6 @@ type narrowTransform struct {
|
||||||
transform.NopResetter
|
transform.NopResetter
|
||||||
}
|
}
|
||||||
|
|
||||||
func (narrowTransform) Span(src []byte, atEOF bool) (n int, err error) {
|
|
||||||
for n < len(src) {
|
|
||||||
if src[n] < utf8.RuneSelf {
|
|
||||||
// ASCII fast path.
|
|
||||||
for n++; n < len(src) && src[n] < utf8.RuneSelf; n++ {
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
v, size := trie.lookup(src[n:])
|
|
||||||
if size == 0 { // incomplete UTF-8 encoding
|
|
||||||
if !atEOF {
|
|
||||||
err = transform.ErrShortSrc
|
|
||||||
} else {
|
|
||||||
n = len(src)
|
|
||||||
}
|
|
||||||
break
|
|
||||||
}
|
|
||||||
if k := elem(v).kind(); byte(v) == 0 || k != EastAsianFullwidth && k != EastAsianWide && k != EastAsianAmbiguous {
|
|
||||||
} else {
|
|
||||||
err = transform.ErrEndOfSpan
|
|
||||||
break
|
|
||||||
}
|
|
||||||
n += size
|
|
||||||
}
|
|
||||||
return n, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (narrowTransform) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
|
func (narrowTransform) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
|
||||||
for nSrc < len(src) {
|
for nSrc < len(src) {
|
||||||
if src[nSrc] < utf8.RuneSelf {
|
if src[nSrc] < utf8.RuneSelf {
|
||||||
|
@ -179,30 +126,6 @@ type wideTransform struct {
|
||||||
transform.NopResetter
|
transform.NopResetter
|
||||||
}
|
}
|
||||||
|
|
||||||
func (wideTransform) Span(src []byte, atEOF bool) (n int, err error) {
|
|
||||||
for n < len(src) {
|
|
||||||
// TODO: Consider ASCII fast path. Special-casing ASCII handling can
|
|
||||||
// reduce the ns/op of BenchmarkWideASCII by about 30%. This is probably
|
|
||||||
// not enough to warrant the extra code and complexity.
|
|
||||||
v, size := trie.lookup(src[n:])
|
|
||||||
if size == 0 { // incomplete UTF-8 encoding
|
|
||||||
if !atEOF {
|
|
||||||
err = transform.ErrShortSrc
|
|
||||||
} else {
|
|
||||||
n = len(src)
|
|
||||||
}
|
|
||||||
break
|
|
||||||
}
|
|
||||||
if k := elem(v).kind(); byte(v) == 0 || k != EastAsianHalfwidth && k != EastAsianNarrow {
|
|
||||||
} else {
|
|
||||||
err = transform.ErrEndOfSpan
|
|
||||||
break
|
|
||||||
}
|
|
||||||
n += size
|
|
||||||
}
|
|
||||||
return n, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (wideTransform) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
|
func (wideTransform) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
|
||||||
for nSrc < len(src) {
|
for nSrc < len(src) {
|
||||||
// TODO: Consider ASCII fast path. Special-casing ASCII handling can
|
// TODO: Consider ASCII fast path. Special-casing ASCII handling can
|
||||||
|
|
9
vendor/golang.org/x/text/width/width.go
generated
vendored
9
vendor/golang.org/x/text/width/width.go
generated
vendored
|
@ -153,22 +153,17 @@ func (p Properties) Wide() rune {
|
||||||
|
|
||||||
// Transformer implements the transform.Transformer interface.
|
// Transformer implements the transform.Transformer interface.
|
||||||
type Transformer struct {
|
type Transformer struct {
|
||||||
t transform.SpanningTransformer
|
t transform.Transformer
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset implements the transform.Transformer interface.
|
// Reset implements the transform.Transformer interface.
|
||||||
func (t Transformer) Reset() { t.t.Reset() }
|
func (t Transformer) Reset() { t.t.Reset() }
|
||||||
|
|
||||||
// Transform implements the transform.Transformer interface.
|
// Transform implements the Transformer interface.
|
||||||
func (t Transformer) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
|
func (t Transformer) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
|
||||||
return t.t.Transform(dst, src, atEOF)
|
return t.t.Transform(dst, src, atEOF)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Span implements the transform.SpanningTransformer interface.
|
|
||||||
func (t Transformer) Span(src []byte, atEOF bool) (n int, err error) {
|
|
||||||
return t.t.Span(src, atEOF)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Bytes returns a new byte slice with the result of applying t to b.
|
// Bytes returns a new byte slice with the result of applying t to b.
|
||||||
func (t Transformer) Bytes(b []byte) []byte {
|
func (t Transformer) Bytes(b []byte) []byte {
|
||||||
b, _, _ = transform.Bytes(t, b)
|
b, _, _ = transform.Bytes(t, b)
|
||||||
|
|
36
vendor/google.golang.org/appengine/appengine.go
generated
vendored
36
vendor/google.golang.org/appengine/appengine.go
generated
vendored
|
@ -17,6 +17,42 @@ import (
|
||||||
"google.golang.org/appengine/internal"
|
"google.golang.org/appengine/internal"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// The gophers party all night; the rabbits provide the beats.
|
||||||
|
|
||||||
|
// Main is the principal entry point for an app running in App Engine.
|
||||||
|
//
|
||||||
|
// On App Engine Flexible it installs a trivial health checker if one isn't
|
||||||
|
// already registered, and starts listening on port 8080 (overridden by the
|
||||||
|
// $PORT environment variable).
|
||||||
|
//
|
||||||
|
// See https://cloud.google.com/appengine/docs/flexible/custom-runtimes#health_check_requests
|
||||||
|
// for details on how to do your own health checking.
|
||||||
|
//
|
||||||
|
// Main is not yet supported on App Engine Standard.
|
||||||
|
//
|
||||||
|
// Main never returns.
|
||||||
|
//
|
||||||
|
// Main is designed so that the app's main package looks like this:
|
||||||
|
//
|
||||||
|
// package main
|
||||||
|
//
|
||||||
|
// import (
|
||||||
|
// "google.golang.org/appengine"
|
||||||
|
//
|
||||||
|
// _ "myapp/package0"
|
||||||
|
// _ "myapp/package1"
|
||||||
|
// )
|
||||||
|
//
|
||||||
|
// func main() {
|
||||||
|
// appengine.Main()
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// The "myapp/packageX" packages are expected to register HTTP handlers
|
||||||
|
// in their init functions.
|
||||||
|
func Main() {
|
||||||
|
internal.Main()
|
||||||
|
}
|
||||||
|
|
||||||
// IsDevAppServer reports whether the App Engine app is running in the
|
// IsDevAppServer reports whether the App Engine app is running in the
|
||||||
// development App Server.
|
// development App Server.
|
||||||
func IsDevAppServer() bool {
|
func IsDevAppServer() bool {
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue