From ed22bba4b17ce5fe1a1f625049cc678b04f81b79 Mon Sep 17 00:00:00 2001 From: Manfred Touron Date: Tue, 5 Jul 2016 09:39:04 +0200 Subject: [PATCH 01/17] Add {Host,Config}.String() helper --- pkg/config/config.go | 6 ++++++ pkg/config/host.go | 7 +++++++ 2 files changed, 13 insertions(+) diff --git a/pkg/config/config.go b/pkg/config/config.go index 6fefa8b48..8248cbfa9 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -41,6 +41,12 @@ func SetASSHBinaryPath(path string) { asshBinaryPath = path } +// String returns the JSON output +func (c *Config) String() string { + s, _ := json.Marshal(c) + return string(s) +} + // SaveNewKnownHost registers the target as a new known host and save the full known hosts list on disk func (c *Config) SaveNewKnownHost(target string) { c.addKnownHost(target) diff --git a/pkg/config/host.go b/pkg/config/host.go index e84ed58e5..146a2c018 100644 --- a/pkg/config/host.go +++ b/pkg/config/host.go @@ -1,6 +1,7 @@ package config import ( + "encoding/json" "fmt" "io" "strings" @@ -128,6 +129,12 @@ func NewHost(name string) *Host { } } +// String returns the JSON output +func (h *Host) String() string { + s, _ := json.Marshal(h) + return string(s) +} + // Name returns the name of a host func (h *Host) Name() string { return h.name From 4e5d3cfaf76bfd1e8b578d9f2eced8be16bbbf38 Mon Sep 17 00:00:00 2001 From: Manfred Touron Date: Tue, 5 Jul 2016 10:09:22 +0200 Subject: [PATCH 02/17] Initial version of listing --- pkg/commands/commands.go | 5 +++++ pkg/commands/list.go | 32 ++++++++++++++++++++++++++++++++ pkg/config/config.go | 6 ------ pkg/config/host.go | 24 ++++++++++++++++++++++++ 4 files changed, 61 insertions(+), 6 deletions(-) create mode 100644 pkg/commands/list.go diff --git a/pkg/commands/commands.go b/pkg/commands/commands.go index 553c937d6..945a6827c 100644 --- a/pkg/commands/commands.go +++ b/pkg/commands/commands.go @@ -66,6 +66,11 @@ var Commands = []cli.Command{ Usage: "Display system-wide information", Action: cmdInfo, }, + { + Name: "list", + Usage: "List all hosts from assh config", + Action: cmdList, + }, { Name: "wrapper", Usage: "Initialize assh, then run ssh/scp/rsync...", diff --git a/pkg/commands/list.go b/pkg/commands/list.go new file mode 100644 index 000000000..b17563da4 --- /dev/null +++ b/pkg/commands/list.go @@ -0,0 +1,32 @@ +package commands + +import ( + "fmt" + "os" + + "github.com/codegangsta/cli" + "golang.org/x/crypto/ssh/terminal" + + "github.com/mgutz/ansi" + "github.com/moul/advanced-ssh-config/pkg/config" + // . "github.com/moul/advanced-ssh-config/pkg/logger" +) + +func cmdList(c *cli.Context) { + conf, err := config.Open() + if err != nil { + panic(err) + } + + // ansi coloring + colorize := func(input string) string { return input } + if terminal.IsTerminal(int(os.Stdout.Fd())) { + colorize = ansi.ColorFunc("green+b+h") + } + + for _, host := range conf.Hosts { + host.ApplyDefaults(&conf.Defaults) + fmt.Printf(" %s -> %s\n", colorize(host.Name()), host.Prototype()) + fmt.Println() + } +} diff --git a/pkg/config/config.go b/pkg/config/config.go index 8248cbfa9..6fefa8b48 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -41,12 +41,6 @@ func SetASSHBinaryPath(path string) { asshBinaryPath = path } -// String returns the JSON output -func (c *Config) String() string { - s, _ := json.Marshal(c) - return string(s) -} - // SaveNewKnownHost registers the target as a new known host and save the full known hosts list on disk func (c *Config) SaveNewKnownHost(target string) { c.addKnownHost(target) diff --git a/pkg/config/host.go b/pkg/config/host.go index 146a2c018..df93adcba 100644 --- a/pkg/config/host.go +++ b/pkg/config/host.go @@ -4,6 +4,7 @@ import ( "encoding/json" "fmt" "io" + "os/user" "strings" ) @@ -135,6 +136,29 @@ func (h *Host) String() string { return string(s) } +// Prototype returns a prototype representation of the host, used in listings +func (h *Host) Prototype() string { + username := h.User + if username == "" { + currentUser, err := user.Current() + if err != nil { + panic(err) + } + username = currentUser.Username + } + + hostname := h.HostName + if hostname == "" { + hostname = "[hostname_not_specified]" + } + + port := h.Port + if port == "" { + port = "22" + } + return fmt.Sprintf("%s@%s:%s", username, hostname, port) +} + // Name returns the name of a host func (h *Host) Name() string { return h.name From 7d32d26e1c81709bb8ca45b4c8f05a1d639bbbcf Mon Sep 17 00:00:00 2001 From: Manfred Touron Date: Tue, 5 Jul 2016 10:27:26 +0200 Subject: [PATCH 03/17] Sort hosts list --- pkg/commands/list.go | 2 +- pkg/config/config.go | 18 ++++++++++++------ pkg/config/hostlist.go | 30 ++++++++++++++++++++++++++++++ 3 files changed, 43 insertions(+), 7 deletions(-) create mode 100644 pkg/config/hostlist.go diff --git a/pkg/commands/list.go b/pkg/commands/list.go index b17563da4..cbeb350d9 100644 --- a/pkg/commands/list.go +++ b/pkg/commands/list.go @@ -24,7 +24,7 @@ func cmdList(c *cli.Context) { colorize = ansi.ColorFunc("green+b+h") } - for _, host := range conf.Hosts { + for _, host := range conf.Hosts.SortedList() { host.ApplyDefaults(&conf.Defaults) fmt.Printf(" %s -> %s\n", colorize(host.Name()), host.Prototype()) fmt.Println() diff --git a/pkg/config/config.go b/pkg/config/config.go index 6fefa8b48..f7316c734 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -24,12 +24,12 @@ const defaultSshConfigPath string = "~/.ssh/config" // Config contains a list of Hosts sections and a Defaults section representing a configuration file type Config struct { - Hosts map[string]*Host `yaml:"hosts,omitempty,flow" json:"hosts"` - Templates map[string]*Host `yaml:"templates,omitempty,flow" json:"templates"` - Defaults Host `yaml:"defaults,omitempty,flow" json:"defaults,omitempty"` - Includes []string `yaml:"includes,omitempty,flow" json:"includes,omitempty"` - ASSHKnownHostFile string `yaml:"asshknownhostfile,omitempty,flow" json:"asshknownhostfile,omitempty"` - ASSHBinaryPath string `yaml:"asshbinarypath,omitempty,flow" json:"asshbinarypath,omitempty"` + Hosts HostsMap `yaml:"hosts,omitempty,flow" json:"hosts"` + Templates HostsMap `yaml:"templates,omitempty,flow" json:"templates"` + Defaults Host `yaml:"defaults,omitempty,flow" json:"defaults,omitempty"` + Includes []string `yaml:"includes,omitempty,flow" json:"includes,omitempty"` + ASSHKnownHostFile string `yaml:"asshknownhostfile,omitempty,flow" json:"asshknownhostfile,omitempty"` + ASSHBinaryPath string `yaml:"asshbinarypath,omitempty,flow" json:"asshbinarypath,omitempty"` includedFiles map[string]bool sshConfigPath string @@ -41,6 +41,12 @@ func SetASSHBinaryPath(path string) { asshBinaryPath = path } +// String returns the JSON output +func (c *Config) String() string { + s, _ := json.Marshal(c) + return string(s) +} + // SaveNewKnownHost registers the target as a new known host and save the full known hosts list on disk func (c *Config) SaveNewKnownHost(target string) { c.addKnownHost(target) diff --git a/pkg/config/hostlist.go b/pkg/config/hostlist.go new file mode 100644 index 000000000..b23603cd2 --- /dev/null +++ b/pkg/config/hostlist.go @@ -0,0 +1,30 @@ +package config + +import "strings" +import "sort" + +// HostsMap is a map of **Host).Name -> *Host +type HostsMap map[string]*Host + +// HostsList is a list of *Host +type HostsList []*Host + +// ToList returns a slice of *Hosts +func (hm *HostsMap) ToList() HostsList { + list := HostsList{} + for _, host := range *hm { + list = append(list, host) + } + return list +} + +func (hl HostsList) Len() int { return len(hl) } +func (hl HostsList) Swap(i, j int) { hl[i], hl[j] = hl[j], hl[i] } +func (hl HostsList) Less(i, j int) bool { return strings.Compare(hl[i].name, hl[j].name) < 0 } + +// SortedList returns a list of hosts sorted by their name +func (hm *HostsMap) SortedList() HostsList { + sortedList := hm.ToList() + sort.Sort(sortedList) + return sortedList +} From e41e29b92ae8e4893a6fe3cdc53ebc807f9f6736 Mon Sep 17 00:00:00 2001 From: Manfred Touron Date: Tue, 5 Jul 2016 11:05:33 +0200 Subject: [PATCH 04/17] Listing options --- pkg/commands/list.go | 28 +++- pkg/config/host.go | 297 +++++++++++++++++++++++++++++++++++++++++++ pkg/config/option.go | 30 +++++ 3 files changed, 352 insertions(+), 3 deletions(-) create mode 100644 pkg/config/option.go diff --git a/pkg/commands/list.go b/pkg/commands/list.go index cbeb350d9..688fcee63 100644 --- a/pkg/commands/list.go +++ b/pkg/commands/list.go @@ -3,6 +3,7 @@ package commands import ( "fmt" "os" + "strings" "github.com/codegangsta/cli" "golang.org/x/crypto/ssh/terminal" @@ -19,14 +20,35 @@ func cmdList(c *cli.Context) { } // ansi coloring - colorize := func(input string) string { return input } + greenColorize := func(input string) string { return input } + redColorize := func(input string) string { return input } + yellowColorize := func(input string) string { return input } if terminal.IsTerminal(int(os.Stdout.Fd())) { - colorize = ansi.ColorFunc("green+b+h") + greenColorize = ansi.ColorFunc("green+b+h") + redColorize = ansi.ColorFunc("red") + yellowColorize = ansi.ColorFunc("yellow") } + fmt.Printf("Listing entries\n\n") + for _, host := range conf.Hosts.SortedList() { + options := host.Options() + options.Remove("User") + options.Remove("Port") host.ApplyDefaults(&conf.Defaults) - fmt.Printf(" %s -> %s\n", colorize(host.Name()), host.Prototype()) + fmt.Printf(" %s -> %s\n", greenColorize(host.Name()), host.Prototype()) + if len(options) > 0 { + fmt.Printf(" %s %s\n", yellowColorize("[custom options]"), strings.Join(options.ToStringList(), " ")) + } + fmt.Println() + } + + generalOptions := conf.Defaults.Options() + if len(generalOptions) > 0 { + fmt.Println(greenColorize(" (*) General options:")) + for _, opt := range conf.Defaults.Options() { + fmt.Printf(" %s: %s\n", redColorize(opt.Name), opt.Value) + } fmt.Println() } } diff --git a/pkg/config/host.go b/pkg/config/host.go index df93adcba..af2527bd1 100644 --- a/pkg/config/host.go +++ b/pkg/config/host.go @@ -170,6 +170,303 @@ func (h *Host) Clone() *Host { return &newHost } +// Options returns a map of set options +func (h *Host) Options() OptionsList { + options := make(OptionsList, 0) + + // ssh-config fields + if h.AddressFamily != "" { + options = append(options, Option{Name: "AddressFamily", Value: h.AddressFamily}) + } + if h.AskPassGUI != "" { + options = append(options, Option{Name: "AskPassGUI", Value: h.AskPassGUI}) + } + if h.BatchMode != "" { + options = append(options, Option{Name: "BatchMode", Value: h.BatchMode}) + } + if h.BindAddress != "" { + options = append(options, Option{Name: "BindAddress", Value: h.BindAddress}) + } + if h.CanonicalDomains != "" { + options = append(options, Option{Name: "CanonicalDomains", Value: h.CanonicalDomains}) + } + if h.CanonicalizeFallbackLocal != "" { + options = append(options, Option{Name: "CanonicalizeFallbackLocal", Value: h.CanonicalizeFallbackLocal}) + } + if h.CanonicalizeHostname != "" { + options = append(options, Option{Name: "CanonicalizeHostname", Value: h.CanonicalizeHostname}) + } + if h.CanonicalizeMaxDots != "" { + options = append(options, Option{Name: "CanonicalizeMaxDots", Value: h.CanonicalizeMaxDots}) + } + if h.CanonicalizePermittedCNAMEs != "" { + options = append(options, Option{Name: "CanonicalizePermittedCNAMEs", Value: h.CanonicalizePermittedCNAMEs}) + } + if h.ChallengeResponseAuthentication != "" { + options = append(options, Option{Name: "ChallengeResponseAuthentication", Value: h.ChallengeResponseAuthentication}) + } + if h.CheckHostIP != "" { + options = append(options, Option{Name: "CheckHostIP", Value: h.CheckHostIP}) + } + if h.Cipher != "" { + options = append(options, Option{Name: "Cipher", Value: h.Cipher}) + } + if h.Ciphers != "" { + options = append(options, Option{Name: "Ciphers", Value: h.Ciphers}) + } + if h.ClearAllForwardings != "" { + options = append(options, Option{Name: "ClearAllForwardings", Value: h.ClearAllForwardings}) + } + if h.Compression != "" { + options = append(options, Option{Name: "Compression", Value: h.Compression}) + } + if h.CompressionLevel != 0 { + options = append(options, Option{Name: "CompressionLevel", Value: string(h.CompressionLevel)}) + } + if h.ConnectionAttempts != "" { + options = append(options, Option{Name: "ConnectionAttempts", Value: h.ConnectionAttempts}) + } + if h.ConnectTimeout != 0 { + options = append(options, Option{Name: "ConnectTimeout", Value: string(h.ConnectTimeout)}) + } + if h.ControlMaster != "" { + options = append(options, Option{Name: "ControlMaster", Value: h.ControlMaster}) + } + if h.ControlPath != "" { + options = append(options, Option{Name: "ControlPath", Value: h.ControlPath}) + } + if h.ControlPersist != "" { + options = append(options, Option{Name: "ControlPersist", Value: h.ControlPersist}) + } + if h.DynamicForward != "" { + options = append(options, Option{Name: "DynamicForward", Value: h.DynamicForward}) + } + if h.EnableSSHKeysign != "" { + options = append(options, Option{Name: "EnableSSHKeysign", Value: h.EnableSSHKeysign}) + } + if h.EscapeChar != "" { + options = append(options, Option{Name: "EscapeChar", Value: h.EscapeChar}) + } + if h.ExitOnForwardFailure != "" { + options = append(options, Option{Name: "ExitOnForwardFailure", Value: h.ExitOnForwardFailure}) + } + if h.FingerprintHash != "" { + options = append(options, Option{Name: "FingerprintHash", Value: h.FingerprintHash}) + } + if h.ForwardAgent != "" { + options = append(options, Option{Name: "ForwardAgent", Value: h.ForwardAgent}) + } + if h.ForwardX11 != "" { + options = append(options, Option{Name: "ForwardX11", Value: h.ForwardX11}) + } + if h.ForwardX11Timeout != 0 { + options = append(options, Option{Name: "ForwardX11Timeout", Value: string(h.ForwardX11Timeout)}) + } + if h.ForwardX11Trusted != "" { + options = append(options, Option{Name: "ForwardX11Trusted", Value: h.ForwardX11Trusted}) + } + if h.GatewayPorts != "" { + options = append(options, Option{Name: "GatewayPorts", Value: h.GatewayPorts}) + } + if h.GlobalKnownHostsFile != "" { + options = append(options, Option{Name: "GlobalKnownHostsFile", Value: h.GlobalKnownHostsFile}) + } + if h.GSSAPIAuthentication != "" { + options = append(options, Option{Name: "GSSAPIAuthentication", Value: h.GSSAPIAuthentication}) + } + if h.GSSAPIClientIdentity != "" { + options = append(options, Option{Name: "GSSAPIClientIdentity", Value: h.GSSAPIClientIdentity}) + } + if h.GSSAPIDelegateCredentials != "" { + options = append(options, Option{Name: "GSSAPIDelegateCredentials", Value: h.GSSAPIDelegateCredentials}) + } + if h.GSSAPIKeyExchange != "" { + options = append(options, Option{Name: "GSSAPIKeyExchange", Value: h.GSSAPIKeyExchange}) + } + if h.GSSAPIRenewalForcesRekey != "" { + options = append(options, Option{Name: "GSSAPIRenewalForcesRekey", Value: h.GSSAPIRenewalForcesRekey}) + } + if h.GSSAPIServerIdentity != "" { + options = append(options, Option{Name: "GSSAPIServerIdentity", Value: h.GSSAPIServerIdentity}) + } + if h.GSSAPITrustDns != "" { + options = append(options, Option{Name: "GSSAPITrustDns", Value: h.GSSAPITrustDns}) + } + if h.HashKnownHosts != "" { + options = append(options, Option{Name: "HashKnownHosts", Value: h.HashKnownHosts}) + } + if h.HostbasedAuthentication != "" { + options = append(options, Option{Name: "HostbasedAuthentication", Value: h.HostbasedAuthentication}) + } + if h.HostbasedKeyTypes != "" { + options = append(options, Option{Name: "HostbasedKeyTypes", Value: h.HostbasedKeyTypes}) + } + if h.HostKeyAlgorithms != "" { + options = append(options, Option{Name: "HostKeyAlgorithms", Value: h.HostKeyAlgorithms}) + } + if h.HostKeyAlias != "" { + options = append(options, Option{Name: "HostKeyAlias", Value: h.HostKeyAlias}) + } + if h.IdentitiesOnly != "" { + options = append(options, Option{Name: "IdentitiesOnly", Value: h.IdentitiesOnly}) + } + if h.IdentityFile != "" { + options = append(options, Option{Name: "IdentityFile", Value: h.IdentityFile}) + } + if h.IgnoreUnknown != "" { + options = append(options, Option{Name: "IgnoreUnknown", Value: h.IgnoreUnknown}) + } + if h.IPQoS != "" { + options = append(options, Option{Name: "IPQoS", Value: h.IPQoS}) + } + if h.KbdInteractiveAuthentication != "" { + options = append(options, Option{Name: "KbdInteractiveAuthentication", Value: h.KbdInteractiveAuthentication}) + } + if h.KbdInteractiveDevices != "" { + options = append(options, Option{Name: "KbdInteractiveDevices", Value: h.KbdInteractiveDevices}) + } + if h.KexAlgorithms != "" { + options = append(options, Option{Name: "KexAlgorithms", Value: h.KexAlgorithms}) + } + if h.KeychainIntegration != "" { + options = append(options, Option{Name: "KeychainIntegration", Value: h.KeychainIntegration}) + } + if h.LocalCommand != "" { + options = append(options, Option{Name: "LocalCommand", Value: h.LocalCommand}) + } + if h.LocalForward != "" { + options = append(options, Option{Name: "LocalForward", Value: h.LocalForward}) + } + if h.LogLevel != "" { + options = append(options, Option{Name: "LogLevel", Value: h.LogLevel}) + } + if h.MACs != "" { + options = append(options, Option{Name: "MACs", Value: h.MACs}) + } + if h.Match != "" { + options = append(options, Option{Name: "Match", Value: h.Match}) + } + if h.NoHostAuthenticationForLocalhost != "" { + options = append(options, Option{Name: "NoHostAuthenticationForLocalhost", Value: h.NoHostAuthenticationForLocalhost}) + } + if h.NumberOfPasswordPrompts != "" { + options = append(options, Option{Name: "NumberOfPasswordPrompts", Value: h.NumberOfPasswordPrompts}) + } + if h.PasswordAuthentication != "" { + options = append(options, Option{Name: "PasswordAuthentication", Value: h.PasswordAuthentication}) + } + if h.PermitLocalCommand != "" { + options = append(options, Option{Name: "PermitLocalCommand", Value: h.PermitLocalCommand}) + } + if h.PKCS11Provider != "" { + options = append(options, Option{Name: "PKCS11Provider", Value: h.PKCS11Provider}) + } + if h.Port != "" { + options = append(options, Option{Name: "Port", Value: h.Port}) + } + if h.PreferredAuthentications != "" { + options = append(options, Option{Name: "PreferredAuthentications", Value: h.PreferredAuthentications}) + } + if h.Protocol != "" { + options = append(options, Option{Name: "Protocol", Value: h.Protocol}) + } + if h.ProxyUseFdpass != "" { + options = append(options, Option{Name: "ProxyUseFdpass", Value: h.ProxyUseFdpass}) + } + if h.PubkeyAuthentication != "" { + options = append(options, Option{Name: "PubkeyAuthentication", Value: h.PubkeyAuthentication}) + } + if h.RekeyLimit != "" { + options = append(options, Option{Name: "RekeyLimit", Value: h.RekeyLimit}) + } + if h.RemoteForward != "" { + options = append(options, Option{Name: "RemoteForward", Value: h.RemoteForward}) + } + if h.RequestTTY != "" { + options = append(options, Option{Name: "RequestTTY", Value: h.RequestTTY}) + } + if h.RevokedHostKeys != "" { + options = append(options, Option{Name: "RevokedHostKeys", Value: h.RevokedHostKeys}) + } + if h.RhostsRSAAuthentication != "" { + options = append(options, Option{Name: "RhostsRSAAuthentication", Value: h.RhostsRSAAuthentication}) + } + if h.RSAAuthentication != "" { + options = append(options, Option{Name: "RSAAuthentication", Value: h.RSAAuthentication}) + } + if h.SendEnv != "" { + options = append(options, Option{Name: "SendEnv", Value: h.SendEnv}) + } + if h.ServerAliveCountMax != 0 { + options = append(options, Option{Name: "ServerAliveCountMax", Value: string(h.ServerAliveCountMax)}) + } + if h.ServerAliveInterval != 0 { + options = append(options, Option{Name: "ServerAliveInterval", Value: string(h.ServerAliveInterval)}) + } + if h.StreamLocalBindMask != "" { + options = append(options, Option{Name: "StreamLocalBindMask", Value: h.StreamLocalBindMask}) + } + if h.StreamLocalBindUnlink != "" { + options = append(options, Option{Name: "StreamLocalBindUnlink", Value: h.StreamLocalBindUnlink}) + } + if h.StrictHostKeyChecking != "" { + options = append(options, Option{Name: "StrictHostKeyChecking", Value: h.StrictHostKeyChecking}) + } + if h.TCPKeepAlive != "" { + options = append(options, Option{Name: "TCPKeepAlive", Value: h.TCPKeepAlive}) + } + if h.Tunnel != "" { + options = append(options, Option{Name: "Tunnel", Value: h.Tunnel}) + } + if h.TunnelDevice != "" { + options = append(options, Option{Name: "TunnelDevice", Value: h.TunnelDevice}) + } + if h.UpdateHostKeys != "" { + options = append(options, Option{Name: "UpdateHostKeys", Value: h.UpdateHostKeys}) + } + if h.UsePrivilegedPort != "" { + options = append(options, Option{Name: "UsePrivilegedPort", Value: h.UsePrivilegedPort}) + } + if h.User != "" { + options = append(options, Option{Name: "User", Value: h.User}) + } + if h.UserKnownHostsFile != "" { + options = append(options, Option{Name: "UserKnownHostsFile", Value: h.UserKnownHostsFile}) + } + if h.VerifyHostKeyDNS != "" { + options = append(options, Option{Name: "VerifyHostKeyDNS", Value: h.VerifyHostKeyDNS}) + } + if h.VisualHostKey != "" { + options = append(options, Option{Name: "VisualHostKey", Value: h.VisualHostKey}) + } + if h.XAuthLocation != "" { + options = append(options, Option{Name: "XAuthLocation", Value: h.XAuthLocation}) + } + + // ssh-config fields with a different behavior + //HostName + //ProxyCommand + + // exposed assh fields + //Inherits + //Gateways + //ResolveNameservers + //ResolveCommand + //NoControlMasterMkdir + //Aliases + + // private assh fields + //knownHosts + //pattern + //name + //inputName + //isDefault + //isTemplate + //inherited + + return options +} + // ApplyDefaults ensures a Host is valid by filling the missing fields with defaults func (h *Host) ApplyDefaults(defaults *Host) { // ssh-config fields diff --git a/pkg/config/option.go b/pkg/config/option.go new file mode 100644 index 000000000..407a1a013 --- /dev/null +++ b/pkg/config/option.go @@ -0,0 +1,30 @@ +package config + +import "fmt" + +type Option struct { + Name string + Value string +} + +type OptionsList []Option + +func (o *Option) String() string { + return fmt.Sprintf("%s=%s", o.Name, o.Value) +} + +func (ol *OptionsList) ToStringList() []string { + list := []string{} + for _, opt := range *ol { + list = append(list, opt.String()) + } + return list +} + +func (ol *OptionsList) Remove(key string) { + for i, opt := range *ol { + if opt.Name == key { + *ol = append((*ol)[:i], (*ol)[i+1:]...) + } + } +} From 5b2eec728684f8e554338ec2e57bc36f511ea714 Mon Sep 17 00:00:00 2001 From: Manfred Touron Date: Tue, 5 Jul 2016 11:13:34 +0200 Subject: [PATCH 05/17] Add assh search command --- pkg/commands/commands.go | 6 ++++++ pkg/commands/search.go | 36 ++++++++++++++++++++++++++++++++++++ pkg/config/host.go | 6 ++++++ 3 files changed, 48 insertions(+) create mode 100644 pkg/commands/search.go diff --git a/pkg/commands/commands.go b/pkg/commands/commands.go index 945a6827c..4e29bbc95 100644 --- a/pkg/commands/commands.go +++ b/pkg/commands/commands.go @@ -71,6 +71,12 @@ var Commands = []cli.Command{ Usage: "List all hosts from assh config", Action: cmdList, }, + { + Name: "search", + Usage: "Search entries by given search text", + Action: cmdSearch, + }, + // FIXME: tree { Name: "wrapper", Usage: "Initialize assh, then run ssh/scp/rsync...", diff --git a/pkg/commands/search.go b/pkg/commands/search.go new file mode 100644 index 000000000..a2a3342df --- /dev/null +++ b/pkg/commands/search.go @@ -0,0 +1,36 @@ +package commands + +import ( + "fmt" + + "github.com/codegangsta/cli" + + "github.com/moul/advanced-ssh-config/pkg/config" + // . "github.com/moul/advanced-ssh-config/pkg/logger" +) + +func cmdSearch(c *cli.Context) { + conf, err := config.Open() + if err != nil { + panic(err) + } + + needle := c.Args()[0] + + found := []*config.Host{} + for _, host := range conf.Hosts.SortedList() { + if host.Matches(needle) { + found = append(found, host) + } + } + + if len(found) == 0 { + fmt.Println("no results found.") + return + } + + fmt.Printf("Listing results for %s:\n", needle) + for _, host := range found { + fmt.Printf(" %s -> %s\n", host.Name(), host.Prototype()) + } +} diff --git a/pkg/config/host.go b/pkg/config/host.go index af2527bd1..7f4033ee5 100644 --- a/pkg/config/host.go +++ b/pkg/config/host.go @@ -170,6 +170,12 @@ func (h *Host) Clone() *Host { return &newHost } +// Matches returns true if the host matches a given string +func (h *Host) Matches(needle string) bool { + // FIXME: lookup all fields + return strings.Contains(h.Name(), needle) +} + // Options returns a map of set options func (h *Host) Options() OptionsList { options := make(OptionsList, 0) From 850328ce6486047b2d9c5d825b567dabf18b0e91 Mon Sep 17 00:00:00 2001 From: Manfred Touron Date: Tue, 5 Jul 2016 11:15:17 +0200 Subject: [PATCH 06/17] assh search looks in all host fields --- pkg/config/host.go | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/pkg/config/host.go b/pkg/config/host.go index 7f4033ee5..5aa07778b 100644 --- a/pkg/config/host.go +++ b/pkg/config/host.go @@ -172,8 +172,16 @@ func (h *Host) Clone() *Host { // Matches returns true if the host matches a given string func (h *Host) Matches(needle string) bool { - // FIXME: lookup all fields - return strings.Contains(h.Name(), needle) + if matches := strings.Contains(h.Name(), needle); matches { + return true + } + + for _, opt := range h.Options() { + if matches := strings.Contains(opt.Value, needle); matches { + return true + } + } + return false } // Options returns a map of set options From f31560f819c4a4ff688b5cfe5a2c15742a6068b6 Mon Sep 17 00:00:00 2001 From: Manfred Touron Date: Tue, 5 Jul 2016 11:20:02 +0200 Subject: [PATCH 07/17] Update README.md --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index afd29529e..bd1a0203e 100644 --- a/README.md +++ b/README.md @@ -300,7 +300,7 @@ USAGE: assh [global options] command [command options] [arguments...] VERSION: - 2.3.0 (HEAD) + 2.3.0+dev (HEAD) AUTHOR(S): Manfred Touron @@ -309,6 +309,8 @@ COMMANDS: proxy Connect to host SSH socket, used by ProxyCommand build Build .ssh/config info Display system-wide information + list List all hosts from assh config + search Search entries by given search text wrapper Initialize assh, then run ssh/scp/rsync... help, h Shows a list of commands or help for one command @@ -378,6 +380,7 @@ With the wrapper, `ssh` will *always* be called with an updated `~/.ssh/config` ### master (unreleased) +* Add storm-like `assh list` and `assh search {keyword}` commands ([#151](https://github.com/moul/advanced-ssh-config/pull/151)) * Add an optional `ASSHBinaryPath` variable in the `assh.yml` file ([#148](https://github.com/moul/advanced-ssh-config/issues/148)) [Full commits list](https://github.com/moul/advanced-ssh-config/compare/v2.3.0...master) From fa5dab882627dd88225ae56a1464e685b93188b4 Mon Sep 17 00:00:00 2001 From: Manfred Touron Date: Tue, 5 Jul 2016 11:34:33 +0200 Subject: [PATCH 08/17] Add a `assh --config=/path/to/assh.yml` option --- README.md | 11 ++++++----- cmd/assh/main.go | 6 ++++++ pkg/commands/build.go | 2 +- pkg/commands/info.go | 2 +- pkg/commands/list.go | 2 +- pkg/commands/proxy.go | 2 +- pkg/commands/search.go | 2 +- pkg/commands/wrapper.go | 2 +- pkg/config/config.go | 6 +++--- 9 files changed, 21 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index bd1a0203e..2f9982c36 100644 --- a/README.md +++ b/README.md @@ -312,14 +312,14 @@ COMMANDS: list List all hosts from assh config search Search entries by given search text wrapper Initialize assh, then run ssh/scp/rsync... - help, h Shows a list of commands or help for one command GLOBAL OPTIONS: - --debug, -D Enable debug mode [$ASSH_DEBUG] - --verbose, -V Enable verbose mode - --help, -h show help + --config, -c "~/.ssh/assh.yml" Location of config file [$ASSH_CONFIG] + --debug, -D Enable debug mode [$ASSH_DEBUG] + --verbose, -V Enable verbose mode + --help, -h show help --generate-bash-completion - --version, -v print the version + --version, -v print the version ``` ## Install @@ -380,6 +380,7 @@ With the wrapper, `ssh` will *always* be called with an updated `~/.ssh/config` ### master (unreleased) +* Add a `assh --config=/path/to/assh.yml` option * Add storm-like `assh list` and `assh search {keyword}` commands ([#151](https://github.com/moul/advanced-ssh-config/pull/151)) * Add an optional `ASSHBinaryPath` variable in the `assh.yml` file ([#148](https://github.com/moul/advanced-ssh-config/issues/148)) diff --git a/cmd/assh/main.go b/cmd/assh/main.go index 67e647d5b..f624ce237 100644 --- a/cmd/assh/main.go +++ b/cmd/assh/main.go @@ -24,6 +24,12 @@ func main() { app.BashComplete = BashComplete app.Flags = []cli.Flag{ + cli.StringFlag{ + Name: "config, c", + EnvVar: "ASSH_CONFIG", + Value: "~/.ssh/assh.yml", + Usage: "Location of config file", + }, cli.BoolFlag{ Name: "debug, D", EnvVar: "ASSH_DEBUG", diff --git a/pkg/commands/build.go b/pkg/commands/build.go index 35ca3c349..6dc9419c1 100644 --- a/pkg/commands/build.go +++ b/pkg/commands/build.go @@ -10,7 +10,7 @@ import ( ) func cmdBuild(c *cli.Context) { - conf, err := config.Open() + conf, err := config.Open(c.GlobalString("config")) if err != nil { Logger.Fatalf("Cannot open configuration file: %v", err) } diff --git a/pkg/commands/info.go b/pkg/commands/info.go index 7803a862c..948e9c995 100644 --- a/pkg/commands/info.go +++ b/pkg/commands/info.go @@ -14,7 +14,7 @@ import ( ) func cmdInfo(c *cli.Context) { - conf, err := config.Open() + conf, err := config.Open(c.GlobalString("config")) if err != nil { panic(err) } diff --git a/pkg/commands/list.go b/pkg/commands/list.go index 688fcee63..3a29b5c3b 100644 --- a/pkg/commands/list.go +++ b/pkg/commands/list.go @@ -14,7 +14,7 @@ import ( ) func cmdList(c *cli.Context) { - conf, err := config.Open() + conf, err := config.Open(c.GlobalString("config")) if err != nil { panic(err) } diff --git a/pkg/commands/proxy.go b/pkg/commands/proxy.go index 1e4215b5e..5f16a06e1 100644 --- a/pkg/commands/proxy.go +++ b/pkg/commands/proxy.go @@ -39,7 +39,7 @@ func cmdProxy(c *cli.Context) { } dryRun := os.Getenv("ASSH_DRYRUN") == "1" - conf, err := config.Open() + conf, err := config.Open(c.GlobalString("config")) if err != nil { Logger.Fatalf("Cannot open configuration file: %v", err) } diff --git a/pkg/commands/search.go b/pkg/commands/search.go index a2a3342df..c2e16bb0a 100644 --- a/pkg/commands/search.go +++ b/pkg/commands/search.go @@ -10,7 +10,7 @@ import ( ) func cmdSearch(c *cli.Context) { - conf, err := config.Open() + conf, err := config.Open(c.String("config")) if err != nil { panic(err) } diff --git a/pkg/commands/wrapper.go b/pkg/commands/wrapper.go index 1e8b0fbf7..42ff77668 100644 --- a/pkg/commands/wrapper.go +++ b/pkg/commands/wrapper.go @@ -44,7 +44,7 @@ func cmdWrapper(c *cli.Context) { Logger.Debugf("Wrapper called with bin=%v target=%v command=%v options=%v, args=%v", bin, target, command, options, args) // check if config is up-to-date - conf, err := config.Open() + conf, err := config.Open(c.String("config")) if err != nil { Logger.Fatalf("Cannot open configuration file: %v", err) } diff --git a/pkg/config/config.go b/pkg/config/config.go index f7316c734..f92887d71 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -525,10 +525,10 @@ func New() *Config { return &config } -// Open returns a Config object loaded with standard configuration file paths -func Open() (*Config, error) { +// OpenPath parses a configuration file and returns a *Config object +func Open(path string) (*Config, error) { config := New() - err := config.LoadFile("~/.ssh/assh.yml") + err := config.LoadFile(path) if err != nil { return nil, err } From b45e43a7fd4cc3ac3ff8bdb5b88826fec228eb7e Mon Sep 17 00:00:00 2001 From: Manfred Touron Date: Tue, 5 Jul 2016 11:38:46 +0200 Subject: [PATCH 09/17] Add usage examples --- README.md | 55 ++++++++++++++++++++++++++++++++++++++++++ pkg/commands/search.go | 2 +- 2 files changed, 56 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 2f9982c36..522ad7c5a 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,7 @@ * [Under the hood features](#under-the-hood-features) 3. [Configuration](#configuration) 4. [Usage](#usage) + * [Usage Examples](#usage-examples) 5. [Install](#install) * [Register the wrapper (optional)](#register-the-wrapper-optional) 6. [Getting started](#getting-started) @@ -322,6 +323,60 @@ GLOBAL OPTIONS: --version, -v print the version ``` +### Usage examples + +```console +$ assh list +Listing entries + + *.scw -> root@[hostname_not_specified]:22 + [custom options] StrictHostKeyChecking=no UserKnownHostsFile=/dev/null + + *.shortcut1 -> bob@[hostname_not_specified]:22 + + *.shortcut2 -> bob@[hostname_not_specified]:22 + + bart -> bart@5.6.7.8:22 + + bart-access -> bob@[hostname_not_specified]:22 + + dolphin -> bob@dolphin:24 + + expanded-host[0-7]* -> bob@%h.some.zone:22 + + homer -> robert@1.2.3.4:2222 + + lisa-access -> bob@[hostname_not_specified]:22 + + maggie -> maggie@[hostname_not_specified]:22 + + marvin -> bob@[hostname_not_specified]:23 + + my-env-host -> user-moul@[hostname_not_specified]:22 + + schoolgw -> bob@gw.school.com:22 + [custom options] ForwardX11=no + + schooltemplate -> student@[hostname_not_specified]:22 + [custom options] ForwardX11=yes IdentityFile=~/.ssh/school-rsa + + vm-*.school.com -> bob@[hostname_not_specified]:22 + + (*) General options: + ControlMaster: auto + ControlPath: ~/tmp/.ssh/cm/%h-%p-%r.sock + ControlPersist: yes + Port: 22 + User: bob +``` + +```console +$ assh search bart +Listing results for bart: + bart -> bart@5.6.7.8:22 + bart-access -> moul@[hostname_not_specified]:22 +``` + ## Install Get the latest version using GO (recommended way): diff --git a/pkg/commands/search.go b/pkg/commands/search.go index c2e16bb0a..0a61d41c8 100644 --- a/pkg/commands/search.go +++ b/pkg/commands/search.go @@ -10,7 +10,7 @@ import ( ) func cmdSearch(c *cli.Context) { - conf, err := config.Open(c.String("config")) + conf, err := config.Open(c.GlobalString("config")) if err != nil { panic(err) } From dcea725748d785eb9b77480b2906213bb8780d0b Mon Sep 17 00:00:00 2001 From: Manfred Touron Date: Tue, 5 Jul 2016 11:38:57 +0200 Subject: [PATCH 10/17] Add dummy-config.yml file --- contrib/dummy-config.yml | 125 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 125 insertions(+) create mode 100644 contrib/dummy-config.yml diff --git a/contrib/dummy-config.yml b/contrib/dummy-config.yml new file mode 100644 index 000000000..7703c9e00 --- /dev/null +++ b/contrib/dummy-config.yml @@ -0,0 +1,125 @@ +hosts: + + homer: + # ssh homer -> ssh 1.2.3.4 -p 2222 -u robert + Hostname: 1.2.3.4 + User: robert + Port: 2222 + + bart: + # ssh bart -> ssh 5.6.7.8 -u bart <- direct access + # or ssh 5.6.7.8/homer -u bart <- using homer as a gateway + Hostname: 5.6.7.8 + User: bart + Gateways: + - direct # tries a direct access first + - homer # fallback on homer gateway + + maggie: + # ssh maggie -> ssh 5.6.7.8 -u maggie <- direct access + # or ssh 5.6.7.8/homer -u maggie <- using homer as a gateway + User: maggie + Inherits: + - bart # inherits rules from "bart" + + bart-access: + # ssh bart-access -> ssh home.simpson.springfield.us -u bart + Inherits: + - bart-template + - simpson-template + + lisa-access: + # ssh lisa-access -> ssh home.simpson.springfield.us -u lisa + Inherits: + - lisa-template + - simpson-template + + marvin: + # ssh marvin -> ssh marvin -p 23 + # ssh sad-robot -> ssh sad-robot -p 23 + # ssh bighead -> ssh bighead -p 23 + # aliases inherit everything from marvin, except hostname + Port: 23 + Aliases: + - sad-robot + - bighead + + dolphin: + # ssh dolphin -> ssh dolphin -p 24 + # ssh ecco -> ssh dolphin -p 24 + # same as above, but with fixed hostname + Port: 24 + Hostname: dolphin + Aliases: + - sad-robot + - bighead + + schooltemplate: + User: student + IdentityFile: ~/.ssh/school-rsa + ForwardX11: yes + + schoolgw: + # ssh school -> ssh gw.school.com -l student -o ForwardX11=no -i ~/.ssh/school-rsa + Hostname: gw.school.com + ForwardX11: no + Inherits: + - schooltemplate + + "expanded-host[0-7]*": + # ssh somehost2042 -> ssh somehost2042.some.zone + Hostname: "%h.some.zone" + + vm-*.school.com: + # ssh vm-42.school.com -> ssh vm-42.school.com/gw.school.com -l student -o ForwardX11=yes -i ~/.ssh/school-rsa + Gateways: + - schoolgw + Inherits: + - schooltemplate + # do not automatically create `ControlPath` -> may result in error + NoControlMasterMkdir: true + + "*.shortcut1": + ResolveCommand: /bin/sh -c "echo %h | sed s/.shortcut1/.my-long-domain-name.com/" + + "*.shortcut2": + ResolveCommand: /bin/sh -c "echo $(echo %h | sed s/.shortcut2//).my-other-long-domain-name.com" + + "*.scw": + # ssh toto.scw -> 1. dynamically resolves the IP address + # 2. ssh {resolved ip address} -u root -p 22 -o UserKnownHostsFile=null -o StrictHostKeyChecking=no + # requires github.com/scaleway/scaleway-cli + ResolveCommand: /bin/sh -c "scw inspect -f {{.PublicAddress.IP}} server:$(echo %h | sed s/.scw//)" + User: root + Port: 22 + UserKnownHostsFile: /dev/null + StrictHostKeyChecking: no + + my-env-host: + User: user-$USER + Hostname: ${HOSTNAME}${HOSTNAME_SUFFIX} + +templates: + # Templates are similar to Hosts, you can inherits from them + # but you cannot ssh to a template + bart-template: + User: bart + lisa-template: + User: lisa + simpson-template: + Host: home.simpson.springfield.us + +defaults: + # Defaults are applied to each hosts + ControlMaster: auto + ControlPath: ~/tmp/.ssh/cm/%h-%p-%r.sock + ControlPersist: yes + Port: 22 + User: bob + +includes: +#- ~/.ssh/assh.d/*.yml +- /etc/assh.yml +- $ENV_VAR/blah-blah-*/*.yml + +ASSHBinaryPath: ~/bin/assh # optionally set the path of assh From db65229e9ad4261e9910cfa3942baacd0dea20c0 Mon Sep 17 00:00:00 2001 From: Manfred Touron Date: Tue, 5 Jul 2016 11:40:35 +0200 Subject: [PATCH 11/17] Add make docker --- Makefile | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Makefile b/Makefile index d17edd641..fde9efa7f 100644 --- a/Makefile +++ b/Makefile @@ -21,6 +21,11 @@ all: build build: $(BINARIES) +.PHONY: docker +docker: + docker build -t moul/assh . + + $(BINARIES): $(SOURCES) $(GO) build -o $@ ./cmd/$@ From 7789dbd144f95029fe9a19e1d149a112128cf3d3 Mon Sep 17 00:00:00 2001 From: Manfred Touron Date: Tue, 5 Jul 2016 12:12:08 +0200 Subject: [PATCH 12/17] Update glide deps --- glide.lock | 40 +- glide.yaml | 4 + vendor/github.com/codegangsta/cli/.gitignore | 2 + vendor/github.com/codegangsta/cli/.travis.yml | 36 +- .../github.com/codegangsta/cli/CHANGELOG.md | 130 +- vendor/github.com/codegangsta/cli/LICENSE | 28 +- vendor/github.com/codegangsta/cli/README.md | 1256 +- .../github.com/codegangsta/cli/altsrc/flag.go | 6 +- .../codegangsta/cli/altsrc/flag_test.go | 4 +- .../cli/altsrc/input_source_context.go | 2 +- .../cli/altsrc/map_input_source.go | 102 +- .../cli/altsrc/yaml_command_test.go | 153 +- .../cli/altsrc/yaml_file_loader.go | 4 +- vendor/github.com/codegangsta/cli/app.go | 224 +- vendor/github.com/codegangsta/cli/app_test.go | 562 +- .../github.com/codegangsta/cli/appveyor.yml | 27 +- vendor/github.com/codegangsta/cli/category.go | 14 + vendor/github.com/codegangsta/cli/cli.go | 23 +- vendor/github.com/codegangsta/cli/command.go | 61 +- .../codegangsta/cli/command_test.go | 20 +- vendor/github.com/codegangsta/cli/context.go | 218 +- .../codegangsta/cli/context_test.go | 176 + vendor/github.com/codegangsta/cli/errors.go | 92 + .../github.com/codegangsta/cli/errors_test.go | 60 + vendor/github.com/codegangsta/cli/flag.go | 412 +- .../github.com/codegangsta/cli/flag_test.go | 371 +- vendor/github.com/codegangsta/cli/funcs.go | 28 + vendor/github.com/codegangsta/cli/help.go | 112 +- .../github.com/codegangsta/cli/help_test.go | 183 +- .../codegangsta/cli/helpers_test.go | 13 +- vendor/github.com/codegangsta/cli/runtests | 105 + .../go-ole/example/libreoffice/libreoffice.go | 162 + vendor/github.com/gopherjs/gopherjs/README.md | 2 +- .../gopherjs/gopherjs/build/build.go | 72 +- .../github.com/gopherjs/gopherjs/circle.yml | 114 +- .../gopherjs/gopherjs/compiler/expressions.go | 8 +- .../gopherjs/gopherjs/compiler/natives/doc.go | 8 + .../gopherjs/gopherjs/compiler/natives/fs.go | 29 + .../gopherjs/compiler/natives/fs_vfsdata.go | 710 + .../compiler/natives/{ => src}/bytes/bytes.go | 0 .../natives/{ => src}/bytes/bytes_test.go | 0 .../natives/{ => src}/crypto/rand/rand.go | 0 .../natives/{ => src}/crypto/x509/x509.go | 0 .../{ => src}/crypto/x509/x509_test.go | 0 .../natives/{ => src}/debug/elf/elf_test.go | 0 .../encoding/json/stream_test.go} | 0 .../natives/{ => src}/fmt/fmt_test.go | 0 .../natives/{ => src}/go/token/token_test.go | 0 .../compiler/natives/{ => src}/io/io_test.go | 0 .../natives/{ => src}/math/big/big.go | 0 .../natives/{ => src}/math/big/big_test.go | 0 .../compiler/natives/{ => src}/math/math.go | 0 .../natives/{ => src}/math/rand/rand_test.go | 0 .../compiler/natives/src/net/http/fetch.go | 144 + .../natives/{ => src}/net/http/http.go | 26 +- .../compiler/natives/{ => src}/net/net.go | 0 .../compiler/natives/{ => src}/os/os.go | 0 .../natives/{ => src}/reflect/reflect.go | 12 +- .../natives/{ => src}/reflect/reflect_test.go | 0 .../natives/{ => src}/regexp/regexp_test.go | 0 .../natives/{ => src}/runtime/debug/debug.go | 0 .../natives/{ => src}/runtime/pprof/pprof.go | 0 .../natives/{ => src}/runtime/runtime.go | 0 .../natives/{ => src}/strings/strings.go | 0 .../natives/{ => src}/sync/atomic/atomic.go | 0 .../{ => src}/sync/atomic/atomic_test.go | 0 .../compiler/natives/{ => src}/sync/cond.go | 0 .../compiler/natives/{ => src}/sync/pool.go | 0 .../compiler/natives/{ => src}/sync/sync.go | 0 .../natives/{ => src}/sync/sync_test.go | 0 .../natives/{ => src}/sync/waitgroup.go | 0 .../natives/{ => src}/syscall/syscall.go | 13 +- .../natives/{ => src}/syscall/syscall_unix.go | 0 .../{ => src}/syscall/syscall_windows.go | 0 .../compiler/natives/{ => src}/time/time.go | 10 +- .../natives/{ => src}/unicode/unicode.go | 0 .../gopherjs/compiler/prelude/goroutines.go | 10 +- .../gopherjs/compiler/prelude/prelude.go | 2 +- .../gopherjs/gopherjs/compiler/statements.go | 21 +- .../gopherjs/compiler/typesutil/typesutil.go | 7 +- .../gopherjs/compiler/version_check.go | 1 + .../gopherjs/gopherjs/doc/packages.md | 2 +- vendor/github.com/gopherjs/gopherjs/js/js.go | 4 +- .../gopherjs/gopherjs/js/js_test.go | 25 +- .../gopherjs/gopherjs/tests/goroutine_test.go | 9 + .../gopherjs/gopherjs/tests/lowlevel_test.go | 2 +- .../gopherjs/gopherjs/tests/misc_test.go | 50 + .../github.com/gopherjs/gopherjs/tests/run.go | 2 +- vendor/github.com/gopherjs/gopherjs/tool.go | 177 +- vendor/github.com/mgutz/ansi/.gitignore | 1 + vendor/github.com/mgutz/ansi/LICENSE | 9 + vendor/github.com/mgutz/ansi/README.md | 119 + vendor/github.com/mgutz/ansi/ansi.go | 246 + vendor/github.com/mgutz/ansi/ansi_test.go | 42 + .../mgutz/ansi/cmd/ansi-mgutz/main.go | 135 + vendor/github.com/mgutz/ansi/doc.go | 65 + vendor/github.com/mgutz/ansi/print.go | 42 + vendor/github.com/shirou/gopsutil/LICENSE | 34 + vendor/github.com/shirou/gopsutil/README.rst | 23 +- vendor/github.com/shirou/gopsutil/cpu/cpu.go | 21 +- .../shirou/gopsutil/cpu/cpu_darwin.go | 4 +- .../shirou/gopsutil/cpu/cpu_darwin_cgo.go | 2 + .../shirou/gopsutil/cpu/cpu_freebsd.go | 59 +- .../shirou/gopsutil/cpu/cpu_linux.go | 2 +- .../shirou/gopsutil/cpu/cpu_test.go | 42 + .../shirou/gopsutil/cpu/cpu_unix.go | 87 +- .../github.com/shirou/gopsutil/disk/disk.go | 8 + .../shirou/gopsutil/disk/disk_darwin_arm64.go | 58 + .../shirou/gopsutil/disk/disk_linux.go | 8 +- .../shirou/gopsutil/docker/docker.go | 20 +- .../shirou/gopsutil/docker/docker_linux.go | 44 +- .../gopsutil/docker/docker_linux_test.go | 24 + .../shirou/gopsutil/docker/docker_notlinux.go | 6 + .../github.com/shirou/gopsutil/host/host.go | 14 +- .../shirou/gopsutil/host/host_darwin.go | 4 +- .../shirou/gopsutil/host/host_freebsd.go | 4 +- .../shirou/gopsutil/host/host_linux.go | 70 +- .../shirou/gopsutil/host/host_linux_arm64.go | 43 + .../gopsutil/host/host_linux_ppc64le.go | 45 + .../shirou/gopsutil/host/host_test.go | 13 + .../shirou/gopsutil/host/host_windows.go | 14 +- .../shirou/gopsutil/internal/common/common.go | 77 +- vendor/github.com/shirou/gopsutil/mem/mem.go | 8 + .../shirou/gopsutil/mem/mem_darwin_nocgo.go | 2 +- .../shirou/gopsutil/mem/mem_darwin_test.go | 3 +- .../shirou/gopsutil/mem/mem_freebsd.go | 2 +- vendor/github.com/shirou/gopsutil/net/net.go | 13 +- .../shirou/gopsutil/net/net_darwin.go | 2 +- .../shirou/gopsutil/net/net_freebsd.go | 2 +- .../shirou/gopsutil/net/net_linux.go | 10 + .../shirou/gopsutil/net/net_test.go | 2 +- .../gopsutil/process/process_linux_arm64.go | 9 + .../shirou/gopsutil/process/process_posix.go | 7 +- .../gopsutil/process/process_windows.go | 103 +- .../gopsutil/process/process_windows_386.go | 16 + .../gopsutil/process/process_windows_amd64.go | 16 + .../smartystreets/goconvey/goconvey.go | 26 +- .../goconvey/web/client/index.html | 35 +- .../web/client/resources/js/goconvey.js | 109 +- vendor/golang.org/x/crypto/.gitattributes | 10 + vendor/golang.org/x/crypto/.gitignore | 2 + vendor/golang.org/x/crypto/AUTHORS | 3 + vendor/golang.org/x/crypto/CONTRIBUTING.md | 31 + vendor/golang.org/x/crypto/CONTRIBUTORS | 3 + vendor/golang.org/x/crypto/LICENSE | 27 + vendor/golang.org/x/crypto/PATENTS | 22 + vendor/golang.org/x/crypto/README | 3 + .../x/crypto/acme/internal/acme/acme.go | 473 + .../x/crypto/acme/internal/acme/acme_test.go | 759 + .../x/crypto/acme/internal/acme/jws.go | 67 + .../x/crypto/acme/internal/acme/jws_test.go | 139 + .../x/crypto/acme/internal/acme/types.go | 181 + vendor/golang.org/x/crypto/bcrypt/base64.go | 35 + vendor/golang.org/x/crypto/bcrypt/bcrypt.go | 294 + .../golang.org/x/crypto/bcrypt/bcrypt_test.go | 226 + vendor/golang.org/x/crypto/blowfish/block.go | 159 + .../x/crypto/blowfish/blowfish_test.go | 274 + vendor/golang.org/x/crypto/blowfish/cipher.go | 91 + vendor/golang.org/x/crypto/blowfish/const.go | 199 + vendor/golang.org/x/crypto/bn256/bn256.go | 404 + .../golang.org/x/crypto/bn256/bn256_test.go | 304 + vendor/golang.org/x/crypto/bn256/constants.go | 44 + vendor/golang.org/x/crypto/bn256/curve.go | 278 + .../golang.org/x/crypto/bn256/example_test.go | 43 + vendor/golang.org/x/crypto/bn256/gfp12.go | 200 + vendor/golang.org/x/crypto/bn256/gfp2.go | 219 + vendor/golang.org/x/crypto/bn256/gfp6.go | 296 + vendor/golang.org/x/crypto/bn256/optate.go | 395 + vendor/golang.org/x/crypto/bn256/twist.go | 249 + vendor/golang.org/x/crypto/cast5/cast5.go | 526 + .../golang.org/x/crypto/cast5/cast5_test.go | 106 + vendor/golang.org/x/crypto/codereview.cfg | 1 + .../x/crypto/curve25519/const_amd64.s | 20 + .../x/crypto/curve25519/cswap_amd64.s | 88 + .../x/crypto/curve25519/curve25519.go | 841 + .../x/crypto/curve25519/curve25519_test.go | 29 + vendor/golang.org/x/crypto/curve25519/doc.go | 23 + .../x/crypto/curve25519/freeze_amd64.s | 94 + .../x/crypto/curve25519/ladderstep_amd64.s | 1398 ++ .../x/crypto/curve25519/mont25519_amd64.go | 240 + .../x/crypto/curve25519/mul_amd64.s | 191 + .../x/crypto/curve25519/square_amd64.s | 153 + vendor/golang.org/x/crypto/ed25519/ed25519.go | 181 + .../x/crypto/ed25519/ed25519_test.go | 183 + .../ed25519/internal/edwards25519/const.go | 1422 ++ .../internal/edwards25519/edwards25519.go | 1771 ++ .../x/crypto/ed25519/testdata/sign.input.gz | Bin 0 -> 50330 bytes .../golang.org/x/crypto/hkdf/example_test.go | 61 + vendor/golang.org/x/crypto/hkdf/hkdf.go | 75 + vendor/golang.org/x/crypto/hkdf/hkdf_test.go | 370 + vendor/golang.org/x/crypto/md4/md4.go | 118 + vendor/golang.org/x/crypto/md4/md4_test.go | 71 + vendor/golang.org/x/crypto/md4/md4block.go | 89 + vendor/golang.org/x/crypto/nacl/box/box.go | 85 + .../golang.org/x/crypto/nacl/box/box_test.go | 78 + .../x/crypto/nacl/secretbox/secretbox.go | 149 + .../x/crypto/nacl/secretbox/secretbox_test.go | 91 + vendor/golang.org/x/crypto/ocsp/ocsp.go | 673 + vendor/golang.org/x/crypto/ocsp/ocsp_test.go | 584 + .../x/crypto/openpgp/armor/armor.go | 219 + .../x/crypto/openpgp/armor/armor_test.go | 95 + .../x/crypto/openpgp/armor/encode.go | 160 + .../x/crypto/openpgp/canonical_text.go | 59 + .../x/crypto/openpgp/canonical_text_test.go | 52 + .../x/crypto/openpgp/clearsign/clearsign.go | 376 + .../openpgp/clearsign/clearsign_test.go | 210 + .../x/crypto/openpgp/elgamal/elgamal.go | 122 + .../x/crypto/openpgp/elgamal/elgamal_test.go | 49 + .../x/crypto/openpgp/errors/errors.go | 72 + vendor/golang.org/x/crypto/openpgp/keys.go | 633 + .../golang.org/x/crypto/openpgp/keys_test.go | 370 + .../x/crypto/openpgp/packet/compressed.go | 123 + .../crypto/openpgp/packet/compressed_test.go | 41 + .../x/crypto/openpgp/packet/config.go | 91 + .../x/crypto/openpgp/packet/encrypted_key.go | 199 + .../openpgp/packet/encrypted_key_test.go | 146 + .../x/crypto/openpgp/packet/literal.go | 89 + .../x/crypto/openpgp/packet/ocfb.go | 143 + .../x/crypto/openpgp/packet/ocfb_test.go | 46 + .../openpgp/packet/one_pass_signature.go | 73 + .../x/crypto/openpgp/packet/opaque.go | 162 + .../x/crypto/openpgp/packet/opaque_test.go | 67 + .../x/crypto/openpgp/packet/packet.go | 539 + .../x/crypto/openpgp/packet/packet_test.go | 255 + .../x/crypto/openpgp/packet/private_key.go | 362 + .../crypto/openpgp/packet/private_key_test.go | 126 + .../x/crypto/openpgp/packet/public_key.go | 750 + .../crypto/openpgp/packet/public_key_test.go | 202 + .../x/crypto/openpgp/packet/public_key_v3.go | 280 + .../openpgp/packet/public_key_v3_test.go | 82 + .../x/crypto/openpgp/packet/reader.go | 76 + .../x/crypto/openpgp/packet/signature.go | 706 + .../x/crypto/openpgp/packet/signature_test.go | 42 + .../x/crypto/openpgp/packet/signature_v3.go | 146 + .../openpgp/packet/signature_v3_test.go | 92 + .../openpgp/packet/symmetric_key_encrypted.go | 155 + .../packet/symmetric_key_encrypted_test.go | 103 + .../openpgp/packet/symmetrically_encrypted.go | 290 + .../packet/symmetrically_encrypted_test.go | 123 + .../x/crypto/openpgp/packet/userattribute.go | 91 + .../openpgp/packet/userattribute_test.go | 109 + .../x/crypto/openpgp/packet/userid.go | 160 + .../x/crypto/openpgp/packet/userid_test.go | 87 + vendor/golang.org/x/crypto/openpgp/read.go | 442 + .../golang.org/x/crypto/openpgp/read_test.go | 613 + vendor/golang.org/x/crypto/openpgp/s2k/s2k.go | 273 + .../x/crypto/openpgp/s2k/s2k_test.go | 137 + vendor/golang.org/x/crypto/openpgp/write.go | 378 + .../golang.org/x/crypto/openpgp/write_test.go | 273 + .../x/crypto/otr/libotr_test_helper.c | 197 + vendor/golang.org/x/crypto/otr/otr.go | 1408 ++ vendor/golang.org/x/crypto/otr/otr_test.go | 470 + vendor/golang.org/x/crypto/otr/smp.go | 572 + vendor/golang.org/x/crypto/pbkdf2/pbkdf2.go | 77 + .../golang.org/x/crypto/pbkdf2/pbkdf2_test.go | 157 + .../golang.org/x/crypto/pkcs12/bmp-string.go | 50 + .../x/crypto/pkcs12/bmp-string_test.go | 63 + vendor/golang.org/x/crypto/pkcs12/crypto.go | 131 + .../golang.org/x/crypto/pkcs12/crypto_test.go | 125 + vendor/golang.org/x/crypto/pkcs12/errors.go | 23 + .../crypto/pkcs12/internal/rc2/bench_test.go | 27 + .../x/crypto/pkcs12/internal/rc2/rc2.go | 274 + .../x/crypto/pkcs12/internal/rc2/rc2_test.go | 93 + vendor/golang.org/x/crypto/pkcs12/mac.go | 45 + vendor/golang.org/x/crypto/pkcs12/mac_test.go | 42 + vendor/golang.org/x/crypto/pkcs12/pbkdf.go | 170 + .../golang.org/x/crypto/pkcs12/pbkdf_test.go | 34 + vendor/golang.org/x/crypto/pkcs12/pkcs12.go | 342 + .../golang.org/x/crypto/pkcs12/pkcs12_test.go | 138 + vendor/golang.org/x/crypto/pkcs12/safebags.go | 57 + .../x/crypto/poly1305/const_amd64.s | 45 + .../golang.org/x/crypto/poly1305/poly1305.go | 32 + .../x/crypto/poly1305/poly1305_amd64.s | 497 + .../x/crypto/poly1305/poly1305_arm.s | 379 + .../x/crypto/poly1305/poly1305_test.go | 86 + .../golang.org/x/crypto/poly1305/sum_amd64.go | 24 + .../golang.org/x/crypto/poly1305/sum_arm.go | 24 + .../golang.org/x/crypto/poly1305/sum_ref.go | 1531 ++ .../x/crypto/ripemd160/ripemd160.go | 120 + .../x/crypto/ripemd160/ripemd160_test.go | 64 + .../x/crypto/ripemd160/ripemd160block.go | 161 + .../x/crypto/salsa20/salsa/hsalsa20.go | 144 + .../x/crypto/salsa20/salsa/salsa2020_amd64.s | 902 + .../x/crypto/salsa20/salsa/salsa208.go | 199 + .../x/crypto/salsa20/salsa/salsa20_amd64.go | 23 + .../x/crypto/salsa20/salsa/salsa20_ref.go | 234 + .../x/crypto/salsa20/salsa/salsa_test.go | 35 + vendor/golang.org/x/crypto/salsa20/salsa20.go | 54 + .../x/crypto/salsa20/salsa20_test.go | 139 + vendor/golang.org/x/crypto/scrypt/scrypt.go | 243 + .../golang.org/x/crypto/scrypt/scrypt_test.go | 160 + vendor/golang.org/x/crypto/sha3/doc.go | 66 + vendor/golang.org/x/crypto/sha3/hashes.go | 65 + vendor/golang.org/x/crypto/sha3/keccakf.go | 410 + vendor/golang.org/x/crypto/sha3/register.go | 18 + vendor/golang.org/x/crypto/sha3/sha3.go | 193 + vendor/golang.org/x/crypto/sha3/sha3_test.go | 306 + vendor/golang.org/x/crypto/sha3/shake.go | 60 + .../sha3/testdata/keccakKats.json.deflate | Bin 0 -> 521342 bytes vendor/golang.org/x/crypto/sha3/xor.go | 16 + .../golang.org/x/crypto/sha3/xor_generic.go | 28 + .../golang.org/x/crypto/sha3/xor_unaligned.go | 58 + .../golang.org/x/crypto/ssh/agent/client.go | 659 + .../x/crypto/ssh/agent/client_test.go | 327 + .../x/crypto/ssh/agent/example_test.go | 40 + .../golang.org/x/crypto/ssh/agent/forward.go | 103 + .../golang.org/x/crypto/ssh/agent/keyring.go | 184 + .../x/crypto/ssh/agent/keyring_test.go | 78 + .../golang.org/x/crypto/ssh/agent/server.go | 451 + .../x/crypto/ssh/agent/server_test.go | 204 + .../x/crypto/ssh/agent/testdata_test.go | 64 + .../golang.org/x/crypto/ssh/benchmark_test.go | 122 + vendor/golang.org/x/crypto/ssh/buffer.go | 98 + vendor/golang.org/x/crypto/ssh/buffer_test.go | 87 + vendor/golang.org/x/crypto/ssh/certs.go | 503 + vendor/golang.org/x/crypto/ssh/certs_test.go | 216 + vendor/golang.org/x/crypto/ssh/channel.go | 631 + vendor/golang.org/x/crypto/ssh/cipher.go | 579 + vendor/golang.org/x/crypto/ssh/cipher_test.go | 127 + vendor/golang.org/x/crypto/ssh/client.go | 213 + vendor/golang.org/x/crypto/ssh/client_auth.go | 473 + .../x/crypto/ssh/client_auth_test.go | 439 + vendor/golang.org/x/crypto/ssh/client_test.go | 39 + vendor/golang.org/x/crypto/ssh/common.go | 356 + vendor/golang.org/x/crypto/ssh/connection.go | 144 + vendor/golang.org/x/crypto/ssh/doc.go | 18 + .../golang.org/x/crypto/ssh/example_test.go | 243 + vendor/golang.org/x/crypto/ssh/handshake.go | 451 + .../golang.org/x/crypto/ssh/handshake_test.go | 486 + vendor/golang.org/x/crypto/ssh/kex.go | 526 + vendor/golang.org/x/crypto/ssh/kex_test.go | 50 + vendor/golang.org/x/crypto/ssh/keys.go | 846 + vendor/golang.org/x/crypto/ssh/keys_test.go | 440 + vendor/golang.org/x/crypto/ssh/mac.go | 57 + .../golang.org/x/crypto/ssh/mempipe_test.go | 110 + vendor/golang.org/x/crypto/ssh/messages.go | 758 + .../golang.org/x/crypto/ssh/messages_test.go | 288 + vendor/golang.org/x/crypto/ssh/mux.go | 330 + vendor/golang.org/x/crypto/ssh/mux_test.go | 502 + vendor/golang.org/x/crypto/ssh/server.go | 489 + vendor/golang.org/x/crypto/ssh/session.go | 612 + .../golang.org/x/crypto/ssh/session_test.go | 774 + vendor/golang.org/x/crypto/ssh/tcpip.go | 407 + vendor/golang.org/x/crypto/ssh/tcpip_test.go | 20 + .../x/crypto/ssh/terminal/terminal.go | 892 + .../x/crypto/ssh/terminal/terminal_test.go | 291 + .../golang.org/x/crypto/ssh/terminal/util.go | 128 + .../x/crypto/ssh/terminal/util_bsd.go | 12 + .../x/crypto/ssh/terminal/util_linux.go | 11 + .../x/crypto/ssh/terminal/util_plan9.go | 58 + .../x/crypto/ssh/terminal/util_windows.go | 174 + .../x/crypto/ssh/test/agent_unix_test.go | 59 + .../golang.org/x/crypto/ssh/test/cert_test.go | 47 + vendor/golang.org/x/crypto/ssh/test/doc.go | 7 + .../x/crypto/ssh/test/forward_unix_test.go | 160 + .../x/crypto/ssh/test/session_test.go | 365 + .../x/crypto/ssh/test/tcpip_test.go | 46 + .../x/crypto/ssh/test/test_unix_test.go | 268 + .../x/crypto/ssh/test/testdata_test.go | 64 + .../golang.org/x/crypto/ssh/testdata/doc.go | 8 + .../golang.org/x/crypto/ssh/testdata/keys.go | 57 + .../golang.org/x/crypto/ssh/testdata_test.go | 63 + vendor/golang.org/x/crypto/ssh/transport.go | 333 + .../golang.org/x/crypto/ssh/transport_test.go | 109 + vendor/golang.org/x/crypto/tea/cipher.go | 109 + vendor/golang.org/x/crypto/tea/tea_test.go | 93 + vendor/golang.org/x/crypto/twofish/twofish.go | 342 + .../x/crypto/twofish/twofish_test.go | 129 + vendor/golang.org/x/crypto/xtea/block.go | 66 + vendor/golang.org/x/crypto/xtea/cipher.go | 82 + vendor/golang.org/x/crypto/xtea/xtea_test.go | 229 + vendor/golang.org/x/crypto/xts/xts.go | 138 + vendor/golang.org/x/crypto/xts/xts_test.go | 85 + vendor/golang.org/x/net/bpf/doc.go | 3 +- vendor/golang.org/x/net/bpf/vm.go | 140 + vendor/golang.org/x/net/bpf/vm_aluop_test.go | 512 + vendor/golang.org/x/net/bpf/vm_bpf_test.go | 192 + .../golang.org/x/net/bpf/vm_extension_test.go | 49 + .../golang.org/x/net/bpf/vm_instructions.go | 174 + vendor/golang.org/x/net/bpf/vm_jump_test.go | 380 + vendor/golang.org/x/net/bpf/vm_load_test.go | 246 + vendor/golang.org/x/net/bpf/vm_ret_test.go | 115 + .../golang.org/x/net/bpf/vm_scratch_test.go | 247 + vendor/golang.org/x/net/bpf/vm_test.go | 144 + vendor/golang.org/x/net/context/context.go | 2 +- .../golang.org/x/net/context/context_test.go | 2 +- .../x/net/http2/client_conn_pool.go | 21 + .../x/net/http2/configure_transport.go | 11 +- vendor/golang.org/x/net/http2/frame.go | 7 +- vendor/golang.org/x/net/http2/go16.go | 43 + vendor/golang.org/x/net/http2/go17.go | 94 + .../x/net/http2/hpack/hpack_test.go | 41 + .../golang.org/x/net/http2/hpack/huffman.go | 42 +- vendor/golang.org/x/net/http2/http2.go | 129 +- vendor/golang.org/x/net/http2/not_go16.go | 35 +- vendor/golang.org/x/net/http2/not_go17.go | 51 + vendor/golang.org/x/net/http2/pipe.go | 6 + vendor/golang.org/x/net/http2/server.go | 118 +- vendor/golang.org/x/net/http2/server_test.go | 77 +- vendor/golang.org/x/net/http2/transport.go | 319 +- .../golang.org/x/net/http2/transport_test.go | 298 +- vendor/golang.org/x/net/http2/write.go | 10 +- vendor/golang.org/x/net/icmp/ipv4_test.go | 45 +- vendor/golang.org/x/net/ipv4/bpf_test.go | 93 + vendor/golang.org/x/net/ipv4/bpfopt_linux.go | 27 + vendor/golang.org/x/net/ipv4/bpfopt_stub.go | 16 + vendor/golang.org/x/net/ipv4/defs_linux.go | 9 + vendor/golang.org/x/net/ipv4/gen.go | 2 +- vendor/golang.org/x/net/ipv4/header_test.go | 75 +- .../golang.org/x/net/ipv4/zsys_linux_386.go | 16 + .../golang.org/x/net/ipv4/zsys_linux_amd64.go | 16 + .../golang.org/x/net/ipv4/zsys_linux_arm.go | 16 + .../golang.org/x/net/ipv4/zsys_linux_arm64.go | 16 + .../x/net/ipv4/zsys_linux_mips64.go | 16 + .../x/net/ipv4/zsys_linux_mips64le.go | 16 + .../golang.org/x/net/ipv4/zsys_linux_ppc.go | 148 + .../golang.org/x/net/ipv4/zsys_linux_ppc64.go | 16 + .../x/net/ipv4/zsys_linux_ppc64le.go | 16 + .../golang.org/x/net/ipv4/zsys_linux_s390x.go | 150 + vendor/golang.org/x/net/ipv6/bpf_test.go | 93 + vendor/golang.org/x/net/ipv6/bpfopt_linux.go | 27 + vendor/golang.org/x/net/ipv6/bpfopt_stub.go | 16 + vendor/golang.org/x/net/ipv6/defs_linux.go | 9 + vendor/golang.org/x/net/ipv6/gen.go | 2 +- .../golang.org/x/net/ipv6/zsys_linux_386.go | 16 + .../golang.org/x/net/ipv6/zsys_linux_amd64.go | 16 + .../golang.org/x/net/ipv6/zsys_linux_arm.go | 16 + .../golang.org/x/net/ipv6/zsys_linux_arm64.go | 16 + .../x/net/ipv6/zsys_linux_mips64.go | 16 + .../x/net/ipv6/zsys_linux_mips64le.go | 16 + .../golang.org/x/net/ipv6/zsys_linux_ppc.go | 170 + .../golang.org/x/net/ipv6/zsys_linux_ppc64.go | 16 + .../x/net/ipv6/zsys_linux_ppc64le.go | 16 + .../golang.org/x/net/ipv6/zsys_linux_s390x.go | 172 + .../golang.org/x/net/lex/httplex/httplex.go | 312 + .../x/net/lex/httplex/httplex_test.go | 101 + vendor/golang.org/x/net/publicsuffix/gen.go | 124 +- vendor/golang.org/x/net/publicsuffix/list.go | 2 + vendor/golang.org/x/net/publicsuffix/table.go | 17617 ++++++++-------- .../x/net/publicsuffix/table_test.go | 296 +- vendor/golang.org/x/net/route/address.go | 269 + .../x/net/route/address_darwin_test.go | 63 + vendor/golang.org/x/net/route/address_test.go | 103 + vendor/golang.org/x/net/route/binary.go | 90 + vendor/golang.org/x/net/route/defs_darwin.go | 106 + .../golang.org/x/net/route/defs_dragonfly.go | 105 + vendor/golang.org/x/net/route/defs_freebsd.go | 329 + vendor/golang.org/x/net/route/defs_netbsd.go | 104 + vendor/golang.org/x/net/route/defs_openbsd.go | 93 + vendor/golang.org/x/net/route/interface.go | 64 + .../x/net/route/interface_announce.go | 32 + .../x/net/route/interface_classic.go | 66 + .../x/net/route/interface_freebsd.go | 78 + .../x/net/route/interface_multicast.go | 30 + .../x/net/route/interface_openbsd.go | 83 + vendor/golang.org/x/net/route/message.go | 70 + .../x/net/route/message_darwin_test.go | 27 + .../x/net/route/message_freebsd_test.go | 106 + vendor/golang.org/x/net/route/message_test.go | 95 + vendor/golang.org/x/net/route/route.go | 74 + .../golang.org/x/net/route/route_classic.go | 31 + .../golang.org/x/net/route/route_openbsd.go | 28 + vendor/golang.org/x/net/route/route_test.go | 385 + vendor/golang.org/x/net/route/sys.go | 40 + vendor/golang.org/x/net/route/sys_darwin.go | 80 + .../golang.org/x/net/route/sys_dragonfly.go | 71 + vendor/golang.org/x/net/route/sys_freebsd.go | 150 + vendor/golang.org/x/net/route/sys_netbsd.go | 67 + vendor/golang.org/x/net/route/sys_openbsd.go | 72 + vendor/golang.org/x/net/route/syscall.go | 33 + vendor/golang.org/x/net/route/syscall.s | 8 + vendor/golang.org/x/net/route/zsys_darwin.go | 93 + .../golang.org/x/net/route/zsys_dragonfly.go | 92 + .../x/net/route/zsys_freebsd_386.go | 120 + .../x/net/route/zsys_freebsd_amd64.go | 117 + .../x/net/route/zsys_freebsd_arm.go | 117 + vendor/golang.org/x/net/route/zsys_netbsd.go | 91 + vendor/golang.org/x/net/route/zsys_openbsd.go | 80 + vendor/golang.org/x/net/trace/trace.go | 3 +- vendor/golang.org/x/net/webdav/file_test.go | 3 + vendor/golang.org/x/net/webdav/prop.go | 9 +- vendor/golang.org/x/net/webdav/prop_test.go | 4 + vendor/golang.org/x/net/webdav/webdav.go | 5 +- vendor/golang.org/x/net/webdav/webdav_test.go | 77 +- vendor/golang.org/x/net/websocket/hybi.go | 3 - .../golang.org/x/sys/unix/asm_dragonfly_386.s | 29 - .../golang.org/x/sys/unix/asm_linux_s390x.s | 28 + vendor/golang.org/x/sys/unix/mkall.sh | 17 +- vendor/golang.org/x/sys/unix/mkpost.go | 62 + vendor/golang.org/x/sys/unix/sockcmsg_unix.go | 2 +- .../golang.org/x/sys/unix/syscall_darwin.go | 2 + .../x/sys/unix/syscall_dragonfly.go | 1 + .../x/sys/unix/syscall_dragonfly_386.go | 61 - .../golang.org/x/sys/unix/syscall_freebsd.go | 1 + vendor/golang.org/x/sys/unix/syscall_linux.go | 11 +- .../x/sys/unix/syscall_linux_386.go | 9 + .../x/sys/unix/syscall_linux_amd64.go | 9 + .../x/sys/unix/syscall_linux_arm.go | 9 + .../x/sys/unix/syscall_linux_arm64.go | 12 + .../x/sys/unix/syscall_linux_mips64x.go | 9 + .../x/sys/unix/syscall_linux_ppc64x.go | 36 + .../x/sys/unix/syscall_linux_s390x.go | 329 + .../x/sys/unix/syscall_linux_test.go | 76 + .../golang.org/x/sys/unix/syscall_openbsd.go | 1 + vendor/golang.org/x/sys/unix/types_linux.go | 36 + .../x/sys/unix/zerrors_dragonfly_386.go | 1530 -- .../x/sys/unix/zerrors_linux_386.go | 1 + .../x/sys/unix/zerrors_linux_amd64.go | 1 + .../x/sys/unix/zerrors_linux_arm.go | 1 + .../x/sys/unix/zerrors_linux_arm64.go | 1 + .../x/sys/unix/zerrors_linux_mips64.go | 1 + .../x/sys/unix/zerrors_linux_mips64le.go | 1 + .../x/sys/unix/zerrors_linux_ppc64.go | 1 + .../x/sys/unix/zerrors_linux_ppc64le.go | 1 + .../x/sys/unix/zerrors_linux_s390x.go | 2027 ++ .../x/sys/unix/zsyscall_darwin_386.go | 1 + .../x/sys/unix/zsyscall_darwin_amd64.go | 1 + .../x/sys/unix/zsyscall_darwin_arm.go | 1 + .../x/sys/unix/zsyscall_darwin_arm64.go | 1 + .../x/sys/unix/zsyscall_dragonfly_amd64.go | 1 + .../x/sys/unix/zsyscall_freebsd_386.go | 1 + .../x/sys/unix/zsyscall_freebsd_amd64.go | 1 + .../x/sys/unix/zsyscall_freebsd_arm.go | 1 + .../x/sys/unix/zsyscall_linux_386.go | 22 + .../x/sys/unix/zsyscall_linux_amd64.go | 22 + .../x/sys/unix/zsyscall_linux_arm.go | 22 + .../x/sys/unix/zsyscall_linux_arm64.go | 11 + .../x/sys/unix/zsyscall_linux_mips64.go | 22 + .../x/sys/unix/zsyscall_linux_mips64le.go | 22 + .../x/sys/unix/zsyscall_linux_ppc64.go | 53 + .../x/sys/unix/zsyscall_linux_ppc64le.go | 53 + ...agonfly_386.go => zsyscall_linux_s390x.go} | 1139 +- .../x/sys/unix/zsyscall_netbsd_386.go | 1 + .../x/sys/unix/zsyscall_netbsd_amd64.go | 1 + .../x/sys/unix/zsyscall_netbsd_arm.go | 1 + .../x/sys/unix/zsyscall_openbsd_386.go | 1 + .../x/sys/unix/zsyscall_openbsd_amd64.go | 1 + .../x/sys/unix/zsysnum_dragonfly_386.go | 304 - .../x/sys/unix/zsysnum_linux_s390x.go | 328 + .../x/sys/unix/ztypes_dragonfly_386.go | 437 - .../golang.org/x/sys/unix/ztypes_linux_386.go | 20 + .../x/sys/unix/ztypes_linux_amd64.go | 20 + .../golang.org/x/sys/unix/ztypes_linux_arm.go | 20 + .../x/sys/unix/ztypes_linux_arm64.go | 20 + .../x/sys/unix/ztypes_linux_mips64.go | 20 + .../x/sys/unix/ztypes_linux_mips64le.go | 20 + .../x/sys/unix/ztypes_linux_ppc64.go | 27 +- .../x/sys/unix/ztypes_linux_ppc64le.go | 27 +- .../x/sys/unix/ztypes_linux_s390x.go | 649 + .../x/sys/windows/registry/syscall.go | 2 +- .../x/sys/windows/syscall_windows.go | 2 +- vendor/gopkg.in/yaml.v2/.travis.yml | 9 + vendor/gopkg.in/yaml.v2/README.md | 5 +- vendor/gopkg.in/yaml.v2/decode_test.go | 22 + vendor/gopkg.in/yaml.v2/readerc.go | 7 +- vendor/gopkg.in/yaml.v2/scannerc.go | 36 +- vendor/gopkg.in/yaml.v2/yaml.go | 2 +- 557 files changed, 84018 insertions(+), 12929 deletions(-) create mode 100644 vendor/github.com/codegangsta/cli/.gitignore create mode 100644 vendor/github.com/codegangsta/cli/errors.go create mode 100644 vendor/github.com/codegangsta/cli/errors_test.go create mode 100644 vendor/github.com/codegangsta/cli/funcs.go create mode 100755 vendor/github.com/codegangsta/cli/runtests create mode 100644 vendor/github.com/go-ole/go-ole/example/libreoffice/libreoffice.go create mode 100644 vendor/github.com/gopherjs/gopherjs/compiler/natives/doc.go create mode 100644 vendor/github.com/gopherjs/gopherjs/compiler/natives/fs.go create mode 100644 vendor/github.com/gopherjs/gopherjs/compiler/natives/fs_vfsdata.go rename vendor/github.com/gopherjs/gopherjs/compiler/natives/{ => src}/bytes/bytes.go (100%) rename vendor/github.com/gopherjs/gopherjs/compiler/natives/{ => src}/bytes/bytes_test.go (100%) rename vendor/github.com/gopherjs/gopherjs/compiler/natives/{ => src}/crypto/rand/rand.go (100%) rename vendor/github.com/gopherjs/gopherjs/compiler/natives/{ => src}/crypto/x509/x509.go (100%) rename vendor/github.com/gopherjs/gopherjs/compiler/natives/{ => src}/crypto/x509/x509_test.go (100%) rename vendor/github.com/gopherjs/gopherjs/compiler/natives/{ => src}/debug/elf/elf_test.go (100%) rename vendor/github.com/gopherjs/gopherjs/compiler/natives/{encoding/json/json.go => src/encoding/json/stream_test.go} (100%) rename vendor/github.com/gopherjs/gopherjs/compiler/natives/{ => src}/fmt/fmt_test.go (100%) rename vendor/github.com/gopherjs/gopherjs/compiler/natives/{ => src}/go/token/token_test.go (100%) rename vendor/github.com/gopherjs/gopherjs/compiler/natives/{ => src}/io/io_test.go (100%) rename vendor/github.com/gopherjs/gopherjs/compiler/natives/{ => src}/math/big/big.go (100%) rename vendor/github.com/gopherjs/gopherjs/compiler/natives/{ => src}/math/big/big_test.go (100%) rename vendor/github.com/gopherjs/gopherjs/compiler/natives/{ => src}/math/math.go (100%) rename vendor/github.com/gopherjs/gopherjs/compiler/natives/{ => src}/math/rand/rand_test.go (100%) create mode 100644 vendor/github.com/gopherjs/gopherjs/compiler/natives/src/net/http/fetch.go rename vendor/github.com/gopherjs/gopherjs/compiler/natives/{ => src}/net/http/http.go (71%) rename vendor/github.com/gopherjs/gopherjs/compiler/natives/{ => src}/net/net.go (100%) rename vendor/github.com/gopherjs/gopherjs/compiler/natives/{ => src}/os/os.go (100%) rename vendor/github.com/gopherjs/gopherjs/compiler/natives/{ => src}/reflect/reflect.go (99%) rename vendor/github.com/gopherjs/gopherjs/compiler/natives/{ => src}/reflect/reflect_test.go (100%) rename vendor/github.com/gopherjs/gopherjs/compiler/natives/{ => src}/regexp/regexp_test.go (100%) rename vendor/github.com/gopherjs/gopherjs/compiler/natives/{ => src}/runtime/debug/debug.go (100%) rename vendor/github.com/gopherjs/gopherjs/compiler/natives/{ => src}/runtime/pprof/pprof.go (100%) rename vendor/github.com/gopherjs/gopherjs/compiler/natives/{ => src}/runtime/runtime.go (100%) rename vendor/github.com/gopherjs/gopherjs/compiler/natives/{ => src}/strings/strings.go (100%) rename vendor/github.com/gopherjs/gopherjs/compiler/natives/{ => src}/sync/atomic/atomic.go (100%) rename vendor/github.com/gopherjs/gopherjs/compiler/natives/{ => src}/sync/atomic/atomic_test.go (100%) rename vendor/github.com/gopherjs/gopherjs/compiler/natives/{ => src}/sync/cond.go (100%) rename vendor/github.com/gopherjs/gopherjs/compiler/natives/{ => src}/sync/pool.go (100%) rename vendor/github.com/gopherjs/gopherjs/compiler/natives/{ => src}/sync/sync.go (100%) rename vendor/github.com/gopherjs/gopherjs/compiler/natives/{ => src}/sync/sync_test.go (100%) rename vendor/github.com/gopherjs/gopherjs/compiler/natives/{ => src}/sync/waitgroup.go (100%) rename vendor/github.com/gopherjs/gopherjs/compiler/natives/{ => src}/syscall/syscall.go (80%) rename vendor/github.com/gopherjs/gopherjs/compiler/natives/{ => src}/syscall/syscall_unix.go (100%) rename vendor/github.com/gopherjs/gopherjs/compiler/natives/{ => src}/syscall/syscall_windows.go (100%) rename vendor/github.com/gopherjs/gopherjs/compiler/natives/{ => src}/time/time.go (87%) rename vendor/github.com/gopherjs/gopherjs/compiler/natives/{ => src}/unicode/unicode.go (100%) create mode 100644 vendor/github.com/mgutz/ansi/.gitignore create mode 100644 vendor/github.com/mgutz/ansi/LICENSE create mode 100644 vendor/github.com/mgutz/ansi/README.md create mode 100644 vendor/github.com/mgutz/ansi/ansi.go create mode 100644 vendor/github.com/mgutz/ansi/ansi_test.go create mode 100644 vendor/github.com/mgutz/ansi/cmd/ansi-mgutz/main.go create mode 100644 vendor/github.com/mgutz/ansi/doc.go create mode 100644 vendor/github.com/mgutz/ansi/print.go create mode 100644 vendor/github.com/shirou/gopsutil/disk/disk_darwin_arm64.go create mode 100644 vendor/github.com/shirou/gopsutil/host/host_linux_arm64.go create mode 100644 vendor/github.com/shirou/gopsutil/host/host_linux_ppc64le.go create mode 100644 vendor/github.com/shirou/gopsutil/process/process_linux_arm64.go create mode 100644 vendor/github.com/shirou/gopsutil/process/process_windows_386.go create mode 100644 vendor/github.com/shirou/gopsutil/process/process_windows_amd64.go create mode 100644 vendor/golang.org/x/crypto/.gitattributes create mode 100644 vendor/golang.org/x/crypto/.gitignore create mode 100644 vendor/golang.org/x/crypto/AUTHORS create mode 100644 vendor/golang.org/x/crypto/CONTRIBUTING.md create mode 100644 vendor/golang.org/x/crypto/CONTRIBUTORS create mode 100644 vendor/golang.org/x/crypto/LICENSE create mode 100644 vendor/golang.org/x/crypto/PATENTS create mode 100644 vendor/golang.org/x/crypto/README create mode 100644 vendor/golang.org/x/crypto/acme/internal/acme/acme.go create mode 100644 vendor/golang.org/x/crypto/acme/internal/acme/acme_test.go create mode 100644 vendor/golang.org/x/crypto/acme/internal/acme/jws.go create mode 100644 vendor/golang.org/x/crypto/acme/internal/acme/jws_test.go create mode 100644 vendor/golang.org/x/crypto/acme/internal/acme/types.go create mode 100644 vendor/golang.org/x/crypto/bcrypt/base64.go create mode 100644 vendor/golang.org/x/crypto/bcrypt/bcrypt.go create mode 100644 vendor/golang.org/x/crypto/bcrypt/bcrypt_test.go create mode 100644 vendor/golang.org/x/crypto/blowfish/block.go create mode 100644 vendor/golang.org/x/crypto/blowfish/blowfish_test.go create mode 100644 vendor/golang.org/x/crypto/blowfish/cipher.go create mode 100644 vendor/golang.org/x/crypto/blowfish/const.go create mode 100644 vendor/golang.org/x/crypto/bn256/bn256.go create mode 100644 vendor/golang.org/x/crypto/bn256/bn256_test.go create mode 100644 vendor/golang.org/x/crypto/bn256/constants.go create mode 100644 vendor/golang.org/x/crypto/bn256/curve.go create mode 100644 vendor/golang.org/x/crypto/bn256/example_test.go create mode 100644 vendor/golang.org/x/crypto/bn256/gfp12.go create mode 100644 vendor/golang.org/x/crypto/bn256/gfp2.go create mode 100644 vendor/golang.org/x/crypto/bn256/gfp6.go create mode 100644 vendor/golang.org/x/crypto/bn256/optate.go create mode 100644 vendor/golang.org/x/crypto/bn256/twist.go create mode 100644 vendor/golang.org/x/crypto/cast5/cast5.go create mode 100644 vendor/golang.org/x/crypto/cast5/cast5_test.go create mode 100644 vendor/golang.org/x/crypto/codereview.cfg create mode 100644 vendor/golang.org/x/crypto/curve25519/const_amd64.s create mode 100644 vendor/golang.org/x/crypto/curve25519/cswap_amd64.s create mode 100644 vendor/golang.org/x/crypto/curve25519/curve25519.go create mode 100644 vendor/golang.org/x/crypto/curve25519/curve25519_test.go create mode 100644 vendor/golang.org/x/crypto/curve25519/doc.go create mode 100644 vendor/golang.org/x/crypto/curve25519/freeze_amd64.s create mode 100644 vendor/golang.org/x/crypto/curve25519/ladderstep_amd64.s create mode 100644 vendor/golang.org/x/crypto/curve25519/mont25519_amd64.go create mode 100644 vendor/golang.org/x/crypto/curve25519/mul_amd64.s create mode 100644 vendor/golang.org/x/crypto/curve25519/square_amd64.s create mode 100644 vendor/golang.org/x/crypto/ed25519/ed25519.go create mode 100644 vendor/golang.org/x/crypto/ed25519/ed25519_test.go create mode 100644 vendor/golang.org/x/crypto/ed25519/internal/edwards25519/const.go create mode 100644 vendor/golang.org/x/crypto/ed25519/internal/edwards25519/edwards25519.go create mode 100644 vendor/golang.org/x/crypto/ed25519/testdata/sign.input.gz create mode 100644 vendor/golang.org/x/crypto/hkdf/example_test.go create mode 100644 vendor/golang.org/x/crypto/hkdf/hkdf.go create mode 100644 vendor/golang.org/x/crypto/hkdf/hkdf_test.go create mode 100644 vendor/golang.org/x/crypto/md4/md4.go create mode 100644 vendor/golang.org/x/crypto/md4/md4_test.go create mode 100644 vendor/golang.org/x/crypto/md4/md4block.go create mode 100644 vendor/golang.org/x/crypto/nacl/box/box.go create mode 100644 vendor/golang.org/x/crypto/nacl/box/box_test.go create mode 100644 vendor/golang.org/x/crypto/nacl/secretbox/secretbox.go create mode 100644 vendor/golang.org/x/crypto/nacl/secretbox/secretbox_test.go create mode 100644 vendor/golang.org/x/crypto/ocsp/ocsp.go create mode 100644 vendor/golang.org/x/crypto/ocsp/ocsp_test.go create mode 100644 vendor/golang.org/x/crypto/openpgp/armor/armor.go create mode 100644 vendor/golang.org/x/crypto/openpgp/armor/armor_test.go create mode 100644 vendor/golang.org/x/crypto/openpgp/armor/encode.go create mode 100644 vendor/golang.org/x/crypto/openpgp/canonical_text.go create mode 100644 vendor/golang.org/x/crypto/openpgp/canonical_text_test.go create mode 100644 vendor/golang.org/x/crypto/openpgp/clearsign/clearsign.go create mode 100644 vendor/golang.org/x/crypto/openpgp/clearsign/clearsign_test.go create mode 100644 vendor/golang.org/x/crypto/openpgp/elgamal/elgamal.go create mode 100644 vendor/golang.org/x/crypto/openpgp/elgamal/elgamal_test.go create mode 100644 vendor/golang.org/x/crypto/openpgp/errors/errors.go create mode 100644 vendor/golang.org/x/crypto/openpgp/keys.go create mode 100644 vendor/golang.org/x/crypto/openpgp/keys_test.go create mode 100644 vendor/golang.org/x/crypto/openpgp/packet/compressed.go create mode 100644 vendor/golang.org/x/crypto/openpgp/packet/compressed_test.go create mode 100644 vendor/golang.org/x/crypto/openpgp/packet/config.go create mode 100644 vendor/golang.org/x/crypto/openpgp/packet/encrypted_key.go create mode 100644 vendor/golang.org/x/crypto/openpgp/packet/encrypted_key_test.go create mode 100644 vendor/golang.org/x/crypto/openpgp/packet/literal.go create mode 100644 vendor/golang.org/x/crypto/openpgp/packet/ocfb.go create mode 100644 vendor/golang.org/x/crypto/openpgp/packet/ocfb_test.go create mode 100644 vendor/golang.org/x/crypto/openpgp/packet/one_pass_signature.go create mode 100644 vendor/golang.org/x/crypto/openpgp/packet/opaque.go create mode 100644 vendor/golang.org/x/crypto/openpgp/packet/opaque_test.go create mode 100644 vendor/golang.org/x/crypto/openpgp/packet/packet.go create mode 100644 vendor/golang.org/x/crypto/openpgp/packet/packet_test.go create mode 100644 vendor/golang.org/x/crypto/openpgp/packet/private_key.go create mode 100644 vendor/golang.org/x/crypto/openpgp/packet/private_key_test.go create mode 100644 vendor/golang.org/x/crypto/openpgp/packet/public_key.go create mode 100644 vendor/golang.org/x/crypto/openpgp/packet/public_key_test.go create mode 100644 vendor/golang.org/x/crypto/openpgp/packet/public_key_v3.go create mode 100644 vendor/golang.org/x/crypto/openpgp/packet/public_key_v3_test.go create mode 100644 vendor/golang.org/x/crypto/openpgp/packet/reader.go create mode 100644 vendor/golang.org/x/crypto/openpgp/packet/signature.go create mode 100644 vendor/golang.org/x/crypto/openpgp/packet/signature_test.go create mode 100644 vendor/golang.org/x/crypto/openpgp/packet/signature_v3.go create mode 100644 vendor/golang.org/x/crypto/openpgp/packet/signature_v3_test.go create mode 100644 vendor/golang.org/x/crypto/openpgp/packet/symmetric_key_encrypted.go create mode 100644 vendor/golang.org/x/crypto/openpgp/packet/symmetric_key_encrypted_test.go create mode 100644 vendor/golang.org/x/crypto/openpgp/packet/symmetrically_encrypted.go create mode 100644 vendor/golang.org/x/crypto/openpgp/packet/symmetrically_encrypted_test.go create mode 100644 vendor/golang.org/x/crypto/openpgp/packet/userattribute.go create mode 100644 vendor/golang.org/x/crypto/openpgp/packet/userattribute_test.go create mode 100644 vendor/golang.org/x/crypto/openpgp/packet/userid.go create mode 100644 vendor/golang.org/x/crypto/openpgp/packet/userid_test.go create mode 100644 vendor/golang.org/x/crypto/openpgp/read.go create mode 100644 vendor/golang.org/x/crypto/openpgp/read_test.go create mode 100644 vendor/golang.org/x/crypto/openpgp/s2k/s2k.go create mode 100644 vendor/golang.org/x/crypto/openpgp/s2k/s2k_test.go create mode 100644 vendor/golang.org/x/crypto/openpgp/write.go create mode 100644 vendor/golang.org/x/crypto/openpgp/write_test.go create mode 100644 vendor/golang.org/x/crypto/otr/libotr_test_helper.c create mode 100644 vendor/golang.org/x/crypto/otr/otr.go create mode 100644 vendor/golang.org/x/crypto/otr/otr_test.go create mode 100644 vendor/golang.org/x/crypto/otr/smp.go create mode 100644 vendor/golang.org/x/crypto/pbkdf2/pbkdf2.go create mode 100644 vendor/golang.org/x/crypto/pbkdf2/pbkdf2_test.go create mode 100644 vendor/golang.org/x/crypto/pkcs12/bmp-string.go create mode 100644 vendor/golang.org/x/crypto/pkcs12/bmp-string_test.go create mode 100644 vendor/golang.org/x/crypto/pkcs12/crypto.go create mode 100644 vendor/golang.org/x/crypto/pkcs12/crypto_test.go create mode 100644 vendor/golang.org/x/crypto/pkcs12/errors.go create mode 100644 vendor/golang.org/x/crypto/pkcs12/internal/rc2/bench_test.go create mode 100644 vendor/golang.org/x/crypto/pkcs12/internal/rc2/rc2.go create mode 100644 vendor/golang.org/x/crypto/pkcs12/internal/rc2/rc2_test.go create mode 100644 vendor/golang.org/x/crypto/pkcs12/mac.go create mode 100644 vendor/golang.org/x/crypto/pkcs12/mac_test.go create mode 100644 vendor/golang.org/x/crypto/pkcs12/pbkdf.go create mode 100644 vendor/golang.org/x/crypto/pkcs12/pbkdf_test.go create mode 100644 vendor/golang.org/x/crypto/pkcs12/pkcs12.go create mode 100644 vendor/golang.org/x/crypto/pkcs12/pkcs12_test.go create mode 100644 vendor/golang.org/x/crypto/pkcs12/safebags.go create mode 100644 vendor/golang.org/x/crypto/poly1305/const_amd64.s create mode 100644 vendor/golang.org/x/crypto/poly1305/poly1305.go create mode 100644 vendor/golang.org/x/crypto/poly1305/poly1305_amd64.s create mode 100644 vendor/golang.org/x/crypto/poly1305/poly1305_arm.s create mode 100644 vendor/golang.org/x/crypto/poly1305/poly1305_test.go create mode 100644 vendor/golang.org/x/crypto/poly1305/sum_amd64.go create mode 100644 vendor/golang.org/x/crypto/poly1305/sum_arm.go create mode 100644 vendor/golang.org/x/crypto/poly1305/sum_ref.go create mode 100644 vendor/golang.org/x/crypto/ripemd160/ripemd160.go create mode 100644 vendor/golang.org/x/crypto/ripemd160/ripemd160_test.go create mode 100644 vendor/golang.org/x/crypto/ripemd160/ripemd160block.go create mode 100644 vendor/golang.org/x/crypto/salsa20/salsa/hsalsa20.go create mode 100644 vendor/golang.org/x/crypto/salsa20/salsa/salsa2020_amd64.s create mode 100644 vendor/golang.org/x/crypto/salsa20/salsa/salsa208.go create mode 100644 vendor/golang.org/x/crypto/salsa20/salsa/salsa20_amd64.go create mode 100644 vendor/golang.org/x/crypto/salsa20/salsa/salsa20_ref.go create mode 100644 vendor/golang.org/x/crypto/salsa20/salsa/salsa_test.go create mode 100644 vendor/golang.org/x/crypto/salsa20/salsa20.go create mode 100644 vendor/golang.org/x/crypto/salsa20/salsa20_test.go create mode 100644 vendor/golang.org/x/crypto/scrypt/scrypt.go create mode 100644 vendor/golang.org/x/crypto/scrypt/scrypt_test.go create mode 100644 vendor/golang.org/x/crypto/sha3/doc.go create mode 100644 vendor/golang.org/x/crypto/sha3/hashes.go create mode 100644 vendor/golang.org/x/crypto/sha3/keccakf.go create mode 100644 vendor/golang.org/x/crypto/sha3/register.go create mode 100644 vendor/golang.org/x/crypto/sha3/sha3.go create mode 100644 vendor/golang.org/x/crypto/sha3/sha3_test.go create mode 100644 vendor/golang.org/x/crypto/sha3/shake.go create mode 100644 vendor/golang.org/x/crypto/sha3/testdata/keccakKats.json.deflate create mode 100644 vendor/golang.org/x/crypto/sha3/xor.go create mode 100644 vendor/golang.org/x/crypto/sha3/xor_generic.go create mode 100644 vendor/golang.org/x/crypto/sha3/xor_unaligned.go create mode 100644 vendor/golang.org/x/crypto/ssh/agent/client.go create mode 100644 vendor/golang.org/x/crypto/ssh/agent/client_test.go create mode 100644 vendor/golang.org/x/crypto/ssh/agent/example_test.go create mode 100644 vendor/golang.org/x/crypto/ssh/agent/forward.go create mode 100644 vendor/golang.org/x/crypto/ssh/agent/keyring.go create mode 100644 vendor/golang.org/x/crypto/ssh/agent/keyring_test.go create mode 100644 vendor/golang.org/x/crypto/ssh/agent/server.go create mode 100644 vendor/golang.org/x/crypto/ssh/agent/server_test.go create mode 100644 vendor/golang.org/x/crypto/ssh/agent/testdata_test.go create mode 100644 vendor/golang.org/x/crypto/ssh/benchmark_test.go create mode 100644 vendor/golang.org/x/crypto/ssh/buffer.go create mode 100644 vendor/golang.org/x/crypto/ssh/buffer_test.go create mode 100644 vendor/golang.org/x/crypto/ssh/certs.go create mode 100644 vendor/golang.org/x/crypto/ssh/certs_test.go create mode 100644 vendor/golang.org/x/crypto/ssh/channel.go create mode 100644 vendor/golang.org/x/crypto/ssh/cipher.go create mode 100644 vendor/golang.org/x/crypto/ssh/cipher_test.go create mode 100644 vendor/golang.org/x/crypto/ssh/client.go create mode 100644 vendor/golang.org/x/crypto/ssh/client_auth.go create mode 100644 vendor/golang.org/x/crypto/ssh/client_auth_test.go create mode 100644 vendor/golang.org/x/crypto/ssh/client_test.go create mode 100644 vendor/golang.org/x/crypto/ssh/common.go create mode 100644 vendor/golang.org/x/crypto/ssh/connection.go create mode 100644 vendor/golang.org/x/crypto/ssh/doc.go create mode 100644 vendor/golang.org/x/crypto/ssh/example_test.go create mode 100644 vendor/golang.org/x/crypto/ssh/handshake.go create mode 100644 vendor/golang.org/x/crypto/ssh/handshake_test.go create mode 100644 vendor/golang.org/x/crypto/ssh/kex.go create mode 100644 vendor/golang.org/x/crypto/ssh/kex_test.go create mode 100644 vendor/golang.org/x/crypto/ssh/keys.go create mode 100644 vendor/golang.org/x/crypto/ssh/keys_test.go create mode 100644 vendor/golang.org/x/crypto/ssh/mac.go create mode 100644 vendor/golang.org/x/crypto/ssh/mempipe_test.go create mode 100644 vendor/golang.org/x/crypto/ssh/messages.go create mode 100644 vendor/golang.org/x/crypto/ssh/messages_test.go create mode 100644 vendor/golang.org/x/crypto/ssh/mux.go create mode 100644 vendor/golang.org/x/crypto/ssh/mux_test.go create mode 100644 vendor/golang.org/x/crypto/ssh/server.go create mode 100644 vendor/golang.org/x/crypto/ssh/session.go create mode 100644 vendor/golang.org/x/crypto/ssh/session_test.go create mode 100644 vendor/golang.org/x/crypto/ssh/tcpip.go create mode 100644 vendor/golang.org/x/crypto/ssh/tcpip_test.go create mode 100644 vendor/golang.org/x/crypto/ssh/terminal/terminal.go create mode 100644 vendor/golang.org/x/crypto/ssh/terminal/terminal_test.go create mode 100644 vendor/golang.org/x/crypto/ssh/terminal/util.go create mode 100644 vendor/golang.org/x/crypto/ssh/terminal/util_bsd.go create mode 100644 vendor/golang.org/x/crypto/ssh/terminal/util_linux.go create mode 100644 vendor/golang.org/x/crypto/ssh/terminal/util_plan9.go create mode 100644 vendor/golang.org/x/crypto/ssh/terminal/util_windows.go create mode 100644 vendor/golang.org/x/crypto/ssh/test/agent_unix_test.go create mode 100644 vendor/golang.org/x/crypto/ssh/test/cert_test.go create mode 100644 vendor/golang.org/x/crypto/ssh/test/doc.go create mode 100644 vendor/golang.org/x/crypto/ssh/test/forward_unix_test.go create mode 100644 vendor/golang.org/x/crypto/ssh/test/session_test.go create mode 100644 vendor/golang.org/x/crypto/ssh/test/tcpip_test.go create mode 100644 vendor/golang.org/x/crypto/ssh/test/test_unix_test.go create mode 100644 vendor/golang.org/x/crypto/ssh/test/testdata_test.go create mode 100644 vendor/golang.org/x/crypto/ssh/testdata/doc.go create mode 100644 vendor/golang.org/x/crypto/ssh/testdata/keys.go create mode 100644 vendor/golang.org/x/crypto/ssh/testdata_test.go create mode 100644 vendor/golang.org/x/crypto/ssh/transport.go create mode 100644 vendor/golang.org/x/crypto/ssh/transport_test.go create mode 100644 vendor/golang.org/x/crypto/tea/cipher.go create mode 100644 vendor/golang.org/x/crypto/tea/tea_test.go create mode 100644 vendor/golang.org/x/crypto/twofish/twofish.go create mode 100644 vendor/golang.org/x/crypto/twofish/twofish_test.go create mode 100644 vendor/golang.org/x/crypto/xtea/block.go create mode 100644 vendor/golang.org/x/crypto/xtea/cipher.go create mode 100644 vendor/golang.org/x/crypto/xtea/xtea_test.go create mode 100644 vendor/golang.org/x/crypto/xts/xts.go create mode 100644 vendor/golang.org/x/crypto/xts/xts_test.go create mode 100644 vendor/golang.org/x/net/bpf/vm.go create mode 100644 vendor/golang.org/x/net/bpf/vm_aluop_test.go create mode 100644 vendor/golang.org/x/net/bpf/vm_bpf_test.go create mode 100644 vendor/golang.org/x/net/bpf/vm_extension_test.go create mode 100644 vendor/golang.org/x/net/bpf/vm_instructions.go create mode 100644 vendor/golang.org/x/net/bpf/vm_jump_test.go create mode 100644 vendor/golang.org/x/net/bpf/vm_load_test.go create mode 100644 vendor/golang.org/x/net/bpf/vm_ret_test.go create mode 100644 vendor/golang.org/x/net/bpf/vm_scratch_test.go create mode 100644 vendor/golang.org/x/net/bpf/vm_test.go create mode 100644 vendor/golang.org/x/net/http2/go16.go create mode 100644 vendor/golang.org/x/net/http2/go17.go create mode 100644 vendor/golang.org/x/net/http2/not_go17.go create mode 100644 vendor/golang.org/x/net/ipv4/bpf_test.go create mode 100644 vendor/golang.org/x/net/ipv4/bpfopt_linux.go create mode 100644 vendor/golang.org/x/net/ipv4/bpfopt_stub.go create mode 100644 vendor/golang.org/x/net/ipv4/zsys_linux_ppc.go create mode 100644 vendor/golang.org/x/net/ipv4/zsys_linux_s390x.go create mode 100644 vendor/golang.org/x/net/ipv6/bpf_test.go create mode 100644 vendor/golang.org/x/net/ipv6/bpfopt_linux.go create mode 100644 vendor/golang.org/x/net/ipv6/bpfopt_stub.go create mode 100644 vendor/golang.org/x/net/ipv6/zsys_linux_ppc.go create mode 100644 vendor/golang.org/x/net/ipv6/zsys_linux_s390x.go create mode 100644 vendor/golang.org/x/net/lex/httplex/httplex.go create mode 100644 vendor/golang.org/x/net/lex/httplex/httplex_test.go create mode 100644 vendor/golang.org/x/net/route/address.go create mode 100644 vendor/golang.org/x/net/route/address_darwin_test.go create mode 100644 vendor/golang.org/x/net/route/address_test.go create mode 100644 vendor/golang.org/x/net/route/binary.go create mode 100644 vendor/golang.org/x/net/route/defs_darwin.go create mode 100644 vendor/golang.org/x/net/route/defs_dragonfly.go create mode 100644 vendor/golang.org/x/net/route/defs_freebsd.go create mode 100644 vendor/golang.org/x/net/route/defs_netbsd.go create mode 100644 vendor/golang.org/x/net/route/defs_openbsd.go create mode 100644 vendor/golang.org/x/net/route/interface.go create mode 100644 vendor/golang.org/x/net/route/interface_announce.go create mode 100644 vendor/golang.org/x/net/route/interface_classic.go create mode 100644 vendor/golang.org/x/net/route/interface_freebsd.go create mode 100644 vendor/golang.org/x/net/route/interface_multicast.go create mode 100644 vendor/golang.org/x/net/route/interface_openbsd.go create mode 100644 vendor/golang.org/x/net/route/message.go create mode 100644 vendor/golang.org/x/net/route/message_darwin_test.go create mode 100644 vendor/golang.org/x/net/route/message_freebsd_test.go create mode 100644 vendor/golang.org/x/net/route/message_test.go create mode 100644 vendor/golang.org/x/net/route/route.go create mode 100644 vendor/golang.org/x/net/route/route_classic.go create mode 100644 vendor/golang.org/x/net/route/route_openbsd.go create mode 100644 vendor/golang.org/x/net/route/route_test.go create mode 100644 vendor/golang.org/x/net/route/sys.go create mode 100644 vendor/golang.org/x/net/route/sys_darwin.go create mode 100644 vendor/golang.org/x/net/route/sys_dragonfly.go create mode 100644 vendor/golang.org/x/net/route/sys_freebsd.go create mode 100644 vendor/golang.org/x/net/route/sys_netbsd.go create mode 100644 vendor/golang.org/x/net/route/sys_openbsd.go create mode 100644 vendor/golang.org/x/net/route/syscall.go create mode 100644 vendor/golang.org/x/net/route/syscall.s create mode 100644 vendor/golang.org/x/net/route/zsys_darwin.go create mode 100644 vendor/golang.org/x/net/route/zsys_dragonfly.go create mode 100644 vendor/golang.org/x/net/route/zsys_freebsd_386.go create mode 100644 vendor/golang.org/x/net/route/zsys_freebsd_amd64.go create mode 100644 vendor/golang.org/x/net/route/zsys_freebsd_arm.go create mode 100644 vendor/golang.org/x/net/route/zsys_netbsd.go create mode 100644 vendor/golang.org/x/net/route/zsys_openbsd.go delete mode 100644 vendor/golang.org/x/sys/unix/asm_dragonfly_386.s create mode 100644 vendor/golang.org/x/sys/unix/asm_linux_s390x.s create mode 100644 vendor/golang.org/x/sys/unix/mkpost.go delete mode 100644 vendor/golang.org/x/sys/unix/syscall_dragonfly_386.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_linux_s390x.go delete mode 100644 vendor/golang.org/x/sys/unix/zerrors_dragonfly_386.go create mode 100644 vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go rename vendor/golang.org/x/sys/unix/{zsyscall_dragonfly_386.go => zsyscall_linux_s390x.go} (57%) delete mode 100644 vendor/golang.org/x/sys/unix/zsysnum_dragonfly_386.go create mode 100644 vendor/golang.org/x/sys/unix/zsysnum_linux_s390x.go delete mode 100644 vendor/golang.org/x/sys/unix/ztypes_dragonfly_386.go create mode 100644 vendor/golang.org/x/sys/unix/ztypes_linux_s390x.go create mode 100644 vendor/gopkg.in/yaml.v2/.travis.yml diff --git a/glide.lock b/glide.lock index c52e8c2bf..672935610 100644 --- a/glide.lock +++ b/glide.lock @@ -1,24 +1,26 @@ -hash: 985ffa23c4e58e70c4f4b5e8cb12c2d1e6d1dc26d1848974358df8e908a38b76 -updated: 2016-06-30T17:34:49.328671685+02:00 +hash: 97d05761c7f4101773abe4db4735d35bbd9799a682384901d14e9e8199a93479 +updated: 2016-07-05T11:55:23.321910466+02:00 imports: - name: github.com/bugsnag/osext - version: 0dd3f918b21bec95ace9dc86c7e70266cfc5c702 + version: "" - name: github.com/codegangsta/cli - version: 4733699ce30faa633c4db36ebfbe427963593d7d + version: "" - name: github.com/flynn/go-shlex - version: 3f9db97f856818214da2e1057f8ad84803971cff + version: "" - name: github.com/go-ole/go-ole - version: 572eabb84c424e76a0d39d31510dd7dfd62f70b2 + version: "" subpackages: - oleutil - name: github.com/gopherjs/gopherjs - version: 19e100e9652485a76176bc5fd2669f57d3a2743c + version: "" subpackages: - js - name: github.com/jtolds/gls - version: 8ddce2a84170772b95dd5d576c48d517b22cac63 + version: "" +- name: github.com/mgutz/ansi + version: c286dcecd19ff979eeb73ea444e479b903f2cfcb - name: github.com/shirou/gopsutil - version: f8c7af556592720f3dfc7098ca55953261c0f02a + version: "" subpackages: - cpu - host @@ -27,30 +29,34 @@ imports: - net - process - name: github.com/shirou/w32 - version: 3c9377fc6748f222729a8270fe2775d149a249ad + version: "" - name: github.com/Sirupsen/logrus - version: cd7d1bbe41066b6c1f19780f895901052150a575 + version: "" - name: github.com/smartystreets/assertions - version: 40711f7748186bbf9c99977cd89f21ce1a229447 + version: "" subpackages: - internal/go-render/render - internal/oglematchers - name: github.com/smartystreets/goconvey - version: cc5d85f4f15bd2163abf0fe6e6753356dde72aa2 + version: "" subpackages: - convey - convey/gotest - convey/reporting - name: github.com/StackExchange/wmi - version: f3e2bae1e0cb5aef83e319133eabfee30013a4a5 + version: "" +- name: golang.org/x/crypto + version: 0c565bf13221fb55497d7ae2bb95694db1fd1bff + subpackages: + - ssh/terminal - name: golang.org/x/net - version: cb0ed7acc4f717d79a358093419e5a7da09b8b45 + version: "" subpackages: - context - name: golang.org/x/sys - version: f64b50fbea64174967a8882830d621a18ee1548e + version: "" subpackages: - unix - name: gopkg.in/yaml.v2 - version: 7ad95dd0798a40da1ccdff6dff35fd177b5edf40 + version: "" devImports: [] diff --git a/glide.yaml b/glide.yaml index 1ffc68aa4..d8646042e 100644 --- a/glide.yaml +++ b/glide.yaml @@ -52,3 +52,7 @@ import: - unix - package: gopkg.in/yaml.v2 version: 7ad95dd0798a40da1ccdff6dff35fd177b5edf40 +- package: github.com/mgutz/ansi +- package: golang.org/x/crypto + subpackages: + - ssh/terminal diff --git a/vendor/github.com/codegangsta/cli/.gitignore b/vendor/github.com/codegangsta/cli/.gitignore new file mode 100644 index 000000000..faf70c4c2 --- /dev/null +++ b/vendor/github.com/codegangsta/cli/.gitignore @@ -0,0 +1,2 @@ +*.coverprofile +node_modules/ diff --git a/vendor/github.com/codegangsta/cli/.travis.yml b/vendor/github.com/codegangsta/cli/.travis.yml index c2b5c8de0..273d017b4 100644 --- a/vendor/github.com/codegangsta/cli/.travis.yml +++ b/vendor/github.com/codegangsta/cli/.travis.yml @@ -1,18 +1,40 @@ language: go + sudo: false +cache: + directories: + - node_modules + go: -- 1.1.2 - 1.2.2 - 1.3.3 -- 1.4.2 -- 1.5.1 -- tip +- 1.4 +- 1.5.4 +- 1.6.2 +- master matrix: allow_failures: - - go: tip + - go: master + include: + - go: 1.6.2 + os: osx + - go: 1.1.2 + install: go get -v . + before_script: echo skipping gfmxr on $TRAVIS_GO_VERSION + script: + - ./runtests vet + - ./runtests test + +before_script: +- go get github.com/urfave/gfmxr/... +- if [ ! -f node_modules/.bin/markdown-toc ] ; then + npm install markdown-toc ; + fi script: -- go vet ./... -- go test -v ./... +- ./runtests vet +- ./runtests test +- ./runtests gfmxr +- ./runtests toc diff --git a/vendor/github.com/codegangsta/cli/CHANGELOG.md b/vendor/github.com/codegangsta/cli/CHANGELOG.md index 074bfb2d6..d1904fe0b 100644 --- a/vendor/github.com/codegangsta/cli/CHANGELOG.md +++ b/vendor/github.com/codegangsta/cli/CHANGELOG.md @@ -4,8 +4,90 @@ ## [Unreleased] +## [1.18.0] - 2016-06-27 ### Added +- `./runtests` test runner with coverage tracking by default +- testing on OS X +- testing on Windows +- `UintFlag`, `Uint64Flag`, and `Int64Flag` types and supporting code + +### Changed +- Use spaces for alignment in help/usage output instead of tabs, making the + output alignment consistent regardless of tab width + +### Fixed +- Printing of command aliases in help text +- Printing of visible flags for both struct and struct pointer flags +- Display the `help` subcommand when using `CommandCategories` +- No longer swallows `panic`s that occur within the `Action`s themselves when + detecting the signature of the `Action` field + +## [1.17.0] - 2016-05-09 +### Added +- Pluggable flag-level help text rendering via `cli.DefaultFlagStringFunc` +- `context.GlobalBoolT` was added as an analogue to `context.GlobalBool` +- Support for hiding commands by setting `Hidden: true` -- this will hide the + commands in help output + +### Changed +- `Float64Flag`, `IntFlag`, and `DurationFlag` default values are no longer + quoted in help text output. +- All flag types now include `(default: {value})` strings following usage when a + default value can be (reasonably) detected. +- `IntSliceFlag` and `StringSliceFlag` usage strings are now more consistent + with non-slice flag types +- Apps now exit with a code of 3 if an unknown subcommand is specified + (previously they printed "No help topic for...", but still exited 0. This + makes it easier to script around apps built using `cli` since they can trust + that a 0 exit code indicated a successful execution. +- cleanups based on [Go Report Card + feedback](https://goreportcard.com/report/github.com/urfave/cli) + +## [1.16.0] - 2016-05-02 +### Added +- `Hidden` field on all flag struct types to omit from generated help text + +### Changed +- `BashCompletionFlag` (`--enable-bash-completion`) is now omitted from +generated help text via the `Hidden` field + +### Fixed +- handling of error values in `HandleAction` and `HandleExitCoder` + +## [1.15.0] - 2016-04-30 +### Added +- This file! - Support for placeholders in flag usage strings +- `App.Metadata` map for arbitrary data/state management +- `Set` and `GlobalSet` methods on `*cli.Context` for altering values after +parsing. +- Support for nested lookup of dot-delimited keys in structures loaded from +YAML. + +### Changed +- The `App.Action` and `Command.Action` now prefer a return signature of +`func(*cli.Context) error`, as defined by `cli.ActionFunc`. If a non-nil +`error` is returned, there may be two outcomes: + - If the error fulfills `cli.ExitCoder`, then `os.Exit` will be called + automatically + - Else the error is bubbled up and returned from `App.Run` +- Specifying an `Action` with the legacy return signature of +`func(*cli.Context)` will produce a deprecation message to stderr +- Specifying an `Action` that is not a `func` type will produce a non-zero exit +from `App.Run` +- Specifying an `Action` func that has an invalid (input) signature will +produce a non-zero exit from `App.Run` + +### Deprecated +- +`cli.App.RunAndExitOnError`, which should now be done by returning an error +that fulfills `cli.ExitCoder` to `cli.App.Run`. +- the legacy signature for +`cli.App.Action` of `func(*cli.Context)`, which should now have a return +signature of `func(*cli.Context) error`, as defined by `cli.ActionFunc`. + +### Fixed +- Added missing `*cli.Context.GlobalFloat64` method ## [1.14.0] - 2016-04-03 (backfilled 2016-04-25) ### Added @@ -219,25 +301,29 @@ ### Added - Initial implementation. -[Unreleased]: https://github.com/codegangsta/cli/compare/v1.14.0...HEAD -[1.14.0]: https://github.com/codegangsta/cli/compare/v1.13.0...v1.14.0 -[1.13.0]: https://github.com/codegangsta/cli/compare/v1.12.0...v1.13.0 -[1.12.0]: https://github.com/codegangsta/cli/compare/v1.11.1...v1.12.0 -[1.11.1]: https://github.com/codegangsta/cli/compare/v1.11.0...v1.11.1 -[1.11.0]: https://github.com/codegangsta/cli/compare/v1.10.2...v1.11.0 -[1.10.2]: https://github.com/codegangsta/cli/compare/v1.10.1...v1.10.2 -[1.10.1]: https://github.com/codegangsta/cli/compare/v1.10.0...v1.10.1 -[1.10.0]: https://github.com/codegangsta/cli/compare/v1.9.0...v1.10.0 -[1.9.0]: https://github.com/codegangsta/cli/compare/v1.8.0...v1.9.0 -[1.8.0]: https://github.com/codegangsta/cli/compare/v1.7.1...v1.8.0 -[1.7.1]: https://github.com/codegangsta/cli/compare/v1.7.0...v1.7.1 -[1.7.0]: https://github.com/codegangsta/cli/compare/v1.6.0...v1.7.0 -[1.6.0]: https://github.com/codegangsta/cli/compare/v1.5.0...v1.6.0 -[1.5.0]: https://github.com/codegangsta/cli/compare/v1.4.1...v1.5.0 -[1.4.1]: https://github.com/codegangsta/cli/compare/v1.4.0...v1.4.1 -[1.4.0]: https://github.com/codegangsta/cli/compare/v1.3.1...v1.4.0 -[1.3.1]: https://github.com/codegangsta/cli/compare/v1.3.0...v1.3.1 -[1.3.0]: https://github.com/codegangsta/cli/compare/v1.2.0...v1.3.0 -[1.2.0]: https://github.com/codegangsta/cli/compare/v1.1.0...v1.2.0 -[1.1.0]: https://github.com/codegangsta/cli/compare/v1.0.0...v1.1.0 -[1.0.0]: https://github.com/codegangsta/cli/compare/v0.1.0...v1.0.0 +[Unreleased]: https://github.com/urfave/cli/compare/v1.18.0...HEAD +[1.18.0]: https://github.com/urfave/cli/compare/v1.17.0...v1.18.0 +[1.17.0]: https://github.com/urfave/cli/compare/v1.16.0...v1.17.0 +[1.16.0]: https://github.com/urfave/cli/compare/v1.15.0...v1.16.0 +[1.15.0]: https://github.com/urfave/cli/compare/v1.14.0...v1.15.0 +[1.14.0]: https://github.com/urfave/cli/compare/v1.13.0...v1.14.0 +[1.13.0]: https://github.com/urfave/cli/compare/v1.12.0...v1.13.0 +[1.12.0]: https://github.com/urfave/cli/compare/v1.11.1...v1.12.0 +[1.11.1]: https://github.com/urfave/cli/compare/v1.11.0...v1.11.1 +[1.11.0]: https://github.com/urfave/cli/compare/v1.10.2...v1.11.0 +[1.10.2]: https://github.com/urfave/cli/compare/v1.10.1...v1.10.2 +[1.10.1]: https://github.com/urfave/cli/compare/v1.10.0...v1.10.1 +[1.10.0]: https://github.com/urfave/cli/compare/v1.9.0...v1.10.0 +[1.9.0]: https://github.com/urfave/cli/compare/v1.8.0...v1.9.0 +[1.8.0]: https://github.com/urfave/cli/compare/v1.7.1...v1.8.0 +[1.7.1]: https://github.com/urfave/cli/compare/v1.7.0...v1.7.1 +[1.7.0]: https://github.com/urfave/cli/compare/v1.6.0...v1.7.0 +[1.6.0]: https://github.com/urfave/cli/compare/v1.5.0...v1.6.0 +[1.5.0]: https://github.com/urfave/cli/compare/v1.4.1...v1.5.0 +[1.4.1]: https://github.com/urfave/cli/compare/v1.4.0...v1.4.1 +[1.4.0]: https://github.com/urfave/cli/compare/v1.3.1...v1.4.0 +[1.3.1]: https://github.com/urfave/cli/compare/v1.3.0...v1.3.1 +[1.3.0]: https://github.com/urfave/cli/compare/v1.2.0...v1.3.0 +[1.2.0]: https://github.com/urfave/cli/compare/v1.1.0...v1.2.0 +[1.1.0]: https://github.com/urfave/cli/compare/v1.0.0...v1.1.0 +[1.0.0]: https://github.com/urfave/cli/compare/v0.1.0...v1.0.0 diff --git a/vendor/github.com/codegangsta/cli/LICENSE b/vendor/github.com/codegangsta/cli/LICENSE index 5515ccfb7..42a597e29 100644 --- a/vendor/github.com/codegangsta/cli/LICENSE +++ b/vendor/github.com/codegangsta/cli/LICENSE @@ -1,21 +1,21 @@ -Copyright (C) 2013 Jeremy Saenz -All Rights Reserved. +MIT License -MIT LICENSE +Copyright (c) 2016 Jeremy Saenz & Contributors -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/github.com/codegangsta/cli/README.md b/vendor/github.com/codegangsta/cli/README.md index 524723ea8..ebb1d7413 100644 --- a/vendor/github.com/codegangsta/cli/README.md +++ b/vendor/github.com/codegangsta/cli/README.md @@ -1,42 +1,145 @@ -[![Coverage](http://gocover.io/_badge/github.com/codegangsta/cli?0)](http://gocover.io/github.com/codegangsta/cli) -[![Build Status](https://travis-ci.org/codegangsta/cli.svg?branch=master)](https://travis-ci.org/codegangsta/cli) -[![GoDoc](https://godoc.org/github.com/codegangsta/cli?status.svg)](https://godoc.org/github.com/codegangsta/cli) -[![codebeat](https://codebeat.co/badges/0a8f30aa-f975-404b-b878-5fab3ae1cc5f)](https://codebeat.co/projects/github.aaakk.us.kg-codegangsta-cli) - -# cli.go - -`cli.go` is simple, fast, and fun package for building command line apps in Go. The goal is to enable developers to write fast and distributable command line applications in an expressive way. +cli +=== + +[![Build Status](https://travis-ci.org/urfave/cli.svg?branch=master)](https://travis-ci.org/urfave/cli) +[![Windows Build Status](https://ci.appveyor.com/api/projects/status/rtgk5xufi932pb2v?svg=true)](https://ci.appveyor.com/project/urfave/cli) +[![GoDoc](https://godoc.org/github.com/urfave/cli?status.svg)](https://godoc.org/github.com/urfave/cli) +[![codebeat](https://codebeat.co/badges/0a8f30aa-f975-404b-b878-5fab3ae1cc5f)](https://codebeat.co/projects/github.aaakk.us.kg-urfave-cli) +[![Go Report Card](https://goreportcard.com/badge/urfave/cli)](https://goreportcard.com/report/urfave/cli) +[![top level coverage](https://gocover.io/_badge/github.com/urfave/cli?0 "top level coverage")](http://gocover.io/github.com/urfave/cli) / +[![altsrc coverage](https://gocover.io/_badge/github.com/urfave/cli/altsrc?0 "altsrc coverage")](http://gocover.io/github.com/urfave/cli/altsrc) + +**Notice:** This is the library formerly known as +`github.com/codegangsta/cli` -- Github will automatically redirect requests +to this repository, but we recommend updating your references for clarity. + +cli is a simple, fast, and fun package for building command line apps in Go. The +goal is to enable developers to write fast and distributable command line +applications in an expressive way. + + + +- [Overview](#overview) +- [Installation](#installation) + * [Supported platforms](#supported-platforms) + * [Using the `v2` branch](#using-the-v2-branch) + * [Pinning to the `v1` branch](#pinning-to-the-v1-branch) +- [Getting Started](#getting-started) +- [Examples](#examples) + * [Arguments](#arguments) + * [Flags](#flags) + + [Placeholder Values](#placeholder-values) + + [Alternate Names](#alternate-names) + + [Values from the Environment](#values-from-the-environment) + + [Values from alternate input sources (YAML and others)](#values-from-alternate-input-sources-yaml-and-others) + * [Subcommands](#subcommands) + * [Subcommands categories](#subcommands-categories) + * [Exit code](#exit-code) + * [Bash Completion](#bash-completion) + + [Enabling](#enabling) + + [Distribution](#distribution) + + [Customization](#customization) + * [Generated Help Text](#generated-help-text) + + [Customization](#customization-1) + * [Version Flag](#version-flag) + + [Customization](#customization-2) + + [Full API Example](#full-api-example) +- [Contribution Guidelines](#contribution-guidelines) + + ## Overview -Command line apps are usually so tiny that there is absolutely no reason why your code should *not* be self-documenting. Things like generating help text and parsing command flags/options should not hinder productivity when writing a command line app. +Command line apps are usually so tiny that there is absolutely no reason why +your code should *not* be self-documenting. Things like generating help text and +parsing command flags/options should not hinder productivity when writing a +command line app. -**This is where `cli.go` comes into play.** `cli.go` makes command line programming fun, organized, and expressive! +**This is where cli comes into play.** cli makes command line programming fun, +organized, and expressive! ## Installation -Make sure you have a working Go environment (go 1.1+ is *required*). [See the install instructions](http://golang.org/doc/install.html). +Make sure you have a working Go environment. Go version 1.1+ is required for +core cli, whereas use of the [`./altsrc`](./altsrc) input extensions requires Go +version 1.2+. [See the install +instructions](http://golang.org/doc/install.html). -To install `cli.go`, simply run: +To install cli, simply run: ``` -$ go get github.com/codegangsta/cli +$ go get github.com/urfave/cli ``` -Make sure your `PATH` includes to the `$GOPATH/bin` directory so your commands can be easily used: +Make sure your `PATH` includes to the `$GOPATH/bin` directory so your commands +can be easily used: ``` export PATH=$PATH:$GOPATH/bin ``` +### Supported platforms + +cli is tested against multiple versions of Go on Linux, and against the latest +released version of Go on OS X and Windows. For full details, see +[`./.travis.yml`](./.travis.yml) and [`./appveyor.yml`](./appveyor.yml). + +### Using the `v2` branch + +**Warning**: The `v2` branch is currently unreleased and considered unstable. + +There is currently a long-lived branch named `v2` that is intended to land as +the new `master` branch once development there has settled down. The current +`master` branch (mirrored as `v1`) is being manually merged into `v2` on +an irregular human-based schedule, but generally if one wants to "upgrade" to +`v2` *now* and accept the volatility (read: "awesomeness") that comes along with +that, please use whatever version pinning of your preference, such as via +`gopkg.in`: + +``` +$ go get gopkg.in/urfave/cli.v2 +``` + +``` go +... +import ( + "gopkg.in/urfave/cli.v2" // imports as package "cli" +) +... +``` + +### Pinning to the `v1` branch + +Similarly to the section above describing use of the `v2` branch, if one wants +to avoid any unexpected compatibility pains once `v2` becomes `master`, then +pinning to the `v1` branch is an acceptable option, e.g.: + +``` +$ go get gopkg.in/urfave/cli.v1 +``` + +``` go +... +import ( + "gopkg.in/urfave/cli.v1" // imports as package "cli" +) +... +``` + ## Getting Started -One of the philosophies behind `cli.go` is that an API should be playful and full of discovery. So a `cli.go` app can be as little as one line of code in `main()`. +One of the philosophies behind cli is that an API should be playful and full of +discovery. So a cli app can be as little as one line of code in `main()`. + ``` go package main import ( "os" - "github.com/codegangsta/cli" + + "github.com/urfave/cli" ) func main() { @@ -44,50 +147,67 @@ func main() { } ``` -This app will run and show help text, but is not very useful. Let's give an action to execute and some help documentation: +This app will run and show help text, but is not very useful. Let's give an +action to execute and some help documentation: + ``` go package main import ( + "fmt" "os" - "github.com/codegangsta/cli" + + "github.com/urfave/cli" ) func main() { app := cli.NewApp() app.Name = "boom" app.Usage = "make an explosive entrance" - app.Action = func(c *cli.Context) { - println("boom! I say!") + app.Action = func(c *cli.Context) error { + fmt.Println("boom! I say!") + return nil } app.Run(os.Args) } ``` -Running this already gives you a ton of functionality, plus support for things like subcommands and flags, which are covered below. +Running this already gives you a ton of functionality, plus support for things +like subcommands and flags, which are covered below. -## Example +## Examples -Being a programmer can be a lonely job. Thankfully by the power of automation that is not the case! Let's create a greeter app to fend off our demons of loneliness! +Being a programmer can be a lonely job. Thankfully by the power of automation +that is not the case! Let's create a greeter app to fend off our demons of +loneliness! -Start by creating a directory named `greet`, and within it, add a file, `greet.go` with the following code in it: +Start by creating a directory named `greet`, and within it, add a file, +`greet.go` with the following code in it: + ``` go package main import ( + "fmt" "os" - "github.com/codegangsta/cli" + + "github.com/urfave/cli" ) func main() { app := cli.NewApp() app.Name = "greet" app.Usage = "fight the loneliness!" - app.Action = func(c *cli.Context) { - println("Hello friend!") + app.Action = func(c *cli.Context) error { + fmt.Println("Hello friend!") + return nil } app.Run(os.Args) @@ -107,7 +227,7 @@ $ greet Hello friend! ``` -`cli.go` also generates neat help text: +cli also generates neat help text: ``` $ greet help @@ -124,87 +244,163 @@ COMMANDS: help, h Shows a list of commands or help for one command GLOBAL OPTIONS - --version Shows version information + --version Shows version information ``` ### Arguments -You can lookup arguments by calling the `Args` function on `cli.Context`. +You can lookup arguments by calling the `Args` function on `cli.Context`, e.g.: + ``` go -... -app.Action = func(c *cli.Context) { - println("Hello", c.Args()[0]) +package main + +import ( + "fmt" + "os" + + "github.com/urfave/cli" +) + +func main() { + app := cli.NewApp() + + app.Action = func(c *cli.Context) error { + fmt.Printf("Hello %q", c.Args().Get(0)) + return nil + } + + app.Run(os.Args) } -... ``` ### Flags Setting and querying flags is simple. + ``` go -... -app.Flags = []cli.Flag { - cli.StringFlag{ - Name: "lang", - Value: "english", - Usage: "language for the greeting", - }, -} -app.Action = func(c *cli.Context) { - name := "someone" - if c.NArg() > 0 { - name = c.Args()[0] +package main + +import ( + "fmt" + "os" + + "github.com/urfave/cli" +) + +func main() { + app := cli.NewApp() + + app.Flags = []cli.Flag { + cli.StringFlag{ + Name: "lang", + Value: "english", + Usage: "language for the greeting", + }, } - if c.String("lang") == "spanish" { - println("Hola", name) - } else { - println("Hello", name) + + app.Action = func(c *cli.Context) error { + name := "Nefertiti" + if c.NArg() > 0 { + name = c.Args().Get(0) + } + if c.String("lang") == "spanish" { + fmt.Println("Hola", name) + } else { + fmt.Println("Hello", name) + } + return nil } + + app.Run(os.Args) } -... ``` -You can also set a destination variable for a flag, to which the content will be scanned. +You can also set a destination variable for a flag, to which the content will be +scanned. + ``` go -... -var language string -app.Flags = []cli.Flag { - cli.StringFlag{ - Name: "lang", - Value: "english", - Usage: "language for the greeting", - Destination: &language, - }, -} -app.Action = func(c *cli.Context) { - name := "someone" - if c.NArg() > 0 { - name = c.Args()[0] +package main + +import ( + "os" + "fmt" + + "github.com/urfave/cli" +) + +func main() { + var language string + + app := cli.NewApp() + + app.Flags = []cli.Flag { + cli.StringFlag{ + Name: "lang", + Value: "english", + Usage: "language for the greeting", + Destination: &language, + }, } - if language == "spanish" { - println("Hola", name) - } else { - println("Hello", name) + + app.Action = func(c *cli.Context) error { + name := "someone" + if c.NArg() > 0 { + name = c.Args()[0] + } + if language == "spanish" { + fmt.Println("Hola", name) + } else { + fmt.Println("Hello", name) + } + return nil } + + app.Run(os.Args) } -... ``` -See full list of flags at http://godoc.org/github.com/codegangsta/cli +See full list of flags at http://godoc.org/github.com/urfave/cli #### Placeholder Values -Sometimes it's useful to specify a flag's value within the usage string itself. Such placeholders are -indicated with back quotes. +Sometimes it's useful to specify a flag's value within the usage string itself. +Such placeholders are indicated with back quotes. For example this: + + ```go -cli.StringFlag{ - Name: "config, c", - Usage: "Load configuration from `FILE`", +package main + +import ( + "os" + + "github.com/urfave/cli" +) + +func main() { + app := cli.NewApp() + + app.Flags = []cli.Flag{ + cli.StringFlag{ + Name: "config, c", + Usage: "Load configuration from `FILE`", + }, + } + + app.Run(os.Args) } ``` @@ -214,140 +410,244 @@ Will result in help output like: --config FILE, -c FILE Load configuration from FILE ``` -Note that only the first placeholder is used. Subsequent back-quoted words will be left as-is. +Note that only the first placeholder is used. Subsequent back-quoted words will +be left as-is. #### Alternate Names -You can set alternate (or short) names for flags by providing a comma-delimited list for the `Name`. e.g. +You can set alternate (or short) names for flags by providing a comma-delimited +list for the `Name`. e.g. + ``` go -app.Flags = []cli.Flag { - cli.StringFlag{ - Name: "lang, l", - Value: "english", - Usage: "language for the greeting", - }, +package main + +import ( + "os" + + "github.com/urfave/cli" +) + +func main() { + app := cli.NewApp() + + app.Flags = []cli.Flag { + cli.StringFlag{ + Name: "lang, l", + Value: "english", + Usage: "language for the greeting", + }, + } + + app.Run(os.Args) } ``` -That flag can then be set with `--lang spanish` or `-l spanish`. Note that giving two different forms of the same flag in the same command invocation is an error. +That flag can then be set with `--lang spanish` or `-l spanish`. Note that +giving two different forms of the same flag in the same command invocation is an +error. #### Values from the Environment You can also have the default value set from the environment via `EnvVar`. e.g. + ``` go -app.Flags = []cli.Flag { - cli.StringFlag{ - Name: "lang, l", - Value: "english", - Usage: "language for the greeting", - EnvVar: "APP_LANG", - }, +package main + +import ( + "os" + + "github.com/urfave/cli" +) + +func main() { + app := cli.NewApp() + + app.Flags = []cli.Flag { + cli.StringFlag{ + Name: "lang, l", + Value: "english", + Usage: "language for the greeting", + EnvVar: "APP_LANG", + }, + } + + app.Run(os.Args) } ``` -The `EnvVar` may also be given as a comma-delimited "cascade", where the first environment variable that resolves is used as the default. +The `EnvVar` may also be given as a comma-delimited "cascade", where the first +environment variable that resolves is used as the default. + ``` go -app.Flags = []cli.Flag { - cli.StringFlag{ - Name: "lang, l", - Value: "english", - Usage: "language for the greeting", - EnvVar: "LEGACY_COMPAT_LANG,APP_LANG,LANG", - }, +package main + +import ( + "os" + + "github.com/urfave/cli" +) + +func main() { + app := cli.NewApp() + + app.Flags = []cli.Flag { + cli.StringFlag{ + Name: "lang, l", + Value: "english", + Usage: "language for the greeting", + EnvVar: "LEGACY_COMPAT_LANG,APP_LANG,LANG", + }, + } + + app.Run(os.Args) } ``` #### Values from alternate input sources (YAML and others) -There is a separate package altsrc that adds support for getting flag values from other input sources like YAML. +There is a separate package altsrc that adds support for getting flag values +from other input sources like YAML. -In order to get values for a flag from an alternate input source the following code would be added to wrap an existing cli.Flag like below: +In order to get values for a flag from an alternate input source the following +code would be added to wrap an existing cli.Flag like below: ``` go altsrc.NewIntFlag(cli.IntFlag{Name: "test"}) ``` -Initialization must also occur for these flags. Below is an example initializing getting data from a yaml file below. +Initialization must also occur for these flags. Below is an example initializing +getting data from a yaml file below. ``` go command.Before = altsrc.InitInputSourceWithContext(command.Flags, NewYamlSourceFromFlagFunc("load")) ``` -The code above will use the "load" string as a flag name to get the file name of a yaml file from the cli.Context. -It will then use that file name to initialize the yaml input source for any flags that are defined on that command. -As a note the "load" flag used would also have to be defined on the command flags in order for this code snipped to work. +The code above will use the "load" string as a flag name to get the file name of +a yaml file from the cli.Context. It will then use that file name to initialize +the yaml input source for any flags that are defined on that command. As a note +the "load" flag used would also have to be defined on the command flags in order +for this code snipped to work. -Currently only YAML files are supported but developers can add support for other input sources by implementing the -altsrc.InputSourceContext for their given sources. +Currently only YAML files are supported but developers can add support for other +input sources by implementing the altsrc.InputSourceContext for their given +sources. Here is a more complete sample of a command using YAML support: + ``` go - command := &cli.Command{ - Name: "test-cmd", - Aliases: []string{"tc"}, - Usage: "this is for testing", - Description: "testing", - Action: func(c *cli.Context) { - // Action to run - }, - Flags: []cli.Flag{ - NewIntFlag(cli.IntFlag{Name: "test"}), - cli.StringFlag{Name: "load"}}, - } - command.Before = InitInputSourceWithContext(command.Flags, NewYamlSourceFromFlagFunc("load")) - err := command.Run(c) +package notmain + +import ( + "fmt" + "os" + + "github.com/urfave/cli" + "github.com/urfave/cli/altsrc" +) + +func main() { + app := cli.NewApp() + + flags := []cli.Flag{ + altsrc.NewIntFlag(cli.IntFlag{Name: "test"}), + cli.StringFlag{Name: "load"}, + } + + app.Action = func(c *cli.Context) error { + fmt.Println("yaml ist rad") + return nil + } + + app.Before = altsrc.InitInputSourceWithContext(flags, altsrc.NewYamlSourceFromFlagFunc("load")) + app.Flags = flags + + app.Run(os.Args) +} ``` ### Subcommands Subcommands can be defined for a more git-like command line app. + ```go -... -app.Commands = []cli.Command{ - { - Name: "add", - Aliases: []string{"a"}, - Usage: "add a task to the list", - Action: func(c *cli.Context) { - println("added task: ", c.Args().First()) +package main + +import ( + "fmt" + "os" + + "github.com/urfave/cli" +) + +func main() { + app := cli.NewApp() + + app.Commands = []cli.Command{ + { + Name: "add", + Aliases: []string{"a"}, + Usage: "add a task to the list", + Action: func(c *cli.Context) error { + fmt.Println("added task: ", c.Args().First()) + return nil + }, }, - }, - { - Name: "complete", - Aliases: []string{"c"}, - Usage: "complete a task on the list", - Action: func(c *cli.Context) { - println("completed task: ", c.Args().First()) + { + Name: "complete", + Aliases: []string{"c"}, + Usage: "complete a task on the list", + Action: func(c *cli.Context) error { + fmt.Println("completed task: ", c.Args().First()) + return nil + }, }, - }, - { - Name: "template", - Aliases: []string{"r"}, - Usage: "options for task templates", - Subcommands: []cli.Command{ - { - Name: "add", - Usage: "add a new template", - Action: func(c *cli.Context) { - println("new task template: ", c.Args().First()) + { + Name: "template", + Aliases: []string{"t"}, + Usage: "options for task templates", + Subcommands: []cli.Command{ + { + Name: "add", + Usage: "add a new template", + Action: func(c *cli.Context) error { + fmt.Println("new task template: ", c.Args().First()) + return nil + }, }, - }, - { - Name: "remove", - Usage: "remove an existing template", - Action: func(c *cli.Context) { - println("removed task template: ", c.Args().First()) + { + Name: "remove", + Usage: "remove an existing template", + Action: func(c *cli.Context) error { + fmt.Println("removed task template: ", c.Args().First()) + return nil + }, }, }, }, - }, + } + + app.Run(os.Args) } -... ``` ### Subcommands categories @@ -359,34 +659,79 @@ output. E.g. ```go -... - app.Commands = []cli.Command{ - { - Name: "noop", - }, - { - Name: "add", - Category: "template", - }, - { - Name: "remove", - Category: "template", - }, - } -... +package main + +import ( + "os" + + "github.com/urfave/cli" +) + +func main() { + app := cli.NewApp() + + app.Commands = []cli.Command{ + { + Name: "noop", + }, + { + Name: "add", + Category: "template", + }, + { + Name: "remove", + Category: "template", + }, + } + + app.Run(os.Args) +} ``` Will include: ``` -... COMMANDS: noop Template actions: add remove -... +``` + +### Exit code + +Calling `App.Run` will not automatically call `os.Exit`, which means that by +default the exit code will "fall through" to being `0`. An explicit exit code +may be set by returning a non-nil error that fulfills `cli.ExitCoder`, *or* a +`cli.MultiError` that includes an error that fulfills `cli.ExitCoder`, e.g.: + +``` go +package main + +import ( + "os" + + "github.com/urfave/cli" +) + +func main() { + app := cli.NewApp() + app.Flags = []cli.Flag{ + cli.BoolTFlag{ + Name: "ginger-crouton", + Usage: "is it in the soup?", + }, + } + app.Action = func(ctx *cli.Context) error { + if !ctx.Bool("ginger-crouton") { + return cli.NewExitError("it is not in the soup", 86) + } + return nil + } + + app.Run(os.Args) +} ``` ### Bash Completion @@ -396,41 +741,58 @@ flag on the `App` object. By default, this setting will only auto-complete to show an app's subcommands, but you can write your own completion methods for the App or its subcommands. -```go -... -var tasks = []string{"cook", "clean", "laundry", "eat", "sleep", "code"} -app := cli.NewApp() -app.EnableBashCompletion = true -app.Commands = []cli.Command{ - { - Name: "complete", - Aliases: []string{"c"}, - Usage: "complete a task on the list", - Action: func(c *cli.Context) { - println("completed task: ", c.Args().First()) - }, - BashComplete: func(c *cli.Context) { - // This will complete if no args are passed - if c.NArg() > 0 { - return - } - for _, t := range tasks { - fmt.Println(t) - } + +``` go +package main + +import ( + "fmt" + "os" + + "github.com/urfave/cli" +) + +func main() { + tasks := []string{"cook", "clean", "laundry", "eat", "sleep", "code"} + + app := cli.NewApp() + app.EnableBashCompletion = true + app.Commands = []cli.Command{ + { + Name: "complete", + Aliases: []string{"c"}, + Usage: "complete a task on the list", + Action: func(c *cli.Context) error { + fmt.Println("completed task: ", c.Args().First()) + return nil + }, + BashComplete: func(c *cli.Context) { + // This will complete if no args are passed + if c.NArg() > 0 { + return + } + for _, t := range tasks { + fmt.Println(t) + } + }, }, } + + app.Run(os.Args) } -... ``` -#### To Enable +#### Enabling Source the `autocomplete/bash_autocomplete` file in your `.bashrc` file while setting the `PROG` variable to the name of your program: `PROG=myprogram source /.../cli/autocomplete/bash_autocomplete` -#### To Distribute +#### Distribution Copy `autocomplete/bash_autocomplete` into `/etc/bash_completion.d/` and rename it to the name of the program you wish to add autocomplete support for (or @@ -446,10 +808,502 @@ Alternatively, you can just document that users should source the generic `autocomplete/bash_autocomplete` in their bash configuration with `$PROG` set to the name of their program (as above). +#### Customization + +The default bash completion flag (`--generate-bash-completion`) is defined as +`cli.BashCompletionFlag`, and may be redefined if desired, e.g.: + + +``` go +package main + +import ( + "os" + + "github.com/urfave/cli" +) + +func main() { + cli.BashCompletionFlag = cli.BoolFlag{ + Name: "compgen", + Hidden: true, + } + + app := cli.NewApp() + app.EnableBashCompletion = true + app.Commands = []cli.Command{ + { + Name: "wat", + }, + } + app.Run(os.Args) +} +``` + +### Generated Help Text + +The default help flag (`-h/--help`) is defined as `cli.HelpFlag` and is checked +by the cli internals in order to print generated help text for the app, command, +or subcommand, and break execution. + +#### Customization + +All of the help text generation may be customized, and at multiple levels. The +templates are exposed as variables `AppHelpTemplate`, `CommandHelpTemplate`, and +`SubcommandHelpTemplate` which may be reassigned or augmented, and full override +is possible by assigning a compatible func to the `cli.HelpPrinter` variable, +e.g.: + + +``` go +package main + +import ( + "fmt" + "io" + "os" + + "github.com/urfave/cli" +) + +func main() { + // EXAMPLE: Append to an existing template + cli.AppHelpTemplate = fmt.Sprintf(`%s + +WEBSITE: http://awesometown.example.com + +SUPPORT: support@awesometown.example.com + +`, cli.AppHelpTemplate) + + // EXAMPLE: Override a template + cli.AppHelpTemplate = `NAME: + {{.Name}} - {{.Usage}} +USAGE: + {{.HelpName}} {{if .VisibleFlags}}[global options]{{end}}{{if .Commands}} command +[command options]{{end}} {{if +.ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}} + {{if len .Authors}} +AUTHOR(S): + {{range .Authors}}{{ . }}{{end}} + {{end}}{{if .Commands}} +COMMANDS: +{{range .Commands}}{{if not .HideHelp}} {{join .Names ", "}}{{ "\t" +}}{{.Usage}}{{ "\n" }}{{end}}{{end}}{{end}}{{if .VisibleFlags}} +GLOBAL OPTIONS: + {{range .VisibleFlags}}{{.}} + {{end}}{{end}}{{if .Copyright }} +COPYRIGHT: + {{.Copyright}} + {{end}}{{if .Version}} +VERSION: + {{.Version}} + {{end}} +` + + // EXAMPLE: Replace the `HelpPrinter` func + cli.HelpPrinter = func(w io.Writer, templ string, data interface{}) { + fmt.Println("Ha HA. I pwnd the help!!1") + } + + cli.NewApp().Run(os.Args) +} +``` + +The default flag may be customized to something other than `-h/--help` by +setting `cli.HelpFlag`, e.g.: + + +``` go +package main + +import ( + "os" + + "github.com/urfave/cli" +) + +func main() { + cli.HelpFlag = cli.BoolFlag{ + Name: "halp, haaaaalp", + Usage: "HALP", + EnvVar: "SHOW_HALP,HALPPLZ", + } + + cli.NewApp().Run(os.Args) +} +``` + +### Version Flag + +The default version flag (`-v/--version`) is defined as `cli.VersionFlag`, which +is checked by the cli internals in order to print the `App.Version` via +`cli.VersionPrinter` and break execution. + +#### Customization + +The default flag may be cusomized to something other than `-v/--version` by +setting `cli.VersionFlag`, e.g.: + + +``` go +package main + +import ( + "os" + + "github.com/urfave/cli" +) + +func main() { + cli.VersionFlag = cli.BoolFlag{ + Name: "print-version, V", + Usage: "print only the version", + } + + app := cli.NewApp() + app.Name = "partay" + app.Version = "v19.99.0" + app.Run(os.Args) +} +``` + +Alternatively, the version printer at `cli.VersionPrinter` may be overridden, e.g.: + + +``` go +package main + +import ( + "fmt" + "os" + + "github.com/urfave/cli" +) + +var ( + Revision = "fafafaf" +) + +func main() { + cli.VersionPrinter = func(c *cli.Context) { + fmt.Printf("version=%s revision=%s\n", c.App.Version, Revision) + } + + app := cli.NewApp() + app.Name = "partay" + app.Version = "v19.99.0" + app.Run(os.Args) +} +``` + +#### Full API Example + +**Notice**: This is a contrived (functioning) example meant strictly for API +demonstration purposes. Use of one's imagination is encouraged. + + +``` go +package main + +import ( + "errors" + "flag" + "fmt" + "io" + "io/ioutil" + "os" + "time" + + "github.com/urfave/cli" +) + +func init() { + cli.AppHelpTemplate += "\nCUSTOMIZED: you bet ur muffins\n" + cli.CommandHelpTemplate += "\nYMMV\n" + cli.SubcommandHelpTemplate += "\nor something\n" + + cli.HelpFlag = cli.BoolFlag{Name: "halp"} + cli.BashCompletionFlag = cli.BoolFlag{Name: "compgen", Hidden: true} + cli.VersionFlag = cli.BoolFlag{Name: "print-version, V"} + + cli.HelpPrinter = func(w io.Writer, templ string, data interface{}) { + fmt.Fprintf(w, "best of luck to you\n") + } + cli.VersionPrinter = func(c *cli.Context) { + fmt.Fprintf(c.App.Writer, "version=%s\n", c.App.Version) + } + cli.OsExiter = func(c int) { + fmt.Fprintf(cli.ErrWriter, "refusing to exit %d\n", c) + } + cli.ErrWriter = ioutil.Discard + cli.FlagStringer = func(fl cli.Flag) string { + return fmt.Sprintf("\t\t%s", fl.GetName()) + } +} + +type hexWriter struct{} + +func (w *hexWriter) Write(p []byte) (int, error) { + for _, b := range p { + fmt.Printf("%x", b) + } + fmt.Printf("\n") + + return len(p), nil +} + +type genericType struct{ + s string +} + +func (g *genericType) Set(value string) error { + g.s = value + return nil +} + +func (g *genericType) String() string { + return g.s +} + +func main() { + app := cli.NewApp() + app.Name = "kənˈtrīv" + app.Version = "v19.99.0" + app.Compiled = time.Now() + app.Authors = []cli.Author{ + cli.Author{ + Name: "Example Human", + Email: "human@example.com", + }, + } + app.Copyright = "(c) 1999 Serious Enterprise" + app.HelpName = "contrive" + app.Usage = "demonstrate available API" + app.UsageText = "contrive - demonstrating the available API" + app.ArgsUsage = "[args and such]" + app.Commands = []cli.Command{ + cli.Command{ + Name: "doo", + Aliases: []string{"do"}, + Category: "motion", + Usage: "do the doo", + UsageText: "doo - does the dooing", + Description: "no really, there is a lot of dooing to be done", + ArgsUsage: "[arrgh]", + Flags: []cli.Flag{ + cli.BoolFlag{Name: "forever, forevvarr"}, + }, + Subcommands: cli.Commands{ + cli.Command{ + Name: "wop", + Action: wopAction, + }, + }, + SkipFlagParsing: false, + HideHelp: false, + Hidden: false, + HelpName: "doo!", + BashComplete: func(c *cli.Context) { + fmt.Fprintf(c.App.Writer, "--better\n") + }, + Before: func(c *cli.Context) error { + fmt.Fprintf(c.App.Writer, "brace for impact\n") + return nil + }, + After: func(c *cli.Context) error { + fmt.Fprintf(c.App.Writer, "did we lose anyone?\n") + return nil + }, + Action: func(c *cli.Context) error { + c.Command.FullName() + c.Command.HasName("wop") + c.Command.Names() + c.Command.VisibleFlags() + fmt.Fprintf(c.App.Writer, "dodododododoodododddooooododododooo\n") + if c.Bool("forever") { + c.Command.Run(c) + } + return nil + }, + OnUsageError: func(c *cli.Context, err error, isSubcommand bool) error { + fmt.Fprintf(c.App.Writer, "for shame\n") + return err + }, + }, + } + app.Flags = []cli.Flag{ + cli.BoolFlag{Name: "fancy"}, + cli.BoolTFlag{Name: "fancier"}, + cli.DurationFlag{Name: "howlong, H", Value: time.Second * 3}, + cli.Float64Flag{Name: "howmuch"}, + cli.GenericFlag{Name: "wat", Value: &genericType{}}, + cli.Int64Flag{Name: "longdistance"}, + cli.Int64SliceFlag{Name: "intervals"}, + cli.IntFlag{Name: "distance"}, + cli.IntSliceFlag{Name: "times"}, + cli.StringFlag{Name: "dance-move, d"}, + cli.StringSliceFlag{Name: "names, N"}, + cli.UintFlag{Name: "age"}, + cli.Uint64Flag{Name: "bigage"}, + } + app.EnableBashCompletion = true + app.HideHelp = false + app.HideVersion = false + app.BashComplete = func(c *cli.Context) { + fmt.Fprintf(c.App.Writer, "lipstick\nkiss\nme\nlipstick\nringo\n") + } + app.Before = func(c *cli.Context) error { + fmt.Fprintf(c.App.Writer, "HEEEERE GOES\n") + return nil + } + app.After = func(c *cli.Context) error { + fmt.Fprintf(c.App.Writer, "Phew!\n") + return nil + } + app.CommandNotFound = func(c *cli.Context, command string) { + fmt.Fprintf(c.App.Writer, "Thar be no %q here.\n", command) + } + app.OnUsageError = func(c *cli.Context, err error, isSubcommand bool) error { + if isSubcommand { + return err + } + + fmt.Fprintf(c.App.Writer, "WRONG: %#v\n", err) + return nil + } + app.Action = func(c *cli.Context) error { + cli.DefaultAppComplete(c) + cli.HandleExitCoder(errors.New("not an exit coder, though")) + cli.ShowAppHelp(c) + cli.ShowCommandCompletions(c, "nope") + cli.ShowCommandHelp(c, "also-nope") + cli.ShowCompletions(c) + cli.ShowSubcommandHelp(c) + cli.ShowVersion(c) + + categories := c.App.Categories() + categories.AddCommand("sounds", cli.Command{ + Name: "bloop", + }) + + for _, category := range c.App.Categories() { + fmt.Fprintf(c.App.Writer, "%s\n", category.Name) + fmt.Fprintf(c.App.Writer, "%#v\n", category.Commands) + fmt.Fprintf(c.App.Writer, "%#v\n", category.VisibleCommands()) + } + + fmt.Printf("%#v\n", c.App.Command("doo")) + if c.Bool("infinite") { + c.App.Run([]string{"app", "doo", "wop"}) + } + + if c.Bool("forevar") { + c.App.RunAsSubcommand(c) + } + c.App.Setup() + fmt.Printf("%#v\n", c.App.VisibleCategories()) + fmt.Printf("%#v\n", c.App.VisibleCommands()) + fmt.Printf("%#v\n", c.App.VisibleFlags()) + + fmt.Printf("%#v\n", c.Args().First()) + if len(c.Args()) > 0 { + fmt.Printf("%#v\n", c.Args()[1]) + } + fmt.Printf("%#v\n", c.Args().Present()) + fmt.Printf("%#v\n", c.Args().Tail()) + + set := flag.NewFlagSet("contrive", 0) + nc := cli.NewContext(c.App, set, c) + + fmt.Printf("%#v\n", nc.Args()) + fmt.Printf("%#v\n", nc.Bool("nope")) + fmt.Printf("%#v\n", nc.BoolT("nerp")) + fmt.Printf("%#v\n", nc.Duration("howlong")) + fmt.Printf("%#v\n", nc.Float64("hay")) + fmt.Printf("%#v\n", nc.Generic("bloop")) + fmt.Printf("%#v\n", nc.Int64("bonk")) + fmt.Printf("%#v\n", nc.Int64Slice("burnks")) + fmt.Printf("%#v\n", nc.Int("bips")) + fmt.Printf("%#v\n", nc.IntSlice("blups")) + fmt.Printf("%#v\n", nc.String("snurt")) + fmt.Printf("%#v\n", nc.StringSlice("snurkles")) + fmt.Printf("%#v\n", nc.Uint("flub")) + fmt.Printf("%#v\n", nc.Uint64("florb")) + fmt.Printf("%#v\n", nc.GlobalBool("global-nope")) + fmt.Printf("%#v\n", nc.GlobalBoolT("global-nerp")) + fmt.Printf("%#v\n", nc.GlobalDuration("global-howlong")) + fmt.Printf("%#v\n", nc.GlobalFloat64("global-hay")) + fmt.Printf("%#v\n", nc.GlobalGeneric("global-bloop")) + fmt.Printf("%#v\n", nc.GlobalInt("global-bips")) + fmt.Printf("%#v\n", nc.GlobalIntSlice("global-blups")) + fmt.Printf("%#v\n", nc.GlobalString("global-snurt")) + fmt.Printf("%#v\n", nc.GlobalStringSlice("global-snurkles")) + + fmt.Printf("%#v\n", nc.FlagNames()) + fmt.Printf("%#v\n", nc.GlobalFlagNames()) + fmt.Printf("%#v\n", nc.GlobalIsSet("wat")) + fmt.Printf("%#v\n", nc.GlobalSet("wat", "nope")) + fmt.Printf("%#v\n", nc.NArg()) + fmt.Printf("%#v\n", nc.NumFlags()) + fmt.Printf("%#v\n", nc.Parent()) + + nc.Set("wat", "also-nope") + + ec := cli.NewExitError("ohwell", 86) + fmt.Fprintf(c.App.Writer, "%d", ec.ExitCode()) + fmt.Printf("made it!\n") + return ec + } + + if os.Getenv("HEXY") != "" { + app.Writer = &hexWriter{} + app.ErrWriter = &hexWriter{} + } + + app.Metadata = map[string]interface{}{ + "layers": "many", + "explicable": false, + "whatever-values": 19.99, + } + + app.Run(os.Args) +} + +func wopAction(c *cli.Context) error { + fmt.Fprintf(c.App.Writer, ":wave: over here, eh\n") + return nil +} +``` + ## Contribution Guidelines -Feel free to put up a pull request to fix a bug or maybe add a feature. I will give it a code review and make sure that it does not break backwards compatibility. If I or any other collaborators agree that it is in line with the vision of the project, we will work with you to get the code into a mergeable state and merge it into the master branch. +Feel free to put up a pull request to fix a bug or maybe add a feature. I will +give it a code review and make sure that it does not break backwards +compatibility. If I or any other collaborators agree that it is in line with +the vision of the project, we will work with you to get the code into +a mergeable state and merge it into the master branch. -If you have contributed something significant to the project, I will most likely add you as a collaborator. As a collaborator you are given the ability to merge others pull requests. It is very important that new code does not break existing code, so be careful about what code you do choose to merge. If you have any questions feel free to link @codegangsta to the issue in question and we can review it together. +If you have contributed something significant to the project, we will most +likely add you as a collaborator. As a collaborator you are given the ability +to merge others pull requests. It is very important that new code does not +break existing code, so be careful about what code you do choose to merge. -If you feel like you have contributed to the project but have not yet been added as a collaborator, I probably forgot to add you. Hit @codegangsta up over email and we will get it figured out. +If you feel like you have contributed to the project but have not yet been +added as a collaborator, we probably forgot to add you, please open an issue. diff --git a/vendor/github.com/codegangsta/cli/altsrc/flag.go b/vendor/github.com/codegangsta/cli/altsrc/flag.go index f13ffb487..3e44d0215 100644 --- a/vendor/github.com/codegangsta/cli/altsrc/flag.go +++ b/vendor/github.com/codegangsta/cli/altsrc/flag.go @@ -7,7 +7,7 @@ import ( "strconv" "strings" - "github.com/codegangsta/cli" + "github.com/urfave/cli" ) // FlagInputSourceExtension is an extension interface of cli.Flag that @@ -38,7 +38,7 @@ func ApplyInputSourceValues(context *cli.Context, inputSourceContext InputSource // InitInputSource is used to to setup an InputSourceContext on a cli.Command Before method. It will create a new // input source based on the func provided. If there is no error it will then apply the new input source to any flags // that are supported by the input source -func InitInputSource(flags []cli.Flag, createInputSource func() (InputSourceContext, error)) func(context *cli.Context) error { +func InitInputSource(flags []cli.Flag, createInputSource func() (InputSourceContext, error)) cli.BeforeFunc { return func(context *cli.Context) error { inputSource, err := createInputSource() if err != nil { @@ -52,7 +52,7 @@ func InitInputSource(flags []cli.Flag, createInputSource func() (InputSourceCont // InitInputSourceWithContext is used to to setup an InputSourceContext on a cli.Command Before method. It will create a new // input source based on the func provided with potentially using existing cli.Context values to initialize itself. If there is // no error it will then apply the new input source to any flags that are supported by the input source -func InitInputSourceWithContext(flags []cli.Flag, createInputSource func(context *cli.Context) (InputSourceContext, error)) func(context *cli.Context) error { +func InitInputSourceWithContext(flags []cli.Flag, createInputSource func(context *cli.Context) (InputSourceContext, error)) cli.BeforeFunc { return func(context *cli.Context) error { inputSource, err := createInputSource(context) if err != nil { diff --git a/vendor/github.com/codegangsta/cli/altsrc/flag_test.go b/vendor/github.com/codegangsta/cli/altsrc/flag_test.go index ac4d1f53a..218e9b869 100644 --- a/vendor/github.com/codegangsta/cli/altsrc/flag_test.go +++ b/vendor/github.com/codegangsta/cli/altsrc/flag_test.go @@ -8,7 +8,7 @@ import ( "testing" "time" - "github.com/codegangsta/cli" + "github.com/urfave/cli" ) type testApplyInputSource struct { @@ -296,7 +296,7 @@ func TestFloat64ApplyInputSourceMethodEnvVarSet(t *testing.T) { } func runTest(t *testing.T, test testApplyInputSource) *cli.Context { - inputSource := &MapInputSource{valueMap: map[string]interface{}{test.FlagName: test.MapValue}} + inputSource := &MapInputSource{valueMap: map[interface{}]interface{}{test.FlagName: test.MapValue}} set := flag.NewFlagSet(test.FlagSetName, flag.ContinueOnError) c := cli.NewContext(nil, set, nil) if test.EnvVarName != "" && test.EnvVarValue != "" { diff --git a/vendor/github.com/codegangsta/cli/altsrc/input_source_context.go b/vendor/github.com/codegangsta/cli/altsrc/input_source_context.go index 6d695ff16..8ea7e9205 100644 --- a/vendor/github.com/codegangsta/cli/altsrc/input_source_context.go +++ b/vendor/github.com/codegangsta/cli/altsrc/input_source_context.go @@ -3,7 +3,7 @@ package altsrc import ( "time" - "github.com/codegangsta/cli" + "github.com/urfave/cli" ) // InputSourceContext is an interface used to allow diff --git a/vendor/github.com/codegangsta/cli/altsrc/map_input_source.go b/vendor/github.com/codegangsta/cli/altsrc/map_input_source.go index f1670fbc4..b1c8e4f1d 100644 --- a/vendor/github.com/codegangsta/cli/altsrc/map_input_source.go +++ b/vendor/github.com/codegangsta/cli/altsrc/map_input_source.go @@ -3,15 +3,40 @@ package altsrc import ( "fmt" "reflect" + "strings" "time" - "github.com/codegangsta/cli" + "github.com/urfave/cli" ) // MapInputSource implements InputSourceContext to return // data from the map that is loaded. type MapInputSource struct { - valueMap map[string]interface{} + valueMap map[interface{}]interface{} +} + +// nestedVal checks if the name has '.' delimiters. +// If so, it tries to traverse the tree by the '.' delimited sections to find +// a nested value for the key. +func nestedVal(name string, tree map[interface{}]interface{}) (interface{}, bool) { + if sections := strings.Split(name, "."); len(sections) > 1 { + node := tree + for _, section := range sections[:len(sections)-1] { + if child, ok := node[section]; !ok { + return nil, false + } else { + if ctype, ok := child.(map[interface{}]interface{}); !ok { + return nil, false + } else { + node = ctype + } + } + } + if val, ok := node[sections[len(sections)-1]]; ok { + return val, true + } + } + return nil, false } // Int returns an int from the map if it exists otherwise returns 0 @@ -22,7 +47,14 @@ func (fsm *MapInputSource) Int(name string) (int, error) { if !isType { return 0, incorrectTypeForFlagError(name, "int", otherGenericValue) } - + return otherValue, nil + } + nestedGenericValue, exists := nestedVal(name, fsm.valueMap) + if exists { + otherValue, isType := nestedGenericValue.(int) + if !isType { + return 0, incorrectTypeForFlagError(name, "int", nestedGenericValue) + } return otherValue, nil } @@ -39,6 +71,14 @@ func (fsm *MapInputSource) Duration(name string) (time.Duration, error) { } return otherValue, nil } + nestedGenericValue, exists := nestedVal(name, fsm.valueMap) + if exists { + otherValue, isType := nestedGenericValue.(time.Duration) + if !isType { + return 0, incorrectTypeForFlagError(name, "duration", nestedGenericValue) + } + return otherValue, nil + } return 0, nil } @@ -53,6 +93,14 @@ func (fsm *MapInputSource) Float64(name string) (float64, error) { } return otherValue, nil } + nestedGenericValue, exists := nestedVal(name, fsm.valueMap) + if exists { + otherValue, isType := nestedGenericValue.(float64) + if !isType { + return 0, incorrectTypeForFlagError(name, "float64", nestedGenericValue) + } + return otherValue, nil + } return 0, nil } @@ -67,6 +115,14 @@ func (fsm *MapInputSource) String(name string) (string, error) { } return otherValue, nil } + nestedGenericValue, exists := nestedVal(name, fsm.valueMap) + if exists { + otherValue, isType := nestedGenericValue.(string) + if !isType { + return "", incorrectTypeForFlagError(name, "string", nestedGenericValue) + } + return otherValue, nil + } return "", nil } @@ -81,6 +137,14 @@ func (fsm *MapInputSource) StringSlice(name string) ([]string, error) { } return otherValue, nil } + nestedGenericValue, exists := nestedVal(name, fsm.valueMap) + if exists { + otherValue, isType := nestedGenericValue.([]string) + if !isType { + return nil, incorrectTypeForFlagError(name, "[]string", nestedGenericValue) + } + return otherValue, nil + } return nil, nil } @@ -95,6 +159,14 @@ func (fsm *MapInputSource) IntSlice(name string) ([]int, error) { } return otherValue, nil } + nestedGenericValue, exists := nestedVal(name, fsm.valueMap) + if exists { + otherValue, isType := nestedGenericValue.([]int) + if !isType { + return nil, incorrectTypeForFlagError(name, "[]int", nestedGenericValue) + } + return otherValue, nil + } return nil, nil } @@ -109,6 +181,14 @@ func (fsm *MapInputSource) Generic(name string) (cli.Generic, error) { } return otherValue, nil } + nestedGenericValue, exists := nestedVal(name, fsm.valueMap) + if exists { + otherValue, isType := nestedGenericValue.(cli.Generic) + if !isType { + return nil, incorrectTypeForFlagError(name, "cli.Generic", nestedGenericValue) + } + return otherValue, nil + } return nil, nil } @@ -123,6 +203,14 @@ func (fsm *MapInputSource) Bool(name string) (bool, error) { } return otherValue, nil } + nestedGenericValue, exists := nestedVal(name, fsm.valueMap) + if exists { + otherValue, isType := nestedGenericValue.(bool) + if !isType { + return false, incorrectTypeForFlagError(name, "bool", nestedGenericValue) + } + return otherValue, nil + } return false, nil } @@ -137,6 +225,14 @@ func (fsm *MapInputSource) BoolT(name string) (bool, error) { } return otherValue, nil } + nestedGenericValue, exists := nestedVal(name, fsm.valueMap) + if exists { + otherValue, isType := nestedGenericValue.(bool) + if !isType { + return true, incorrectTypeForFlagError(name, "bool", nestedGenericValue) + } + return otherValue, nil + } return true, nil } diff --git a/vendor/github.com/codegangsta/cli/altsrc/yaml_command_test.go b/vendor/github.com/codegangsta/cli/altsrc/yaml_command_test.go index 275bc645f..31f78ce58 100644 --- a/vendor/github.com/codegangsta/cli/altsrc/yaml_command_test.go +++ b/vendor/github.com/codegangsta/cli/altsrc/yaml_command_test.go @@ -11,7 +11,7 @@ import ( "os" "testing" - "github.com/codegangsta/cli" + "github.com/urfave/cli" ) func TestCommandYamlFileTest(t *testing.T) { @@ -29,9 +29,10 @@ func TestCommandYamlFileTest(t *testing.T) { Aliases: []string{"tc"}, Usage: "this is for testing", Description: "testing", - Action: func(c *cli.Context) { + Action: func(c *cli.Context) error { val := c.Int("test") expect(t, val, 15) + return nil }, Flags: []cli.Flag{ NewIntFlag(cli.IntFlag{Name: "test"}), @@ -61,9 +62,10 @@ func TestCommandYamlFileTestGlobalEnvVarWins(t *testing.T) { Aliases: []string{"tc"}, Usage: "this is for testing", Description: "testing", - Action: func(c *cli.Context) { + Action: func(c *cli.Context) error { val := c.Int("test") expect(t, val, 10) + return nil }, Flags: []cli.Flag{ NewIntFlag(cli.IntFlag{Name: "test", EnvVar: "THE_TEST"}), @@ -76,6 +78,41 @@ func TestCommandYamlFileTestGlobalEnvVarWins(t *testing.T) { expect(t, err, nil) } +func TestCommandYamlFileTestGlobalEnvVarWinsNested(t *testing.T) { + app := cli.NewApp() + set := flag.NewFlagSet("test", 0) + ioutil.WriteFile("current.yaml", []byte(`top: + test: 15`), 0666) + defer os.Remove("current.yaml") + + os.Setenv("THE_TEST", "10") + defer os.Setenv("THE_TEST", "") + test := []string{"test-cmd", "--load", "current.yaml"} + set.Parse(test) + + c := cli.NewContext(app, set, nil) + + command := &cli.Command{ + Name: "test-cmd", + Aliases: []string{"tc"}, + Usage: "this is for testing", + Description: "testing", + Action: func(c *cli.Context) error { + val := c.Int("top.test") + expect(t, val, 10) + return nil + }, + Flags: []cli.Flag{ + NewIntFlag(cli.IntFlag{Name: "top.test", EnvVar: "THE_TEST"}), + cli.StringFlag{Name: "load"}}, + } + command.Before = InitInputSourceWithContext(command.Flags, NewYamlSourceFromFlagFunc("load")) + + err := command.Run(c) + + expect(t, err, nil) +} + func TestCommandYamlFileTestSpecifiedFlagWins(t *testing.T) { app := cli.NewApp() set := flag.NewFlagSet("test", 0) @@ -92,9 +129,10 @@ func TestCommandYamlFileTestSpecifiedFlagWins(t *testing.T) { Aliases: []string{"tc"}, Usage: "this is for testing", Description: "testing", - Action: func(c *cli.Context) { + Action: func(c *cli.Context) error { val := c.Int("test") expect(t, val, 7) + return nil }, Flags: []cli.Flag{ NewIntFlag(cli.IntFlag{Name: "test"}), @@ -107,6 +145,39 @@ func TestCommandYamlFileTestSpecifiedFlagWins(t *testing.T) { expect(t, err, nil) } +func TestCommandYamlFileTestSpecifiedFlagWinsNested(t *testing.T) { + app := cli.NewApp() + set := flag.NewFlagSet("test", 0) + ioutil.WriteFile("current.yaml", []byte(`top: + test: 15`), 0666) + defer os.Remove("current.yaml") + + test := []string{"test-cmd", "--load", "current.yaml", "--top.test", "7"} + set.Parse(test) + + c := cli.NewContext(app, set, nil) + + command := &cli.Command{ + Name: "test-cmd", + Aliases: []string{"tc"}, + Usage: "this is for testing", + Description: "testing", + Action: func(c *cli.Context) error { + val := c.Int("top.test") + expect(t, val, 7) + return nil + }, + Flags: []cli.Flag{ + NewIntFlag(cli.IntFlag{Name: "top.test"}), + cli.StringFlag{Name: "load"}}, + } + command.Before = InitInputSourceWithContext(command.Flags, NewYamlSourceFromFlagFunc("load")) + + err := command.Run(c) + + expect(t, err, nil) +} + func TestCommandYamlFileTestDefaultValueFileWins(t *testing.T) { app := cli.NewApp() set := flag.NewFlagSet("test", 0) @@ -123,9 +194,10 @@ func TestCommandYamlFileTestDefaultValueFileWins(t *testing.T) { Aliases: []string{"tc"}, Usage: "this is for testing", Description: "testing", - Action: func(c *cli.Context) { + Action: func(c *cli.Context) error { val := c.Int("test") expect(t, val, 15) + return nil }, Flags: []cli.Flag{ NewIntFlag(cli.IntFlag{Name: "test", Value: 7}), @@ -138,6 +210,39 @@ func TestCommandYamlFileTestDefaultValueFileWins(t *testing.T) { expect(t, err, nil) } +func TestCommandYamlFileTestDefaultValueFileWinsNested(t *testing.T) { + app := cli.NewApp() + set := flag.NewFlagSet("test", 0) + ioutil.WriteFile("current.yaml", []byte(`top: + test: 15`), 0666) + defer os.Remove("current.yaml") + + test := []string{"test-cmd", "--load", "current.yaml"} + set.Parse(test) + + c := cli.NewContext(app, set, nil) + + command := &cli.Command{ + Name: "test-cmd", + Aliases: []string{"tc"}, + Usage: "this is for testing", + Description: "testing", + Action: func(c *cli.Context) error { + val := c.Int("top.test") + expect(t, val, 15) + return nil + }, + Flags: []cli.Flag{ + NewIntFlag(cli.IntFlag{Name: "top.test", Value: 7}), + cli.StringFlag{Name: "load"}}, + } + command.Before = InitInputSourceWithContext(command.Flags, NewYamlSourceFromFlagFunc("load")) + + err := command.Run(c) + + expect(t, err, nil) +} + func TestCommandYamlFileFlagHasDefaultGlobalEnvYamlSetGlobalEnvWins(t *testing.T) { app := cli.NewApp() set := flag.NewFlagSet("test", 0) @@ -157,9 +262,10 @@ func TestCommandYamlFileFlagHasDefaultGlobalEnvYamlSetGlobalEnvWins(t *testing.T Aliases: []string{"tc"}, Usage: "this is for testing", Description: "testing", - Action: func(c *cli.Context) { + Action: func(c *cli.Context) error { val := c.Int("test") expect(t, val, 11) + return nil }, Flags: []cli.Flag{ NewIntFlag(cli.IntFlag{Name: "test", Value: 7, EnvVar: "THE_TEST"}), @@ -170,3 +276,38 @@ func TestCommandYamlFileFlagHasDefaultGlobalEnvYamlSetGlobalEnvWins(t *testing.T expect(t, err, nil) } + +func TestCommandYamlFileFlagHasDefaultGlobalEnvYamlSetGlobalEnvWinsNested(t *testing.T) { + app := cli.NewApp() + set := flag.NewFlagSet("test", 0) + ioutil.WriteFile("current.yaml", []byte(`top: + test: 15`), 0666) + defer os.Remove("current.yaml") + + os.Setenv("THE_TEST", "11") + defer os.Setenv("THE_TEST", "") + + test := []string{"test-cmd", "--load", "current.yaml"} + set.Parse(test) + + c := cli.NewContext(app, set, nil) + + command := &cli.Command{ + Name: "test-cmd", + Aliases: []string{"tc"}, + Usage: "this is for testing", + Description: "testing", + Action: func(c *cli.Context) error { + val := c.Int("top.test") + expect(t, val, 11) + return nil + }, + Flags: []cli.Flag{ + NewIntFlag(cli.IntFlag{Name: "top.test", Value: 7, EnvVar: "THE_TEST"}), + cli.StringFlag{Name: "load"}}, + } + command.Before = InitInputSourceWithContext(command.Flags, NewYamlSourceFromFlagFunc("load")) + err := command.Run(c) + + expect(t, err, nil) +} diff --git a/vendor/github.com/codegangsta/cli/altsrc/yaml_file_loader.go b/vendor/github.com/codegangsta/cli/altsrc/yaml_file_loader.go index 4fb096527..b4e336563 100644 --- a/vendor/github.com/codegangsta/cli/altsrc/yaml_file_loader.go +++ b/vendor/github.com/codegangsta/cli/altsrc/yaml_file_loader.go @@ -12,7 +12,7 @@ import ( "net/url" "os" - "github.com/codegangsta/cli" + "github.com/urfave/cli" "gopkg.in/yaml.v2" ) @@ -24,7 +24,7 @@ type yamlSourceContext struct { // NewYamlSourceFromFile creates a new Yaml InputSourceContext from a filepath. func NewYamlSourceFromFile(file string) (InputSourceContext, error) { ysc := &yamlSourceContext{FilePath: file} - var results map[string]interface{} + var results map[interface{}]interface{} err := readCommandYaml(ysc.FilePath, &results) if err != nil { return nil, fmt.Errorf("Unable to load Yaml file '%s': inner error: \n'%v'", ysc.FilePath, err.Error()) diff --git a/vendor/github.com/codegangsta/cli/app.go b/vendor/github.com/codegangsta/cli/app.go index bd20a2d34..a046c0128 100644 --- a/vendor/github.com/codegangsta/cli/app.go +++ b/vendor/github.com/codegangsta/cli/app.go @@ -6,10 +6,27 @@ import ( "io/ioutil" "os" "path/filepath" + "reflect" "sort" + "strings" "time" ) +var ( + changeLogURL = "https://github.com/urfave/cli/blob/master/CHANGELOG.md" + appActionDeprecationURL = fmt.Sprintf("%s#deprecated-cli-app-action-signature", changeLogURL) + runAndExitOnErrorDeprecationURL = fmt.Sprintf("%s#deprecated-cli-app-runandexitonerror", changeLogURL) + + contactSysadmin = "This is an error in the application. Please contact the distributor of this application if this is not you." + + errNonFuncAction = NewExitError("ERROR invalid Action type. "+ + fmt.Sprintf("Must be a func of type `cli.ActionFunc`. %s", contactSysadmin)+ + fmt.Sprintf("See %s", appActionDeprecationURL), 2) + errInvalidActionSignature = NewExitError("ERROR invalid Action signature. "+ + fmt.Sprintf("Must be `cli.ActionFunc`. %s", contactSysadmin)+ + fmt.Sprintf("See %s", appActionDeprecationURL), 2) +) + // App is the main structure of a cli application. It is recommended that // an app be created with the cli.NewApp() function type App struct { @@ -35,24 +52,25 @@ type App struct { HideHelp bool // Boolean to hide built-in version flag and the VERSION section of help HideVersion bool - // Populate on app startup, only gettable throught method Categories() + // Populate on app startup, only gettable through method Categories() categories CommandCategories // An action to execute when the bash-completion flag is set - BashComplete func(context *Context) + BashComplete BashCompleteFunc // An action to execute before any subcommands are run, but after the context is ready // If a non-nil error is returned, no subcommands are run - Before func(context *Context) error + Before BeforeFunc // An action to execute after any subcommands are run, but after the subcommand has finished // It is run even if Action() panics - After func(context *Context) error + After AfterFunc // The action to execute when no subcommands are specified - Action func(context *Context) + Action interface{} + // TODO: replace `Action: interface{}` with `Action: ActionFunc` once some kind + // of deprecation period has passed, maybe? + // Execute this function if the proper command cannot be found - CommandNotFound func(context *Context, command string) - // Execute this function, if an usage error occurs. This is useful for displaying customized usage error messages. - // This function is able to replace the original error messages. - // If this function is not set, the "Incorrect usage" is displayed and the execution is interrupted. - OnUsageError func(context *Context, err error, isSubcommand bool) error + CommandNotFound CommandNotFoundFunc + // Execute this function if an usage error occurs + OnUsageError OnUsageErrorFunc // Compilation date Compiled time.Time // List of all authors who contributed @@ -65,6 +83,12 @@ type App struct { Email string // Writer writer to write output to Writer io.Writer + // ErrWriter writes error output + ErrWriter io.Writer + // Other custom info + Metadata map[string]interface{} + + didSetup bool } // Tries to find out when this binary was compiled. @@ -77,7 +101,8 @@ func compileTime() time.Time { return info.ModTime() } -// Creates a new cli Application with some reasonable defaults for Name, Usage, Version and Action. +// NewApp creates a new cli Application with some reasonable defaults for Name, +// Usage, Version and Action. func NewApp() *App { return &App{ Name: filepath.Base(os.Args[0]), @@ -92,8 +117,16 @@ func NewApp() *App { } } -// Entry point to the cli app. Parses the arguments slice and routes to the proper flag/args combination -func (a *App) Run(arguments []string) (err error) { +// Setup runs initialization code to ensure all data structures are ready for +// `Run` or inspection prior to `Run`. It is internally called by `Run`, but +// will return early if setup has already happened. +func (a *App) Setup() { + if a.didSetup { + return + } + + a.didSetup = true + if a.Author != "" || a.Email != "" { a.Authors = append(a.Authors, Author{Name: a.Author, Email: a.Email}) } @@ -107,13 +140,6 @@ func (a *App) Run(arguments []string) (err error) { } a.Commands = newCmds - a.categories = CommandCategories{} - for _, command := range a.Commands { - a.categories = a.categories.AddCommand(command.Category, command) - } - sort.Sort(a.categories) - - // append help to commands if a.Command(helpCommand.Name) == nil && !a.HideHelp { a.Commands = append(a.Commands, helpCommand) if (HelpFlag != BoolFlag{}) { @@ -121,7 +147,6 @@ func (a *App) Run(arguments []string) (err error) { } } - //append version/help flags if a.EnableBashCompletion { a.appendFlag(BashCompletionFlag) } @@ -130,6 +155,18 @@ func (a *App) Run(arguments []string) (err error) { a.appendFlag(VersionFlag) } + a.categories = CommandCategories{} + for _, command := range a.Commands { + a.categories = a.categories.AddCommand(command.Category, command) + } + sort.Sort(a.categories) +} + +// Run is the entry point to the cli app. Parses the arguments slice and routes +// to the proper flag/args combination +func (a *App) Run(arguments []string) (err error) { + a.Setup() + // parse flags set := flagSet(a.Name, a.Flags) set.SetOutput(ioutil.Discard) @@ -149,12 +186,12 @@ func (a *App) Run(arguments []string) (err error) { if err != nil { if a.OnUsageError != nil { err := a.OnUsageError(context, err, false) - return err - } else { - fmt.Fprintf(a.Writer, "%s\n\n", "Incorrect Usage.") - ShowAppHelp(context) + HandleExitCoder(err) return err } + fmt.Fprintf(a.Writer, "%s\n\n", "Incorrect Usage.") + ShowAppHelp(context) + return err } if !a.HideHelp && checkHelp(context) { @@ -180,10 +217,12 @@ func (a *App) Run(arguments []string) (err error) { } if a.Before != nil { - err = a.Before(context) - if err != nil { - fmt.Fprintf(a.Writer, "%v\n\n", err) + beforeErr := a.Before(context) + if beforeErr != nil { + fmt.Fprintf(a.Writer, "%v\n\n", beforeErr) ShowAppHelp(context) + HandleExitCoder(beforeErr) + err = beforeErr return err } } @@ -198,19 +237,25 @@ func (a *App) Run(arguments []string) (err error) { } // Run default Action - a.Action(context) - return nil + err = HandleAction(a.Action, context) + + HandleExitCoder(err) + return err } -// Another entry point to the cli app, takes care of passing arguments and error handling +// DEPRECATED: Another entry point to the cli app, takes care of passing arguments and error handling func (a *App) RunAndExitOnError() { + fmt.Fprintf(a.errWriter(), + "DEPRECATED cli.App.RunAndExitOnError. %s See %s\n", + contactSysadmin, runAndExitOnErrorDeprecationURL) if err := a.Run(os.Args); err != nil { - fmt.Fprintln(os.Stderr, err) - os.Exit(1) + fmt.Fprintln(a.errWriter(), err) + OsExiter(1) } } -// Invokes the subcommand given the context, parses ctx.Args() to generate command-specific flags +// RunAsSubcommand invokes the subcommand given the context, parses ctx.Args() to +// generate command-specific flags func (a *App) RunAsSubcommand(ctx *Context) (err error) { // append help to commands if len(a.Commands) > 0 { @@ -261,12 +306,12 @@ func (a *App) RunAsSubcommand(ctx *Context) (err error) { if err != nil { if a.OnUsageError != nil { err = a.OnUsageError(context, err, true) - return err - } else { - fmt.Fprintf(a.Writer, "%s\n\n", "Incorrect Usage.") - ShowSubcommandHelp(context) + HandleExitCoder(err) return err } + fmt.Fprintf(a.Writer, "%s\n\n", "Incorrect Usage.") + ShowSubcommandHelp(context) + return err } if len(a.Commands) > 0 { @@ -283,6 +328,7 @@ func (a *App) RunAsSubcommand(ctx *Context) (err error) { defer func() { afterErr := a.After(context) if afterErr != nil { + HandleExitCoder(err) if err != nil { err = NewMultiError(err, afterErr) } else { @@ -293,8 +339,10 @@ func (a *App) RunAsSubcommand(ctx *Context) (err error) { } if a.Before != nil { - err := a.Before(context) - if err != nil { + beforeErr := a.Before(context) + if beforeErr != nil { + HandleExitCoder(beforeErr) + err = beforeErr return err } } @@ -309,12 +357,13 @@ func (a *App) RunAsSubcommand(ctx *Context) (err error) { } // Run default Action - a.Action(context) + err = HandleAction(a.Action, context) - return nil + HandleExitCoder(err) + return err } -// Returns the named command on App. Returns nil if the command does not exist +// Command returns the named command on App. Returns nil if the command does not exist func (a *App) Command(name string) *Command { for _, c := range a.Commands { if c.HasName(name) { @@ -325,11 +374,46 @@ func (a *App) Command(name string) *Command { return nil } -// Returnes the array containing all the categories with the commands they contain +// Categories returns a slice containing all the categories with the commands they contain func (a *App) Categories() CommandCategories { return a.categories } +// VisibleCategories returns a slice of categories and commands that are +// Hidden=false +func (a *App) VisibleCategories() []*CommandCategory { + ret := []*CommandCategory{} + for _, category := range a.categories { + if visible := func() *CommandCategory { + for _, command := range category.Commands { + if !command.Hidden { + return category + } + } + return nil + }(); visible != nil { + ret = append(ret, visible) + } + } + return ret +} + +// VisibleCommands returns a slice of the Commands with Hidden=false +func (a *App) VisibleCommands() []Command { + ret := []Command{} + for _, command := range a.Commands { + if !command.Hidden { + ret = append(ret, command) + } + } + return ret +} + +// VisibleFlags returns a slice of the Flags with Hidden=false +func (a *App) VisibleFlags() []Flag { + return visibleFlags(a.Flags) +} + func (a *App) hasFlag(flag Flag) bool { for _, f := range a.Flags { if flag == f { @@ -340,6 +424,16 @@ func (a *App) hasFlag(flag Flag) bool { return false } +func (a *App) errWriter() io.Writer { + + // When the app ErrWriter is nil use the package level one. + if a.ErrWriter == nil { + return ErrWriter + } + + return a.ErrWriter +} + func (a *App) appendFlag(flag Flag) { if !a.hasFlag(flag) { a.Flags = append(a.Flags, flag) @@ -361,3 +455,45 @@ func (a Author) String() string { return fmt.Sprintf("%v %v", a.Name, e) } + +// HandleAction uses ✧✧✧reflection✧✧✧ to figure out if the given Action is an +// ActionFunc, a func with the legacy signature for Action, or some other +// invalid thing. If it's an ActionFunc or a func with the legacy signature for +// Action, the func is run! +func HandleAction(action interface{}, context *Context) (err error) { + defer func() { + if r := recover(); r != nil { + // Try to detect a known reflection error from *this scope*, rather than + // swallowing all panics that may happen when calling an Action func. + s := fmt.Sprintf("%v", r) + if strings.HasPrefix(s, "reflect: ") && strings.Contains(s, "too many input arguments") { + err = NewExitError(fmt.Sprintf("ERROR unknown Action error: %v. See %s", r, appActionDeprecationURL), 2) + } else { + panic(r) + } + } + }() + + if reflect.TypeOf(action).Kind() != reflect.Func { + return errNonFuncAction + } + + vals := reflect.ValueOf(action).Call([]reflect.Value{reflect.ValueOf(context)}) + + if len(vals) == 0 { + fmt.Fprintf(ErrWriter, + "DEPRECATED Action signature. Must be `cli.ActionFunc`. %s See %s\n", + contactSysadmin, appActionDeprecationURL) + return nil + } + + if len(vals) > 1 { + return errInvalidActionSignature + } + + if retErr, ok := vals[0].Interface().(error); vals[0].IsValid() && ok { + return retErr + } + + return err +} diff --git a/vendor/github.com/codegangsta/cli/app_test.go b/vendor/github.com/codegangsta/cli/app_test.go index ebf26c70f..9c6b9605f 100644 --- a/vendor/github.com/codegangsta/cli/app_test.go +++ b/vendor/github.com/codegangsta/cli/app_test.go @@ -13,6 +13,10 @@ import ( "testing" ) +type opCounts struct { + Total, BashComplete, OnUsageError, Before, CommandNotFound, Action, After, SubCommand int +} + func ExampleApp_Run() { // set args for examples sake os.Args = []string{"greet", "--name", "Jeremy"} @@ -22,13 +26,14 @@ func ExampleApp_Run() { app.Flags = []Flag{ StringFlag{Name: "name", Value: "bob", Usage: "a name to say"}, } - app.Action = func(c *Context) { + app.Action = func(c *Context) error { fmt.Printf("Hello %v\n", c.String("name")) + return nil } app.UsageText = "app [first_arg] [second_arg]" app.Author = "Harrison" app.Email = "harrison@lolwut.com" - app.Authors = []Author{Author{Name: "Oliver Allen", Email: "oliver@toyshop.com"}} + app.Authors = []Author{{Name: "Oliver Allen", Email: "oliver@toyshop.com"}} app.Run(os.Args) // Output: // Hello Jeremy @@ -58,8 +63,9 @@ func ExampleApp_Run_subcommand() { Usage: "Name of the person to greet", }, }, - Action: func(c *Context) { + Action: func(c *Context) error { fmt.Println("Hello,", c.String("name")) + return nil }, }, }, @@ -86,8 +92,9 @@ func ExampleApp_Run_help() { Aliases: []string{"d"}, Usage: "use it to see a description", Description: "This is how we describe describeit the function", - Action: func(c *Context) { + Action: func(c *Context) error { fmt.Printf("i like to describe things") + return nil }, }, } @@ -116,15 +123,17 @@ func ExampleApp_Run_bashComplete() { Aliases: []string{"d"}, Usage: "use it to see a description", Description: "This is how we describe describeit the function", - Action: func(c *Context) { + Action: func(c *Context) error { fmt.Printf("i like to describe things") + return nil }, }, { Name: "next", Usage: "next example", Description: "more stuff to see when generating bash completion", - Action: func(c *Context) { + Action: func(c *Context) error { fmt.Printf("the next example") + return nil }, }, } @@ -142,8 +151,9 @@ func TestApp_Run(t *testing.T) { s := "" app := NewApp() - app.Action = func(c *Context) { + app.Action = func(c *Context) error { s = s + c.Args().First() + return nil } err := app.Run([]string{"command", "foo"}) @@ -188,9 +198,10 @@ func TestApp_CommandWithArgBeforeFlags(t *testing.T) { Flags: []Flag{ StringFlag{Name: "option", Value: "", Usage: "some option"}, }, - Action: func(c *Context) { + Action: func(c *Context) error { parsedOption = c.String("option") firstArg = c.Args().First() + return nil }, } app.Commands = []Command{command} @@ -208,8 +219,9 @@ func TestApp_RunAsSubcommandParseFlags(t *testing.T) { a.Commands = []Command{ { Name: "foo", - Action: func(c *Context) { + Action: func(c *Context) error { context = c + return nil }, Flags: []Flag{ StringFlag{ @@ -237,9 +249,10 @@ func TestApp_CommandWithFlagBeforeTerminator(t *testing.T) { Flags: []Flag{ StringFlag{Name: "option", Value: "", Usage: "some option"}, }, - Action: func(c *Context) { + Action: func(c *Context) error { parsedOption = c.String("option") args = c.Args() + return nil }, } app.Commands = []Command{command} @@ -258,8 +271,9 @@ func TestApp_CommandWithDash(t *testing.T) { app := NewApp() command := Command{ Name: "cmd", - Action: func(c *Context) { + Action: func(c *Context) error { args = c.Args() + return nil }, } app.Commands = []Command{command} @@ -276,8 +290,9 @@ func TestApp_CommandWithNoFlagBeforeTerminator(t *testing.T) { app := NewApp() command := Command{ Name: "cmd", - Action: func(c *Context) { + Action: func(c *Context) error { args = c.Args() + return nil }, } app.Commands = []Command{command} @@ -289,6 +304,48 @@ func TestApp_CommandWithNoFlagBeforeTerminator(t *testing.T) { expect(t, args[2], "notAFlagAtAll") } +func TestApp_VisibleCommands(t *testing.T) { + app := NewApp() + app.Commands = []Command{ + { + Name: "frob", + HelpName: "foo frob", + Action: func(_ *Context) error { return nil }, + }, + { + Name: "frib", + HelpName: "foo frib", + Hidden: true, + Action: func(_ *Context) error { return nil }, + }, + } + + app.Setup() + expected := []Command{ + app.Commands[0], + app.Commands[2], // help + } + actual := app.VisibleCommands() + expect(t, len(expected), len(actual)) + for i, actualCommand := range actual { + expectedCommand := expected[i] + + if expectedCommand.Action != nil { + // comparing func addresses is OK! + expect(t, fmt.Sprintf("%p", expectedCommand.Action), fmt.Sprintf("%p", actualCommand.Action)) + } + + // nil out funcs, as they cannot be compared + // (https://github.com/golang/go/issues/8554) + expectedCommand.Action = nil + actualCommand.Action = nil + + if !reflect.DeepEqual(expectedCommand, actualCommand) { + t.Errorf("expected\n%#v\n!=\n%#v", expectedCommand, actualCommand) + } + } +} + func TestApp_Float64Flag(t *testing.T) { var meters float64 @@ -296,8 +353,9 @@ func TestApp_Float64Flag(t *testing.T) { app.Flags = []Flag{ Float64Flag{Name: "height", Value: 1.5, Usage: "Set the height, in meters"}, } - app.Action = func(c *Context) { + app.Action = func(c *Context) error { meters = c.Float64("height") + return nil } app.Run([]string{"", "--height", "1.93"}) @@ -316,11 +374,12 @@ func TestApp_ParseSliceFlags(t *testing.T) { IntSliceFlag{Name: "p", Value: &IntSlice{}, Usage: "set one or more ip addr"}, StringSliceFlag{Name: "ip", Value: &StringSlice{}, Usage: "set one or more ports to open"}, }, - Action: func(c *Context) { + Action: func(c *Context) error { parsedIntSlice = c.IntSlice("p") parsedStringSlice = c.StringSlice("ip") parsedOption = c.String("option") firstArg = c.Args().First() + return nil }, } app.Commands = []Command{command} @@ -373,9 +432,10 @@ func TestApp_ParseSliceFlagsWithMissingValue(t *testing.T) { IntSliceFlag{Name: "a", Usage: "set numbers"}, StringSliceFlag{Name: "str", Usage: "set strings"}, }, - Action: func(c *Context) { + Action: func(c *Context) error { parsedIntSlice = c.IntSlice("a") parsedStringSlice = c.StringSlice("str") + return nil }, } app.Commands = []Command{command} @@ -439,14 +499,15 @@ func TestApp_SetStdout(t *testing.T) { } func TestApp_BeforeFunc(t *testing.T) { - beforeRun, subcommandRun := false, false + counts := &opCounts{} beforeError := fmt.Errorf("fail") var err error app := NewApp() app.Before = func(c *Context) error { - beforeRun = true + counts.Total++ + counts.Before = counts.Total s := c.String("opt") if s == "fail" { return beforeError @@ -456,10 +517,12 @@ func TestApp_BeforeFunc(t *testing.T) { } app.Commands = []Command{ - Command{ + { Name: "sub", - Action: func(c *Context) { - subcommandRun = true + Action: func(c *Context) error { + counts.Total++ + counts.SubCommand = counts.Total + return nil }, }, } @@ -475,16 +538,16 @@ func TestApp_BeforeFunc(t *testing.T) { t.Fatalf("Run error: %s", err) } - if beforeRun == false { + if counts.Before != 1 { t.Errorf("Before() not executed when expected") } - if subcommandRun == false { + if counts.SubCommand != 2 { t.Errorf("Subcommand not executed when expected") } // reset - beforeRun, subcommandRun = false, false + counts = &opCounts{} // run with the Before() func failing err = app.Run([]string{"command", "--opt", "fail", "sub"}) @@ -494,25 +557,49 @@ func TestApp_BeforeFunc(t *testing.T) { t.Errorf("Run error expected, but not received") } - if beforeRun == false { + if counts.Before != 1 { t.Errorf("Before() not executed when expected") } - if subcommandRun == true { + if counts.SubCommand != 0 { t.Errorf("Subcommand executed when NOT expected") } + // reset + counts = &opCounts{} + + afterError := errors.New("fail again") + app.After = func(_ *Context) error { + return afterError + } + + // run with the Before() func failing, wrapped by After() + err = app.Run([]string{"command", "--opt", "fail", "sub"}) + + // should be the same error produced by the Before func + if _, ok := err.(MultiError); !ok { + t.Errorf("MultiError expected, but not received") + } + + if counts.Before != 1 { + t.Errorf("Before() not executed when expected") + } + + if counts.SubCommand != 0 { + t.Errorf("Subcommand executed when NOT expected") + } } func TestApp_AfterFunc(t *testing.T) { - afterRun, subcommandRun := false, false + counts := &opCounts{} afterError := fmt.Errorf("fail") var err error app := NewApp() app.After = func(c *Context) error { - afterRun = true + counts.Total++ + counts.After = counts.Total s := c.String("opt") if s == "fail" { return afterError @@ -522,10 +609,12 @@ func TestApp_AfterFunc(t *testing.T) { } app.Commands = []Command{ - Command{ + { Name: "sub", - Action: func(c *Context) { - subcommandRun = true + Action: func(c *Context) error { + counts.Total++ + counts.SubCommand = counts.Total + return nil }, }, } @@ -541,16 +630,16 @@ func TestApp_AfterFunc(t *testing.T) { t.Fatalf("Run error: %s", err) } - if afterRun == false { + if counts.After != 2 { t.Errorf("After() not executed when expected") } - if subcommandRun == false { + if counts.SubCommand != 1 { t.Errorf("Subcommand not executed when expected") } // reset - afterRun, subcommandRun = false, false + counts = &opCounts{} // run with the Before() func failing err = app.Run([]string{"command", "--opt", "fail", "sub"}) @@ -560,11 +649,11 @@ func TestApp_AfterFunc(t *testing.T) { t.Errorf("Run error expected, but not received") } - if afterRun == false { + if counts.After != 2 { t.Errorf("After() not executed when expected") } - if subcommandRun == false { + if counts.SubCommand != 1 { t.Errorf("Subcommand not executed when expected") } } @@ -605,7 +694,7 @@ func TestAppHelpPrinter(t *testing.T) { } } -func TestAppVersionPrinter(t *testing.T) { +func TestApp_VersionPrinter(t *testing.T) { oldPrinter := VersionPrinter defer func() { VersionPrinter = oldPrinter @@ -625,81 +714,172 @@ func TestAppVersionPrinter(t *testing.T) { } } -func TestAppCommandNotFound(t *testing.T) { - beforeRun, subcommandRun := false, false +func TestApp_CommandNotFound(t *testing.T) { + counts := &opCounts{} app := NewApp() app.CommandNotFound = func(c *Context, command string) { - beforeRun = true + counts.Total++ + counts.CommandNotFound = counts.Total } app.Commands = []Command{ - Command{ + { Name: "bar", - Action: func(c *Context) { - subcommandRun = true + Action: func(c *Context) error { + counts.Total++ + counts.SubCommand = counts.Total + return nil }, }, } app.Run([]string{"command", "foo"}) - expect(t, beforeRun, true) - expect(t, subcommandRun, false) + expect(t, counts.CommandNotFound, 1) + expect(t, counts.SubCommand, 0) + expect(t, counts.Total, 1) } -func TestGlobalFlag(t *testing.T) { - var globalFlag string - var globalFlagSet bool +func TestApp_OrderOfOperations(t *testing.T) { + counts := &opCounts{} + + resetCounts := func() { counts = &opCounts{} } + app := NewApp() - app.Flags = []Flag{ - StringFlag{Name: "global, g", Usage: "global"}, + app.EnableBashCompletion = true + app.BashComplete = func(c *Context) { + counts.Total++ + counts.BashComplete = counts.Total } - app.Action = func(c *Context) { - globalFlag = c.GlobalString("global") - globalFlagSet = c.GlobalIsSet("global") + + app.OnUsageError = func(c *Context, err error, isSubcommand bool) error { + counts.Total++ + counts.OnUsageError = counts.Total + return errors.New("hay OnUsageError") } - app.Run([]string{"command", "-g", "foo"}) - expect(t, globalFlag, "foo") - expect(t, globalFlagSet, true) -} + beforeNoError := func(c *Context) error { + counts.Total++ + counts.Before = counts.Total + return nil + } -func TestGlobalFlagsInSubcommands(t *testing.T) { - subcommandRun := false - parentFlag := false - app := NewApp() + beforeError := func(c *Context) error { + counts.Total++ + counts.Before = counts.Total + return errors.New("hay Before") + } - app.Flags = []Flag{ - BoolFlag{Name: "debug, d", Usage: "Enable debugging"}, + app.Before = beforeNoError + app.CommandNotFound = func(c *Context, command string) { + counts.Total++ + counts.CommandNotFound = counts.Total } + afterNoError := func(c *Context) error { + counts.Total++ + counts.After = counts.Total + return nil + } + + afterError := func(c *Context) error { + counts.Total++ + counts.After = counts.Total + return errors.New("hay After") + } + + app.After = afterNoError app.Commands = []Command{ - Command{ - Name: "foo", - Flags: []Flag{ - BoolFlag{Name: "parent, p", Usage: "Parent flag"}, - }, - Subcommands: []Command{ - { - Name: "bar", - Action: func(c *Context) { - if c.GlobalBool("debug") { - subcommandRun = true - } - if c.GlobalBool("parent") { - parentFlag = true - } - }, - }, + { + Name: "bar", + Action: func(c *Context) error { + counts.Total++ + counts.SubCommand = counts.Total + return nil }, }, } - app.Run([]string{"command", "-d", "foo", "-p", "bar"}) + app.Action = func(c *Context) error { + counts.Total++ + counts.Action = counts.Total + return nil + } + + _ = app.Run([]string{"command", "--nope"}) + expect(t, counts.OnUsageError, 1) + expect(t, counts.Total, 1) + + resetCounts() + + _ = app.Run([]string{"command", "--generate-bash-completion"}) + expect(t, counts.BashComplete, 1) + expect(t, counts.Total, 1) + + resetCounts() + + oldOnUsageError := app.OnUsageError + app.OnUsageError = nil + _ = app.Run([]string{"command", "--nope"}) + expect(t, counts.Total, 0) + app.OnUsageError = oldOnUsageError + + resetCounts() + + _ = app.Run([]string{"command", "foo"}) + expect(t, counts.OnUsageError, 0) + expect(t, counts.Before, 1) + expect(t, counts.CommandNotFound, 0) + expect(t, counts.Action, 2) + expect(t, counts.After, 3) + expect(t, counts.Total, 3) + + resetCounts() + + app.Before = beforeError + _ = app.Run([]string{"command", "bar"}) + expect(t, counts.OnUsageError, 0) + expect(t, counts.Before, 1) + expect(t, counts.After, 2) + expect(t, counts.Total, 2) + app.Before = beforeNoError + + resetCounts() - expect(t, subcommandRun, true) - expect(t, parentFlag, true) + app.After = nil + _ = app.Run([]string{"command", "bar"}) + expect(t, counts.OnUsageError, 0) + expect(t, counts.Before, 1) + expect(t, counts.SubCommand, 2) + expect(t, counts.Total, 2) + app.After = afterNoError + + resetCounts() + + app.After = afterError + err := app.Run([]string{"command", "bar"}) + if err == nil { + t.Fatalf("expected a non-nil error") + } + expect(t, counts.OnUsageError, 0) + expect(t, counts.Before, 1) + expect(t, counts.SubCommand, 2) + expect(t, counts.After, 3) + expect(t, counts.Total, 3) + app.After = afterNoError + + resetCounts() + + oldCommands := app.Commands + app.Commands = nil + _ = app.Run([]string{"command"}) + expect(t, counts.OnUsageError, 0) + expect(t, counts.Before, 1) + expect(t, counts.Action, 2) + expect(t, counts.After, 3) + expect(t, counts.Total, 3) + app.Commands = oldCommands } func TestApp_Run_CommandWithSubcommandHasHelpTopic(t *testing.T) { @@ -891,8 +1071,9 @@ func TestApp_Run_Help(t *testing.T) { app.Name = "boom" app.Usage = "make an explosive entrance" app.Writer = buf - app.Action = func(c *Context) { + app.Action = func(c *Context) error { buf.WriteString("boom I say!") + return nil } err := app.Run(args) @@ -922,8 +1103,9 @@ func TestApp_Run_Version(t *testing.T) { app.Usage = "make an explosive entrance" app.Version = "0.1.0" app.Writer = buf - app.Action = func(c *Context) { + app.Action = func(c *Context) error { buf.WriteString("boom I say!") + return nil } err := app.Run(args) @@ -943,16 +1125,17 @@ func TestApp_Run_Version(t *testing.T) { func TestApp_Run_Categories(t *testing.T) { app := NewApp() app.Name = "categories" + app.HideHelp = true app.Commands = []Command{ - Command{ + { Name: "command1", Category: "1", }, - Command{ + { Name: "command2", Category: "1", }, - Command{ + { Name: "command3", Category: "2", }, @@ -984,14 +1167,120 @@ func TestApp_Run_Categories(t *testing.T) { output := buf.String() t.Logf("output: %q\n", buf.Bytes()) - if !strings.Contains(output, "1:\n command1") { - t.Errorf("want buffer to include category %q, did not: \n%q", "1:\n command1", output) + if !strings.Contains(output, "1:\n command1") { + t.Errorf("want buffer to include category %q, did not: \n%q", "1:\n command1", output) } } +func TestApp_VisibleCategories(t *testing.T) { + app := NewApp() + app.Name = "visible-categories" + app.HideHelp = true + app.Commands = []Command{ + { + Name: "command1", + Category: "1", + HelpName: "foo command1", + Hidden: true, + }, + { + Name: "command2", + Category: "2", + HelpName: "foo command2", + }, + { + Name: "command3", + Category: "3", + HelpName: "foo command3", + }, + } + + expected := []*CommandCategory{ + { + Name: "2", + Commands: []Command{ + app.Commands[1], + }, + }, + { + Name: "3", + Commands: []Command{ + app.Commands[2], + }, + }, + } + + app.Setup() + expect(t, expected, app.VisibleCategories()) + + app = NewApp() + app.Name = "visible-categories" + app.HideHelp = true + app.Commands = []Command{ + { + Name: "command1", + Category: "1", + HelpName: "foo command1", + Hidden: true, + }, + { + Name: "command2", + Category: "2", + HelpName: "foo command2", + Hidden: true, + }, + { + Name: "command3", + Category: "3", + HelpName: "foo command3", + }, + } + + expected = []*CommandCategory{ + { + Name: "3", + Commands: []Command{ + app.Commands[2], + }, + }, + } + + app.Setup() + expect(t, expected, app.VisibleCategories()) + + app = NewApp() + app.Name = "visible-categories" + app.HideHelp = true + app.Commands = []Command{ + { + Name: "command1", + Category: "1", + HelpName: "foo command1", + Hidden: true, + }, + { + Name: "command2", + Category: "2", + HelpName: "foo command2", + Hidden: true, + }, + { + Name: "command3", + Category: "3", + HelpName: "foo command3", + Hidden: true, + }, + } + + expected = []*CommandCategory{} + + app.Setup() + expect(t, expected, app.VisibleCategories()) +} + func TestApp_Run_DoesNotOverwriteErrorFromBefore(t *testing.T) { app := NewApp() - app.Action = func(c *Context) {} + app.Action = func(c *Context) error { return nil } app.Before = func(c *Context) error { return fmt.Errorf("before error") } app.After = func(c *Context) error { return fmt.Errorf("after error") } @@ -1011,9 +1300,9 @@ func TestApp_Run_DoesNotOverwriteErrorFromBefore(t *testing.T) { func TestApp_Run_SubcommandDoesNotOverwriteErrorFromBefore(t *testing.T) { app := NewApp() app.Commands = []Command{ - Command{ + { Subcommands: []Command{ - Command{ + { Name: "sub", }, }, @@ -1051,7 +1340,7 @@ func TestApp_OnUsageError_WithWrongFlagValue(t *testing.T) { return errors.New("intercepted: " + err.Error()) } app.Commands = []Command{ - Command{ + { Name: "bar", }, } @@ -1081,7 +1370,7 @@ func TestApp_OnUsageError_WithWrongFlagValue_ForSubcommand(t *testing.T) { return errors.New("intercepted: " + err.Error()) } app.Commands = []Command{ - Command{ + { Name: "bar", }, } @@ -1095,3 +1384,88 @@ func TestApp_OnUsageError_WithWrongFlagValue_ForSubcommand(t *testing.T) { t.Errorf("Expect an intercepted error, but got \"%v\"", err) } } + +func TestHandleAction_WithNonFuncAction(t *testing.T) { + app := NewApp() + app.Action = 42 + err := HandleAction(app.Action, NewContext(app, flagSet(app.Name, app.Flags), nil)) + + if err == nil { + t.Fatalf("expected to receive error from Run, got none") + } + + exitErr, ok := err.(*ExitError) + + if !ok { + t.Fatalf("expected to receive a *ExitError") + } + + if !strings.HasPrefix(exitErr.Error(), "ERROR invalid Action type") { + t.Fatalf("expected an unknown Action error, but got: %v", exitErr.Error()) + } + + if exitErr.ExitCode() != 2 { + t.Fatalf("expected error exit code to be 2, but got: %v", exitErr.ExitCode()) + } +} + +func TestHandleAction_WithInvalidFuncSignature(t *testing.T) { + app := NewApp() + app.Action = func() string { return "" } + err := HandleAction(app.Action, NewContext(app, flagSet(app.Name, app.Flags), nil)) + + if err == nil { + t.Fatalf("expected to receive error from Run, got none") + } + + exitErr, ok := err.(*ExitError) + + if !ok { + t.Fatalf("expected to receive a *ExitError") + } + + if !strings.HasPrefix(exitErr.Error(), "ERROR unknown Action error") { + t.Fatalf("expected an unknown Action error, but got: %v", exitErr.Error()) + } + + if exitErr.ExitCode() != 2 { + t.Fatalf("expected error exit code to be 2, but got: %v", exitErr.ExitCode()) + } +} + +func TestHandleAction_WithInvalidFuncReturnSignature(t *testing.T) { + app := NewApp() + app.Action = func(_ *Context) (int, error) { return 0, nil } + err := HandleAction(app.Action, NewContext(app, flagSet(app.Name, app.Flags), nil)) + + if err == nil { + t.Fatalf("expected to receive error from Run, got none") + } + + exitErr, ok := err.(*ExitError) + + if !ok { + t.Fatalf("expected to receive a *ExitError") + } + + if !strings.HasPrefix(exitErr.Error(), "ERROR invalid Action signature") { + t.Fatalf("expected an invalid Action signature error, but got: %v", exitErr.Error()) + } + + if exitErr.ExitCode() != 2 { + t.Fatalf("expected error exit code to be 2, but got: %v", exitErr.ExitCode()) + } +} + +func TestHandleAction_WithUnknownPanic(t *testing.T) { + defer func() { refute(t, recover(), nil) }() + + var fn ActionFunc + + app := NewApp() + app.Action = func(ctx *Context) error { + fn(ctx) + return nil + } + HandleAction(app.Action, NewContext(app, flagSet(app.Name, app.Flags), nil)) +} diff --git a/vendor/github.com/codegangsta/cli/appveyor.yml b/vendor/github.com/codegangsta/cli/appveyor.yml index 3ca7afabd..173086e5f 100644 --- a/vendor/github.com/codegangsta/cli/appveyor.yml +++ b/vendor/github.com/codegangsta/cli/appveyor.yml @@ -2,15 +2,24 @@ version: "{build}" os: Windows Server 2012 R2 -install: - - go version - - go env +clone_folder: c:\gopath\src\github.com\urfave\cli -build_script: - - cd %APPVEYOR_BUILD_FOLDER% - - go vet ./... - - go test -v ./... +environment: + GOPATH: C:\gopath + GOVERSION: 1.6 + PYTHON: C:\Python27-x64 + PYTHON_VERSION: 2.7.x + PYTHON_ARCH: 64 + GFMXR_DEBUG: 1 -test: off +install: +- set PATH=%GOPATH%\bin;C:\go\bin;%PATH% +- go version +- go env +- go get github.com/urfave/gfmxr/... +- go get -v -t ./... -deploy: off +build_script: +- python runtests vet +- python runtests test +- python runtests gfmxr diff --git a/vendor/github.com/codegangsta/cli/category.go b/vendor/github.com/codegangsta/cli/category.go index 7dbf2182f..1a6055023 100644 --- a/vendor/github.com/codegangsta/cli/category.go +++ b/vendor/github.com/codegangsta/cli/category.go @@ -1,7 +1,9 @@ package cli +// CommandCategories is a slice of *CommandCategory. type CommandCategories []*CommandCategory +// CommandCategory is a category containing commands. type CommandCategory struct { Name string Commands Commands @@ -19,6 +21,7 @@ func (c CommandCategories) Swap(i, j int) { c[i], c[j] = c[j], c[i] } +// AddCommand adds a command to a category. func (c CommandCategories) AddCommand(category string, command Command) CommandCategories { for _, commandCategory := range c { if commandCategory.Name == category { @@ -28,3 +31,14 @@ func (c CommandCategories) AddCommand(category string, command Command) CommandC } return append(c, &CommandCategory{Name: category, Commands: []Command{command}}) } + +// VisibleCommands returns a slice of the Commands with Hidden=false +func (c *CommandCategory) VisibleCommands() []Command { + ret := []Command{} + for _, command := range c.Commands { + if !command.Hidden { + ret = append(ret, command) + } + } + return ret +} diff --git a/vendor/github.com/codegangsta/cli/cli.go b/vendor/github.com/codegangsta/cli/cli.go index 31dc9124d..f0440c563 100644 --- a/vendor/github.com/codegangsta/cli/cli.go +++ b/vendor/github.com/codegangsta/cli/cli.go @@ -10,31 +10,10 @@ // app := cli.NewApp() // app.Name = "greet" // app.Usage = "say a greeting" -// app.Action = func(c *cli.Context) { +// app.Action = func(c *cli.Context) error { // println("Greetings") // } // // app.Run(os.Args) // } package cli - -import ( - "strings" -) - -type MultiError struct { - Errors []error -} - -func NewMultiError(err ...error) MultiError { - return MultiError{Errors: err} -} - -func (m MultiError) Error() string { - errs := make([]string, len(m.Errors)) - for i, err := range m.Errors { - errs[i] = err.Error() - } - - return strings.Join(errs, "\n") -} diff --git a/vendor/github.com/codegangsta/cli/command.go b/vendor/github.com/codegangsta/cli/command.go index 1a05b5497..8950ccae4 100644 --- a/vendor/github.com/codegangsta/cli/command.go +++ b/vendor/github.com/codegangsta/cli/command.go @@ -26,19 +26,20 @@ type Command struct { // The category the command is part of Category string // The function to call when checking for bash command completions - BashComplete func(context *Context) + BashComplete BashCompleteFunc // An action to execute before any sub-subcommands are run, but after the context is ready // If a non-nil error is returned, no sub-subcommands are run - Before func(context *Context) error - // An action to execute after any subcommands are run, but before the subcommand has finished + Before BeforeFunc + // An action to execute after any subcommands are run, but after the subcommand has finished // It is run even if Action() panics - After func(context *Context) error + After AfterFunc // The function to call when this command is invoked - Action func(context *Context) - // Execute this function, if an usage error occurs. This is useful for displaying customized usage error messages. - // This function is able to replace the original error messages. - // If this function is not set, the "Incorrect usage" is displayed and the execution is interrupted. - OnUsageError func(context *Context, err error) error + Action interface{} + // TODO: replace `Action: interface{}` with `Action: ActionFunc` once some kind + // of deprecation period has passed, maybe? + + // Execute this function if a usage error occurs. + OnUsageError OnUsageErrorFunc // List of child commands Subcommands Commands // List of flags to parse @@ -47,13 +48,15 @@ type Command struct { SkipFlagParsing bool // Boolean to hide built-in help command HideHelp bool + // Boolean to hide this command from help or completion + Hidden bool // Full name of command for help, defaults to full command name, including parent commands. HelpName string commandNamePath []string } -// Returns the full name of the command. +// FullName returns the full name of the command. // For subcommands this ensures that parent commands are part of the command path func (c Command) FullName() string { if c.commandNamePath == nil { @@ -62,9 +65,10 @@ func (c Command) FullName() string { return strings.Join(c.commandNamePath, " ") } +// Commands is a slice of Command type Commands []Command -// Invokes the command given the context, parses ctx.Args() to generate command-specific flags +// Run invokes the command given the context, parses ctx.Args() to generate command-specific flags func (c Command) Run(ctx *Context) (err error) { if len(c.Subcommands) > 0 { return c.startApp(ctx) @@ -125,14 +129,14 @@ func (c Command) Run(ctx *Context) (err error) { if err != nil { if c.OnUsageError != nil { - err := c.OnUsageError(ctx, err) - return err - } else { - fmt.Fprintln(ctx.App.Writer, "Incorrect Usage.") - fmt.Fprintln(ctx.App.Writer) - ShowCommandHelp(ctx, c.Name) + err := c.OnUsageError(ctx, err, false) + HandleExitCoder(err) return err } + fmt.Fprintln(ctx.App.Writer, "Incorrect Usage.") + fmt.Fprintln(ctx.App.Writer) + ShowCommandHelp(ctx, c.Name) + return err } nerr := normalizeFlags(c.Flags, set) @@ -142,6 +146,7 @@ func (c Command) Run(ctx *Context) (err error) { ShowCommandHelp(ctx, c.Name) return nerr } + context := NewContext(ctx.App, set, ctx) if checkCommandCompletions(context, c.Name) { @@ -156,6 +161,7 @@ func (c Command) Run(ctx *Context) (err error) { defer func() { afterErr := c.After(context) if afterErr != nil { + HandleExitCoder(err) if err != nil { err = NewMultiError(err, afterErr) } else { @@ -166,20 +172,26 @@ func (c Command) Run(ctx *Context) (err error) { } if c.Before != nil { - err := c.Before(context) + err = c.Before(context) if err != nil { fmt.Fprintln(ctx.App.Writer, err) fmt.Fprintln(ctx.App.Writer) ShowCommandHelp(ctx, c.Name) + HandleExitCoder(err) return err } } context.Command = c - c.Action(context) - return nil + err = HandleAction(c.Action, context) + + if err != nil { + HandleExitCoder(err) + } + return err } +// Names returns the names including short names and aliases. func (c Command) Names() []string { names := []string{c.Name} @@ -190,7 +202,7 @@ func (c Command) Names() []string { return append(names, c.Aliases...) } -// Returns true if Command.Name or Command.ShortName matches given name +// HasName returns true if Command.Name or Command.ShortName matches given name func (c Command) HasName(name string) bool { for _, n := range c.Names() { if n == name { @@ -202,7 +214,7 @@ func (c Command) HasName(name string) bool { func (c Command) startApp(ctx *Context) error { app := NewApp() - + app.Metadata = ctx.App.Metadata // set the name and usage app.Name = fmt.Sprintf("%s %s", ctx.App.Name, c.Name) if c.HelpName == "" { @@ -260,3 +272,8 @@ func (c Command) startApp(ctx *Context) error { return app.RunAsSubcommand(ctx) } + +// VisibleFlags returns a slice of the Flags with Hidden=false +func (c Command) VisibleFlags() []Flag { + return visibleFlags(c.Flags) +} diff --git a/vendor/github.com/codegangsta/cli/command_test.go b/vendor/github.com/codegangsta/cli/command_test.go index 827da1df2..660825461 100644 --- a/vendor/github.com/codegangsta/cli/command_test.go +++ b/vendor/github.com/codegangsta/cli/command_test.go @@ -34,7 +34,7 @@ func TestCommandFlagParsing(t *testing.T) { Aliases: []string{"tc"}, Usage: "this is for testing", Description: "testing", - Action: func(_ *Context) {}, + Action: func(_ *Context) error { return nil }, } command.SkipFlagParsing = c.skipFlagParsing @@ -49,10 +49,14 @@ func TestCommandFlagParsing(t *testing.T) { func TestCommand_Run_DoesNotOverwriteErrorFromBefore(t *testing.T) { app := NewApp() app.Commands = []Command{ - Command{ - Name: "bar", - Before: func(c *Context) error { return fmt.Errorf("before error") }, - After: func(c *Context) error { return fmt.Errorf("after error") }, + { + Name: "bar", + Before: func(c *Context) error { + return fmt.Errorf("before error") + }, + After: func(c *Context) error { + return fmt.Errorf("after error") + }, }, } @@ -72,12 +76,12 @@ func TestCommand_Run_DoesNotOverwriteErrorFromBefore(t *testing.T) { func TestCommand_OnUsageError_WithWrongFlagValue(t *testing.T) { app := NewApp() app.Commands = []Command{ - Command{ - Name: "bar", + { + Name: "bar", Flags: []Flag{ IntFlag{Name: "flag"}, }, - OnUsageError: func(c *Context, err error) error { + OnUsageError: func(c *Context, err error, _ bool) error { if !strings.HasPrefix(err.Error(), "invalid value \"wrong\"") { t.Errorf("Expect an invalid value error, but got \"%v\"", err) } diff --git a/vendor/github.com/codegangsta/cli/context.go b/vendor/github.com/codegangsta/cli/context.go index b66d278d0..879bae5ec 100644 --- a/vendor/github.com/codegangsta/cli/context.go +++ b/vendor/github.com/codegangsta/cli/context.go @@ -21,57 +21,83 @@ type Context struct { parentContext *Context } -// Creates a new context. For use in when invoking an App or Command action. +// NewContext creates a new context. For use in when invoking an App or Command action. func NewContext(app *App, set *flag.FlagSet, parentCtx *Context) *Context { return &Context{App: app, flagSet: set, parentContext: parentCtx} } -// Looks up the value of a local int flag, returns 0 if no int flag exists +// Int looks up the value of a local int flag, returns 0 if no int flag exists func (c *Context) Int(name string) int { return lookupInt(name, c.flagSet) } -// Looks up the value of a local time.Duration flag, returns 0 if no time.Duration flag exists +// Int64 looks up the value of a local int flag, returns 0 if no int flag exists +func (c *Context) Int64(name string) int64 { + return lookupInt64(name, c.flagSet) +} + +// Uint looks up the value of a local int flag, returns 0 if no int flag exists +func (c *Context) Uint(name string) uint { + return lookupUint(name, c.flagSet) +} + +// Uint64 looks up the value of a local int flag, returns 0 if no int flag exists +func (c *Context) Uint64(name string) uint64 { + return lookupUint64(name, c.flagSet) +} + +// Duration looks up the value of a local time.Duration flag, returns 0 if no +// time.Duration flag exists func (c *Context) Duration(name string) time.Duration { return lookupDuration(name, c.flagSet) } -// Looks up the value of a local float64 flag, returns 0 if no float64 flag exists +// Float64 looks up the value of a local float64 flag, returns 0 if no float64 +// flag exists func (c *Context) Float64(name string) float64 { return lookupFloat64(name, c.flagSet) } -// Looks up the value of a local bool flag, returns false if no bool flag exists +// Bool looks up the value of a local bool flag, returns false if no bool flag exists func (c *Context) Bool(name string) bool { return lookupBool(name, c.flagSet) } -// Looks up the value of a local boolT flag, returns false if no bool flag exists +// BoolT looks up the value of a local boolT flag, returns false if no bool flag exists func (c *Context) BoolT(name string) bool { return lookupBoolT(name, c.flagSet) } -// Looks up the value of a local string flag, returns "" if no string flag exists +// String looks up the value of a local string flag, returns "" if no string flag exists func (c *Context) String(name string) string { return lookupString(name, c.flagSet) } -// Looks up the value of a local string slice flag, returns nil if no string slice flag exists +// StringSlice looks up the value of a local string slice flag, returns nil if no +// string slice flag exists func (c *Context) StringSlice(name string) []string { return lookupStringSlice(name, c.flagSet) } -// Looks up the value of a local int slice flag, returns nil if no int slice flag exists +// IntSlice looks up the value of a local int slice flag, returns nil if no int +// slice flag exists func (c *Context) IntSlice(name string) []int { return lookupIntSlice(name, c.flagSet) } -// Looks up the value of a local generic flag, returns nil if no generic flag exists +// Int64Slice looks up the value of a local int slice flag, returns nil if no int +// slice flag exists +func (c *Context) Int64Slice(name string) []int64 { + return lookupInt64Slice(name, c.flagSet) +} + +// Generic looks up the value of a local generic flag, returns nil if no generic +// flag exists func (c *Context) Generic(name string) interface{} { return lookupGeneric(name, c.flagSet) } -// Looks up the value of a global int flag, returns 0 if no int flag exists +// GlobalInt looks up the value of a global int flag, returns 0 if no int flag exists func (c *Context) GlobalInt(name string) int { if fs := lookupGlobalFlagSet(name, c); fs != nil { return lookupInt(name, fs) @@ -79,7 +105,41 @@ func (c *Context) GlobalInt(name string) int { return 0 } -// Looks up the value of a global time.Duration flag, returns 0 if no time.Duration flag exists +// GlobalInt64 looks up the value of a global int flag, returns 0 if no int flag exists +func (c *Context) GlobalInt64(name string) int64 { + if fs := lookupGlobalFlagSet(name, c); fs != nil { + return lookupInt64(name, fs) + } + return 0 +} + +// GlobalUint looks up the value of a global int flag, returns 0 if no int flag exists +func (c *Context) GlobalUint(name string) uint { + if fs := lookupGlobalFlagSet(name, c); fs != nil { + return lookupUint(name, fs) + } + return 0 +} + +// GlobalUint64 looks up the value of a global int flag, returns 0 if no int flag exists +func (c *Context) GlobalUint64(name string) uint64 { + if fs := lookupGlobalFlagSet(name, c); fs != nil { + return lookupUint64(name, fs) + } + return 0 +} + +// GlobalFloat64 looks up the value of a global float64 flag, returns float64(0) +// if no float64 flag exists +func (c *Context) GlobalFloat64(name string) float64 { + if fs := lookupGlobalFlagSet(name, c); fs != nil { + return lookupFloat64(name, fs) + } + return float64(0) +} + +// GlobalDuration looks up the value of a global time.Duration flag, returns 0 +// if no time.Duration flag exists func (c *Context) GlobalDuration(name string) time.Duration { if fs := lookupGlobalFlagSet(name, c); fs != nil { return lookupDuration(name, fs) @@ -87,7 +147,8 @@ func (c *Context) GlobalDuration(name string) time.Duration { return 0 } -// Looks up the value of a global bool flag, returns false if no bool flag exists +// GlobalBool looks up the value of a global bool flag, returns false if no bool +// flag exists func (c *Context) GlobalBool(name string) bool { if fs := lookupGlobalFlagSet(name, c); fs != nil { return lookupBool(name, fs) @@ -95,7 +156,17 @@ func (c *Context) GlobalBool(name string) bool { return false } -// Looks up the value of a global string flag, returns "" if no string flag exists +// GlobalBoolT looks up the value of a global bool flag, returns true if no bool +// flag exists +func (c *Context) GlobalBoolT(name string) bool { + if fs := lookupGlobalFlagSet(name, c); fs != nil { + return lookupBoolT(name, fs) + } + return false +} + +// GlobalString looks up the value of a global string flag, returns "" if no +// string flag exists func (c *Context) GlobalString(name string) string { if fs := lookupGlobalFlagSet(name, c); fs != nil { return lookupString(name, fs) @@ -103,7 +174,8 @@ func (c *Context) GlobalString(name string) string { return "" } -// Looks up the value of a global string slice flag, returns nil if no string slice flag exists +// GlobalStringSlice looks up the value of a global string slice flag, returns +// nil if no string slice flag exists func (c *Context) GlobalStringSlice(name string) []string { if fs := lookupGlobalFlagSet(name, c); fs != nil { return lookupStringSlice(name, fs) @@ -111,7 +183,8 @@ func (c *Context) GlobalStringSlice(name string) []string { return nil } -// Looks up the value of a global int slice flag, returns nil if no int slice flag exists +// GlobalIntSlice looks up the value of a global int slice flag, returns nil if +// no int slice flag exists func (c *Context) GlobalIntSlice(name string) []int { if fs := lookupGlobalFlagSet(name, c); fs != nil { return lookupIntSlice(name, fs) @@ -119,7 +192,17 @@ func (c *Context) GlobalIntSlice(name string) []int { return nil } -// Looks up the value of a global generic flag, returns nil if no generic flag exists +// GlobalInt64Slice looks up the value of a global int slice flag, returns nil if +// no int slice flag exists +func (c *Context) GlobalInt64Slice(name string) []int64 { + if fs := lookupGlobalFlagSet(name, c); fs != nil { + return lookupInt64Slice(name, fs) + } + return nil +} + +// GlobalGeneric looks up the value of a global generic flag, returns nil if no +// generic flag exists func (c *Context) GlobalGeneric(name string) interface{} { if fs := lookupGlobalFlagSet(name, c); fs != nil { return lookupGeneric(name, fs) @@ -127,12 +210,22 @@ func (c *Context) GlobalGeneric(name string) interface{} { return nil } -// Returns the number of flags set +// NumFlags returns the number of flags set func (c *Context) NumFlags() int { return c.flagSet.NFlag() } -// Determines if the flag was actually set +// Set sets a context flag to a value. +func (c *Context) Set(name, value string) error { + return c.flagSet.Set(name, value) +} + +// GlobalSet sets a context flag to a value on the global flagset +func (c *Context) GlobalSet(name, value string) error { + return globalContext(c).flagSet.Set(name, value) +} + +// IsSet determines if the flag was actually set func (c *Context) IsSet(name string) bool { if c.setFlags == nil { c.setFlags = make(map[string]bool) @@ -143,7 +236,7 @@ func (c *Context) IsSet(name string) bool { return c.setFlags[name] == true } -// Determines if the global flag was actually set +// GlobalIsSet determines if the global flag was actually set func (c *Context) GlobalIsSet(name string) bool { if c.globalSetFlags == nil { c.globalSetFlags = make(map[string]bool) @@ -160,7 +253,7 @@ func (c *Context) GlobalIsSet(name string) bool { return c.globalSetFlags[name] } -// Returns a slice of flag names used in this context. +// FlagNames returns a slice of flag names used in this context. func (c *Context) FlagNames() (names []string) { for _, flag := range c.Command.Flags { name := strings.Split(flag.GetName(), ",")[0] @@ -172,7 +265,7 @@ func (c *Context) FlagNames() (names []string) { return } -// Returns a slice of global flag names used by the app. +// GlobalFlagNames returns a slice of global flag names used by the app. func (c *Context) GlobalFlagNames() (names []string) { for _, flag := range c.App.Flags { name := strings.Split(flag.GetName(), ",")[0] @@ -184,25 +277,26 @@ func (c *Context) GlobalFlagNames() (names []string) { return } -// Returns the parent context, if any +// Parent returns the parent context, if any func (c *Context) Parent() *Context { return c.parentContext } +// Args contains apps console arguments type Args []string -// Returns the command line arguments associated with the context. +// Args returns the command line arguments associated with the context. func (c *Context) Args() Args { args := Args(c.flagSet.Args()) return args } -// Returns the number of the command line arguments. +// NArg returns the number of the command line arguments. func (c *Context) NArg() int { return len(c.Args()) } -// Returns the nth argument, or else a blank string +// Get returns the nth argument, or else a blank string func (a Args) Get(n int) string { if len(a) > n { return a[n] @@ -210,12 +304,12 @@ func (a Args) Get(n int) string { return "" } -// Returns the first argument, or else a blank string +// First returns the first argument, or else a blank string func (a Args) First() string { return a.Get(0) } -// Return the rest of the arguments (not the first one) +// Tail returns the rest of the arguments (not the first one) // or else an empty string slice func (a Args) Tail() []string { if len(a) >= 2 { @@ -224,12 +318,12 @@ func (a Args) Tail() []string { return []string{} } -// Checks if there are any arguments present +// Present checks if there are any arguments present func (a Args) Present() bool { return len(a) != 0 } -// Swaps arguments at the given indexes +// Swap swaps arguments at the given indexes func (a Args) Swap(from, to int) error { if from >= len(a) || to >= len(a) { return errors.New("index out of range") @@ -238,6 +332,19 @@ func (a Args) Swap(from, to int) error { return nil } +func globalContext(ctx *Context) *Context { + if ctx == nil { + return nil + } + + for { + if ctx.parentContext == nil { + return ctx + } + ctx = ctx.parentContext + } +} + func lookupGlobalFlagSet(name string, ctx *Context) *flag.FlagSet { if ctx.parentContext != nil { ctx = ctx.parentContext @@ -253,7 +360,46 @@ func lookupGlobalFlagSet(name string, ctx *Context) *flag.FlagSet { func lookupInt(name string, set *flag.FlagSet) int { f := set.Lookup(name) if f != nil { - val, err := strconv.Atoi(f.Value.String()) + val, err := strconv.ParseInt(f.Value.String(), 0, 64) + if err != nil { + return 0 + } + return int(val) + } + + return 0 +} + +func lookupInt64(name string, set *flag.FlagSet) int64 { + f := set.Lookup(name) + if f != nil { + val, err := strconv.ParseInt(f.Value.String(), 0, 64) + if err != nil { + return 0 + } + return val + } + + return 0 +} + +func lookupUint(name string, set *flag.FlagSet) uint { + f := set.Lookup(name) + if f != nil { + val, err := strconv.ParseUint(f.Value.String(), 0, 64) + if err != nil { + return 0 + } + return uint(val) + } + + return 0 +} + +func lookupUint64(name string, set *flag.FlagSet) uint64 { + f := set.Lookup(name) + if f != nil { + val, err := strconv.ParseUint(f.Value.String(), 0, 64) if err != nil { return 0 } @@ -317,6 +463,16 @@ func lookupIntSlice(name string, set *flag.FlagSet) []int { return nil } +func lookupInt64Slice(name string, set *flag.FlagSet) []int64 { + f := set.Lookup(name) + if f != nil { + return (f.Value.(*Int64Slice)).Value() + + } + + return nil +} + func lookupGeneric(name string, set *flag.FlagSet) interface{} { f := set.Lookup(name) if f != nil { diff --git a/vendor/github.com/codegangsta/cli/context_test.go b/vendor/github.com/codegangsta/cli/context_test.go index b8ab37d4e..5c68fdd36 100644 --- a/vendor/github.com/codegangsta/cli/context_test.go +++ b/vendor/github.com/codegangsta/cli/context_test.go @@ -9,14 +9,30 @@ import ( func TestNewContext(t *testing.T) { set := flag.NewFlagSet("test", 0) set.Int("myflag", 12, "doc") + set.Int64("myflagInt64", int64(12), "doc") + set.Uint("myflagUint", uint(93), "doc") + set.Uint64("myflagUint64", uint64(93), "doc") + set.Float64("myflag64", float64(17), "doc") globalSet := flag.NewFlagSet("test", 0) globalSet.Int("myflag", 42, "doc") + globalSet.Int64("myflagInt64", int64(42), "doc") + globalSet.Uint("myflagUint", uint(33), "doc") + globalSet.Uint64("myflagUint64", uint64(33), "doc") + globalSet.Float64("myflag64", float64(47), "doc") globalCtx := NewContext(nil, globalSet, nil) command := Command{Name: "mycommand"} c := NewContext(nil, set, globalCtx) c.Command = command expect(t, c.Int("myflag"), 12) + expect(t, c.Int64("myflagInt64"), int64(12)) + expect(t, c.Uint("myflagUint"), uint(93)) + expect(t, c.Uint64("myflagUint64"), uint64(93)) + expect(t, c.Float64("myflag64"), float64(17)) expect(t, c.GlobalInt("myflag"), 42) + expect(t, c.GlobalInt64("myflagInt64"), int64(42)) + expect(t, c.GlobalUint("myflagUint"), uint(33)) + expect(t, c.GlobalUint64("myflagUint64"), uint64(33)) + expect(t, c.GlobalFloat64("myflag64"), float64(47)) expect(t, c.Command.Name, "mycommand") } @@ -27,6 +43,58 @@ func TestContext_Int(t *testing.T) { expect(t, c.Int("myflag"), 12) } +func TestContext_Int64(t *testing.T) { + set := flag.NewFlagSet("test", 0) + set.Int64("myflagInt64", 12, "doc") + c := NewContext(nil, set, nil) + expect(t, c.Int64("myflagInt64"), int64(12)) +} + +func TestContext_Uint(t *testing.T) { + set := flag.NewFlagSet("test", 0) + set.Uint("myflagUint", uint(13), "doc") + c := NewContext(nil, set, nil) + expect(t, c.Uint("myflagUint"), uint(13)) +} + +func TestContext_Uint64(t *testing.T) { + set := flag.NewFlagSet("test", 0) + set.Uint64("myflagUint64", uint64(9), "doc") + c := NewContext(nil, set, nil) + expect(t, c.Uint64("myflagUint64"), uint64(9)) +} + +func TestContext_GlobalInt(t *testing.T) { + set := flag.NewFlagSet("test", 0) + set.Int("myflag", 12, "doc") + c := NewContext(nil, set, nil) + expect(t, c.GlobalInt("myflag"), 12) + expect(t, c.GlobalInt("nope"), 0) +} + +func TestContext_GlobalInt64(t *testing.T) { + set := flag.NewFlagSet("test", 0) + set.Int64("myflagInt64", 12, "doc") + c := NewContext(nil, set, nil) + expect(t, c.GlobalInt64("myflagInt64"), int64(12)) + expect(t, c.GlobalInt64("nope"), int64(0)) +} + +func TestContext_Float64(t *testing.T) { + set := flag.NewFlagSet("test", 0) + set.Float64("myflag", float64(17), "doc") + c := NewContext(nil, set, nil) + expect(t, c.Float64("myflag"), float64(17)) +} + +func TestContext_GlobalFloat64(t *testing.T) { + set := flag.NewFlagSet("test", 0) + set.Float64("myflag", float64(17), "doc") + c := NewContext(nil, set, nil) + expect(t, c.GlobalFloat64("myflag"), float64(17)) + expect(t, c.GlobalFloat64("nope"), float64(0)) +} + func TestContext_Duration(t *testing.T) { set := flag.NewFlagSet("test", 0) set.Duration("myflag", time.Duration(12*time.Second), "doc") @@ -55,6 +123,30 @@ func TestContext_BoolT(t *testing.T) { expect(t, c.BoolT("myflag"), true) } +func TestContext_GlobalBool(t *testing.T) { + set := flag.NewFlagSet("test", 0) + + globalSet := flag.NewFlagSet("test-global", 0) + globalSet.Bool("myflag", false, "doc") + globalCtx := NewContext(nil, globalSet, nil) + + c := NewContext(nil, set, globalCtx) + expect(t, c.GlobalBool("myflag"), false) + expect(t, c.GlobalBool("nope"), false) +} + +func TestContext_GlobalBoolT(t *testing.T) { + set := flag.NewFlagSet("test", 0) + + globalSet := flag.NewFlagSet("test-global", 0) + globalSet.Bool("myflag", true, "doc") + globalCtx := NewContext(nil, globalSet, nil) + + c := NewContext(nil, set, globalCtx) + expect(t, c.GlobalBoolT("myflag"), true) + expect(t, c.GlobalBoolT("nope"), false) +} + func TestContext_Args(t *testing.T) { set := flag.NewFlagSet("test", 0) set.Bool("myflag", false, "doc") @@ -119,3 +211,87 @@ func TestContext_NumFlags(t *testing.T) { globalSet.Parse([]string{"--myflagGlobal"}) expect(t, c.NumFlags(), 2) } + +func TestContext_GlobalFlag(t *testing.T) { + var globalFlag string + var globalFlagSet bool + app := NewApp() + app.Flags = []Flag{ + StringFlag{Name: "global, g", Usage: "global"}, + } + app.Action = func(c *Context) error { + globalFlag = c.GlobalString("global") + globalFlagSet = c.GlobalIsSet("global") + return nil + } + app.Run([]string{"command", "-g", "foo"}) + expect(t, globalFlag, "foo") + expect(t, globalFlagSet, true) + +} + +func TestContext_GlobalFlagsInSubcommands(t *testing.T) { + subcommandRun := false + parentFlag := false + app := NewApp() + + app.Flags = []Flag{ + BoolFlag{Name: "debug, d", Usage: "Enable debugging"}, + } + + app.Commands = []Command{ + { + Name: "foo", + Flags: []Flag{ + BoolFlag{Name: "parent, p", Usage: "Parent flag"}, + }, + Subcommands: []Command{ + { + Name: "bar", + Action: func(c *Context) error { + if c.GlobalBool("debug") { + subcommandRun = true + } + if c.GlobalBool("parent") { + parentFlag = true + } + return nil + }, + }, + }, + }, + } + + app.Run([]string{"command", "-d", "foo", "-p", "bar"}) + + expect(t, subcommandRun, true) + expect(t, parentFlag, true) +} + +func TestContext_Set(t *testing.T) { + set := flag.NewFlagSet("test", 0) + set.Int("int", 5, "an int") + c := NewContext(nil, set, nil) + + c.Set("int", "1") + expect(t, c.Int("int"), 1) +} + +func TestContext_GlobalSet(t *testing.T) { + gSet := flag.NewFlagSet("test", 0) + gSet.Int("int", 5, "an int") + + set := flag.NewFlagSet("sub", 0) + set.Int("int", 3, "an int") + + pc := NewContext(nil, gSet, nil) + c := NewContext(nil, set, pc) + + c.Set("int", "1") + expect(t, c.Int("int"), 1) + expect(t, c.GlobalInt("int"), 5) + + c.GlobalSet("int", "1") + expect(t, c.Int("int"), 1) + expect(t, c.GlobalInt("int"), 1) +} diff --git a/vendor/github.com/codegangsta/cli/errors.go b/vendor/github.com/codegangsta/cli/errors.go new file mode 100644 index 000000000..ea551be16 --- /dev/null +++ b/vendor/github.com/codegangsta/cli/errors.go @@ -0,0 +1,92 @@ +package cli + +import ( + "fmt" + "io" + "os" + "strings" +) + +// OsExiter is the function used when the app exits. If not set defaults to os.Exit. +var OsExiter = os.Exit + +// ErrWriter is used to write errors to the user. This can be anything +// implementing the io.Writer interface and defaults to os.Stderr. +var ErrWriter io.Writer = os.Stderr + +// MultiError is an error that wraps multiple errors. +type MultiError struct { + Errors []error +} + +// NewMultiError creates a new MultiError. Pass in one or more errors. +func NewMultiError(err ...error) MultiError { + return MultiError{Errors: err} +} + +// Error implents the error interface. +func (m MultiError) Error() string { + errs := make([]string, len(m.Errors)) + for i, err := range m.Errors { + errs[i] = err.Error() + } + + return strings.Join(errs, "\n") +} + +// ExitCoder is the interface checked by `App` and `Command` for a custom exit +// code +type ExitCoder interface { + error + ExitCode() int +} + +// ExitError fulfills both the builtin `error` interface and `ExitCoder` +type ExitError struct { + exitCode int + message string +} + +// NewExitError makes a new *ExitError +func NewExitError(message string, exitCode int) *ExitError { + return &ExitError{ + exitCode: exitCode, + message: message, + } +} + +// Error returns the string message, fulfilling the interface required by +// `error` +func (ee *ExitError) Error() string { + return ee.message +} + +// ExitCode returns the exit code, fulfilling the interface required by +// `ExitCoder` +func (ee *ExitError) ExitCode() int { + return ee.exitCode +} + +// HandleExitCoder checks if the error fulfills the ExitCoder interface, and if +// so prints the error to stderr (if it is non-empty) and calls OsExiter with the +// given exit code. If the given error is a MultiError, then this func is +// called on all members of the Errors slice. +func HandleExitCoder(err error) { + if err == nil { + return + } + + if exitErr, ok := err.(ExitCoder); ok { + if err.Error() != "" { + fmt.Fprintln(ErrWriter, err) + } + OsExiter(exitErr.ExitCode()) + return + } + + if multiErr, ok := err.(MultiError); ok { + for _, merr := range multiErr.Errors { + HandleExitCoder(merr) + } + } +} diff --git a/vendor/github.com/codegangsta/cli/errors_test.go b/vendor/github.com/codegangsta/cli/errors_test.go new file mode 100644 index 000000000..8f5f28431 --- /dev/null +++ b/vendor/github.com/codegangsta/cli/errors_test.go @@ -0,0 +1,60 @@ +package cli + +import ( + "errors" + "os" + "testing" +) + +func TestHandleExitCoder_nil(t *testing.T) { + exitCode := 0 + called := false + + OsExiter = func(rc int) { + exitCode = rc + called = true + } + + defer func() { OsExiter = os.Exit }() + + HandleExitCoder(nil) + + expect(t, exitCode, 0) + expect(t, called, false) +} + +func TestHandleExitCoder_ExitCoder(t *testing.T) { + exitCode := 0 + called := false + + OsExiter = func(rc int) { + exitCode = rc + called = true + } + + defer func() { OsExiter = os.Exit }() + + HandleExitCoder(NewExitError("galactic perimeter breach", 9)) + + expect(t, exitCode, 9) + expect(t, called, true) +} + +func TestHandleExitCoder_MultiErrorWithExitCoder(t *testing.T) { + exitCode := 0 + called := false + + OsExiter = func(rc int) { + exitCode = rc + called = true + } + + defer func() { OsExiter = os.Exit }() + + exitErr := NewExitError("galactic perimeter breach", 9) + err := NewMultiError(errors.New("wowsa"), errors.New("egad"), exitErr) + HandleExitCoder(err) + + expect(t, exitCode, 9) + expect(t, called, true) +} diff --git a/vendor/github.com/codegangsta/cli/flag.go b/vendor/github.com/codegangsta/cli/flag.go index 42f6a616e..f8a28d119 100644 --- a/vendor/github.com/codegangsta/cli/flag.go +++ b/vendor/github.com/codegangsta/cli/flag.go @@ -4,24 +4,28 @@ import ( "flag" "fmt" "os" + "reflect" "runtime" "strconv" "strings" "time" ) -// This flag enables bash-completion for all commands and subcommands +const defaultPlaceholder = "value" + +// BashCompletionFlag enables bash-completion for all commands and subcommands var BashCompletionFlag = BoolFlag{ - Name: "generate-bash-completion", + Name: "generate-bash-completion", + Hidden: true, } -// This flag prints the version for the application +// VersionFlag prints the version for the application var VersionFlag = BoolFlag{ Name: "version, v", Usage: "print the version", } -// This flag prints the help for all commands and subcommands +// HelpFlag prints the help for all commands and subcommands // Set to the zero value (BoolFlag{}) to disable flag -- keeps subcommand // unless HideHelp is set to true) var HelpFlag = BoolFlag{ @@ -29,6 +33,10 @@ var HelpFlag = BoolFlag{ Usage: "show help", } +// FlagStringer converts a flag definition to a string. This is used by help +// to display a flag. +var FlagStringer FlagStringFunc = stringifyFlag + // Flag is a common interface related to parsing flags in cli. // For more advanced flag parsing techniques, it is recommended that // this interface be implemented. @@ -68,25 +76,14 @@ type GenericFlag struct { Value Generic Usage string EnvVar string + Hidden bool } // String returns the string representation of the generic flag to display the // help text to the user (uses the String() method of the generic flag to show // the value) func (f GenericFlag) String() string { - placeholder, usage := unquoteUsage(f.Usage) - return withEnvHint(f.EnvVar, fmt.Sprintf("%s %v\t%v", prefixedNames(f.Name, placeholder), f.FormatValueHelp(), usage)) -} - -func (f GenericFlag) FormatValueHelp() string { - if f.Value == nil { - return "" - } - s := f.Value.String() - if len(s) == 0 { - return "" - } - return fmt.Sprintf("\"%s\"", s) + return FlagStringer(f) } // Apply takes the flagset and calls Set on the generic flag with the value @@ -108,6 +105,7 @@ func (f GenericFlag) Apply(set *flag.FlagSet) { }) } +// GetName returns the name of a flag. func (f GenericFlag) GetName() string { return f.Name } @@ -131,21 +129,19 @@ func (f *StringSlice) Value() []string { return *f } -// StringSlice is a string flag that can be specified multiple times on the +// StringSliceFlag is a string flag that can be specified multiple times on the // command-line type StringSliceFlag struct { Name string Value *StringSlice Usage string EnvVar string + Hidden bool } // String returns the usage func (f StringSliceFlag) String() string { - firstName := strings.Trim(strings.Split(f.Name, ",")[0], " ") - pref := prefixFor(firstName) - placeholder, usage := unquoteUsage(f.Usage) - return withEnvHint(f.EnvVar, fmt.Sprintf("%s [%v]\t%v", prefixedNames(f.Name, placeholder), pref+firstName+" option "+pref+firstName+" option", usage)) + return FlagStringer(f) } // Apply populates the flag given the flag set and environment @@ -173,11 +169,12 @@ func (f StringSliceFlag) Apply(set *flag.FlagSet) { }) } +// GetName returns the name of a flag. func (f StringSliceFlag) GetName() string { return f.Name } -// StringSlice is an opaque type for []int to satisfy flag.Value +// IntSlice is an opaque type for []int to satisfy flag.Value type IntSlice []int // Set parses the value into an integer and appends it to the list of values @@ -185,15 +182,14 @@ func (f *IntSlice) Set(value string) error { tmp, err := strconv.Atoi(value) if err != nil { return err - } else { - *f = append(*f, tmp) } + *f = append(*f, tmp) return nil } // String returns a readable representation of this value (for usage defaults) func (f *IntSlice) String() string { - return fmt.Sprintf("%d", *f) + return fmt.Sprintf("%#v", *f) } // Value returns the slice of ints set by this flag @@ -208,14 +204,12 @@ type IntSliceFlag struct { Value *IntSlice Usage string EnvVar string + Hidden bool } // String returns the usage func (f IntSliceFlag) String() string { - firstName := strings.Trim(strings.Split(f.Name, ",")[0], " ") - pref := prefixFor(firstName) - placeholder, usage := unquoteUsage(f.Usage) - return withEnvHint(f.EnvVar, fmt.Sprintf("%s [%v]\t%v", prefixedNames(f.Name, placeholder), pref+firstName+" option "+pref+firstName+" option", usage)) + return FlagStringer(f) } // Apply populates the flag given the flag set and environment @@ -229,7 +223,7 @@ func (f IntSliceFlag) Apply(set *flag.FlagSet) { s = strings.TrimSpace(s) err := newVal.Set(s) if err != nil { - fmt.Fprintf(os.Stderr, err.Error()) + fmt.Fprintf(ErrWriter, err.Error()) } } f.Value = newVal @@ -246,22 +240,94 @@ func (f IntSliceFlag) Apply(set *flag.FlagSet) { }) } +// GetName returns the name of the flag. func (f IntSliceFlag) GetName() string { return f.Name } +// Int64Slice is an opaque type for []int to satisfy flag.Value +type Int64Slice []int64 + +// Set parses the value into an integer and appends it to the list of values +func (f *Int64Slice) Set(value string) error { + tmp, err := strconv.ParseInt(value, 10, 64) + if err != nil { + return err + } + *f = append(*f, tmp) + return nil +} + +// String returns a readable representation of this value (for usage defaults) +func (f *Int64Slice) String() string { + return fmt.Sprintf("%#v", *f) +} + +// Value returns the slice of ints set by this flag +func (f *Int64Slice) Value() []int64 { + return *f +} + +// Int64SliceFlag is an int flag that can be specified multiple times on the +// command-line +type Int64SliceFlag struct { + Name string + Value *Int64Slice + Usage string + EnvVar string + Hidden bool +} + +// String returns the usage +func (f Int64SliceFlag) String() string { + return FlagStringer(f) +} + +// Apply populates the flag given the flag set and environment +func (f Int64SliceFlag) Apply(set *flag.FlagSet) { + if f.EnvVar != "" { + for _, envVar := range strings.Split(f.EnvVar, ",") { + envVar = strings.TrimSpace(envVar) + if envVal := os.Getenv(envVar); envVal != "" { + newVal := &Int64Slice{} + for _, s := range strings.Split(envVal, ",") { + s = strings.TrimSpace(s) + err := newVal.Set(s) + if err != nil { + fmt.Fprintf(ErrWriter, err.Error()) + } + } + f.Value = newVal + break + } + } + } + + eachName(f.Name, func(name string) { + if f.Value == nil { + f.Value = &Int64Slice{} + } + set.Var(f.Value, name, f.Usage) + }) +} + +// GetName returns the name of the flag. +func (f Int64SliceFlag) GetName() string { + return f.Name +} + // BoolFlag is a switch that defaults to false type BoolFlag struct { Name string Usage string EnvVar string Destination *bool + Hidden bool } // String returns a readable representation of this value (for usage defaults) func (f BoolFlag) String() string { - placeholder, usage := unquoteUsage(f.Usage) - return withEnvHint(f.EnvVar, fmt.Sprintf("%s\t%v", prefixedNames(f.Name, placeholder), usage)) + return FlagStringer(f) } // Apply populates the flag given the flag set and environment @@ -289,6 +355,7 @@ func (f BoolFlag) Apply(set *flag.FlagSet) { }) } +// GetName returns the name of the flag. func (f BoolFlag) GetName() string { return f.Name } @@ -300,12 +367,12 @@ type BoolTFlag struct { Usage string EnvVar string Destination *bool + Hidden bool } // String returns a readable representation of this value (for usage defaults) func (f BoolTFlag) String() string { - placeholder, usage := unquoteUsage(f.Usage) - return withEnvHint(f.EnvVar, fmt.Sprintf("%s\t%v", prefixedNames(f.Name, placeholder), usage)) + return FlagStringer(f) } // Apply populates the flag given the flag set and environment @@ -333,6 +400,7 @@ func (f BoolTFlag) Apply(set *flag.FlagSet) { }) } +// GetName returns the name of the flag. func (f BoolTFlag) GetName() string { return f.Name } @@ -344,20 +412,12 @@ type StringFlag struct { Usage string EnvVar string Destination *string + Hidden bool } // String returns the usage func (f StringFlag) String() string { - placeholder, usage := unquoteUsage(f.Usage) - return withEnvHint(f.EnvVar, fmt.Sprintf("%s %v\t%v", prefixedNames(f.Name, placeholder), f.FormatValueHelp(), usage)) -} - -func (f StringFlag) FormatValueHelp() string { - s := f.Value - if len(s) == 0 { - return "" - } - return fmt.Sprintf("\"%s\"", s) + return FlagStringer(f) } // Apply populates the flag given the flag set and environment @@ -381,24 +441,24 @@ func (f StringFlag) Apply(set *flag.FlagSet) { }) } +// GetName returns the name of the flag. func (f StringFlag) GetName() string { return f.Name } // IntFlag is a flag that takes an integer -// Errors if the value provided cannot be parsed type IntFlag struct { Name string Value int Usage string EnvVar string Destination *int + Hidden bool } // String returns the usage func (f IntFlag) String() string { - placeholder, usage := unquoteUsage(f.Usage) - return withEnvHint(f.EnvVar, fmt.Sprintf("%s \"%v\"\t%v", prefixedNames(f.Name, placeholder), f.Value, usage)) + return FlagStringer(f) } // Apply populates the flag given the flag set and environment @@ -425,10 +485,143 @@ func (f IntFlag) Apply(set *flag.FlagSet) { }) } +// GetName returns the name of the flag. func (f IntFlag) GetName() string { return f.Name } +// Int64Flag is a flag that takes a 64-bit integer +type Int64Flag struct { + Name string + Value int64 + Usage string + EnvVar string + Destination *int64 + Hidden bool +} + +// String returns the usage +func (f Int64Flag) String() string { + return FlagStringer(f) +} + +// Apply populates the flag given the flag set and environment +func (f Int64Flag) Apply(set *flag.FlagSet) { + if f.EnvVar != "" { + for _, envVar := range strings.Split(f.EnvVar, ",") { + envVar = strings.TrimSpace(envVar) + if envVal := os.Getenv(envVar); envVal != "" { + envValInt, err := strconv.ParseInt(envVal, 0, 64) + if err == nil { + f.Value = envValInt + break + } + } + } + } + + eachName(f.Name, func(name string) { + if f.Destination != nil { + set.Int64Var(f.Destination, name, f.Value, f.Usage) + return + } + set.Int64(name, f.Value, f.Usage) + }) +} + +// GetName returns the name of the flag. +func (f Int64Flag) GetName() string { + return f.Name +} + +// UintFlag is a flag that takes an unsigned integer +type UintFlag struct { + Name string + Value uint + Usage string + EnvVar string + Destination *uint + Hidden bool +} + +// String returns the usage +func (f UintFlag) String() string { + return FlagStringer(f) +} + +// Apply populates the flag given the flag set and environment +func (f UintFlag) Apply(set *flag.FlagSet) { + if f.EnvVar != "" { + for _, envVar := range strings.Split(f.EnvVar, ",") { + envVar = strings.TrimSpace(envVar) + if envVal := os.Getenv(envVar); envVal != "" { + envValInt, err := strconv.ParseUint(envVal, 0, 64) + if err == nil { + f.Value = uint(envValInt) + break + } + } + } + } + + eachName(f.Name, func(name string) { + if f.Destination != nil { + set.UintVar(f.Destination, name, f.Value, f.Usage) + return + } + set.Uint(name, f.Value, f.Usage) + }) +} + +// GetName returns the name of the flag. +func (f UintFlag) GetName() string { + return f.Name +} + +// Uint64Flag is a flag that takes an unsigned 64-bit integer +type Uint64Flag struct { + Name string + Value uint64 + Usage string + EnvVar string + Destination *uint64 + Hidden bool +} + +// String returns the usage +func (f Uint64Flag) String() string { + return FlagStringer(f) +} + +// Apply populates the flag given the flag set and environment +func (f Uint64Flag) Apply(set *flag.FlagSet) { + if f.EnvVar != "" { + for _, envVar := range strings.Split(f.EnvVar, ",") { + envVar = strings.TrimSpace(envVar) + if envVal := os.Getenv(envVar); envVal != "" { + envValInt, err := strconv.ParseUint(envVal, 0, 64) + if err == nil { + f.Value = uint64(envValInt) + break + } + } + } + } + + eachName(f.Name, func(name string) { + if f.Destination != nil { + set.Uint64Var(f.Destination, name, f.Value, f.Usage) + return + } + set.Uint64(name, f.Value, f.Usage) + }) +} + +// GetName returns the name of the flag. +func (f Uint64Flag) GetName() string { + return f.Name +} + // DurationFlag is a flag that takes a duration specified in Go's duration // format: https://golang.org/pkg/time/#ParseDuration type DurationFlag struct { @@ -437,12 +630,12 @@ type DurationFlag struct { Usage string EnvVar string Destination *time.Duration + Hidden bool } // String returns a readable representation of this value (for usage defaults) func (f DurationFlag) String() string { - placeholder, usage := unquoteUsage(f.Usage) - return withEnvHint(f.EnvVar, fmt.Sprintf("%s \"%v\"\t%v", prefixedNames(f.Name, placeholder), f.Value, usage)) + return FlagStringer(f) } // Apply populates the flag given the flag set and environment @@ -469,24 +662,24 @@ func (f DurationFlag) Apply(set *flag.FlagSet) { }) } +// GetName returns the name of the flag. func (f DurationFlag) GetName() string { return f.Name } // Float64Flag is a flag that takes an float value -// Errors if the value provided cannot be parsed type Float64Flag struct { Name string Value float64 Usage string EnvVar string Destination *float64 + Hidden bool } // String returns the usage func (f Float64Flag) String() string { - placeholder, usage := unquoteUsage(f.Usage) - return withEnvHint(f.EnvVar, fmt.Sprintf("%s \"%v\"\t%v", prefixedNames(f.Name, placeholder), f.Value, usage)) + return FlagStringer(f) } // Apply populates the flag given the flag set and environment @@ -512,10 +705,21 @@ func (f Float64Flag) Apply(set *flag.FlagSet) { }) } +// GetName returns the name of the flag. func (f Float64Flag) GetName() string { return f.Name } +func visibleFlags(fl []Flag) []Flag { + visible := []Flag{} + for _, flag := range fl { + if !flagValue(flag).FieldByName("Hidden").Bool() { + visible = append(visible, flag) + } + } + return visible +} + func prefixFor(name string) (prefix string) { if len(name) == 1 { prefix = "-" @@ -574,3 +778,105 @@ func withEnvHint(envVar, str string) string { } return str + envText } + +func flagValue(f Flag) reflect.Value { + fv := reflect.ValueOf(f) + for fv.Kind() == reflect.Ptr { + fv = reflect.Indirect(fv) + } + return fv +} + +func stringifyFlag(f Flag) string { + fv := flagValue(f) + + switch f.(type) { + case IntSliceFlag: + return withEnvHint(fv.FieldByName("EnvVar").String(), + stringifyIntSliceFlag(f.(IntSliceFlag))) + case Int64SliceFlag: + return withEnvHint(fv.FieldByName("EnvVar").String(), + stringifyInt64SliceFlag(f.(Int64SliceFlag))) + case StringSliceFlag: + return withEnvHint(fv.FieldByName("EnvVar").String(), + stringifyStringSliceFlag(f.(StringSliceFlag))) + } + + placeholder, usage := unquoteUsage(fv.FieldByName("Usage").String()) + + needsPlaceholder := false + defaultValueString := "" + val := fv.FieldByName("Value") + + if val.IsValid() { + needsPlaceholder = true + defaultValueString = fmt.Sprintf(" (default: %v)", val.Interface()) + + if val.Kind() == reflect.String && val.String() != "" { + defaultValueString = fmt.Sprintf(" (default: %q)", val.String()) + } + } + + if defaultValueString == " (default: )" { + defaultValueString = "" + } + + if needsPlaceholder && placeholder == "" { + placeholder = defaultPlaceholder + } + + usageWithDefault := strings.TrimSpace(fmt.Sprintf("%s%s", usage, defaultValueString)) + + return withEnvHint(fv.FieldByName("EnvVar").String(), + fmt.Sprintf("%s\t%s", prefixedNames(fv.FieldByName("Name").String(), placeholder), usageWithDefault)) +} + +func stringifyIntSliceFlag(f IntSliceFlag) string { + defaultVals := []string{} + if f.Value != nil && len(f.Value.Value()) > 0 { + for _, i := range f.Value.Value() { + defaultVals = append(defaultVals, fmt.Sprintf("%d", i)) + } + } + + return stringifySliceFlag(f.Usage, f.Name, defaultVals) +} + +func stringifyInt64SliceFlag(f Int64SliceFlag) string { + defaultVals := []string{} + if f.Value != nil && len(f.Value.Value()) > 0 { + for _, i := range f.Value.Value() { + defaultVals = append(defaultVals, fmt.Sprintf("%d", i)) + } + } + + return stringifySliceFlag(f.Usage, f.Name, defaultVals) +} + +func stringifyStringSliceFlag(f StringSliceFlag) string { + defaultVals := []string{} + if f.Value != nil && len(f.Value.Value()) > 0 { + for _, s := range f.Value.Value() { + if len(s) > 0 { + defaultVals = append(defaultVals, fmt.Sprintf("%q", s)) + } + } + } + + return stringifySliceFlag(f.Usage, f.Name, defaultVals) +} + +func stringifySliceFlag(usage, name string, defaultVals []string) string { + placeholder, usage := unquoteUsage(usage) + if placeholder == "" { + placeholder = defaultPlaceholder + } + + defaultVal := "" + if len(defaultVals) > 0 { + defaultVal = fmt.Sprintf(" (default: %s)", strings.Join(defaultVals, ", ")) + } + + usageWithDefault := strings.TrimSpace(fmt.Sprintf("%s%s", usage, defaultVal)) + return fmt.Sprintf("%s\t%s", prefixedNames(name, placeholder), usageWithDefault) +} diff --git a/vendor/github.com/codegangsta/cli/flag_test.go b/vendor/github.com/codegangsta/cli/flag_test.go index 6bebf1b64..a7afcc4ff 100644 --- a/vendor/github.com/codegangsta/cli/flag_test.go +++ b/vendor/github.com/codegangsta/cli/flag_test.go @@ -7,6 +7,7 @@ import ( "runtime" "strings" "testing" + "time" ) var boolFlagTests = []struct { @@ -18,13 +19,12 @@ var boolFlagTests = []struct { } func TestBoolFlagHelpOutput(t *testing.T) { - for _, test := range boolFlagTests { flag := BoolFlag{Name: test.name} output := flag.String() if output != test.expected { - t.Errorf("%s does not match %s", output, test.expected) + t.Errorf("%q does not match %q", output, test.expected) } } } @@ -35,21 +35,21 @@ var stringFlagTests = []struct { value string expected string }{ - {"help", "", "", "--help \t"}, - {"h", "", "", "-h \t"}, - {"h", "", "", "-h \t"}, - {"test", "", "Something", "--test \"Something\"\t"}, - {"config,c", "Load configuration from `FILE`", "", "--config FILE, -c FILE \tLoad configuration from FILE"}, + {"foo", "", "", "--foo value\t"}, + {"f", "", "", "-f value\t"}, + {"f", "The total `foo` desired", "all", "-f foo\tThe total foo desired (default: \"all\")"}, + {"test", "", "Something", "--test value\t(default: \"Something\")"}, + {"config,c", "Load configuration from `FILE`", "", "--config FILE, -c FILE\tLoad configuration from FILE"}, + {"config,c", "Load configuration from `CONFIG`", "config.json", "--config CONFIG, -c CONFIG\tLoad configuration from CONFIG (default: \"config.json\")"}, } func TestStringFlagHelpOutput(t *testing.T) { - for _, test := range stringFlagTests { flag := StringFlag{Name: test.name, Usage: test.usage, Value: test.value} output := flag.String() if output != test.expected { - t.Errorf("%s does not match %s", output, test.expected) + t.Errorf("%q does not match %q", output, test.expected) } } } @@ -76,30 +76,29 @@ var stringSliceFlagTests = []struct { value *StringSlice expected string }{ - {"help", func() *StringSlice { + {"foo", func() *StringSlice { s := &StringSlice{} s.Set("") return s - }(), "--help [--help option --help option]\t"}, - {"h", func() *StringSlice { + }(), "--foo value\t"}, + {"f", func() *StringSlice { s := &StringSlice{} s.Set("") return s - }(), "-h [-h option -h option]\t"}, - {"h", func() *StringSlice { + }(), "-f value\t"}, + {"f", func() *StringSlice { s := &StringSlice{} - s.Set("") + s.Set("Lipstick") return s - }(), "-h [-h option -h option]\t"}, + }(), "-f value\t(default: \"Lipstick\")"}, {"test", func() *StringSlice { s := &StringSlice{} s.Set("Something") return s - }(), "--test [--test option --test option]\t"}, + }(), "--test value\t(default: \"Something\")"}, } func TestStringSliceFlagHelpOutput(t *testing.T) { - for _, test := range stringSliceFlagTests { flag := StringSliceFlag{Name: test.name, Value: test.value} output := flag.String() @@ -131,14 +130,13 @@ var intFlagTests = []struct { name string expected string }{ - {"help", "--help \"0\"\t"}, - {"h", "-h \"0\"\t"}, + {"hats", "--hats value\t(default: 9)"}, + {"H", "-H value\t(default: 9)"}, } func TestIntFlagHelpOutput(t *testing.T) { - for _, test := range intFlagTests { - flag := IntFlag{Name: test.name} + flag := IntFlag{Name: test.name, Value: 9} output := flag.String() if output != test.expected { @@ -164,22 +162,129 @@ func TestIntFlagWithEnvVarHelpOutput(t *testing.T) { } } +var int64FlagTests = []struct { + name string + expected string +}{ + {"hats", "--hats value\t(default: 8589934592)"}, + {"H", "-H value\t(default: 8589934592)"}, +} + +func TestInt64FlagHelpOutput(t *testing.T) { + for _, test := range int64FlagTests { + flag := Int64Flag{Name: test.name, Value: 8589934592} + output := flag.String() + + if output != test.expected { + t.Errorf("%s does not match %s", output, test.expected) + } + } +} + +func TestInt64FlagWithEnvVarHelpOutput(t *testing.T) { + os.Clearenv() + os.Setenv("APP_BAR", "2") + for _, test := range int64FlagTests { + flag := IntFlag{Name: test.name, EnvVar: "APP_BAR"} + output := flag.String() + + expectedSuffix := " [$APP_BAR]" + if runtime.GOOS == "windows" { + expectedSuffix = " [%APP_BAR%]" + } + if !strings.HasSuffix(output, expectedSuffix) { + t.Errorf("%s does not end with"+expectedSuffix, output) + } + } +} + +var uintFlagTests = []struct { + name string + expected string +}{ + {"nerfs", "--nerfs value\t(default: 41)"}, + {"N", "-N value\t(default: 41)"}, +} + +func TestUintFlagHelpOutput(t *testing.T) { + for _, test := range uintFlagTests { + flag := UintFlag{Name: test.name, Value: 41} + output := flag.String() + + if output != test.expected { + t.Errorf("%s does not match %s", output, test.expected) + } + } +} + +func TestUintFlagWithEnvVarHelpOutput(t *testing.T) { + os.Clearenv() + os.Setenv("APP_BAR", "2") + for _, test := range uintFlagTests { + flag := UintFlag{Name: test.name, EnvVar: "APP_BAR"} + output := flag.String() + + expectedSuffix := " [$APP_BAR]" + if runtime.GOOS == "windows" { + expectedSuffix = " [%APP_BAR%]" + } + if !strings.HasSuffix(output, expectedSuffix) { + t.Errorf("%s does not end with"+expectedSuffix, output) + } + } +} + +var uint64FlagTests = []struct { + name string + expected string +}{ + {"gerfs", "--gerfs value\t(default: 8589934582)"}, + {"G", "-G value\t(default: 8589934582)"}, +} + +func TestUint64FlagHelpOutput(t *testing.T) { + for _, test := range uint64FlagTests { + flag := Uint64Flag{Name: test.name, Value: 8589934582} + output := flag.String() + + if output != test.expected { + t.Errorf("%s does not match %s", output, test.expected) + } + } +} + +func TestUint64FlagWithEnvVarHelpOutput(t *testing.T) { + os.Clearenv() + os.Setenv("APP_BAR", "2") + for _, test := range uint64FlagTests { + flag := UintFlag{Name: test.name, EnvVar: "APP_BAR"} + output := flag.String() + + expectedSuffix := " [$APP_BAR]" + if runtime.GOOS == "windows" { + expectedSuffix = " [%APP_BAR%]" + } + if !strings.HasSuffix(output, expectedSuffix) { + t.Errorf("%s does not end with"+expectedSuffix, output) + } + } +} + var durationFlagTests = []struct { name string expected string }{ - {"help", "--help \"0\"\t"}, - {"h", "-h \"0\"\t"}, + {"hooting", "--hooting value\t(default: 1s)"}, + {"H", "-H value\t(default: 1s)"}, } func TestDurationFlagHelpOutput(t *testing.T) { - for _, test := range durationFlagTests { - flag := DurationFlag{Name: test.name} + flag := DurationFlag{Name: test.name, Value: 1 * time.Second} output := flag.String() if output != test.expected { - t.Errorf("%s does not match %s", output, test.expected) + t.Errorf("%q does not match %q", output, test.expected) } } } @@ -206,18 +311,17 @@ var intSliceFlagTests = []struct { value *IntSlice expected string }{ - {"help", &IntSlice{}, "--help [--help option --help option]\t"}, - {"h", &IntSlice{}, "-h [-h option -h option]\t"}, - {"h", &IntSlice{}, "-h [-h option -h option]\t"}, - {"test", func() *IntSlice { + {"heads", &IntSlice{}, "--heads value\t"}, + {"H", &IntSlice{}, "-H value\t"}, + {"H, heads", func() *IntSlice { i := &IntSlice{} i.Set("9") + i.Set("3") return i - }(), "--test [--test option --test option]\t"}, + }(), "-H value, --heads value\t(default: 9, 3)"}, } func TestIntSliceFlagHelpOutput(t *testing.T) { - for _, test := range intSliceFlagTests { flag := IntSliceFlag{Name: test.name, Value: test.value} output := flag.String() @@ -245,22 +349,64 @@ func TestIntSliceFlagWithEnvVarHelpOutput(t *testing.T) { } } +var int64SliceFlagTests = []struct { + name string + value *Int64Slice + expected string +}{ + {"heads", &Int64Slice{}, "--heads value\t"}, + {"H", &Int64Slice{}, "-H value\t"}, + {"H, heads", func() *Int64Slice { + i := &Int64Slice{} + i.Set("2") + i.Set("17179869184") + return i + }(), "-H value, --heads value\t(default: 2, 17179869184)"}, +} + +func TestInt64SliceFlagHelpOutput(t *testing.T) { + for _, test := range int64SliceFlagTests { + flag := Int64SliceFlag{Name: test.name, Value: test.value} + output := flag.String() + + if output != test.expected { + t.Errorf("%q does not match %q", output, test.expected) + } + } +} + +func TestInt64SliceFlagWithEnvVarHelpOutput(t *testing.T) { + os.Clearenv() + os.Setenv("APP_SMURF", "42,17179869184") + for _, test := range int64SliceFlagTests { + flag := Int64SliceFlag{Name: test.name, Value: test.value, EnvVar: "APP_SMURF"} + output := flag.String() + + expectedSuffix := " [$APP_SMURF]" + if runtime.GOOS == "windows" { + expectedSuffix = " [%APP_SMURF%]" + } + if !strings.HasSuffix(output, expectedSuffix) { + t.Errorf("%q does not end with"+expectedSuffix, output) + } + } +} + var float64FlagTests = []struct { name string expected string }{ - {"help", "--help \"0\"\t"}, - {"h", "-h \"0\"\t"}, + {"hooting", "--hooting value\t(default: 0.1)"}, + {"H", "-H value\t(default: 0.1)"}, } func TestFloat64FlagHelpOutput(t *testing.T) { - for _, test := range float64FlagTests { - flag := Float64Flag{Name: test.name} + flag := Float64Flag{Name: test.name, Value: float64(0.1)} output := flag.String() if output != test.expected { - t.Errorf("%s does not match %s", output, test.expected) + t.Errorf("%q does not match %q", output, test.expected) } } } @@ -287,12 +433,11 @@ var genericFlagTests = []struct { value Generic expected string }{ - {"test", &Parser{"abc", "def"}, "--test \"abc,def\"\ttest flag"}, - {"t", &Parser{"abc", "def"}, "-t \"abc,def\"\ttest flag"}, + {"toads", &Parser{"abc", "def"}, "--toads value\ttest flag (default: abc,def)"}, + {"t", &Parser{"abc", "def"}, "-t value\ttest flag (default: abc,def)"}, } func TestGenericFlagHelpOutput(t *testing.T) { - for _, test := range genericFlagTests { flag := GenericFlag{Name: test.name, Value: test.value, Usage: "test flag"} output := flag.String() @@ -325,13 +470,14 @@ func TestParseMultiString(t *testing.T) { Flags: []Flag{ StringFlag{Name: "serve, s"}, }, - Action: func(ctx *Context) { + Action: func(ctx *Context) error { if ctx.String("serve") != "10" { t.Errorf("main name not set") } if ctx.String("s") != "10" { t.Errorf("short name not set") } + return nil }, }).Run([]string{"run", "-s", "10"}) } @@ -345,10 +491,11 @@ func TestParseDestinationString(t *testing.T) { Destination: &dest, }, }, - Action: func(ctx *Context) { + Action: func(ctx *Context) error { if dest != "10" { t.Errorf("expected destination String 10") } + return nil }, } a.Run([]string{"run", "--dest", "10"}) @@ -361,13 +508,14 @@ func TestParseMultiStringFromEnv(t *testing.T) { Flags: []Flag{ StringFlag{Name: "count, c", EnvVar: "APP_COUNT"}, }, - Action: func(ctx *Context) { + Action: func(ctx *Context) error { if ctx.String("count") != "20" { t.Errorf("main name not set") } if ctx.String("c") != "20" { t.Errorf("short name not set") } + return nil }, }).Run([]string{"run"}) } @@ -379,13 +527,14 @@ func TestParseMultiStringFromEnvCascade(t *testing.T) { Flags: []Flag{ StringFlag{Name: "count, c", EnvVar: "COMPAT_COUNT,APP_COUNT"}, }, - Action: func(ctx *Context) { + Action: func(ctx *Context) error { if ctx.String("count") != "20" { t.Errorf("main name not set") } if ctx.String("c") != "20" { t.Errorf("short name not set") } + return nil }, }).Run([]string{"run"}) } @@ -395,13 +544,14 @@ func TestParseMultiStringSlice(t *testing.T) { Flags: []Flag{ StringSliceFlag{Name: "serve, s", Value: &StringSlice{}}, }, - Action: func(ctx *Context) { + Action: func(ctx *Context) error { if !reflect.DeepEqual(ctx.StringSlice("serve"), []string{"10", "20"}) { t.Errorf("main name not set") } if !reflect.DeepEqual(ctx.StringSlice("s"), []string{"10", "20"}) { t.Errorf("short name not set") } + return nil }, }).Run([]string{"run", "-s", "10", "-s", "20"}) } @@ -414,13 +564,14 @@ func TestParseMultiStringSliceFromEnv(t *testing.T) { Flags: []Flag{ StringSliceFlag{Name: "intervals, i", Value: &StringSlice{}, EnvVar: "APP_INTERVALS"}, }, - Action: func(ctx *Context) { + Action: func(ctx *Context) error { if !reflect.DeepEqual(ctx.StringSlice("intervals"), []string{"20", "30", "40"}) { t.Errorf("main name not set from env") } if !reflect.DeepEqual(ctx.StringSlice("i"), []string{"20", "30", "40"}) { t.Errorf("short name not set from env") } + return nil }, }).Run([]string{"run"}) } @@ -433,13 +584,14 @@ func TestParseMultiStringSliceFromEnvCascade(t *testing.T) { Flags: []Flag{ StringSliceFlag{Name: "intervals, i", Value: &StringSlice{}, EnvVar: "COMPAT_INTERVALS,APP_INTERVALS"}, }, - Action: func(ctx *Context) { + Action: func(ctx *Context) error { if !reflect.DeepEqual(ctx.StringSlice("intervals"), []string{"20", "30", "40"}) { t.Errorf("main name not set from env") } if !reflect.DeepEqual(ctx.StringSlice("i"), []string{"20", "30", "40"}) { t.Errorf("short name not set from env") } + return nil }, }).Run([]string{"run"}) } @@ -449,13 +601,14 @@ func TestParseMultiInt(t *testing.T) { Flags: []Flag{ IntFlag{Name: "serve, s"}, }, - Action: func(ctx *Context) { + Action: func(ctx *Context) error { if ctx.Int("serve") != 10 { t.Errorf("main name not set") } if ctx.Int("s") != 10 { t.Errorf("short name not set") } + return nil }, } a.Run([]string{"run", "-s", "10"}) @@ -470,10 +623,11 @@ func TestParseDestinationInt(t *testing.T) { Destination: &dest, }, }, - Action: func(ctx *Context) { + Action: func(ctx *Context) error { if dest != 10 { t.Errorf("expected destination Int 10") } + return nil }, } a.Run([]string{"run", "--dest", "10"}) @@ -486,13 +640,14 @@ func TestParseMultiIntFromEnv(t *testing.T) { Flags: []Flag{ IntFlag{Name: "timeout, t", EnvVar: "APP_TIMEOUT_SECONDS"}, }, - Action: func(ctx *Context) { + Action: func(ctx *Context) error { if ctx.Int("timeout") != 10 { t.Errorf("main name not set") } if ctx.Int("t") != 10 { t.Errorf("short name not set") } + return nil }, } a.Run([]string{"run"}) @@ -505,13 +660,14 @@ func TestParseMultiIntFromEnvCascade(t *testing.T) { Flags: []Flag{ IntFlag{Name: "timeout, t", EnvVar: "COMPAT_TIMEOUT_SECONDS,APP_TIMEOUT_SECONDS"}, }, - Action: func(ctx *Context) { + Action: func(ctx *Context) error { if ctx.Int("timeout") != 10 { t.Errorf("main name not set") } if ctx.Int("t") != 10 { t.Errorf("short name not set") } + return nil }, } a.Run([]string{"run"}) @@ -522,13 +678,14 @@ func TestParseMultiIntSlice(t *testing.T) { Flags: []Flag{ IntSliceFlag{Name: "serve, s", Value: &IntSlice{}}, }, - Action: func(ctx *Context) { + Action: func(ctx *Context) error { if !reflect.DeepEqual(ctx.IntSlice("serve"), []int{10, 20}) { t.Errorf("main name not set") } if !reflect.DeepEqual(ctx.IntSlice("s"), []int{10, 20}) { t.Errorf("short name not set") } + return nil }, }).Run([]string{"run", "-s", "10", "-s", "20"}) } @@ -541,13 +698,14 @@ func TestParseMultiIntSliceFromEnv(t *testing.T) { Flags: []Flag{ IntSliceFlag{Name: "intervals, i", Value: &IntSlice{}, EnvVar: "APP_INTERVALS"}, }, - Action: func(ctx *Context) { + Action: func(ctx *Context) error { if !reflect.DeepEqual(ctx.IntSlice("intervals"), []int{20, 30, 40}) { t.Errorf("main name not set from env") } if !reflect.DeepEqual(ctx.IntSlice("i"), []int{20, 30, 40}) { t.Errorf("short name not set from env") } + return nil }, }).Run([]string{"run"}) } @@ -560,13 +718,71 @@ func TestParseMultiIntSliceFromEnvCascade(t *testing.T) { Flags: []Flag{ IntSliceFlag{Name: "intervals, i", Value: &IntSlice{}, EnvVar: "COMPAT_INTERVALS,APP_INTERVALS"}, }, - Action: func(ctx *Context) { + Action: func(ctx *Context) error { if !reflect.DeepEqual(ctx.IntSlice("intervals"), []int{20, 30, 40}) { t.Errorf("main name not set from env") } if !reflect.DeepEqual(ctx.IntSlice("i"), []int{20, 30, 40}) { t.Errorf("short name not set from env") } + return nil + }, + }).Run([]string{"run"}) +} + +func TestParseMultiInt64Slice(t *testing.T) { + (&App{ + Flags: []Flag{ + Int64SliceFlag{Name: "serve, s", Value: &Int64Slice{}}, + }, + Action: func(ctx *Context) error { + if !reflect.DeepEqual(ctx.Int64Slice("serve"), []int64{10, 17179869184}) { + t.Errorf("main name not set") + } + if !reflect.DeepEqual(ctx.Int64Slice("s"), []int64{10, 17179869184}) { + t.Errorf("short name not set") + } + return nil + }, + }).Run([]string{"run", "-s", "10", "-s", "17179869184"}) +} + +func TestParseMultiInt64SliceFromEnv(t *testing.T) { + os.Clearenv() + os.Setenv("APP_INTERVALS", "20,30,17179869184") + + (&App{ + Flags: []Flag{ + Int64SliceFlag{Name: "intervals, i", Value: &Int64Slice{}, EnvVar: "APP_INTERVALS"}, + }, + Action: func(ctx *Context) error { + if !reflect.DeepEqual(ctx.Int64Slice("intervals"), []int64{20, 30, 17179869184}) { + t.Errorf("main name not set from env") + } + if !reflect.DeepEqual(ctx.Int64Slice("i"), []int64{20, 30, 17179869184}) { + t.Errorf("short name not set from env") + } + return nil + }, + }).Run([]string{"run"}) +} + +func TestParseMultiInt64SliceFromEnvCascade(t *testing.T) { + os.Clearenv() + os.Setenv("APP_INTERVALS", "20,30,17179869184") + + (&App{ + Flags: []Flag{ + Int64SliceFlag{Name: "intervals, i", Value: &Int64Slice{}, EnvVar: "COMPAT_INTERVALS,APP_INTERVALS"}, + }, + Action: func(ctx *Context) error { + if !reflect.DeepEqual(ctx.Int64Slice("intervals"), []int64{20, 30, 17179869184}) { + t.Errorf("main name not set from env") + } + if !reflect.DeepEqual(ctx.Int64Slice("i"), []int64{20, 30, 17179869184}) { + t.Errorf("short name not set from env") + } + return nil }, }).Run([]string{"run"}) } @@ -576,13 +792,14 @@ func TestParseMultiFloat64(t *testing.T) { Flags: []Flag{ Float64Flag{Name: "serve, s"}, }, - Action: func(ctx *Context) { + Action: func(ctx *Context) error { if ctx.Float64("serve") != 10.2 { t.Errorf("main name not set") } if ctx.Float64("s") != 10.2 { t.Errorf("short name not set") } + return nil }, } a.Run([]string{"run", "-s", "10.2"}) @@ -597,10 +814,11 @@ func TestParseDestinationFloat64(t *testing.T) { Destination: &dest, }, }, - Action: func(ctx *Context) { + Action: func(ctx *Context) error { if dest != 10.2 { t.Errorf("expected destination Float64 10.2") } + return nil }, } a.Run([]string{"run", "--dest", "10.2"}) @@ -613,13 +831,14 @@ func TestParseMultiFloat64FromEnv(t *testing.T) { Flags: []Flag{ Float64Flag{Name: "timeout, t", EnvVar: "APP_TIMEOUT_SECONDS"}, }, - Action: func(ctx *Context) { + Action: func(ctx *Context) error { if ctx.Float64("timeout") != 15.5 { t.Errorf("main name not set") } if ctx.Float64("t") != 15.5 { t.Errorf("short name not set") } + return nil }, } a.Run([]string{"run"}) @@ -632,13 +851,14 @@ func TestParseMultiFloat64FromEnvCascade(t *testing.T) { Flags: []Flag{ Float64Flag{Name: "timeout, t", EnvVar: "COMPAT_TIMEOUT_SECONDS,APP_TIMEOUT_SECONDS"}, }, - Action: func(ctx *Context) { + Action: func(ctx *Context) error { if ctx.Float64("timeout") != 15.5 { t.Errorf("main name not set") } if ctx.Float64("t") != 15.5 { t.Errorf("short name not set") } + return nil }, } a.Run([]string{"run"}) @@ -649,13 +869,14 @@ func TestParseMultiBool(t *testing.T) { Flags: []Flag{ BoolFlag{Name: "serve, s"}, }, - Action: func(ctx *Context) { + Action: func(ctx *Context) error { if ctx.Bool("serve") != true { t.Errorf("main name not set") } if ctx.Bool("s") != true { t.Errorf("short name not set") } + return nil }, } a.Run([]string{"run", "--serve"}) @@ -670,10 +891,11 @@ func TestParseDestinationBool(t *testing.T) { Destination: &dest, }, }, - Action: func(ctx *Context) { + Action: func(ctx *Context) error { if dest != true { t.Errorf("expected destination Bool true") } + return nil }, } a.Run([]string{"run", "--dest"}) @@ -686,13 +908,14 @@ func TestParseMultiBoolFromEnv(t *testing.T) { Flags: []Flag{ BoolFlag{Name: "debug, d", EnvVar: "APP_DEBUG"}, }, - Action: func(ctx *Context) { + Action: func(ctx *Context) error { if ctx.Bool("debug") != true { t.Errorf("main name not set from env") } if ctx.Bool("d") != true { t.Errorf("short name not set from env") } + return nil }, } a.Run([]string{"run"}) @@ -705,13 +928,14 @@ func TestParseMultiBoolFromEnvCascade(t *testing.T) { Flags: []Flag{ BoolFlag{Name: "debug, d", EnvVar: "COMPAT_DEBUG,APP_DEBUG"}, }, - Action: func(ctx *Context) { + Action: func(ctx *Context) error { if ctx.Bool("debug") != true { t.Errorf("main name not set from env") } if ctx.Bool("d") != true { t.Errorf("short name not set from env") } + return nil }, } a.Run([]string{"run"}) @@ -722,13 +946,14 @@ func TestParseMultiBoolT(t *testing.T) { Flags: []Flag{ BoolTFlag{Name: "serve, s"}, }, - Action: func(ctx *Context) { + Action: func(ctx *Context) error { if ctx.BoolT("serve") != true { t.Errorf("main name not set") } if ctx.BoolT("s") != true { t.Errorf("short name not set") } + return nil }, } a.Run([]string{"run", "--serve"}) @@ -743,10 +968,11 @@ func TestParseDestinationBoolT(t *testing.T) { Destination: &dest, }, }, - Action: func(ctx *Context) { + Action: func(ctx *Context) error { if dest != true { t.Errorf("expected destination BoolT true") } + return nil }, } a.Run([]string{"run", "--dest"}) @@ -759,13 +985,14 @@ func TestParseMultiBoolTFromEnv(t *testing.T) { Flags: []Flag{ BoolTFlag{Name: "debug, d", EnvVar: "APP_DEBUG"}, }, - Action: func(ctx *Context) { + Action: func(ctx *Context) error { if ctx.BoolT("debug") != false { t.Errorf("main name not set from env") } if ctx.BoolT("d") != false { t.Errorf("short name not set from env") } + return nil }, } a.Run([]string{"run"}) @@ -778,13 +1005,14 @@ func TestParseMultiBoolTFromEnvCascade(t *testing.T) { Flags: []Flag{ BoolTFlag{Name: "debug, d", EnvVar: "COMPAT_DEBUG,APP_DEBUG"}, }, - Action: func(ctx *Context) { + Action: func(ctx *Context) error { if ctx.BoolT("debug") != false { t.Errorf("main name not set from env") } if ctx.BoolT("d") != false { t.Errorf("short name not set from env") } + return nil }, } a.Run([]string{"run"}) @@ -813,13 +1041,14 @@ func TestParseGeneric(t *testing.T) { Flags: []Flag{ GenericFlag{Name: "serve, s", Value: &Parser{}}, }, - Action: func(ctx *Context) { + Action: func(ctx *Context) error { if !reflect.DeepEqual(ctx.Generic("serve"), &Parser{"10", "20"}) { t.Errorf("main name not set") } if !reflect.DeepEqual(ctx.Generic("s"), &Parser{"10", "20"}) { t.Errorf("short name not set") } + return nil }, } a.Run([]string{"run", "-s", "10,20"}) @@ -832,13 +1061,14 @@ func TestParseGenericFromEnv(t *testing.T) { Flags: []Flag{ GenericFlag{Name: "serve, s", Value: &Parser{}, EnvVar: "APP_SERVE"}, }, - Action: func(ctx *Context) { + Action: func(ctx *Context) error { if !reflect.DeepEqual(ctx.Generic("serve"), &Parser{"20", "30"}) { t.Errorf("main name not set from env") } if !reflect.DeepEqual(ctx.Generic("s"), &Parser{"20", "30"}) { t.Errorf("short name not set from env") } + return nil }, } a.Run([]string{"run"}) @@ -851,10 +1081,11 @@ func TestParseGenericFromEnvCascade(t *testing.T) { Flags: []Flag{ GenericFlag{Name: "foos", Value: &Parser{}, EnvVar: "COMPAT_FOO,APP_FOO"}, }, - Action: func(ctx *Context) { + Action: func(ctx *Context) error { if !reflect.DeepEqual(ctx.Generic("foos"), &Parser{"99", "2000"}) { t.Errorf("value not set from env") } + return nil }, } a.Run([]string{"run"}) diff --git a/vendor/github.com/codegangsta/cli/funcs.go b/vendor/github.com/codegangsta/cli/funcs.go new file mode 100644 index 000000000..cba5e6cb0 --- /dev/null +++ b/vendor/github.com/codegangsta/cli/funcs.go @@ -0,0 +1,28 @@ +package cli + +// BashCompleteFunc is an action to execute when the bash-completion flag is set +type BashCompleteFunc func(*Context) + +// BeforeFunc is an action to execute before any subcommands are run, but after +// the context is ready if a non-nil error is returned, no subcommands are run +type BeforeFunc func(*Context) error + +// AfterFunc is an action to execute after any subcommands are run, but after the +// subcommand has finished it is run even if Action() panics +type AfterFunc func(*Context) error + +// ActionFunc is the action to execute when no subcommands are specified +type ActionFunc func(*Context) error + +// CommandNotFoundFunc is executed if the proper command cannot be found +type CommandNotFoundFunc func(*Context, string) + +// OnUsageErrorFunc is executed if an usage error occurs. This is useful for displaying +// customized usage error messages. This function is able to replace the +// original error messages. If this function is not set, the "Incorrect usage" +// is displayed and the execution is interrupted. +type OnUsageErrorFunc func(context *Context, err error, isSubcommand bool) error + +// FlagStringFunc is used by the help generation to display a flag, which is +// expected to be a single line. +type FlagStringFunc func(Flag) string diff --git a/vendor/github.com/codegangsta/cli/help.go b/vendor/github.com/codegangsta/cli/help.go index adf157df1..0f4cf14cd 100644 --- a/vendor/github.com/codegangsta/cli/help.go +++ b/vendor/github.com/codegangsta/cli/help.go @@ -3,73 +3,74 @@ package cli import ( "fmt" "io" + "os" "strings" "text/tabwriter" "text/template" ) -// The text template for the Default help topic. +// AppHelpTemplate is the text template for the Default help topic. // cli.go uses text/template to render templates. You can // render custom help text by setting this variable. var AppHelpTemplate = `NAME: {{.Name}} - {{.Usage}} USAGE: - {{if .UsageText}}{{.UsageText}}{{else}}{{.HelpName}} {{if .Flags}}[global options]{{end}}{{if .Commands}} command [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{end}} + {{if .UsageText}}{{.UsageText}}{{else}}{{.HelpName}} {{if .VisibleFlags}}[global options]{{end}}{{if .Commands}} command [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{end}} {{if .Version}}{{if not .HideVersion}} VERSION: {{.Version}} {{end}}{{end}}{{if len .Authors}} AUTHOR(S): - {{range .Authors}}{{ . }}{{end}} - {{end}}{{if .Commands}} -COMMANDS:{{range .Categories}}{{if .Name}} - {{.Name}}{{ ":" }}{{end}}{{range .Commands}} - {{.Name}}{{with .ShortName}}, {{.}}{{end}}{{ "\t" }}{{.Usage}}{{end}} -{{end}}{{end}}{{if .Flags}} + {{range .Authors}}{{.}}{{end}} + {{end}}{{if .VisibleCommands}} +COMMANDS:{{range .VisibleCategories}}{{if .Name}} + {{.Name}}:{{end}}{{range .VisibleCommands}} + {{join .Names ", "}}{{"\t"}}{{.Usage}}{{end}} +{{end}}{{end}}{{if .VisibleFlags}} GLOBAL OPTIONS: - {{range .Flags}}{{.}} - {{end}}{{end}}{{if .Copyright }} + {{range .VisibleFlags}}{{.}} + {{end}}{{end}}{{if .Copyright}} COPYRIGHT: {{.Copyright}} {{end}} ` -// The text template for the command help topic. +// CommandHelpTemplate is the text template for the command help topic. // cli.go uses text/template to render templates. You can // render custom help text by setting this variable. var CommandHelpTemplate = `NAME: {{.HelpName}} - {{.Usage}} USAGE: - {{.HelpName}}{{if .Flags}} [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{if .Category}} + {{.HelpName}}{{if .VisibleFlags}} [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{if .Category}} CATEGORY: {{.Category}}{{end}}{{if .Description}} DESCRIPTION: - {{.Description}}{{end}}{{if .Flags}} + {{.Description}}{{end}}{{if .VisibleFlags}} OPTIONS: - {{range .Flags}}{{.}} - {{end}}{{ end }} + {{range .VisibleFlags}}{{.}} + {{end}}{{end}} ` -// The text template for the subcommand help topic. +// SubcommandHelpTemplate is the text template for the subcommand help topic. // cli.go uses text/template to render templates. You can // render custom help text by setting this variable. var SubcommandHelpTemplate = `NAME: {{.HelpName}} - {{.Usage}} USAGE: - {{.HelpName}} command{{if .Flags}} [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}} + {{.HelpName}} command{{if .VisibleFlags}} [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}} -COMMANDS:{{range .Categories}}{{if .Name}} - {{.Name}}{{ ":" }}{{end}}{{range .Commands}} - {{.Name}}{{with .ShortName}}, {{.}}{{end}}{{ "\t" }}{{.Usage}}{{end}} -{{end}}{{if .Flags}} +COMMANDS:{{range .VisibleCategories}}{{if .Name}} + {{.Name}}:{{end}}{{range .VisibleCommands}} + {{join .Names ", "}}{{"\t"}}{{.Usage}}{{end}} +{{end}}{{if .VisibleFlags}} OPTIONS: - {{range .Flags}}{{.}} + {{range .VisibleFlags}}{{.}} {{end}}{{end}} ` @@ -78,13 +79,14 @@ var helpCommand = Command{ Aliases: []string{"h"}, Usage: "Shows a list of commands or help for one command", ArgsUsage: "[command]", - Action: func(c *Context) { + Action: func(c *Context) error { args := c.Args() if args.Present() { - ShowCommandHelp(c, args.First()) - } else { - ShowAppHelp(c) + return ShowCommandHelp(c, args.First()) } + + ShowAppHelp(c) + return nil }, } @@ -93,65 +95,74 @@ var helpSubcommand = Command{ Aliases: []string{"h"}, Usage: "Shows a list of commands or help for one command", ArgsUsage: "[command]", - Action: func(c *Context) { + Action: func(c *Context) error { args := c.Args() if args.Present() { - ShowCommandHelp(c, args.First()) - } else { - ShowSubcommandHelp(c) + return ShowCommandHelp(c, args.First()) } + + return ShowSubcommandHelp(c) }, } // Prints help for the App or Command type helpPrinter func(w io.Writer, templ string, data interface{}) +// HelpPrinter is a function that writes the help output. If not set a default +// is used. The function signature is: +// func(w io.Writer, templ string, data interface{}) var HelpPrinter helpPrinter = printHelp -// Prints version for the App +// VersionPrinter prints the version for the App var VersionPrinter = printVersion -func ShowAppHelp(c *Context) { +// ShowAppHelp is an action that displays the help. +func ShowAppHelp(c *Context) error { HelpPrinter(c.App.Writer, AppHelpTemplate, c.App) + return nil } -// Prints the list of subcommands as the default app completion method +// DefaultAppComplete prints the list of subcommands as the default app completion method func DefaultAppComplete(c *Context) { for _, command := range c.App.Commands { + if command.Hidden { + continue + } for _, name := range command.Names() { fmt.Fprintln(c.App.Writer, name) } } } -// Prints help for the given command -func ShowCommandHelp(ctx *Context, command string) { +// ShowCommandHelp prints help for the given command +func ShowCommandHelp(ctx *Context, command string) error { // show the subcommand help for a command with subcommands if command == "" { HelpPrinter(ctx.App.Writer, SubcommandHelpTemplate, ctx.App) - return + return nil } for _, c := range ctx.App.Commands { if c.HasName(command) { HelpPrinter(ctx.App.Writer, CommandHelpTemplate, c) - return + return nil } } - if ctx.App.CommandNotFound != nil { - ctx.App.CommandNotFound(ctx, command) - } else { - fmt.Fprintf(ctx.App.Writer, "No help topic for '%v'\n", command) + if ctx.App.CommandNotFound == nil { + return NewExitError(fmt.Sprintf("No help topic for '%v'", command), 3) } + + ctx.App.CommandNotFound(ctx, command) + return nil } -// Prints help for the given subcommand -func ShowSubcommandHelp(c *Context) { - ShowCommandHelp(c, c.Command.Name) +// ShowSubcommandHelp prints help for the given subcommand +func ShowSubcommandHelp(c *Context) error { + return ShowCommandHelp(c, c.Command.Name) } -// Prints the version number of the App +// ShowVersion prints the version number of the App func ShowVersion(c *Context) { VersionPrinter(c) } @@ -160,7 +171,7 @@ func printVersion(c *Context) { fmt.Fprintf(c.App.Writer, "%v version %v\n", c.App.Name, c.App.Version) } -// Prints the lists of commands within a given context +// ShowCompletions prints the lists of commands within a given context func ShowCompletions(c *Context) { a := c.App if a != nil && a.BashComplete != nil { @@ -168,7 +179,7 @@ func ShowCompletions(c *Context) { } } -// Prints the custom completions for a given command +// ShowCommandCompletions prints the custom completions for a given command func ShowCommandCompletions(ctx *Context, command string) { c := ctx.App.Command(command) if c != nil && c.BashComplete != nil { @@ -181,12 +192,15 @@ func printHelp(out io.Writer, templ string, data interface{}) { "join": strings.Join, } - w := tabwriter.NewWriter(out, 0, 8, 1, '\t', 0) + w := tabwriter.NewWriter(out, 1, 8, 2, ' ', 0) t := template.Must(template.New("help").Funcs(funcMap).Parse(templ)) err := t.Execute(w, data) if err != nil { // If the writer is closed, t.Execute will fail, and there's nothing - // we can do to recover. We could send this to os.Stderr if we need. + // we can do to recover. + if os.Getenv("CLI_TEMPLATE_ERROR_DEBUG") != "" { + fmt.Fprintf(ErrWriter, "CLI TEMPLATE ERROR: %#v\n", err) + } return } w.Flush() diff --git a/vendor/github.com/codegangsta/cli/help_test.go b/vendor/github.com/codegangsta/cli/help_test.go index 0821f48ae..7c1540000 100644 --- a/vendor/github.com/codegangsta/cli/help_test.go +++ b/vendor/github.com/codegangsta/cli/help_test.go @@ -2,6 +2,8 @@ package cli import ( "bytes" + "flag" + "strings" "testing" ) @@ -66,10 +68,11 @@ func Test_Help_Custom_Flags(t *testing.T) { Flags: []Flag{ BoolFlag{Name: "foo, h"}, }, - Action: func(ctx *Context) { + Action: func(ctx *Context) error { if ctx.Bool("h") != true { t.Errorf("custom help flag not set") } + return nil }, } output := new(bytes.Buffer) @@ -95,10 +98,11 @@ func Test_Version_Custom_Flags(t *testing.T) { Flags: []Flag{ BoolFlag{Name: "foo, v"}, }, - Action: func(ctx *Context) { + Action: func(ctx *Context) error { if ctx.Bool("v") != true { t.Errorf("custom version flag not set") } + return nil }, } output := new(bytes.Buffer) @@ -108,3 +112,178 @@ func Test_Version_Custom_Flags(t *testing.T) { t.Errorf("unexpected output: %s", output.String()) } } + +func Test_helpCommand_Action_ErrorIfNoTopic(t *testing.T) { + app := NewApp() + + set := flag.NewFlagSet("test", 0) + set.Parse([]string{"foo"}) + + c := NewContext(app, set, nil) + + err := helpCommand.Action.(func(*Context) error)(c) + + if err == nil { + t.Fatalf("expected error from helpCommand.Action(), but got nil") + } + + exitErr, ok := err.(*ExitError) + if !ok { + t.Fatalf("expected ExitError from helpCommand.Action(), but instead got: %v", err.Error()) + } + + if !strings.HasPrefix(exitErr.Error(), "No help topic for") { + t.Fatalf("expected an unknown help topic error, but got: %v", exitErr.Error()) + } + + if exitErr.exitCode != 3 { + t.Fatalf("expected exit value = 3, got %d instead", exitErr.exitCode) + } +} + +func Test_helpCommand_InHelpOutput(t *testing.T) { + app := NewApp() + output := &bytes.Buffer{} + app.Writer = output + app.Run([]string{"test", "--help"}) + + s := output.String() + + if strings.Contains(s, "\nCOMMANDS:\nGLOBAL OPTIONS:\n") { + t.Fatalf("empty COMMANDS section detected: %q", s) + } + + if !strings.Contains(s, "help, h") { + t.Fatalf("missing \"help, h\": %q", s) + } +} + +func Test_helpSubcommand_Action_ErrorIfNoTopic(t *testing.T) { + app := NewApp() + + set := flag.NewFlagSet("test", 0) + set.Parse([]string{"foo"}) + + c := NewContext(app, set, nil) + + err := helpSubcommand.Action.(func(*Context) error)(c) + + if err == nil { + t.Fatalf("expected error from helpCommand.Action(), but got nil") + } + + exitErr, ok := err.(*ExitError) + if !ok { + t.Fatalf("expected ExitError from helpCommand.Action(), but instead got: %v", err.Error()) + } + + if !strings.HasPrefix(exitErr.Error(), "No help topic for") { + t.Fatalf("expected an unknown help topic error, but got: %v", exitErr.Error()) + } + + if exitErr.exitCode != 3 { + t.Fatalf("expected exit value = 3, got %d instead", exitErr.exitCode) + } +} + +func TestShowAppHelp_CommandAliases(t *testing.T) { + app := &App{ + Commands: []Command{ + { + Name: "frobbly", + Aliases: []string{"fr", "frob"}, + Action: func(ctx *Context) error { + return nil + }, + }, + }, + } + + output := &bytes.Buffer{} + app.Writer = output + app.Run([]string{"foo", "--help"}) + + if !strings.Contains(output.String(), "frobbly, fr, frob") { + t.Errorf("expected output to include all command aliases; got: %q", output.String()) + } +} + +func TestShowCommandHelp_CommandAliases(t *testing.T) { + app := &App{ + Commands: []Command{ + { + Name: "frobbly", + Aliases: []string{"fr", "frob", "bork"}, + Action: func(ctx *Context) error { + return nil + }, + }, + }, + } + + output := &bytes.Buffer{} + app.Writer = output + app.Run([]string{"foo", "help", "fr"}) + + if !strings.Contains(output.String(), "frobbly") { + t.Errorf("expected output to include command name; got: %q", output.String()) + } + + if strings.Contains(output.String(), "bork") { + t.Errorf("expected output to exclude command aliases; got: %q", output.String()) + } +} + +func TestShowSubcommandHelp_CommandAliases(t *testing.T) { + app := &App{ + Commands: []Command{ + { + Name: "frobbly", + Aliases: []string{"fr", "frob", "bork"}, + Action: func(ctx *Context) error { + return nil + }, + }, + }, + } + + output := &bytes.Buffer{} + app.Writer = output + app.Run([]string{"foo", "help"}) + + if !strings.Contains(output.String(), "frobbly, fr, frob, bork") { + t.Errorf("expected output to include all command aliases; got: %q", output.String()) + } +} + +func TestShowAppHelp_HiddenCommand(t *testing.T) { + app := &App{ + Commands: []Command{ + { + Name: "frobbly", + Action: func(ctx *Context) error { + return nil + }, + }, + { + Name: "secretfrob", + Hidden: true, + Action: func(ctx *Context) error { + return nil + }, + }, + }, + } + + output := &bytes.Buffer{} + app.Writer = output + app.Run([]string{"app", "--help"}) + + if strings.Contains(output.String(), "secretfrob") { + t.Errorf("expected output to exclude \"secretfrob\"; got: %q", output.String()) + } + + if !strings.Contains(output.String(), "frobbly") { + t.Errorf("expected output to include \"frobbly\"; got: %q", output.String()) + } +} diff --git a/vendor/github.com/codegangsta/cli/helpers_test.go b/vendor/github.com/codegangsta/cli/helpers_test.go index b1b7339f2..109ea7ad9 100644 --- a/vendor/github.com/codegangsta/cli/helpers_test.go +++ b/vendor/github.com/codegangsta/cli/helpers_test.go @@ -1,14 +1,23 @@ package cli import ( + "os" "reflect" + "runtime" + "strings" "testing" ) -/* Test Helpers */ +var ( + wd, _ = os.Getwd() +) + func expect(t *testing.T, a interface{}, b interface{}) { + _, fn, line, _ := runtime.Caller(1) + fn = strings.Replace(fn, wd+"/", "", -1) + if !reflect.DeepEqual(a, b) { - t.Errorf("Expected %v (type %v) - Got %v (type %v)", b, reflect.TypeOf(b), a, reflect.TypeOf(a)) + t.Errorf("(%s:%d) Expected %v (type %v) - Got %v (type %v)", fn, line, b, reflect.TypeOf(b), a, reflect.TypeOf(a)) } } diff --git a/vendor/github.com/codegangsta/cli/runtests b/vendor/github.com/codegangsta/cli/runtests new file mode 100755 index 000000000..0a7b483e3 --- /dev/null +++ b/vendor/github.com/codegangsta/cli/runtests @@ -0,0 +1,105 @@ +#!/usr/bin/env python +from __future__ import print_function + +import argparse +import os +import sys +import tempfile + +from subprocess import check_call, check_output + + +PACKAGE_NAME = os.environ.get( + 'CLI_PACKAGE_NAME', 'github.com/urfave/cli' +) + + +def main(sysargs=sys.argv[:]): + targets = { + 'vet': _vet, + 'test': _test, + 'gfmxr': _gfmxr, + 'toc': _toc, + } + + parser = argparse.ArgumentParser() + parser.add_argument( + 'target', nargs='?', choices=tuple(targets.keys()), default='test' + ) + args = parser.parse_args(sysargs[1:]) + + targets[args.target]() + return 0 + + +def _test(): + if check_output('go version'.split()).split()[2] < 'go1.2': + _run('go test -v .'.split()) + return + + coverprofiles = [] + for subpackage in ['', 'altsrc']: + coverprofile = 'cli.coverprofile' + if subpackage != '': + coverprofile = '{}.coverprofile'.format(subpackage) + + coverprofiles.append(coverprofile) + + _run('go test -v'.split() + [ + '-coverprofile={}'.format(coverprofile), + ('{}/{}'.format(PACKAGE_NAME, subpackage)).rstrip('/') + ]) + + combined_name = _combine_coverprofiles(coverprofiles) + _run('go tool cover -func={}'.format(combined_name).split()) + os.remove(combined_name) + + +def _gfmxr(): + _run(['gfmxr', '-c', str(_gfmxr_count()), '-s', 'README.md']) + + +def _vet(): + _run('go vet ./...'.split()) + + +def _toc(): + _run(['node_modules/.bin/markdown-toc', '-i', 'README.md']) + _run(['git', 'diff', '--quiet']) + + +def _run(command): + print('runtests: {}'.format(' '.join(command)), file=sys.stderr) + check_call(command) + + +def _gfmxr_count(): + with open('README.md') as infile: + lines = infile.read().splitlines() + return len(filter(_is_go_runnable, lines)) + + +def _is_go_runnable(line): + return line.startswith('package main') + + +def _combine_coverprofiles(coverprofiles): + combined = tempfile.NamedTemporaryFile( + suffix='.coverprofile', delete=False + ) + combined.write('mode: set\n') + + for coverprofile in coverprofiles: + with open(coverprofile, 'r') as infile: + for line in infile.readlines(): + if not line.startswith('mode: '): + combined.write(line) + + combined.flush() + name = combined.name + combined.close() + return name + + +if __name__ == '__main__': + sys.exit(main()) diff --git a/vendor/github.com/go-ole/go-ole/example/libreoffice/libreoffice.go b/vendor/github.com/go-ole/go-ole/example/libreoffice/libreoffice.go new file mode 100644 index 000000000..3a1d92871 --- /dev/null +++ b/vendor/github.com/go-ole/go-ole/example/libreoffice/libreoffice.go @@ -0,0 +1,162 @@ +// +build windows + +/* + Demonstrates basic LibreOffce (OpenOffice) automation with OLE using GO-OLE. + Usage: cd [...]\go-ole\example\libreoffice + go run libreoffice.go + References: + http://www.openoffice.org/api/basic/man/tutorial/tutorial.pdf + http://api.libreoffice.org/examples/examples.html#OLE_examples + https://wiki.openoffice.org/wiki/Documentation/BASIC_Guide + + Tested environment: + go 1.6.2 (windows/amd64) + LibreOffice 5.1.0.3 (32 bit) + Windows 10 (64 bit) + + The MIT License (MIT) + Copyright (c) 2016 Sebastian Schleemilch . + + Permission is hereby granted, free of charge, to any person obtaining a copy of + this software and associated documentation files (the "Software"), to deal in + the Software without restriction, including without limitation the rights to use, + copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, + and to permit persons to whom the Software is furnished to do so, subject to the + following conditions: + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR + PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE + OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +package main + +import ( + "fmt" + "log" + + ole "github.com/go-ole/go-ole" + "github.com/go-ole/go-ole/oleutil" +) + +func checkError(err error, msg string) { + if err != nil { + log.Fatal(msg) + } +} + +// LOGetCell returns an handle to a cell within a worksheet +// LibreOffice Basic: GetCell = oSheet.getCellByPosition (nColumn , nRow) +func LOGetCell(worksheet *ole.IDispatch, nColumn int, nRow int) (cell *ole.IDispatch) { + return oleutil.MustCallMethod(worksheet, "getCellByPosition", nColumn, nRow).ToIDispatch() +} + +// LOGetCellRangeByName returns a named range (e.g. "A1:B4") +func LOGetCellRangeByName(worksheet *ole.IDispatch, rangeName string) (cells *ole.IDispatch) { + return oleutil.MustCallMethod(worksheet, "getCellRangeByName", rangeName).ToIDispatch() +} + +// LOGetCellString returns the displayed value +func LOGetCellString(cell *ole.IDispatch) (value string) { + return oleutil.MustGetProperty(cell, "string").ToString() +} + +// LOGetCellValue returns the cell's internal value (not formatted, dummy code, FIXME) +func LOGetCellValue(cell *ole.IDispatch) (value string) { + val := oleutil.MustGetProperty(cell, "value") + fmt.Printf("Cell: %+v\n", val) + return val.ToString() +} + +// LOGetCellError returns the error value of a cell (dummy code, FIXME) +func LOGetCellError(cell *ole.IDispatch) (result *ole.VARIANT) { + return oleutil.MustGetProperty(cell, "error") +} + +// LOSetCellString sets the text value of a cell +func LOSetCellString(cell *ole.IDispatch, text string) { + oleutil.MustPutProperty(cell, "string", text) +} + +// LOSetCellValue sets the numeric value of a cell +func LOSetCellValue(cell *ole.IDispatch, value float64) { + oleutil.MustPutProperty(cell, "value", value) +} + +// LOSetCellFormula sets the formula (in englisch language) +func LOSetCellFormula(cell *ole.IDispatch, formula string) { + oleutil.MustPutProperty(cell, "formula", formula) +} + +// LOSetCellFormulaLocal sets the formula in the user's language (e.g. German =SUMME instead of =SUM) +func LOSetCellFormulaLocal(cell *ole.IDispatch, formula string) { + oleutil.MustPutProperty(cell, "FormulaLocal", formula) +} + +// LONewSpreadsheet creates a new spreadsheet in a new window and returns a document handle. +func LONewSpreadsheet(desktop *ole.IDispatch) (document *ole.IDispatch) { + var args = []string{} + document = oleutil.MustCallMethod(desktop, + "loadComponentFromURL", "private:factory/scalc", // alternative: private:factory/swriter + "_blank", 0, args).ToIDispatch() + return +} + +// LOOpenFile opens a file (text, spreadsheet, ...) in a new window and returns a document +// handle. Example: /home/testuser/spreadsheet.ods +func LOOpenFile(desktop *ole.IDispatch, fullpath string) (document *ole.IDispatch) { + var args = []string{} + document = oleutil.MustCallMethod(desktop, + "loadComponentFromURL", "file://"+fullpath, + "_blank", 0, args).ToIDispatch() + return +} + +// LOSaveFile saves the current document. +// Only works if a file already exists, +// see https://wiki.openoffice.org/wiki/Saving_a_document +func LOSaveFile(document *ole.IDispatch) { + // use storeAsURL if neccessary with third URL parameter + oleutil.MustCallMethod(document, "store") +} + +// LOGetWorksheet returns a worksheet (index starts at 0) +func LOGetWorksheet(document *ole.IDispatch, index int) (worksheet *ole.IDispatch) { + sheets := oleutil.MustGetProperty(document, "Sheets").ToIDispatch() + worksheet = oleutil.MustCallMethod(sheets, "getByIndex", index).ToIDispatch() + return +} + +// This example creates a new spreadsheet, reads and modifies cell values and style. +func main() { + ole.CoInitialize(0) + unknown, errCreate := oleutil.CreateObject("com.sun.star.ServiceManager") + checkError(errCreate, "Couldn't create a OLE connection to LibreOffice") + ServiceManager, errSM := unknown.QueryInterface(ole.IID_IDispatch) + checkError(errSM, "Couldn't start a LibreOffice instance") + desktop := oleutil.MustCallMethod(ServiceManager, + "createInstance", "com.sun.star.frame.Desktop").ToIDispatch() + + document := LONewSpreadsheet(desktop) + sheet0 := LOGetWorksheet(document, 0) + + cell1_1 := LOGetCell(sheet0, 1, 1) // cell B2 + cell1_2 := LOGetCell(sheet0, 1, 2) // cell B3 + cell1_3 := LOGetCell(sheet0, 1, 3) // cell B4 + cell1_4 := LOGetCell(sheet0, 1, 4) // cell B5 + LOSetCellString(cell1_1, "Hello World") + LOSetCellValue(cell1_2, 33.45) + LOSetCellFormula(cell1_3, "=B3+5") + b4Value := LOGetCellString(cell1_3) + LOSetCellString(cell1_4, b4Value) + // set background color yellow: + oleutil.MustPutProperty(cell1_1, "cellbackcolor", 0xFFFF00) + + fmt.Printf("Press [ENTER] to exit") + fmt.Scanf("%s") + ServiceManager.Release() + ole.CoUninitialize() +} diff --git a/vendor/github.com/gopherjs/gopherjs/README.md b/vendor/github.com/gopherjs/gopherjs/README.md index ab6dd6afe..8f7e38179 100644 --- a/vendor/github.com/gopherjs/gopherjs/README.md +++ b/vendor/github.com/gopherjs/gopherjs/README.md @@ -6,7 +6,7 @@ GopherJS - A compiler from Go to JavaScript GopherJS compiles Go code ([golang.org](https://golang.org/)) to pure JavaScript code. Its main purpose is to give you the opportunity to write front-end code in Go which will still run in all browsers. Give GopherJS a try on the [GopherJS Playground](http://gopherjs.github.io/playground/). ### What is supported? -Nearly everything, including Goroutines ([compatibility table](https://github.com/gopherjs/gopherjs/blob/master/doc/packages.md)). Performance is quite good in most cases, see [HTML5 game engine benchmark](http://ajhager.github.io/enj/). +Nearly everything, including Goroutines ([compatibility table](https://github.com/gopherjs/gopherjs/blob/master/doc/packages.md)). Performance is quite good in most cases, see [HTML5 game engine benchmark](https://ajhager.github.io/engi/demos/botmark.html). ### Installation and Usage Get or update GopherJS and dependencies with: diff --git a/vendor/github.com/gopherjs/gopherjs/build/build.go b/vendor/github.com/gopherjs/gopherjs/build/build.go index 1bbeda493..4f037220b 100644 --- a/vendor/github.com/gopherjs/gopherjs/build/build.go +++ b/vendor/github.com/gopherjs/gopherjs/build/build.go @@ -8,9 +8,11 @@ import ( "go/scanner" "go/token" "go/types" + "io" "io/ioutil" "os" "os/exec" + "path" "path/filepath" "strconv" "strings" @@ -18,6 +20,7 @@ import ( "github.com/fsnotify/fsnotify" "github.com/gopherjs/gopherjs/compiler" + "github.com/gopherjs/gopherjs/compiler/natives" "github.com/kardianos/osext" "github.com/neelance/sourcemap" ) @@ -132,10 +135,18 @@ func ImportDir(dir string, mode build.ImportMode) (*PackageData, error) { return &PackageData{Package: pkg, JSFiles: jsFiles}, nil } -// parse parses and returns all .go files of given pkg. +// parseAndAugment parses and returns all .go files of given pkg. // Standard Go library packages are augmented with files in compiler/natives folder. -// isTest is true when package is being built for running tests. -func parse(pkg *build.Package, isTest bool, fileSet *token.FileSet) ([]*ast.File, error) { +// If isTest is true and pkg.ImportPath has no _test suffix, package is built for running internal tests. +// If isTest is true and pkg.ImportPath has _test suffix, package is built for running external tests. +// +// The native packages are augmented by the contents of natives.FS in the following way. +// The file names do not matter except the usual `_test` suffix. The files for +// native overrides get added to the package (even if they have the same name +// as an existing file from the standard library). For all identifiers that exist +// in the original AND the overrides, the original identifier in the AST gets +// replaced by `_`. New identifiers that don't exist in original package get added. +func parseAndAugment(pkg *build.Package, isTest bool, fileSet *token.FileSet) ([]*ast.File, error) { var files []*ast.File replacedDeclNames := make(map[string]bool) funcName := func(d *ast.FuncDecl) string { @@ -153,7 +164,48 @@ func parse(pkg *build.Package, isTest bool, fileSet *token.FileSet) ([]*ast.File if isXTest { importPath = importPath[:len(importPath)-5] } - if nativesPkg, err := Import("github.com/gopherjs/gopherjs/compiler/natives/"+importPath, 0, "", nil); err == nil { + + nativesContext := &build.Context{ + GOROOT: "/", + GOOS: build.Default.GOOS, + GOARCH: "js", + Compiler: "gc", + JoinPath: path.Join, + SplitPathList: func(list string) []string { + if list == "" { + return nil + } + return strings.Split(list, "/") + }, + IsAbsPath: path.IsAbs, + IsDir: func(name string) bool { + dir, err := natives.FS.Open(name) + if err != nil { + return false + } + defer dir.Close() + info, err := dir.Stat() + if err != nil { + return false + } + return info.IsDir() + }, + HasSubdir: func(root, name string) (rel string, ok bool) { + panic("not implemented") + }, + ReadDir: func(name string) (fi []os.FileInfo, err error) { + dir, err := natives.FS.Open(name) + if err != nil { + return nil, err + } + defer dir.Close() + return dir.Readdir(0) + }, + OpenFile: func(name string) (r io.ReadCloser, err error) { + return natives.FS.Open(name) + }, + } + if nativesPkg, err := nativesContext.Import(importPath, "", 0); err == nil { names := nativesPkg.GoFiles if isTest { names = append(names, nativesPkg.TestGoFiles...) @@ -162,10 +214,16 @@ func parse(pkg *build.Package, isTest bool, fileSet *token.FileSet) ([]*ast.File names = nativesPkg.XTestGoFiles } for _, name := range names { - file, err := parser.ParseFile(fileSet, filepath.Join(nativesPkg.Dir, name), nil, parser.ParseComments) + fullPath := path.Join(nativesPkg.Dir, name) + r, err := nativesContext.OpenFile(fullPath) + if err != nil { + panic(err) + } + file, err := parser.ParseFile(fileSet, fullPath, r, parser.ParseComments) if err != nil { panic(err) } + r.Close() for _, decl := range file.Decls { switch d := decl.(type) { case *ast.FuncDecl: @@ -455,7 +513,7 @@ func (s *Session) BuildPackage(pkg *PackageData) (*compiler.Archive, error) { if importedPkgPath == "unsafe" || ignored { continue } - pkg, _, err := s.buildImportPathWithSrcDir(importedPkgPath, "") + pkg, _, err := s.buildImportPathWithSrcDir(importedPkgPath, pkg.Dir) if err != nil { return nil, err } @@ -500,7 +558,7 @@ func (s *Session) BuildPackage(pkg *PackageData) (*compiler.Archive, error) { } fileSet := token.NewFileSet() - files, err := parse(pkg.Package, pkg.IsTest, fileSet) + files, err := parseAndAugment(pkg.Package, pkg.IsTest, fileSet) if err != nil { return nil, err } diff --git a/vendor/github.com/gopherjs/gopherjs/circle.yml b/vendor/github.com/gopherjs/gopherjs/circle.yml index bc6599c43..52db9c108 100644 --- a/vendor/github.com/gopherjs/gopherjs/circle.yml +++ b/vendor/github.com/gopherjs/gopherjs/circle.yml @@ -1,12 +1,12 @@ machine: node: - version: 5.1.0 + version: 6.2.2 environment: SOURCE_MAP_SUPPORT: false dependencies: pre: - - cd /usr/local && sudo rm -rf go && curl https://storage.googleapis.com/golang/go1.6.linux-amd64.tar.gz | sudo tar -xz && sudo chmod a+w go/src/path/filepath + - cd /usr/local && sudo rm -rf go && curl https://storage.googleapis.com/golang/go1.6.2.linux-amd64.tar.gz | sudo tar -xz && sudo chmod a+w go/src/path/filepath post: - mv ./gopherjs $HOME/bin - npm install --global node-gyp @@ -17,5 +17,113 @@ test: - diff -u <(echo -n) <(gofmt -d .) - go tool vet *.go # Go package in root directory. - for d in */; do echo $d; done | grep -v tests/ | grep -v third_party/ | xargs go tool vet # All subdirectories except "tests", "third_party". - - gopherjs test --short --minify github.com/gopherjs/gopherjs/tests github.com/gopherjs/gopherjs/tests/main github.com/gopherjs/gopherjs/js archive/tar archive/zip bufio bytes compress/bzip2 compress/flate compress/gzip compress/lzw compress/zlib container/heap container/list container/ring crypto/aes crypto/cipher crypto/des crypto/dsa crypto/ecdsa crypto/elliptic crypto/hmac crypto/md5 crypto/rand crypto/rc4 crypto/rsa crypto/sha1 crypto/sha256 crypto/sha512 crypto/subtle crypto/x509 database/sql database/sql/driver debug/dwarf debug/elf debug/macho debug/pe encoding/ascii85 encoding/asn1 encoding/base32 encoding/base64 encoding/binary encoding/csv encoding/gob encoding/hex encoding/json encoding/pem encoding/xml errors expvar flag fmt go/ast go/constant go/doc go/format go/parser go/printer go/scanner go/token hash/adler32 hash/crc32 hash/crc64 hash/fnv html html/template image image/color image/draw image/gif image/jpeg image/png index/suffixarray io io/ioutil math math/big math/cmplx math/rand mime mime/multipart mime/quotedprintable net/http/cookiejar net/http/fcgi net/mail net/rpc/jsonrpc net/textproto net/url path path/filepath reflect regexp regexp/syntax sort strconv strings sync sync/atomic testing/quick text/scanner text/tabwriter text/template text/template/parse time unicode unicode/utf16 unicode/utf8 + - > + gopherjs test --short --minify --run='^Test' + github.com/gopherjs/gopherjs/tests + github.com/gopherjs/gopherjs/tests/main + github.com/gopherjs/gopherjs/js + archive/tar + archive/zip + bufio + bytes + compress/bzip2 + compress/flate + compress/gzip + compress/lzw + compress/zlib + container/heap + container/list + container/ring + crypto/aes + crypto/cipher + crypto/des + crypto/dsa + crypto/ecdsa + crypto/elliptic + crypto/hmac + crypto/md5 + crypto/rand + crypto/rc4 + crypto/rsa + crypto/sha1 + crypto/sha256 + crypto/sha512 + crypto/subtle + crypto/x509 + database/sql + database/sql/driver + debug/dwarf + debug/elf + debug/macho + debug/pe + encoding/ascii85 + encoding/asn1 + encoding/base32 + encoding/base64 + encoding/binary + encoding/csv + encoding/gob + encoding/hex + encoding/json + encoding/pem + encoding/xml + errors + expvar + flag + fmt + go/ast + go/constant + go/doc + go/format + go/parser + go/printer + go/scanner + go/token + hash/adler32 + hash/crc32 + hash/crc64 + hash/fnv + html + html/template + image + image/color + image/draw + image/gif + image/jpeg + image/png + index/suffixarray + io + io/ioutil + math + math/big + math/cmplx + math/rand + mime + mime/multipart + mime/quotedprintable + net/http/cookiejar + net/http/fcgi + net/mail + net/rpc/jsonrpc + net/textproto + net/url + path + path/filepath + reflect + regexp + regexp/syntax + sort + strconv + strings + sync + sync/atomic + testing/quick + text/scanner + text/tabwriter + text/template + text/template/parse + time + unicode + unicode/utf16 + unicode/utf8 - go test -v -race ./... diff --git a/vendor/github.com/gopherjs/gopherjs/compiler/expressions.go b/vendor/github.com/gopherjs/gopherjs/compiler/expressions.go index f83b9251a..de1e2e002 100644 --- a/vendor/github.com/gopherjs/gopherjs/compiler/expressions.go +++ b/vendor/github.com/gopherjs/gopherjs/compiler/expressions.go @@ -566,8 +566,6 @@ func (c *funcContext) translateExpr(expr ast.Expr) *expression { return c.formatExpr("debugger") case "InternalObject": return c.translateExpr(e.Args[0]) - case "MakeFunc": - return c.formatExpr("(function() { return $externalize(%e(this, new ($sliceType($jsObjectPtr))($global.Array.prototype.slice.call(arguments, []))), $emptyInterface); })", e.Args[0]) } } return c.translateCall(e, sig, c.translateExpr(f)) @@ -591,10 +589,10 @@ func (c *funcContext) translateExpr(expr ast.Expr) *expression { switch sel.Kind() { case types.MethodVal: recv := c.makeReceiver(f) - - if typesutil.IsJsPackage(sel.Obj().Pkg()) { + declaredFuncRecv := sel.Obj().(*types.Func).Type().(*types.Signature).Recv().Type() + if typesutil.IsJsObject(declaredFuncRecv) { globalRef := func(id string) string { - if recv.String() == "$global" && id[0] == '$' { + if recv.String() == "$global" && id[0] == '$' && len(id) > 1 { return id } return recv.String() + "." + id diff --git a/vendor/github.com/gopherjs/gopherjs/compiler/natives/doc.go b/vendor/github.com/gopherjs/gopherjs/compiler/natives/doc.go new file mode 100644 index 000000000..1a97b4c52 --- /dev/null +++ b/vendor/github.com/gopherjs/gopherjs/compiler/natives/doc.go @@ -0,0 +1,8 @@ +// Package natives provides native packages via a virtual filesystem. +// +// See documentation of parseAndAugment in github.com/gopherjs/gopherjs/build +// for explanation of behavior used to augment the native packages using the files +// in src subfolder. +package natives + +//go:generate vfsgendev -source="github.com/gopherjs/gopherjs/compiler/natives".FS diff --git a/vendor/github.com/gopherjs/gopherjs/compiler/natives/fs.go b/vendor/github.com/gopherjs/gopherjs/compiler/natives/fs.go new file mode 100644 index 000000000..afca23f23 --- /dev/null +++ b/vendor/github.com/gopherjs/gopherjs/compiler/natives/fs.go @@ -0,0 +1,29 @@ +// +build dev + +package natives + +import ( + "go/build" + "log" + "net/http" + "os" + "strings" + + "github.com/shurcooL/httpfs/filter" +) + +func importPathToDir(importPath string) string { + p, err := build.Import(importPath, "", build.FindOnly) + if err != nil { + log.Fatalln(err) + } + return p.Dir +} + +// FS is a virtual filesystem that contains native packages. +var FS = filter.Keep( + http.Dir(importPathToDir("github.com/gopherjs/gopherjs/compiler/natives")), + func(path string, fi os.FileInfo) bool { + return path == "/" || path == "/src" || strings.HasPrefix(path, "/src/") + }, +) diff --git a/vendor/github.com/gopherjs/gopherjs/compiler/natives/fs_vfsdata.go b/vendor/github.com/gopherjs/gopherjs/compiler/natives/fs_vfsdata.go new file mode 100644 index 000000000..2a4b4c20c --- /dev/null +++ b/vendor/github.com/gopherjs/gopherjs/compiler/natives/fs_vfsdata.go @@ -0,0 +1,710 @@ +// Code generated by vfsgen; DO NOT EDIT + +// +build !dev + +package natives + +import ( + "bytes" + "compress/gzip" + "fmt" + "io" + "io/ioutil" + "net/http" + "os" + pathpkg "path" + "time" +) + +// FS statically implements the virtual filesystem provided to vfsgen. +var FS = func() http.FileSystem { + mustUnmarshalTextTime := func(text string) time.Time { + var t time.Time + err := t.UnmarshalText([]byte(text)) + if err != nil { + panic(err) + } + return t + } + + fs := _vfsgen_fs{ + "/": &_vfsgen_dirInfo{ + name: "/", + modTime: mustUnmarshalTextTime("2016-07-04T23:28:53Z"), + }, + "/src": &_vfsgen_dirInfo{ + name: "src", + modTime: mustUnmarshalTextTime("2016-06-27T01:43:45Z"), + }, + "/src/bytes": &_vfsgen_dirInfo{ + name: "bytes", + modTime: mustUnmarshalTextTime("2016-06-27T01:43:45Z"), + }, + "/src/bytes/bytes.go": &_vfsgen_compressedFileInfo{ + name: "bytes.go", + modTime: mustUnmarshalTextTime("2016-06-27T01:43:45Z"), + uncompressedSize: 508, + + compressedContent: []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x6c\x90\xc1\x4e\xc3\x30\x0c\x86\xcf\xed\x53\xfc\xdc\x5a\xb1\x69\xf4\x8a\xd6\x1d\x40\x1c\x78\x86\x69\x07\x27\x4b\x51\x20\xa4\x23\x6d\x24\x10\xda\xbb\x13\xa7\xe9\x4a\xa6\x49\x39\xc4\xbf\xed\xdf\x9f\xbd\xd9\xe0\x5e\x78\x6d\x8e\x78\x1f\xca\xf2\x44\xf2\x83\xde\x14\xc4\xcf\xa8\x42\xd8\x79\x2b\xf1\x6a\x8f\xea\xfb\x29\x08\xd5\x80\xfd\x81\x33\x2b\xc8\x58\x51\x43\xdb\x11\xbf\x65\xd1\xf5\x0e\x7a\x05\x81\xc7\x16\x8e\x6c\x30\x18\x58\x2e\x74\x17\xb4\xb6\x0d\xe5\x1c\x15\x4e\x8d\xde\x59\xe8\xf0\x3f\x97\xfc\x92\xb0\x6e\xca\x73\x1a\xf6\xf2\xe5\xc9\x54\xc4\x5e\xd3\xac\x1a\xa2\xef\x0d\xf7\x07\x33\xa3\x6c\x45\x35\xee\xda\xf8\x13\x75\xb4\x4d\x26\x1d\x99\x41\x45\xd7\x44\x23\x17\x1a\x9a\x69\x24\xf7\x8a\xbd\x3e\x64\x40\xa9\x35\x87\x1a\x9d\x57\x17\xac\xe7\xfe\xf3\x44\x4e\xe5\x60\xf9\xf2\x92\x6e\xcc\xd3\xd8\x65\xac\xb3\x79\x33\x4d\x2b\x64\x3c\x19\x03\x25\x3e\xc2\x16\x41\xfc\x5f\xbb\x9e\x8b\xa7\xfc\xee\x3a\xdf\x5c\xc8\x97\x0b\x6d\x6f\x1c\x88\x7d\x96\xf5\x1e\xc2\x6e\x7f\x01\x00\x00\xff\xff\x23\x2d\xfc\x5d\xfc\x01\x00\x00"), + }, + "/src/bytes/bytes_test.go": &_vfsgen_fileInfo{ + name: "bytes_test.go", + modTime: mustUnmarshalTextTime("2016-06-27T01:43:45Z"), + content: []byte("\x2f\x2f\x20\x2b\x62\x75\x69\x6c\x64\x20\x6a\x73\x0a\x0a\x70\x61\x63\x6b\x61\x67\x65\x20\x62\x79\x74\x65\x73\x5f\x74\x65\x73\x74\x0a\x0a\x69\x6d\x70\x6f\x72\x74\x20\x28\x0a\x09\x22\x74\x65\x73\x74\x69\x6e\x67\x22\x0a\x29\x0a\x0a\x66\x75\x6e\x63\x20\x54\x65\x73\x74\x45\x71\x75\x61\x6c\x4e\x65\x61\x72\x50\x61\x67\x65\x42\x6f\x75\x6e\x64\x61\x72\x79\x28\x74\x20\x2a\x74\x65\x73\x74\x69\x6e\x67\x2e\x54\x29\x20\x7b\x0a\x09\x74\x2e\x53\x6b\x69\x70\x28\x29\x0a\x7d\x0a"), + }, + "/src/crypto": &_vfsgen_dirInfo{ + name: "crypto", + modTime: mustUnmarshalTextTime("2016-06-27T01:43:45Z"), + }, + "/src/crypto/rand": &_vfsgen_dirInfo{ + name: "rand", + modTime: mustUnmarshalTextTime("2016-06-27T01:43:45Z"), + }, + "/src/crypto/rand/rand.go": &_vfsgen_compressedFileInfo{ + name: "rand.go", + modTime: mustUnmarshalTextTime("2016-06-27T01:43:45Z"), + uncompressedSize: 1175, + + compressedContent: []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x84\x54\x4d\x6f\xd4\x30\x10\x3d\xaf\x7f\xc5\x10\x10\x4a\xe8\x36\x41\xaa\xda\x43\x51\x91\x4a\x55\x55\xbd\x14\xa8\xf8\x38\x20\x0e\x76\x32\x9b\x78\x9b\xd8\xc1\x76\x36\xac\xaa\xfd\xef\x8c\xe3\x64\xbb\x74\x17\x71\x69\xec\xce\xcc\x7b\x33\x6f\x9e\x37\xcb\xe0\x48\x74\xb2\x2e\x60\x69\x19\x6b\x79\xfe\xc0\x4b\x04\xc3\x55\xc1\x98\x6c\x5a\x6d\x1c\xc4\x6c\x16\xa1\x31\xda\xd8\x88\xd1\xb1\x94\xae\xea\x44\x9a\xeb\x26\x2b\x75\x5b\xa1\x59\xda\xa7\xc3\x92\x72\x12\xc6\x16\x9d\xca\x41\x2a\xe9\xe2\x04\x1e\xd9\xec\x1e\x79\x81\x06\x2e\xe0\xb5\x51\x65\xb8\x3c\x6e\xd8\x86\x31\xb7\x6e\x89\x6c\xfa\x1f\x58\x67\xba\xdc\x51\x28\x00\xc4\x06\xde\x6c\x83\x09\xf8\x6f\x2c\xe0\xc7\x4f\xb1\x76\x98\x40\xac\x88\xc1\xcd\x81\x5a\x83\xa1\xbd\x81\x8a\x1b\xc3\xd7\x70\x7e\x41\xe3\xa4\xb7\xca\xa1\x51\xbc\xfe\x28\x96\x98\xbb\x58\x24\xe9\x0d\xba\x38\x7a\x35\xe4\x44\x09\x9b\xe9\xc5\xc2\xa2\xfb\x4f\x76\x48\x8a\x12\x9f\x10\xd3\x6c\x33\x92\x4c\x18\xdd\x5b\x34\x6c\x96\x9b\x75\xeb\xf4\x88\x70\x53\x6b\xc1\xeb\x50\x16\x02\x9e\x44\x2e\x60\xcc\xba\x18\xb2\xbe\xaa\x02\x17\x52\x61\xe1\xdb\x9d\x00\xf6\xea\x1b\x7b\xb5\x45\xd8\xec\x82\xbc\x38\x00\xb2\x8d\x86\xda\x12\xdd\x3d\x2d\x50\x37\xdf\x78\xdd\xa1\x8d\x92\x83\x45\x33\x45\xac\x35\x2a\x9a\xd4\xdf\x08\x43\xc1\x7b\x38\x3b\x3d\x3d\x39\x0b\x71\x3f\xe8\xe5\x4a\xcb\x02\x3e\x77\xda\xf1\xeb\xdf\x39\x62\x81\xc5\xb5\xd7\x1a\x5c\x45\x12\x28\x10\x6b\x78\xc6\x36\x55\xf6\x15\x2a\x0f\x5f\xba\x0a\xa4\x85\x46\x1b\xa4\x22\xae\x02\xc3\x1c\xb8\x05\xdb\x62\x2e\x17\x92\xfa\x91\x6a\x2a\xab\x9c\x6b\xcf\xb3\xac\xef\xfb\xb4\x3f\x49\xb5\x29\xb3\x2f\xf7\xd9\x77\x14\x41\x8d\xcb\x4f\xb7\xd9\xcb\x70\x3c\x6e\xd0\x55\xba\x38\x3e\x44\xef\x27\x1b\x68\xfc\x6d\xe3\xff\x8c\xf2\x5c\xf1\xba\xde\xd7\x87\x9a\xf1\x8e\x18\xa3\xb6\x13\xc1\x20\x73\x08\xab\x9f\xbe\x47\x2a\x19\x94\x32\xe8\x3a\xa3\x40\xcd\x41\xc9\x9a\x0d\x04\x9b\x60\x8b\x3b\x5d\x60\x4a\xef\xc8\x8b\x69\xf0\x57\x27\x69\xe6\x7d\x6b\x8c\x91\x28\x79\xb7\x4d\xfa\xc7\x52\xcd\xd0\xe5\x07\xb2\xbb\xf5\x38\x63\x36\x19\x71\xa5\x1f\xf0\xc9\x63\x23\xec\x53\xf2\x00\xbd\x53\x7b\x70\xfd\x7f\xcd\x4c\x06\x9f\xef\x96\x4c\x1c\xc1\x1f\xc9\x24\xc1\xee\xfc\x21\xf4\x4c\x84\x31\xf6\x76\x1e\x9e\xa4\x4d\xef\xb0\x9f\x1a\xcd\x3c\x3e\x28\xed\x80\xaf\xb8\xac\xb9\xa8\x91\x16\x4f\xa6\x20\x7b\xa0\x5a\x49\xa3\x55\x83\x8a\x5e\x1a\xfd\x32\xfc\x09\x00\x00\xff\xff\xe9\xf9\x0b\x94\x97\x04\x00\x00"), + }, + "/src/crypto/x509": &_vfsgen_dirInfo{ + name: "x509", + modTime: mustUnmarshalTextTime("2016-06-27T01:43:45Z"), + }, + "/src/crypto/x509/x509.go": &_vfsgen_compressedFileInfo{ + name: "x509.go", + modTime: mustUnmarshalTextTime("2016-06-27T01:43:45Z"), + uncompressedSize: 165, + + compressedContent: []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x34\xcc\xc1\xaa\xc2\x40\x0c\x85\xe1\xf5\xcd\x53\x84\xae\x7a\x55\xac\x1b\x17\xae\xa5\x5b\x11\xfb\x04\x75\x8c\x12\x6d\x27\x25\xc9\x40\x8b\xf8\xee\x8e\x45\xb7\x3f\xe7\x7c\x55\x85\xcb\x73\xe2\xee\x82\x77\x03\x18\xda\xf0\x68\x6f\x84\xe3\x76\xb3\x03\xe0\x7e\x10\x75\x2c\xc4\x0a\x80\x6b\x8a\x01\x39\xb2\x37\x93\x39\xf5\x27\x11\xb7\xf2\x1f\x9f\xf0\x97\x89\x28\x68\x73\x46\xfd\x74\x78\x7d\xf7\x34\x52\x68\x28\x24\x65\x9f\x7e\x8f\x72\xb1\x27\xf5\xa3\x48\xb7\x42\x52\x15\x9d\x11\x25\x4f\x1a\x31\x72\xae\x62\xeb\x5a\xf5\x20\x5e\x8f\x6c\x9e\xb1\x77\x00\x00\x00\xff\xff\x1f\x54\x0e\x6a\xa5\x00\x00\x00"), + }, + "/src/crypto/x509/x509_test.go": &_vfsgen_compressedFileInfo{ + name: "x509_test.go", + modTime: mustUnmarshalTextTime("2016-06-27T01:43:45Z"), + uncompressedSize: 231, + + compressedContent: []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\xd2\xd7\x57\xd0\x4e\x2a\xcd\xcc\x49\x51\xc8\x2a\xe6\xe2\x2a\x48\x4c\xce\x4e\x4c\x4f\x55\xa8\x30\x35\xb0\xe4\xe2\xca\xcc\x2d\xc8\x2f\x2a\x51\x50\x2a\x49\x2d\x2e\xc9\xcc\x4b\x57\xe2\xe2\x4a\x2b\xcd\x4b\x56\x08\x01\x72\x83\x2b\x8b\x4b\x52\x73\x83\xf2\xf3\x4b\x8a\x35\x4a\x14\xb4\xa0\x2a\xf4\x42\x34\x15\xaa\xb9\x38\x4b\xf4\x82\xb3\x33\x0b\x34\x94\xf2\xf2\x15\x8a\xc1\xea\x14\x8a\x40\x0a\x95\x34\xb9\x6a\x31\x8c\x08\x4b\x2d\xca\x4c\xab\x24\xc2\x0c\x34\xdd\x9e\x60\xb7\x11\x63\x39\x58\x23\x20\x00\x00\xff\xff\xc0\x80\xbe\xca\xe7\x00\x00\x00"), + }, + "/src/debug": &_vfsgen_dirInfo{ + name: "debug", + modTime: mustUnmarshalTextTime("2016-06-27T01:43:45Z"), + }, + "/src/debug/elf": &_vfsgen_dirInfo{ + name: "elf", + modTime: mustUnmarshalTextTime("2016-06-27T01:43:45Z"), + }, + "/src/debug/elf/elf_test.go": &_vfsgen_fileInfo{ + name: "elf_test.go", + modTime: mustUnmarshalTextTime("2016-06-27T01:43:45Z"), + content: []byte("\x2f\x2f\x20\x2b\x62\x75\x69\x6c\x64\x20\x6a\x73\x0a\x0a\x70\x61\x63\x6b\x61\x67\x65\x20\x65\x6c\x66\x0a\x0a\x69\x6d\x70\x6f\x72\x74\x20\x22\x74\x65\x73\x74\x69\x6e\x67\x22\x0a\x0a\x66\x75\x6e\x63\x20\x54\x65\x73\x74\x4e\x6f\x53\x65\x63\x74\x69\x6f\x6e\x4f\x76\x65\x72\x6c\x61\x70\x73\x28\x74\x20\x2a\x74\x65\x73\x74\x69\x6e\x67\x2e\x54\x29\x20\x7b\x0a\x09\x74\x2e\x53\x6b\x69\x70\x28\x22\x6e\x6f\x74\x20\x36\x6c\x22\x29\x0a\x7d\x0a"), + }, + "/src/encoding": &_vfsgen_dirInfo{ + name: "encoding", + modTime: mustUnmarshalTextTime("2016-06-27T01:43:45Z"), + }, + "/src/encoding/json": &_vfsgen_dirInfo{ + name: "json", + modTime: mustUnmarshalTextTime("2016-06-27T01:43:45Z"), + }, + "/src/encoding/json/stream_test.go": &_vfsgen_fileInfo{ + name: "stream_test.go", + modTime: mustUnmarshalTextTime("2016-06-27T01:43:45Z"), + content: []byte("\x2f\x2f\x20\x2b\x62\x75\x69\x6c\x64\x20\x6a\x73\x0a\x0a\x70\x61\x63\x6b\x61\x67\x65\x20\x6a\x73\x6f\x6e\x0a\x0a\x69\x6d\x70\x6f\x72\x74\x20\x22\x74\x65\x73\x74\x69\x6e\x67\x22\x0a\x0a\x66\x75\x6e\x63\x20\x54\x65\x73\x74\x48\x54\x54\x50\x44\x65\x63\x6f\x64\x69\x6e\x67\x28\x74\x20\x2a\x74\x65\x73\x74\x69\x6e\x67\x2e\x54\x29\x20\x7b\x0a\x09\x74\x2e\x53\x6b\x69\x70\x28\x22\x6e\x65\x74\x77\x6f\x72\x6b\x20\x61\x63\x63\x65\x73\x73\x20\x69\x73\x20\x6e\x6f\x74\x20\x73\x75\x70\x70\x6f\x72\x74\x65\x64\x20\x62\x79\x20\x47\x6f\x70\x68\x65\x72\x4a\x53\x22\x29\x0a\x7d\x0a"), + }, + "/src/fmt": &_vfsgen_dirInfo{ + name: "fmt", + modTime: mustUnmarshalTextTime("2016-06-27T01:43:45Z"), + }, + "/src/fmt/fmt_test.go": &_vfsgen_fileInfo{ + name: "fmt_test.go", + modTime: mustUnmarshalTextTime("2016-06-27T01:43:45Z"), + content: []byte("\x2f\x2f\x20\x2b\x62\x75\x69\x6c\x64\x20\x6a\x73\x0a\x0a\x70\x61\x63\x6b\x61\x67\x65\x20\x66\x6d\x74\x5f\x74\x65\x73\x74\x0a\x0a\x63\x6f\x6e\x73\x74\x20\x69\x6e\x74\x43\x6f\x75\x6e\x74\x20\x3d\x20\x31\x30\x30\x0a"), + }, + "/src/go": &_vfsgen_dirInfo{ + name: "go", + modTime: mustUnmarshalTextTime("2016-06-27T01:43:45Z"), + }, + "/src/go/token": &_vfsgen_dirInfo{ + name: "token", + modTime: mustUnmarshalTextTime("2016-06-27T01:43:45Z"), + }, + "/src/go/token/token_test.go": &_vfsgen_fileInfo{ + name: "token_test.go", + modTime: mustUnmarshalTextTime("2016-06-27T01:43:45Z"), + content: []byte("\x2f\x2f\x20\x2b\x62\x75\x69\x6c\x64\x20\x6a\x73\x0a\x0a\x70\x61\x63\x6b\x61\x67\x65\x20\x74\x6f\x6b\x65\x6e\x0a\x0a\x69\x6d\x70\x6f\x72\x74\x20\x28\x0a\x09\x22\x74\x65\x73\x74\x69\x6e\x67\x22\x0a\x29\x0a\x0a\x66\x75\x6e\x63\x20\x54\x65\x73\x74\x46\x69\x6c\x65\x53\x65\x74\x52\x61\x63\x65\x28\x74\x20\x2a\x74\x65\x73\x74\x69\x6e\x67\x2e\x54\x29\x20\x7b\x0a\x09\x74\x2e\x53\x6b\x69\x70\x28\x29\x0a\x7d\x0a"), + }, + "/src/io": &_vfsgen_dirInfo{ + name: "io", + modTime: mustUnmarshalTextTime("2016-06-27T01:43:45Z"), + }, + "/src/io/io_test.go": &_vfsgen_fileInfo{ + name: "io_test.go", + modTime: mustUnmarshalTextTime("2016-06-27T01:43:45Z"), + content: []byte("\x2f\x2f\x20\x2b\x62\x75\x69\x6c\x64\x20\x6a\x73\x0a\x0a\x70\x61\x63\x6b\x61\x67\x65\x20\x69\x6f\x5f\x74\x65\x73\x74\x0a\x0a\x69\x6d\x70\x6f\x72\x74\x20\x28\x0a\x09\x22\x74\x65\x73\x74\x69\x6e\x67\x22\x0a\x29\x0a\x0a\x66\x75\x6e\x63\x20\x54\x65\x73\x74\x4d\x75\x6c\x74\x69\x57\x72\x69\x74\x65\x72\x5f\x57\x72\x69\x74\x65\x53\x74\x72\x69\x6e\x67\x53\x69\x6e\x67\x6c\x65\x41\x6c\x6c\x6f\x63\x28\x74\x20\x2a\x74\x65\x73\x74\x69\x6e\x67\x2e\x54\x29\x20\x7b\x0a\x09\x74\x2e\x53\x6b\x69\x70\x28\x29\x0a\x7d\x0a"), + }, + "/src/math": &_vfsgen_dirInfo{ + name: "math", + modTime: mustUnmarshalTextTime("2016-06-27T01:43:45Z"), + }, + "/src/math/big": &_vfsgen_dirInfo{ + name: "big", + modTime: mustUnmarshalTextTime("2016-06-27T01:43:45Z"), + }, + "/src/math/big/big.go": &_vfsgen_compressedFileInfo{ + name: "big.go", + modTime: mustUnmarshalTextTime("2016-06-27T01:43:45Z"), + uncompressedSize: 875, + + compressedContent: []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x94\xd2\xc1\x4e\xc4\x20\x10\x06\xe0\xb3\x3c\xc5\x1c\xbb\xb1\xc9\xae\x8f\xe0\x5d\x8f\x96\x83\x31\xa6\x2d\xb5\xa2\x15\x95\x16\x83\x35\xbe\xbb\x0c\xb0\x14\xb7\xb3\xc9\xee\x6d\xb7\xf9\xff\x2f\xcc\xc0\x76\x0b\x97\x8d\x91\x83\x80\x97\x91\xb1\x8f\xba\x7d\xad\xfb\x0e\x1a\xd9\x33\xf6\x64\x54\x0b\x6f\x66\xe0\xbc\xb0\x25\x7c\x03\x7f\xd7\x62\x03\xc5\x7c\x55\xc2\xbc\x8b\xff\x7e\xd8\x85\xee\x26\xa3\x55\x08\x3e\xf6\x3e\xba\x61\xbf\xa1\x2d\xe4\x17\xb6\x5d\xc3\xee\x32\xe2\xb3\x04\xbd\x02\x7c\x16\x81\x7d\x3a\x29\xb5\x10\x55\x55\xcc\xee\x33\x1a\xf7\x0f\x51\x69\x57\x84\x0f\x3a\x22\x46\x13\x30\x9a\xe6\x34\xc0\x07\x09\x00\x61\xee\xbf\xc6\x76\x36\x0c\x7d\x0c\x7e\xe4\x18\xa7\x2b\x3e\x4d\x29\xcf\x43\x75\xf7\x5f\x19\xc1\x48\x35\xd1\x0a\xa6\x93\x32\x66\x8a\x3e\x4b\xd1\xa4\xe2\x2e\xfd\x1a\x87\x3d\x9c\x6a\xb9\x5f\x02\x4b\xa5\x65\x38\x97\xcf\x77\x7d\x6b\x86\xea\xbc\x7d\x87\x06\xb1\x2d\x7c\x55\x48\x25\xc7\x2a\x88\x3f\xd6\x34\xfd\x28\x93\xab\x0e\xec\x46\x4e\x37\x9d\x2a\xec\xbe\xae\xc0\xef\x6f\x69\x87\x00\xbe\x69\xec\xfc\x05\x00\x00\xff\xff\x99\x66\xd8\x28\x6b\x03\x00\x00"), + }, + "/src/math/big/big_test.go": &_vfsgen_compressedFileInfo{ + name: "big_test.go", + modTime: mustUnmarshalTextTime("2016-06-27T01:43:45Z"), + uncompressedSize: 148, + + compressedContent: []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\xd2\xd7\x57\xd0\x4e\x2a\xcd\xcc\x49\x51\xc8\x2a\xe6\xe2\x2a\x48\x4c\xce\x4e\x4c\x4f\x55\x48\xca\x4c\xe7\xe2\xca\xcc\x2d\xc8\x2f\x2a\x51\x50\x2a\x49\x2d\x2e\xc9\xcc\x4b\x57\xe2\xe2\x4a\x2b\xcd\x4b\x56\x08\x01\x72\x9d\x2a\x81\x82\x1a\x25\x0a\x5a\x50\x39\xbd\x10\x4d\x85\x6a\x2e\xce\x12\xbd\xe0\xec\xcc\x02\x0d\xa5\xa4\xa2\xfc\xec\xd4\x3c\x25\x4d\xae\x5a\x24\x3d\xbe\xf9\x29\xc1\x85\x45\x25\xb8\x75\x15\xe7\xe4\x97\x83\xf5\x00\x02\x00\x00\xff\xff\x9b\x59\x2d\xf0\x94\x00\x00\x00"), + }, + "/src/math/math.go": &_vfsgen_compressedFileInfo{ + name: "math.go", + modTime: mustUnmarshalTextTime("2016-06-27T01:43:45Z"), + uncompressedSize: 4108, + + compressedContent: []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x9c\x57\xdf\x6f\xdb\xb6\x13\x7f\x8e\xfe\x0a\x7e\x8d\x2f\x0a\x69\xf1\x2f\x39\x46\x50\x14\x76\x80\x2e\x5b\xba\x02\x6d\x36\xac\xdd\x5e\x0a\x3f\x50\x32\x65\x2b\x95\x44\x95\xa2\x6a\x79\x6d\xff\xf7\x1d\x49\x51\xa2\x64\xc9\x56\xf6\x12\x58\xbc\xcf\x7d\xee\x07\xef\x8e\x97\xd9\x0c\x5d\x7b\x79\x18\x6d\xd1\x53\x66\x59\x29\xf6\x3f\xe3\x1d\x41\x31\xe6\x7b\xcb\x0a\xe3\x94\x32\x8e\x6c\xeb\x6a\xb4\x0b\xf9\x3e\xf7\xa6\x3e\x8d\x67\x3b\x9a\xee\x09\x7b\xca\xea\x1f\x4f\xd9\xc8\x72\x2c\xeb\x2b\x66\x52\x11\xad\x81\x6b\xfa\x26\xa2\x1e\x8e\xa6\x6f\x08\xb7\x47\xef\xe1\x74\xe4\x48\xc0\x3f\x84\x51\x14\x44\x14\xf3\xdb\x25\x00\xe7\xf2\x30\xa5\xd9\xdb\x24\x80\x4f\x17\xcd\x24\x42\x9e\x26\x64\xa7\x4e\x27\xcd\x63\x9c\x08\x45\x7d\x64\x05\x79\xe2\xa3\xd7\x3e\xcd\xec\x42\x13\x3b\x95\x85\x6f\xd6\x15\x23\x3c\x67\x89\xf4\x6c\x7a\x8f\xa3\xc8\x1e\x61\x00\x8f\xc6\xa8\x70\xa6\x0f\x02\x66\x3b\xd6\x0f\x4d\x93\x85\xc9\x70\x1a\x00\xf7\xd0\x70\xfc\x0c\x1a\x00\xf7\xd3\x2c\xec\x23\xc8\x9e\x41\xb5\x00\xae\x63\x27\xdd\x3d\x09\xa3\xc1\x5e\xf9\x00\xee\xf6\xea\x9e\xa6\xc7\x2c\xdc\x41\x80\x60\xa8\x93\x2d\x0c\x10\xd8\x59\xc1\x1d\x7d\xff\x8e\xdc\x59\x81\xd6\xeb\xf2\x32\x1d\xf4\xbf\x35\xb2\x8f\xb5\xec\x68\xca\x40\x55\x7b\x32\x29\xac\xab\x1f\x95\x5f\x85\x61\x7c\xf8\x35\xf7\xde\xf2\x2f\x61\xdc\xef\x7c\xc9\xb3\x2d\x31\xb5\xd6\xaf\x45\x3a\xd8\x34\x29\xd2\x6e\xd3\x40\xb2\x18\xcc\x92\xd2\x03\xb0\x2c\xfa\x88\x62\xf7\x3c\x13\x51\x90\x5a\x07\x38\x28\x1b\x6c\x3d\x10\xe8\xee\x28\x1e\x18\x70\xdb\x41\x4d\x64\x07\x0c\xfb\xfa\x73\x2c\x2c\xa3\x30\xe1\x8e\x41\x1c\x28\x95\x9a\xe3\xb7\x63\x4a\xb9\x9d\x8e\xd1\x97\x73\xfe\xec\x2b\x54\xad\x09\xb5\x62\x8b\x02\x54\x26\x0c\x9d\xec\x10\x72\x7f\x2f\x7e\xf9\x38\x23\x48\x62\xee\x60\x54\xbc\xaa\xeb\x4a\x4d\x1a\xeb\x6a\x4b\x02\x9c\x47\xdc\x90\xa8\x22\x14\x55\x57\xd9\x11\xd0\x3a\xca\x31\xaa\x8d\x7a\x94\x46\x65\xa5\x07\xa2\x82\xcb\x01\x66\x14\x70\x65\x5c\xd6\xb1\xc6\x95\x23\xad\x8d\x5b\x69\x9c\x4e\x16\x8e\x32\x62\xf8\xf1\x88\x1f\x1b\xd9\x0e\x33\xe9\x41\x23\xbf\xa2\xb3\x82\x4a\xe7\xdd\x56\xa6\xbb\xfb\x56\x9a\xad\x2a\x41\x6b\x31\x51\x0d\xb7\xc4\xa1\xf6\x5c\xe8\x41\x24\xee\x7c\xb1\x6c\x43\xd0\x4f\x9d\xf5\x0a\xd0\x9b\xaa\x6a\x7a\x30\xc0\x3a\x69\xe0\x4c\x73\x2b\x31\xf4\x87\xdb\x9b\x0c\x34\x78\x7d\x6a\xf0\x32\x39\xe8\x9d\x76\xc0\x3b\xba\xeb\x69\x24\x88\xa0\x10\x77\x51\xa0\x6f\x08\x1e\xd7\x03\x65\x9f\x31\xa3\x79\xb2\x45\x01\x65\x88\xa6\x3c\x8c\x43\x78\xb8\x90\x97\xef\xe0\x36\xd0\xdf\x2f\xc7\x88\x91\x98\x7e\x25\x08\x73\x94\xd1\x98\x40\x31\xc1\x2d\x19\x85\x89\x13\xd3\x53\xc3\xc5\x88\xee\xba\xfb\x13\xbc\x73\xe7\xe7\x1b\x3d\x52\x90\xa6\xce\x85\x01\x17\x29\x48\x43\xe7\xc2\x34\x8b\x24\xa2\xd6\x78\x8f\x8b\x8b\xa3\x37\x2e\x31\x86\x56\x78\xe6\xb5\xd1\x5a\x25\xc6\xd0\xa2\xdb\x8b\x5a\xf5\xa2\xa2\x52\xfa\xff\x98\x6e\x45\x4e\x05\xd1\x49\x5a\x81\x30\x68\x4e\x3d\xdd\x5a\xd5\xd1\xe9\x4c\x80\x67\xae\xa7\xf5\x83\x71\x75\xb7\xa0\xe3\xce\xfa\x61\x72\x2c\x5d\xc9\x1a\x7d\xb5\x96\x71\xc1\xa1\xeb\x18\xcd\x3f\x91\x15\x3c\x56\x7d\xab\xfd\x15\x63\xa3\x2b\x68\x61\x55\x63\xfe\xa0\x87\xb3\x0f\xb9\x7c\xbc\x5d\x11\x85\x2d\x7f\xc2\x2e\xf6\xe2\x85\x78\xc2\x1b\x11\x9a\xcf\x78\xe3\x1d\x77\x7b\x4a\x57\x75\x57\x77\x9a\xff\x24\x31\x0e\x93\x2d\x61\x17\x6f\x8f\x35\x90\x35\xc3\x07\x18\xaa\x5e\xc8\xcd\xd2\xd4\x13\x5b\x6f\x14\x9d\xeb\x89\x41\x30\x7c\x7f\xeb\xdd\x02\x81\xa4\xb5\x95\xc2\xb3\x95\x8c\x11\x1c\x36\x0a\xa6\xa4\x94\x36\x9d\xb1\x5a\x71\x0c\x96\x2f\x8c\x0f\xf7\x05\xc0\xdd\xce\x7c\x7c\xc6\x46\xda\xbb\x90\x7e\x64\xf0\xf7\xdc\xdc\x6b\x14\x85\x91\x58\xf5\x29\xa7\x62\x3b\xe7\x66\xb5\x34\x96\xbe\x92\xdb\x86\x61\x08\xf9\x90\x4e\x88\xf5\xdf\xcb\x03\x94\x71\x96\xfb\x5c\x68\xe6\x20\xbd\x59\x60\xc6\xf0\x11\xa1\x4f\x8b\x8d\xfa\x86\x5e\x11\xca\x5a\x00\xe7\xe5\x77\x29\xb8\x5d\x96\x02\x77\x53\x7e\x57\x21\x86\x49\x28\x9e\x10\xa0\xc6\x9e\x68\xb6\xd6\x7f\x32\xaf\x85\xde\xcf\x79\x10\x10\x36\x72\xa6\x8f\xe4\x60\xbf\x84\x36\x04\xd0\xdb\x84\x13\x96\xe0\xe8\x77\xef\x89\xf8\xdc\x06\x2f\x9d\xe9\x07\xa1\x61\x78\x08\x49\x6d\xd1\xfd\x25\x85\x92\xb4\xa4\xc3\x9e\x73\x81\xd0\x0c\xed\x94\xf1\x41\x49\xff\x03\x65\x99\x94\x1e\xca\xdb\xe5\x09\xa5\xb1\x56\x0a\x93\xd0\x70\x99\x9e\x8e\x37\x0b\x07\xa9\xc0\x45\x26\xc1\xd0\xd4\xf4\xfa\xd3\x7c\x83\xc4\xb2\xa2\x6f\x5a\xc8\x8d\x34\x81\xb8\xcd\x1d\x30\x1a\x4b\x7e\xaf\xa4\x75\xb4\x1d\xcd\xdf\xd4\x07\x7a\xaf\x41\xdf\x32\xdf\xe4\xbf\x5d\x9a\xbe\x8b\xba\x16\x6c\xaa\xac\x2b\xe5\x32\x3d\x6d\xdf\x15\xd2\x6e\xbb\xe0\x6e\x9c\xd5\x0a\xbc\xbb\xee\x03\xcc\x37\x4e\xdb\x89\x56\x90\xad\xfe\xea\x0c\x52\x1d\xd8\x9e\x73\x2a\x77\x4d\x39\xba\xbb\x43\x90\xb4\xd3\x94\xd4\x51\x81\x37\xff\x06\x00\x00\xff\xff\x74\xe8\xb2\xb0\x0c\x10\x00\x00"), + }, + "/src/math/rand": &_vfsgen_dirInfo{ + name: "rand", + modTime: mustUnmarshalTextTime("2016-06-27T01:43:45Z"), + }, + "/src/math/rand/rand_test.go": &_vfsgen_fileInfo{ + name: "rand_test.go", + modTime: mustUnmarshalTextTime("2016-06-27T01:43:45Z"), + content: []byte("\x2f\x2f\x20\x2b\x62\x75\x69\x6c\x64\x20\x6a\x73\x0a\x0a\x70\x61\x63\x6b\x61\x67\x65\x20\x72\x61\x6e\x64\x0a\x0a\x69\x6d\x70\x6f\x72\x74\x20\x22\x74\x65\x73\x74\x69\x6e\x67\x22\x0a\x0a\x66\x75\x6e\x63\x20\x54\x65\x73\x74\x46\x6c\x6f\x61\x74\x33\x32\x28\x74\x20\x2a\x74\x65\x73\x74\x69\x6e\x67\x2e\x54\x29\x20\x7b\x0a\x09\x74\x2e\x53\x6b\x69\x70\x28\x22\x73\x6c\x6f\x77\x22\x29\x0a\x7d\x0a"), + }, + "/src/net": &_vfsgen_dirInfo{ + name: "net", + modTime: mustUnmarshalTextTime("2016-06-27T01:43:45Z"), + }, + "/src/net/http": &_vfsgen_dirInfo{ + name: "http", + modTime: mustUnmarshalTextTime("2016-07-04T23:17:35Z"), + }, + "/src/net/http/fetch.go": &_vfsgen_compressedFileInfo{ + name: "fetch.go", + modTime: mustUnmarshalTextTime("2016-07-04T23:18:19Z"), + uncompressedSize: 3821, + + compressedContent: []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x94\x57\xdd\x72\xdb\xb8\x0e\xbe\xb6\x9e\x02\x47\x67\xa6\x95\x52\x47\x6e\xcf\xe9\x74\x76\xb4\xcd\x45\xea\xfe\x6c\x77\xdb\x4d\x27\x49\xf7\x26\x93\xd9\x52\x12\x6d\x31\x96\x49\x85\xa4\xe2\x7a\x32\x7e\xf7\x05\x48\x49\x96\x63\x37\xb3\x75\x1b\x47\x22\x41\x00\x04\xbe\x0f\x40\x26\x13\x78\x96\x35\xa2\x2a\xe0\xc6\x04\x41\xcd\xf2\x05\x9b\x73\x28\xad\xad\x83\x40\x2c\x6b\xa5\x2d\x44\xc1\x28\xe4\x5a\x2b\x6d\x42\x7c\x12\xca\x7f\x4f\x84\x6a\xac\xa8\xe8\xc5\x58\x9d\x2b\x79\x17\x06\xf8\x3c\x17\xb6\x6c\xb2\x24\x57\xcb\xc9\x5c\xd5\x25\xd7\x37\x66\xfb\x70\x83\x1a\xe2\x20\x40\x9b\x78\x84\xb3\xe5\x39\x67\x05\xd7\x80\x76\x2a\xbe\xe4\xd2\x1a\x60\x12\x84\x4a\x68\x7d\x5a\x29\x83\x7b\x2b\xcd\xea\x1a\x7f\xcf\x94\x06\x5a\x66\x59\xc5\x2f\xdc\x61\x50\x33\xe7\xa7\x49\x27\x93\x19\xb7\x79\x99\x98\x9a\xe7\xc9\xaa\x64\x76\x35\x4f\x94\x9e\x4f\x92\xc0\xae\x6b\xbe\x6b\x0b\x5f\x9a\xdc\xc2\x7d\x30\xaa\xb9\x2c\x84\x9c\xc3\xd5\x75\xb6\xb6\x3c\x18\x79\x31\x80\xa3\x1b\x93\x9c\x65\x37\x3c\xb7\xc1\x26\x08\x66\x8d\xcc\x21\xd2\x70\x34\xd4\x12\x3b\x57\xa2\xba\x3d\x1b\x43\x84\x6e\x4b\x3b\x06\x0c\x13\xb8\x50\xc5\x64\x41\xcc\xa0\xe2\x32\xd2\x49\x6b\x2a\x86\x93\x13\x78\x4e\x3b\xa3\x3b\xa6\x29\xae\xa3\x51\x36\x2d\x01\xe0\x04\x96\x6c\xc1\xa3\xbc\xc4\xfb\xb7\x3a\x69\x13\x55\xe1\xf6\x70\xd3\x2b\xc7\x3d\xfa\xd1\x89\x77\x2a\x99\xb2\xaa\x8a\x42\x7c\x2c\xc2\xb8\x7d\xb1\x25\x97\xe1\x98\x94\xd0\x0d\x22\xcd\x4d\x53\xd9\xc1\xdd\x9c\x83\xf8\x41\x1f\xfd\x5e\xf2\x81\xdb\x28\x2c\x94\xe4\xa8\xe3\x8d\x52\x55\xd4\x89\xb4\x6e\xbc\x3e\xa6\xd4\xbc\x3b\x7b\xef\x17\x35\xb7\x8d\x96\xee\x79\xe3\xbe\x33\x2f\x33\xd4\x76\xc7\xaa\x86\xd4\x7d\x94\x96\xeb\x19\xcb\x79\x14\x27\xd1\xe0\x7e\x9b\xa1\x83\xcc\x28\x79\xc0\x41\x04\xcb\xa9\x31\xcd\x92\x1b\x10\xf6\x29\x22\x04\xde\x9e\x7d\x7e\xf7\x3d\xe7\xb5\x15\x4a\x26\xc1\x8e\x83\x1e\xa6\xc9\x9f\x7c\xd5\x2a\xf4\x7e\xe0\x61\x83\xb0\x46\x4f\x10\x3a\x98\x88\x28\xde\x9a\xa7\x27\xc3\x2b\xee\x41\x31\xca\x99\xe1\x90\x41\x7a\x82\xea\xf0\x46\x29\xc9\xf5\x09\xc4\x54\x64\x9d\x0c\xa5\xda\x49\x39\xe3\x5e\xce\x85\x04\x9e\x3b\x1c\x04\x2e\x2e\xf8\x5f\xe2\xa9\x5c\xd5\xeb\xa8\x1e\xc3\x16\x0a\xc1\x8e\xd6\xfe\xf9\x4a\xa6\xd7\x41\xa7\x48\x8e\x41\x8a\xea\x11\x14\x3a\x8e\x60\x9e\xdc\xb5\xc9\x7d\x0c\xd6\xe5\xd9\xd9\xdb\x14\xa6\x4c\x4a\x65\xa1\x50\x60\x4b\x61\x20\xe3\x39\x6b\xd0\xe9\x36\x82\x59\xa5\xf2\x05\x59\xce\x11\x2b\x63\x24\x5d\xd1\xab\x42\x61\x35\xb3\x5c\xba\x2d\x5e\x38\x95\xfe\x73\x27\x18\x7c\x2b\xf8\x0c\x49\x84\x39\xae\x11\x23\xc5\x3a\x69\x8f\x7d\x1b\x43\xd6\x58\xf8\xe0\x88\xfe\xfb\x05\xe4\x8d\xd6\xc8\xe7\x6a\x0d\x25\xf3\xa4\xc6\x14\x72\x58\x61\x71\x00\xd3\xd4\x54\x56\xc8\xbc\x45\xae\x26\x03\x13\x17\x9c\xf7\x94\x7e\xb4\x90\x38\x75\x66\xf2\xff\x5f\x5e\x38\xe7\x7f\xe6\xcc\xcb\xff\xbd\x22\x93\x47\x79\x49\xe9\xdb\x67\xd6\x03\x52\xe5\x4c\xe6\xbc\xda\xa7\xd5\xa3\xac\xea\x49\x05\xff\x39\xc1\xba\x9a\x7c\x95\x18\x37\x21\x79\xd1\x62\x3a\xdf\x07\xab\x23\x4d\x8f\x4e\x70\x89\x7c\x7b\x96\xc2\x5f\x5c\x8b\xd9\xda\x67\x71\xa5\xf4\xc2\x8c\x31\x89\x50\x6b\x95\x61\x25\x5c\x63\x82\xb9\x91\x4f\xad\x8b\x82\x29\x55\x83\x75\x3c\xe3\x68\x7c\xa5\x85\xa5\x2c\x62\xf4\x87\x84\xdc\x27\x02\x20\x70\x8c\x5a\x72\x34\x20\xe7\x9e\x4d\x5b\x66\x3b\x62\x7b\x67\x09\x88\x9e\x31\x71\x8f\xcf\xd7\xc7\x79\x79\x34\xf9\x61\xc8\xb6\x38\xf6\x20\xc6\x3b\xb9\x3a\x7d\xa9\x99\x34\xae\xb3\x08\x02\xe3\xb9\x6a\x64\x71\xa9\x85\x2b\xf3\x84\x08\x5a\xee\x5b\x02\xc6\xac\x31\x84\x95\xf7\x74\x14\x4e\xbf\x7c\x4c\xe0\xa3\xed\x40\x64\xda\xe2\x8e\x02\xa4\x9e\x70\xa9\x24\x11\x58\x15\x82\x9b\xb6\xfe\x3f\x30\xea\x3b\xc0\x7d\xcf\x2a\xcc\xdf\xae\x44\xbc\x75\x09\x13\x73\x0b\x47\xe7\xfc\x16\x91\x83\xeb\x11\x3e\x7a\x0b\xe3\x41\x99\x2f\x1d\x1b\x0d\xc1\x09\x73\xfd\xa1\xc2\xd4\x54\x3e\xdc\xbf\xf9\x1d\x0c\x37\x25\x19\x03\x42\x5d\x6c\xc1\xd7\x63\x70\x95\xd1\x1d\x41\xab\x73\xca\xd8\x6d\xe2\xa5\x1d\x44\x48\xee\xef\x56\x6a\x2b\xd4\x1e\x72\x18\x6a\x8d\xb6\x21\xa7\x1e\x29\x8b\x70\x3c\x50\x1e\xf7\x05\x48\xd5\xd6\x43\xbd\xbe\x32\x2e\xeb\xd7\xa2\xab\xc7\xf7\x1b\x52\x16\x52\xfa\x55\x11\xa6\x9e\x85\xe4\xcb\x67\xb7\x42\x40\x0f\x5b\x4b\xed\x6e\xfb\xe6\x76\x72\xcd\x0b\x4c\x91\x60\x15\xed\x86\x86\x2d\xf9\xb1\xd2\x62\x2e\x1c\x45\x36\x81\xe7\xc1\xad\xab\x14\xc4\x04\xc4\x81\x73\xbe\x07\xf7\x7b\x81\xb0\xc5\x31\x02\xbc\x20\x05\x99\x52\xb7\xc6\xe2\x23\x09\xc7\x3e\xb9\x08\x01\x74\x98\x2a\x59\x9b\xcb\x5e\x56\x33\x5c\x73\xa0\xa1\xfe\x0b\xac\xb8\x23\xe8\xa1\x8f\x9a\x27\xde\xce\xb6\xae\xbc\x69\x66\x58\xba\x2e\x54\xa3\x51\x02\x41\xf6\xf8\xe8\xf0\x5f\x72\xe3\x78\x29\xbe\x0b\xd7\x62\xe8\x6d\xdc\x95\x7c\x3f\xf8\xb8\x21\xe5\x14\x83\xdf\xdd\x90\x02\x8e\xf7\x20\xa1\xc1\x5d\x47\xdd\x76\x57\x2a\x89\xda\x3d\xbe\x60\xd9\xe0\x35\x58\xb5\x62\x6b\x03\x39\x09\xb8\x5b\x7a\x73\x42\xe6\x55\xe3\x1a\x84\x92\x5d\xb1\x18\xb4\x19\xb4\x30\x68\x34\x7b\x76\x70\x09\x13\x7f\x15\x92\xae\xf0\x9a\x3a\x17\x3e\xb8\xac\x10\x4b\xbe\x68\xb5\x14\x86\xef\x62\xd6\x63\xc9\x05\x04\xa1\x44\x0a\xbf\x9e\x7f\xea\x2b\xc5\x18\x50\x1f\x4e\x6f\xfd\xec\x42\x7a\x1e\x8c\x27\x3d\x3f\xc8\xbc\xef\xca\x07\xc7\x97\x78\xc7\x8b\x9f\xaa\xad\x1e\x80\xe4\xb8\xe7\xcb\xfd\xc6\xc7\x64\x5b\xe4\xca\x9e\x75\xed\x85\x94\x7e\xc7\xdc\x95\x9c\x62\xc7\x0e\xc7\x94\x03\xd3\x46\xbe\x20\xcd\xd8\x3d\x95\x14\xd8\x01\xbd\x89\x3f\xf8\x3a\x42\xf1\xdd\xe1\xa1\x75\xe4\x2a\x5f\x50\x70\x3d\x01\xa3\xed\x5a\xcb\xc2\x07\x03\x07\x85\x0f\x8d\x28\xe4\x9f\xb4\x9f\xb8\x9c\x5b\xd7\x85\x10\xde\xaf\x5e\x46\xc7\x2f\xe2\xb6\x79\xe4\x55\x0f\xb6\x76\xb6\x4e\xbe\x30\x6d\x38\xce\x51\xad\x09\x7f\xd3\xa9\x57\x74\xec\x35\x85\x98\xa2\x17\x38\x7c\xbc\x7a\x19\xff\xea\x8e\x9f\x0c\x60\xf8\xc0\x28\x8e\x24\x95\xaf\xf0\xf4\x3d\x98\x7f\xfc\x70\xd3\xa6\x16\xeb\xfe\x93\x2e\xa3\x5e\xcb\x85\x65\xb6\x31\x6d\xa1\x80\x9d\xde\x62\xdc\xd6\xb0\xb5\x3c\x83\x10\xff\x3d\x03\x7f\xe8\x92\x7f\xb7\xd1\xc1\x03\x74\xad\x38\x1e\x0f\x0c\x4c\x55\xc1\xd3\x1f\x1a\x70\xf2\x5e\xdc\x27\xa8\xf7\xc7\x07\xc7\x6f\x4d\x87\x17\x4e\x61\xe7\xfe\x5e\x82\xe8\xd2\x1f\x05\x78\x32\x1c\xae\xee\xfd\x4b\xba\xe3\x81\xe3\x52\x07\xab\x39\xb7\x5e\x34\x8c\xfd\x1c\x3b\x6a\xfb\x44\xda\x07\xe7\xd6\xad\x6f\xd2\x3e\xae\xaf\x8f\x89\x55\x53\xd7\x20\xd3\xae\xc3\x6e\x06\x98\x3f\x3c\x04\xef\xe5\xe7\xd0\xc0\x1b\x4a\x6e\x27\x54\xd5\x52\x5f\x25\x31\x01\x33\x26\x70\x86\x0b\xe3\x7f\xe1\x00\x42\x6f\x6b\xe5\xa0\x68\x5f\xb5\x4f\x33\x6a\xa3\x5d\x0d\x46\xb8\xd6\xca\x18\x81\x7f\x97\xed\x75\xea\x60\xaf\x58\x1d\x70\xb6\x53\xe4\xc7\x06\x72\x37\xd8\x82\xd0\x8f\xd8\x1e\x8e\xe9\x56\x1d\x2d\xf8\xe1\xf8\x47\xc3\xf8\x5e\x91\xdc\xe0\x08\xf2\x4f\x00\x00\x00\xff\xff\x72\xed\xf9\xdc\xed\x0e\x00\x00"), + }, + "/src/net/http/http.go": &_vfsgen_compressedFileInfo{ + name: "http.go", + modTime: mustUnmarshalTextTime("2016-06-27T01:43:45Z"), + uncompressedSize: 3000, + + compressedContent: []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x9c\x56\x6d\x6f\xdb\x36\x10\xfe\x2c\xfd\x8a\x9b\x06\x04\x52\xab\xc8\x0d\x50\x74\x83\x5b\x63\xc8\xdc\xae\x09\xd0\x74\x45\x9a\x02\x05\xba\xa2\xa0\xa5\xb3\xa5\x44\x26\x55\x92\x8a\x9b\x15\xf9\xef\xbb\x23\x25\x59\x76\xbc\x0d\x9b\xf3\x21\x14\x79\xbc\x97\xe7\xee\x9e\xe3\x64\x02\x8f\x17\x6d\x55\x17\x70\x6d\xc2\xb0\x11\xf9\x8d\x58\x21\x94\xd6\x36\x61\x58\xad\x1b\xa5\x2d\xc4\x61\x10\x2d\xda\x65\xa5\x22\x5e\xdc\x59\x34\xbc\x40\xad\x95\x76\xab\x4a\x4d\x2a\xd5\xda\xaa\xe6\x0f\x89\x76\x62\xf1\x9b\x6d\xb4\xb2\xee\x82\xb1\x3a\x57\xf2\x36\x0a\x69\xbd\xaa\x6c\xd9\x2e\xb2\x5c\xad\x27\x2b\xd5\x94\xa8\xaf\xcd\x76\x71\x4d\xca\x92\x30\xbc\x15\x1a\x5e\xe2\x52\xb4\xb5\xbd\xd2\x42\x1a\xe7\xc2\x0c\x96\xad\xcc\xe3\x04\x2e\x55\x2b\x8b\x2b\x5d\x35\x0d\x6a\xf8\x1e\x06\x66\x53\xd9\xbc\xe4\x55\x2e\x0c\x52\x0c\xd9\xeb\x5a\x2d\x44\x9d\xbd\x46\x1b\x47\x4b\xa4\xc3\x28\x81\x1f\x66\x7c\xf2\x41\x16\xb8\xac\x24\x16\x70\x74\xb4\x2f\x79\x89\xa2\x10\x8b\x1a\xdf\x5b\x8d\x62\xfd\xf0\xca\x14\x08\xa8\x5d\x21\xa8\x0c\xb4\x86\xb4\x09\x03\x02\xf2\x12\xf3\x1b\x58\x2a\x0d\xa6\x6d\x9c\xcf\x6a\x09\xc6\x09\x56\x72\x05\x1a\x29\x10\x49\x1e\x2e\x54\x51\xa1\x49\xc1\xa0\x47\xd9\x4c\x27\x13\xe7\x66\x66\x1a\xcc\xb3\x4d\x29\xec\x66\x95\x29\xbd\x9a\xfc\xe8\x6f\x9b\x2c\x0c\x02\x8d\xb6\xd5\x12\x8e\x9c\xe4\x00\xcb\xf7\xfb\xc3\x61\x7f\xbc\x78\x73\x46\xaa\x2f\xf1\x6b\x8b\xc6\x1e\x08\x66\xa4\xf1\xe3\xd9\xe5\x8e\xbe\xc2\x43\x3f\x12\x91\x6a\x47\xe0\x3e\xbc\x8f\x29\x4d\x04\xc7\xe8\x60\xc0\x62\x53\x22\xdd\x40\xca\x33\xe5\xe7\x37\xf6\x16\x4e\xdf\x9d\x93\xa8\x86\x5d\xaf\xdc\xb6\xd0\x08\xe2\x56\x54\x35\xa3\x9a\xc1\xb9\x05\x51\x6f\xc4\x9d\x81\x25\xed\x51\xe0\xf6\xae\xc1\x1d\x33\x04\x49\x9b\xb3\x1b\x21\xd7\x03\xc4\xa3\xb3\x51\x6d\xc4\x1a\xbf\xc2\xa3\xce\x50\x02\x31\x2d\x3d\xfa\x29\xb8\xaa\x4d\xb8\x5e\xfa\xe8\xaa\xba\xdb\x35\xd9\x5b\xdc\xc4\xae\x80\x39\x31\xd3\x21\x0c\x4a\xa4\x8f\xe4\x70\x14\x86\x83\x1f\xa2\x88\x92\x90\xbc\x73\x8e\x8f\xa1\xed\x3c\x67\xc3\x95\x5c\xd6\xd5\xaa\xb4\xb0\x16\xcd\xa7\xde\xcb\xcf\x8f\x28\x41\xbf\x2f\xae\x31\xb7\xe1\x10\x9d\x85\x47\x63\x1d\xff\x35\xc2\x6f\xa5\x86\xe9\xec\xdf\x8a\xc3\x45\x4d\x09\x0d\xaa\x25\xd8\x6c\x70\x6e\x36\x63\x68\x58\x4d\x30\xde\xfd\x3b\xa7\x7d\x65\x8c\x44\x3f\x91\x87\x9f\x49\x9e\x9c\x70\x45\x45\x38\x16\x58\xa3\xc5\x78\x2b\x93\x52\x5b\x7c\x65\xd3\xdc\x1d\xf3\x92\x9d\x5d\x8b\x1b\x8c\xf3\x52\x48\x18\x42\x4a\xc2\x80\x62\xda\x3f\xf6\x61\x86\x2e\xca\xec\x3d\x07\xa6\x64\xad\x44\x11\xa5\x3d\x55\xb0\xeb\x25\x75\x2c\xea\x14\xbe\xf0\xe5\x81\x96\x38\xe4\x4b\x77\x12\x3b\x5e\x1b\x7f\x33\xbd\x8d\xbe\x3f\x7d\xe6\x9d\x98\x8d\xcc\x45\x5d\xc7\xd1\x0a\xed\x69\x5d\xf7\xbe\x9d\x39\x29\x43\x28\x12\x27\x50\x9f\x93\xd9\xc7\x10\xfd\x21\xa3\x84\x7e\x19\xeb\xb8\x38\xbf\x78\xe5\xa5\x08\xe4\x20\xa0\xf6\xbf\x3b\x90\x94\x0f\x95\xb4\x3f\x9f\x6a\x2d\xee\xba\x84\xb0\x41\x77\xd2\x13\x07\x69\xcc\xce\xa5\x45\xbd\x14\x39\xc6\x49\xd6\x79\xc6\x08\x04\xc4\xaf\x16\xa5\x7d\x83\x72\x65\x1d\x4c\xa4\xed\xd9\xd3\xf8\xf8\x84\x2d\x76\x0c\x49\x48\x67\x17\x68\x4b\x55\x38\x60\x1c\x6d\x44\x67\xaf\x4e\x5f\x46\xdc\xea\x9c\x7c\xdf\x07\x7c\xbd\xa3\xec\xec\x9d\xd0\x06\xc9\x68\xec\x61\xf4\x0e\xcd\xbd\xb1\x63\x6f\x2d\x4a\x52\x38\x79\x92\xc2\xb3\xa7\xc9\x73\x77\x7d\x54\x37\xfb\x8e\xcd\xa0\xe6\x5d\x2a\x93\x31\xcb\x3c\x10\xf2\xce\xd7\x28\x63\x06\x2b\xe1\x18\xee\x43\x47\x47\xae\x48\x5e\x1c\xc3\x51\x0f\xbf\xb3\xf2\xde\x0a\xdb\x9a\x29\x74\xbf\x01\x39\xe3\xf6\xf7\x52\x43\x7f\x8f\xf7\x45\xae\xa8\x2e\x46\x62\xe9\x56\xe9\x5c\x15\x38\x3d\xac\x94\x61\xf1\xa2\x3e\xbb\x83\xfd\x2e\xd9\x1e\x32\x2f\x31\x1f\x47\x38\x85\x9d\x80\x9d\xc0\xaf\x14\xe8\xa0\x00\xc0\x4f\xd3\xec\xad\x6a\xe6\xb5\x32\x07\xaa\xd2\x03\xe3\xae\x76\xad\xd8\xdf\xa6\x34\xa7\x0e\xb0\xe0\x7e\xaf\x39\x5c\xc3\xf4\xdd\x81\xb0\x6d\x5d\xdf\x29\xbe\xc5\x08\xdc\xc3\x5c\xb8\x47\x7b\xcc\xcf\x58\x10\xd7\x3d\x30\x23\x16\xc4\x54\xff\xdb\x8c\xee\xf4\xe7\x42\xe6\xb8\x6f\xc1\x37\xa0\x6a\x50\x46\xe9\xa8\x9e\xfd\xfa\xc3\xe5\x9b\x21\x83\xc9\xc8\xa3\xbe\x7f\xae\x88\x91\xe9\x5a\x24\xb8\xc9\xa8\xeb\x89\x90\x68\x30\xd2\x14\x2b\x69\x7c\x5b\x05\x0b\x9a\x44\x4b\x6a\x2f\xf0\x06\xa0\x95\x94\x82\x61\x42\x2f\xda\xd5\x9f\x55\x5d\x8b\x6c\xad\xfc\x7f\x1e\xd0\xa6\x54\x9b\x2f\x74\x92\xe5\xab\xea\x97\xaa\x98\x9d\x9c\x9c\x3c\xf9\xe9\xd9\x09\x8f\x03\xb2\xaa\xea\x5b\x2c\xc2\x80\x5f\x04\x37\x78\x97\xc2\xad\xa8\x29\x34\x6e\x2f\xe2\x73\x7a\x62\xb1\xd3\xbe\x56\x1c\x30\x2c\xf7\xa5\x93\xda\x0a\x75\x97\x5c\x9d\x6f\x21\x30\x68\xbb\x44\x78\x05\x14\xd7\xd6\x44\xd2\xa5\x3f\x0c\xf8\x25\xe5\xf8\xc6\x53\x85\x63\x78\xb6\xca\xd5\xc6\x4f\x82\xbe\x4f\x59\x8e\x5b\xd7\xa5\xa4\xe3\x28\xcf\x05\xb3\xbe\x14\xb9\xee\x88\xf6\xe2\xfe\x3a\x1b\x21\x6d\x2c\x33\x52\x14\xf4\xc7\x99\xab\xdb\xd8\xe1\x3b\xcc\x2c\x58\xb7\x66\x18\xf0\x39\x0b\x00\x8d\x57\xf0\xd6\x2a\x99\xd7\x6d\xc1\x2f\x25\x25\xfb\xda\xf0\x1a\x77\xa6\xb4\x8f\xed\x81\x1d\x17\xee\x18\x1f\xc9\x73\xc0\x75\x09\xd5\x8e\xa1\x4a\xf2\xa3\xd7\xb1\x1e\x57\x04\x23\xfc\xe2\xd8\x33\xca\xe8\xa9\xc3\x1b\x29\x1b\xeb\x44\x3b\x3e\x7c\x71\xec\xca\x76\xfc\x26\x1a\xfc\xb9\xff\x87\x71\x3d\x77\x55\xdc\xa5\x6a\x6f\x64\x7f\x77\xe9\x20\x9f\x53\x50\x37\x6e\x3a\xed\x8e\xce\xe7\xbc\xcd\xa0\x6e\xc3\xf2\xad\x95\x78\x9b\x7f\x05\x00\x00\xff\xff\x5e\x5e\xc6\xb7\xb8\x0b\x00\x00"), + }, + "/src/net/net.go": &_vfsgen_compressedFileInfo{ + name: "net.go", + modTime: mustUnmarshalTextTime("2016-06-27T01:43:45Z"), + uncompressedSize: 770, + + compressedContent: []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\xb4\x92\x41\x6f\xdc\x20\x10\x85\xcf\xe1\x57\x8c\x38\x41\x6b\x79\x2f\x51\xef\xad\x2b\xad\x5c\xb5\xbb\x91\x56\x6a\x7b\xc5\x78\xd6\x8b\x83\xc1\x02\xdc\x4d\x54\xf5\xbf\x77\xf0\xda\x49\x94\xec\x35\x27\x63\x78\x7c\xf3\x66\x1e\x9b\x0d\x7c\x6c\x26\x63\x5b\xe8\x23\x63\xa3\xd2\xf7\xaa\x43\x70\x98\x18\x33\xc3\xe8\x43\x02\xc1\x6e\x38\x86\xe0\x43\xe4\xb4\x8a\x8f\x51\x2b\x6b\x39\xa3\x75\x67\xd2\x69\x6a\x4a\xed\x87\x4d\xe7\xc7\x13\x86\x3e\x3e\x2f\x7a\x92\x4b\xc6\x8e\x93\xd3\xd0\x3c\x26\xac\x5d\x8b\x0f\x22\x42\x4c\xc1\xb8\xae\x80\xcb\xae\x04\xe3\x12\xfc\x65\x37\x01\xd3\x14\x1c\x99\x28\x6b\x97\x30\x38\x65\xf7\x4d\x8f\x3a\x89\x28\xcb\x8a\x0a\x0a\x6e\x32\x60\x7f\xe4\x45\x16\x6d\xad\x6f\x94\x2d\xb7\x98\x04\x3f\xcc\x44\xbe\xea\x8e\xc1\x0f\xd5\x49\x85\xca\xb7\x48\x62\x2d\x65\x46\x0a\xc9\xfe\x2d\x6e\xbe\x9b\x98\xd0\x09\xea\xb1\x00\xab\xda\x36\x2c\x9e\x24\x88\xcb\x11\x86\x02\xe6\x8e\x65\x76\x36\x2a\x67\xb4\xb8\x4c\xa0\xdc\xe1\x59\x70\xba\x79\xf6\xe1\x1e\x94\xd6\x18\x23\x98\x08\xce\x27\x88\xd3\x98\xe7\x85\x2d\x35\x06\xdb\x79\x0c\xdf\x0e\x5c\x3e\xd7\x15\x2d\x7c\xf8\x6a\x94\x45\xe2\xe6\xaf\x58\x38\x05\x64\x13\x99\xf4\xe4\xa3\xf2\xce\xbd\x8b\x07\x8a\xaf\x76\x86\xa6\x41\xd4\x75\x6f\x0c\xbe\xc1\xfa\xee\xcf\xed\x21\x51\xfc\x74\xd4\x78\x6f\x5f\x64\x72\x54\x36\xe2\x1b\xf5\xa7\x55\x2d\x96\xa2\x31\x6f\x16\xf0\xe2\xef\x76\x50\xe3\x0c\x93\xaf\x69\xc5\x35\xe8\x2f\x4a\xd8\x9f\xe9\xe2\x1b\xf2\x4f\x8a\x45\xd5\x77\xd7\x59\x4f\x90\x41\x3d\xac\xf9\x7d\x21\x80\xf5\x9d\x78\xfd\xbc\x96\xd7\x5b\x1e\xf6\x3f\x3e\xff\xae\xf6\xbb\x1d\x5d\xfe\x1f\x00\x00\xff\xff\xaa\x32\xc7\x87\x02\x03\x00\x00"), + }, + "/src/os": &_vfsgen_dirInfo{ + name: "os", + modTime: mustUnmarshalTextTime("2016-06-27T01:43:45Z"), + }, + "/src/os/os.go": &_vfsgen_compressedFileInfo{ + name: "os.go", + modTime: mustUnmarshalTextTime("2016-06-27T01:43:45Z"), + uncompressedSize: 464, + + compressedContent: []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x5c\x90\x5f\x4b\xc3\x30\x14\xc5\x9f\x9b\x4f\x71\xcd\x53\x42\xb5\x73\xaf\xce\x21\x3e\xc8\x10\x7c\x13\xf1\x61\x0c\xe9\x9f\xb4\xbb\x5b\x9b\x94\x24\xd5\x41\xe9\x77\xf7\x26\xeb\x14\x06\x85\x86\xdc\x73\x7e\xe7\xe4\x2e\x16\x90\x16\x03\xb6\x15\x1c\x1c\x63\x7d\x5e\x1e\xf3\x46\x81\xa1\x33\x76\xbd\xb1\x1e\x04\x4b\x78\x83\x7e\x3f\x14\x59\x69\xba\x45\x63\xfa\xbd\xb2\x07\xf7\x7f\x38\x38\xce\x24\x63\xf5\xa0\x4b\xb0\x83\xf6\xd8\xa9\xaf\xdc\x36\x4e\x48\xd8\xee\x9c\xb7\xa8\x1b\x18\x81\x72\xb4\xf1\x50\xe6\x6d\xab\x2a\x30\x1a\x3e\x51\x57\xe6\xc7\xb1\xc4\x2a\x3f\x58\x0d\xcf\x64\x61\xd3\xcc\x41\x8d\x9e\xfc\x23\x4b\xb0\x86\xde\x9a\x52\x39\x07\x0f\x6b\xea\x98\x6d\x5a\x53\xe4\x6d\xb6\x51\x5e\xf0\x79\xc2\xe5\xea\x4f\x74\x13\x45\x1f\xba\x52\x35\x6a\x4a\x22\x44\x42\x6d\xbe\x83\x7b\xd6\x9c\xbd\xe1\x92\x4b\x9a\x86\x60\x58\x43\x97\x1f\x95\xb8\x14\xbe\x85\x30\xce\xde\x94\x6e\xfc\x5e\xc8\xbb\x65\x10\xd6\xc6\x02\x06\xce\xfd\x8a\xfe\x8f\xd7\x12\xba\x4c\xd3\x98\x17\x91\x5b\xdc\x11\x35\x6a\x5e\xa9\xcd\x49\x20\xa4\xb0\x94\xd9\x7b\x0c\x10\x01\x38\xb1\xf0\xd1\x0b\x5b\xa5\x45\xf0\x48\x58\x13\x3d\x32\xe6\x56\x97\x42\x23\x7f\xe2\x51\x3e\x5d\x6d\xba\x50\x54\x4b\xbd\x9c\xce\xfb\x9a\xd8\x6f\x00\x00\x00\xff\xff\x4f\xb8\xac\xc5\xd0\x01\x00\x00"), + }, + "/src/reflect": &_vfsgen_dirInfo{ + name: "reflect", + modTime: mustUnmarshalTextTime("2016-06-27T01:43:45Z"), + }, + "/src/reflect/reflect.go": &_vfsgen_compressedFileInfo{ + name: "reflect.go", + modTime: mustUnmarshalTextTime("2016-06-27T01:43:45Z"), + uncompressedSize: 33268, + + compressedContent: []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\xec\x3d\x7f\x73\xe3\xb6\xb1\x7f\x5b\x9f\x82\xa7\xe9\xdc\x13\xcf\x8a\x62\x3b\x99\x4c\xc6\xa9\xd3\x69\x92\x4b\xdf\x25\x4d\xee\x26\x97\xf4\xbd\x79\xae\x27\x43\x4b\x94\x4d\x5b\x22\x55\x92\xd2\xd9\x75\xfc\xdd\xdf\xfe\x02\xb0\x00\x41\x49\xbe\x24\xef\xf5\x8f\xb6\x99\xb3\x44\x02\x8b\xc5\xee\x62\xb1\xbf\x00\x7d\xf8\x61\x72\x78\xb9\x2e\x16\xb3\xe4\xa6\x19\x0c\x56\xd9\xf4\x36\xbb\xca\x93\x3a\x9f\x2f\xf2\x69\x3b\x18\x14\xcb\x55\x55\xb7\xc9\x68\x70\x30\xcc\xeb\xba\xaa\x9b\x21\x7c\x6a\xda\x7a\x5a\x95\x1b\xfc\xb8\x2e\x9b\x6c\x9e\x0f\x07\xf0\xf1\xaa\x68\xaf\xd7\x97\x93\x69\xb5\xfc\xf0\xaa\x5a\x5d\xe7\xf5\x4d\xe3\x3e\xdc\x40\xc7\x74\x30\xd8\x64\x75\x52\x94\x45\x5b\x64\x8b\xe2\x9f\xf9\x2c\x39\x4b\xe6\xd9\xa2\xc9\x07\x83\xf9\xba\x9c\xd2\x9b\x51\x9a\x3c\x0c\x0e\x00\xab\x6c\x53\x15\xb3\x64\x96\x67\xb3\x64\x5a\xcd\xf2\x24\x5f\x14\xcb\xa2\xcc\xda\xa2\x2a\x07\x07\xeb\x06\x3a\x9f\x42\x6f\xe8\x36\x2a\xa0\x63\x9b\xd7\xf3\x6c\x9a\x3f\x3c\x42\xf7\x47\x7e\x3f\xaa\xdb\xfb\x15\x3e\x91\xaf\xd0\xb4\x5a\x2e\xab\xf2\x47\xef\xe9\x32\x6f\xaf\xab\x99\xfb\x9e\xd5\x75\x76\xef\x37\x99\x5e\x67\x41\x27\x1c\xd6\x7f\x62\x31\x08\xa0\x67\x2b\xff\xc1\xaa\xad\xfd\x07\xcd\xa2\x08\x3b\x01\x79\xd7\xd3\x36\x80\x1f\xe2\xc9\x8d\xbe\x2e\xf2\x05\x3d\x1c\x1c\xf8\x64\x85\xb7\x39\xb4\x04\xb4\x3e\x45\x40\xf0\x04\xff\xbc\x9e\x8f\xe8\xd1\xe8\x28\x4d\x27\xa3\x17\x44\xa0\x34\x01\x62\x37\x79\x9b\xcc\xab\x1a\xf8\x9e\x2d\x06\x8f\xc2\x8e\x9b\x06\xfb\x8c\xa0\x11\x75\x4e\x93\x17\x37\xcd\xe4\xf5\xe5\x0d\x08\x06\xf2\xa8\xce\xdb\x75\x5d\x42\xab\xc9\x2b\x9c\x7c\x99\x2d\xf8\x1d\x76\x48\x27\x7f\xc9\xdb\xd1\x90\x21\x0c\x53\x0b\x52\xe4\xca\xc2\x75\x10\x01\x3a\xa1\x83\x90\x8b\x79\x02\x1f\x19\x84\xea\x31\x4c\x93\xb3\x33\x1c\xef\xa7\x72\x96\xcf\x8b\x12\x26\x0a\x8d\x0f\x40\x3c\x41\x12\x9e\x33\xb7\xe1\xfb\x41\x03\x34\x38\x4d\x92\x04\xa7\x0a\xf4\x1e\x59\x58\xf8\x62\x98\x22\xba\xa3\x34\x1d\x63\xd3\xdb\xa2\x9c\x99\xa6\x9f\xba\x86\xf8\xd8\x6f\x08\xe4\x2e\xca\xab\xd3\xa4\xcc\xdf\xbd\xa5\x8f\x6f\x3c\xc0\xf4\x68\xc8\x6d\x41\xfc\x0e\xba\x44\xa9\xdb\x74\xf2\x56\xd1\x64\x8c\x53\x04\x66\x1e\x20\x90\xb7\xe1\x4c\xc7\x11\xb2\x02\x04\xe4\xf3\x01\x4b\x02\x74\xc1\x69\x43\xb3\xbf\x2c\xaa\xcb\x6c\x31\xf9\x32\x5b\x2c\x46\xc3\x3f\xd8\xb7\x6e\x04\x4d\x4e\x24\xd2\xf7\xd9\x12\xc9\xc0\xf3\x80\xf5\xf6\xec\x2c\x19\x0e\x93\x5f\x7e\x49\x6c\xdf\xc9\x5f\xf3\xf2\xaa\xbd\xe6\x77\x47\x44\xe5\x03\x41\xef\x3b\x6a\xd3\xe0\xd8\xcb\xec\x36\x1f\x9d\x5f\x70\xaf\x71\xa4\x37\x0e\x7e\x80\x62\x55\x60\xf3\x3a\x2b\x9d\x66\x31\x60\x08\xf4\xc1\x92\xc0\xd9\xfe\xaf\x80\xbf\x77\xa3\x82\xba\x1f\xd0\x34\x97\x16\xfb\x21\x3f\xf5\xc1\x9c\x17\x17\x89\x01\xc0\x10\x0f\x4a\x98\x24\x72\xd6\xe7\x98\xc0\x29\x89\x02\xcc\xd9\x83\x83\xd5\xed\xd5\x9b\xac\xbd\x3e\x8d\x36\x85\x97\xae\xe5\x12\x10\x20\xa0\x9e\x1c\x9b\xb7\xe6\xa5\xf7\xb6\xc3\x20\xa3\x3b\x98\xc7\xf2\x8e\x86\xfa\x33\xaa\x1e\x60\xcc\xf7\xf9\x3b\x5e\x43\xdc\x03\x54\xed\x34\x23\x76\x0a\x46\x59\x9d\x2d\x1b\x44\xca\x3c\xa9\xf3\x66\xbd\x68\xe1\x91\x7d\x02\x7a\xb6\xc8\x66\xc5\x14\x5a\x09\x76\x28\x95\xfc\x4f\xdd\x4e\xb4\x2a\x04\xc2\x3d\xf7\x54\xe3\xa0\x9f\x7c\x11\x31\x12\xf0\x71\x1a\xda\xf6\x9a\x8a\xcc\xa6\xe6\x34\x10\x85\xb1\x45\x30\x26\xfa\x1e\xca\x3d\x2b\xe9\x11\x57\x47\xf3\xae\x68\xa7\xd7\x09\xf4\xf8\x16\x16\x31\xef\x26\x07\xd3\xac\xc9\x13\x22\xef\x29\x2d\xe6\xbc\xc5\x97\xc4\x9f\xba\x1d\x27\xcf\x9d\xd2\x27\x0c\xf3\x45\xbe\x3c\x0d\x75\x15\x4f\x04\x5f\xd9\x99\x2c\xf2\xf2\x34\xa2\x66\xe0\xb1\xaf\x3c\x50\x69\x33\x0e\x5f\xc2\x56\x42\x28\xcc\x8a\x1a\xe5\xfa\x8b\xaa\xbd\xfe\xaa\xa8\xf1\x89\x5e\xa5\x4d\x5e\xce\x5e\x97\x0b\x14\x86\x2f\xaa\x6a\x21\xb3\xe0\x5e\x67\xc9\x5b\x78\x2b\x9d\x1e\xc3\x9e\x75\x3e\xdd\xf4\xf7\xfc\x01\xde\xea\x9e\x1d\x42\xd8\xad\xee\x49\x74\x00\xe0\x8a\x0e\xf0\x2d\x9c\xf6\xd7\xc0\x3d\x9a\x36\xcb\x2e\xce\xdc\x89\x86\x88\x33\xcd\xa4\x54\x7a\x85\xf7\x83\x71\xc2\x0d\xb6\x2a\x15\xe8\xc7\x18\x17\x25\xab\x02\x8d\xb3\xf4\x37\x4a\x25\x75\x0b\x81\x97\x8d\x87\x8d\x5d\x4a\xd8\xa0\x5a\xb7\x11\x7c\xa4\xc9\x56\x84\xb0\x27\x63\x04\x9f\xba\x28\x19\x10\x5d\x9c\x3a\x1c\xb1\xa6\x06\xab\x3d\x44\x81\x95\x0c\xa0\x23\xd4\xaf\x5a\xfe\xef\xd4\x4d\xc3\xad\x7f\x11\x83\xb1\x90\x87\xfb\xc2\xff\x8a\x72\x6c\xf0\x33\xcf\xe0\x63\xc0\xb7\x57\xc6\xaa\x21\xe6\x2d\x9d\xea\xb7\x03\xc9\x33\x61\xdf\xb2\xb3\x39\x14\xfe\xee\xb0\x83\x8d\xcb\xbe\x5d\xa1\xf1\xf7\x04\xd3\x90\x29\x5b\xfc\xfe\x8a\x3f\xaa\xda\xf5\xa6\xd4\xd1\xb2\x1d\x46\xfa\x16\xa2\xcf\x4d\xcb\x4b\xab\x1b\xcd\x0c\x03\x86\x7c\x97\xad\xe2\x1a\xcc\x18\x9a\x04\xe5\x36\xbf\x3f\x4d\xe2\xeb\x16\x5e\x59\x64\xf7\x5c\xde\x6e\x74\xa0\x4e\x7c\x74\x63\xd5\xbe\x1f\xd8\xb7\x68\x02\xc7\x01\x3b\xeb\xf8\x3d\x41\x93\x95\x4c\xb0\xe7\x68\x2a\xfb\xc2\xcb\x8f\x58\x76\x05\xe8\xd7\xb6\x95\x08\xb0\xb2\xb3\xc7\x09\x77\xd8\xc7\xbe\x11\x38\x8c\xf6\x9c\x5c\x15\xee\xeb\xc9\xb1\xd7\x98\x85\x59\xdb\xf5\xdb\x04\x7a\xbe\xbf\x40\xcf\xf7\x15\xe8\x79\x57\xa0\x0f\xda\xec\x8a\x1b\xc6\x40\xc2\x4b\xd7\xb2\x9a\xcf\x81\x7f\x6a\x23\x28\x76\x2f\x0a\xe5\xea\x78\x2b\xc2\x2e\x08\xa6\xda\xa9\x4f\x56\xc7\x64\x80\x8a\xbb\xbe\xb8\x22\xc6\xa3\x19\xb1\x57\x3a\x79\x53\xd1\xa2\x1b\xc5\x9d\x09\x70\x23\xb0\x15\xb0\xd1\xf9\x27\x3e\x82\x89\x51\xf9\xb7\xf2\x2c\x70\x34\x07\xdb\xec\x7c\xd3\x27\x6a\xcb\x9b\x97\x28\x42\x5b\xde\x8a\x63\xd0\x6e\x75\x09\x1e\xd9\xad\x6e\x0c\x73\x40\x47\x24\x22\xbe\xa0\x15\xce\xf9\xf9\xc5\x0b\xfe\x9b\xca\x44\x3d\x6e\xc2\x2b\x00\xe8\x3b\x63\xdc\x1c\xe7\x88\xc0\xa7\x22\x97\x0f\xf8\x57\x86\x4a\x1e\x63\xb8\x4f\x05\x69\x68\x03\x28\x33\x64\x72\x31\xaf\xc0\x61\x91\x8e\x60\xa2\x5d\xe3\x0e\x59\x48\xd7\xe2\x9f\xf0\x74\x80\x3e\x16\x2e\x94\xe9\x04\x3e\x90\x13\x88\x0f\xce\xc8\x39\x21\x3f\x8f\x99\x5c\x16\x0b\x64\xfa\x01\x48\xd8\x38\xa9\x6e\xb1\x87\x9e\x3a\xce\xf7\x82\x7a\x3f\x83\x97\xd8\x6f\x85\x50\x48\xd4\x06\xc6\x8f\x53\x4d\xe1\xd5\x0a\xdf\x3c\x5a\x29\xc2\xaf\x46\x1e\x8a\xe6\xbf\xea\x6c\xb5\x02\x7f\xdb\x79\xc1\x97\xb0\xa1\x7a\xfe\xaf\x51\x44\xe2\xf4\xbe\xe3\x1e\x76\xeb\xb5\xc0\xa6\xd5\xea\x9e\x15\xd2\x68\xd6\x80\xf4\x37\xf5\x54\xd1\x9c\xcc\x58\x19\x02\xa0\x3b\x75\xd5\x19\xc0\xa9\x2d\xab\x7b\x8e\x3e\x83\xbf\x7f\x0c\xf5\x13\x3c\x3c\x3c\x64\x1a\xd4\xd5\x2a\xa2\x84\x44\x31\xc0\x4b\xe5\x0f\x42\x73\x40\x8f\xb8\x88\x6f\x08\x4f\x6a\x88\xdf\x50\x60\x1f\xed\x8c\x50\xc8\xfe\x96\x2d\xd6\x80\x1d\x61\x3e\x4e\x36\xde\x8c\xe6\x0b\xf8\x2f\xbb\x4a\x13\x6a\x44\x44\x23\x8b\xaa\x9d\xb0\x31\x8f\x83\xa1\xf5\x6a\x6c\x75\x60\x36\x59\xe9\xe8\x8c\xea\x87\x4c\xb5\xf0\x29\x70\x51\x0b\x06\x8d\xf1\x80\x6a\x25\x58\xfe\x1b\xb7\xd2\x09\xa5\x5f\x08\xa9\x91\x01\x95\x3e\x6a\xee\xf7\x42\xe9\x38\x72\xb0\x84\xbe\xca\xda\x4c\xde\x83\xb0\x6f\xc6\x86\x57\xe0\x7d\xe0\x96\x58\xa1\x6e\xd9\x31\xb8\x3c\x00\x8e\x14\xb5\x23\xec\x77\x40\x58\xda\x16\xad\xdc\x8d\x13\x70\x2b\xc6\xc9\x14\x16\x37\x8c\xa7\x28\x2a\xd6\xbf\x90\x05\xfc\x75\xea\xc7\x5c\xcf\xca\x62\x6a\xb5\xde\xc4\x02\x4d\xaa\x79\x52\x56\xe5\x07\xb4\xbb\x26\x2d\x87\x68\x90\x06\x00\x0b\x46\x01\x41\x3a\xda\xda\x1f\xf7\x97\xab\xac\x2d\x36\x79\x42\xbe\x8e\xe9\x8b\xc8\x3d\xa1\x2f\x34\xf7\xc7\xfd\x9c\x20\x6c\xef\x6d\xdb\x71\x57\xcb\x37\x25\x8a\xf7\xab\x71\x24\x2e\x62\x40\x0c\xc7\x7a\x45\x39\xb2\xc6\xf4\x2b\x85\x17\xfd\xb8\x57\xd2\x59\xf6\x93\x97\x60\x7a\x00\x27\x65\xa4\x7f\xe6\x75\x35\x4c\x93\x47\xe4\xf7\x91\x5b\xfc\x12\x7e\x0b\x62\x95\x3f\xba\x88\xd7\x33\x1d\xc0\x7b\x48\x6c\x04\x94\xc2\xae\xc8\x31\x1b\xcc\x73\x22\x2f\x41\xaf\x47\x43\xc4\x02\x97\x05\x28\xc8\x98\xbe\x94\xaf\x41\x6c\x22\x98\xb0\x51\x09\xd3\xaa\x64\x85\x5f\xd5\x43\xb5\x3d\x12\x81\xbb\xb3\xd0\xb2\x18\x43\x81\xd7\x94\xb7\xcc\x1c\xbb\xde\x07\xa1\x18\xaf\x4c\xcb\x3f\x6c\xb2\xc5\xd0\xa7\x3d\xe9\x14\x40\x7b\x5a\xad\x4b\xda\x75\xc6\x09\x9a\x8b\xa2\x6c\x0d\x0f\xe2\x04\xf2\xa5\xc8\x06\x0a\x9c\x14\x21\x24\x18\x8e\x60\x2b\x52\xa1\xa7\x0f\x43\xa2\xdf\x8d\x1f\xc1\xeb\x06\x05\xff\x1e\x23\x1a\x8f\x5c\x89\x2d\x8c\x46\xee\xbc\x8d\x04\xd8\xef\xe2\xdf\x2b\x34\xd0\xf3\x46\x86\x81\x8c\xe3\x8e\x7b\x7e\x21\x6a\x5a\xfc\x43\xda\xcc\x3c\x31\xb4\x6f\x9e\x3f\x4f\x46\xb0\x36\xa0\x2b\x29\xdb\x23\xd4\xbe\xe0\x5e\xcb\xa3\x0f\x8e\x2f\x42\x95\x93\xc6\x56\x2e\x8f\x0f\xcb\x36\x6b\xda\x24\xab\xaf\x50\x90\xed\x10\xbc\x87\xac\xe1\xcd\x65\x9e\x90\x32\x32\x8b\xfa\xa6\x79\xe5\x85\x02\xd4\x9e\x22\x08\x98\xdd\x0f\xb7\x9c\x30\x0e\x80\xbd\xd9\x9a\x16\x92\x6d\x58\xcd\xdc\x34\xaf\x7d\x8f\x3e\x00\x0b\x14\x8a\xc3\x35\xee\x3c\x01\x88\x41\xde\x87\x93\x5e\xe0\xef\x55\x89\xff\x02\x34\xc7\x0b\xc5\x35\x30\x4e\x80\x69\xe0\xab\x45\x05\x55\x42\x5c\xf0\x5a\xc5\xb8\x6c\x9c\x65\x8c\xbd\xc7\xce\xa9\xea\xa8\xd2\x15\xf2\xa3\x28\x61\x99\x80\x76\x01\x20\xb4\x01\x24\xc3\xe4\x90\x20\x1a\x2b\xc0\xd7\xae\x5b\x27\x26\xbe\xa7\x93\x50\x80\x93\xfa\xeb\x43\xcd\x6d\x64\xcc\xea\x34\x91\x3d\x52\x45\xfe\xf7\x19\x4e\x9c\x4d\xbd\x20\x14\x78\x9a\x37\x10\xef\x7d\xd6\x9a\xf5\x36\x7b\x60\xff\x0f\xa8\x76\x65\x08\x3a\xa3\xa6\x67\x0b\x72\x76\x9b\xde\x1a\x3c\xd5\xc4\x46\xc6\xcf\x12\xf2\xb5\x94\xf1\x6d\x0f\xc5\x74\xb5\xd5\x1b\xa6\x3b\x1f\x57\xf0\xe8\x18\x2e\x81\xfd\x08\x04\x94\x28\xb3\x32\x4e\x06\x41\x90\x74\x37\x2c\x3d\x27\x0d\x67\x96\xcf\xb3\xf5\x62\x2b\x42\xbb\x2c\xa9\x7e\xd2\xa9\x6d\x37\x62\x61\x85\xb6\x29\xc6\x60\xe7\x64\x5f\x8d\x93\xcb\xa2\x6d\x68\x0f\xfd\xe4\x63\xa7\x89\x2d\x0b\x91\xf8\x81\x61\xba\x62\x77\xc4\xe7\x50\xba\x8d\x13\x30\xdc\xa7\x38\xed\x17\xa3\x17\xb8\x57\xa7\x98\xed\x4b\x31\x40\x85\xc9\x25\x1c\x3f\x75\x0d\x8f\x3f\x71\x2d\x8f\x3f\xd1\x4d\x8f\x3f\x09\xdb\x8e\xf1\x9f\x8f\x4e\x5c\x87\x8f\x4e\x74\x87\x8f\x4e\xc2\x0e\x9f\x7c\xec\xda\x7e\xf2\xb1\x6e\xfb\xc9\xc7\x5e\xdb\x9f\x0a\x87\xf2\xda\xc3\x79\xdd\x41\xfa\xa7\x42\x61\xbd\xf6\xd1\x5e\x77\xf1\xfe\x89\xf6\xd9\x9f\x08\x3f\xfe\xbb\xe2\xf0\x91\xf4\x56\x73\x58\x77\x27\xf1\x53\xa1\x66\xb1\xf6\xa7\xb1\xf6\xe6\x11\x9a\xee\xb4\xf6\xc8\x39\x9c\x6b\xdb\xda\x1a\xde\x96\x6d\xa9\x6f\x6e\xa3\xee\x54\xd6\xf6\xbc\xe4\xe4\x32\xec\x59\x0d\x6c\x9b\x04\x3b\x4d\x4c\xe4\xd6\x3e\xd9\x66\x88\x23\xc4\xc8\x9e\x78\x0a\xd6\xe6\x62\x81\x1b\xa1\x19\x96\x1c\x62\xb2\xc8\xe9\x9b\x33\xc8\x07\x9c\xfd\x42\xb0\x4e\x2e\xe7\x22\xab\xa3\x17\x66\x47\xe9\x06\x3c\x28\x53\x38\xdf\x48\x86\xd0\x4e\x8f\x66\xd4\x5e\x17\x8d\xe7\xa5\xc1\x14\xd7\xcb\xbc\xa4\x59\xe9\x18\x80\xb2\xf1\x68\x1a\x44\x0a\xb7\x7b\xd2\xc4\x81\x50\x88\xdd\xf7\xeb\xe5\xab\x92\x03\x62\x41\x3c\x8c\x3a\x51\x70\x07\x3e\x91\x32\x46\x37\x14\xfb\x40\x07\xb0\xd9\xdc\xbc\x78\x00\x49\xe5\x59\x55\x2a\xbd\x14\x96\xd0\x82\x54\x28\xc7\x94\x84\x21\xec\xd7\x20\xe8\x92\x58\x96\xba\x54\x90\x41\x10\x36\x5b\x9d\x0e\x3a\x3a\xe5\xb0\x9f\x33\x92\xf9\xf9\xb1\x7e\xae\xa1\x9f\x1f\x5d\x4c\x2a\xb6\x35\xc9\x47\x76\x6a\x4e\x67\x12\xb6\xe4\xf4\x3c\x44\x5c\xec\x70\x9c\xd4\x3a\x7c\xa8\xa6\x23\x31\x31\x49\x16\x80\x43\x2e\x7e\x3b\xf4\xb0\x98\xe8\x74\x86\x46\x59\x82\x63\xe9\x20\x5c\x1e\x1d\xc7\x76\x1e\xf8\xc7\xb0\x48\x50\x58\xd4\xf2\x40\x81\x9c\x2d\x73\x60\xd4\x26\x1f\xb9\xa8\x98\x0d\x62\xf8\x00\x7b\x02\x63\xd0\x3a\xb5\x1b\x2d\xa5\xa7\xbb\x6d\x00\x98\x6d\x73\x05\x6d\xd4\xde\xbb\xa8\xb2\xd9\x5b\x58\x38\x59\x3d\x5a\x05\x03\x8e\x93\xd2\xc4\x1c\x53\xf3\x61\x6b\x81\xc2\xca\x1f\xc4\x4e\xdf\xdb\x3b\xd0\xf0\x56\x7b\x32\xcc\x14\x3c\x33\xd1\x3d\xa0\x08\x40\xb0\x22\xd3\x9e\xda\xb5\x69\xec\xf6\x58\x30\x12\x99\xb6\x6b\x6b\x64\x5f\x06\x5d\x07\x91\x1e\xd9\xf9\x70\x84\x89\xf8\x1c\x88\x91\xde\xfd\x34\xfa\x60\x94\x29\x4b\x6b\xb4\x8c\x61\xbb\x17\x0e\x4c\xb3\x88\xc1\x60\x46\x03\x6b\xef\xeb\xaa\x56\x72\x81\x36\x65\x38\xda\x48\x2b\x1c\x09\x45\x22\x0a\xb7\x46\x47\x85\x21\x50\x30\x21\x49\xa5\xde\x6e\x84\x14\xc4\x2a\x54\xab\x9d\x02\x10\x80\x71\x86\xed\x34\x4f\x69\x5f\xb8\xd5\xe1\xb3\xc9\xb7\xf9\xbd\xf3\xd2\x19\x69\x10\xc2\xdb\x8d\x8e\x7c\x09\x45\x6e\x37\xf0\x42\x91\x73\x95\x4d\xa7\x79\xd3\xa8\x39\x2e\xe3\xd3\xec\xda\x6d\x3f\x43\x43\x44\xc3\x50\x89\xfa\xc1\x48\xa0\xc9\xea\xfb\xf8\xdc\x97\x6c\xa7\xdd\x32\x01\xb8\x61\xb4\xf0\x25\xea\xe0\x3f\xd9\xd8\xa2\x01\x24\x6d\xa8\x4c\xac\x37\x64\x5e\xb5\x26\xba\x91\xc6\x05\x6d\x95\x35\x4d\x71\x55\x76\x28\x83\x6e\xcd\x22\x26\x73\x44\xda\x18\x41\x6e\x1a\x50\x50\x71\x82\x00\xa8\x34\xe0\x6e\x2e\x71\x44\xc6\x8e\x09\x15\x89\x18\x22\x99\x60\xc2\x16\x32\x7b\x24\xad\x6f\x55\xa2\xe6\x77\xa1\x59\x6e\x8e\x64\xa0\x3f\xd0\x98\x1c\x3f\x04\x71\x96\xf0\x4b\x22\xb7\x66\x60\xff\x7a\x91\x76\x92\x12\x60\x79\xf3\x9e\x6d\x86\x32\x54\x34\x13\xb0\xe4\x68\xfa\xad\x70\xc9\xa3\xfc\x0c\xb4\x40\xab\xf5\x71\xb8\xc6\xe3\x22\xba\x45\x26\xa3\xe3\x7f\xc5\xc3\xdc\xd2\xd8\xe4\xa7\xc1\xd8\xaf\x50\xba\x1b\x4b\xe3\x16\x13\x44\x1c\x9a\x5a\x52\x6e\xda\x2e\xf6\x01\x26\x23\x1b\xef\x41\xc1\xe9\xe7\x56\xcf\xa5\x00\x78\x54\xfd\xd7\x3f\x1b\x70\x13\x2f\xef\x5b\xed\x6f\x8d\xe8\x41\x47\xc1\x3e\x17\xfc\x70\xab\x8b\xcd\x28\x12\x1c\x44\x1c\xa3\x1b\xd2\x92\xa2\x78\x8f\xbe\xc8\x23\xb2\xd0\x63\x54\xb4\x8c\x52\x6c\xd9\x63\x1b\xde\x08\x04\x9b\x0e\x9a\x05\xc5\x1a\x88\x0f\xd8\x78\x82\x38\x98\xc0\x3c\x7e\x2f\xf6\xd8\x24\xfa\x96\x34\x01\xe0\xf4\xf4\xad\xf3\xe8\x25\x03\xdc\x59\xe3\xd4\xda\xe8\xc7\xbe\x75\x8e\x8d\xca\xfc\xae\x55\xb3\x7e\xc2\x34\x79\x46\x87\x87\x1a\x22\x46\x5c\xba\x4c\x86\x3f\xfe\xde\xbd\x3f\xa7\x6c\xde\xc3\x65\x5c\x36\xed\x57\x45\x4d\x2a\x24\x11\x73\x35\xe2\xbe\x53\xf6\xac\x9e\xf2\x0a\xdf\x28\x1b\x0f\x53\x50\xf2\xdc\x05\x7c\x26\xce\x91\x06\xcd\x3b\x4c\xb5\x2a\xde\x12\x01\x70\x1d\x40\x35\x4e\x28\x2b\xc2\x16\x3e\x8e\x8e\xba\x52\x2f\x11\x13\xe1\x31\xc6\x3f\xeb\xb5\xcf\x92\x5b\xe7\xf4\x9b\xf0\x4e\x63\x0c\x5f\x3d\x18\xaa\x1e\xc6\x5c\x36\xcf\x8c\xcd\xd0\xd4\x74\x60\xdd\xf3\x07\x4e\xd9\x0e\xc7\x89\xd7\x58\x9e\x76\x5a\x2f\x88\xbc\x61\x6b\x79\xda\x69\x3d\xc5\x5d\xb3\x68\xef\xc3\xf6\xf6\x39\xf5\xd8\x10\xd1\x77\x4b\x34\x41\x0e\xf7\x26\xb4\xa4\x8c\xc3\x28\xb5\x09\xe2\x84\xf1\xb6\x10\xdf\x0f\xfc\x36\xf8\x92\x78\x6a\xbe\xb3\xd1\xcd\x78\x31\xe2\xf4\xe0\xb2\xce\xb3\x5b\x6b\x6b\x1b\xb4\x7d\x92\x93\x2d\xae\xb6\x92\x0d\x6e\x20\x0c\x63\xac\x86\xa4\x66\x06\xde\xe3\xa0\x0f\x9a\x47\x35\xda\xf6\x02\x4a\x1a\x26\x05\x51\xa0\x2e\xb4\x30\xea\x33\xd8\x8a\xa5\x17\x0a\x1a\x27\x98\xc4\x1c\x53\x0c\x7b\x2c\xf1\x45\x5b\x15\x64\x42\x8d\x5c\x1b\xab\xb9\x19\x6e\xe0\x18\xac\xf1\x43\x43\xec\x13\x3f\xa7\xd5\xf2\x12\x53\x1c\x0f\x36\x44\xf9\x65\x55\x6e\xf2\x1a\xc5\xf2\xf6\x31\xee\xe0\x5b\xaf\xb1\x9b\xeb\x03\xea\x28\x6f\x86\x57\xda\xf3\x11\xfe\xfb\xc3\xeb\x5f\x6c\x34\x20\xdd\x1a\x0e\xf8\x12\x88\xe3\x52\xb4\xe2\xfa\x8b\x62\x9a\xd1\xa2\xc4\x04\xe9\x2d\x75\x23\x2d\x01\x0f\x9f\x99\xd4\xe5\xf3\xe7\xf2\x35\xcc\xc3\xf5\xcc\x75\x85\x2b\x64\x66\x66\xca\xc0\x6c\x1e\xf4\x41\x92\xb1\x18\x24\xff\x22\xff\x33\xd9\x5a\xd9\xe5\x02\x7d\x15\x6c\xed\x5e\xbd\xbc\xc3\x3a\xfd\x1c\x11\x02\xf5\xc1\x59\xf1\x7a\xaa\x71\x6c\x7c\x1c\x9b\x27\xe3\xd8\x18\x1c\x11\x70\x64\x54\xdc\xb6\x9b\xef\xe0\xf9\x77\x19\x28\xaf\x51\x67\x8a\x80\xab\x5b\x03\x9c\x55\xd6\x6b\x82\x66\x23\x86\x1a\xb6\xf5\xd4\x70\x84\x26\x7f\xd3\x62\x6e\xa2\xbe\xfe\x20\x29\xcb\x3b\x37\x16\x75\x2b\x0a\x5d\xe8\xe3\xeb\xfa\x60\x10\xbb\x27\x04\x83\x04\x98\xeb\xd5\xea\x47\xcd\xbb\xc9\x1c\x5c\x75\x92\x84\x64\xac\xcc\xca\x93\x7a\x51\xb7\x3f\x52\xf9\xd7\x0f\xf9\x34\x2f\x60\x2d\x8c\xaa\x95\x38\x4d\x98\x96\x90\x9d\xac\xe0\x44\xf0\xa8\x9e\x6e\xc4\x64\x72\xc6\xd3\x3c\x34\x1a\x52\x4e\x29\xfe\xf8\xfa\xab\xd7\xc9\x74\x91\x67\xe5\x7a\xc5\x5b\x0f\x55\x06\x30\x6c\xce\xff\x4c\x54\x10\x0b\xc8\x61\x17\x3b\x91\xa4\x6d\x79\xb7\xf7\x8a\xd9\x3a\x7b\x3e\xef\x91\x52\x7a\x5e\x50\x4a\x18\x93\x47\xc9\xe7\x67\x94\x66\x69\x41\x68\xb9\xba\x4d\xb4\x6d\x18\x1f\x33\x75\x21\x9c\xfb\x74\xc9\x0a\xee\x05\x5f\xc1\x48\x1a\x9a\x00\x10\x55\x09\x3e\x77\x30\xcf\x8b\x0b\x1e\x78\x39\x91\x72\x28\x14\x74\x93\x91\xec\x8c\x85\x79\x0f\xa0\xc0\x21\x7c\xc0\x1c\x2b\x98\x38\x2c\xd2\x32\x98\x1d\xa6\x20\x1a\xd0\xe4\xcb\xaa\x7c\xb9\x5c\xb5\xf7\x96\x34\xa9\x55\x70\x34\x61\x7c\x34\x29\xda\xec\x52\xa7\x42\x77\x0c\x2c\x53\xab\xc8\x9d\x73\x91\x37\xb4\x0c\xd6\xb9\x45\x02\x38\x68\xb8\x8d\xe1\x5c\x3b\x10\xd2\x1b\xb9\x83\x91\x33\xf9\x4c\x7c\x3d\x4b\x5e\x2c\x27\x58\x22\x06\x62\x99\xe4\x8b\x86\x99\xe8\x43\xd9\x48\x07\xce\x8c\x31\xfb\x4d\xb1\xf5\x48\xa6\x04\xef\x64\x2a\xc4\xc7\x90\xa1\xeb\xdf\x81\xa1\xeb\xdf\x9b\xa1\x4c\xac\xa5\x47\xad\xad\xa7\x29\x3c\x03\x30\xdd\x55\x43\x83\xbb\x16\x10\x99\x69\xea\xa9\x19\x57\x53\xc4\xa0\xd8\x80\xc4\xb6\xa1\x91\x89\x7a\x05\x5f\x30\x38\x58\xd3\x67\xe1\x76\x87\x6f\x5d\x6d\x8e\x4e\x84\xb0\x0a\xb2\xfa\x84\xe4\xc8\x0a\xac\x33\x87\xb1\xbd\x24\x81\x83\x70\x2f\xe9\x02\xdc\x23\x39\xfb\xbb\x63\x8f\xa0\x67\x13\x3b\xc0\x90\xbc\x26\xb3\xa3\xd1\x20\xb0\xe7\xc8\x6e\xcc\x9b\xb1\x3b\x5a\x12\x64\x28\x03\x50\x18\x2e\x2f\xcb\xaa\x35\x85\x17\x34\x93\xa4\xba\x6c\x33\x0a\x84\xcc\xeb\x6a\xa9\xb9\x4c\x15\x4e\x49\x55\x2b\x76\x3f\xaa\xc9\xd0\xe0\x7c\xe2\xc0\x21\xb0\x91\x88\x33\x3f\x67\x03\x7e\xa8\xe7\xb2\x11\xbd\xde\xcb\x3d\x46\x4d\x51\x30\x54\x89\x5d\xc6\x3a\xa9\xf0\x2a\x11\x95\xb9\xb3\x05\x9c\xeb\x1c\xab\x62\x24\xc5\xf0\xf2\xe4\x95\xf2\xa6\xd1\x90\x51\xf0\x68\xfb\xf9\x6d\xe3\xb6\xe1\xde\x85\xc7\x43\x60\x0b\x71\x75\x84\x32\xab\xe1\x9f\xbe\x7e\xf5\xdf\xdf\xbd\xfc\xd3\xd0\x0b\x57\x6a\xd2\x77\x37\x3b\x3f\xcb\xd2\xe5\xe4\x59\x5c\x94\xfa\x15\xcf\xba\xa1\x22\x28\x1c\xf9\x4d\x56\x63\xd9\x0d\x9a\xb6\x26\xe9\xf2\xf3\x38\xf9\x99\xf6\x50\x5b\x7f\xae\x36\x62\xaa\xf3\x02\xb8\x23\xf1\xe2\x3e\xff\xdc\x21\xf2\xf6\xba\x98\x63\xbc\xe8\xb7\x5e\xf9\xbf\x71\x22\xa7\x37\x30\x3e\x2f\x0d\xab\x01\xcd\x05\x5a\x6d\x88\x84\x02\x9c\x52\x4a\xc1\xb7\xc7\x37\x13\xc2\x3c\xed\x37\xca\xfd\x0c\x83\xaf\x05\x7e\x89\x66\x1c\x74\x91\x00\x03\x69\x46\xae\xf2\xd2\x64\x60\xc3\xfc\xeb\x1b\xcc\xfa\x91\x4b\xa2\xdd\x15\x76\x73\xc6\x9d\xd4\x36\x1f\x91\xec\x66\xab\xf9\x44\xea\x41\x14\x99\x2f\xab\x25\x1e\x27\x21\x0b\x7c\x27\x3a\x32\x3c\x7b\xae\x52\xb9\xef\x8f\x11\x4d\xb9\x9b\xa0\xe6\x44\x0f\xd6\xf1\xf2\xc2\xd2\xcf\x16\x33\x4b\x54\x1e\xad\xeb\x3e\xa9\xb0\xac\x9d\xf0\x73\xd8\xab\x90\x53\x1e\x5c\x9b\x63\xd2\x68\xf1\x06\xe9\xd5\x6b\x11\xb1\x34\x41\xbc\xf3\x58\x09\x8b\xff\xc8\x98\xa4\x4b\x79\x90\x9a\xbc\xe8\x56\xf3\x21\xb0\x1e\xc2\x35\xfc\x9d\x32\x12\xa8\x12\x07\x16\x2e\x25\xcb\x44\xb7\xaf\xd8\x00\xf4\xcc\x05\x18\x73\x45\x86\x8f\x36\x15\x96\x13\xd4\x49\x68\x14\xad\x8c\x51\x04\x6b\x8b\x7c\x01\x27\x83\xd2\x37\x62\x69\x2c\x27\x6f\xe4\x21\x41\x90\x16\xc8\x0a\x98\x17\x83\x78\xdb\x16\xd3\xdb\xfb\x1f\x5e\x13\xe4\x25\x19\x54\x2b\x36\xaf\x96\x44\x7a\xdc\x67\xda\x81\xad\xc6\xdd\x61\x6e\x74\xce\xd5\x06\xa7\x6a\x77\xda\x20\xac\xc1\x7e\x43\xbd\x21\x6a\xcd\xa5\x62\x8f\x2e\x9c\xdc\x06\xb6\xc8\x56\x3d\x72\x7e\x7c\x7a\x21\xba\x64\x49\x35\x62\x40\x19\xd6\x26\xcb\x48\x82\xb2\xf4\x13\x94\x48\x5b\x9e\x3a\x1a\xc1\x1d\x53\x67\x64\x37\x0d\xa3\x7c\x83\x83\xcb\x11\x2f\xc7\x56\x1d\x87\x2f\x54\xdc\xa8\x57\x6b\x1a\xe3\xbf\x63\x67\x70\xe1\x81\x33\x33\x7a\xf3\x1b\x04\x20\xc8\x70\x70\x31\xde\x42\x32\x5e\x5e\x56\x90\xf6\xf7\xef\x29\xf8\x88\x56\x95\x79\xee\xd5\x48\x72\x3f\xb5\xa7\xf0\x4a\x17\x5d\xe5\x4d\x93\x5e\xa8\xaa\x8b\xb1\x2b\x21\x09\xa2\x49\xda\x7c\xb1\xd8\x5c\x17\x57\xd7\x14\xd5\x74\x21\xc1\xea\x1d\x47\xf7\xe4\xd0\x23\xe8\x9b\x45\x7e\x87\x80\xe5\xe3\xf1\xc9\xa7\xfb\x42\xc7\x13\xe9\x3e\xf4\x62\x49\xa7\x4e\x2c\x78\x77\x7c\xc8\x90\x0c\x43\x7a\x51\xa2\x84\x61\xdb\x1e\x0c\x5c\x2b\x6e\x63\x63\x7f\x1c\xfc\xeb\x66\x94\xa2\x98\xab\x98\xab\xe9\x12\x86\x5d\x37\xd1\x98\x6b\xd0\xda\x86\x5d\x37\xd1\x98\x6b\xd0\x5a\x85\x5d\x37\x3d\x31\x57\x33\x69\x93\xcc\xb2\xea\x7e\x8b\x88\xeb\xb0\x9a\xde\x17\x7a\x57\x83\x9c\x4a\xc1\x52\x97\xff\xcc\x17\xab\xbc\x4e\xba\x72\x8c\x2f\xf9\xa4\xac\xb8\x25\xe9\x84\x35\xd4\x64\x32\xf1\x0a\x8c\x95\x52\xea\x2c\x72\x04\xa2\x4d\xc6\xa2\x74\xe5\x3a\xf2\x81\x53\x54\xa7\xd6\xd7\x45\xc4\x46\xa8\xb8\x4b\x3c\xfa\xef\x29\x1b\xa3\xe5\x74\x34\x3e\xdd\xe5\x3f\x80\xb1\xd8\x92\xbd\xf8\x9e\xe6\xa2\xb1\x01\xb5\xb9\xd8\x6b\x2f\xee\x34\x18\x69\xe3\x76\xde\x7e\xcc\x6d\x8c\xb9\x0f\xda\x14\x75\x89\x66\xeb\xf7\x20\x18\xb7\x17\x46\x5d\x36\xd4\x5f\xae\xb8\x09\x9b\x22\xab\xf0\xc2\x0e\x63\x58\x17\xae\x4e\x07\xfd\xed\xb3\x64\x88\x7d\x38\x22\x36\x38\x28\x39\xa5\x2b\xb5\x44\x62\x31\xbb\x08\x25\x9b\x32\xaf\x9a\xbf\x49\xbd\xec\xa8\x27\xd8\x60\x41\x9a\x63\x0e\x5e\xbd\xb1\x41\x47\x82\x3a\xa6\x9c\x18\x8c\x92\x72\x17\x38\xaa\xd2\x6a\xab\x2a\x99\xe7\xef\x80\xa5\xab\x75\xeb\x36\xb4\x18\xc8\xcf\x9f\x00\x72\x99\x95\xf7\x7d\x30\x15\x33\xe9\xb0\x4c\x97\x04\xe5\x07\x1f\x3c\x71\x46\x7b\x4f\x26\x24\x39\x6c\x38\x7b\xcd\x6f\xcf\xa9\x71\xb5\x35\x2c\xa0\xbb\x4e\x15\x37\x0c\x7e\xe7\x05\x22\xd9\x75\xdb\x15\xf4\x59\x37\xe8\x6f\x62\x66\x5f\x9c\x46\x33\x68\x30\xa6\x36\x9e\x4b\x67\x31\xe3\xa8\x78\x16\x0b\x6b\xd5\x31\x35\x8b\x85\xe4\xe2\xe0\xe0\xed\x0a\x54\xb4\xf6\x59\xf2\xec\xae\x9d\xb8\x68\x3c\xe6\xa2\xa0\x7d\x8f\x3c\x76\x70\xc3\x07\xd0\xdf\xde\xbf\x81\x6f\xb2\xc6\x95\x61\x23\x2c\x5d\x87\x7d\x60\xcf\x77\x3c\x33\xeb\x01\xb8\x10\x91\x83\x0f\x3f\x4c\x56\x75\x0e\xb6\xbd\x54\xd3\xcb\x95\x2e\xcb\xac\x28\x71\x5c\x8a\x9c\x34\x26\xc2\x66\xb8\xf8\x41\x52\x0e\x54\x1a\x51\x9d\x3c\xc2\xc9\x96\x29\x55\x74\x2c\x11\x0d\x2a\x45\xa7\x25\x4a\x2f\x6c\xed\x45\x87\x9c\x4b\xe5\x80\xdc\x09\x15\xcb\x43\x0a\xe3\x31\x7d\xf1\xd9\x9d\x50\x35\x42\x4c\x2a\x6f\x92\x0d\xba\x5b\x3b\x49\xc1\x20\x74\xe0\x77\xd1\x11\xc1\xf8\x6f\x41\xb2\x98\x1b\xae\x6a\x8e\x53\x96\xd6\x90\xc6\x4d\xf4\xce\x88\x7f\x55\x17\x57\x7c\x0e\xa1\x40\x1a\x15\x65\x12\x16\x3f\x96\x87\xc7\x26\x9b\x06\xc4\x3c\x3f\x2d\x2f\xc6\x09\xf7\x22\x15\x0e\xd3\xa6\x33\xbd\x38\x06\x6b\xc0\x92\xaf\x38\x10\xe2\x13\x53\xf1\xd1\x33\xa5\xf8\x76\x29\xd8\x77\x75\x05\xcc\x34\x52\xcd\x07\x4f\xc4\x15\x2a\xe5\xc6\x82\xd6\x96\x19\xc2\x90\x58\x0e\xc9\xf6\xed\xf6\xf2\xc4\x56\x55\x71\x4a\x61\xa2\x2c\x02\x6f\x59\x5a\x70\x5e\x41\xe2\xba\xc4\x63\x8f\xdf\x34\xc6\x55\xe1\x85\x42\x10\x26\x5c\x22\x04\x7c\x8d\x4c\x67\x68\x17\x95\x0a\x1f\xc0\xd6\x91\xba\xe8\x98\xb1\x37\x6c\x89\xa5\xb3\x29\x22\x07\x86\xe6\x28\xb1\xd6\xdb\x60\x4c\x29\x27\xc6\x86\x6f\x29\x47\x39\x5c\x09\xa8\xae\xa2\x72\x05\xa0\xf2\x54\x18\xfd\xa0\x12\xfb\x13\xa4\xeb\x11\x0c\x12\x4c\xd8\x3c\x16\x44\xa9\xcc\xff\x31\x8c\x2f\x74\xcb\x67\x11\xa1\x48\xd9\x2c\xb6\xe5\xdd\x3e\x6f\xc3\x92\x58\x1e\xab\x88\xa3\x50\x38\x14\xdc\xf5\x12\x5e\xbd\xac\x54\x89\xb6\x5e\x88\xc3\x9a\x53\x5f\x66\xab\x91\x4d\x76\xde\xb2\xd1\x64\xb2\x88\xb6\x2c\xe1\xa1\x27\x74\xc1\x6e\xc5\x5f\xf3\xd2\x06\x2c\x38\x10\x63\x4d\x74\xdb\xce\xda\x1f\xa1\x81\x2a\x79\x30\x72\xec\x77\x85\x9b\x01\x57\x49\x12\x8b\xb5\x79\x23\xb4\x78\x43\x47\x7e\xe3\x67\x3d\x78\x40\xd5\x12\x8d\x62\xa6\x82\x4f\x4e\x5b\x0a\xee\x57\x67\x44\xbc\x49\x6c\x4a\x15\x22\x6e\x74\xcf\x61\x14\x0c\xec\x5b\xeb\x29\x78\xa6\xf4\x46\x5d\xbd\x15\x2e\xa7\xdf\x0a\x17\xeb\x12\x54\x52\xa5\xd6\x87\x80\x13\x08\x29\x8b\xb0\x86\xb4\xae\x4d\x31\xa2\xa1\x2b\x53\x5e\xe9\x3b\x43\xc4\xe5\x0d\x0d\xdb\x8d\x29\xa9\xe9\xf5\x6b\x8d\xec\x7b\xc7\x07\x39\x6f\xc3\x15\xb6\x9a\xb9\x71\x67\x2f\x1d\xf4\xd5\xe5\x38\xc7\x68\x93\xa9\x82\x1c\x09\x49\xa2\xb6\x08\x4a\x4a\x36\xb0\xd7\x02\x5e\xa3\x6d\x78\xc5\xa6\x6a\xd2\xa5\x72\x64\x69\x4b\xa2\x74\x2e\x9d\xbb\xa1\x51\x7d\x7a\xe1\xcf\xb3\x59\xed\x05\x9c\x30\x97\x4a\xdb\x9c\xd4\x30\x0c\x02\xe4\xe4\x75\x27\xa4\xe2\x4b\x97\x69\x44\x75\x96\x41\xa8\x65\xdf\xa2\x0d\x5e\x91\x28\x2c\xae\x6e\xa3\x2b\x4c\x12\x88\x0c\x8e\x30\x6f\xa4\x9c\x60\xc4\xd1\x16\xe8\x6b\x08\xe7\xee\x87\xe8\xa7\x5d\x5f\x8e\x99\xcf\xba\xc7\x63\x8a\x84\x47\x6f\x48\x51\x47\xe8\x3a\x71\x01\x73\xfa\x7e\x67\xf0\x8d\x86\x90\xdc\xf4\xdc\xdc\xf0\x61\x4f\x1a\xd1\x13\x72\x47\x07\x3e\xf3\x47\x3a\x90\xe8\x2a\x56\x7e\x31\xfc\x8f\x95\xae\xb0\x87\x46\x10\x23\x81\x4b\xfb\x8e\x02\xa2\x3a\x27\xed\x04\xe9\xe5\xf2\x32\x9f\x61\xe0\x52\x7b\x1b\xd1\xc8\xa6\xb9\x73\x03\x75\x4d\x46\xe6\x81\x9e\xdf\x04\x9e\x7d\x46\x2f\x04\x01\xb0\x54\x0b\xe7\x29\x43\x27\x20\x29\x77\xbb\xca\xdb\x6f\xf0\xf3\xe8\x05\x34\x07\x15\xc2\x2f\x9e\xd9\xfb\x1e\x68\x4b\x94\x6a\x2c\x72\x8e\x59\x78\x8e\x52\x1b\xea\x99\xf4\x28\x3b\xbc\x8c\xc4\x5f\x8b\xa1\xd2\x3b\x08\x57\x31\xe9\x85\x78\xce\x4e\x15\x9b\x91\xde\xe6\xde\x91\x4c\xd9\xd6\xd3\xe2\x41\xa4\xb7\xb0\x57\x5f\x60\x7e\xb1\x22\xfc\x88\x00\xde\x19\xb7\x14\xcf\x91\x8f\xb7\x0f\x78\xe7\xed\x07\x0f\x00\xeb\xad\x81\x15\xa9\x74\xcd\xef\xf4\xb8\x77\xfe\x60\x6a\xb4\x8e\x1e\x70\xd1\xaf\x48\xf8\x54\x11\x9e\x59\x65\x5d\x03\x75\xfb\x8b\xc8\x4d\xb3\x2d\x06\xca\x82\xbc\x08\xa3\xa7\xe8\xee\x78\x47\xab\x6c\x19\x93\xff\xb8\x1b\xad\x7d\x2f\xee\x3e\x89\xb5\xe1\x46\x3d\x4e\x1a\x75\x5b\x86\xa1\xe8\x9e\xcc\x6b\xd4\xb5\x1b\x5d\x1b\x00\x18\x66\x21\x76\x19\x14\x3b\x5c\x4f\x9d\xb6\x63\x88\xbd\x5d\xee\xd6\x2e\x4a\x5c\xc2\xe6\x9c\x86\xcb\xe1\xe2\x92\x6c\xbd\x55\x8a\x97\x87\xde\x16\x2b\x50\xba\xe0\x88\x42\xa3\x06\x0c\x39\x4c\x21\xb1\x3f\x68\x0d\xdb\x3f\xb2\x56\xc6\xbb\x40\x90\x6b\xd9\x15\x19\xb5\x67\xc9\x7f\xc0\xff\x39\x51\x75\x78\x68\x36\x78\x2c\x39\xe0\x26\xa7\x52\xf9\xd1\x72\x15\x82\x51\x0c\xae\x76\x52\x10\x00\xa7\x30\x69\x2b\x70\x85\x16\x55\x39\xe1\x67\x19\x63\x82\x95\x00\x59\xf2\x8f\x75\xd5\x82\x03\xd3\xe0\xd3\xfb\xb2\xcd\xee\x38\x1f\x4c\x68\xee\xc4\xf2\x19\x63\xe9\x3f\x38\x0d\x1f\x0c\x3b\xf3\xc0\x7d\xe9\xf0\xd8\x6e\x48\x08\x14\x2f\x30\xf1\x60\x98\x07\x87\xc7\x3e\x14\x5d\x1d\x4a\x5a\xdb\xde\x72\x83\x80\xce\x4f\x8b\x8b\xd4\xa7\xd4\xe1\x31\xd0\x4a\x51\x83\x66\x3c\x33\x9c\x03\xda\xcc\x61\x91\x70\x04\x40\x66\x7d\xbc\x7b\xd6\x76\x4e\x73\xcd\xb1\xbf\xff\x5d\x1e\xcb\x5c\xe5\x12\x42\x6f\xde\xde\xac\x3b\x33\xfa\x07\xd7\x70\x84\x73\x02\x22\xf4\xcc\x0a\xbd\x64\xd9\xbb\x86\x37\x8d\x48\xc1\x86\x1d\xa8\x9f\x05\x0e\xde\x48\x0c\x6b\x82\x26\x3e\xe2\x11\x52\x65\xac\x99\xa9\x7b\x0b\x65\x38\x8c\xd8\x28\xb2\xaf\x07\x36\xca\x2e\xb3\xd7\xba\x42\xc6\x74\xb1\x57\x45\xec\x5f\x1e\x47\x71\x62\xd8\x4d\x81\x72\x3d\xb1\x24\x02\xda\x63\xb7\x68\xeb\x58\x4c\xba\xc0\xb0\x4c\x9e\x27\xa3\xad\xb6\x65\x1a\x18\x97\xca\xc2\x40\xcf\x7f\xbb\xe6\xfe\xcd\x54\xf7\xaf\xdb\x99\x7f\xa5\xf2\xce\x9c\xd7\x6c\x77\xc3\x3d\x95\x77\xb6\x35\x22\xe2\xab\xef\xd8\x06\xfb\xd8\xeb\xb0\x6c\x45\x93\x15\x78\xe7\x5c\x40\xcc\xef\xf2\xed\xe4\x26\xc8\x26\xb1\xeb\x1d\x17\x3c\x8e\x0f\x6e\x13\x3c\x63\xb1\x9b\x3b\x14\xb6\x88\x7d\x8f\x90\x1a\x29\x0c\x84\xd3\x73\x8a\xb6\x0a\x68\x91\x1c\xba\x59\x99\x8c\x9a\x09\x28\xb0\xf8\x36\x7e\x72\xee\xdf\x52\xfb\xaf\x21\xb5\xf6\x04\x81\xdc\x01\xf7\x62\x64\xee\xab\xf3\x4b\x6b\x3b\x7e\x5e\xd3\xd6\x7d\x12\xcb\x5b\xdf\x16\x91\xed\xf7\xb9\x47\x74\x2f\x02\x45\x76\x65\x77\xe1\x22\x54\x8f\xc5\xf6\x3e\xa6\x0e\xa3\x9f\x4f\xf5\x5d\x5f\x72\xb5\xd7\xd3\x1c\x69\xa2\xd3\x36\x4f\xda\x86\x59\xf0\x9c\x0c\xc8\xc9\xf9\xc9\x85\x3a\xfa\xcc\xf0\xf9\xc6\x7e\x12\xb2\xa1\xd7\x1e\x4d\x21\x8c\xa2\x37\xeb\x95\x94\x4d\x5e\xde\x27\x7f\xa1\xbb\xfa\xbf\x79\xab\x4f\x5d\xab\xf1\x24\x00\x12\x14\x3d\xf5\xee\x87\x54\x8b\xd5\x1f\xf7\xdb\x76\xa2\x6a\xe0\xdf\x95\xdc\xd3\x37\x48\x25\x43\xe3\xef\x55\x67\x73\xe3\xf0\x5e\x9d\xdb\xeb\xba\x7a\x07\xbd\x85\x7f\xc4\x10\x0b\xc9\x2f\xdc\xea\x00\x0a\x97\x18\x56\x50\xa5\xb1\x50\xd8\x5e\x98\xb8\x08\xd8\x13\xc5\x05\xb9\xb3\x4d\x5c\x28\x26\x6b\xc2\xba\x7b\xd9\x32\xfa\x5c\x4f\x37\x6c\x6b\x8f\xda\x05\xdb\x4e\x5f\x80\xd7\xdf\x63\x76\x71\x58\x3a\x5d\xae\xe7\xf3\xdc\x96\x6d\x44\x41\xf8\xdc\xe9\x3b\x2e\xa8\x6b\x6d\x1d\xe6\x4f\x21\x30\xf4\xda\x46\x5e\xb3\xf2\xbd\xfb\x07\x76\x91\x99\x63\xe3\x54\xaf\x48\xab\x85\x55\xab\x80\xda\x1a\x79\x3c\xf2\xf5\x6e\x24\x9d\x1f\x2c\x83\x7d\x21\x1d\x87\xfc\x7c\x0f\x14\xbc\x0d\x56\x21\xf4\x14\x72\xbb\x83\x7f\xbd\x24\xa7\x4c\x9d\xf9\xa2\x82\x88\xfe\x21\xa9\xbb\xee\x49\xa5\x03\x2c\x1b\xbb\x8b\x64\xa5\xb8\xee\x8e\xd4\x11\xe7\xa0\x76\xd4\x73\xf5\xd5\x52\x05\xb7\xcd\xfb\x6a\xce\xdc\xe9\x4f\x67\xa2\xfa\x8c\xe9\xd8\x9b\x3b\x7a\x93\x0e\xa2\x57\x73\xef\xaa\x29\xeb\x2b\xdc\x0e\x8e\x05\xdc\x8d\xb9\x04\x34\x75\xe3\xa8\x1b\x94\xd5\x99\xc1\xa7\x23\x2e\x84\x45\xb8\xfa\xe6\x94\xfd\x10\xbf\xf3\xae\x3b\x71\x62\x47\xbe\x1c\x75\x20\x96\xea\x9b\x5b\x3d\x41\xf9\xe2\xbe\xcd\x1b\x90\x96\xf3\x0b\x7b\x72\x39\x2e\x2e\x2e\x12\x4d\x37\xda\xa9\x5a\x41\xff\x44\x29\xc8\x00\x99\x08\xfd\xb9\x5a\x33\xaa\x29\x42\xa1\xb3\xeb\xea\x8e\x3b\x7d\x70\xb7\x43\x31\x3d\xb0\xd4\xd1\xdb\x1f\xe9\xf0\xd0\xf1\x5e\x3e\xb0\x69\x9d\xcf\xde\x06\x67\x82\x55\x8d\x10\xa7\xbb\x3b\x05\x6a\xae\x5b\xe7\x64\xb0\xea\xa0\x8b\xd4\x3a\x3d\xdc\xe9\x60\xd5\x43\x17\xaa\x75\x7a\xe8\x13\xc2\xaa\x8f\x5f\xac\xc6\x64\x3a\x4b\x5c\x6f\xb9\xca\x6f\x1f\xb9\x69\x98\x8b\x51\x99\xc0\x44\x67\xc9\x4e\xfe\xfe\xe2\xb0\x35\x78\x19\x14\x70\x62\xd0\x02\xec\xd5\x1e\x2f\x0b\x38\x89\x17\x99\x36\x3d\x09\xd0\x68\xd6\x82\x69\x61\x9a\x7a\x46\x2d\x66\xe7\x79\x52\xa6\x14\x20\x7f\xb7\x4d\x0c\x3a\x22\x60\xda\x77\xf8\xdf\xe5\x7d\xd0\xd4\x31\xbe\xcb\xf4\xa0\xa9\xe2\x38\x16\x3f\xec\xc7\x44\x03\xa3\x87\x8f\x68\xd9\xfc\x5f\xf0\xf1\xe8\x57\xb0\x8c\x29\x12\x63\xd8\x5f\xed\xfd\xb9\xff\x0f\x0c\x2b\xb7\x72\xa8\x3b\xcf\xdf\x86\x65\x54\x5c\x04\xae\xe6\x4d\x98\x05\x94\xaa\x4c\xb9\xe2\x58\xe2\x04\x3f\xd2\xad\x22\xc0\xb0\x24\xac\xc9\x34\xe6\x15\x06\x36\x7d\x0b\x0b\x9f\x74\xe2\x72\xfe\x56\x4e\x71\x06\x7b\x6c\xa8\x47\x85\xf3\x8d\xc3\x8d\xa9\x25\x5c\x97\x19\xf4\xca\x9b\x06\xc5\x2a\x71\x11\x84\xc7\x27\x46\xfd\xa6\x74\x41\xbb\x8a\xf5\xc9\x54\xcf\xdc\xe5\x95\x1c\x19\x21\xfd\x17\xb9\x19\x40\x99\xb3\x9d\xb8\x0f\x03\x32\x87\x3a\x9b\xb0\xaa\x94\xc7\xee\x13\xe1\xf7\xf6\xc7\x6f\xe0\x43\xc1\x1f\x3e\xdf\xea\x97\x07\xa4\x65\x1f\x3d\x12\x5c\xba\xac\xd6\xe5\xcc\x15\x22\x6a\xc7\x1b\x4f\x60\xa3\x43\x7e\x7a\x73\x91\x3e\xd1\xab\x36\x67\xaf\x51\x42\x1e\x53\x77\xa6\x2f\x3a\x8d\x9e\xbb\xa8\x23\xb2\xd1\x83\xf9\x13\x6e\xa7\x6e\xd6\x97\x8d\xe0\xd6\x8c\xb1\xf2\xea\xa6\x5b\x95\xd0\xb3\x94\x3e\xa2\xb5\x84\x37\xfa\xfc\x7b\x39\xfd\xeb\x2d\xa7\x27\x4b\xe7\x47\xfb\x88\xe7\x2d\x7c\xb8\xe1\x0f\xfb\xc8\xe9\x47\xbf\xa7\xa0\x02\xba\xfb\xc8\xea\x97\x8b\xaa\x91\xf3\x66\x76\x37\x46\x07\x58\xed\xce\xda\x47\xeb\x5e\x9d\x80\xfd\x7d\x57\xde\xfe\xf2\x45\x8e\x13\xee\x3d\x65\xc0\xaf\xdf\xf3\x9c\x01\xc6\x95\xf0\x37\xb5\xd4\x51\xda\xce\xcd\x7f\xb0\xdf\x5d\x52\x5c\x2c\x7e\xe9\xd9\x88\x11\xc8\x67\x58\x98\x47\xe7\x02\x66\x72\xe2\x1a\x17\x55\xb5\xe4\xdf\xc3\x3a\xbf\xd0\x67\xaf\x1e\x1e\x22\xbf\xac\x71\x9d\x3e\x72\x19\x30\x0c\x47\x7e\x26\xf5\x3d\x4b\xf0\x88\x00\x2c\x55\xfa\x3a\xf6\x8e\x70\x3d\x98\x1b\x3b\x08\x83\x1f\x72\x1a\x49\x93\x8b\x3b\xa5\x06\x2a\xde\x0b\x62\x9a\x4a\xa8\xf6\xc8\x58\x37\xb0\xba\x8f\x75\x66\x9d\x1c\xc5\xb1\x3b\x2d\x79\x80\x64\xf2\x86\x70\x40\x8e\xe3\x96\x83\xba\xd6\x8d\xed\x06\x01\x61\x87\x4e\xbd\xf3\x87\xe1\xfb\xe3\xee\x2f\x6c\x00\xb7\xf0\xb7\xd3\xb6\x73\xab\xcb\x24\xcb\x41\x17\xdf\x7c\x1a\x63\x7a\x7c\x6b\xdf\x94\xfc\x97\xe3\x5e\xef\x01\xcf\x9a\xe1\x8c\xe4\x2f\x9e\x0b\xac\xd7\x65\x5b\x2c\xf3\xb7\xf4\x80\xee\xbf\x84\xf5\x58\xf2\x65\xfa\xf4\xa3\x73\xdf\x46\x84\x5a\x4a\x5d\xbb\x37\xad\x1b\xc0\xaa\xd6\xb8\x51\xc5\xaf\x66\x58\x15\x65\xe1\x81\xbf\x2a\x6a\x30\x85\xe9\x02\x1f\x1b\x69\x91\x37\x2a\xa8\x40\xe3\x73\xd5\xac\x4f\x4f\xbf\x0b\xde\x96\xcf\xed\xaf\x23\xa5\xd1\x3a\xa4\x2c\x85\x4b\x9d\x63\xef\x13\x60\xbd\x1c\xd0\x0b\x5e\x1d\x99\xfa\xf5\xe9\x75\xf4\x46\x24\xea\x3a\x30\xc9\xf3\x3e\x84\xa7\xd7\x01\xca\x78\xe1\xff\xbe\x28\xc7\x2e\x16\xfb\x1d\x27\xd2\x7b\xf9\x53\x33\xe9\xac\x84\x3d\x26\x4e\xcb\xd4\x1d\x43\xde\xbd\x06\xa6\x31\xc5\x73\x64\xa3\xc5\x30\x6f\x27\x42\x46\xc0\xce\xa7\x17\x2c\x4c\xf4\x5b\x0a\x46\x26\x64\x9d\x6c\xd5\x66\xb1\x5f\x7e\x52\x40\xf7\x52\x6d\x66\xe9\x4d\xfb\x15\x9b\x5a\xa0\x53\xa3\x6b\xcd\x22\xfd\x2a\xcf\x57\x2f\xff\xb1\xce\x16\xa3\xec\x78\x9c\x64\x27\xfe\x6f\x72\x18\x3d\x56\x1c\xc7\x5d\xdd\x0c\x67\x51\x9c\xf4\xbc\x3c\x91\xba\xca\x63\xa4\x0c\xb4\x52\x9a\x83\x8f\xcd\x3f\xaa\xf7\xe6\x60\xf7\x89\xfe\x72\xdc\x73\x26\xb5\x38\x89\xbd\xd8\xa6\x99\x66\x30\x4f\x36\x9a\x70\xb2\xdf\x34\x23\xe3\x05\xc0\x14\xc6\xd6\x25\x00\x94\x25\x68\x6b\xe8\xd3\xe9\xb7\x01\x32\x6d\x4e\xcc\xcd\x27\x9b\xa2\x29\x30\xf3\x05\xea\xe9\xe4\x22\xdc\xb3\x2d\xf5\xe6\xc9\xb3\xcd\x31\x9d\xb4\x59\x14\x33\x0e\xdb\x3c\xdb\x9c\xa8\x07\x0a\x73\xbf\x25\x68\x63\xaf\xa5\x3d\x1f\x7c\x2c\x07\x5f\x90\x1a\xd0\x40\xbe\xc4\x28\x60\x8d\x72\xe8\x13\xdc\x2d\x20\x29\x1a\xf7\x53\x0f\xe3\xe0\x6e\x80\x9f\xe5\xca\x50\xa7\x55\xcd\x84\x4d\x49\x0f\x00\x5d\xf1\x0f\x6c\x51\xc3\xf3\xa3\x0b\x3a\x4d\x7c\xe2\x3f\x3d\xbe\xf0\xaf\x08\x60\xf6\xbb\x23\xa3\x06\xaa\xdd\xc8\xe4\xc1\x38\xe9\x90\xf5\x81\x47\x1c\xcb\x18\xc6\xc2\xdd\x35\x47\x2f\x17\x71\xac\xcf\x66\xbb\x4b\xb2\xf9\x95\xc9\x53\x30\x61\xbd\xac\x45\xf4\x86\x03\xe9\xa6\x13\x72\xd0\xcf\x7e\xdd\x3e\x6f\xd0\xae\x78\x1e\x08\xfa\xcb\x79\x07\x0e\x14\xf1\xd8\x9c\x6e\xd3\xf9\x12\x33\xf0\xe3\xa0\x7b\x5e\xaa\x0c\x2e\x6c\x88\x48\xae\x4d\x9c\x13\xf5\xd4\x17\xa6\xf6\x8e\x7b\x1c\xfc\x49\x74\xf3\x07\x3e\xf9\x30\xc8\x7c\x12\x4d\xfa\xa8\x46\x2c\x2a\xf2\xcd\x1f\x25\x86\xbe\xb9\xf5\x0d\xfa\xd8\x8f\x82\xba\x5f\x6d\xff\xab\x60\xe8\x4b\x10\x2d\x7b\xdc\xbd\x18\xef\x49\x7a\x73\x7b\x06\x8d\xac\xbe\xbc\x2f\xe9\x25\x67\xb9\x53\x66\x23\x92\xb3\x87\xc0\xfa\xf2\x6a\x44\x95\x6e\xe1\x25\x72\xc0\xe8\xdf\xc2\x17\x23\xb1\x68\x8d\xe1\xcb\x74\x6f\xc9\x35\xb7\x07\xb3\x56\x21\xc0\xa6\x1e\x8f\xf6\x1a\x1e\x83\x45\xf4\x56\x2c\x91\x05\x6d\x34\x00\x3e\x78\x43\xfa\x15\xfa\x85\x1a\x16\x3a\x04\x8f\xba\x8c\x81\x6e\x64\x24\x9c\xfc\x0a\x56\x84\x65\x02\xbd\xf2\xcd\xd7\x23\x84\x09\x5a\xd7\xad\x87\x25\xdb\xaf\x03\xb4\x1b\xf6\xab\x86\x66\xb5\x4f\x8a\x0e\x37\x31\xc9\xd1\xed\xd3\xfa\xc4\x65\xf4\x9c\xb3\xf4\xbf\x01\x00\x00\xff\xff\xd1\x07\xdc\xea\xf4\x81\x00\x00"), + }, + "/src/reflect/reflect_test.go": &_vfsgen_compressedFileInfo{ + name: "reflect_test.go", + modTime: mustUnmarshalTextTime("2016-06-27T01:43:45Z"), + uncompressedSize: 701, + + compressedContent: []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x8c\x91\x4f\x4b\xc4\x30\x10\xc5\xcf\xc9\xa7\x08\x7b\x6a\x75\xd9\xc5\xeb\xde\x6a\x17\x65\x41\x28\xd8\xe2\x45\x44\x62\x3a\xa9\xb1\xb3\x69\x49\xd3\x4a\x59\xfa\xdd\x4d\xd8\x22\xd6\x7f\xe4\x10\x18\xe6\xfd\xde\x64\xf2\xb2\xdd\xb2\xcb\x97\x5e\x61\xc9\xde\x3a\x4a\x5b\x2e\x6a\x5e\x01\x33\x20\x11\x84\x7d\xb6\xd0\x59\x4a\xd5\xb1\x6d\x8c\x65\x11\x25\xab\x59\x58\xb9\xd2\x6b\x4a\x57\x2b\x1a\x53\x2a\x7b\x2d\x58\xe1\x1a\x09\xaa\x4a\x1f\x41\xdb\xc8\xb2\x8b\x99\xd8\x14\x31\x3b\x51\x62\x37\x79\xad\xda\x28\xa6\xd3\x17\x3e\x47\x25\x20\x1b\xc0\x48\x6c\xde\x03\x3d\x37\xae\xb8\xe3\x63\xd3\x87\x5e\x92\x18\xc3\xc7\x4c\xee\x95\x71\xab\x1f\x24\x17\x10\x68\x2c\xc6\x16\x50\xe9\xba\xcb\xdd\xfb\xa1\x0c\x74\xdd\xa6\xd7\xca\x76\x81\x70\xfa\xca\x75\x82\xd8\x88\xd0\xc0\xc0\xe7\x9f\xe9\x83\x1e\x38\xaa\x5f\x56\x9a\x7f\x68\x73\x06\xa3\xc7\xa7\x65\x23\xe5\x1d\x38\x8a\xf8\x43\x5c\x22\x3b\xc6\x96\xc0\x3d\x88\x61\xed\x45\xbf\xd9\xee\x53\x7c\xe0\xd8\xc3\x69\xf2\xca\xb4\x66\x7f\xba\x73\xd0\xe5\xff\x6e\xe2\x91\x6f\x4a\x26\xa3\xab\xf8\xc7\xe8\xe5\xe4\x3d\x48\xde\xa3\x3d\x53\x94\x4c\x3e\x96\x8f\x00\x00\x00\xff\xff\x43\xcd\x21\xd1\xbd\x02\x00\x00"), + }, + "/src/regexp": &_vfsgen_dirInfo{ + name: "regexp", + modTime: mustUnmarshalTextTime("2016-06-27T01:43:45Z"), + }, + "/src/regexp/regexp_test.go": &_vfsgen_fileInfo{ + name: "regexp_test.go", + modTime: mustUnmarshalTextTime("2016-06-27T01:43:45Z"), + content: []byte("\x2f\x2f\x20\x2b\x62\x75\x69\x6c\x64\x20\x6a\x73\x0a\x0a\x70\x61\x63\x6b\x61\x67\x65\x20\x72\x65\x67\x65\x78\x70\x0a\x0a\x69\x6d\x70\x6f\x72\x74\x20\x28\x0a\x09\x22\x74\x65\x73\x74\x69\x6e\x67\x22\x0a\x29\x0a\x0a\x66\x75\x6e\x63\x20\x54\x65\x73\x74\x4f\x6e\x65\x50\x61\x73\x73\x43\x75\x74\x6f\x66\x66\x28\x74\x20\x2a\x74\x65\x73\x74\x69\x6e\x67\x2e\x54\x29\x20\x7b\x0a\x09\x74\x2e\x53\x6b\x69\x70\x28\x29\x20\x2f\x2f\x20\x22\x4d\x61\x78\x69\x6d\x75\x6d\x20\x63\x61\x6c\x6c\x20\x73\x74\x61\x63\x6b\x20\x73\x69\x7a\x65\x20\x65\x78\x63\x65\x65\x64\x65\x64\x22\x20\x6f\x6e\x20\x56\x38\x0a\x7d\x0a"), + }, + "/src/runtime": &_vfsgen_dirInfo{ + name: "runtime", + modTime: mustUnmarshalTextTime("2016-06-27T01:43:45Z"), + }, + "/src/runtime/debug": &_vfsgen_dirInfo{ + name: "debug", + modTime: mustUnmarshalTextTime("2016-06-27T01:43:45Z"), + }, + "/src/runtime/debug/debug.go": &_vfsgen_fileInfo{ + name: "debug.go", + modTime: mustUnmarshalTextTime("2016-06-27T01:43:45Z"), + content: []byte("\x2f\x2f\x20\x2b\x62\x75\x69\x6c\x64\x20\x6a\x73\x0a\x0a\x70\x61\x63\x6b\x61\x67\x65\x20\x64\x65\x62\x75\x67\x0a\x0a\x66\x75\x6e\x63\x20\x73\x65\x74\x47\x43\x50\x65\x72\x63\x65\x6e\x74\x28\x69\x6e\x74\x33\x32\x29\x20\x69\x6e\x74\x33\x32\x20\x7b\x0a\x09\x72\x65\x74\x75\x72\x6e\x20\x31\x30\x30\x0a\x7d\x0a"), + }, + "/src/runtime/pprof": &_vfsgen_dirInfo{ + name: "pprof", + modTime: mustUnmarshalTextTime("2016-06-27T01:43:45Z"), + }, + "/src/runtime/pprof/pprof.go": &_vfsgen_compressedFileInfo{ + name: "pprof.go", + modTime: mustUnmarshalTextTime("2016-06-27T01:43:45Z"), + uncompressedSize: 462, + + compressedContent: []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x94\x90\x41\x6b\xc3\x30\x0c\x85\xcf\xd1\xaf\x10\x39\xc5\xdb\x68\x7f\xc4\x2e\x3b\x6c\x50\xd8\xc6\x0e\xa5\x07\xd7\x55\x82\xd7\xc4\x16\x8a\x4c\x57\x4a\xff\xfb\xec\xb4\x2b\x81\x1d\xc6\x72\x08\xe8\xbd\xf7\x3d\x64\x2d\x97\x78\xbf\x4d\xbe\xdf\xe1\xe7\x08\xc0\xd6\xed\x6d\x47\xc8\x2c\xb1\x05\xf0\x03\x47\x51\x6c\xa0\xaa\x7d\xac\xf3\x7f\x3c\x06\x57\x83\x01\xd0\x23\x13\xae\x72\xc8\xf7\x84\xa3\x4a\x72\x8a\x27\xa8\x82\x1d\x08\xcb\xec\x43\x07\xd5\x90\x30\x7f\x85\x59\xbc\x24\xa5\xaf\xac\x14\x01\x07\xcb\x6b\x1f\x94\xa4\xb5\x8e\x4e\xe7\xcd\x7a\x93\xf2\xc8\x2a\x50\xb9\x98\x82\x62\x9b\x82\x6b\x0c\x66\x11\xaa\x83\x78\xa5\x8b\xe2\xe3\xe2\xa3\x4c\xf2\x50\x2c\x83\x24\x12\x05\xce\x00\xc5\xc5\x86\xf1\xee\xba\x91\xc1\x29\xf7\x16\x9b\x03\xce\xa0\x1d\x6d\x53\x37\x43\xcb\xc6\x42\x9a\x24\x60\xf0\xfd\xad\xe8\x55\xad\xe8\xe3\xea\xfd\x5a\x36\xef\xf8\x0b\x8c\x3c\xe3\x4c\x8e\xfd\x58\x13\xfe\x44\x96\xff\x5d\xfa\x1c\xe3\x3e\x71\x33\x5d\xf6\x72\x58\x73\x7b\xe7\x2f\xe4\x3b\x00\x00\xff\xff\x04\x28\x27\xe9\xce\x01\x00\x00"), + }, + "/src/runtime/runtime.go": &_vfsgen_compressedFileInfo{ + name: "runtime.go", + modTime: mustUnmarshalTextTime("2016-06-27T01:43:45Z"), + uncompressedSize: 4711, + + compressedContent: []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x9c\x58\xed\x6e\xdb\xbc\x15\xfe\x6d\x5d\xc5\x99\xb1\x0d\x72\x9a\x26\x4d\xf6\xb6\xc3\x8a\xf5\x47\xeb\x35\x6e\x81\x36\x0e\xe2\x74\x2b\xd0\x15\x05\x2d\x53\xb6\x62\x49\xd4\x48\x2a\x8e\x57\xe4\x02\x76\x21\xbb\xb1\x5d\xc9\x9e\x43\x8a\x92\x9c\x38\xed\xf6\xe6\x47\xe2\x1c\x3e\xe7\x83\xe7\x8b\xe7\xf8\xf8\x98\x9e\xcc\xeb\x2c\x5f\xd0\xb5\x89\xa2\x4a\x24\x6b\xb1\x94\xa4\xeb\xd2\x66\x85\x8c\xa2\xac\xa8\x94\xb6\x14\x47\x83\x61\x43\x3b\xce\x4a\x2b\x75\x29\xf2\x63\xb3\x35\xc3\x08\x07\xcb\xcc\xae\xea\xf9\x51\xa2\x8a\xe3\xa5\xaa\x56\x52\x5f\x9b\xee\xc3\x35\x30\xa3\x28\x4a\x54\x69\x2c\x4d\xa6\xd3\x19\xbd\x22\x30\x1e\x5d\xad\xe4\x44\x29\xd3\x1e\xbc\xbe\x1c\xbf\xc3\xd1\x90\xf1\x9e\x36\x56\x45\x95\xe5\x52\x33\x35\x88\x83\x3e\x18\x9c\x8a\xb5\xa4\x54\x69\x92\x5a\x2b\x7d\xb4\x54\x91\xdd\x56\x92\x64\x2a\x12\x49\xc6\xea\x3a\xb1\xf4\x3d\x1a\x7c\x73\xd4\x83\x8e\x30\xf8\x86\xcf\x59\xb9\x74\x34\xfc\x8d\x06\x77\xd1\x5d\x14\xa5\x75\x99\x50\x56\x66\x36\x1e\x31\xea\xda\x5c\xac\x97\xf4\xf2\x15\x1c\x72\x34\xc9\xd5\x5c\xe4\x47\x13\x69\xe3\xe1\x6f\x1b\xe7\x98\xe1\xc8\x13\x7e\x76\xef\x11\xcb\x0a\x22\x66\x4e\xc4\xb5\x99\xce\xaf\x65\x62\x2f\xac\x1e\x1e\x92\xd3\xe4\x65\x79\x72\x90\x5c\xe1\x78\xb4\x97\xfd\x2d\xdf\xf8\x01\xb7\xa3\xfe\x8c\xd9\xae\xb4\xda\x5c\xfa\x20\x7a\x06\x96\x71\xf4\xbe\x09\xa7\xb7\x20\x66\x67\xc4\x85\x59\x92\x77\x91\xf3\xc8\xa0\x12\x65\x96\xc4\xce\xdb\x33\x47\x66\x04\xeb\xb8\xe3\x5f\x88\x88\xb8\x51\xd9\x82\x16\x52\x2c\x28\x51\x0b\x84\x22\xcf\x8a\xac\x14\x36\x53\x65\x34\xb8\x11\x88\x94\x8f\x55\x34\x90\x08\xe7\xef\xaf\x10\x98\xd7\xc6\x48\xcd\x00\x67\xcb\xf7\x3b\xc4\x0b\x47\xb2\x0d\xc8\x64\x7a\x39\x9d\x5e\x21\x24\x4d\xcc\x60\x47\xa5\x55\x22\x8d\xd9\x13\x9b\xe6\x84\x5d\x9e\xa5\x14\x70\xaf\x1c\xee\x53\xb9\x90\x69\x56\xca\x85\xbb\x8a\x96\xb6\xd6\x25\x0d\x8f\x87\x1c\xfd\xc1\x52\x69\xa5\x2c\x4b\x6c\x98\xbc\x3c\x59\xde\x04\x77\x7a\x3b\x1a\xc9\x0d\xfc\x37\x8f\x0b\xf6\x88\xa3\xc6\x4d\x23\xa7\xa4\x39\xe2\xb4\xff\x0b\x92\xb4\xce\xed\xc4\xa1\xda\xbb\xbe\xd1\x52\xac\x2b\x85\xca\x0a\x29\x08\xe0\xbc\x5e\x2e\xa5\x86\x88\x80\x1a\x8b\x1c\xe5\x10\x9b\x75\x56\x21\x5d\xed\x88\xe2\x2a\xa1\x1a\x9f\x10\xf1\x43\x4a\x51\x2b\x8d\xaf\x0e\x29\x87\x59\x8c\x39\x24\xb5\xa6\xb9\x52\xb9\x13\x9b\x95\xa9\xda\xe3\xbc\x90\x3d\xe7\x72\x13\x37\x97\x36\x16\xb9\x0e\x12\xab\xc4\x7f\x55\x9e\x59\x64\xcb\xf0\xef\x25\x68\xef\x71\xed\x5b\x6f\xc5\x13\x3a\xf5\x7e\x71\x92\x7f\xe0\xee\x67\x60\x86\x00\xfc\x49\x45\x6e\xa4\xf3\x4a\x25\xb4\x75\xb1\x64\xe6\xa0\xa9\x9e\xfb\x2b\x00\xdc\x23\x67\xac\x72\x9a\xb2\x09\xb1\xb3\x00\x7e\x7a\x72\xf2\x18\x64\x14\x20\x0f\xec\x7f\xc9\x61\xec\x4c\x72\x16\x34\xf7\x79\x36\x6a\x63\xb6\x7b\x70\xd2\x08\x3b\x24\xf4\x11\x79\x2f\x18\xa6\x8d\x06\x98\x12\xfa\xf2\xb5\x09\xc7\x88\x49\xec\x80\xa0\xac\x4b\xeb\xb1\x0b\x71\xfb\xaf\x92\xb7\x5d\xe3\xd9\xed\x37\x49\xad\x39\x4f\x6a\x0b\x6f\xe2\x4a\xae\x8a\x19\x3d\xf4\xa6\xec\x94\xb8\xbf\xa8\xaf\x71\x9c\x97\x59\x3e\xea\x55\xd2\xc7\xd7\x9f\x2f\x2e\xa7\xe3\x59\x5c\xfa\xc4\xd9\x35\xee\xa4\x67\x8d\x49\x56\x72\xe1\xcd\x49\x38\x36\x05\x5a\x6d\x9c\xac\x44\xd9\xf4\xd5\xef\x77\x7b\xd4\x1a\x69\xaf\xd0\x54\x60\x29\x54\xbb\x06\x02\x01\x94\xe4\xca\x80\x77\x44\x77\x08\x3c\xb8\xfe\xfc\x34\x69\x15\x9d\xd7\xc5\xf8\xe2\x53\xfc\xb8\x25\x00\xb4\x77\x7f\x00\xbb\xef\x28\xab\xac\xc8\x5b\xb8\x09\xe1\x67\x61\xee\x09\xf8\x28\x8b\x99\x15\x48\xb6\xee\x29\x40\xcf\x9a\xc8\x52\x6a\x91\x83\x88\x3e\x65\x6c\x96\x98\xa3\x68\xf0\x3a\xcf\x55\x42\xee\x87\x43\xf9\xe2\x17\x02\x72\xbe\xb5\xd2\x90\xe0\x23\x61\x91\xd8\xa2\x5c\x80\x2b\xcb\x73\xd8\x45\x35\xa7\xf3\x15\x5b\xe0\x79\x1f\x67\x8b\xe5\x8d\x44\x00\x52\x4a\xb5\x94\x0b\x78\x64\xb6\x35\x44\xfb\x95\xa9\xb9\x15\xae\x88\x52\xad\x0a\xee\x1c\x56\x16\x14\x9b\xba\x20\x95\xd2\xe7\xdb\x5b\x66\x9d\xcb\x5c\x6d\x20\xe6\x83\x52\xeb\xba\x32\xbb\x62\xca\xba\x98\xe3\xed\x04\xda\xf5\x15\x7c\xcc\x3d\x2c\x1a\x7c\x74\x26\x3d\x8a\x2f\xfc\x71\x34\x38\x83\x99\xe6\xbe\x79\x1d\x8e\x6f\x81\x91\x81\x5d\xf9\x11\xb6\x86\x8b\xa2\xa3\xd3\x4a\x8a\x6a\xd7\xaf\xef\x40\x69\x7d\xfb\xff\x78\x96\x19\x5b\x3f\xfd\x2f\x5e\xf2\x2c\xef\x17\xe8\x86\xfb\x58\x20\x37\xe3\x33\x83\x37\xcd\x34\xd8\x12\x9a\x1e\xc1\x96\xaa\x7c\xda\xe2\x3d\xfc\x52\xe6\x52\x18\x28\xbd\x0f\xd7\xe1\xc0\x2a\xb2\x2b\x49\xd3\x99\x67\xf0\x2f\xab\xe9\xcb\x77\x19\xdb\xf3\x65\xe7\x01\xe5\xc1\xde\xaf\x1f\xd4\xe6\x69\x8e\xac\xc9\xd1\xdd\x6f\xe5\xe2\xa9\xc9\xfe\x19\x06\x9c\x5a\xcb\xc0\x85\x41\x68\xc7\xd7\xc7\xc7\x03\x7f\xa5\xcc\x34\x96\xd5\x6c\x55\xa9\x36\xfe\x90\xdd\xd9\x1e\xed\x73\x21\x60\x33\x7e\x00\x1a\xc7\xdc\xbf\xa7\x93\x36\xdf\x92\x7b\x24\x3a\x23\x1a\xa6\x26\x58\x9e\x09\xc9\x36\x83\xe3\x1e\x08\x2a\xd8\x9d\xdd\x4d\x4c\x83\xbb\xcf\x3b\x16\x68\x47\x9e\xb9\xc7\x9b\x30\x75\x97\xd9\x01\x3d\x77\x60\x7e\x53\x27\xeb\x77\xc2\xac\x98\xda\x31\xe3\x95\xc7\x43\xc9\xf3\xc4\x1c\xe7\xd2\xd2\x0a\x10\xb2\x62\x9e\x23\xd7\x26\xe3\xae\x22\x3b\x96\xc9\x98\x0a\x69\xc5\x42\x58\x11\x0d\xa6\x08\xac\xde\x31\x93\x21\x8a\xa9\xa1\x4a\xbb\x3a\x68\xa2\x38\x11\x7a\xce\x43\x75\xa2\xf0\x64\x24\x0f\xc2\x75\x2e\x6f\x2d\x74\x3c\xd0\x5b\x82\x1e\x78\xb8\xa8\x36\x5c\x16\x2b\x51\x55\x68\x22\x9b\x15\x7e\x75\x35\xf5\x9f\x7f\xfd\x1b\x19\x87\x98\x8a\x42\x61\xc0\x43\x4b\x10\x66\xaf\x4c\x89\xfa\xe2\xf9\x8f\x73\x2e\x07\xa6\x2f\x3f\x2e\x45\x89\x8e\x8d\xe1\x7b\x81\x4e\x99\x95\x98\xa5\x4f\xfe\xf4\x47\xee\xdc\x17\x02\x11\x70\x2d\xee\xdc\x74\x0e\x76\xd4\xf3\xe0\xaf\x2f\xa7\xcf\x5f\x7c\xed\x14\x25\x99\x4e\xea\x1c\x83\xdf\xbc\x4e\x53\x9f\xe3\x5a\x26\x12\x6d\x1c\x66\x55\xcc\x49\x8b\x5a\x7b\x2f\x1d\x52\xa1\x60\x4a\x73\x2e\x2c\x7d\x89\xb9\xfd\x8f\x9f\x9c\x3e\x7f\x3e\xfa\x1d\xcb\x6d\x94\xbd\x85\xf5\xbf\x52\x59\xb8\x38\x92\xc5\xc9\xa6\xbe\x6f\xfe\x70\xca\xb1\xc7\x83\x74\xa6\x85\xf7\x45\x9a\x2b\xd1\x08\x4f\x03\x0d\x52\x01\xf1\xee\x0b\x25\x30\x19\x47\x83\xb7\x25\x67\x4f\x10\xc9\xc3\x56\x34\x70\xd3\x5b\xab\xc5\xd1\x5c\x2a\x5c\x48\xed\x8b\xb8\xd7\x2c\xef\xd5\x2e\xbd\x38\xe1\xea\x84\x95\x33\x00\xc7\x88\x92\xf1\xad\x88\x5b\xca\xd8\x8d\xd7\xc0\xbd\xd9\xf2\x29\x7d\x79\x71\xf2\xb5\xb7\xdf\x38\x5a\xef\x52\x6d\xab\x0f\x31\x6b\x7b\x7a\x20\x74\x0b\xd0\x25\x86\xf7\xf0\x50\xc6\x05\x1d\x84\xcf\xfd\x69\x05\x23\xc8\x19\xc6\xfa\x1c\x6a\x74\x7c\x8b\xb7\x9e\xdc\xd3\xc2\x7b\x17\x06\x03\x0f\x74\x2f\xee\x19\xa3\x3b\xc3\x54\x25\xfe\x51\xcb\x76\x84\x60\xb7\xd6\x48\x6f\x5e\x2d\xb9\xf3\x64\x32\x77\x4d\x73\x91\x19\xb6\x77\x83\x4b\x96\x37\x18\xae\x5c\x09\x05\xdd\xf1\x37\x3a\x60\xb1\x23\x7a\x5b\x5a\xbd\xc5\x50\xd0\xcc\x5a\xf4\xc3\x9f\xef\x14\x46\x30\xba\xbb\x2f\xe8\x0c\x23\xf3\x07\x1e\x30\xba\x39\x1a\x43\xf5\xde\x41\x7a\xd4\x09\x72\x83\xec\x43\x61\xe7\xa2\x90\xdd\xb6\xf2\x93\x9f\x9e\x30\x0a\x17\x64\x31\x67\x58\xee\xc6\x3b\xe6\x38\xe9\xbd\xd9\x07\x93\x1d\xbb\x84\x77\x2a\x44\xe8\xc2\xb5\x33\x79\x89\xa7\xc3\xcd\x48\xaf\xe8\xf9\xc9\x29\x1d\xd0\xc9\xb3\xd3\x5f\xba\x98\xbd\x41\x0e\xac\x7b\xd0\x58\x37\xf8\x9d\xd8\x72\xf3\x8e\x51\x41\x98\x62\xb9\xcf\x1f\x72\x8e\x36\xbb\x43\x33\x7e\xed\xdb\xbc\x1e\x5f\x1e\xdc\x62\xf0\xc3\x25\xec\x59\x7f\x3b\x4a\x54\xb5\x65\xf5\x87\x64\x76\x96\x81\x61\x47\xe8\xcd\xf8\xcd\x26\xe2\xf6\x80\x6e\x72\xef\x66\xde\x0f\xb8\xf1\x74\x76\xb5\xc2\x62\xe5\xc6\xd9\x40\xff\x54\xe6\x8f\x9c\xfc\xd5\x27\xdc\xce\xc2\xd9\x5b\xdc\xae\x56\xb2\x41\xf4\x3d\xa6\xed\x15\xda\x03\xc7\xdd\xad\xb7\x5d\x5c\x11\xa6\x90\x22\x33\xab\xaa\x80\x0a\xe1\xbf\xeb\x6a\x2e\x1c\x79\xaf\xbb\xef\x37\xfe\x26\xfd\x57\x1c\x82\x92\xa5\x42\xeb\xba\xc9\xb4\x2a\x0b\xee\x67\x28\x12\x74\x8d\x64\xe5\xd5\x99\x23\x82\x59\x5a\xf2\x57\x21\x1b\x89\xb7\xe1\x46\x32\x22\x2b\xaa\x5c\x7a\xb8\x7b\x13\xd0\xfa\x44\xbe\x11\x5b\xd3\x96\x42\x37\x84\x2f\x95\x73\xad\x0b\x31\xfa\xdd\xbe\x8d\xc5\x7d\xad\x32\x4d\x63\x59\xd1\xc1\x4e\xb9\x1f\xf8\x2f\x5c\x78\x31\x77\xdf\x0f\x0c\x1b\xe4\x4b\x8c\x1a\x96\x4c\x5d\xf9\xfa\x1e\x72\x54\xfe\x1b\x00\x00\xff\xff\xd7\xc0\x45\xc1\x67\x12\x00\x00"), + }, + "/src/strings": &_vfsgen_dirInfo{ + name: "strings", + modTime: mustUnmarshalTextTime("2016-06-27T01:43:45Z"), + }, + "/src/strings/strings.go": &_vfsgen_compressedFileInfo{ + name: "strings.go", + modTime: mustUnmarshalTextTime("2016-06-27T01:43:45Z"), + uncompressedSize: 806, + + compressedContent: []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\xa4\x92\x41\x6f\xd4\x30\x10\x85\xcf\xf1\xaf\x18\xe5\x14\x2b\x4b\xb6\xbd\xa1\x95\xca\x81\x1c\xaa\x95\x90\x2a\xc1\x11\x71\x70\xbc\x93\xc4\xa9\xd7\x8e\x3c\xb6\x00\xa1\xfe\x77\xc6\xc9\x86\x2e\xa5\x17\xe0\xb2\xf2\x3e\xbf\xf9\xde\xb3\x9d\xfd\x1e\xea\x2e\x19\x7b\x82\x89\x84\x98\x95\x7e\x54\x03\x02\xc5\x60\xdc\xc0\x82\x39\xcf\x3e\x44\xa8\x44\x51\x26\x67\xb4\x3f\xe1\x3e\xc5\xfe\x6d\x29\x58\x18\x4c\x1c\x53\xd7\x68\x7f\xde\x0f\x7e\x1e\x31\x4c\xf4\xbc\x98\xa8\x14\x52\x88\x3e\x39\x0d\x47\x77\xc2\x6f\xef\xbf\x47\xac\xe8\x42\xde\x81\x86\x8e\x05\x09\xc6\x45\xf8\x21\x8a\x80\x31\x05\xc7\x1d\x9a\xa3\x8b\x18\x9c\xb2\x0f\xdd\x84\x3a\x56\x24\x9b\x56\x59\x5b\x95\x26\x43\x1e\xfa\x72\x97\x4d\xf7\xd6\x77\xca\x36\xf7\x18\xab\xf2\xd3\x42\x2c\x37\x5f\x1f\xfc\xb9\x1d\x55\x68\xb9\x2b\x9b\xb5\x94\x19\x59\x49\xf1\x74\xdd\xa6\xa2\x1d\x10\xce\x97\x3a\xff\x5a\xe3\xa5\x09\xe7\x3f\xd2\x3e\x28\x8a\xff\x97\x68\x37\xc2\x5f\xa4\xb6\x3e\xf1\xff\xd7\x13\x1d\x1c\xee\xe0\x46\x14\xfc\xf2\x34\xa3\x36\xca\x82\x56\x84\x24\x0a\xfa\x6a\xa2\x1e\xb3\x27\x0b\x60\xd1\x2d\x70\xb8\x63\xff\x41\x14\x5b\xd7\xfc\x01\x34\x1f\x93\xc3\x25\xe5\xe8\xd6\x07\xe0\xc2\x50\xc3\xed\xcb\xd9\x77\xeb\x52\x5e\xcd\xdf\xbc\xc2\x7f\x36\x99\x7e\x29\xcd\x1a\xe5\x26\xbf\xa6\x98\x5c\x3c\xfd\x06\xe1\xc3\x16\xbd\x0f\x8b\x6b\xf6\x94\x8f\x75\x7d\xd3\x72\x85\xe5\x1d\x86\xbd\xb9\x5d\x69\x5d\x40\xf5\x78\x41\xb9\xba\xe6\x5f\xde\x06\xfa\xcc\xb6\x7a\x2b\x74\xf8\x92\xe1\x5b\x92\xe3\x5b\xfd\x19\x00\x00\xff\xff\x1d\x5f\x2c\x75\x26\x03\x00\x00"), + }, + "/src/sync": &_vfsgen_dirInfo{ + name: "sync", + modTime: mustUnmarshalTextTime("2016-06-27T01:43:45Z"), + }, + "/src/sync/atomic": &_vfsgen_dirInfo{ + name: "atomic", + modTime: mustUnmarshalTextTime("2016-06-27T01:43:45Z"), + }, + "/src/sync/atomic/atomic.go": &_vfsgen_compressedFileInfo{ + name: "atomic.go", + modTime: mustUnmarshalTextTime("2016-06-27T01:43:45Z"), + uncompressedSize: 3060, + + compressedContent: []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\xbc\x56\x4f\x6f\x9b\x30\x14\x3f\xe3\x4f\xf1\xc6\xa1\x82\x74\x4a\xa4\x2d\xca\xa1\x52\x0e\xd5\x0e\x53\xa5\x49\x9b\x54\x75\x77\x07\x4c\xea\x8c\xd8\x08\xec\x34\x51\x94\xef\x3e\xdb\x40\x30\x60\x58\x97\xb4\x3d\x61\xd0\xfb\xfd\xf1\xfb\x97\xcc\x66\x70\xbb\x92\x34\x8d\x61\x53\x20\x94\xe1\xe8\x0f\x5e\x13\xc0\x82\x6f\x69\x84\x10\xdd\x66\x3c\x17\x10\x20\xcf\x97\xac\xc0\x09\xf1\x91\x3a\xae\xa9\x78\x96\xab\x69\xc4\xb7\xb3\x35\xcf\x9e\x49\xbe\x29\x9a\xc3\xa6\xf0\x51\x88\x50\x22\x59\x04\x8f\x2f\x38\x7b\x60\xe2\xeb\x97\x00\xc7\x71\x0e\x13\xaa\xcf\x9f\x81\x91\x17\x30\xc7\xb0\x7c\xc0\x11\x79\x5c\x39\xb8\x5b\xc2\x44\x07\x22\xcf\x3c\x60\xa9\x23\x91\x97\x13\x21\x73\x06\x2a\x02\x9d\xda\xc4\x8b\x79\x43\xbc\x98\x9f\x89\x17\xf3\xb0\x7c\x5c\x46\xfc\x44\x2d\xcb\xd2\xf2\x2c\x2b\xd3\xf2\x0a\xd7\x4f\xd4\xb2\x2d\x2d\xdf\xb2\x32\x2e\xaf\x74\x9e\x89\xdc\x62\x57\x6f\x0d\xbd\x7a\x09\xeb\xc3\x65\x02\xbf\xb8\x42\x93\xb3\x80\x69\x89\x69\xf5\xb1\xd2\x69\x7d\x0b\x3b\xef\xff\xaf\xfa\x8d\x6f\x33\x9c\x93\x7b\x16\x0f\x34\x93\x0a\x6e\x75\xd4\x8a\xf3\x54\xcb\xd0\x04\x2a\xee\xa5\x8e\xd1\x9f\xda\x62\xb5\x9a\xc8\x25\x41\xde\xe9\xac\x9e\xe0\xb4\x20\xc3\xfa\xdd\x9e\xb3\xf5\x75\xfd\xde\x55\xdf\xd9\x9a\x67\x07\xf2\x23\x52\xe0\x6c\xe0\x96\x85\x0f\xc9\x82\xa3\xcd\x5b\x26\x4c\xaf\xbf\xab\x8b\xf1\x59\x68\xcc\x74\x06\xe2\x8d\x3d\xdd\xc7\xb1\x63\x28\x62\x92\x0a\xdc\xdb\xb1\xda\x4e\x3d\x79\x70\x5b\x06\xb9\x27\x50\x9f\x2d\x05\x67\xdb\x95\x1a\xfd\x9d\x78\xb1\x8a\x63\xb8\xce\xf7\x68\xad\xf4\xab\xee\xd1\xeb\xdd\xe6\x1e\xed\xf5\x7b\x95\x8a\xa3\x3d\x1b\x9d\xee\x1e\xbe\x4c\xe9\x07\xc7\xfd\xd2\x5b\xd5\xae\x20\xe5\x9e\xed\x80\xda\x79\xb6\x52\x3b\x08\x72\xb4\x80\x5d\xf4\x51\x5c\x27\xe5\x76\x92\x47\x71\xbd\x24\xb6\xb2\x36\x08\x1d\x1b\x4c\xd7\x0f\x92\x93\xe8\x51\xf0\x9c\x38\x26\x6b\x87\xd3\x7a\xae\x8e\x4d\x8d\xd4\xd7\x1e\xb2\xdb\xcb\x15\x52\xdf\x7f\x0c\xe9\x9c\x35\x8d\x95\xaf\x90\x75\x36\x78\x0d\x7e\x8d\xb2\xa3\x6f\x6b\xb8\xc9\xff\x18\x7e\x7c\x21\x1a\x9a\x4e\x2d\x06\xd8\x82\x1d\x4c\x7e\xe3\x54\x92\xd0\xd4\x33\x08\x21\xd8\x83\x81\x24\x38\x22\xc7\x53\x68\x55\x6d\x37\xdd\xb9\x70\xc6\x90\x03\xa5\xb6\xee\x5e\x6f\x5c\x46\xcd\x12\xf6\x32\xcc\x68\x14\xf8\xc5\x81\x45\xb3\xf2\x4f\xef\x1d\x14\x1a\x0b\x3c\x31\x41\x3b\xcd\xa7\x69\x38\x18\x6a\x3f\x34\xbb\x58\xf1\x28\x65\xf8\x54\x32\xdd\xdc\xa8\x7f\xcf\xd3\x07\xad\xc5\x70\xfa\x73\xb5\x21\x91\x08\xf6\xe1\xf4\x3b\x11\x81\x1f\x71\x56\xa8\x1d\x1e\x29\x56\x3f\xd4\x88\x7e\xa8\xa2\x72\x06\xff\xd3\x21\x65\x1a\x40\x0b\x41\x98\x48\x0f\x20\x0e\x19\x89\x87\x2c\x6b\xbf\x4b\xd8\xab\x6c\xfd\x0d\x00\x00\xff\xff\x2a\xf7\xf1\xfd\xf4\x0b\x00\x00"), + }, + "/src/sync/atomic/atomic_test.go": &_vfsgen_fileInfo{ + name: "atomic_test.go", + modTime: mustUnmarshalTextTime("2016-06-27T01:43:45Z"), + content: []byte("\x2f\x2f\x20\x2b\x62\x75\x69\x6c\x64\x20\x6a\x73\x0a\x0a\x70\x61\x63\x6b\x61\x67\x65\x20\x61\x74\x6f\x6d\x69\x63\x5f\x74\x65\x73\x74\x0a\x0a\x69\x6d\x70\x6f\x72\x74\x20\x22\x74\x65\x73\x74\x69\x6e\x67\x22\x0a\x0a\x66\x75\x6e\x63\x20\x54\x65\x73\x74\x48\x61\x6d\x6d\x65\x72\x53\x74\x6f\x72\x65\x4c\x6f\x61\x64\x28\x74\x20\x2a\x74\x65\x73\x74\x69\x6e\x67\x2e\x54\x29\x20\x7b\x0a\x09\x74\x2e\x53\x6b\x69\x70\x28\x22\x75\x73\x65\x20\x6f\x66\x20\x75\x6e\x73\x61\x66\x65\x22\x29\x0a\x7d\x0a"), + }, + "/src/sync/cond.go": &_vfsgen_compressedFileInfo{ + name: "cond.go", + modTime: mustUnmarshalTextTime("2016-06-27T01:43:45Z"), + uncompressedSize: 469, + + compressedContent: []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x6c\x90\x41\x53\xc2\x30\x10\x85\xcf\xd9\x5f\xf1\x8e\xc5\x4e\x81\xd1\x9b\xc2\x45\xae\xbd\x31\x8e\x47\x27\x84\x00\x91\xb2\xe9\x24\xe9\x38\xe8\xf0\xdf\xdd\x34\xa0\x07\xed\x25\xe9\xee\xbe\xf7\x65\xdf\x6c\x86\x7a\x33\xb8\x6e\x8b\xf7\x48\xd4\x6b\x73\xd4\x7b\x8b\x78\x66\x43\x94\xce\xbd\xc5\xca\xf3\x16\x31\x85\xc1\x24\x7c\x91\x6a\xd1\x7a\x73\xb4\x81\x48\x45\x7b\xd2\x90\x2f\x0f\xaf\xe5\x4e\xea\x43\xbb\x64\x43\xc4\xe0\x38\x3d\xdc\x93\x32\x07\x9b\x67\x61\x7c\x7f\x5e\x95\xbb\xe8\x18\x90\x7e\xee\xc2\x1c\x34\x63\xe3\x7d\x47\x17\xa2\xdd\xc0\x06\x95\xc1\x5d\x46\x4e\xf0\x2a\x66\xd5\x24\x33\xcd\x94\xeb\x9a\x94\xdb\xc1\x4c\x45\xb4\x5c\x82\x5d\x97\x1b\xaa\xfc\xe3\xa4\x8f\xb6\xfa\xf1\x9a\x90\xba\x64\x51\x3b\x7d\xe1\x4e\x1e\x5b\x49\x61\xd1\xe4\xd1\x52\x6d\x4b\xed\x2f\x71\xed\xf6\xac\xbb\xc2\x1c\x61\x9c\x59\xf3\x91\x14\x6c\x1a\x02\x5f\x9d\xb9\x69\xa8\xb0\x17\x0d\x24\x1a\xfb\x8f\xd9\x73\xf0\x7a\x6b\x74\xbc\xee\xc0\x78\x5c\x66\xc7\x51\x2e\x4f\x9e\x93\xda\xf9\x00\x97\xcb\xf3\x27\x39\x17\x60\x39\xea\xfa\x77\xaf\x9b\xb7\x30\x6f\xf6\x61\xe0\xe4\x4e\xf6\x6d\x2d\x91\x4b\xfc\x63\xbe\x55\x74\x9f\x76\x8c\xbc\x4f\x21\xb3\x2e\xf4\x1d\x00\x00\xff\xff\x0b\x37\xe3\x6c\xd5\x01\x00\x00"), + }, + "/src/sync/pool.go": &_vfsgen_compressedFileInfo{ + name: "pool.go", + modTime: mustUnmarshalTextTime("2016-06-27T01:43:45Z"), + uncompressedSize: 505, + + compressedContent: []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x6c\x90\xcd\x4e\xc3\x30\x10\x84\xcf\xd9\xa7\x58\x7a\xb2\xf9\x69\xe1\x5a\x29\x27\x0e\xdc\x50\x25\x8e\x55\x85\x8c\xbb\xa9\x0c\xae\x6d\xf9\x47\xa4\x54\x7d\x77\xec\xc4\xa5\x41\x90\x4b\xb4\xb3\x93\x6f\x66\xb3\x58\xe0\xcd\x5b\x52\x7a\x8b\xef\x01\xc0\x09\xf9\x21\x76\x84\xe1\x60\x24\x80\xda\x3b\xeb\x23\xce\x92\x09\xa2\xa3\x19\x40\x3c\x38\xc2\x95\xb5\x1a\x43\xf4\x49\x46\x3c\x42\xa3\xad\x14\x1a\xcb\x33\xda\xe6\x2b\xab\x4c\x24\x5f\x37\x2f\xea\x8b\x30\x65\xc5\x45\x0f\xd0\x84\x68\x3d\xe1\x7a\x33\x58\x3a\x21\xe9\x78\x82\xe6\x99\x3e\xf3\xe7\x5d\x32\x92\x71\x9c\x6e\x4e\x00\x45\x45\xe6\xf0\xba\xc4\x72\x7c\xa2\xf8\xdb\x53\x2a\xa8\x0e\x35\x19\xe6\xe6\x03\x9d\x63\xdb\xe2\x7d\xd1\xcb\xc2\xcd\x0b\xfd\xaa\x45\xa3\xf4\xa0\x35\x9e\x62\xf2\x66\x5c\x30\x9e\x95\xdc\xe0\x2c\x66\x13\x94\xb9\xc7\x65\x8b\x95\xb7\x9e\xb2\xef\x1e\x36\xd0\xd4\x01\x2f\x96\xe5\x1f\x4f\x05\xf6\xff\xdc\xb0\x4a\x91\xf5\xd3\x1b\x78\x3d\xa2\x2f\xcd\xcf\x3d\x47\xc0\xd0\xe6\x92\x27\x9c\x23\xb3\x3d\x27\xdd\x62\xcf\x7f\xf8\x3e\x99\xa8\xf6\xf4\xea\x69\xa7\x42\x46\x97\xac\x47\x4d\xc2\x24\xc7\xe4\xf8\xae\xbf\xb8\xc4\x9d\xe0\x3b\x00\x00\xff\xff\xd6\xf1\x0f\x08\xf9\x01\x00\x00"), + }, + "/src/sync/sync.go": &_vfsgen_compressedFileInfo{ + name: "sync.go", + modTime: mustUnmarshalTextTime("2016-06-27T01:43:45Z"), + uncompressedSize: 463, + + compressedContent: []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x6c\x90\xcb\x6e\xab\x30\x10\x86\xd7\x9e\xa7\x98\x25\x97\xa0\xe4\x9c\xee\xa2\xe4\x29\xb2\xe8\x02\xa1\x6a\x62\x86\xe2\x06\x1c\xea\xb1\x8b\xaa\x2a\xef\x5e\x9c\xa2\xe6\xd6\xdd\x80\x66\xbe\xff\xfb\xbd\x5c\x62\xbe\x0f\xa6\xab\xf1\x4d\x00\x06\xd2\x07\x7a\x65\x94\x4f\xab\x01\x3e\xc8\xa1\x70\xff\x4c\xc6\xb3\x13\xdc\x62\x4f\x07\x4e\x7a\x1a\xca\x2c\x18\xeb\x9f\xfe\x57\x65\xa5\x5b\xb2\xb8\x3f\x1e\xbb\x14\xa0\x09\x56\xa3\x0b\xd6\x9b\x9e\x5f\x76\xdc\x93\x7e\x0f\xc6\x71\x22\x38\xef\xa7\xf8\x05\xca\x34\x98\x4d\xb0\x2d\xae\xe2\x97\xd2\x2d\xae\x67\xf2\x15\x4b\xa9\x4b\x70\x29\xd5\x94\x4d\xc3\xc0\xb6\x4e\x6e\x7e\x2f\x50\xb7\x71\x77\x53\xe8\x16\xd4\x09\x54\x26\x45\x01\xa7\x47\x13\xc7\x1d\x93\xdc\x9b\x64\x92\xe7\x00\x6a\x8c\x02\x37\xdc\xb3\x64\xc7\x36\x19\xd3\x8b\xa8\x63\x1f\x9c\x8d\x31\x30\x4b\x8f\xe5\xaa\x8a\xe7\x71\xfa\xb7\x9e\xc6\x7b\xe7\xf1\x4f\x50\x3d\xc9\x78\xbe\x6a\xb2\x40\x49\x7f\xb9\x9b\x02\xbd\x0b\xfc\xd0\x42\x93\xdd\x0d\xc6\x26\x06\xa7\x02\xe9\xf9\x99\x22\xed\xc7\x0a\x1b\xea\x24\xde\x7c\x07\x00\x00\xff\xff\x22\x9d\xd0\xd3\xcf\x01\x00\x00"), + }, + "/src/sync/sync_test.go": &_vfsgen_compressedFileInfo{ + name: "sync_test.go", + modTime: mustUnmarshalTextTime("2016-06-27T01:43:45Z"), + uncompressedSize: 240, + + compressedContent: []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\xd2\xd7\x57\xd0\x4e\x2a\xcd\xcc\x49\x51\xc8\x2a\xe6\xe2\x2a\x48\x4c\xce\x4e\x4c\x4f\x55\x28\xae\xcc\x4b\x8e\x2f\x49\x2d\x2e\xe1\xe2\xca\xcc\x2d\xc8\x2f\x2a\x51\xd0\xe0\xe2\x54\x02\x09\x64\xe6\xa5\x2b\x71\x69\x72\x71\xa5\x95\xe6\x25\x2b\x84\x00\x05\x02\xf2\xf3\x73\x34\x4a\x14\xb4\xa0\x92\x7a\x21\x9a\x0a\xd5\x5c\x9c\x25\x7a\xc1\xd9\x99\x05\x1a\x9a\x5c\xb5\x68\x4a\xdd\x9d\x49\x50\x1c\x94\x9a\x93\x9a\x58\x9c\x4a\xa4\x0e\xe7\xfc\xbc\x14\xe7\xfc\x82\x4a\xbc\xca\x01\x01\x00\x00\xff\xff\x93\xcf\x90\x60\xf0\x00\x00\x00"), + }, + "/src/sync/waitgroup.go": &_vfsgen_compressedFileInfo{ + name: "waitgroup.go", + modTime: mustUnmarshalTextTime("2016-06-27T01:43:45Z"), + uncompressedSize: 446, + + compressedContent: []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x74\x90\xcd\x4e\xc3\x30\x10\x84\xcf\xf1\x53\x0c\x3d\x54\x0e\x08\x44\xcb\x0d\x35\x48\x9c\x78\x04\x0e\x88\xc3\xe2\x6c\x13\xab\xa9\x13\x25\x6b\xaa\xa8\xea\xbb\x63\x9b\x00\xe1\x2f\xa7\x78\x76\xf6\x9b\xdd\xed\xc8\xec\xa8\x62\x0c\xa3\x33\x4a\xc9\xd8\x31\x1e\xc9\xca\x43\xdf\xfa\x0e\x83\xf4\xde\x08\x8e\x2a\x33\xad\x77\xc2\x3d\xac\x93\xf0\xa8\x91\x3e\x53\x93\x9b\x3c\xc7\x93\x52\xd9\x20\x24\xbc\xc2\xd3\x6a\xfd\xfc\x32\x0a\x07\x81\xf7\x14\x7c\x3e\x74\xdd\xac\x55\xb0\x6c\xbd\x33\xd0\x87\x0a\xe7\x9f\x21\x39\xee\xcb\x52\x97\xdc\x08\x45\x7a\x1e\xd3\x0e\xd5\xd5\x47\xe0\x45\x81\x54\x53\x99\xdd\x62\xa6\x6f\x70\x1d\x9d\x59\x47\xce\x1a\xbd\x88\xe3\xdf\xc2\x71\x45\x62\x5f\xe7\x2b\x4c\xfe\x45\xae\xb2\xd3\x4f\xc6\x5d\x60\x2c\x97\x49\xa9\x51\x14\x70\xb6\x49\xcc\x49\xc0\x9e\x76\xac\xbf\x2d\xf9\x17\x25\x34\xce\x30\x67\x5f\x18\xd3\xb4\x03\xeb\x24\xe7\x33\x6a\x28\x47\xca\x7f\xd7\x88\xbf\x3a\x5d\xe1\xf7\xb0\x91\xba\xb9\x4c\xa0\x77\xc4\x5b\x00\x00\x00\xff\xff\x61\x38\x6e\x82\xbe\x01\x00\x00"), + }, + "/src/syscall": &_vfsgen_dirInfo{ + name: "syscall", + modTime: mustUnmarshalTextTime("2016-06-27T01:43:45Z"), + }, + "/src/syscall/syscall.go": &_vfsgen_compressedFileInfo{ + name: "syscall.go", + modTime: mustUnmarshalTextTime("2016-06-27T01:43:45Z"), + uncompressedSize: 1281, + + compressedContent: []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x9c\x94\xc1\x4e\xdc\x30\x10\x86\xcf\xeb\xa7\x18\xa2\x4a\x24\x02\x92\x72\x5d\x69\x2f\x70\x40\x3d\x15\xa9\xad\x7a\xa0\x1c\x1c\x67\x92\x9d\xc5\xb1\x23\xdb\xa1\xd0\x8a\x77\xef\x38\x4e\x60\x77\x91\x5a\xa9\xb7\x28\xe3\x99\xf9\xff\xf9\xc6\xae\x2a\x38\xab\x47\xd2\x0d\xec\xbc\x10\x83\x54\x0f\xb2\x43\xf0\xcf\x5e\x49\xad\x85\xa0\x7e\xb0\x2e\x40\x2e\x56\xd9\x68\xbc\x6c\x31\x13\xfc\xd9\x51\xd8\x8e\x75\xa9\x6c\x5f\x75\x76\xd8\xa2\xdb\xf9\xb7\x8f\x9d\xcf\x44\x21\xc4\xa3\x74\xf0\x53\x3a\x43\xa6\xbb\x75\x64\x02\x36\xb0\x81\x56\x6a\x8f\x53\x48\x93\xc1\xab\xb1\x6d\xd1\xc1\xdd\x7d\xfd\x1c\x50\x88\x76\x34\x0a\xc8\x50\xc8\x0b\xf8\x2d\x56\x3b\x5f\xde\x68\x5b\x4b\x5d\x7e\xc1\x90\x67\x1f\x5a\x3d\xfa\xed\xb5\x35\xde\x6a\xcc\xce\x59\x6e\xf9\x89\xab\x3a\x23\xf5\xe7\x7a\x87\x2a\xe4\x31\x3f\xa5\xae\xa8\x05\x8d\x26\x7f\x6b\x52\xc0\xc9\x06\x3e\x4e\xb1\xbd\xc2\x37\xb1\xb0\x9a\x4b\x16\xe5\x35\x5b\xce\x33\x6d\x3b\x2e\xef\x03\x8b\xee\xf6\x2b\x14\x31\x77\x4f\xf6\x06\x0c\x69\xfe\xf7\x22\x56\x2f\x1c\x7c\x99\x0d\x0c\xd1\xec\xf7\x64\x3c\xa9\x61\x31\x27\x47\x93\x88\x3a\xfe\x21\x03\x9d\xb3\x8e\x85\x64\x73\xea\x3a\x42\x09\xd8\x43\x04\xe3\xc1\xd8\x00\xf2\x51\x92\x96\xb5\x46\x96\x8b\x08\xdb\x10\x06\xbf\xae\xaa\xbf\xd2\xa9\xb9\x65\xd5\x4b\xae\xe4\xaa\xc6\xaa\x6a\x26\xed\xcb\xbe\xc9\xd8\x21\x9b\x79\x07\x2d\xb8\x11\x0f\xed\x7d\xb5\x33\x87\xbc\x9e\xe9\x4d\x46\x3b\x7b\x7b\x10\x85\xf5\x06\x8e\x5c\x1e\x1f\x89\x3d\x79\x3e\xef\x32\x4f\xa6\xcc\x6f\xa6\xc1\x96\x27\x9e\x06\x76\x7c\x88\xf9\x3f\xda\x07\xcc\xdf\x6f\x42\x3d\xc1\x72\x18\x46\x67\xa2\x27\x71\xc8\x4d\x0e\x03\x9a\x66\x8f\xed\x39\xd4\x65\x59\x72\x4e\x6b\x5d\xda\x9f\x28\x9d\xb8\xfb\xd3\x15\x9b\x3b\x38\x79\xfa\xc3\x9c\x16\x69\xc5\x08\x36\x1b\xb8\xb8\x4c\x5b\x55\x3b\x94\x0f\x69\x1d\xfe\x73\xc3\xee\xd6\x74\x5f\x14\xc0\x37\xb2\xb1\xe6\x34\xc0\xe8\x31\x8d\x5b\x1b\x3e\x4d\x46\x21\x50\xe0\x18\x26\xfa\xf8\x94\x3c\xd3\x2f\x84\x7e\xd4\x81\x22\x07\x50\x5b\xe9\xa4\xe2\x88\x17\x47\xdb\xba\xd7\x88\xce\x2e\xd7\xf7\x71\x30\x0b\x55\x6e\x95\x0f\x90\x6e\x78\x79\x6b\x23\x79\x37\x21\x65\x31\xc6\x5e\xd8\x21\x9e\xe4\xef\xd7\x91\x00\x79\x50\x76\x20\x46\xd3\x3a\xdb\x43\xec\xed\x61\x79\x3e\x82\xe5\xdd\xb4\xd4\x40\x7a\x3e\xd8\x66\x54\x9e\x27\x0f\x61\x8b\xc0\xb3\xd2\xcb\x23\xf3\x9a\x15\x9d\xb1\xef\xa2\x5c\x5e\x82\x65\xfc\x7e\x5e\xb2\x73\x50\x90\x96\x8d\x05\x46\x75\x11\x17\x31\xbc\x48\xcb\x49\x13\x1f\xae\xe5\xfa\xd7\x91\x8d\x4a\x68\xd2\x22\x00\xcd\x97\x55\x2c\x3f\x2e\x2e\xd9\xd6\x9f\x00\x00\x00\xff\xff\xfd\x00\xda\x9e\x01\x05\x00\x00"), + }, + "/src/syscall/syscall_unix.go": &_vfsgen_compressedFileInfo{ + name: "syscall_unix.go", + modTime: mustUnmarshalTextTime("2016-06-27T01:43:45Z"), + uncompressedSize: 2931, + + compressedContent: []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\xe4\x56\x5f\x6f\xdb\x36\x10\x7f\x96\x3e\xc5\x45\x18\x0a\xaa\xf1\x94\xd8\xdb\x82\x61\x5d\x1e\xb2\xc0\x0b\x02\x64\x4d\x51\x3b\x6b\x87\xa2\x08\x68\xf9\xec\xd0\x96\x49\x8d\xa4\x9c\x1a\x6d\xbe\xfb\x8e\x7f\x14\x3b\xb6\x5f\xba\x00\x7d\x29\x60\x46\x0c\xef\xdf\xef\x7e\x3c\x1e\x79\x74\x04\x87\xa3\x46\x54\x63\x98\x99\xce\xc1\xbd\x90\x63\x75\x6f\xd2\xb4\xe6\xe5\x9c\x4f\x11\xcc\xca\x94\xbc\xaa\xd2\x54\x2c\x6a\xa5\x2d\xb0\x34\xc9\x74\x23\xad\x58\x60\x46\xd3\x46\x1a\x3e\xa1\x19\x4d\xa7\xc2\xde\x35\xa3\xa2\x54\x8b\xa3\xa9\xaa\xef\x50\xcf\xcc\x7a\x32\x33\x59\x9a\xa7\xe9\xa4\x91\x25\x44\xf3\x5b\x94\x4b\xc3\x72\xf8\xf0\xd1\x58\x2d\xe4\x14\x3e\xa7\x49\xad\x55\x89\xc6\xc0\x6f\xa7\x84\xa6\xb8\xa8\xd4\x88\x57\xc5\x05\x5a\x96\x45\x49\x96\xa7\x89\x98\x40\xab\x77\xea\xf5\x6e\xe4\x18\x27\x42\xe2\xd8\xb9\x48\x34\xda\x46\x4b\x90\xa2\x4a\x93\x87\x34\x99\x99\xbe\x5c\x3a\x87\xd1\x26\xb8\xa3\xd8\xce\x15\x7d\xe6\xb8\xda\x17\xef\x7a\x34\xc3\xd2\x66\x79\x71\x4e\xd9\xb3\xcc\x69\x65\x1d\xf0\xce\x82\x9d\x37\x5a\xf0\x39\xb2\x36\x81\x0e\x44\x77\xc5\x15\xca\xa9\xbd\x63\x39\x69\x4e\x94\x06\xe1\x54\x8f\x5f\xd1\xf7\xf7\x1d\x15\x5a\x3d\x3c\xf4\xb8\x69\xd9\xe9\xb5\x0a\x97\x94\xd4\x27\x26\xf2\x62\xe0\x9d\x33\xf2\xe5\xc3\x7e\x10\x1f\xe1\x14\x9c\xf2\x21\x64\xa7\x19\xfd\xf5\xa0\x3c\x6a\x5a\xdd\xd4\xa7\xec\x23\x19\xce\x30\x7d\x88\xfc\x1b\xb4\xf4\xff\x6d\xc9\xe6\x1d\x58\x42\xc0\x9e\xff\x1f\xf6\x0f\xf6\xb0\xbf\xcb\x72\x31\x70\xc8\x28\x94\x47\x44\x20\x96\x5c\xb7\x65\xf5\x97\x1a\x37\x15\xc2\x4b\x72\x13\x08\xf7\x42\x5e\x69\xe4\xe3\xd5\x50\x0b\x1c\x0f\xd5\x95\xe2\x63\xca\x78\xc2\x2b\x83\x5e\xbc\x10\xb2\x31\xd7\x12\x69\xf1\xc7\x6e\x9b\x53\xf0\xc7\x24\x5f\xe0\x63\x4a\x6b\xb7\x0e\x1a\xa1\x44\x0d\x4e\x9b\xe5\xb1\x50\x4a\xb5\x44\xed\x99\xa5\x53\xb0\xae\x1b\xa0\x1c\xa3\x10\xc7\x04\x9a\x85\xb4\x9f\x62\xa6\xd2\x73\xaa\xce\x11\xc9\xf6\x40\x76\x92\x27\xc5\xe8\xf6\x23\xd9\x9b\x9b\xd5\x0d\x7a\x40\xff\x36\x42\xe3\x1e\xfe\xa3\xc4\xf1\x9f\x78\x70\x41\x71\x5f\xf9\x27\x35\x97\xa2\x64\x99\xd7\x75\x11\xb7\x60\xb7\xc6\x54\x60\x4b\x45\xd5\x9b\x45\x79\xf6\xa4\x60\x9e\x18\x79\x0c\x8e\xd9\xfc\xb1\x86\x06\x91\x6f\xab\x79\xdd\x01\xde\xa5\xd1\xa3\xf1\x13\x34\x42\xda\xda\xea\x1c\x98\xa6\x45\xdd\x6b\x17\xe8\x70\x68\x0d\x7d\xad\xa5\xf2\xec\x53\x16\x13\x97\x68\xbb\x71\xd9\xa0\x85\xf1\x8a\x04\x07\x6b\x72\xb5\xd3\x9a\xb4\x68\xb7\xe3\xe5\xeb\x03\x1f\x03\x31\x1d\x8f\xce\x71\x4e\x13\x4b\x87\xb0\xb3\x23\xea\xae\x45\x1e\xd1\xa3\xa0\xd7\x0a\x3c\x17\x84\xd1\xc5\x73\x34\x0f\xfe\x19\xdc\xbe\x7b\x7b\x39\xec\xc3\x8b\x17\xc0\x78\xd7\xad\x75\xe1\xcb\x17\x08\xd3\x5e\xa8\x28\xae\x35\x5f\xc5\xed\x23\x3f\xa8\x25\xaf\x42\x01\x32\xde\x73\x50\x4d\x25\x4a\xdc\x68\x1c\xa3\x95\x45\x4a\xc3\x99\x6d\x36\x8d\x64\xd7\xde\x5b\x86\xb3\x94\xfd\xe0\x0d\xb2\x68\x98\xfb\x53\x47\x19\x0e\xd5\xb9\x92\x46\x55\x18\x95\x77\xa9\xd9\x0a\xd4\x81\x63\xfa\xed\x4b\xb5\xff\xfe\x72\x18\xd8\x0f\xbd\xba\xb8\x50\xf8\x49\xd8\xd8\x54\x7c\xb4\x77\x5c\xcb\xd8\x67\xb6\xa2\xb4\xe7\x33\xf8\xef\x9f\x9d\x9f\xf7\x07\xdb\x85\x73\xb2\xb3\x93\x34\x7e\xa6\xf1\x0b\x8d\x93\x67\x57\xd1\xc9\x57\x96\xd1\x66\xf0\x6f\x52\x52\x84\xac\x77\xdc\x83\xcf\x40\x8d\x67\x4e\xfb\x5c\x28\xa3\xb1\x42\x6e\x10\x94\x84\xeb\x01\xbc\xef\xc0\x1d\xaf\x6b\x94\x06\x84\xa4\x9f\xb0\xa0\x26\x90\x29\x93\x41\xbc\x9a\xdb\x6d\xdf\xd8\x88\x87\xaf\xdb\x8b\xb7\xfc\xfe\xbb\x38\xc7\xcf\xa9\xd7\x35\x47\xdf\x6b\xc9\x3e\x87\xbd\x3f\xa8\xbf\xbd\xb1\xfa\x4f\xad\x16\xf1\x59\x62\x1e\x6f\x67\xf6\x32\x74\x3f\xa2\x47\x69\x4f\xcd\x66\xfb\xdc\xbc\xfd\x6e\x28\xd4\xaf\x67\xbe\xe7\xe5\xc5\x6b\xbc\x67\x15\x4a\x66\x72\x7a\xfa\x74\xdb\x17\x56\x07\x46\xce\x50\x73\x49\x6f\xd6\xd0\x57\x9d\x46\xbc\x9d\x47\xae\xaf\x1d\x6f\xdf\xc8\x84\xf6\xf2\xf5\xdf\x67\x57\xed\xcd\xec\x9b\x23\x35\xd8\xf8\xf2\x22\x97\x81\x80\x2d\x41\x08\x4e\xd9\xae\xb9\x08\xa9\xe4\x2c\xbc\x86\x8b\x37\x4a\xb8\xe6\x1d\xdb\xed\x8d\x5f\x24\x36\xc9\xc6\xbd\x03\x1e\xd2\xff\x02\x00\x00\xff\xff\xba\x7d\x55\xf6\x73\x0b\x00\x00"), + }, + "/src/syscall/syscall_windows.go": &_vfsgen_compressedFileInfo{ + name: "syscall_windows.go", + modTime: mustUnmarshalTextTime("2016-06-27T01:43:45Z"), + uncompressedSize: 2363, + + compressedContent: []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\xcc\x55\x5f\x6f\xe3\x36\x0c\x7f\x8e\x3f\x05\x91\x87\xc1\xce\xbc\x3a\xf6\xad\x5d\x7b\x40\x1e\x8a\x26\x77\x37\x20\xb7\x14\x4d\x8a\x02\x2b\x8a\x42\xb6\x15\x47\xad\x2c\x19\x92\x1c\x2c\xfd\xf3\xdd\x47\xd9\x71\xe2\xac\x29\xb0\xa1\x43\x70\x0f\x8c\x25\x92\x22\x7f\xfc\x91\x52\x82\x00\x7e\x8e\x4b\xc6\x53\x78\xd0\x8e\x53\x90\xe4\x91\x64\x14\xf4\x4a\x27\x84\x73\xc7\x61\x79\x21\x95\x81\xae\x2a\x85\x61\x39\xed\x3a\xce\x92\x28\xc8\x99\x28\xf5\x44\x50\x18\xc0\x2f\xa1\xe3\xcc\x4b\x91\xc0\xb4\x3e\xe2\x1a\x45\x0a\x1f\x04\x51\x99\xf6\x81\x84\x28\x11\xca\x27\x28\x99\x30\x85\x51\x1e\xb8\x0a\x95\x2a\x6a\x14\x3e\x50\xa5\x60\xa4\x94\x90\x1e\x3c\x3b\x9d\x42\xa1\xfe\x86\x28\xc1\x44\xe6\x7a\x4e\x47\x51\x53\x2a\xd1\x78\xbb\x4d\x6a\xcf\x87\xbe\x0f\xa3\xf3\x8b\x8b\xd1\xd4\x79\xdd\xc5\x70\xf2\x1e\x08\x94\x5f\x51\x8e\x51\x4e\x0e\x09\xe8\xec\xdf\x00\x42\xf9\x0d\xe5\x14\xe5\xec\x90\xe0\xc2\xe8\xbf\xa2\xb3\x3e\x7d\xfb\x63\x3d\xc3\xe8\xa0\x60\x8f\x3f\x08\xd6\xfe\x58\xdf\xd0\x3a\x87\xc7\x07\xc1\xce\x25\x49\x39\x8b\x15\x51\x2b\x77\xce\x38\x15\x24\xa7\xd0\xb3\x47\xc3\x13\x4c\xbc\x20\x22\xe5\xf4\xe3\x89\xff\x91\x35\xa3\xa6\x50\x32\x21\x69\xaa\xa8\xd6\x6f\xb2\x58\xdb\x16\xc8\x29\xe2\xb0\x9a\xff\x1d\x85\x9b\x42\x6f\x4c\x9e\x56\xc3\xf1\xd8\x83\x31\x12\xe1\x7a\x36\xb4\x54\x36\xea\x3a\xca\x4f\x68\x1c\x59\xdd\xf3\x77\x9d\x7d\x86\x2e\xbe\x3e\x86\xe6\x60\xfb\xad\x41\x48\x03\x64\x49\x18\x27\x31\xa7\x3e\x68\x4a\x61\x61\x4c\xa1\x3f\x07\x41\xc6\xcc\xa2\x8c\x8f\x12\x99\x07\x99\x2c\x16\x54\x3d\xe8\xed\x22\xe6\x32\x0e\x72\x82\x91\x54\x90\xca\x24\x58\x3f\x69\xfa\x28\x4f\xbb\xaf\x5b\x78\x45\x0d\xef\x12\x6b\xf7\xe0\x0b\x13\x3f\x18\x3e\x6c\xe2\xd4\xa4\xdf\xaa\xde\xb9\x0b\x40\xba\xb1\x51\xf3\x14\x6a\x4d\xd5\x1a\x36\x87\x05\x0c\x06\x30\x9d\x0d\xef\x27\xd7\xb3\xcb\xeb\xd9\xfd\xb7\xf3\x3f\x86\xe3\x91\x35\x36\x25\x84\x4e\xe7\x75\xd7\x75\x74\x75\x35\xb9\xda\xe3\x19\x55\x9e\xeb\x4d\x7f\x03\xe4\x2b\x35\x17\x52\x68\xc9\xe9\x77\x99\x52\x37\xa9\xd7\x6b\x1c\x3e\xe4\xa8\xac\x27\xe9\x53\x84\x08\xed\xf0\x54\x2c\x7a\x2d\x1a\x87\x65\x9e\xaf\x6a\x1e\xb7\x05\xde\x28\x66\xe8\x17\x66\xab\xab\x07\xb4\x89\x18\x97\x73\xb8\xbd\x8b\x57\x06\xd7\xa9\x14\x9b\xe8\x3e\xc8\x25\x55\x9c\x14\x05\xc5\xd1\x9a\x6c\xd6\x6f\xb2\xda\x62\xeb\x90\x58\x71\x08\x2f\x2f\xad\x6d\x54\x55\x5c\x0d\xf5\x4c\xae\xeb\x72\x31\x23\x4e\x76\xa7\x57\x65\x1b\x40\x9d\xce\xc5\xeb\x5a\x59\xbc\x2d\x45\x82\xf1\x8a\xa4\x77\x2e\x85\x35\x37\xe5\x8d\xfe\x62\xc6\xce\x96\xbd\x81\x14\xd7\x89\xe5\xa9\xa1\xc9\x52\x53\xff\xaf\x1e\x7d\x95\xd6\x8a\x41\x76\xf8\xce\x73\x44\x3c\x66\x82\xe2\x50\xba\x49\x9e\x6e\x1f\x8d\x0d\xab\x9b\x03\x2d\xef\x99\x3c\x57\xd9\xb2\x7d\x00\xdf\x3a\x95\x25\xd0\x6b\xfa\x83\xbb\x25\xf4\x6e\x4f\xc3\xb3\xe8\x6e\xfd\x69\x1c\xf7\xb6\x0e\x4b\xf2\xf7\xf7\x0f\x71\x52\xb1\x74\x1f\xe9\x0a\xb4\x41\x3e\x32\x8c\xbe\x24\xbc\xa4\xeb\xad\x0f\x73\x59\x8a\x14\x62\x29\x79\x3b\x62\xb7\x8b\x16\xc2\x35\x6d\x47\x9a\x21\x15\x7f\x22\xfb\xbf\x8b\xb9\x54\x39\x31\x4c\x0a\xd7\x3c\x31\xe8\x59\xc3\x13\x1a\xd8\xd6\x60\x5f\xec\x04\x9a\x99\xd8\x8b\xba\xff\x16\xb3\x59\x15\xb4\xa5\xb4\x20\xcb\xc4\x3c\x6f\x9e\x83\xb6\xd1\x83\xea\x83\xdc\xd7\xa5\xec\xa0\xc7\x60\x7f\x07\x00\x00\xff\xff\x4f\x7e\x0c\x93\x3b\x09\x00\x00"), + }, + "/src/time": &_vfsgen_dirInfo{ + name: "time", + modTime: mustUnmarshalTextTime("2016-06-27T01:43:45Z"), + }, + "/src/time/time.go": &_vfsgen_compressedFileInfo{ + name: "time.go", + modTime: mustUnmarshalTextTime("2016-06-27T01:43:45Z"), + uncompressedSize: 2387, + + compressedContent: []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x94\x56\x6d\x6f\xdb\x36\x10\xfe\x2c\xfd\x8a\x9b\xb0\x21\x54\xec\x48\x49\x5b\x74\x58\x10\x0f\xe8\xd2\x17\x14\x68\x6b\x60\x49\xbf\xb4\x28\x0a\x5a\xa2\x6c\xba\x34\x29\x90\x54\x5e\x9c\xfa\xbf\xef\x8e\x94\x65\x3b\xeb\x0a\x2c\x1f\x02\xe9\x74\xbc\x7b\x9e\x87\xf7\xe2\xb2\x84\xd1\xac\x93\xaa\x86\xa5\x4b\xd3\x96\x57\xdf\xf8\x5c\x80\x97\x2b\x91\xa6\x72\xd5\x1a\xeb\x81\xa5\x49\x66\x3b\x4d\xb6\x2c\xc5\xe7\xb9\xf4\x8b\x6e\x56\x54\x66\x55\xce\x4d\xbb\x10\x76\xe9\x76\x0f\x4b\x97\xa5\x79\x9a\x62\xd8\xf7\xfc\x9b\x00\xd7\xd9\x18\xad\xf8\xa8\xe5\x1d\x34\x9d\xae\x80\xeb\x3a\x9a\xae\xf1\x1f\x38\x6f\xbb\xca\x83\xf4\x60\x85\xef\xac\x76\xc0\xf1\x08\x57\xb7\xfc\xde\x81\xd4\x95\xea\x6a\x51\xc3\x2d\xe6\x04\xbf\x90\x0e\xb6\x10\x59\x2d\x5c\x2b\xbd\x80\x97\x97\xaf\xf2\x31\x25\x9c\x89\x8a\x77\x0e\xd3\x2d\xc4\xfd\x11\xc6\xd0\x42\xd0\xd1\xc6\x58\x8c\xe3\x85\xd5\x5c\xc9\x35\xf7\xd2\xe8\x52\xdc\x1d\xbc\x83\x69\x76\x88\xca\x97\xdc\x8b\x02\xae\x84\x00\xe9\x5c\x27\x60\xe1\x7d\xeb\xce\xcb\xf2\xa7\xbc\x83\xab\x2b\x9f\xfc\xfe\x47\x91\x06\x96\x52\x4b\xcf\x72\x78\x48\x13\x84\xc6\x6f\x8c\xac\xa1\x16\xbc\x86\xca\xd4\x02\x84\x92\x2b\xa9\x43\xee\x34\xb9\xe1\x16\xbe\x42\x10\x63\x02\x24\x13\x3b\x1d\xc3\x69\x9e\x6e\xd2\xd4\xdf\xb7\x02\x7a\xed\xc9\xc1\x6e\xe5\xc2\xb0\x12\xe2\x1f\x72\x7b\xfa\x24\x4d\x6e\x17\x42\xf7\xaf\xcf\x9f\xa5\x49\x2b\xac\x34\xf5\xf0\xda\xf4\xce\x04\x8d\x05\x35\x1a\x5e\x89\x87\xcd\x18\x3a\x7c\x6b\xbd\xcd\xd3\x84\xdb\xf9\x36\xe0\xf6\x73\x9a\x50\x66\xd3\x79\x38\x5e\xba\x62\x3a\x5b\x8a\xca\xa3\x63\xe5\xe5\x8d\x00\x98\x19\xa3\x08\xe5\xc0\xf7\x9d\xa9\xb8\x8a\xa4\x6b\x38\x9f\x60\x49\x15\x6f\x94\x99\x71\x55\xbc\x11\x9e\x65\x24\x6c\x96\x17\x1f\xc4\x2d\xc3\x74\x8e\x3c\xea\xe2\xca\x5b\xa9\xe7\x64\x90\x64\x90\xba\x16\x77\x7f\xdd\x7b\xc1\xdc\x18\x8e\xd8\x11\xda\x97\xff\xb6\xe7\x64\x97\x0d\x48\x98\x4c\xe0\xe4\x0c\xbe\x7f\x87\x65\xff\x88\xb9\x13\x45\x38\x10\x4c\xa1\x79\x10\x35\xfb\x78\x7d\x99\xa1\x3d\x56\x58\x9a\x20\xaf\xc7\x2e\xee\xb3\x1c\x9d\xc1\x39\x2c\xbf\xec\x7d\x5b\x1b\x4d\xdf\x3e\x7f\xa1\x87\x87\x87\x83\x33\x63\xc4\x7e\xc9\x95\x62\xd9\x5c\x78\xba\x1b\xf2\x99\x36\x8d\x13\x1e\x39\xbe\xd5\x74\xf9\xc7\x70\xf2\x1c\xef\xb2\xe1\xca\x89\xcd\x66\x90\xaa\xbf\xd0\x0f\x5c\x1b\x74\x0a\x37\x44\xb0\x23\xba\x9f\x89\x76\x98\x30\xa6\x79\xfe\x2c\x24\x0a\x51\xd8\x7b\xa9\x94\x74\xa2\x32\xba\xce\x87\x74\xda\xe0\x51\x60\x68\x8e\x5e\x63\xd0\xfd\xf3\xd3\x27\xe1\xae\x34\x09\x7c\x00\x6a\x00\xa3\xa1\xec\x43\x5f\xc5\xa8\xe3\x78\x8e\x69\xf8\xed\xf0\xc3\x2e\xdf\x95\x12\xa2\x65\x35\xbc\xec\x6c\xa8\xf0\x90\xa3\xa2\x1c\x2b\x1c\x09\xac\x5a\x70\xdd\x97\xf1\xc3\x86\xae\x77\xe0\x1b\xd9\xfd\xea\x22\x3d\xac\xba\x6c\x4c\x6a\xbc\xed\x9b\x37\x96\x1f\x0b\x25\x8c\x31\xa1\x52\xc6\x61\xb8\x1c\x36\x11\x15\xab\xcb\x7d\xfe\x18\xfa\xe2\xa4\x1a\x50\x39\xcf\x6d\x88\x6b\x19\x56\xf3\x7e\x4f\x05\x7c\xbe\xe8\xab\x7a\x02\x08\x4d\x60\x01\xcb\xa6\x21\xcc\xcc\x17\xa1\xb5\x4e\x0e\x15\xca\x07\x61\x0e\x34\xa7\xa2\x0c\x27\xff\x84\xb3\x8b\x8b\xa7\x67\x54\x90\x80\x03\x60\xc5\xfd\xa2\x78\xcf\xef\xde\xc6\x66\xdd\xaf\xc4\xed\x89\x0b\x38\x0d\xc5\x1b\x5e\x26\x70\x1a\x3e\xfa\x62\xdb\x80\xfb\xdd\xf4\xff\x84\xc2\x98\x7b\xec\x42\x31\xa2\x69\x6e\xc0\x17\x0d\xb2\xc3\xb6\x0f\xe3\x26\x21\x24\xbe\xe8\x07\xc7\x2f\x93\x1e\x4e\xd2\xf3\x1f\x4d\x86\x8f\x64\xdd\x97\x93\xce\x22\x56\xba\x06\x02\x3f\x3a\xcb\xf7\x54\x37\xed\x7f\x88\x4e\xd3\x83\x32\x3c\xa6\x55\x29\xc1\xed\x8e\xd7\xa0\x00\x66\xb9\xe5\xee\x45\xe4\x71\x4e\x68\x22\xa7\xf4\x07\xec\xfa\xea\x1d\xfc\x07\x3c\xca\xf0\x9a\xa6\x14\xd5\x25\x0b\xad\xef\xc2\xfc\xc1\xfe\x38\xde\xda\xc7\x20\xac\x35\xb1\x2c\xfa\x40\x74\xec\x13\xf6\xf7\x6b\xa9\x04\xeb\x69\x14\x6f\xa6\x7f\x4f\xa7\xd7\x2c\x1f\x65\xa5\x92\xb3\x92\x6c\x25\x0d\x01\xa9\x1b\x53\xac\x65\x8b\xe0\x29\xc3\x4e\x0c\xdc\x44\x95\xf8\x24\x5b\x8a\xf2\xda\xd8\x6b\xe1\x3c\x8d\x3e\x74\x9d\x6a\x75\x1f\x04\xa1\xa4\xfb\x13\xb5\xf7\xa1\xdc\xf1\x2a\xd7\x01\x1d\xf1\x3f\xa0\x92\xbd\x40\x4d\x65\xc5\xcb\x77\xc6\x7d\x7d\xa1\xe7\x42\x09\x97\xc5\x72\x24\x77\xbc\x4d\x2d\x83\xda\x49\xcb\xb5\xac\x50\x65\xae\xb5\xf1\x21\x08\xfc\xe0\x6c\xd8\x9a\x3e\x26\x3f\x87\x0c\x46\x14\xa6\x78\x45\xba\x30\xea\x2c\xbc\xee\xf5\x30\x5d\xc3\xd8\xcf\x76\x73\x13\x6d\xc7\x6b\xa2\x51\x96\xbb\xb9\x8d\xcb\x14\x77\x5f\x2b\x69\x23\x5b\xb3\xea\x75\xdf\xed\x73\x6f\xfa\x2d\x19\x7f\x75\xe0\x37\xfa\x4d\xc0\x1c\xfe\x04\x08\x2b\x1d\x7f\x1e\x70\x15\xb6\xf4\x70\xa4\x36\xc2\xe9\x23\x9f\x0f\x1b\x77\x58\x11\x7d\xf4\x31\x54\x30\x43\x43\x18\xb2\x87\x23\xf6\x51\xaf\xb8\xed\x6c\x0d\x41\xa6\x4d\x6c\xa8\xfd\x39\x1c\xf7\x54\xb6\xf5\x23\x0e\x97\x0b\x6e\x2f\x71\x9d\xa3\x73\x95\xf7\x33\x1f\x69\xff\x13\x00\x00\xff\xff\xe6\x0c\x33\x31\x53\x09\x00\x00"), + }, + "/src/unicode": &_vfsgen_dirInfo{ + name: "unicode", + modTime: mustUnmarshalTextTime("2016-06-27T01:43:45Z"), + }, + "/src/unicode/unicode.go": &_vfsgen_compressedFileInfo{ + name: "unicode.go", + modTime: mustUnmarshalTextTime("2016-06-27T01:43:45Z"), + uncompressedSize: 600, + + compressedContent: []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x4c\x51\xc1\x8e\xd3\x30\x10\x3d\xc7\x5f\xf1\x4e\x51\xac\xdd\xa5\x5b\x8e\xab\x2d\x97\x22\x81\x10\x5c\xca\xb1\x2a\xc8\x38\xd3\xc6\xe0\xd8\x91\xe3\x48\x20\xda\x7f\xdf\x19\xa7\xad\x22\x45\xd1\xf8\xcd\x9b\x37\x7e\xcf\xab\x15\x1e\x7e\x4d\xce\xb7\xf8\x3d\x2a\x35\x18\xfb\xc7\x9c\x08\x53\x70\x36\xb6\xa4\xd4\x71\x0a\x16\x39\x36\x3f\xad\x19\x09\x2e\xe4\x47\x24\xa4\x29\xd0\x23\x04\xd9\x99\xc0\xec\xfd\x61\x7b\xab\x75\x69\xe2\xbf\xaa\xdc\x11\xf3\xd0\x2b\x9e\x71\x3e\xe3\x9b\xf9\xbb\x2d\xc7\xcd\x15\x67\x4e\x95\x28\x4f\x29\x60\x47\x83\x37\x96\x7a\x0a\x79\xdb\x99\xa4\xaa\x8b\xaa\x7c\xc4\xcb\x06\xcf\xaa\xea\x9c\x14\x9e\x42\x73\xdf\xa8\x55\x75\x8c\x09\x4c\x79\x05\xb7\x45\xa9\x2f\xa4\x88\x07\x34\x9d\x7b\xf2\x51\xaf\xde\x33\x6a\x93\xc0\xf5\x7d\x70\xdf\x1f\xc0\x8e\x07\x4a\x3c\xdf\x9b\x60\x09\x36\xb9\xec\xac\xf1\x10\xc5\x4f\x71\xe8\x28\x7d\xf9\xfe\x82\x13\x65\x98\xb6\x4d\x34\x8e\x60\x48\xbc\x8f\x99\x4c\x8b\x78\x84\x8d\xc3\x3f\x17\x4e\xc8\x1d\xe1\xee\x9c\xb7\xb1\x65\x71\xdf\xd8\xf4\xee\x6b\xd4\xe2\x34\xa1\xae\xf9\x27\xd5\xb5\xf1\xd9\xe9\x72\xdf\xaa\x25\x9f\x8d\xdc\xee\xd6\xf9\x28\xc0\xbe\x64\x73\xd0\xc2\x60\xb9\x99\xf4\x41\xc2\xdb\x5d\x73\xad\xee\xa9\x2d\x77\xb1\xed\x26\x3d\x2d\x10\x5d\xff\x58\xe3\x3c\x73\x8a\x66\xbd\xd6\x45\xf5\xa2\x16\x0a\x3c\x57\x56\xa8\x19\x17\x03\x1c\xe9\x52\xb8\x6c\xe4\x8c\x37\xe8\x85\x04\xf2\xd7\xa7\x93\x07\x62\x90\x15\xd6\xf3\x34\x7f\x37\x59\x75\x51\x6f\x01\x00\x00\xff\xff\xba\x6a\xe6\xd2\x58\x02\x00\x00"), + }, + } + + fs["/"].(*_vfsgen_dirInfo).entries = []os.FileInfo{ + fs["/src"].(os.FileInfo), + } + fs["/src"].(*_vfsgen_dirInfo).entries = []os.FileInfo{ + fs["/src/bytes"].(os.FileInfo), + fs["/src/crypto"].(os.FileInfo), + fs["/src/debug"].(os.FileInfo), + fs["/src/encoding"].(os.FileInfo), + fs["/src/fmt"].(os.FileInfo), + fs["/src/go"].(os.FileInfo), + fs["/src/io"].(os.FileInfo), + fs["/src/math"].(os.FileInfo), + fs["/src/net"].(os.FileInfo), + fs["/src/os"].(os.FileInfo), + fs["/src/reflect"].(os.FileInfo), + fs["/src/regexp"].(os.FileInfo), + fs["/src/runtime"].(os.FileInfo), + fs["/src/strings"].(os.FileInfo), + fs["/src/sync"].(os.FileInfo), + fs["/src/syscall"].(os.FileInfo), + fs["/src/time"].(os.FileInfo), + fs["/src/unicode"].(os.FileInfo), + } + fs["/src/bytes"].(*_vfsgen_dirInfo).entries = []os.FileInfo{ + fs["/src/bytes/bytes.go"].(os.FileInfo), + fs["/src/bytes/bytes_test.go"].(os.FileInfo), + } + fs["/src/crypto"].(*_vfsgen_dirInfo).entries = []os.FileInfo{ + fs["/src/crypto/rand"].(os.FileInfo), + fs["/src/crypto/x509"].(os.FileInfo), + } + fs["/src/crypto/rand"].(*_vfsgen_dirInfo).entries = []os.FileInfo{ + fs["/src/crypto/rand/rand.go"].(os.FileInfo), + } + fs["/src/crypto/x509"].(*_vfsgen_dirInfo).entries = []os.FileInfo{ + fs["/src/crypto/x509/x509.go"].(os.FileInfo), + fs["/src/crypto/x509/x509_test.go"].(os.FileInfo), + } + fs["/src/debug"].(*_vfsgen_dirInfo).entries = []os.FileInfo{ + fs["/src/debug/elf"].(os.FileInfo), + } + fs["/src/debug/elf"].(*_vfsgen_dirInfo).entries = []os.FileInfo{ + fs["/src/debug/elf/elf_test.go"].(os.FileInfo), + } + fs["/src/encoding"].(*_vfsgen_dirInfo).entries = []os.FileInfo{ + fs["/src/encoding/json"].(os.FileInfo), + } + fs["/src/encoding/json"].(*_vfsgen_dirInfo).entries = []os.FileInfo{ + fs["/src/encoding/json/stream_test.go"].(os.FileInfo), + } + fs["/src/fmt"].(*_vfsgen_dirInfo).entries = []os.FileInfo{ + fs["/src/fmt/fmt_test.go"].(os.FileInfo), + } + fs["/src/go"].(*_vfsgen_dirInfo).entries = []os.FileInfo{ + fs["/src/go/token"].(os.FileInfo), + } + fs["/src/go/token"].(*_vfsgen_dirInfo).entries = []os.FileInfo{ + fs["/src/go/token/token_test.go"].(os.FileInfo), + } + fs["/src/io"].(*_vfsgen_dirInfo).entries = []os.FileInfo{ + fs["/src/io/io_test.go"].(os.FileInfo), + } + fs["/src/math"].(*_vfsgen_dirInfo).entries = []os.FileInfo{ + fs["/src/math/big"].(os.FileInfo), + fs["/src/math/math.go"].(os.FileInfo), + fs["/src/math/rand"].(os.FileInfo), + } + fs["/src/math/big"].(*_vfsgen_dirInfo).entries = []os.FileInfo{ + fs["/src/math/big/big.go"].(os.FileInfo), + fs["/src/math/big/big_test.go"].(os.FileInfo), + } + fs["/src/math/rand"].(*_vfsgen_dirInfo).entries = []os.FileInfo{ + fs["/src/math/rand/rand_test.go"].(os.FileInfo), + } + fs["/src/net"].(*_vfsgen_dirInfo).entries = []os.FileInfo{ + fs["/src/net/http"].(os.FileInfo), + fs["/src/net/net.go"].(os.FileInfo), + } + fs["/src/net/http"].(*_vfsgen_dirInfo).entries = []os.FileInfo{ + fs["/src/net/http/fetch.go"].(os.FileInfo), + fs["/src/net/http/http.go"].(os.FileInfo), + } + fs["/src/os"].(*_vfsgen_dirInfo).entries = []os.FileInfo{ + fs["/src/os/os.go"].(os.FileInfo), + } + fs["/src/reflect"].(*_vfsgen_dirInfo).entries = []os.FileInfo{ + fs["/src/reflect/reflect.go"].(os.FileInfo), + fs["/src/reflect/reflect_test.go"].(os.FileInfo), + } + fs["/src/regexp"].(*_vfsgen_dirInfo).entries = []os.FileInfo{ + fs["/src/regexp/regexp_test.go"].(os.FileInfo), + } + fs["/src/runtime"].(*_vfsgen_dirInfo).entries = []os.FileInfo{ + fs["/src/runtime/debug"].(os.FileInfo), + fs["/src/runtime/pprof"].(os.FileInfo), + fs["/src/runtime/runtime.go"].(os.FileInfo), + } + fs["/src/runtime/debug"].(*_vfsgen_dirInfo).entries = []os.FileInfo{ + fs["/src/runtime/debug/debug.go"].(os.FileInfo), + } + fs["/src/runtime/pprof"].(*_vfsgen_dirInfo).entries = []os.FileInfo{ + fs["/src/runtime/pprof/pprof.go"].(os.FileInfo), + } + fs["/src/strings"].(*_vfsgen_dirInfo).entries = []os.FileInfo{ + fs["/src/strings/strings.go"].(os.FileInfo), + } + fs["/src/sync"].(*_vfsgen_dirInfo).entries = []os.FileInfo{ + fs["/src/sync/atomic"].(os.FileInfo), + fs["/src/sync/cond.go"].(os.FileInfo), + fs["/src/sync/pool.go"].(os.FileInfo), + fs["/src/sync/sync.go"].(os.FileInfo), + fs["/src/sync/sync_test.go"].(os.FileInfo), + fs["/src/sync/waitgroup.go"].(os.FileInfo), + } + fs["/src/sync/atomic"].(*_vfsgen_dirInfo).entries = []os.FileInfo{ + fs["/src/sync/atomic/atomic.go"].(os.FileInfo), + fs["/src/sync/atomic/atomic_test.go"].(os.FileInfo), + } + fs["/src/syscall"].(*_vfsgen_dirInfo).entries = []os.FileInfo{ + fs["/src/syscall/syscall.go"].(os.FileInfo), + fs["/src/syscall/syscall_unix.go"].(os.FileInfo), + fs["/src/syscall/syscall_windows.go"].(os.FileInfo), + } + fs["/src/time"].(*_vfsgen_dirInfo).entries = []os.FileInfo{ + fs["/src/time/time.go"].(os.FileInfo), + } + fs["/src/unicode"].(*_vfsgen_dirInfo).entries = []os.FileInfo{ + fs["/src/unicode/unicode.go"].(os.FileInfo), + } + + return fs +}() + +type _vfsgen_fs map[string]interface{} + +func (fs _vfsgen_fs) Open(path string) (http.File, error) { + path = pathpkg.Clean("/" + path) + f, ok := fs[path] + if !ok { + return nil, &os.PathError{Op: "open", Path: path, Err: os.ErrNotExist} + } + + switch f := f.(type) { + case *_vfsgen_compressedFileInfo: + gr, err := gzip.NewReader(bytes.NewReader(f.compressedContent)) + if err != nil { + // This should never happen because we generate the gzip bytes such that they are always valid. + panic("unexpected error reading own gzip compressed bytes: " + err.Error()) + } + return &_vfsgen_compressedFile{ + _vfsgen_compressedFileInfo: f, + gr: gr, + }, nil + case *_vfsgen_fileInfo: + return &_vfsgen_file{ + _vfsgen_fileInfo: f, + Reader: bytes.NewReader(f.content), + }, nil + case *_vfsgen_dirInfo: + return &_vfsgen_dir{ + _vfsgen_dirInfo: f, + }, nil + default: + // This should never happen because we generate only the above types. + panic(fmt.Sprintf("unexpected type %T", f)) + } +} + +// _vfsgen_compressedFileInfo is a static definition of a gzip compressed file. +type _vfsgen_compressedFileInfo struct { + name string + modTime time.Time + compressedContent []byte + uncompressedSize int64 +} + +func (f *_vfsgen_compressedFileInfo) Readdir(count int) ([]os.FileInfo, error) { + return nil, fmt.Errorf("cannot Readdir from file %s", f.name) +} +func (f *_vfsgen_compressedFileInfo) Stat() (os.FileInfo, error) { return f, nil } + +func (f *_vfsgen_compressedFileInfo) GzipBytes() []byte { + return f.compressedContent +} + +func (f *_vfsgen_compressedFileInfo) Name() string { return f.name } +func (f *_vfsgen_compressedFileInfo) Size() int64 { return f.uncompressedSize } +func (f *_vfsgen_compressedFileInfo) Mode() os.FileMode { return 0444 } +func (f *_vfsgen_compressedFileInfo) ModTime() time.Time { return f.modTime } +func (f *_vfsgen_compressedFileInfo) IsDir() bool { return false } +func (f *_vfsgen_compressedFileInfo) Sys() interface{} { return nil } + +// _vfsgen_compressedFile is an opened compressedFile instance. +type _vfsgen_compressedFile struct { + *_vfsgen_compressedFileInfo + gr *gzip.Reader + grPos int64 // Actual gr uncompressed position. + seekPos int64 // Seek uncompressed position. +} + +func (f *_vfsgen_compressedFile) Read(p []byte) (n int, err error) { + if f.grPos > f.seekPos { + // Rewind to beginning. + err = f.gr.Reset(bytes.NewReader(f._vfsgen_compressedFileInfo.compressedContent)) + if err != nil { + return 0, err + } + f.grPos = 0 + } + if f.grPos < f.seekPos { + // Fast-forward. + _, err = io.CopyN(ioutil.Discard, f.gr, f.seekPos-f.grPos) + if err != nil { + return 0, err + } + f.grPos = f.seekPos + } + n, err = f.gr.Read(p) + f.grPos += int64(n) + f.seekPos = f.grPos + return n, err +} +func (f *_vfsgen_compressedFile) Seek(offset int64, whence int) (int64, error) { + switch whence { + case os.SEEK_SET: + f.seekPos = 0 + offset + case os.SEEK_CUR: + f.seekPos += offset + case os.SEEK_END: + f.seekPos = f._vfsgen_compressedFileInfo.uncompressedSize + offset + default: + panic(fmt.Errorf("invalid whence value: %v", whence)) + } + return f.seekPos, nil +} +func (f *_vfsgen_compressedFile) Close() error { + return f.gr.Close() +} + +// _vfsgen_fileInfo is a static definition of an uncompressed file (because it's not worth gzip compressing). +type _vfsgen_fileInfo struct { + name string + modTime time.Time + content []byte +} + +func (f *_vfsgen_fileInfo) Readdir(count int) ([]os.FileInfo, error) { + return nil, fmt.Errorf("cannot Readdir from file %s", f.name) +} +func (f *_vfsgen_fileInfo) Stat() (os.FileInfo, error) { return f, nil } + +func (f *_vfsgen_fileInfo) NotWorthGzipCompressing() {} + +func (f *_vfsgen_fileInfo) Name() string { return f.name } +func (f *_vfsgen_fileInfo) Size() int64 { return int64(len(f.content)) } +func (f *_vfsgen_fileInfo) Mode() os.FileMode { return 0444 } +func (f *_vfsgen_fileInfo) ModTime() time.Time { return f.modTime } +func (f *_vfsgen_fileInfo) IsDir() bool { return false } +func (f *_vfsgen_fileInfo) Sys() interface{} { return nil } + +// _vfsgen_file is an opened file instance. +type _vfsgen_file struct { + *_vfsgen_fileInfo + *bytes.Reader +} + +func (f *_vfsgen_file) Close() error { + return nil +} + +// _vfsgen_dirInfo is a static definition of a directory. +type _vfsgen_dirInfo struct { + name string + modTime time.Time + entries []os.FileInfo +} + +func (d *_vfsgen_dirInfo) Read([]byte) (int, error) { + return 0, fmt.Errorf("cannot Read from directory %s", d.name) +} +func (d *_vfsgen_dirInfo) Close() error { return nil } +func (d *_vfsgen_dirInfo) Stat() (os.FileInfo, error) { return d, nil } + +func (d *_vfsgen_dirInfo) Name() string { return d.name } +func (d *_vfsgen_dirInfo) Size() int64 { return 0 } +func (d *_vfsgen_dirInfo) Mode() os.FileMode { return 0755 | os.ModeDir } +func (d *_vfsgen_dirInfo) ModTime() time.Time { return d.modTime } +func (d *_vfsgen_dirInfo) IsDir() bool { return true } +func (d *_vfsgen_dirInfo) Sys() interface{} { return nil } + +// _vfsgen_dir is an opened dir instance. +type _vfsgen_dir struct { + *_vfsgen_dirInfo + pos int // Position within entries for Seek and Readdir. +} + +func (d *_vfsgen_dir) Seek(offset int64, whence int) (int64, error) { + if offset == 0 && whence == os.SEEK_SET { + d.pos = 0 + return 0, nil + } + return 0, fmt.Errorf("unsupported Seek in directory %s", d._vfsgen_dirInfo.name) +} + +func (d *_vfsgen_dir) Readdir(count int) ([]os.FileInfo, error) { + if d.pos >= len(d._vfsgen_dirInfo.entries) && count > 0 { + return nil, io.EOF + } + if count <= 0 || count > len(d._vfsgen_dirInfo.entries)-d.pos { + count = len(d._vfsgen_dirInfo.entries) - d.pos + } + e := d._vfsgen_dirInfo.entries[d.pos : d.pos+count] + d.pos += count + return e, nil +} diff --git a/vendor/github.com/gopherjs/gopherjs/compiler/natives/bytes/bytes.go b/vendor/github.com/gopherjs/gopherjs/compiler/natives/src/bytes/bytes.go similarity index 100% rename from vendor/github.com/gopherjs/gopherjs/compiler/natives/bytes/bytes.go rename to vendor/github.com/gopherjs/gopherjs/compiler/natives/src/bytes/bytes.go diff --git a/vendor/github.com/gopherjs/gopherjs/compiler/natives/bytes/bytes_test.go b/vendor/github.com/gopherjs/gopherjs/compiler/natives/src/bytes/bytes_test.go similarity index 100% rename from vendor/github.com/gopherjs/gopherjs/compiler/natives/bytes/bytes_test.go rename to vendor/github.com/gopherjs/gopherjs/compiler/natives/src/bytes/bytes_test.go diff --git a/vendor/github.com/gopherjs/gopherjs/compiler/natives/crypto/rand/rand.go b/vendor/github.com/gopherjs/gopherjs/compiler/natives/src/crypto/rand/rand.go similarity index 100% rename from vendor/github.com/gopherjs/gopherjs/compiler/natives/crypto/rand/rand.go rename to vendor/github.com/gopherjs/gopherjs/compiler/natives/src/crypto/rand/rand.go diff --git a/vendor/github.com/gopherjs/gopherjs/compiler/natives/crypto/x509/x509.go b/vendor/github.com/gopherjs/gopherjs/compiler/natives/src/crypto/x509/x509.go similarity index 100% rename from vendor/github.com/gopherjs/gopherjs/compiler/natives/crypto/x509/x509.go rename to vendor/github.com/gopherjs/gopherjs/compiler/natives/src/crypto/x509/x509.go diff --git a/vendor/github.com/gopherjs/gopherjs/compiler/natives/crypto/x509/x509_test.go b/vendor/github.com/gopherjs/gopherjs/compiler/natives/src/crypto/x509/x509_test.go similarity index 100% rename from vendor/github.com/gopherjs/gopherjs/compiler/natives/crypto/x509/x509_test.go rename to vendor/github.com/gopherjs/gopherjs/compiler/natives/src/crypto/x509/x509_test.go diff --git a/vendor/github.com/gopherjs/gopherjs/compiler/natives/debug/elf/elf_test.go b/vendor/github.com/gopherjs/gopherjs/compiler/natives/src/debug/elf/elf_test.go similarity index 100% rename from vendor/github.com/gopherjs/gopherjs/compiler/natives/debug/elf/elf_test.go rename to vendor/github.com/gopherjs/gopherjs/compiler/natives/src/debug/elf/elf_test.go diff --git a/vendor/github.com/gopherjs/gopherjs/compiler/natives/encoding/json/json.go b/vendor/github.com/gopherjs/gopherjs/compiler/natives/src/encoding/json/stream_test.go similarity index 100% rename from vendor/github.com/gopherjs/gopherjs/compiler/natives/encoding/json/json.go rename to vendor/github.com/gopherjs/gopherjs/compiler/natives/src/encoding/json/stream_test.go diff --git a/vendor/github.com/gopherjs/gopherjs/compiler/natives/fmt/fmt_test.go b/vendor/github.com/gopherjs/gopherjs/compiler/natives/src/fmt/fmt_test.go similarity index 100% rename from vendor/github.com/gopherjs/gopherjs/compiler/natives/fmt/fmt_test.go rename to vendor/github.com/gopherjs/gopherjs/compiler/natives/src/fmt/fmt_test.go diff --git a/vendor/github.com/gopherjs/gopherjs/compiler/natives/go/token/token_test.go b/vendor/github.com/gopherjs/gopherjs/compiler/natives/src/go/token/token_test.go similarity index 100% rename from vendor/github.com/gopherjs/gopherjs/compiler/natives/go/token/token_test.go rename to vendor/github.com/gopherjs/gopherjs/compiler/natives/src/go/token/token_test.go diff --git a/vendor/github.com/gopherjs/gopherjs/compiler/natives/io/io_test.go b/vendor/github.com/gopherjs/gopherjs/compiler/natives/src/io/io_test.go similarity index 100% rename from vendor/github.com/gopherjs/gopherjs/compiler/natives/io/io_test.go rename to vendor/github.com/gopherjs/gopherjs/compiler/natives/src/io/io_test.go diff --git a/vendor/github.com/gopherjs/gopherjs/compiler/natives/math/big/big.go b/vendor/github.com/gopherjs/gopherjs/compiler/natives/src/math/big/big.go similarity index 100% rename from vendor/github.com/gopherjs/gopherjs/compiler/natives/math/big/big.go rename to vendor/github.com/gopherjs/gopherjs/compiler/natives/src/math/big/big.go diff --git a/vendor/github.com/gopherjs/gopherjs/compiler/natives/math/big/big_test.go b/vendor/github.com/gopherjs/gopherjs/compiler/natives/src/math/big/big_test.go similarity index 100% rename from vendor/github.com/gopherjs/gopherjs/compiler/natives/math/big/big_test.go rename to vendor/github.com/gopherjs/gopherjs/compiler/natives/src/math/big/big_test.go diff --git a/vendor/github.com/gopherjs/gopherjs/compiler/natives/math/math.go b/vendor/github.com/gopherjs/gopherjs/compiler/natives/src/math/math.go similarity index 100% rename from vendor/github.com/gopherjs/gopherjs/compiler/natives/math/math.go rename to vendor/github.com/gopherjs/gopherjs/compiler/natives/src/math/math.go diff --git a/vendor/github.com/gopherjs/gopherjs/compiler/natives/math/rand/rand_test.go b/vendor/github.com/gopherjs/gopherjs/compiler/natives/src/math/rand/rand_test.go similarity index 100% rename from vendor/github.com/gopherjs/gopherjs/compiler/natives/math/rand/rand_test.go rename to vendor/github.com/gopherjs/gopherjs/compiler/natives/src/math/rand/rand_test.go diff --git a/vendor/github.com/gopherjs/gopherjs/compiler/natives/src/net/http/fetch.go b/vendor/github.com/gopherjs/gopherjs/compiler/natives/src/net/http/fetch.go new file mode 100644 index 000000000..f3de001bd --- /dev/null +++ b/vendor/github.com/gopherjs/gopherjs/compiler/natives/src/net/http/fetch.go @@ -0,0 +1,144 @@ +// +build js + +package http + +import ( + "errors" + "io" + "io/ioutil" + "strconv" + + "github.com/gopherjs/gopherjs/js" +) + +// streamReader implements an io.ReadCloser wrapper for ReadableStream of https://fetch.spec.whatwg.org/. +type streamReader struct { + pending []byte + stream *js.Object +} + +func (r *streamReader) Read(p []byte) (n int, err error) { + if len(r.pending) == 0 { + var ( + bCh = make(chan []byte) + errCh = make(chan error) + ) + r.stream.Call("read").Call("then", + func(result *js.Object) { + if result.Get("done").Bool() { + errCh <- io.EOF + return + } + bCh <- result.Get("value").Interface().([]byte) + }, + func(reason *js.Object) { + // Assumes it's a DOMException. + errCh <- errors.New(reason.Get("message").String()) + }, + ) + select { + case b := <-bCh: + r.pending = b + case err := <-errCh: + return 0, err + } + } + n = copy(p, r.pending) + r.pending = r.pending[n:] + return n, nil +} + +func (r *streamReader) Close() error { + // TOOD: Cannot do this because it's a blocking call, and Close() is often called + // via `defer resp.Body.Close()`, but GopherJS currently has an issue with supporting that. + // See https://github.com/gopherjs/gopherjs/issues/381 and https://github.com/gopherjs/gopherjs/issues/426. + /*ch := make(chan error) + r.stream.Call("cancel").Call("then", + func(result *js.Object) { + if result != js.Undefined { + ch <- errors.New(result.String()) // TODO: Verify this works, it probably doesn't and should be rewritten as result.Get("message").String() or something. + return + } + ch <- nil + }, + ) + return <-ch*/ + r.stream.Call("cancel") + return nil +} + +// fetchTransport is a RoundTripper that is implemented using Fetch API. It supports streaming +// response bodies. +type fetchTransport struct{} + +func (t *fetchTransport) RoundTrip(req *Request) (*Response, error) { + headers := js.Global.Get("Headers").New() + for key, values := range req.Header { + for _, value := range values { + headers.Call("append", key, value) + } + } + opt := map[string]interface{}{ + "method": req.Method, + "headers": headers, + "credentials": "same-origin", + } + if req.Body != nil { + // TODO: Find out if request body can be streamed into the fetch request rather than in advance here. + // See BufferSource at https://fetch.spec.whatwg.org/#body-mixin. + body, err := ioutil.ReadAll(req.Body) + if err != nil { + req.Body.Close() // RoundTrip must always close the body, including on errors. + return nil, err + } + req.Body.Close() + opt["body"] = body + } + respPromise := js.Global.Call("fetch", req.URL.String(), opt) + + var ( + respCh = make(chan *Response) + errCh = make(chan error) + ) + respPromise.Call("then", + func(result *js.Object) { + header := Header{} + result.Get("headers").Call("forEach", func(value, key *js.Object) { + ck := CanonicalHeaderKey(key.String()) + header[ck] = append(header[ck], value.String()) + }) + + contentLength := int64(-1) + if cl, err := strconv.ParseInt(header.Get("Content-Length"), 10, 64); err == nil { + contentLength = cl + } + + select { + case respCh <- &Response{ + Status: result.Get("status").String() + " " + StatusText(result.Get("status").Int()), + StatusCode: result.Get("status").Int(), + Header: header, + ContentLength: contentLength, + Body: &streamReader{stream: result.Get("body").Call("getReader")}, + Request: req, + }: + case <-req.Cancel: + } + }, + func(reason *js.Object) { + select { + case errCh <- errors.New("net/http: fetch() failed"): + case <-req.Cancel: + } + }, + ) + select { + case <-req.Cancel: + // TODO: Abort request if possible using Fetch API. + return nil, errors.New("net/http: request canceled") + case resp := <-respCh: + return resp, nil + case err := <-errCh: + return nil, err + } +} diff --git a/vendor/github.com/gopherjs/gopherjs/compiler/natives/net/http/http.go b/vendor/github.com/gopherjs/gopherjs/compiler/natives/src/net/http/http.go similarity index 71% rename from vendor/github.com/gopherjs/gopherjs/compiler/natives/net/http/http.go rename to vendor/github.com/gopherjs/gopherjs/compiler/natives/src/net/http/http.go index 6b9362f6d..198c5d6a0 100644 --- a/vendor/github.com/gopherjs/gopherjs/compiler/natives/net/http/http.go +++ b/vendor/github.com/gopherjs/gopherjs/compiler/natives/src/net/http/http.go @@ -13,18 +13,30 @@ import ( "github.com/gopherjs/gopherjs/js" ) -var DefaultTransport RoundTripper = &XHRTransport{} +var DefaultTransport = func() RoundTripper { + switch { + case js.Global.Get("fetch") != js.Undefined && js.Global.Get("ReadableStream") != js.Undefined: // ReadableStream is used as a check for support of streaming response bodies, see https://fetch.spec.whatwg.org/#streams. + return &fetchTransport{} + case js.Global.Get("XMLHttpRequest") != js.Undefined: + return &XHRTransport{} + default: + return noTransport{} + } +}() + +// noTransport is used when neither Fetch API nor XMLHttpRequest API are available. It always fails. +type noTransport struct{} + +func (noTransport) RoundTrip(req *Request) (*Response, error) { + return nil, errors.New("net/http: neither of Fetch nor XMLHttpRequest APIs is available") +} type XHRTransport struct { inflight map[*Request]*js.Object } func (t *XHRTransport) RoundTrip(req *Request) (*Response, error) { - xhrConstructor := js.Global.Get("XMLHttpRequest") - if xhrConstructor == js.Undefined { - return nil, errors.New("net/http: XMLHttpRequest not available") - } - xhr := xhrConstructor.New() + xhr := js.Global.Get("XMLHttpRequest").New() if t.inflight == nil { t.inflight = map[*Request]*js.Object{} @@ -79,8 +91,10 @@ func (t *XHRTransport) RoundTrip(req *Request) (*Response, error) { var err error body, err = ioutil.ReadAll(req.Body) if err != nil { + req.Body.Close() // RoundTrip must always close the body, including on errors. return nil, err } + req.Body.Close() } xhr.Call("send", body) diff --git a/vendor/github.com/gopherjs/gopherjs/compiler/natives/net/net.go b/vendor/github.com/gopherjs/gopherjs/compiler/natives/src/net/net.go similarity index 100% rename from vendor/github.com/gopherjs/gopherjs/compiler/natives/net/net.go rename to vendor/github.com/gopherjs/gopherjs/compiler/natives/src/net/net.go diff --git a/vendor/github.com/gopherjs/gopherjs/compiler/natives/os/os.go b/vendor/github.com/gopherjs/gopherjs/compiler/natives/src/os/os.go similarity index 100% rename from vendor/github.com/gopherjs/gopherjs/compiler/natives/os/os.go rename to vendor/github.com/gopherjs/gopherjs/compiler/natives/src/os/os.go diff --git a/vendor/github.com/gopherjs/gopherjs/compiler/natives/reflect/reflect.go b/vendor/github.com/gopherjs/gopherjs/compiler/natives/src/reflect/reflect.go similarity index 99% rename from vendor/github.com/gopherjs/gopherjs/compiler/natives/reflect/reflect.go rename to vendor/github.com/gopherjs/gopherjs/compiler/natives/src/reflect/reflect.go index 2b9d462e3..0dfff0842 100644 --- a/vendor/github.com/gopherjs/gopherjs/compiler/natives/reflect/reflect.go +++ b/vendor/github.com/gopherjs/gopherjs/compiler/natives/src/reflect/reflect.go @@ -318,7 +318,7 @@ func MakeFunc(typ Type, fn func(args []Value) (results []Value)) Value { t := typ.common() ftyp := (*funcType)(unsafe.Pointer(t)) - fv := js.Global.Call("$makeFunc", js.InternalObject(func(arguments []*js.Object) *js.Object { + fv := js.MakeFunc(func(this *js.Object, arguments []*js.Object) interface{} { args := make([]Value, ftyp.NumIn()) for i := range args { argType := ftyp.In(i).common() @@ -337,7 +337,7 @@ func MakeFunc(typ Type, fn func(args []Value) (results []Value)) Value { } return results } - })) + }) return Value{t, unsafe.Pointer(fv.Unsafe()), flag(Func)} } @@ -564,9 +564,9 @@ func makeMethodValue(op string, v Value) Value { if isWrapped(v.typ) { rcvr = jsType(v.typ).New(rcvr) } - fv := js.Global.Call("$makeFunc", js.InternalObject(func(arguments []*js.Object) *js.Object { + fv := js.MakeFunc(func(this *js.Object, arguments []*js.Object) interface{} { return js.InternalObject(fn).Call("apply", rcvr, arguments) - })) + }) return Value{v.Type().common(), unsafe.Pointer(fv.Unsafe()), v.flag&flagRO | flag(Func)} } @@ -611,10 +611,10 @@ func (t *uncommonType) Method(i int) (m Method) { mt := p.typ m.Type = mt prop := js.Global.Call("$methodSet", js.InternalObject(t).Get("jsType")).Index(i).Get("prop").String() - fn := js.Global.Call("$makeFunc", js.InternalObject(func(arguments []*js.Object) *js.Object { + fn := js.MakeFunc(func(this *js.Object, arguments []*js.Object) interface{} { rcvr := arguments[0] return rcvr.Get(prop).Call("apply", rcvr, arguments[1:]) - })) + }) m.Func = Value{mt, unsafe.Pointer(fn.Unsafe()), fl} m.Index = i return diff --git a/vendor/github.com/gopherjs/gopherjs/compiler/natives/reflect/reflect_test.go b/vendor/github.com/gopherjs/gopherjs/compiler/natives/src/reflect/reflect_test.go similarity index 100% rename from vendor/github.com/gopherjs/gopherjs/compiler/natives/reflect/reflect_test.go rename to vendor/github.com/gopherjs/gopherjs/compiler/natives/src/reflect/reflect_test.go diff --git a/vendor/github.com/gopherjs/gopherjs/compiler/natives/regexp/regexp_test.go b/vendor/github.com/gopherjs/gopherjs/compiler/natives/src/regexp/regexp_test.go similarity index 100% rename from vendor/github.com/gopherjs/gopherjs/compiler/natives/regexp/regexp_test.go rename to vendor/github.com/gopherjs/gopherjs/compiler/natives/src/regexp/regexp_test.go diff --git a/vendor/github.com/gopherjs/gopherjs/compiler/natives/runtime/debug/debug.go b/vendor/github.com/gopherjs/gopherjs/compiler/natives/src/runtime/debug/debug.go similarity index 100% rename from vendor/github.com/gopherjs/gopherjs/compiler/natives/runtime/debug/debug.go rename to vendor/github.com/gopherjs/gopherjs/compiler/natives/src/runtime/debug/debug.go diff --git a/vendor/github.com/gopherjs/gopherjs/compiler/natives/runtime/pprof/pprof.go b/vendor/github.com/gopherjs/gopherjs/compiler/natives/src/runtime/pprof/pprof.go similarity index 100% rename from vendor/github.com/gopherjs/gopherjs/compiler/natives/runtime/pprof/pprof.go rename to vendor/github.com/gopherjs/gopherjs/compiler/natives/src/runtime/pprof/pprof.go diff --git a/vendor/github.com/gopherjs/gopherjs/compiler/natives/runtime/runtime.go b/vendor/github.com/gopherjs/gopherjs/compiler/natives/src/runtime/runtime.go similarity index 100% rename from vendor/github.com/gopherjs/gopherjs/compiler/natives/runtime/runtime.go rename to vendor/github.com/gopherjs/gopherjs/compiler/natives/src/runtime/runtime.go diff --git a/vendor/github.com/gopherjs/gopherjs/compiler/natives/strings/strings.go b/vendor/github.com/gopherjs/gopherjs/compiler/natives/src/strings/strings.go similarity index 100% rename from vendor/github.com/gopherjs/gopherjs/compiler/natives/strings/strings.go rename to vendor/github.com/gopherjs/gopherjs/compiler/natives/src/strings/strings.go diff --git a/vendor/github.com/gopherjs/gopherjs/compiler/natives/sync/atomic/atomic.go b/vendor/github.com/gopherjs/gopherjs/compiler/natives/src/sync/atomic/atomic.go similarity index 100% rename from vendor/github.com/gopherjs/gopherjs/compiler/natives/sync/atomic/atomic.go rename to vendor/github.com/gopherjs/gopherjs/compiler/natives/src/sync/atomic/atomic.go diff --git a/vendor/github.com/gopherjs/gopherjs/compiler/natives/sync/atomic/atomic_test.go b/vendor/github.com/gopherjs/gopherjs/compiler/natives/src/sync/atomic/atomic_test.go similarity index 100% rename from vendor/github.com/gopherjs/gopherjs/compiler/natives/sync/atomic/atomic_test.go rename to vendor/github.com/gopherjs/gopherjs/compiler/natives/src/sync/atomic/atomic_test.go diff --git a/vendor/github.com/gopherjs/gopherjs/compiler/natives/sync/cond.go b/vendor/github.com/gopherjs/gopherjs/compiler/natives/src/sync/cond.go similarity index 100% rename from vendor/github.com/gopherjs/gopherjs/compiler/natives/sync/cond.go rename to vendor/github.com/gopherjs/gopherjs/compiler/natives/src/sync/cond.go diff --git a/vendor/github.com/gopherjs/gopherjs/compiler/natives/sync/pool.go b/vendor/github.com/gopherjs/gopherjs/compiler/natives/src/sync/pool.go similarity index 100% rename from vendor/github.com/gopherjs/gopherjs/compiler/natives/sync/pool.go rename to vendor/github.com/gopherjs/gopherjs/compiler/natives/src/sync/pool.go diff --git a/vendor/github.com/gopherjs/gopherjs/compiler/natives/sync/sync.go b/vendor/github.com/gopherjs/gopherjs/compiler/natives/src/sync/sync.go similarity index 100% rename from vendor/github.com/gopherjs/gopherjs/compiler/natives/sync/sync.go rename to vendor/github.com/gopherjs/gopherjs/compiler/natives/src/sync/sync.go diff --git a/vendor/github.com/gopherjs/gopherjs/compiler/natives/sync/sync_test.go b/vendor/github.com/gopherjs/gopherjs/compiler/natives/src/sync/sync_test.go similarity index 100% rename from vendor/github.com/gopherjs/gopherjs/compiler/natives/sync/sync_test.go rename to vendor/github.com/gopherjs/gopherjs/compiler/natives/src/sync/sync_test.go diff --git a/vendor/github.com/gopherjs/gopherjs/compiler/natives/sync/waitgroup.go b/vendor/github.com/gopherjs/gopherjs/compiler/natives/src/sync/waitgroup.go similarity index 100% rename from vendor/github.com/gopherjs/gopherjs/compiler/natives/sync/waitgroup.go rename to vendor/github.com/gopherjs/gopherjs/compiler/natives/src/sync/waitgroup.go diff --git a/vendor/github.com/gopherjs/gopherjs/compiler/natives/syscall/syscall.go b/vendor/github.com/gopherjs/gopherjs/compiler/natives/src/syscall/syscall.go similarity index 80% rename from vendor/github.com/gopherjs/gopherjs/compiler/natives/syscall/syscall.go rename to vendor/github.com/gopherjs/gopherjs/compiler/natives/src/syscall/syscall.go index ec205dcda..a269ea717 100644 --- a/vendor/github.com/gopherjs/gopherjs/compiler/natives/syscall/syscall.go +++ b/vendor/github.com/gopherjs/gopherjs/compiler/natives/src/syscall/syscall.go @@ -3,7 +3,6 @@ package syscall import ( - "bytes" "unsafe" "github.com/gopherjs/gopherjs/js" @@ -37,7 +36,7 @@ func printToConsole(b []byte) { lineBuffer = append(lineBuffer, b...) for { - i := bytes.IndexByte(lineBuffer, '\n') + i := indexByte(lineBuffer, '\n') if i == -1 { break } @@ -49,3 +48,13 @@ func printToConsole(b []byte) { func use(p unsafe.Pointer) { // no-op } + +// indexByte is copied from bytes package to avoid importing it (since the real syscall package doesn't). +func indexByte(s []byte, c byte) int { + for i, b := range s { + if b == c { + return i + } + } + return -1 +} diff --git a/vendor/github.com/gopherjs/gopherjs/compiler/natives/syscall/syscall_unix.go b/vendor/github.com/gopherjs/gopherjs/compiler/natives/src/syscall/syscall_unix.go similarity index 100% rename from vendor/github.com/gopherjs/gopherjs/compiler/natives/syscall/syscall_unix.go rename to vendor/github.com/gopherjs/gopherjs/compiler/natives/src/syscall/syscall_unix.go diff --git a/vendor/github.com/gopherjs/gopherjs/compiler/natives/syscall/syscall_windows.go b/vendor/github.com/gopherjs/gopherjs/compiler/natives/src/syscall/syscall_windows.go similarity index 100% rename from vendor/github.com/gopherjs/gopherjs/compiler/natives/syscall/syscall_windows.go rename to vendor/github.com/gopherjs/gopherjs/compiler/natives/src/syscall/syscall_windows.go diff --git a/vendor/github.com/gopherjs/gopherjs/compiler/natives/time/time.go b/vendor/github.com/gopherjs/gopherjs/compiler/natives/src/time/time.go similarity index 87% rename from vendor/github.com/gopherjs/gopherjs/compiler/natives/time/time.go rename to vendor/github.com/gopherjs/gopherjs/compiler/natives/src/time/time.go index 24e0b2b14..11cc7d33b 100644 --- a/vendor/github.com/gopherjs/gopherjs/compiler/natives/time/time.go +++ b/vendor/github.com/gopherjs/gopherjs/compiler/natives/src/time/time.go @@ -4,7 +4,6 @@ package time import ( "runtime" - "strings" "github.com/gopherjs/gopherjs/js" ) @@ -29,8 +28,8 @@ type runtimeTimer struct { func initLocal() { d := js.Global.Get("Date").New() s := d.String() - i := strings.IndexByte(s, '(') - j := strings.IndexByte(s, ')') + i := indexByte(s, '(') + j := indexByte(s, ')') if i == -1 || j == -1 { localLoc.name = "UTC" return @@ -95,3 +94,8 @@ func initTestingZone() { z.name = "Local" localLoc = *z } + +// indexByte is copied from strings package to avoid importing it (since the real time package doesn't). +func indexByte(s string, c byte) int { + return js.InternalObject(s).Call("indexOf", js.Global.Get("String").Call("fromCharCode", c)).Int() +} diff --git a/vendor/github.com/gopherjs/gopherjs/compiler/natives/unicode/unicode.go b/vendor/github.com/gopherjs/gopherjs/compiler/natives/src/unicode/unicode.go similarity index 100% rename from vendor/github.com/gopherjs/gopherjs/compiler/natives/unicode/unicode.go rename to vendor/github.com/gopherjs/gopherjs/compiler/natives/src/unicode/unicode.go diff --git a/vendor/github.com/gopherjs/gopherjs/compiler/prelude/goroutines.go b/vendor/github.com/gopherjs/gopherjs/compiler/prelude/goroutines.go index 32ff870d6..a279675f6 100644 --- a/vendor/github.com/gopherjs/gopherjs/compiler/prelude/goroutines.go +++ b/vendor/github.com/gopherjs/gopherjs/compiler/prelude/goroutines.go @@ -218,14 +218,16 @@ var $send = function(chan, value) { } var thisGoroutine = $curGoroutine; - chan.$sendQueue.push(function() { + var closedDuringSend; + chan.$sendQueue.push(function(closed) { + closedDuringSend = closed; $schedule(thisGoroutine); return value; }); $block(); return { $blk: function() { - if (chan.$closed) { + if (closedDuringSend) { $throwRuntimeError("send on closed channel"); } } @@ -234,7 +236,7 @@ var $send = function(chan, value) { var $recv = function(chan) { var queuedSend = chan.$sendQueue.shift(); if (queuedSend !== undefined) { - chan.$buffer.push(queuedSend()); + chan.$buffer.push(queuedSend(false)); } var bufferedValue = chan.$buffer.shift(); if (bufferedValue !== undefined) { @@ -264,7 +266,7 @@ var $close = function(chan) { if (queuedSend === undefined) { break; } - queuedSend(); /* will panic because of closed channel */ + queuedSend(true); /* will panic */ } while (true) { var queuedRecv = chan.$recvQueue.shift(); diff --git a/vendor/github.com/gopherjs/gopherjs/compiler/prelude/prelude.go b/vendor/github.com/gopherjs/gopherjs/compiler/prelude/prelude.go index cafef185b..27173094f 100644 --- a/vendor/github.com/gopherjs/gopherjs/compiler/prelude/prelude.go +++ b/vendor/github.com/gopherjs/gopherjs/compiler/prelude/prelude.go @@ -29,7 +29,7 @@ var $flushConsole = function() {}; var $throwRuntimeError; /* set by package "runtime" */ var $throwNilPointerError = function() { $throwRuntimeError("invalid memory address or nil pointer dereference"); }; var $call = function(fn, rcvr, args) { return fn.apply(rcvr, args); }; -var $makeFunc = function(fn) { return function() { return fn(new ($sliceType($jsObjectPtr))($global.Array.prototype.slice.call(arguments, []))); } }; +var $makeFunc = function(fn) { return function() { return $externalize(fn(this, new ($sliceType($jsObjectPtr))($global.Array.prototype.slice.call(arguments, []))), $emptyInterface); }; }; var $mapArray = function(array, f) { var newArray = new array.constructor(array.length); diff --git a/vendor/github.com/gopherjs/gopherjs/compiler/statements.go b/vendor/github.com/gopherjs/gopherjs/compiler/statements.go index 87042d007..cbd39a79a 100644 --- a/vendor/github.com/gopherjs/gopherjs/compiler/statements.go +++ b/vendor/github.com/gopherjs/gopherjs/compiler/statements.go @@ -748,7 +748,26 @@ func (c *funcContext) translateResults(results []ast.Expr) string { return " " + v.String() default: if len(results) == 1 { - return " " + c.translateExpr(results[0]).String() + resultTuple := c.p.TypeOf(results[0]).(*types.Tuple) + + if resultTuple.Len() != tuple.Len() { + panic("invalid tuple return assignment") + } + + resultExpr := c.translateExpr(results[0]).String() + + if types.Identical(resultTuple, tuple) { + return " " + resultExpr + } + + tmpVar := c.newVariable("_returncast") + c.Printf("%s = %s;", tmpVar, resultExpr) + + // Not all the return types matched, map everything out for implicit casting + results = make([]ast.Expr, resultTuple.Len()) + for i := range results { + results[i] = c.newIdent(fmt.Sprintf("%s[%d]", tmpVar, i), resultTuple.At(i).Type()) + } } values := make([]string, tuple.Len()) for i := range values { diff --git a/vendor/github.com/gopherjs/gopherjs/compiler/typesutil/typesutil.go b/vendor/github.com/gopherjs/gopherjs/compiler/typesutil/typesutil.go index 600925b81..fccb71f77 100644 --- a/vendor/github.com/gopherjs/gopherjs/compiler/typesutil/typesutil.go +++ b/vendor/github.com/gopherjs/gopherjs/compiler/typesutil/typesutil.go @@ -1,9 +1,12 @@ package typesutil -import "go/types" +import ( + "go/types" + "strings" +) func IsJsPackage(pkg *types.Package) bool { - return pkg != nil && pkg.Path() == "github.com/gopherjs/gopherjs/js" + return pkg != nil && (pkg.Path() == "github.com/gopherjs/gopherjs/js" || strings.HasSuffix(pkg.Path(), "/vendor/github.com/gopherjs/gopherjs/js")) } func IsJsObject(t types.Type) bool { diff --git a/vendor/github.com/gopherjs/gopherjs/compiler/version_check.go b/vendor/github.com/gopherjs/gopherjs/compiler/version_check.go index ac5ee363d..c297ea27d 100644 --- a/vendor/github.com/gopherjs/gopherjs/compiler/version_check.go +++ b/vendor/github.com/gopherjs/gopherjs/compiler/version_check.go @@ -1,3 +1,4 @@ +// +build !go1.7 // +build go1.6 package compiler diff --git a/vendor/github.com/gopherjs/gopherjs/doc/packages.md b/vendor/github.com/gopherjs/gopherjs/doc/packages.md index a88bf4f36..1629d0a34 100644 --- a/vendor/github.com/gopherjs/gopherjs/doc/packages.md +++ b/vendor/github.com/gopherjs/gopherjs/doc/packages.md @@ -107,7 +107,7 @@ On each commit, Circle CI automatically compiles all supported packages with Gop | -- multipart | yes | | | -- quotedprintable | yes | | | net | no | | -| -- http | partially | emulated via XMLHttpRequest | +| -- http | partially | client only, emulated via Fetch/XMLHttpRequest APIs;
node.js requires polyfill | | -- -- cgi | no | | | -- -- cookiejar | yes | | | -- -- fcgi | yes | | diff --git a/vendor/github.com/gopherjs/gopherjs/js/js.go b/vendor/github.com/gopherjs/gopherjs/js/js.go index 5367d3d0f..42249fdd6 100644 --- a/vendor/github.com/gopherjs/gopherjs/js/js.go +++ b/vendor/github.com/gopherjs/gopherjs/js/js.go @@ -112,8 +112,8 @@ func InternalObject(i interface{}) *Object { } // MakeFunc wraps a function and gives access to the values of JavaScript's "this" and "arguments" keywords. -func MakeFunc(func(this *Object, arguments []*Object) interface{}) *Object { - return nil +func MakeFunc(fn func(this *Object, arguments []*Object) interface{}) *Object { + return Global.Call("$makeFunc", InternalObject(fn)) } // Keys returns the keys of the given JavaScript object. diff --git a/vendor/github.com/gopherjs/gopherjs/js/js_test.go b/vendor/github.com/gopherjs/gopherjs/js/js_test.go index c9797fb0f..798d73e50 100644 --- a/vendor/github.com/gopherjs/gopherjs/js/js_test.go +++ b/vendor/github.com/gopherjs/gopherjs/js/js_test.go @@ -5,6 +5,7 @@ package js_test import ( "fmt" "reflect" + "strings" "testing" "time" @@ -376,7 +377,7 @@ func TestError(t *testing.T) { t.Fail() } jsErr, ok := err.(*js.Error) - if !ok || jsErr.Get("stack") == js.Undefined { + if !ok || !strings.Contains(jsErr.Error(), "throwsError") { t.Fail() } }() @@ -398,15 +399,21 @@ func TestExternalizeField(t *testing.T) { func TestMakeFunc(t *testing.T) { o := js.Global.Get("Object").New() - o.Set("f", js.MakeFunc(func(this *js.Object, arguments []*js.Object) interface{} { - if this != o { - t.Fail() - } - if len(arguments) != 2 || arguments[0].Int() != 1 || arguments[1].Int() != 2 { - t.Fail() + for i := 3; i < 5; i++ { + x := i + if i == 4 { + break } - return 3 - })) + o.Set("f", js.MakeFunc(func(this *js.Object, arguments []*js.Object) interface{} { + if this != o { + t.Fail() + } + if len(arguments) != 2 || arguments[0].Int() != 1 || arguments[1].Int() != 2 { + t.Fail() + } + return x + })) + } if o.Call("f", 1, 2).Int() != 3 { t.Fail() } diff --git a/vendor/github.com/gopherjs/gopherjs/tests/goroutine_test.go b/vendor/github.com/gopherjs/gopherjs/tests/goroutine_test.go index 42b77718e..9e3ced056 100644 --- a/vendor/github.com/gopherjs/gopherjs/tests/goroutine_test.go +++ b/vendor/github.com/gopherjs/gopherjs/tests/goroutine_test.go @@ -122,3 +122,12 @@ func TestSelect(t *testing.T) { <-c checkI(t, 3) } + +func TestCloseAfterReceiving(t *testing.T) { + ch := make(chan struct{}) + go func() { + <-ch + close(ch) + }() + ch <- struct{}{} +} diff --git a/vendor/github.com/gopherjs/gopherjs/tests/lowlevel_test.go b/vendor/github.com/gopherjs/gopherjs/tests/lowlevel_test.go index ace2d183a..cc4a7d4b2 100644 --- a/vendor/github.com/gopherjs/gopherjs/tests/lowlevel_test.go +++ b/vendor/github.com/gopherjs/gopherjs/tests/lowlevel_test.go @@ -15,7 +15,7 @@ import ( // // See https://github.com/gopherjs/gopherjs/issues/279. func TestTimeInternalizationExternalization(t *testing.T) { - got, err := exec.Command("gopherjs", "run", filepath.Join("testdata", "time_inexternalization.go")).CombinedOutput() + got, err := exec.Command("gopherjs", "run", filepath.Join("testdata", "time_inexternalization.go")).Output() if err != nil { t.Fatalf("%v:\n%s", err, got) } diff --git a/vendor/github.com/gopherjs/gopherjs/tests/misc_test.go b/vendor/github.com/gopherjs/gopherjs/tests/misc_test.go index 5c54fd9ec..cb34b2185 100644 --- a/vendor/github.com/gopherjs/gopherjs/tests/misc_test.go +++ b/vendor/github.com/gopherjs/gopherjs/tests/misc_test.go @@ -535,3 +535,53 @@ func TestTrivialSwitch(t *testing.T) { } t.Fail() } + +func TestTupleFnReturnImplicitCast(t *testing.T) { + var ycalled int = 0 + x := func(fn func() (int, error)) (interface{}, error) { + return fn() + } + y, _ := x(func() (int, error) { + ycalled++ + return 14, nil + }) + if y != 14 || ycalled != 1 { + t.Fail() + } +} + +var tuple2called = 0 + +func tuple1() (interface{}, error) { + return tuple2() +} +func tuple2() (int, error) { + tuple2called++ + return 14, nil +} +func TestTupleReturnImplicitCast(t *testing.T) { + x, _ := tuple1() + if x != 14 || tuple2called != 1 { + t.Fail() + } +} + +func TestDeferNamedTupleReturnImplicitCast(t *testing.T) { + var ycalled int = 0 + var zcalled int = 0 + z := func() { + zcalled++ + } + x := func(fn func() (int, error)) (i interface{}, e error) { + defer z() + i, e = fn() + return + } + y, _ := x(func() (int, error) { + ycalled++ + return 14, nil + }) + if y != 14 || ycalled != 1 || zcalled != 1 { + t.Fail() + } +} diff --git a/vendor/github.com/gopherjs/gopherjs/tests/run.go b/vendor/github.com/gopherjs/gopherjs/tests/run.go index af9f3deeb..e90f06526 100644 --- a/vendor/github.com/gopherjs/gopherjs/tests/run.go +++ b/vendor/github.com/gopherjs/gopherjs/tests/run.go @@ -242,7 +242,7 @@ func main() { errStr, test.goFileName(), dt) continue } - if !*verbose { + if !*verbose && status != "unok" { continue } fmt.Printf("%s\t%s\t%s\n", status, test.goFileName(), dt) diff --git a/vendor/github.com/gopherjs/gopherjs/tool.go b/vendor/github.com/gopherjs/gopherjs/tool.go index 92c9ac41c..951fe0a62 100644 --- a/vendor/github.com/gopherjs/gopherjs/tool.go +++ b/vendor/github.com/gopherjs/gopherjs/tool.go @@ -2,9 +2,11 @@ package main import ( "bytes" + "errors" "fmt" "go/ast" "go/build" + "go/doc" "go/parser" "go/scanner" "go/token" @@ -23,6 +25,8 @@ import ( "syscall" "text/template" "time" + "unicode" + "unicode/utf8" gbuild "github.com/gopherjs/gopherjs/build" "github.com/gopherjs/gopherjs/compiler" @@ -325,25 +329,27 @@ func main() { fmt.Printf("? \t%s\t[no test files]\n", pkg.ImportPath) continue } - s := gbuild.NewSession(options) + tests := &testFuncs{Package: pkg.Package} collectTests := func(testPkg *gbuild.PackageData, testPkgName string, needVar *bool) error { - archive, err := s.BuildPackage(testPkg) - if err != nil { - return err - } - - for _, decl := range archive.Declarations { - if strings.HasPrefix(decl.FullName, testPkg.ImportPath+".Test") { - tests.Tests = append(tests.Tests, testFunc{Package: testPkgName, Name: decl.FullName[len(testPkg.ImportPath)+1:]}) - *needVar = true + if testPkgName == "_test" { + for _, file := range pkg.TestGoFiles { + if err := tests.load(filepath.Join(pkg.Package.Dir, file), testPkgName, &tests.ImportTest, &tests.NeedTest); err != nil { + return err + } } - if strings.HasPrefix(decl.FullName, testPkg.ImportPath+".Benchmark") { - tests.Benchmarks = append(tests.Benchmarks, testFunc{Package: testPkgName, Name: decl.FullName[len(testPkg.ImportPath)+1:]}) - *needVar = true + } else { + for _, file := range pkg.XTestGoFiles { + if err := tests.load(filepath.Join(pkg.Package.Dir, file), "_xtest", &tests.ImportXtest, &tests.NeedXtest); err != nil { + return err + } } } + _, err := s.BuildPackage(testPkg) + if err != nil { + return err + } return nil } @@ -457,33 +463,6 @@ func main() { }, options, nil)) } - cmdTool := &cobra.Command{ - Use: "tool [command] [args...]", - Short: "run specified go tool", - } - cmdTool.Flags().BoolP("e", "e", false, "") - cmdTool.Flags().BoolP("l", "l", false, "") - cmdTool.Flags().StringP("o", "o", "", "") - cmdTool.Flags().StringP("D", "D", "", "") - cmdTool.Flags().StringP("I", "I", "", "") - cmdTool.Run = func(cmd *cobra.Command, args []string) { - os.Exit(handleError(func() error { - if len(args) == 2 { - switch args[0][1] { - case 'g': - basename := filepath.Base(args[1]) - s := gbuild.NewSession(options) - if err := s.BuildFiles([]string{args[1]}, basename[:len(basename)-3]+".js", currentDirectory); err != nil { - return err - } - return nil - } - } - cmdTool.Help() - return nil - }, options, nil)) - } - cmdServe := &cobra.Command{ Use: "serve [root]", Short: "compile on-the-fly and serve", @@ -533,7 +512,7 @@ func main() { Use: "gopherjs", Long: "GopherJS is a tool for compiling Go source code to JavaScript.", } - rootCmd.AddCommand(cmdBuild, cmdGet, cmdInstall, cmdRun, cmdTest, cmdTool, cmdServe) + rootCmd.AddCommand(cmdBuild, cmdGet, cmdInstall, cmdRun, cmdTest, cmdServe) rootCmd.Execute() } @@ -640,7 +619,7 @@ func (fs serveCommandFileSystem) Open(requestName string) (http.File, error) { if isIndex { // If there was no index.html file in any dirs, supply our own. - return newFakeFile("index.html", []byte(``)), nil + return newFakeFile("index.html", []byte(``)), nil } return nil, os.ErrNotExist @@ -770,12 +749,15 @@ func runNode(script string, args []string, dir string, quiet bool) error { } type testFuncs struct { - Tests []testFunc - Benchmarks []testFunc - Examples []testFunc - Package *build.Package - NeedTest bool - NeedXtest bool + Tests []testFunc + Benchmarks []testFunc + Examples []testFunc + TestMain *testFunc + Package *build.Package + ImportTest bool + NeedTest bool + ImportXtest bool + NeedXtest bool } type testFunc struct { @@ -784,18 +766,102 @@ type testFunc struct { Output string // output, for examples } +var testFileSet = token.NewFileSet() + +func (t *testFuncs) load(filename, pkg string, doImport, seen *bool) error { + f, err := parser.ParseFile(testFileSet, filename, nil, parser.ParseComments) + if err != nil { + return err + } + for _, d := range f.Decls { + n, ok := d.(*ast.FuncDecl) + if !ok { + continue + } + if n.Recv != nil { + continue + } + name := n.Name.String() + switch { + case isTestMain(n): + if t.TestMain != nil { + return errors.New("multiple definitions of TestMain") + } + t.TestMain = &testFunc{pkg, name, ""} + *doImport, *seen = true, true + case isTest(name, "Test"): + t.Tests = append(t.Tests, testFunc{pkg, name, ""}) + *doImport, *seen = true, true + case isTest(name, "Benchmark"): + t.Benchmarks = append(t.Benchmarks, testFunc{pkg, name, ""}) + *doImport, *seen = true, true + } + } + // TODO: Support examples, populate t.Examples here. + // Blocking on https://github.com/gopherjs/gopherjs/issues/381 being resolved. + return nil +} + +type byOrder []*doc.Example + +func (x byOrder) Len() int { return len(x) } +func (x byOrder) Swap(i, j int) { x[i], x[j] = x[j], x[i] } +func (x byOrder) Less(i, j int) bool { return x[i].Order < x[j].Order } + +// isTestMain tells whether fn is a TestMain(m *testing.M) function. +func isTestMain(fn *ast.FuncDecl) bool { + if fn.Name.String() != "TestMain" || + fn.Type.Results != nil && len(fn.Type.Results.List) > 0 || + fn.Type.Params == nil || + len(fn.Type.Params.List) != 1 || + len(fn.Type.Params.List[0].Names) > 1 { + return false + } + ptr, ok := fn.Type.Params.List[0].Type.(*ast.StarExpr) + if !ok { + return false + } + // We can't easily check that the type is *testing.M + // because we don't know how testing has been imported, + // but at least check that it's *M or *something.M. + if name, ok := ptr.X.(*ast.Ident); ok && name.Name == "M" { + return true + } + if sel, ok := ptr.X.(*ast.SelectorExpr); ok && sel.Sel.Name == "M" { + return true + } + return false +} + +// isTest tells whether name looks like a test (or benchmark, according to prefix). +// It is a Test (say) if there is a character after Test that is not a lower-case letter. +// We don't want TesticularCancer. +func isTest(name, prefix string) bool { + if !strings.HasPrefix(name, prefix) { + return false + } + if len(name) == len(prefix) { // "Test" is ok + return true + } + rune, _ := utf8.DecodeRuneInString(name[len(prefix):]) + return !unicode.IsLower(rune) +} + var testmainTmpl = template.Must(template.New("main").Parse(` package main import ( +{{if not .TestMain}} + "os" +{{end}} "regexp" "testing" -{{if .NeedTest}} - _test {{.Package.ImportPath | printf "%q"}} +{{if .ImportTest}} + {{if .NeedTest}}_test{{else}}_{{end}} {{.Package.ImportPath | printf "%q"}} {{end}} -{{if .NeedXtest}} - _xtest {{.Package.ImportPath | printf "%s_test" | printf "%q"}} +{{if .ImportXtest}} + {{if .NeedXtest}}_xtest{{else}}_{{end}} {{.Package.ImportPath | printf "%s_test" | printf "%q"}} {{end}} ) @@ -832,7 +898,12 @@ func matchString(pat, str string) (result bool, err error) { } func main() { - testing.Main(matchString, tests, benchmarks, examples) + m := testing.MainStart(matchString, tests, benchmarks, examples) +{{with .TestMain}} + {{.Package}}.{{.Name}}(m) +{{else}} + os.Exit(m.Run()) +{{end}} } `)) diff --git a/vendor/github.com/mgutz/ansi/.gitignore b/vendor/github.com/mgutz/ansi/.gitignore new file mode 100644 index 000000000..9ed3b07ce --- /dev/null +++ b/vendor/github.com/mgutz/ansi/.gitignore @@ -0,0 +1 @@ +*.test diff --git a/vendor/github.com/mgutz/ansi/LICENSE b/vendor/github.com/mgutz/ansi/LICENSE new file mode 100644 index 000000000..06ce0c3b5 --- /dev/null +++ b/vendor/github.com/mgutz/ansi/LICENSE @@ -0,0 +1,9 @@ +The MIT License (MIT) +Copyright (c) 2013 Mario L. Gutierrez + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + diff --git a/vendor/github.com/mgutz/ansi/README.md b/vendor/github.com/mgutz/ansi/README.md new file mode 100644 index 000000000..5fb3f2227 --- /dev/null +++ b/vendor/github.com/mgutz/ansi/README.md @@ -0,0 +1,119 @@ +# ansi + +Package ansi is a small, fast library to create ANSI colored strings and codes. + +## Install + +This install the color viewer and the package itself + +```sh +go get -u github.com/mgutz/ansi/cmd/ansi-mgutz +``` + +## Example + +```go +import "github.com/mgutz/ansi" + +// colorize a string, SLOW +msg := ansi.Color("foo", "red+b:white") + +// create a closure to avoid recalculating ANSI code compilation +phosphorize := ansi.ColorFunc("green+h:black") +msg = phosphorize("Bring back the 80s!") +msg2 := phospohorize("Look, I'm a CRT!") + +// cache escape codes and build strings manually +lime := ansi.ColorCode("green+h:black") +reset := ansi.ColorCode("reset") + +fmt.Println(lime, "Bring back the 80s!", reset) +``` + +Other examples + +```go +Color(s, "red") // red +Color(s, "red+b") // red bold +Color(s, "red+B") // red blinking +Color(s, "red+u") // red underline +Color(s, "red+bh") // red bold bright +Color(s, "red:white") // red on white +Color(s, "red+b:white+h") // red bold on white bright +Color(s, "red+B:white+h") // red blink on white bright +Color(s, "off") // turn off ansi codes +``` + +To view color combinations, from terminal. + +```sh +ansi-mgutz +``` + +## Style format + +```go +"foregroundColor+attributes:backgroundColor+attributes" +``` + +Colors + +* black +* red +* green +* yellow +* blue +* magenta +* cyan +* white +* 0...255 (256 colors) + +Attributes + +* b = bold foreground +* B = Blink foreground +* u = underline foreground +* i = inverse +* h = high intensity (bright) foreground, background + + does not work with 256 colors + +## Constants + +* ansi.Reset +* ansi.DefaultBG +* ansi.DefaultFG +* ansi.Black +* ansi.Red +* ansi.Green +* ansi.Yellow +* ansi.Blue +* ansi.Magenta +* ansi.Cyan +* ansi.White +* ansi.LightBlack +* ansi.LightRed +* ansi.LightGreen +* ansi.LightYellow +* ansi.LightBlue +* ansi.LightMagenta +* ansi.LightCyan +* ansi.LightWhite + + +## References + +Wikipedia ANSI escape codes [Colors](http://en.wikipedia.org/wiki/ANSI_escape_code#Colors) + +General [tips and formatting](http://misc.flogisoft.com/bash/tip_colors_and_formatting) + +What about support on Windows? Use [colorable by mattn](https://github.com/mattn/go-colorable). +Ansi and colorable are used by [logxi](https://github.com/mgutz/logxi) to support logging in +color on Windows. + +## MIT License + +Copyright (c) 2013 Mario Gutierrez mario@mgutz.com + +See the file LICENSE for copying permission. + diff --git a/vendor/github.com/mgutz/ansi/ansi.go b/vendor/github.com/mgutz/ansi/ansi.go new file mode 100644 index 000000000..099aee3c5 --- /dev/null +++ b/vendor/github.com/mgutz/ansi/ansi.go @@ -0,0 +1,246 @@ +package ansi + +import ( + "bytes" + "fmt" + "strconv" + "strings" +) + +const ( + black = iota + red + green + yellow + blue + magenta + cyan + white + defaultt = 9 + + normalIntensityFG = 30 + highIntensityFG = 90 + normalIntensityBG = 40 + highIntensityBG = 100 + + start = "\033[" + bold = "1;" + blink = "5;" + underline = "4;" + inverse = "7;" + + // Reset is the ANSI reset escape sequence + Reset = "\033[0m" + // DefaultBG is the default background + DefaultBG = "\033[49m" + // DefaultFG is the default foreground + DefaultFG = "\033[39m" +) + +// Black FG +var Black string + +// Red FG +var Red string + +// Green FG +var Green string + +// Yellow FG +var Yellow string + +// Blue FG +var Blue string + +// Magenta FG +var Magenta string + +// Cyan FG +var Cyan string + +// White FG +var White string + +// LightBlack FG +var LightBlack string + +// LightRed FG +var LightRed string + +// LightGreen FG +var LightGreen string + +// LightYellow FG +var LightYellow string + +// LightBlue FG +var LightBlue string + +// LightMagenta FG +var LightMagenta string + +// LightCyan FG +var LightCyan string + +// LightWhite FG +var LightWhite string + +var ( + plain = false + // Colors maps common color names to their ANSI color code. + Colors = map[string]int{ + "black": black, + "red": red, + "green": green, + "yellow": yellow, + "blue": blue, + "magenta": magenta, + "cyan": cyan, + "white": white, + "default": defaultt, + } +) + +func init() { + for i := 0; i < 256; i++ { + Colors[strconv.Itoa(i)] = i + } + + Black = ColorCode("black") + Red = ColorCode("red") + Green = ColorCode("green") + Yellow = ColorCode("yellow") + Blue = ColorCode("blue") + Magenta = ColorCode("magenta") + Cyan = ColorCode("cyan") + White = ColorCode("white") + LightBlack = ColorCode("black+h") + LightRed = ColorCode("red+h") + LightGreen = ColorCode("green+h") + LightYellow = ColorCode("yellow+h") + LightBlue = ColorCode("blue+h") + LightMagenta = ColorCode("magenta+h") + LightCyan = ColorCode("cyan+h") + LightWhite = ColorCode("white+h") +} + +// ColorCode returns the ANSI color color code for style. +func ColorCode(style string) string { + return colorCode(style).String() +} + +// Gets the ANSI color code for a style. +func colorCode(style string) *bytes.Buffer { + buf := bytes.NewBufferString("") + if plain || style == "" { + return buf + } + if style == "reset" { + buf.WriteString(Reset) + return buf + } else if style == "off" { + return buf + } + + foregroundBackground := strings.Split(style, ":") + foreground := strings.Split(foregroundBackground[0], "+") + fgKey := foreground[0] + fg := Colors[fgKey] + fgStyle := "" + if len(foreground) > 1 { + fgStyle = foreground[1] + } + + bg, bgStyle := "", "" + + if len(foregroundBackground) > 1 { + background := strings.Split(foregroundBackground[1], "+") + bg = background[0] + if len(background) > 1 { + bgStyle = background[1] + } + } + + buf.WriteString(start) + base := normalIntensityFG + if len(fgStyle) > 0 { + if strings.Contains(fgStyle, "b") { + buf.WriteString(bold) + } + if strings.Contains(fgStyle, "B") { + buf.WriteString(blink) + } + if strings.Contains(fgStyle, "u") { + buf.WriteString(underline) + } + if strings.Contains(fgStyle, "i") { + buf.WriteString(inverse) + } + if strings.Contains(fgStyle, "h") { + base = highIntensityFG + } + } + + // if 256-color + n, err := strconv.Atoi(fgKey) + if err == nil { + fmt.Fprintf(buf, "38;5;%d;", n) + } else { + fmt.Fprintf(buf, "%d;", base+fg) + } + + base = normalIntensityBG + if len(bg) > 0 { + if strings.Contains(bgStyle, "h") { + base = highIntensityBG + } + // if 256-color + n, err := strconv.Atoi(bg) + if err == nil { + fmt.Fprintf(buf, "48;5;%d;", n) + } else { + fmt.Fprintf(buf, "%d;", base+Colors[bg]) + } + } + + // remove last ";" + buf.Truncate(buf.Len() - 1) + buf.WriteRune('m') + return buf +} + +// Color colors a string based on the ANSI color code for style. +func Color(s, style string) string { + if plain || len(style) < 1 { + return s + } + buf := colorCode(style) + buf.WriteString(s) + buf.WriteString(Reset) + return buf.String() +} + +// ColorFunc creates a closureto avoid ANSI color code calculation. +func ColorFunc(style string) func(string) string { + if style == "" { + return func(s string) string { + return s + } + } + color := ColorCode(style) + return func(s string) string { + if plain || s == "" { + return s + } + buf := bytes.NewBufferString(color) + buf.WriteString(s) + buf.WriteString(Reset) + result := buf.String() + return result + } +} + +// DisableColors disables ANSI color codes. On by default. +func DisableColors(disable bool) { + plain = disable +} diff --git a/vendor/github.com/mgutz/ansi/ansi_test.go b/vendor/github.com/mgutz/ansi/ansi_test.go new file mode 100644 index 000000000..d601e1163 --- /dev/null +++ b/vendor/github.com/mgutz/ansi/ansi_test.go @@ -0,0 +1,42 @@ +package ansi + +import ( + "fmt" + "testing" +) + +func TestPlain(t *testing.T) { + DisableColors(true) + bgColors := []string{ + "", + ":black", + ":red", + ":green", + ":yellow", + ":blue", + ":magenta", + ":cyan", + ":white", + } + for fg := range Colors { + for _, bg := range bgColors { + println(padColor(fg, []string{"" + bg, "+b" + bg, "+bh" + bg, "+u" + bg})) + println(padColor(fg, []string{"+uh" + bg, "+B" + bg, "+Bb" + bg /* backgrounds */, "" + bg + "+h"})) + println(padColor(fg, []string{"+b" + bg + "+h", "+bh" + bg + "+h", "+u" + bg + "+h", "+uh" + bg + "+h"})) + } + } +} + +func TestStyles(t *testing.T) { + PrintStyles() + DisableColors(false) + buf := colorCode("off") + if buf.String() != "" { + t.Fail() + } +} + +func ExampleColorFunc() { + brightGreen := ColorFunc("green+h") + fmt.Println(brightGreen("lime")) +} diff --git a/vendor/github.com/mgutz/ansi/cmd/ansi-mgutz/main.go b/vendor/github.com/mgutz/ansi/cmd/ansi-mgutz/main.go new file mode 100644 index 000000000..66ab77979 --- /dev/null +++ b/vendor/github.com/mgutz/ansi/cmd/ansi-mgutz/main.go @@ -0,0 +1,135 @@ +package main + +import ( + "fmt" + "sort" + "strconv" + + "github.com/mattn/go-colorable" + "github.com/mgutz/ansi" +) + +func main() { + printColors() + print256Colors() + printConstants() +} + +func pad(s string, length int) string { + for len(s) < length { + s += " " + } + return s +} + +func padColor(s string, styles []string) string { + buffer := "" + for _, style := range styles { + buffer += ansi.Color(pad(s+style, 20), s+style) + } + return buffer +} + +func printPlain() { + ansi.DisableColors(true) + bgColors := []string{ + "", + ":black", + ":red", + ":green", + ":yellow", + ":blue", + ":magenta", + ":cyan", + ":white", + } + for fg := range ansi.Colors { + for _, bg := range bgColors { + println(padColor(fg, []string{"" + bg, "+b" + bg, "+bh" + bg, "+u" + bg})) + println(padColor(fg, []string{"+uh" + bg, "+B" + bg, "+Bb" + bg /* backgrounds */, "" + bg + "+h"})) + println(padColor(fg, []string{"+b" + bg + "+h", "+bh" + bg + "+h", "+u" + bg + "+h", "+uh" + bg + "+h"})) + } + } +} + +func printColors() { + ansi.DisableColors(false) + stdout := colorable.NewColorableStdout() + + bgColors := []string{ + "", + ":black", + ":red", + ":green", + ":yellow", + ":blue", + ":magenta", + ":cyan", + ":white", + } + + keys := []string{} + for fg := range ansi.Colors { + _, err := strconv.Atoi(fg) + if err != nil { + keys = append(keys, fg) + } + } + sort.Strings(keys) + + for _, fg := range keys { + for _, bg := range bgColors { + fmt.Fprintln(stdout, padColor(fg, []string{"" + bg, "+b" + bg, "+bh" + bg, "+u" + bg})) + fmt.Fprintln(stdout, padColor(fg, []string{"+uh" + bg, "+B" + bg, "+Bb" + bg /* backgrounds */, "" + bg + "+h"})) + fmt.Fprintln(stdout, padColor(fg, []string{"+b" + bg + "+h", "+bh" + bg + "+h", "+u" + bg + "+h", "+uh" + bg + "+h"})) + } + } +} + +func print256Colors() { + ansi.DisableColors(false) + stdout := colorable.NewColorableStdout() + + bgColors := []string{""} + for i := 0; i < 256; i++ { + key := fmt.Sprintf(":%d", i) + bgColors = append(bgColors, key) + } + + keys := []string{} + for fg := range ansi.Colors { + n, err := strconv.Atoi(fg) + if err == nil { + keys = append(keys, fmt.Sprintf("%3d", n)) + } + } + sort.Strings(keys) + + for _, fg := range keys { + for _, bg := range bgColors { + fmt.Fprintln(stdout, padColor(fg, []string{"" + bg, "+b" + bg, "+u" + bg})) + fmt.Fprintln(stdout, padColor(fg, []string{"+B" + bg, "+Bb" + bg})) + } + } +} + +func printConstants() { + stdout := colorable.NewColorableStdout() + fmt.Fprintln(stdout, ansi.DefaultFG, "ansi.DefaultFG", ansi.Reset) + fmt.Fprintln(stdout, ansi.Black, "ansi.Black", ansi.Reset) + fmt.Fprintln(stdout, ansi.Red, "ansi.Red", ansi.Reset) + fmt.Fprintln(stdout, ansi.Green, "ansi.Green", ansi.Reset) + fmt.Fprintln(stdout, ansi.Yellow, "ansi.Yellow", ansi.Reset) + fmt.Fprintln(stdout, ansi.Blue, "ansi.Blue", ansi.Reset) + fmt.Fprintln(stdout, ansi.Magenta, "ansi.Magenta", ansi.Reset) + fmt.Fprintln(stdout, ansi.Cyan, "ansi.Cyan", ansi.Reset) + fmt.Fprintln(stdout, ansi.White, "ansi.White", ansi.Reset) + fmt.Fprintln(stdout, ansi.LightBlack, "ansi.LightBlack", ansi.Reset) + fmt.Fprintln(stdout, ansi.LightRed, "ansi.LightRed", ansi.Reset) + fmt.Fprintln(stdout, ansi.LightGreen, "ansi.LightGreen", ansi.Reset) + fmt.Fprintln(stdout, ansi.LightYellow, "ansi.LightYellow", ansi.Reset) + fmt.Fprintln(stdout, ansi.LightBlue, "ansi.LightBlue", ansi.Reset) + fmt.Fprintln(stdout, ansi.LightMagenta, "ansi.LightMagenta", ansi.Reset) + fmt.Fprintln(stdout, ansi.LightCyan, "ansi.LightCyan", ansi.Reset) + fmt.Fprintln(stdout, ansi.LightWhite, "ansi.LightWhite", ansi.Reset) +} diff --git a/vendor/github.com/mgutz/ansi/doc.go b/vendor/github.com/mgutz/ansi/doc.go new file mode 100644 index 000000000..43c217e11 --- /dev/null +++ b/vendor/github.com/mgutz/ansi/doc.go @@ -0,0 +1,65 @@ +/* +Package ansi is a small, fast library to create ANSI colored strings and codes. + +Installation + + # this installs the color viewer and the package + go get -u github.com/mgutz/ansi/cmd/ansi-mgutz + +Example + + // colorize a string, SLOW + msg := ansi.Color("foo", "red+b:white") + + // create a closure to avoid recalculating ANSI code compilation + phosphorize := ansi.ColorFunc("green+h:black") + msg = phosphorize("Bring back the 80s!") + msg2 := phospohorize("Look, I'm a CRT!") + + // cache escape codes and build strings manually + lime := ansi.ColorCode("green+h:black") + reset := ansi.ColorCode("reset") + + fmt.Println(lime, "Bring back the 80s!", reset) + +Other examples + + Color(s, "red") // red + Color(s, "red+b") // red bold + Color(s, "red+B") // red blinking + Color(s, "red+u") // red underline + Color(s, "red+bh") // red bold bright + Color(s, "red:white") // red on white + Color(s, "red+b:white+h") // red bold on white bright + Color(s, "red+B:white+h") // red blink on white bright + +To view color combinations, from terminal + + ansi-mgutz + +Style format + + "foregroundColor+attributes:backgroundColor+attributes" + +Colors + + black + red + green + yellow + blue + magenta + cyan + white + +Attributes + + b = bold foreground + B = Blink foreground + u = underline foreground + h = high intensity (bright) foreground, background + i = inverse + +Wikipedia ANSI escape codes [Colors](http://en.wikipedia.org/wiki/ANSI_escape_code#Colors) +*/ +package ansi diff --git a/vendor/github.com/mgutz/ansi/print.go b/vendor/github.com/mgutz/ansi/print.go new file mode 100644 index 000000000..044c9a684 --- /dev/null +++ b/vendor/github.com/mgutz/ansi/print.go @@ -0,0 +1,42 @@ +package ansi + +// PrintStyles prints all style combinations to the terminal. +func PrintStyles() { + oldPlain := plain + plain = false + + bgColors := []string{ + "", + ":black", + ":red", + ":green", + ":yellow", + ":blue", + ":magenta", + ":cyan", + ":white", + } + for fg := range Colors { + for _, bg := range bgColors { + println(padColor(fg, []string{"" + bg, "+b" + bg, "+bh" + bg, "+u" + bg})) + println(padColor(fg, []string{"+uh" + bg, "+B" + bg, "+Bb" + bg /* backgrounds */, "" + bg + "+h"})) + println(padColor(fg, []string{"+b" + bg + "+h", "+bh" + bg + "+h", "+u" + bg + "+h", "+uh" + bg + "+h"})) + } + } + plain = oldPlain +} + +func pad(s string, length int) string { + for len(s) < length { + s += " " + } + return s +} + +func padColor(s string, styles []string) string { + buffer := "" + for _, style := range styles { + buffer += Color(pad(s+style, 20), s+style) + } + return buffer +} diff --git a/vendor/github.com/shirou/gopsutil/LICENSE b/vendor/github.com/shirou/gopsutil/LICENSE index 602b2c098..da71a5e72 100644 --- a/vendor/github.com/shirou/gopsutil/LICENSE +++ b/vendor/github.com/shirou/gopsutil/LICENSE @@ -25,3 +25,37 @@ 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. + + +------- +internal/common/binary.go in the gopsutil is copied and modifid from golang/encoding/binary.go. + + + +Copyright (c) 2009 The Go Authors. 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. \ No newline at end of file diff --git a/vendor/github.com/shirou/gopsutil/README.rst b/vendor/github.com/shirou/gopsutil/README.rst index b96fd5f4f..97669563a 100644 --- a/vendor/github.com/shirou/gopsutil/README.rst +++ b/vendor/github.com/shirou/gopsutil/README.rst @@ -11,7 +11,7 @@ gopsutil: psutil for golang :target: http://godoc.org/github.com/shirou/gopsutil This is a port of psutil (http://pythonhosted.org/psutil/). The challenge is porting all -psutil functions on some architectures... +psutil functions on some architectures. .. highlights:: Breaking Changes! @@ -22,7 +22,7 @@ psutil functions on some architectures... Migrating to v2 ------------------------- -On gopsutil itself, `v2migration.sh `_ is used for migration. It can not be commly used, but it may help to your migration. +On gopsutil itself, `v2migration.sh `_ is used for migration. It can not be commonly used, but it may help you with migration. Available Architectures @@ -68,15 +68,22 @@ The output is below. Total: 3179569152, Free:284233728, UsedPercent:84.508194% {"total":3179569152,"available":492572672,"used":2895335424,"usedPercent":84.50819439828305, (snip...)} -You can set an alternative location to /proc by setting the HOST_PROC environment variable. -You can set an alternative location to /sys by setting the HOST_SYS environment variable. -You can set an alternative location to /etc by setting the HOST_ETC environment variable. +You can set an alternative location to :code:`/proc` by setting the :code:`HOST_PROC` environment variable. + +You can set an alternative location to :code:`/sys` by setting the :code:`HOST_SYS` environment variable. + +You can set an alternative location to :code:`/etc` by setting the :code:`HOST_ETC` environment variable. Documentation ------------------------ see http://godoc.org/github.com/shirou/gopsutil +Requirements +----------------- + +- go1.5 or above is required. + More Info -------------------- @@ -146,7 +153,7 @@ Current Status ------------------ - x: work -- b: almost work but something broken +- b: almost works, but something is broken ================= ====== ======= ====== ======= name Linux FreeBSD MacOSX Windows @@ -187,13 +194,13 @@ exe x x x uids x x x gids x x x terminal x x x -io_counters x x +io_counters x x x nice x x x x num_fds x num_ctx_switches x num_threads x x x x cpu_times x -memory_info x x x +memory_info x x x x memory_info_ex x memory_maps x open_files x diff --git a/vendor/github.com/shirou/gopsutil/cpu/cpu.go b/vendor/github.com/shirou/gopsutil/cpu/cpu.go index 71535094d..6f76b764c 100644 --- a/vendor/github.com/shirou/gopsutil/cpu/cpu.go +++ b/vendor/github.com/shirou/gopsutil/cpu/cpu.go @@ -5,6 +5,9 @@ import ( "runtime" "strconv" "strings" + "sync" + + "github.com/shirou/gopsutil/internal/common" ) type TimesStat struct { @@ -37,8 +40,22 @@ type InfoStat struct { Flags []string `json:"flags"` } -var lastCPUTimes []TimesStat -var lastPerCPUTimes []TimesStat +type lastPercent struct { + sync.Mutex + lastCPUTimes []TimesStat + lastPerCPUTimes []TimesStat +} + +var lastCPUPercent lastPercent +var invoke common.Invoker + +func init() { + invoke = common.Invoke{} + lastCPUPercent.Lock() + lastCPUPercent.lastCPUTimes, _ = Times(false) + lastCPUPercent.lastPerCPUTimes, _ = Times(true) + lastCPUPercent.Unlock() +} func Counts(logical bool) (int, error) { return runtime.NumCPU(), nil diff --git a/vendor/github.com/shirou/gopsutil/cpu/cpu_darwin.go b/vendor/github.com/shirou/gopsutil/cpu/cpu_darwin.go index fbb74a821..4cb1d8ca8 100644 --- a/vendor/github.com/shirou/gopsutil/cpu/cpu_darwin.go +++ b/vendor/github.com/shirou/gopsutil/cpu/cpu_darwin.go @@ -36,7 +36,7 @@ func Info() ([]InfoStat, error) { if err != nil { return ret, err } - out, err := exec.Command(sysctl, "machdep.cpu").Output() + out, err := invoke.Command(sysctl, "machdep.cpu") if err != nil { return ret, err } @@ -90,7 +90,7 @@ func Info() ([]InfoStat, error) { // Use the rated frequency of the CPU. This is a static value and does not // account for low power or Turbo Boost modes. - out, err = exec.Command(sysctl, "hw.cpufrequency").Output() + out, err = invoke.Command(sysctl, "hw.cpufrequency") if err != nil { return ret, err } diff --git a/vendor/github.com/shirou/gopsutil/cpu/cpu_darwin_cgo.go b/vendor/github.com/shirou/gopsutil/cpu/cpu_darwin_cgo.go index ee59fefc0..d38dd627e 100644 --- a/vendor/github.com/shirou/gopsutil/cpu/cpu_darwin_cgo.go +++ b/vendor/github.com/shirou/gopsutil/cpu/cpu_darwin_cgo.go @@ -10,7 +10,9 @@ package cpu #include #include #include +#if TARGET_OS_MAC #include +#endif #include #include */ diff --git a/vendor/github.com/shirou/gopsutil/cpu/cpu_freebsd.go b/vendor/github.com/shirou/gopsutil/cpu/cpu_freebsd.go index ce1adf3c1..edc962788 100644 --- a/vendor/github.com/shirou/gopsutil/cpu/cpu_freebsd.go +++ b/vendor/github.com/shirou/gopsutil/cpu/cpu_freebsd.go @@ -1,5 +1,3 @@ -// +build freebsd - package cpu import ( @@ -29,7 +27,7 @@ func init() { if err != nil { return } - out, err := exec.Command(getconf, "CLK_TCK").Output() + out, err := invoke.Command(getconf, "CLK_TCK") // ignore errors if err == nil { i, err := strconv.ParseFloat(strings.TrimSpace(string(out)), 64) @@ -99,29 +97,46 @@ func Times(percpu bool) ([]TimesStat, error) { return ret, nil } -// Returns only one CPUInfoStat on FreeBSD +// Returns only one InfoStat on FreeBSD. The information regarding core +// count, however is accurate and it is assumed that all InfoStat attributes +// are the same across CPUs. func Info() ([]InfoStat, error) { - filename := "/var/run/dmesg.boot" - lines, _ := common.ReadLines(filename) - - var ret []InfoStat + const dmesgBoot = "/var/run/dmesg.boot" + lines, _ := common.ReadLines(dmesgBoot) c := InfoStat{} + var vals []string + var err error + if vals, err = common.DoSysctrl("hw.clockrate"); err != nil { + return nil, err + } + if c.Mhz, err = strconv.ParseFloat(vals[0], 64); err != nil { + return nil, fmt.Errorf("Unable to parse FreeBSD CPU clock rate: %v", err) + } + c.CPU = int32(c.Mhz) + + if vals, err = common.DoSysctrl("hw.ncpu"); err != nil { + return nil, err + } + var i64 int64 + if i64, err = strconv.ParseInt(vals[0], 10, 32); err != nil { + return nil, fmt.Errorf("Unable to parse FreeBSD cores: %v", err) + } + c.Cores = int32(i64) + + if vals, err = common.DoSysctrl("hw.model"); err != nil { + return nil, err + } + c.ModelName = strings.Join(vals, " ") + for _, line := range lines { - if matches := regexp.MustCompile(`CPU:\s+(.+) \(([\d.]+).+\)`).FindStringSubmatch(line); matches != nil { - c.ModelName = matches[1] - t, err := strconv.ParseFloat(matches[2], 64) - if err != nil { - return ret, nil - } - c.Mhz = t - } else if matches := regexp.MustCompile(`Origin = "(.+)" Id = (.+) Family = (.+) Model = (.+) Stepping = (.+)`).FindStringSubmatch(line); matches != nil { + if matches := regexp.MustCompile(`Origin\s*=\s*"(.+)"\s+Id\s*=\s*(.+)\s+Family\s*=\s*(.+)\s+Model\s*=\s*(.+)\s+Stepping\s*=\s*(.+)`).FindStringSubmatch(line); matches != nil { c.VendorID = matches[1] c.Family = matches[3] c.Model = matches[4] t, err := strconv.ParseInt(matches[5], 10, 32) if err != nil { - return ret, nil + return nil, fmt.Errorf("Unable to parse FreeBSD CPU stepping information from %q: %v", line, err) } c.Stepping = int32(t) } else if matches := regexp.MustCompile(`Features=.+<(.+)>`).FindStringSubmatch(line); matches != nil { @@ -132,16 +147,8 @@ func Info() ([]InfoStat, error) { for _, v := range strings.Split(matches[1], ",") { c.Flags = append(c.Flags, strings.ToLower(v)) } - } else if matches := regexp.MustCompile(`Logical CPUs per core: (\d+)`).FindStringSubmatch(line); matches != nil { - // FIXME: no this line? - t, err := strconv.ParseInt(matches[1], 10, 32) - if err != nil { - return ret, nil - } - c.Cores = int32(t) } - } - return append(ret, c), nil + return []InfoStat{c}, nil } diff --git a/vendor/github.com/shirou/gopsutil/cpu/cpu_linux.go b/vendor/github.com/shirou/gopsutil/cpu/cpu_linux.go index 975b75c07..6df542bdb 100644 --- a/vendor/github.com/shirou/gopsutil/cpu/cpu_linux.go +++ b/vendor/github.com/shirou/gopsutil/cpu/cpu_linux.go @@ -19,7 +19,7 @@ func init() { if err != nil { return } - out, err := exec.Command(getconf, "CLK_TCK").Output() + out, err := invoke.Command(getconf, "CLK_TCK") // ignore errors if err == nil { i, err := strconv.ParseFloat(strings.TrimSpace(string(out)), 64) diff --git a/vendor/github.com/shirou/gopsutil/cpu/cpu_test.go b/vendor/github.com/shirou/gopsutil/cpu/cpu_test.go index c3d56ebe3..6082ffcc5 100644 --- a/vendor/github.com/shirou/gopsutil/cpu/cpu_test.go +++ b/vendor/github.com/shirou/gopsutil/cpu/cpu_test.go @@ -94,6 +94,40 @@ func testCPUPercent(t *testing.T, percpu bool) { } } +func testCPUPercentLastUsed(t *testing.T, percpu bool) { + + numcpu := runtime.NumCPU() + testCount := 10 + + if runtime.GOOS != "windows" { + testCount = 2 + v, err := Percent(time.Millisecond, percpu) + if err != nil { + t.Errorf("error %v", err) + } + // Skip CircleCI which CPU num is different + if os.Getenv("CIRCLECI") != "true" { + if (percpu && len(v) != numcpu) || (!percpu && len(v) != 1) { + t.Fatalf("wrong number of entries from CPUPercent: %v", v) + } + } + } + for i := 0; i < testCount; i++ { + v, err := Percent(0, percpu) + if err != nil { + t.Errorf("error %v", err) + } + time.Sleep(1 * time.Millisecond) + for _, percent := range v { + // Check for slightly greater then 100% to account for any rounding issues. + if percent < 0.0 || percent > 100.0001*float64(numcpu) { + t.Fatalf("CPUPercent value is invalid: %f", percent) + } + } + } + +} + func TestCPUPercent(t *testing.T) { testCPUPercent(t, false) } @@ -101,3 +135,11 @@ func TestCPUPercent(t *testing.T) { func TestCPUPercentPerCpu(t *testing.T) { testCPUPercent(t, true) } + +func TestCPUPercentIntervalZero(t *testing.T) { + testCPUPercentLastUsed(t, false) +} + +func TestCPUPercentIntervalZeroPerCPU(t *testing.T) { + testCPUPercentLastUsed(t, true) +} diff --git a/vendor/github.com/shirou/gopsutil/cpu/cpu_unix.go b/vendor/github.com/shirou/gopsutil/cpu/cpu_unix.go index 9f1ea4d77..0ed7d62ad 100644 --- a/vendor/github.com/shirou/gopsutil/cpu/cpu_unix.go +++ b/vendor/github.com/shirou/gopsutil/cpu/cpu_unix.go @@ -7,24 +7,46 @@ import ( "time" ) -func Percent(interval time.Duration, percpu bool) ([]float64, error) { - getAllBusy := func(t TimesStat) (float64, float64) { - busy := t.User + t.System + t.Nice + t.Iowait + t.Irq + - t.Softirq + t.Steal + t.Guest + t.GuestNice + t.Stolen - return busy + t.Idle, busy +func getAllBusy(t TimesStat) (float64, float64) { + busy := t.User + t.System + t.Nice + t.Iowait + t.Irq + + t.Softirq + t.Steal + t.Guest + t.GuestNice + t.Stolen + return busy + t.Idle, busy +} + +func calculateBusy(t1, t2 TimesStat) float64 { + t1All, t1Busy := getAllBusy(t1) + t2All, t2Busy := getAllBusy(t2) + + if t2Busy <= t1Busy { + return 0 + } + if t2All <= t1All { + return 1 + } + return (t2Busy - t1Busy) / (t2All - t1All) * 100 +} + +func calculateAllBusy(t1, t2 []TimesStat) ([]float64, error) { + // Make sure the CPU measurements have the same length. + if len(t1) != len(t2) { + return nil, fmt.Errorf( + "received two CPU counts: %d != %d", + len(t1), len(t2), + ) } - calculate := func(t1, t2 TimesStat) float64 { - t1All, t1Busy := getAllBusy(t1) - t2All, t2Busy := getAllBusy(t2) + ret := make([]float64, len(t1)) + for i, t := range t2 { + ret[i] = calculateBusy(t1[i], t) + } + return ret, nil +} - if t2Busy <= t1Busy { - return 0 - } - if t2All <= t1All { - return 1 - } - return (t2Busy - t1Busy) / (t2All - t1All) * 100 +//Percent calculates the percentage of cpu used either per CPU or combined. +//If an interval of 0 is given it will compare the current cpu times against the last call. +func Percent(interval time.Duration, percpu bool) ([]float64, error) { + if interval <= 0 { + return percentUsedFromLastCall(percpu) } // Get CPU usage at the start of the interval. @@ -33,9 +55,7 @@ func Percent(interval time.Duration, percpu bool) ([]float64, error) { return nil, err } - if interval > 0 { - time.Sleep(interval) - } + time.Sleep(interval) // And at the end of the interval. cpuTimes2, err := Times(percpu) @@ -43,17 +63,28 @@ func Percent(interval time.Duration, percpu bool) ([]float64, error) { return nil, err } - // Make sure the CPU measurements have the same length. - if len(cpuTimes1) != len(cpuTimes2) { - return nil, fmt.Errorf( - "received two CPU counts: %d != %d", - len(cpuTimes1), len(cpuTimes2), - ) + return calculateAllBusy(cpuTimes1, cpuTimes2) +} + +func percentUsedFromLastCall(percpu bool) ([]float64, error) { + cpuTimes, err := Times(percpu) + if err != nil { + return nil, err + } + lastCPUPercent.Lock() + defer lastCPUPercent.Unlock() + var lastTimes []TimesStat + if percpu { + lastTimes = lastCPUPercent.lastPerCPUTimes + lastCPUPercent.lastPerCPUTimes = cpuTimes + } else { + lastTimes = lastCPUPercent.lastCPUTimes + lastCPUPercent.lastCPUTimes = cpuTimes } - ret := make([]float64, len(cpuTimes1)) - for i, t := range cpuTimes2 { - ret[i] = calculate(cpuTimes1[i], t) + if lastTimes == nil { + return nil, fmt.Errorf("Error getting times for cpu percent. LastTimes was nil") } - return ret, nil + return calculateAllBusy(lastTimes, cpuTimes) + } diff --git a/vendor/github.com/shirou/gopsutil/disk/disk.go b/vendor/github.com/shirou/gopsutil/disk/disk.go index b187a1db0..3135c0ca1 100644 --- a/vendor/github.com/shirou/gopsutil/disk/disk.go +++ b/vendor/github.com/shirou/gopsutil/disk/disk.go @@ -2,8 +2,16 @@ package disk import ( "encoding/json" + + "github.com/shirou/gopsutil/internal/common" ) +var invoke common.Invoker + +func init() { + invoke = common.Invoke{} +} + type UsageStat struct { Path string `json:"path"` Fstype string `json:"fstype"` diff --git a/vendor/github.com/shirou/gopsutil/disk/disk_darwin_arm64.go b/vendor/github.com/shirou/gopsutil/disk/disk_darwin_arm64.go new file mode 100644 index 000000000..52bcf4c8a --- /dev/null +++ b/vendor/github.com/shirou/gopsutil/disk/disk_darwin_arm64.go @@ -0,0 +1,58 @@ +// +build darwin +// +build arm64 + +package disk + +const ( + MntWait = 1 + MfsNameLen = 15 /* length of fs type name, not inc. nul */ + MNameLen = 90 /* length of buffer for returned name */ + + MFSTYPENAMELEN = 16 /* length of fs type name including null */ + MAXPATHLEN = 1024 + MNAMELEN = MAXPATHLEN + + SYS_GETFSSTAT64 = 347 +) + +type Fsid struct{ val [2]int32 } /* file system id type */ +type uid_t int32 + +// sys/mount.h +const ( + MntReadOnly = 0x00000001 /* read only filesystem */ + MntSynchronous = 0x00000002 /* filesystem written synchronously */ + MntNoExec = 0x00000004 /* can't exec from filesystem */ + MntNoSuid = 0x00000008 /* don't honor setuid bits on fs */ + MntUnion = 0x00000020 /* union with underlying filesystem */ + MntAsync = 0x00000040 /* filesystem written asynchronously */ + MntSuidDir = 0x00100000 /* special handling of SUID on dirs */ + MntSoftDep = 0x00200000 /* soft updates being done */ + MntNoSymFollow = 0x00400000 /* do not follow symlinks */ + MntGEOMJournal = 0x02000000 /* GEOM journal support enabled */ + MntMultilabel = 0x04000000 /* MAC support for individual objects */ + MntACLs = 0x08000000 /* ACL support enabled */ + MntNoATime = 0x10000000 /* disable update of file access time */ + MntClusterRead = 0x40000000 /* disable cluster read */ + MntClusterWrite = 0x80000000 /* disable cluster write */ + MntNFS4ACLs = 0x00000010 +) + +type Statfs_t struct { + Bsize uint32 + Iosize int32 + Blocks uint64 + Bfree uint64 + Bavail uint64 + Files uint64 + Ffree uint64 + Fsid Fsid + Owner uint32 + Type uint32 + Flags uint32 + Fssubtype uint32 + Fstypename [16]int8 + Mntonname [1024]int8 + Mntfromname [1024]int8 + Reserved [8]uint32 +} diff --git a/vendor/github.com/shirou/gopsutil/disk/disk_linux.go b/vendor/github.com/shirou/gopsutil/disk/disk_linux.go index c1c334525..757becb72 100644 --- a/vendor/github.com/shirou/gopsutil/disk/disk_linux.go +++ b/vendor/github.com/shirou/gopsutil/disk/disk_linux.go @@ -283,6 +283,10 @@ func IOCounters() (map[string]IOCountersStat, error) { for _, line := range lines { fields := strings.Fields(line) + if len(fields) < 14 { + // malformed line in /proc/diskstats, avoid panic by ignoring. + continue + } name := fields[2] reads, err := strconv.ParseUint((fields[3]), 10, 64) if err != nil { @@ -332,6 +336,8 @@ func IOCounters() (map[string]IOCountersStat, error) { return ret, nil } +// GetDiskSerialNumber returns Serial Number of given device or empty string +// on error. Name of device is expected, eg. /dev/sda func GetDiskSerialNumber(name string) string { n := fmt.Sprintf("--name=%s", name) udevadm, err := exec.LookPath("/sbin/udevadm") @@ -339,7 +345,7 @@ func GetDiskSerialNumber(name string) string { return "" } - out, err := exec.Command(udevadm, "info", "--query=property", n).Output() + out, err := invoke.Command(udevadm, "info", "--query=property", n) // does not return error, just an empty string if err != nil { diff --git a/vendor/github.com/shirou/gopsutil/docker/docker.go b/vendor/github.com/shirou/gopsutil/docker/docker.go index e002f7b28..1d932cfd1 100644 --- a/vendor/github.com/shirou/gopsutil/docker/docker.go +++ b/vendor/github.com/shirou/gopsutil/docker/docker.go @@ -1,10 +1,20 @@ package docker -import "errors" +import ( + "errors" + + "github.com/shirou/gopsutil/internal/common" +) var ErrDockerNotAvailable = errors.New("docker not available") var ErrCgroupNotAvailable = errors.New("cgroup not available") +var invoke common.Invoker + +func init() { + invoke = common.Invoke{} +} + type CgroupMemStat struct { ContainerID string `json:"containerID"` Cache uint64 `json:"cache"` @@ -39,3 +49,11 @@ type CgroupMemStat struct { MemLimitInBytes uint64 `json:"memoryLimitInBbytes"` MemFailCnt uint64 `json:"memoryFailcnt"` } + +type CgroupDockerStat struct { + ContainerID string `json:"containerID"` + Name string `json:"name"` + Image string `json:"image"` + Status string `json:"status"` + Running bool `json:"running"` +} diff --git a/vendor/github.com/shirou/gopsutil/docker/docker_linux.go b/vendor/github.com/shirou/gopsutil/docker/docker_linux.go index ee74525db..000d2f2a9 100644 --- a/vendor/github.com/shirou/gopsutil/docker/docker_linux.go +++ b/vendor/github.com/shirou/gopsutil/docker/docker_linux.go @@ -15,6 +15,48 @@ import ( "github.com/shirou/gopsutil/internal/common" ) +// GetDockerStat returns a list of Docker basic stats. +// This requires certain permission. +func GetDockerStat() ([]CgroupDockerStat, error) { + path, err := exec.LookPath("docker") + if err != nil { + return nil, ErrDockerNotAvailable + } + + out, err := invoke.Command(path, "ps", "-a", "--no-trunc", "--format", "{{.ID}}|{{.Image}}|{{.Names}}|{{.Status}}") + if err != nil { + return []CgroupDockerStat{}, err + } + lines := strings.Split(string(out), "\n") + ret := make([]CgroupDockerStat, 0, len(lines)) + + for _, l := range lines { + if l == "" { + continue + } + cols := strings.Split(l, "|") + if len(cols) != 4 { + continue + } + names := strings.Split(cols[2], ",") + stat := CgroupDockerStat{ + ContainerID: cols[0], + Name: names[0], + Image: cols[1], + Status: cols[3], + Running: strings.Contains(cols[3], "Up"), + } + ret = append(ret, stat) + } + + return ret, nil +} + +func (c CgroupDockerStat) String() string { + s, _ := json.Marshal(c) + return string(s) +} + // GetDockerIDList returnes a list of DockerID. // This requires certain permission. func GetDockerIDList() ([]string, error) { @@ -23,7 +65,7 @@ func GetDockerIDList() ([]string, error) { return nil, ErrDockerNotAvailable } - out, err := exec.Command(path, "ps", "-q", "--no-trunc").Output() + out, err := invoke.Command(path, "ps", "-q", "--no-trunc") if err != nil { return []string{}, err } diff --git a/vendor/github.com/shirou/gopsutil/docker/docker_linux_test.go b/vendor/github.com/shirou/gopsutil/docker/docker_linux_test.go index c284d5a69..bd5b8c7d7 100644 --- a/vendor/github.com/shirou/gopsutil/docker/docker_linux_test.go +++ b/vendor/github.com/shirou/gopsutil/docker/docker_linux_test.go @@ -15,6 +15,30 @@ func TestGetDockerIDList(t *testing.T) { */ } +func TestGetDockerStat(t *testing.T) { + // If there is not docker environment, this test always fail. + // not tested here + + /* + ret, err := GetDockerStat() + if err != nil { + t.Errorf("error %v", err) + } + if len(ret) == 0 { + t.Errorf("ret is empty") + } + empty := CgroupDockerStat{} + for _, v := range ret { + if empty == v { + t.Errorf("empty CgroupDockerStat") + } + if v.ContainerID == "" { + t.Errorf("Could not get container id") + } + } + */ +} + func TestCgroupCPU(t *testing.T) { v, _ := GetDockerIDList() for _, id := range v { diff --git a/vendor/github.com/shirou/gopsutil/docker/docker_notlinux.go b/vendor/github.com/shirou/gopsutil/docker/docker_notlinux.go index 03a56e633..f78fb33e9 100644 --- a/vendor/github.com/shirou/gopsutil/docker/docker_notlinux.go +++ b/vendor/github.com/shirou/gopsutil/docker/docker_notlinux.go @@ -9,6 +9,12 @@ import ( "github.com/shirou/gopsutil/internal/common" ) +// GetDockerStat returns a list of Docker basic stats. +// This requires certain permission. +func GetDockerStat() ([]CgroupDockerStat, error) { + return nil, ErrDockerNotAvailable +} + // GetDockerIDList returnes a list of DockerID. // This requires certain permission. func GetDockerIDList() ([]string, error) { diff --git a/vendor/github.com/shirou/gopsutil/host/host.go b/vendor/github.com/shirou/gopsutil/host/host.go index 150eb60a7..1a6545b99 100644 --- a/vendor/github.com/shirou/gopsutil/host/host.go +++ b/vendor/github.com/shirou/gopsutil/host/host.go @@ -2,17 +2,25 @@ package host import ( "encoding/json" + + "github.com/shirou/gopsutil/internal/common" ) +var invoke common.Invoker + +func init() { + invoke = common.Invoke{} +} + // A HostInfoStat describes the host status. // This is not in the psutil but it useful. type InfoStat struct { Hostname string `json:"hostname"` Uptime uint64 `json:"uptime"` BootTime uint64 `json:"bootTime"` - Procs uint64 `json:"procs"` // number of processes - OS string `json:"os"` // ex: freebsd, linux - Platform string `json:"platform"` // ex: ubuntu, linuxmint + Procs uint64 `json:"procs"` // number of processes + OS string `json:"os"` // ex: freebsd, linux + Platform string `json:"platform"` // ex: ubuntu, linuxmint PlatformFamily string `json:"platformFamily"` // ex: debian, rhel PlatformVersion string `json:"platformVersion"` VirtualizationSystem string `json:"virtualizationSystem"` diff --git a/vendor/github.com/shirou/gopsutil/host/host_darwin.go b/vendor/github.com/shirou/gopsutil/host/host_darwin.go index f4a8c36a2..ec2dc2ce8 100644 --- a/vendor/github.com/shirou/gopsutil/host/host_darwin.go +++ b/vendor/github.com/shirou/gopsutil/host/host_darwin.go @@ -131,12 +131,12 @@ func PlatformInformation() (string, string, string, error) { if err != nil { return "", "", "", err } - out, err := exec.Command(uname, "-s").Output() + out, err := invoke.Command(uname, "-s") if err == nil { platform = strings.ToLower(strings.TrimSpace(string(out))) } - out, err = exec.Command(uname, "-r").Output() + out, err = invoke.Command(uname, "-r") if err == nil { version = strings.ToLower(strings.TrimSpace(string(out))) } diff --git a/vendor/github.com/shirou/gopsutil/host/host_freebsd.go b/vendor/github.com/shirou/gopsutil/host/host_freebsd.go index aeb1b45a5..30206d200 100644 --- a/vendor/github.com/shirou/gopsutil/host/host_freebsd.go +++ b/vendor/github.com/shirou/gopsutil/host/host_freebsd.go @@ -136,12 +136,12 @@ func PlatformInformation() (string, string, string, error) { return "", "", "", err } - out, err := exec.Command(uname, "-s").Output() + out, err := invoke.Command(uname, "-s") if err == nil { platform = strings.ToLower(strings.TrimSpace(string(out))) } - out, err = exec.Command(uname, "-r").Output() + out, err = invoke.Command(uname, "-r") if err == nil { version = strings.ToLower(strings.TrimSpace(string(out))) } diff --git a/vendor/github.com/shirou/gopsutil/host/host_linux.go b/vendor/github.com/shirou/gopsutil/host/host_linux.go index 14d09357d..b56cc98a2 100644 --- a/vendor/github.com/shirou/gopsutil/host/host_linux.go +++ b/vendor/github.com/shirou/gopsutil/host/host_linux.go @@ -15,7 +15,7 @@ import ( "strings" "time" - "github.com/shirou/gopsutil/internal/common" + common "github.com/shirou/gopsutil/internal/common" ) type LSB struct { @@ -136,6 +136,26 @@ func Users() ([]UserStat, error) { } +func getOSRelease() (platform string, version string, err error) { + contents, err := common.ReadLines(common.HostEtc("os-release")) + if err != nil { + return "", "", nil // return empty + } + for _, line := range contents { + field := strings.Split(line, "=") + if len(field) < 2 { + continue + } + switch field[0] { + case "ID": // use ID for lowercase + platform = field[1] + case "VERSION": + version = field[1] + } + } + return platform, version, nil +} + func getLSB() (*LSB, error) { ret := &LSB{} if common.PathExists(common.HostEtc("lsb-release")) { @@ -164,7 +184,7 @@ func getLSB() (*LSB, error) { if err != nil { return ret, err } - out, err := exec.Command(lsb_release).Output() + out, err := invoke.Command(lsb_release) if err != nil { return ret, err } @@ -256,6 +276,18 @@ func PlatformInformation() (platform string, family string, version string, err } else if common.PathExists(common.HostEtc("arch-release")) { platform = "arch" version = lsb.Release + } else if common.PathExists(common.HostEtc("alpine-release")) { + platform = "alpine" + contents, err := common.ReadLines(common.HostEtc("alpine-release")) + if err == nil && len(contents) > 0 { + version = contents[0] + } + } else if common.PathExists(common.HostEtc("os-release")) { + p, v, err := getOSRelease() + if err == nil { + platform = p + version = v + } } else if lsb.ID == "RedHat" { platform = "redhat" version = lsb.Release @@ -290,6 +322,10 @@ func PlatformInformation() (platform string, family string, version string, err family = "arch" case "exherbo": family = "exherbo" + case "alpine": + family = "alpine" + case "coreos": + family = "coreos" } return platform, family, version, nil @@ -351,7 +387,7 @@ func Virtualization() (string, string, error) { if common.PathExists(filename + "/capabilities") { contents, err := common.ReadLines(filename + "/capabilities") if err == nil { - if common.StringsHas(contents, "control_d") { + if common.StringsContains(contents, "control_d") { role = "host" } } @@ -379,9 +415,9 @@ func Virtualization() (string, string, error) { if common.PathExists(filename) { contents, err := common.ReadLines(filename) if err == nil { - if common.StringsHas(contents, "QEMU Virtual CPU") || - common.StringsHas(contents, "Common KVM processor") || - common.StringsHas(contents, "Common 32-bit KVM processor") { + if common.StringsContains(contents, "QEMU Virtual CPU") || + common.StringsContains(contents, "Common KVM processor") || + common.StringsContains(contents, "Common 32-bit KVM processor") { system = "kvm" role = "guest" } @@ -402,8 +438,8 @@ func Virtualization() (string, string, error) { contents, err := common.ReadLines(filename + "/self/status") if err == nil { - if common.StringsHas(contents, "s_context:") || - common.StringsHas(contents, "VxID:") { + if common.StringsContains(contents, "s_context:") || + common.StringsContains(contents, "VxID:") { system = "linux-vserver" } // TODO: guest or host @@ -413,16 +449,28 @@ func Virtualization() (string, string, error) { if common.PathExists(filename + "/self/cgroup") { contents, err := common.ReadLines(filename + "/self/cgroup") if err == nil { - if common.StringsHas(contents, "lxc") || - common.StringsHas(contents, "docker") { + if common.StringsContains(contents, "lxc") { system = "lxc" role = "guest" - } else if common.PathExists("/usr/bin/lxc-version") { // TODO: which + } else if common.StringsContains(contents, "docker") { + system = "docker" + role = "guest" + } else if common.StringsContains(contents, "machine-rkt") { + system = "rkt" + role = "guest" + } else if common.PathExists("/usr/bin/lxc-version") { system = "lxc" role = "host" } } } + if common.PathExists(common.HostEtc("os-release")) { + p, _, err := getOSRelease() + if err == nil && p == "coreos" { + system = "rkt" // Is it true? + role = "host" + } + } return system, role, nil } diff --git a/vendor/github.com/shirou/gopsutil/host/host_linux_arm64.go b/vendor/github.com/shirou/gopsutil/host/host_linux_arm64.go new file mode 100644 index 000000000..37dbe5c8c --- /dev/null +++ b/vendor/github.com/shirou/gopsutil/host/host_linux_arm64.go @@ -0,0 +1,43 @@ +// Created by cgo -godefs - DO NOT EDIT +// cgo -godefs types_linux.go + +package host + +const ( + sizeofPtr = 0x8 + sizeofShort = 0x2 + sizeofInt = 0x4 + sizeofLong = 0x8 + sizeofLongLong = 0x8 + sizeOfUtmp = 0x180 +) + +type ( + _C_short int16 + _C_int int32 + _C_long int64 + _C_long_long int64 +) + +type utmp struct { + Type int16 + Pad_cgo_0 [2]byte + Pid int32 + Line [32]int8 + Id [4]int8 + User [32]int8 + Host [256]int8 + Exit exit_status + Session int32 + Tv timeval + Addr_v6 [4]int32 + X__glibc_reserved [20]int8 +} +type exit_status struct { + Termination int16 + Exit int16 +} +type timeval struct { + Sec int64 + Usec int64 +} diff --git a/vendor/github.com/shirou/gopsutil/host/host_linux_ppc64le.go b/vendor/github.com/shirou/gopsutil/host/host_linux_ppc64le.go new file mode 100644 index 000000000..d081a0819 --- /dev/null +++ b/vendor/github.com/shirou/gopsutil/host/host_linux_ppc64le.go @@ -0,0 +1,45 @@ +// +build linux +// +build ppc64le +// Created by cgo -godefs - DO NOT EDIT +// cgo -godefs types_linux.go + +package host + +const ( + sizeofPtr = 0x8 + sizeofShort = 0x2 + sizeofInt = 0x4 + sizeofLong = 0x8 + sizeofLongLong = 0x8 + sizeOfUtmp = 0x180 +) + +type ( + _C_short int16 + _C_int int32 + _C_long int64 + _C_long_long int64 +) + +type utmp struct { + Type int16 + Pad_cgo_0 [2]byte + Pid int32 + Line [32]int8 + Id [4]int8 + User [32]int8 + Host [256]int8 + Exit exit_status + Session int32 + Tv timeval + Addr_v6 [4]int32 + X__glibc_reserved [20]int8 +} +type exit_status struct { + Termination int16 + Exit int16 +} +type timeval struct { + Sec int64 + Usec int64 +} diff --git a/vendor/github.com/shirou/gopsutil/host/host_test.go b/vendor/github.com/shirou/gopsutil/host/host_test.go index 2bf395cd9..526f0ecf6 100644 --- a/vendor/github.com/shirou/gopsutil/host/host_test.go +++ b/vendor/github.com/shirou/gopsutil/host/host_test.go @@ -16,6 +16,16 @@ func TestHostInfo(t *testing.T) { } } +func TestUptime(t *testing.T) { + v, err := Uptime() + if err != nil { + t.Errorf("error %v", err) + } + if v == 0 { + t.Errorf("Could not get up time %v", v) + } +} + func TestBoot_time(t *testing.T) { v, err := BootTime() if err != nil { @@ -24,6 +34,9 @@ func TestBoot_time(t *testing.T) { if v == 0 { t.Errorf("Could not get boot time %v", v) } + if v < 946652400 { + t.Errorf("Invalid Boottime, older than 2000-01-01") + } } func TestUsers(t *testing.T) { diff --git a/vendor/github.com/shirou/gopsutil/host/host_windows.go b/vendor/github.com/shirou/gopsutil/host/host_windows.go index 29f900c6e..18062dfe5 100644 --- a/vendor/github.com/shirou/gopsutil/host/host_windows.go +++ b/vendor/github.com/shirou/gopsutil/host/host_windows.go @@ -50,7 +50,7 @@ func Info() (*InfoStat, error) { boot, err := BootTime() if err == nil { ret.BootTime = boot - ret.Uptime = uptime(boot) + ret.Uptime, _ = Uptime() } procs, err := process.Pids() @@ -76,7 +76,7 @@ func GetOSInfo() (Win32_OperatingSystem, error) { return dst[0], nil } -func BootTime() (uint64, error) { +func Uptime() (uint64, error) { if osInfo == nil { _, err := GetOSInfo() if err != nil { @@ -88,16 +88,16 @@ func BootTime() (uint64, error) { return uint64(now.Sub(t).Seconds()), nil } -func uptime(boot uint64) uint64 { - return uint64(time.Now().Unix()) - boot +func bootTime(up uint64) uint64 { + return uint64(time.Now().Unix()) - up } -func Uptime() (uint64, error) { - boot, err := BootTime() +func BootTime() (uint64, error) { + up, err := Uptime() if err != nil { return 0, err } - return uptime(boot), nil + return bootTime(up), nil } func PlatformInformation() (platform string, family string, version string, err error) { diff --git a/vendor/github.com/shirou/gopsutil/internal/common/common.go b/vendor/github.com/shirou/gopsutil/internal/common/common.go index e190f4d13..42cbaf92a 100644 --- a/vendor/github.com/shirou/gopsutil/internal/common/common.go +++ b/vendor/github.com/shirou/gopsutil/internal/common/common.go @@ -8,8 +8,10 @@ package common // - windows (amd64) import ( "bufio" + "bytes" "errors" "io/ioutil" + "log" "net/url" "os" "os/exec" @@ -19,6 +21,12 @@ import ( "runtime" "strconv" "strings" + "time" +) + +var ( + Timeout = 3 * time.Second + TimeoutErr = errors.New("Command timed out.") ) type Invoker interface { @@ -28,7 +36,8 @@ type Invoker interface { type Invoke struct{} func (i Invoke) Command(name string, arg ...string) ([]byte, error) { - return exec.Command(name, arg...).Output() + cmd := exec.Command(name, arg...) + return CombinedOutputTimeout(cmd, Timeout) } type FakeInvoke struct { @@ -118,20 +127,20 @@ func IntToString(orig []int8) string { } func UintToString(orig []uint8) string { - ret := make([]byte, len(orig)) - size := -1 - for i, o := range orig { - if o == 0 { - size = i - break - } - ret[i] = byte(o) - } - if size == -1 { - size = len(orig) - } - - return string(ret[0:size]) + ret := make([]byte, len(orig)) + size := -1 + for i, o := range orig { + if o == 0 { + size = i + break + } + ret[i] = byte(o) + } + if size == -1 { + size = len(orig) + } + + return string(ret[0:size]) } func ByteToString(orig []byte) string { @@ -294,3 +303,41 @@ func HostSys(combineWith ...string) string { func HostEtc(combineWith ...string) string { return GetEnv("HOST_ETC", "/etc", combineWith...) } + +// CombinedOutputTimeout runs the given command with the given timeout and +// returns the combined output of stdout and stderr. +// If the command times out, it attempts to kill the process. +// copied from https://github.com/influxdata/telegraf +func CombinedOutputTimeout(c *exec.Cmd, timeout time.Duration) ([]byte, error) { + var b bytes.Buffer + c.Stdout = &b + c.Stderr = &b + if err := c.Start(); err != nil { + return nil, err + } + err := WaitTimeout(c, timeout) + return b.Bytes(), err +} + +// WaitTimeout waits for the given command to finish with a timeout. +// It assumes the command has already been started. +// If the command times out, it attempts to kill the process. +// copied from https://github.com/influxdata/telegraf +func WaitTimeout(c *exec.Cmd, timeout time.Duration) error { + timer := time.NewTimer(timeout) + done := make(chan error) + go func() { done <- c.Wait() }() + select { + case err := <-done: + timer.Stop() + return err + case <-timer.C: + if err := c.Process.Kill(); err != nil { + log.Printf("FATAL error killing process: %s", err) + return err + } + // wait for the command to return after killing it + <-done + return TimeoutErr + } +} diff --git a/vendor/github.com/shirou/gopsutil/mem/mem.go b/vendor/github.com/shirou/gopsutil/mem/mem.go index 5f122d11b..32558908a 100644 --- a/vendor/github.com/shirou/gopsutil/mem/mem.go +++ b/vendor/github.com/shirou/gopsutil/mem/mem.go @@ -2,8 +2,16 @@ package mem import ( "encoding/json" + + "github.com/shirou/gopsutil/internal/common" ) +var invoke common.Invoker + +func init() { + invoke = common.Invoke{} +} + // Memory usage statistics. Total, Available and Used contain numbers of bytes // for human consumption. // diff --git a/vendor/github.com/shirou/gopsutil/mem/mem_darwin_nocgo.go b/vendor/github.com/shirou/gopsutil/mem/mem_darwin_nocgo.go index 7094802d9..3eb33abb1 100644 --- a/vendor/github.com/shirou/gopsutil/mem/mem_darwin_nocgo.go +++ b/vendor/github.com/shirou/gopsutil/mem/mem_darwin_nocgo.go @@ -16,7 +16,7 @@ func getVMStat(vms *VirtualMemoryStat) error { if err != nil { return err } - out, err := exec.Command(vm_stat).Output() + out, err := invoke.Command(vm_stat) if err != nil { return err } diff --git a/vendor/github.com/shirou/gopsutil/mem/mem_darwin_test.go b/vendor/github.com/shirou/gopsutil/mem/mem_darwin_test.go index 6d9e6b89c..dba421ffc 100644 --- a/vendor/github.com/shirou/gopsutil/mem/mem_darwin_test.go +++ b/vendor/github.com/shirou/gopsutil/mem/mem_darwin_test.go @@ -3,7 +3,6 @@ package mem import ( - "os/exec" "strconv" "strings" "testing" @@ -15,7 +14,7 @@ func TestVirtualMemoryDarwin(t *testing.T) { v, err := VirtualMemory() assert.Nil(t, err) - outBytes, err := exec.Command("/usr/sbin/sysctl", "hw.memsize").Output() + outBytes, err := invoke.Command("/usr/sbin/sysctl", "hw.memsize") assert.Nil(t, err) outString := string(outBytes) outString = strings.TrimSpace(outString) diff --git a/vendor/github.com/shirou/gopsutil/mem/mem_freebsd.go b/vendor/github.com/shirou/gopsutil/mem/mem_freebsd.go index 719405767..8cca44b53 100644 --- a/vendor/github.com/shirou/gopsutil/mem/mem_freebsd.go +++ b/vendor/github.com/shirou/gopsutil/mem/mem_freebsd.go @@ -93,7 +93,7 @@ func SwapMemory() (*SwapMemoryStat, error) { return nil, err } - out, err := exec.Command(swapinfo).Output() + out, err := invoke.Command(swapinfo) if err != nil { return nil, err } diff --git a/vendor/github.com/shirou/gopsutil/net/net.go b/vendor/github.com/shirou/gopsutil/net/net.go index 60f1069c8..4d120dc7e 100644 --- a/vendor/github.com/shirou/gopsutil/net/net.go +++ b/vendor/github.com/shirou/gopsutil/net/net.go @@ -18,15 +18,18 @@ func init() { } type IOCountersStat struct { - Name string `json:"name"` // interface name + Name string `json:"name"` // interface name BytesSent uint64 `json:"bytesSent"` // number of bytes sent BytesRecv uint64 `json:"bytesRecv"` // number of bytes received PacketsSent uint64 `json:"packetsSent"` // number of packets sent PacketsRecv uint64 `json:"packetsRecv"` // number of packets received - Errin uint64 `json:"errin"` // total number of errors while receiving - Errout uint64 `json:"errout"` // total number of errors while sending - Dropin uint64 `json:"dropin"` // total number of incoming packets which were dropped - Dropout uint64 `json:"dropout"` // total number of outgoing packets which were dropped (always 0 on OSX and BSD) + Errin uint64 `json:"errin"` // total number of errors while receiving + Errout uint64 `json:"errout"` // total number of errors while sending + Dropin uint64 `json:"dropin"` // total number of incoming packets which were dropped + Dropout uint64 `json:"dropout"` // total number of outgoing packets which were dropped (always 0 on OSX and BSD) + Fifoin uint64 `json:"fifoin"` // total number of FIFO buffers errors while receiving + Fifoout uint64 `json:"fifoout"` // total number of FIFO buffers errors while sending + } // Addr is implemented compatibility to psutil diff --git a/vendor/github.com/shirou/gopsutil/net/net_darwin.go b/vendor/github.com/shirou/gopsutil/net/net_darwin.go index 4fa358a38..78ccb665d 100644 --- a/vendor/github.com/shirou/gopsutil/net/net_darwin.go +++ b/vendor/github.com/shirou/gopsutil/net/net_darwin.go @@ -21,7 +21,7 @@ func IOCounters(pernic bool) ([]IOCountersStat, error) { if err != nil { return nil, err } - out, err := exec.Command(netstat, "-ibdnW").Output() + out, err := invoke.Command(netstat, "-ibdnW") if err != nil { return nil, err } diff --git a/vendor/github.com/shirou/gopsutil/net/net_freebsd.go b/vendor/github.com/shirou/gopsutil/net/net_freebsd.go index 3a67b4af4..2b546550e 100644 --- a/vendor/github.com/shirou/gopsutil/net/net_freebsd.go +++ b/vendor/github.com/shirou/gopsutil/net/net_freebsd.go @@ -16,7 +16,7 @@ func IOCounters(pernic bool) ([]IOCountersStat, error) { if err != nil { return nil, err } - out, err := exec.Command(netstat, "-ibdnW").Output() + out, err := invoke.Command(netstat, "-ibdnW") if err != nil { return nil, err } diff --git a/vendor/github.com/shirou/gopsutil/net/net_linux.go b/vendor/github.com/shirou/gopsutil/net/net_linux.go index e0247714f..0803d8e78 100644 --- a/vendor/github.com/shirou/gopsutil/net/net_linux.go +++ b/vendor/github.com/shirou/gopsutil/net/net_linux.go @@ -63,6 +63,10 @@ func IOCountersByFile(pernic bool, filename string) ([]IOCountersStat, error) { if err != nil { return ret, err } + fifoIn, err := strconv.ParseUint(fields[4], 10, 64) + if err != nil { + return ret, err + } bytesSent, err := strconv.ParseUint(fields[8], 10, 64) if err != nil { return ret, err @@ -79,6 +83,10 @@ func IOCountersByFile(pernic bool, filename string) ([]IOCountersStat, error) { if err != nil { return ret, err } + fifoOut, err := strconv.ParseUint(fields[14], 10, 64) + if err != nil { + return ret, err + } nic := IOCountersStat{ Name: interfaceName, @@ -86,10 +94,12 @@ func IOCountersByFile(pernic bool, filename string) ([]IOCountersStat, error) { PacketsRecv: packetsRecv, Errin: errIn, Dropin: dropIn, + Fifoin: fifoIn, BytesSent: bytesSent, PacketsSent: packetsSent, Errout: errOut, Dropout: dropOut, + Fifoout: fifoOut, } ret = append(ret, nic) } diff --git a/vendor/github.com/shirou/gopsutil/net/net_test.go b/vendor/github.com/shirou/gopsutil/net/net_test.go index 88748bef3..9ec87adb3 100644 --- a/vendor/github.com/shirou/gopsutil/net/net_test.go +++ b/vendor/github.com/shirou/gopsutil/net/net_test.go @@ -23,7 +23,7 @@ func TestNetIOCountersStatString(t *testing.T) { Name: "test", BytesSent: 100, } - e := `{"name":"test","bytesSent":100,"bytesRecv":0,"packetsSent":0,"packetsRecv":0,"errin":0,"errout":0,"dropin":0,"dropout":0}` + e := `{"name":"test","bytesSent":100,"bytesRecv":0,"packetsSent":0,"packetsRecv":0,"errin":0,"errout":0,"dropin":0,"dropout":0,"fifoin":0,"fifoout":0}` if e != fmt.Sprintf("%v", v) { t.Errorf("NetIOCountersStat string is invalid: %v", v) } diff --git a/vendor/github.com/shirou/gopsutil/process/process_linux_arm64.go b/vendor/github.com/shirou/gopsutil/process/process_linux_arm64.go new file mode 100644 index 000000000..529aeaa9a --- /dev/null +++ b/vendor/github.com/shirou/gopsutil/process/process_linux_arm64.go @@ -0,0 +1,9 @@ +// +build linux +// +build arm64 + +package process + +const ( + ClockTicks = 100 // C.sysconf(C._SC_CLK_TCK) + PageSize = 4096 // C.sysconf(C._SC_PAGE_SIZE) +) diff --git a/vendor/github.com/shirou/gopsutil/process/process_posix.go b/vendor/github.com/shirou/gopsutil/process/process_posix.go index 8853118ac..0751f6860 100644 --- a/vendor/github.com/shirou/gopsutil/process/process_posix.go +++ b/vendor/github.com/shirou/gopsutil/process/process_posix.go @@ -9,6 +9,8 @@ import ( "strconv" "strings" "syscall" + + "github.com/shirou/gopsutil/internal/common" ) // POSIX @@ -72,7 +74,10 @@ func (p *Process) SendSignal(sig syscall.Signal) error { } cmd := exec.Command(kill, "-s", sigAsStr, strconv.Itoa(int(p.Pid))) cmd.Stderr = os.Stderr - err = cmd.Run() + if err := cmd.Start(); err != nil { + return err + } + err = common.WaitTimeout(cmd, common.Timeout) if err != nil { return err } diff --git a/vendor/github.com/shirou/gopsutil/process/process_windows.go b/vendor/github.com/shirou/gopsutil/process/process_windows.go index 3176cde05..8982a9559 100644 --- a/vendor/github.com/shirou/gopsutil/process/process_windows.go +++ b/vendor/github.com/shirou/gopsutil/process/process_windows.go @@ -23,6 +23,11 @@ const ( MaxPathLength = 260 ) +var ( + modpsapi = syscall.NewLazyDLL("psapi.dll") + procGetProcessMemoryInfo = modpsapi.NewProc("GetProcessMemoryInfo") +) + type SystemProcessInformation struct { NextEntryOffset uint64 NumberOfThreads uint64 @@ -46,13 +51,18 @@ type MemoryMapsStat struct { } type Win32_Process struct { - Name string - ExecutablePath *string - CommandLine *string - Priority uint32 - CreationDate *time.Time - ProcessID uint32 - ThreadCount uint32 + Name string + ExecutablePath *string + CommandLine *string + Priority uint32 + CreationDate *time.Time + ProcessID uint32 + ThreadCount uint32 + Status *string + ReadOperationCount uint64 + ReadTransferCount uint64 + WriteOperationCount uint64 + WriteTransferCount uint64 /* CSCreationClassName string @@ -76,14 +86,9 @@ type Win32_Process struct { PeakVirtualSize uint64 PeakWorkingSetSize uint32 PrivatePageCount uint64 - ReadOperationCount uint64 - ReadTransferCount uint64 - Status *string TerminationDate *time.Time UserModeTime uint64 WorkingSetSize uint64 - WriteOperationCount uint64 - WriteTransferCount uint64 */ } @@ -158,12 +163,12 @@ func (p *Process) CmdlineSlice() ([]string, error) { } func (p *Process) CreateTime() (int64, error) { - dst, err := GetWin32Proc(p.Pid) + ru, err := getRusage(p.Pid) if err != nil { return 0, fmt.Errorf("could not get CreationDate: %s", err) } - date := *dst[0].CreationDate - return date.Unix(), nil + + return ru.CreationTime.Nanoseconds() / 1000000, nil } func (p *Process) Cwd() (string, error) { @@ -207,8 +212,20 @@ func (p *Process) Rlimit() ([]RlimitStat, error) { return rlimit, common.ErrNotImplementedError } + func (p *Process) IOCounters() (*IOCountersStat, error) { - return nil, common.ErrNotImplementedError + dst, err := GetWin32Proc(p.Pid) + if err != nil || len(dst) == 0 { + return nil, fmt.Errorf("could not get Win32Proc: %s", err) + } + ret := &IOCountersStat{ + ReadCount: uint64(dst[0].ReadOperationCount), + ReadBytes: uint64(dst[0].ReadTransferCount), + WriteCount: uint64(dst[0].WriteOperationCount), + WriteBytes: uint64(dst[0].WriteTransferCount), + } + + return ret, nil } func (p *Process) NumCtxSwitches() (*NumCtxSwitchesStat, error) { return nil, common.ErrNotImplementedError @@ -234,7 +251,17 @@ func (p *Process) CPUAffinity() ([]int32, error) { return nil, common.ErrNotImplementedError } func (p *Process) MemoryInfo() (*MemoryInfoStat, error) { - return nil, common.ErrNotImplementedError + mem, err := getMemoryInfo(p.Pid) + if err != nil { + return nil, err + } + + ret := &MemoryInfoStat{ + RSS: uint64(mem.WorkingSetSize), + VMS: uint64(mem.PagefileUsage), + } + + return ret, nil } func (p *Process) MemoryInfoEx() (*MemoryInfoExStat, error) { return nil, common.ErrNotImplementedError @@ -355,3 +382,45 @@ func getProcInfo(pid int32) (*SystemProcessInformation, error) { return &sysProcInfo, nil } + +func getRusage(pid int32) (*syscall.Rusage, error) { + var CPU syscall.Rusage + + c, err := syscall.OpenProcess(syscall.PROCESS_QUERY_INFORMATION, false, uint32(pid)) + if err != nil { + return nil, err + } + defer syscall.CloseHandle(c) + + if err := syscall.GetProcessTimes(c, &CPU.CreationTime, &CPU.ExitTime, &CPU.KernelTime, &CPU.UserTime); err != nil { + return nil, err + } + + return &CPU, nil +} + +func getMemoryInfo(pid int32) (PROCESS_MEMORY_COUNTERS, error) { + var mem PROCESS_MEMORY_COUNTERS + c, err := syscall.OpenProcess(syscall.PROCESS_QUERY_INFORMATION, false, uint32(pid)) + if err != nil { + return mem, err + } + defer syscall.CloseHandle(c) + if err := getProcessMemoryInfo(c, &mem); err != nil { + return mem, err + } + + return mem, err +} + +func getProcessMemoryInfo(h syscall.Handle, mem *PROCESS_MEMORY_COUNTERS) (err error) { + r1, _, e1 := syscall.Syscall(procGetProcessMemoryInfo.Addr(), 3, uintptr(h), uintptr(unsafe.Pointer(mem)), uintptr(unsafe.Sizeof(*mem))) + if r1 == 0 { + if e1 != 0 { + err = error(e1) + } else { + err = syscall.EINVAL + } + } + return +} diff --git a/vendor/github.com/shirou/gopsutil/process/process_windows_386.go b/vendor/github.com/shirou/gopsutil/process/process_windows_386.go new file mode 100644 index 000000000..68f3153dc --- /dev/null +++ b/vendor/github.com/shirou/gopsutil/process/process_windows_386.go @@ -0,0 +1,16 @@ +// +build windows + +package process + +type PROCESS_MEMORY_COUNTERS struct { + CB uint32 + PageFaultCount uint32 + PeakWorkingSetSize uint32 + WorkingSetSize uint32 + QuotaPeakPagedPoolUsage uint32 + QuotaPagedPoolUsage uint32 + QuotaPeakNonPagedPoolUsage uint32 + QuotaNonPagedPoolUsage uint32 + PagefileUsage uint32 + PeakPagefileUsage uint32 +} diff --git a/vendor/github.com/shirou/gopsutil/process/process_windows_amd64.go b/vendor/github.com/shirou/gopsutil/process/process_windows_amd64.go new file mode 100644 index 000000000..df286dfff --- /dev/null +++ b/vendor/github.com/shirou/gopsutil/process/process_windows_amd64.go @@ -0,0 +1,16 @@ +// +build windows + +package process + +type PROCESS_MEMORY_COUNTERS struct { + CB uint32 + PageFaultCount uint32 + PeakWorkingSetSize uint64 + WorkingSetSize uint64 + QuotaPeakPagedPoolUsage uint64 + QuotaPagedPoolUsage uint64 + QuotaPeakNonPagedPoolUsage uint64 + QuotaNonPagedPoolUsage uint64 + PagefileUsage uint64 + PeakPagefileUsage uint64 +} diff --git a/vendor/github.com/smartystreets/goconvey/goconvey.go b/vendor/github.com/smartystreets/goconvey/goconvey.go index d68429834..2c433c4bc 100644 --- a/vendor/github.com/smartystreets/goconvey/goconvey.go +++ b/vendor/github.com/smartystreets/goconvey/goconvey.go @@ -44,6 +44,7 @@ func flags() { flag.StringVar(&watchedSuffixes, "watchedSuffixes", ".go", "A comma separated list of file suffixes to watch for modifications (default: .go).") flag.StringVar(&excludedDirs, "excludedDirs", "vendor,node_modules", "A comma separated list of directories that will be excluded from being watched") flag.StringVar(&workDir, "workDir", "", "set goconvey working directory (default current directory)") + flag.BoolVar(&autoLaunchBrowser, "launchBrowser", true, "toggle auto launching of browser (default: true)") log.SetOutput(os.Stdout) log.SetFlags(log.LstdFlags | log.Lshortfile) @@ -78,7 +79,9 @@ func main() { listener := createListener() go runTestOnUpdates(watcherOutput, executor, server) go watcher.Listen() - go launchBrowser(listener.Addr().String()) + if autoLaunchBrowser { + go launchBrowser(listener.Addr().String()) + } serveHTTP(server, listener) } @@ -267,16 +270,17 @@ func getWorkDir() string { } var ( - port int - host string - gobin string - nap time.Duration - packages int - cover bool - depth int - timeout string - watchedSuffixes string - excludedDirs string + port int + host string + gobin string + nap time.Duration + packages int + cover bool + depth int + timeout string + watchedSuffixes string + excludedDirs string + autoLaunchBrowser bool static string reports string diff --git a/vendor/github.com/smartystreets/goconvey/web/client/index.html b/vendor/github.com/smartystreets/goconvey/web/client/index.html index 7d098c58e..490e4cb51 100644 --- a/vendor/github.com/smartystreets/goconvey/web/client/index.html +++ b/vendor/github.com/smartystreets/goconvey/web/client/index.html @@ -60,7 +60,7 @@
-