├── .gitignore ├── .goxc.json ├── README.md ├── config.go ├── files.go ├── keys.go ├── main.go ├── prompt.go ├── scripts └── teardown.sh ├── templates.go ├── templates ├── Caddyfile ├── docker-compose.yml └── setup.sh └── vendor ├── github.com ├── fatih │ └── color │ │ ├── LICENSE.md │ │ ├── README.md │ │ ├── color.go │ │ └── doc.go ├── howeyc │ └── gopass │ │ ├── LICENSE.txt │ │ ├── OPENSOLARIS.LICENSE │ │ ├── README.md │ │ ├── pass.go │ │ ├── terminal.go │ │ └── terminal_solaris.go └── mattn │ ├── go-colorable │ ├── LICENSE │ ├── README.md │ ├── colorable_others.go │ ├── colorable_windows.go │ └── noncolorable.go │ └── go-isatty │ ├── LICENSE │ ├── README.md │ ├── doc.go │ ├── isatty_appengine.go │ ├── isatty_bsd.go │ ├── isatty_linux.go │ ├── isatty_solaris.go │ └── isatty_windows.go ├── golang.org └── x │ └── crypto │ ├── LICENSE │ ├── PATENTS │ └── ssh │ └── terminal │ ├── terminal.go │ ├── util.go │ ├── util_bsd.go │ ├── util_linux.go │ ├── util_plan9.go │ ├── util_solaris.go │ └── util_windows.go └── vendor.json /.gitignore: -------------------------------------------------------------------------------- 1 | .goxc.local.json 2 | -------------------------------------------------------------------------------- /.goxc.json: -------------------------------------------------------------------------------- 1 | { 2 | "Tasks": [ 3 | "default", 4 | "publish-github" 5 | ], 6 | "Arch": "amd64", 7 | "Os": "linux darwin", 8 | "PackageVersion": "0.0.10", 9 | "TaskSettings": { 10 | "publish-github": { 11 | "owner": "coralproject", 12 | "repository": "ask-install" 13 | } 14 | }, 15 | "ConfigVersion": "0.9" 16 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ask-install 2 | 3 | The `ask-install` tool can be used to bootstrap an environment to run the 4 | Coral Project's Ask product. 5 | 6 | ## Getting Started 7 | 8 | Head over to the 9 | [Latest release](https://github.com/coralproject/ask-install/releases/latest) 10 | page and download the precompiled binary there. If you would rather you can also 11 | compile from source provided you have a Go environment setup. 12 | 13 | Then just run the binary and follow the instructions provided. 14 | 15 | ## System Requirements 16 | 17 | - [Docker](https://www.docker.com/) 18 | - [Docker Compose](https://www.docker.com/products/docker-compose) 19 | 20 | ## Production Use 21 | 22 | If this is to be used in production, it is required that you enable SSL and 23 | provide a real hostname for the machine. When you run this setup you must have 24 | already pointed your DNS records to your machine running these services. 25 | 26 | This installer uses the [Caddy Webserver](https://caddyserver.com/) which will 27 | automatically setup and manage SSL for you provided that the DNS records point 28 | to the machine and the docker user can bind to ports 80/443. 29 | -------------------------------------------------------------------------------- /config.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "net" 6 | "net/http" 7 | "strings" 8 | 9 | "github.com/fatih/color" 10 | ) 11 | 12 | // Config stores the answers to the questions made from the interactive console. 13 | type Config struct { 14 | Hostname string 15 | RootURL string 16 | UseS3 bool 17 | UseSSL bool 18 | UseWordpress bool 19 | S3Bucket string 20 | S3Endpoint string 21 | AWSRegion string 22 | AWSAccessKeyID string 23 | AWSAccessKey string 24 | RecaptchaSecret string 25 | GoogleAnalyticsID string 26 | Email string `json:"-"` 27 | Password string `json:"-"` 28 | DisplayName string `json:"-"` 29 | Port string 30 | AuthPublicKey string 31 | AuthPrivateKey string 32 | SessionSecret string 33 | Channel string 34 | SlackNotificationsEnabled bool 35 | SlackHook string 36 | SlackChannel string 37 | } 38 | 39 | // GetConfigurationFromInteractive uses prompts to request the configuration 40 | // options. 41 | func GetConfigurationFromInteractive() (*Config, error) { 42 | color.Cyan("\nGeneral Configuration\n") 43 | 44 | var config Config 45 | 46 | if useStable := Confirm("Do you want to use the stable version of ask?"); useStable { 47 | config.Channel = "release" 48 | } else { 49 | config.Channel = "latest" 50 | } 51 | 52 | fmt.Println(` 53 | This is where you can specify the host on which the provided server will bind 54 | to. If you specify the host with a port, it will specifically bind to that port, 55 | otherwise, port 80, 443 will be bound to 56 | `) 57 | 58 | for { 59 | config.Hostname = StringRequired("What's the external hostname of this machine?") 60 | 61 | if strings.Contains(config.Hostname, "http") { 62 | color.Red("Hostname can't contain the scheme (http://, https://)") 63 | continue 64 | } 65 | 66 | if strings.Contains(config.Hostname, ":") { 67 | _, port, err := net.SplitHostPort(config.Hostname) 68 | if err != nil { 69 | port = "80" 70 | } 71 | 72 | config.Port = port 73 | 74 | } else { 75 | config.Port = "80" 76 | } 77 | 78 | config.UseSSL = Confirm("Do you want SSL enabled?") 79 | 80 | if config.UseSSL { 81 | config.RootURL = "https://" + config.Hostname 82 | } else { 83 | config.RootURL = "http://" + config.Hostname 84 | } 85 | 86 | if ok := Confirm("External URL will be \"%s\", is that ok?", config.RootURL); ok { 87 | break 88 | } 89 | } 90 | 91 | config.UseWordpress = Confirm("Do you want to use the Wordpress integration?") 92 | 93 | if config.SlackNotificationsEnabled = Confirm("Do you want form submissions to post to a slack channel?"); config.SlackNotificationsEnabled { 94 | for { 95 | config.SlackHook = StringRequired("What is the slack incoming hook url?") 96 | 97 | req, err := http.NewRequest("OPTIONS", config.SlackHook, nil) 98 | if err != nil { 99 | color.Red("Slack hook url is invalid: %s", err.Error()) 100 | continue 101 | } 102 | 103 | res, err := http.DefaultClient.Do(req) 104 | if err != nil { 105 | color.Red("Slack hook url is invalid: %s", err.Error()) 106 | continue 107 | } 108 | 109 | // Close the body now because we don't need it. 110 | res.Body.Close() 111 | 112 | if res.StatusCode != http.StatusOK { 113 | color.Red("Slack hook url is invalid: OPTIONS request did not return OK") 114 | continue 115 | } 116 | 117 | break 118 | } 119 | 120 | for { 121 | config.SlackChannel = StringRequired("What is the slack channel you want notifications posted? (without the #)") 122 | 123 | if strings.Contains(config.SlackChannel, "#") { 124 | color.Red("Channel should not contain a # character") 125 | continue 126 | } 127 | 128 | break 129 | } 130 | } 131 | 132 | if ok := Confirm("Do you want to enable recaptcha?"); ok { 133 | config.RecaptchaSecret = StringRequired("What is the recaptcha server secret?") 134 | } 135 | 136 | if ok := Confirm("Do you want to enable Google Analytics?"); ok { 137 | config.GoogleAnalyticsID = StringRequired("What is the Google Analytics ID?") 138 | } 139 | 140 | color.Cyan("\nAmazon\n") 141 | 142 | if config.UseS3 = Confirm("Do you want forms uploaded to S3?"); config.UseS3 { 143 | for { 144 | config.S3Bucket = StringRequired("What's the name of the S3 Bucket we can upload forms to?") 145 | config.AWSRegion = StringRequired("What's the S3 Region for this bucket?") 146 | config.AWSAccessKeyID = StringRequired("What's the AWS_ACCESS_KEY_ID with write access to this bucket?") 147 | config.AWSAccessKey = StringRequired("What's the AWS_SECRET_ACCESS_KEY associated with this AWS_ACCESS_KEY_ID?") 148 | 149 | if ok := Confirm("Is this bucket hosted in AWS?"); ok { 150 | endpoints := map[string]string{ 151 | "us-east-1": "s3.amazonaws.com", 152 | "us-east-2": "s3-us-east-2.amazonaws.com", 153 | "us-west-1": "s3-us-west-1.amazonaws.com", 154 | "us-west-2": "s3-us-west-2.amazonaws.com", 155 | "ap-south-1": "s3-ap-south-1.amazonaws.com", 156 | "ap-northeast-2": "s3-ap-northeast-2.amazonaws.com", 157 | "ap-southeast-1": "s3-ap-southeast-1.amazonaws.com", 158 | "ap-southeast-2": "s3-ap-southeast-2.amazonaws.com", 159 | "ap-northeast-1": "s3-ap-northeast-1.amazonaws.com", 160 | "eu-central-1": "s3-eu-central-1.amazonaws.com", 161 | "eu-west-1": "s3-eu-west-1.amazonaws.com", 162 | "sa-east-1": "s3-sa-east-1.amazonaws.com", 163 | } 164 | 165 | if endpoint, ok := endpoints[config.AWSRegion]; ok { 166 | config.S3Endpoint = endpoint 167 | } 168 | } 169 | 170 | if config.S3Endpoint == "" { 171 | config.S3Endpoint = StringRequired("What's the endpoint for the S3 service?") 172 | } 173 | 174 | break 175 | } 176 | } 177 | 178 | color.Cyan("\nAuth\n") 179 | 180 | config.DisplayName = StringRequired("What's the name for the user account?") 181 | config.Email = StringRequired("What's the email address for the user account?") 182 | config.Password = PasswordMasked("What's the password for the account?") 183 | 184 | privateKey, publicKey, err := GenerateKeys() 185 | if err != nil { 186 | return nil, fmt.Errorf("Couldn't create keys: %s", err.Error()) 187 | } 188 | 189 | config.AuthPrivateKey = privateKey 190 | config.AuthPublicKey = publicKey 191 | 192 | sessionSecret, _, err := GenerateKeys() 193 | if err != nil { 194 | return nil, fmt.Errorf("Couldn't create keys: %s", err.Error()) 195 | } 196 | 197 | config.SessionSecret = sessionSecret 198 | 199 | return &config, nil 200 | } 201 | -------------------------------------------------------------------------------- /files.go: -------------------------------------------------------------------------------- 1 | //go:generate go get -u github.com/jteeuwen/go-bindata/... 2 | //go:generate go-bindata -pkg $GOPACKAGE -o templates.go templates/ 3 | package main 4 | 5 | import ( 6 | "encoding/json" 7 | "os" 8 | "text/template" 9 | ) 10 | 11 | const ( 12 | askInstallerStateFilename = "ask-install.json" 13 | setupScriptFilename = "setup.sh" 14 | ) 15 | 16 | var ( 17 | dockerComposeTemplate = template.Must(template.New("docker-compose.yml").Parse(string(MustAsset("templates/docker-compose.yml")))) 18 | setupScriptTemplate = template.Must(template.New(setupScriptFilename).Parse(string(MustAsset("templates/" + setupScriptFilename)))) 19 | caddyfileTemplate = template.Must(template.New("Caddyfile").Parse(string(MustAsset("templates/Caddyfile")))) 20 | ) 21 | 22 | // CreateDockerComposeFile will template out the docker-compose.yml file. 23 | func CreateDockerComposeFile(config Config) error { 24 | f, err := os.Create("docker-compose.yml") 25 | if err != nil { 26 | return err 27 | } 28 | defer f.Close() 29 | 30 | if err := dockerComposeTemplate.Execute(f, config); err != nil { 31 | return err 32 | } 33 | 34 | return nil 35 | } 36 | 37 | // CreateSetupScript will create the setup script to start the application for 38 | // the first time. 39 | func CreateSetupScript(config Config) error { 40 | f, err := os.Create(setupScriptFilename) 41 | if err != nil { 42 | return err 43 | } 44 | defer f.Close() 45 | 46 | if err := setupScriptTemplate.Execute(f, config); err != nil { 47 | return err 48 | } 49 | 50 | return nil 51 | } 52 | 53 | // CreateCaddyFile will tempalte out the Caddyfile to be used by Caddy. 54 | func CreateCaddyFile(config Config) error { 55 | f, err := os.Create("Caddyfile") 56 | if err != nil { 57 | return err 58 | } 59 | defer f.Close() 60 | 61 | if err := caddyfileTemplate.Execute(f, config); err != nil { 62 | return err 63 | } 64 | 65 | return nil 66 | } 67 | 68 | // LoadAskInstallState loads the state of the configuration from the filesystem. 69 | func LoadAskInstallState() (*Config, error) { 70 | f, err := os.Open(askInstallerStateFilename) 71 | if err != nil { 72 | return nil, err 73 | } 74 | defer f.Close() 75 | 76 | var config Config 77 | if err := json.NewDecoder(f).Decode(&config); err != nil { 78 | return nil, err 79 | } 80 | 81 | return &config, nil 82 | } 83 | 84 | // CreateAskInstallState saves the state of the configuration to the filesystem. 85 | func CreateAskInstallState(config Config) error { 86 | f, err := os.Create(askInstallerStateFilename) 87 | if err != nil { 88 | return err 89 | } 90 | defer f.Close() 91 | 92 | e := json.NewEncoder(f) 93 | 94 | e.SetIndent("", " ") 95 | 96 | if err := e.Encode(config); err != nil { 97 | return err 98 | } 99 | 100 | return nil 101 | } 102 | -------------------------------------------------------------------------------- /keys.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bytes" 5 | "crypto/ecdsa" 6 | "crypto/elliptic" 7 | "crypto/rand" 8 | "crypto/x509" 9 | "encoding/base64" 10 | "encoding/pem" 11 | ) 12 | 13 | // DERtoPEM encodes a DER encoded key into a PEM format with the specified 14 | // header. 15 | func DERtoPEM(header string, data []byte) ([]byte, error) { 16 | 17 | // Create the PEM block. 18 | block := pem.Block{ 19 | Type: header, 20 | Bytes: data, 21 | } 22 | 23 | var buf bytes.Buffer 24 | 25 | if err := pem.Encode(&buf, &block); err != nil { 26 | return nil, err 27 | } 28 | 29 | return buf.Bytes(), nil 30 | } 31 | 32 | // GenerateKeys will output the private key and public key of a newly created 33 | // ecdsa keypair that has been encoded into PEM format + base64'd. 34 | func GenerateKeys() (string, string, error) { 35 | 36 | // Generate the elliptic curve certificate. 37 | priv, err := ecdsa.GenerateKey(elliptic.P384(), rand.Reader) 38 | if err != nil { 39 | return "", "", err 40 | } 41 | 42 | // Marshal the certificate into a ASN.1, DER format. 43 | privDER, err := x509.MarshalECPrivateKey(priv) 44 | if err != nil { 45 | return "", "", err 46 | } 47 | 48 | // Encode the DER format into PEM. 49 | privPEM, err := DERtoPEM("EC PRIVATE KEY", privDER) 50 | if err != nil { 51 | return "", "", err 52 | } 53 | 54 | // Marshal the public key into a DER-encoded PKIX format. 55 | pubDER, err := x509.MarshalPKIXPublicKey(priv.Public()) 56 | if err != nil { 57 | return "", "", err 58 | } 59 | 60 | // Encode the DER format into PEM. 61 | pubPEM, err := DERtoPEM("PUBLIC KEY", pubDER) 62 | if err != nil { 63 | return "", "", err 64 | } 65 | 66 | // Encode the PEM certificates into base64 strings. 67 | return base64.StdEncoding.EncodeToString(privPEM), base64.StdEncoding.EncodeToString(pubPEM), nil 68 | } 69 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "fmt" 6 | "os" 7 | 8 | "github.com/fatih/color" 9 | ) 10 | 11 | func main() { 12 | var useState = flag.Bool("s", false, "Use the state file in the current directory") 13 | 14 | flag.Parse() 15 | 16 | fmt.Println("Coral Project ASK Installer") 17 | 18 | var config *Config 19 | var err error 20 | 21 | if *useState { 22 | config, err = LoadAskInstallState() 23 | if err != nil { 24 | color.Red("Couldn't load state file: %s", err.Error()) 25 | os.Exit(1) 26 | } 27 | 28 | } else { 29 | config, err = GetConfigurationFromInteractive() 30 | if err != nil { 31 | color.Red(err.Error()) 32 | os.Exit(1) 33 | } 34 | } 35 | 36 | color.Cyan("\nCreating Files\n") 37 | if err := CreateFiles(*config); err != nil { 38 | color.Red("%s", err.Error()) 39 | os.Exit(1) 40 | } 41 | 42 | color.Green("\n\nFinished! Run the following to start using Ask!\n\n\tbash %s\n", setupScriptFilename) 43 | 44 | } 45 | 46 | // CreateFiles creates all the files that are templated. 47 | func CreateFiles(config Config) error { 48 | if err := CreateSetupScript(config); err != nil { 49 | return fmt.Errorf("Couldn't create %s: %s", setupScriptFilename, err.Error()) 50 | } 51 | color.Green("Created: %s", setupScriptFilename) 52 | 53 | if err := CreateCaddyFile(config); err != nil { 54 | return fmt.Errorf("Couldn't create Caddyfile: %s", err.Error()) 55 | } 56 | color.Green("Created: Caddyfile") 57 | 58 | if err := CreateDockerComposeFile(config); err != nil { 59 | return fmt.Errorf("Couldn't create docker-compose.yml: %s", err.Error()) 60 | } 61 | color.Green("Created: docker-compose.yml") 62 | 63 | if err := CreateAskInstallState(config); err != nil { 64 | return fmt.Errorf("Couldn't create %s: %s", askInstallerStateFilename, err.Error()) 65 | } 66 | color.Green("Created: %s", askInstallerStateFilename) 67 | 68 | return nil 69 | } 70 | -------------------------------------------------------------------------------- /prompt.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "fmt" 6 | "os" 7 | "strings" 8 | 9 | "github.com/howeyc/gopass" 10 | ) 11 | 12 | // String prompt. 13 | func String(prompt string, args ...interface{}) string { 14 | fmt.Printf(prompt+": ", args...) 15 | reader := bufio.NewReader(os.Stdin) 16 | bytes, _, _ := reader.ReadLine() 17 | return string(bytes) 18 | } 19 | 20 | // StringRequired prompt. 21 | func StringRequired(prompt string, args ...interface{}) string { 22 | var s string 23 | 24 | for { 25 | s = String(prompt, args...) 26 | if strings.Trim(s, " ") == "" { 27 | continue 28 | } 29 | 30 | break 31 | } 32 | 33 | return s 34 | } 35 | 36 | // Confirm continues prompting until the input is boolean-ish. 37 | func Confirm(prompt string, args ...interface{}) bool { 38 | for { 39 | s := StringRequired(prompt, args...) 40 | 41 | switch s { 42 | case "yes", "y", "Y": 43 | return true 44 | case "no", "n", "N": 45 | return false 46 | default: 47 | continue 48 | } 49 | } 50 | } 51 | 52 | // Password prompt. 53 | func Password(prompt string, args ...interface{}) string { 54 | fmt.Printf(prompt+": ", args...) 55 | password, _ := gopass.GetPasswd() 56 | s := string(password[0:]) 57 | return s 58 | } 59 | 60 | // PasswordMasked is a password prompt with a mask. 61 | func PasswordMasked(prompt string, args ...interface{}) string { 62 | fmt.Printf(prompt+": ", args...) 63 | password, _ := gopass.GetPasswdMasked() 64 | s := string(password[0:]) 65 | return s 66 | } 67 | -------------------------------------------------------------------------------- /scripts/teardown.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | docker-compose stop 4 | docker-compose rm -f 5 | docker volume rm $(docker volume ls -f dangling=true -q) 6 | -------------------------------------------------------------------------------- /templates.go: -------------------------------------------------------------------------------- 1 | // Code generated by go-bindata. 2 | // sources: 3 | // templates/Caddyfile 4 | // templates/docker-compose.yml 5 | // templates/setup.sh 6 | // DO NOT EDIT! 7 | 8 | package main 9 | 10 | import ( 11 | "bytes" 12 | "compress/gzip" 13 | "fmt" 14 | "io" 15 | "io/ioutil" 16 | "os" 17 | "path/filepath" 18 | "strings" 19 | "time" 20 | ) 21 | 22 | func bindataRead(data []byte, name string) ([]byte, error) { 23 | gz, err := gzip.NewReader(bytes.NewBuffer(data)) 24 | if err != nil { 25 | return nil, fmt.Errorf("Read %q: %v", name, err) 26 | } 27 | 28 | var buf bytes.Buffer 29 | _, err = io.Copy(&buf, gz) 30 | clErr := gz.Close() 31 | 32 | if err != nil { 33 | return nil, fmt.Errorf("Read %q: %v", name, err) 34 | } 35 | if clErr != nil { 36 | return nil, err 37 | } 38 | 39 | return buf.Bytes(), nil 40 | } 41 | 42 | type asset struct { 43 | bytes []byte 44 | info os.FileInfo 45 | } 46 | 47 | type bindataFileInfo struct { 48 | name string 49 | size int64 50 | mode os.FileMode 51 | modTime time.Time 52 | } 53 | 54 | func (fi bindataFileInfo) Name() string { 55 | return fi.name 56 | } 57 | func (fi bindataFileInfo) Size() int64 { 58 | return fi.size 59 | } 60 | func (fi bindataFileInfo) Mode() os.FileMode { 61 | return fi.mode 62 | } 63 | func (fi bindataFileInfo) ModTime() time.Time { 64 | return fi.modTime 65 | } 66 | func (fi bindataFileInfo) IsDir() bool { 67 | return false 68 | } 69 | func (fi bindataFileInfo) Sys() interface{} { 70 | return nil 71 | } 72 | 73 | var _templatesCaddyfile = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x94\x92\xcf\x6a\xe3\x30\x10\x87\xef\x7a\x8a\x1f\xf8\xba\x8e\x0f\xcd\xa9\xb7\x42\xbc\xbb\x85\x25\x81\x26\xbd\x57\x6b\x8f\x63\x11\x55\x0a\x9a\x71\xdd\x62\xfc\xee\x8b\xa5\x34\x6d\xf3\x87\xb2\x27\x33\x33\xd2\x7c\xf3\x69\x9c\x61\xb1\xc2\x72\xb5\x41\xb9\xb8\xdf\xe0\xe7\xfd\x9f\xf2\x07\xee\x1e\x37\xab\x5f\xe5\xb2\x7c\xb8\xdb\x94\x8b\x99\xca\x54\x86\x07\xea\x98\x20\x2d\x41\xf3\x2e\x37\x8e\x45\x5b\x0b\xdd\x08\x05\x50\x6d\xc4\xb8\x6d\xac\x56\xde\x35\x66\x8b\xc6\x58\x82\x76\x35\x02\xe5\xa1\x73\xa7\x17\x55\x06\xf1\xde\xa2\x37\xd2\xe2\x29\xe7\xa7\xdb\x08\xf9\xd2\x3b\x67\x95\x29\x35\x0c\x98\xfd\xf6\x2c\x4e\x3f\x13\xc6\x11\x83\x52\x80\xf5\x5b\xb0\xd4\xbe\x93\x29\x1a\x06\x98\x06\xb3\xb5\xd5\xd5\x6e\xe9\xc5\x34\xa6\xd2\x62\xbc\xe3\xd2\xe9\xbf\x96\x6a\xe4\xe3\xa8\x80\x0c\x3c\x9d\xa8\x27\x48\x8d\x7d\xf0\xaf\x6f\x0a\xe9\x8b\x62\xca\x15\x68\x45\xf6\xb7\x45\x11\xcf\x15\x18\x14\x80\x38\xa2\xef\x24\x1d\x89\x19\x09\xda\xf1\x5e\x07\x72\xa2\x80\x31\x4e\x90\x83\x2c\xd3\x91\xf4\x2d\x22\x05\xff\x49\x70\x35\xc6\x51\x45\x00\xd9\x5d\xeb\x83\x3b\x65\x1c\xd2\x47\xcc\x21\xbe\x9d\xcf\xe7\xf3\x33\xdc\xa1\x78\x91\x98\x2c\x3a\x69\xcf\x2c\x3a\x69\x3f\x2c\x62\x70\x6a\xd1\x49\x7b\xad\x67\x5a\x95\xf3\x82\xd9\x23\xd3\xfa\xe6\x63\x35\xa2\xc5\x54\xf1\xb7\x61\x05\x04\xef\x05\xc5\x8b\x0e\x45\xdf\xf7\x97\x1e\x78\x61\x38\xed\x56\x33\xd6\x37\xe8\x35\x83\xd2\xb6\x63\xf9\xac\x61\x76\xb9\xe5\xa7\x17\xad\xf4\x27\xcb\x77\xc1\x4a\xbf\xbd\xfb\x5d\x19\x7d\xba\xba\xa6\xf0\x42\x8c\xde\xd4\x5b\x12\xb4\xf2\x6c\x63\x81\x5e\x2b\xda\x0b\x8a\x94\xe7\x43\x97\x2f\x22\xdf\xaa\x24\x99\x2b\x80\xec\x3a\xe2\x28\x76\x61\x0d\xa3\xfa\x17\x00\x00\xff\xff\x70\xa5\x12\xc5\xf4\x03\x00\x00") 74 | 75 | func templatesCaddyfileBytes() ([]byte, error) { 76 | return bindataRead( 77 | _templatesCaddyfile, 78 | "templates/Caddyfile", 79 | ) 80 | } 81 | 82 | func templatesCaddyfile() (*asset, error) { 83 | bytes, err := templatesCaddyfileBytes() 84 | if err != nil { 85 | return nil, err 86 | } 87 | 88 | info := bindataFileInfo{name: "templates/Caddyfile", size: 1012, mode: os.FileMode(420), modTime: time.Unix(1493312981, 0)} 89 | a := &asset{bytes: bytes, info: info} 90 | return a, nil 91 | } 92 | 93 | var _templatesDockerComposeYml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x57\x4d\x73\xe2\x38\x13\xbe\xfb\x57\xa8\xc2\x61\x2e\x2f\x38\x33\x99\x77\x6b\xd7\x55\x1c\x1c\xa3\x01\x2f\x8e\x4d\x59\x66\x32\x73\xf2\x08\x5b\x80\x17\x47\x62\x25\x39\xd9\x54\x8a\xff\xbe\x25\xd9\x80\x30\x1f\x43\xcd\x26\xa9\xa4\x6c\xf5\xd3\xad\x56\xf7\xd3\xad\x76\x07\x0c\x22\x10\x46\x09\x80\x03\x3f\x01\x5f\xfc\x00\xfe\x0f\xb8\xd3\x24\x1a\xc2\x10\xc6\x6e\x02\x07\x3d\xab\x63\x75\x40\x4c\x2a\x41\x80\x5c\x12\x80\xc5\xaa\x5b\x50\x21\x71\x59\x02\x3c\x97\x84\x03\x92\x17\xb2\xa0\x0b\x2d\xcd\x18\x9d\x17\x0b\x30\x2f\x4a\x02\x30\xcd\x01\x27\x5d\x5e\xd1\xb6\xa2\xd5\x01\x92\xb1\x12\xbc\x14\x72\x09\x7e\x74\xc5\x0f\x47\x6f\x72\x60\xbb\x2b\xac\x8e\x65\x3d\x13\x2e\x0a\x46\x1d\xf0\xe1\xd3\x07\xcb\xea\x9c\xfd\xb1\x3a\x00\x11\xfe\x5c\x64\x44\x5c\x42\x59\xa2\x01\x39\x96\x05\x40\x86\x5f\x1d\x0b\x00\x00\x8a\x27\xbc\x20\x0e\xc8\x18\xc7\xe5\x9a\xb3\xbf\x48\x26\x6d\x25\x7c\x7b\x03\x3d\x6f\x89\x29\x25\x25\xd8\x6c\x34\x94\x13\x21\x31\x97\x0e\x60\xb4\x3b\xc7\x45\x59\x71\xe2\x7c\xbc\xd5\x22\x42\x9f\x0b\xce\xe8\x13\xa1\xb2\x36\x0b\x40\x17\xdc\x0c\x5d\x7f\xd0\x57\x86\x86\x8c\x2d\x4a\xe2\x52\x5c\xbe\xca\x22\x13\xfe\x00\x6c\x36\x37\x7b\x9c\x3b\x4d\x46\xa9\x17\xf8\x30\x4c\x52\x7f\xd0\xcf\xf0\x6b\x5b\xa8\xfe\x45\xb1\x9f\x7c\xd7\xe6\x62\xc6\xe4\x34\x0e\xc0\x66\x63\xe3\x4a\x2e\xed\x8c\x51\x4a\x32\x69\x28\xc1\x60\x3c\x8a\xe2\x30\x9d\xc6\x41\x5b\x83\x94\xab\x25\xe3\xd4\xdc\x01\x8d\x4f\x01\xb1\x58\xe5\x6d\x3f\x60\xe8\xde\x07\x70\xd0\x97\xbc\x22\x86\x2c\x89\xa7\x28\xe9\xcf\x71\x29\x9a\x55\x4a\xe4\x0b\xe3\x2b\xb1\x0f\xc6\x0c\x67\xab\xae\x58\x92\x72\xae\xc2\xff\xf6\x06\x8a\x39\xe8\xa1\x12\x67\xab\x90\xc9\x62\x5e\x64\x58\x16\x8c\x0a\x48\xf1\xac\x24\x39\xe8\xea\x98\x0b\x25\x3f\x9f\x27\x2d\xee\xce\x58\x45\x33\xc2\x9d\x12\x4b\x22\xe4\xaf\x65\x6a\x12\xc5\x49\xff\xf7\x5b\xe3\x48\x28\x70\xbd\x7d\x58\xb4\xa3\x23\xc6\x56\x87\x89\xab\x41\xde\xc8\x0d\x43\x68\x00\xf7\xbc\x39\x36\x88\x60\x1c\xba\x0f\xb0\x8f\xc5\x6a\xc6\xe4\x91\xdc\xf7\xa2\x30\x85\x0f\xd1\x9f\x7e\xdf\xf9\xbb\x22\x42\x05\xc5\x31\x23\xed\xc6\x43\x98\x68\xbf\x96\x52\xae\x1d\x5b\xa7\xc9\x36\x10\x0f\xee\x64\xe2\x87\x43\xd4\xbf\x22\x13\x6a\x21\x27\x6b\x42\x73\x91\x32\xba\x87\x28\x9b\x3a\x4b\x5d\x40\x68\xae\xf8\x6f\xe9\x0a\xcd\xcf\xe7\x42\x4b\xdf\xa3\x68\x14\x1b\x47\x11\x4a\xfa\xb7\x3d\xfd\xeb\x1c\xa4\x45\x49\x83\x68\x38\xf4\xc3\x61\x1a\xc0\xaf\x30\xe8\x7f\x6c\x49\x1f\xa2\x70\x18\xa5\xd3\xd8\xef\x3f\x31\xba\x60\xf9\xcc\xb1\x6d\x7d\xda\xae\x7e\xb7\x15\x49\x5a\x2a\x35\xab\x53\x2f\x8a\x51\x3f\x89\xa7\xb0\x25\xd6\xcc\x9f\x4c\xef\x03\xdf\x4b\xc7\xb0\x2e\x41\xb7\x92\xcb\x49\x35\x2b\x8b\x6c\x4c\x5e\x5b\xd5\x8c\xc6\x69\x0c\x3d\x77\x92\x78\x23\x37\x45\xd0\x8b\x61\x52\xd7\x16\xc9\xf0\x5a\x66\x4b\x8c\x48\xc6\x89\xdc\x69\xfd\x52\x8a\x8c\x23\xa9\xe4\x34\x55\x7d\x3e\x3f\x5b\xc0\x7b\xa5\xa8\xc5\x40\x93\xc8\x77\xe9\xfd\xd4\x1b\x37\x87\x46\x77\xf7\x55\xb6\x32\x4e\xbb\xc3\xb8\x08\xee\xeb\xeb\x0e\xd2\x7c\xcd\x0a\xda\xc2\xb9\x8f\x28\x8d\xe1\xd0\x8f\xc2\x3a\xea\x8f\x28\x26\x8b\x82\xd1\x63\x94\xeb\x79\x10\x21\x95\x9f\xb4\x69\xba\xee\x23\x72\xb3\x8c\x08\x31\x26\xaf\x47\x1d\xf7\x40\xe3\x08\x7e\x08\xde\x25\xf3\x62\x16\xeb\x3e\xa2\x58\x82\x46\x70\x70\x70\xbc\x62\x0e\x28\x93\xa0\x37\x15\x04\xdd\x81\xcd\xa6\xd5\x68\x5f\x8a\x7c\x41\xa4\xb0\xdf\xde\x9a\x6a\xab\x0d\x9e\x50\xd4\xeb\xcf\xac\xac\x9e\x88\xc1\x96\xde\x2e\xb9\x76\x25\xb8\x2d\x78\x66\xe3\xf5\xda\x56\xf7\x1d\xe1\x5b\xeb\x5b\x93\x4d\x3d\xff\xb7\xd6\xa0\xba\x41\x25\x97\x17\x6e\x50\xf5\xd2\xd5\x98\xf7\x20\x9c\x17\xc5\x6e\xd0\xd4\xe1\x51\xa7\x36\x84\xfa\x1e\x4a\x27\x71\xf4\xed\x7b\xbb\x90\x4d\x54\x34\x86\x61\x0a\xbf\x4d\xfc\xf8\x7b\x9a\xf8\x0f\xb0\x7f\xf7\x1b\x58\xf2\xd3\xe0\x6d\x3b\x09\x8c\x76\xa2\xce\x75\xba\x9b\x98\x8e\xc6\xfe\x57\x37\x81\x87\x1d\x83\x17\xcf\x58\x92\x23\x86\x99\x6a\x57\xf7\x19\x43\x09\x41\x84\xfc\x28\x34\x9b\x0d\x22\x42\x4d\x4f\xa7\x48\x6a\x28\xba\x41\x10\x3d\xc2\x41\x33\x7c\x20\x35\x7a\x80\x16\x3b\x33\x5c\x96\x8a\x17\xa7\x0d\xc4\x51\x94\x9c\x1c\x1e\x2a\xb9\x3c\xad\x31\xf0\x91\xee\xb6\x5f\x62\xf7\x01\x0e\xa7\x6e\x3c\x68\x4a\x44\xb1\xfc\x91\xf1\x7c\xcd\x89\x10\x60\xb3\x51\x09\x54\x84\x2d\x05\x01\x9b\xcd\x17\x37\x40\xb0\x55\x21\x67\x08\xac\xf6\x3e\xcf\xdf\x5d\xee\x14\x8b\x2f\xcc\x8b\x00\x74\xc0\x00\x4b\x3c\xc3\x82\x88\xcb\x50\x35\xa9\xec\xdb\xf1\x41\x55\xd4\x2b\x77\xbd\x4f\x3f\x23\xfe\x51\x55\x9b\x16\xed\x1c\x4b\x6c\xe7\xb3\xab\x66\xab\xfd\x09\xdf\xc9\x13\xc3\xe0\x35\x8e\xe8\xf0\xff\x3c\xb6\x8f\x64\xa6\xe7\x76\xc2\x7f\x1e\xdd\x0c\xe7\xf9\xe1\xbc\x8e\x67\x05\x13\x6c\xae\x66\x75\x25\xba\xed\xfd\xd1\xfb\xff\xb9\xee\xe8\x29\x88\xfa\x2c\x71\x6c\x22\xb3\xfd\x6b\x03\x51\x53\xce\xc9\x46\xdb\xea\xad\xcf\x98\xdb\x2f\x2f\x2f\x07\x0d\xb5\xdd\x52\x95\x8a\xf6\xa8\x9b\x11\x2e\x85\x63\x73\xc6\xa4\xdd\xd3\x4b\x1a\xb0\x66\x6a\x79\x5f\x18\xdb\x21\x47\x95\xcf\x84\x71\x55\xa9\xe6\xf3\xcd\xa1\x8f\xda\x3f\x14\x98\xbb\xed\x2c\x7c\xfe\x7c\xa7\xfe\x6e\x4e\xfa\x75\x2a\x55\x7a\xb6\x3c\x53\x39\xd7\x5e\x06\x26\xbe\x19\x1a\xeb\x97\x26\x6a\x46\x50\x5e\xf7\x8e\x5d\x33\xfa\x37\x45\xa0\x50\x46\x0c\xb6\xd3\xe8\x05\xba\xec\xbe\x06\x41\xd8\x1c\xfa\xe2\x57\xa1\x19\x99\x26\x26\xf5\xe3\xf6\xf0\xbb\xb7\xfa\xc6\xbb\x6e\xeb\xaf\x35\x0b\x2f\xee\x6c\x30\xd5\xa4\x4c\x7d\x0d\xfe\x23\x09\xa7\xb8\x74\x80\xfe\xa8\x3a\x51\xd5\xc7\x88\xa3\x16\xd4\x86\xfc\x1b\x00\x00\xff\xff\xe5\x56\x7b\xba\xf0\x0f\x00\x00") 94 | 95 | func templatesDockerComposeYmlBytes() ([]byte, error) { 96 | return bindataRead( 97 | _templatesDockerComposeYml, 98 | "templates/docker-compose.yml", 99 | ) 100 | } 101 | 102 | func templatesDockerComposeYml() (*asset, error) { 103 | bytes, err := templatesDockerComposeYmlBytes() 104 | if err != nil { 105 | return nil, err 106 | } 107 | 108 | info := bindataFileInfo{name: "templates/docker-compose.yml", size: 4080, mode: os.FileMode(420), modTime: time.Unix(1493312981, 0)} 109 | a := &asset{bytes: bytes, info: info} 110 | return a, nil 111 | } 112 | 113 | var _templatesSetupSh = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x64\x90\xc1\x6e\xc3\x20\x10\x44\xef\x7c\xc5\x94\x9c\x71\xee\xb9\xb6\xbd\x55\x51\xa4\xa8\x1f\x40\xf1\xa6\x46\xc5\x60\xb1\x38\x6e\x64\xf9\xdf\x2b\x70\xdc\x3a\xee\x09\xc4\xcc\x32\x6f\x76\xf7\xb4\xff\xb0\x7e\xcf\x8d\x10\x4c\x09\x8a\x84\x20\xd3\x04\xc8\x53\xef\x9c\xf5\x9f\x60\x8a\x57\x6b\x08\x4e\xdf\x28\xf2\x41\xde\x65\x29\x44\x1d\xcc\x17\x45\x65\x42\xdb\x05\x26\x74\xbd\x73\xcb\xf0\x5b\x31\x97\x27\xaa\xab\xd5\xcc\x7c\x79\x8e\xa4\x53\xfe\x3c\x35\xb4\x04\x30\x7c\x18\x0e\xbf\x16\x29\xc4\x0e\xe7\xa4\x63\x7a\x30\x55\xdb\xd4\xbe\x83\xaa\xff\x86\xe6\xf3\xbc\x7c\x69\x72\x50\x21\x18\x47\xd8\x0b\xaa\x93\x66\x1e\x42\xac\x31\x4d\x9b\x99\x63\x18\x66\x7b\xe6\xea\x99\xe2\xba\xea\x0e\x05\x99\x0a\x4b\x16\xff\x71\xc4\xde\x43\xa9\xd8\x42\xf7\xa9\x81\x71\xf6\x9e\x0d\x75\x81\x52\xd4\x6a\xeb\x20\xc7\x11\xd5\x6b\xb9\x4e\x93\x84\x52\xdd\x42\x53\x94\x15\x5b\x16\xbd\x6e\x69\x16\x5e\x2c\x77\x4e\xdf\x8e\xf9\x61\x9a\xe4\xb6\xed\x3b\x53\xc4\xa0\xd7\x6d\x1f\x0d\x27\x47\x3a\x23\x52\x1b\xae\xb9\x82\x65\x5c\xac\x23\x68\x86\x4d\x30\xc1\x27\x6d\x3d\x97\x6e\x9d\xd3\xd6\x27\xfa\x4e\x58\xd8\xe6\xdd\x91\x2f\x2b\xfb\x09\x00\x00\xff\xff\x1b\x30\xfc\xf6\x2e\x02\x00\x00") 114 | 115 | func templatesSetupShBytes() ([]byte, error) { 116 | return bindataRead( 117 | _templatesSetupSh, 118 | "templates/setup.sh", 119 | ) 120 | } 121 | 122 | func templatesSetupSh() (*asset, error) { 123 | bytes, err := templatesSetupShBytes() 124 | if err != nil { 125 | return nil, err 126 | } 127 | 128 | info := bindataFileInfo{name: "templates/setup.sh", size: 558, mode: os.FileMode(420), modTime: time.Unix(1493312981, 0)} 129 | a := &asset{bytes: bytes, info: info} 130 | return a, nil 131 | } 132 | 133 | // Asset loads and returns the asset for the given name. 134 | // It returns an error if the asset could not be found or 135 | // could not be loaded. 136 | func Asset(name string) ([]byte, error) { 137 | cannonicalName := strings.Replace(name, "\\", "/", -1) 138 | if f, ok := _bindata[cannonicalName]; ok { 139 | a, err := f() 140 | if err != nil { 141 | return nil, fmt.Errorf("Asset %s can't read by error: %v", name, err) 142 | } 143 | return a.bytes, nil 144 | } 145 | return nil, fmt.Errorf("Asset %s not found", name) 146 | } 147 | 148 | // MustAsset is like Asset but panics when Asset would return an error. 149 | // It simplifies safe initialization of global variables. 150 | func MustAsset(name string) []byte { 151 | a, err := Asset(name) 152 | if err != nil { 153 | panic("asset: Asset(" + name + "): " + err.Error()) 154 | } 155 | 156 | return a 157 | } 158 | 159 | // AssetInfo loads and returns the asset info for the given name. 160 | // It returns an error if the asset could not be found or 161 | // could not be loaded. 162 | func AssetInfo(name string) (os.FileInfo, error) { 163 | cannonicalName := strings.Replace(name, "\\", "/", -1) 164 | if f, ok := _bindata[cannonicalName]; ok { 165 | a, err := f() 166 | if err != nil { 167 | return nil, fmt.Errorf("AssetInfo %s can't read by error: %v", name, err) 168 | } 169 | return a.info, nil 170 | } 171 | return nil, fmt.Errorf("AssetInfo %s not found", name) 172 | } 173 | 174 | // AssetNames returns the names of the assets. 175 | func AssetNames() []string { 176 | names := make([]string, 0, len(_bindata)) 177 | for name := range _bindata { 178 | names = append(names, name) 179 | } 180 | return names 181 | } 182 | 183 | // _bindata is a table, holding each asset generator, mapped to its name. 184 | var _bindata = map[string]func() (*asset, error){ 185 | "templates/Caddyfile": templatesCaddyfile, 186 | "templates/docker-compose.yml": templatesDockerComposeYml, 187 | "templates/setup.sh": templatesSetupSh, 188 | } 189 | 190 | // AssetDir returns the file names below a certain 191 | // directory embedded in the file by go-bindata. 192 | // For example if you run go-bindata on data/... and data contains the 193 | // following hierarchy: 194 | // data/ 195 | // foo.txt 196 | // img/ 197 | // a.png 198 | // b.png 199 | // then AssetDir("data") would return []string{"foo.txt", "img"} 200 | // AssetDir("data/img") would return []string{"a.png", "b.png"} 201 | // AssetDir("foo.txt") and AssetDir("notexist") would return an error 202 | // AssetDir("") will return []string{"data"}. 203 | func AssetDir(name string) ([]string, error) { 204 | node := _bintree 205 | if len(name) != 0 { 206 | cannonicalName := strings.Replace(name, "\\", "/", -1) 207 | pathList := strings.Split(cannonicalName, "/") 208 | for _, p := range pathList { 209 | node = node.Children[p] 210 | if node == nil { 211 | return nil, fmt.Errorf("Asset %s not found", name) 212 | } 213 | } 214 | } 215 | if node.Func != nil { 216 | return nil, fmt.Errorf("Asset %s not found", name) 217 | } 218 | rv := make([]string, 0, len(node.Children)) 219 | for childName := range node.Children { 220 | rv = append(rv, childName) 221 | } 222 | return rv, nil 223 | } 224 | 225 | type bintree struct { 226 | Func func() (*asset, error) 227 | Children map[string]*bintree 228 | } 229 | var _bintree = &bintree{nil, map[string]*bintree{ 230 | "templates": &bintree{nil, map[string]*bintree{ 231 | "Caddyfile": &bintree{templatesCaddyfile, map[string]*bintree{}}, 232 | "docker-compose.yml": &bintree{templatesDockerComposeYml, map[string]*bintree{}}, 233 | "setup.sh": &bintree{templatesSetupSh, map[string]*bintree{}}, 234 | }}, 235 | }} 236 | 237 | // RestoreAsset restores an asset under the given directory 238 | func RestoreAsset(dir, name string) error { 239 | data, err := Asset(name) 240 | if err != nil { 241 | return err 242 | } 243 | info, err := AssetInfo(name) 244 | if err != nil { 245 | return err 246 | } 247 | err = os.MkdirAll(_filePath(dir, filepath.Dir(name)), os.FileMode(0755)) 248 | if err != nil { 249 | return err 250 | } 251 | err = ioutil.WriteFile(_filePath(dir, name), data, info.Mode()) 252 | if err != nil { 253 | return err 254 | } 255 | err = os.Chtimes(_filePath(dir, name), info.ModTime(), info.ModTime()) 256 | if err != nil { 257 | return err 258 | } 259 | return nil 260 | } 261 | 262 | // RestoreAssets restores an asset under the given directory recursively 263 | func RestoreAssets(dir, name string) error { 264 | children, err := AssetDir(name) 265 | // File 266 | if err != nil { 267 | return RestoreAsset(dir, name) 268 | } 269 | // Dir 270 | for _, child := range children { 271 | err = RestoreAssets(dir, filepath.Join(name, child)) 272 | if err != nil { 273 | return err 274 | } 275 | } 276 | return nil 277 | } 278 | 279 | func _filePath(dir, name string) string { 280 | cannonicalName := strings.Replace(name, "\\", "/", -1) 281 | return filepath.Join(append([]string{dir}, strings.Split(cannonicalName, "/")...)...) 282 | } 283 | 284 | -------------------------------------------------------------------------------- /templates/Caddyfile: -------------------------------------------------------------------------------- 1 | # DO NOT EDIT FILE, AUTOGENERATED. 2 | # 3 | # Reuse the ask-install after editing the config file and re-run the ask-install 4 | # tool with `-s`: 5 | # 6 | # ask-install -s 7 | # 8 | 9 | {{ .Hostname }} { 10 | 11 | log stdout 12 | 13 | {{ if .SlackNotificationsEnabled -}} 14 | # slackd askd proxy 15 | proxy /askd/ http://slack/ { 16 | without /askd 17 | transparent 18 | } 19 | {{- else -}} 20 | # askd proxy 21 | proxy /askd/ http://askd/ { 22 | without /askd 23 | transparent 24 | } 25 | {{- end }} 26 | 27 | # elkhorn proxy 28 | proxy /elkhorn/ http://elkhorn:4444/ { 29 | without /elkhorn 30 | transparent 31 | } 32 | 33 | # auth proxy 34 | proxy /auth/ http://auth/ { 35 | without /auth 36 | transparent 37 | } 38 | 39 | {{ if not .UseS3 -}} 40 | # static files 41 | root /var/www 42 | {{- else -}} 43 | # Disabled as S3 was enabled 44 | # # static files 45 | # root /var/www 46 | {{- end }} 47 | 48 | # cay 49 | proxy / http://cay/ { 50 | {{ if not .UseS3 -}} 51 | # Serves widget html 52 | except /widgets 53 | {{- else -}} 54 | # Disabled as S3 was enabled 55 | # # Serves widget html 56 | # except /widgets 57 | {{- end }} 58 | 59 | transparent 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /templates/docker-compose.yml: -------------------------------------------------------------------------------- 1 | # DO NOT EDIT FILE, AUTOGENERATED. 2 | # 3 | # Reuse the ask-install after editing the config file and re-run the ask-install 4 | # tool with `-s`: 5 | # 6 | # ask-install -s 7 | # 8 | 9 | version: '2' 10 | 11 | ########################## 12 | # Services 13 | ########################## 14 | 15 | services: 16 | 17 | cay: 18 | image: coralproject/cay:{{ .Channel }} 19 | restart: on-failure:10 20 | environment: 21 | - "GAID={{ .GoogleAnalyticsID }}" 22 | - "AUTH_CLIENT_ID=cay" 23 | - "AUTH_AUTHORITY={{ .RootURL }}/auth/connect" 24 | - "ELKHORN_URL={{ .RootURL }}/elkhorn" 25 | - "ASK_URL={{ .RootURL }}/askd" 26 | - "AUTH_ENABLED=true" 27 | - "TRUST=false" 28 | networks: 29 | - back-shelf 30 | 31 | {{ if .SlackNotificationsEnabled -}} 32 | slack: 33 | image: coralproject/slack-bouncer:latest 34 | restart: on-failure:10 35 | environment: 36 | - "PORT=80" 37 | - "SLACK_URL={{ .SlackHook }}" 38 | - "SLACK_CHANNEL={{ .SlackChannel }}" 39 | - "SLACK_USERNAME=askbot" 40 | - "SLACK_ICON_EMOJI=:question:" 41 | - "TARGET_URL=http://askd/" 42 | - "MAPPINGS=" 43 | networks: 44 | - back-shelf 45 | depends_on: 46 | - askd 47 | {{- end }} 48 | 49 | askd: 50 | image: coralproject/askd:{{ .Channel }} 51 | restart: on-failure:10 52 | environment: 53 | - "ASK_HOST=0.0.0.0:80" 54 | - "ASK_LOGGING_LEVEL=1" 55 | - "ASK_MONGO_URI=mongodb://shelf-mongo/test" 56 | - "ASK_ENABLE_CORS=TRUE" 57 | - "ASK_AUTH_PUBLIC_KEY={{ .AuthPublicKey }}" 58 | - "ASK_RECAPTCHA_SECRET={{ .RecaptchaSecret }}" 59 | networks: 60 | - back-shelf 61 | depends_on: 62 | - shelf-mongo 63 | 64 | elkhorn: 65 | image: coralproject/elkhorn:{{ .Channel }} 66 | restart: on-failure:10 67 | environment: 68 | - "ASK_URL=http://askd" 69 | - "S3_BUCKET={{ .S3Bucket }}" 70 | - "S3_BASE_URL={{ .S3Endpoint }}" 71 | - "AWS_REGION={{ .AWSRegion }}" 72 | - "AWS_ACCESS_KEY_ID={{ .AWSAccessKeyID }}" 73 | - "AWS_ACCESS_KEY={{ .AWSAccessKey }}" 74 | - "RECAPTCHA={{ .RecaptchaSecret }}" 75 | - "PUBLISHED_BASE_URL={{ if not .UseS3 }}{{ .RootURL }}/widgets/{{ end }}" 76 | {{ if not .UseS3 }} 77 | volumes: 78 | - ./elkhorn:/usr/src/app/server/widgets 79 | {{ end }} 80 | networks: 81 | - back-shelf 82 | depends_on: 83 | - askd 84 | 85 | auth: 86 | image: coralproject/coral-auth:{{ .Channel }} 87 | restart: on-failure:10 88 | environment: 89 | - "CORAL_AUTH_PORT=80" 90 | - "CORAL_AUTH_TRUST_PROXY=TRUE" 91 | - "CORAL_AUTH_TOKEN_EXPIRY_TIME=36 hr" 92 | - "CORAL_AUTH_MONGO_URL=mongodb://auth-mongo/test" 93 | - "CORAL_AUTH_PRIVATE_KEY={{ .AuthPrivateKey }}" 94 | - "CORAL_AUTH_PUBLIC_KEY={{ .AuthPublicKey }}" 95 | - "CORAL_AUTH_SESSION_SECRET={{ .SessionSecret }}" 96 | - "CORAL_AUTH_ALLOWED_CLIENTS=cay {{ .RootURL }}/callback" 97 | - "CORAL_AUTH_ROOT_URL={{ .RootURL }}/auth" 98 | - "CORAL_AUTH_DISABLE_FRAMEGUARD={{ if .UseWordpress }}TRUE{{ else }}FALSE{{ end }}" 99 | networks: 100 | - back-auth 101 | depends_on: 102 | - auth-mongo 103 | 104 | ########################## 105 | # Databases 106 | ########################## 107 | 108 | shelf-mongo: 109 | image: mongo:3.2 110 | restart: on-failure:10 111 | volumes: 112 | - shelf-mongo:/data/db 113 | networks: 114 | - back-shelf 115 | 116 | auth-mongo: 117 | image: mongo:3.2 118 | restart: on-failure:10 119 | volumes: 120 | - auth-mongo:/data/db 121 | networks: 122 | - back-auth 123 | 124 | ########################## 125 | # Web Servers 126 | ########################## 127 | 128 | caddy: 129 | image: abiosoft/caddy:0.9.5 130 | volumes: 131 | - ./Caddyfile:/etc/Caddyfile 132 | {{- if not .UseS3 }} 133 | - ./elkhorn:/var/www/widgets 134 | {{ end }} 135 | - caddy-certs:/root/.caddy 136 | ports: 137 | - "0.0.0.0:{{ .Port }}:{{ .Port }}" 138 | {{- if .UseSSL }} 139 | - "0.0.0.0:443:443" 140 | {{ end }} 141 | networks: 142 | - bastion 143 | - back-auth 144 | - back-shelf 145 | depends_on: 146 | - auth 147 | - askd 148 | - elkhorn 149 | - cay 150 | {{ if .SlackNotificationsEnabled -}} 151 | - slack 152 | {{- end }} 153 | 154 | ########################## 155 | # Service Networks 156 | ########################## 157 | 158 | networks: 159 | bastion: 160 | back-shelf: 161 | back-auth: 162 | 163 | ########################## 164 | # Service Volumes 165 | ########################## 166 | 167 | volumes: 168 | caddy-certs: 169 | external: false 170 | auth-mongo: 171 | external: false 172 | shelf-mongo: 173 | external: false 174 | -------------------------------------------------------------------------------- /templates/setup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | echo "Pulling service layers:" 6 | echo "" 7 | 8 | docker-compose pull 9 | 10 | echo "Layers pulled." 11 | echo "" 12 | 13 | echo "Creating the services now:" 14 | 15 | echo "" 16 | 17 | # Start the services. 18 | docker-compose up -d 19 | 20 | echo "" 21 | echo "Services created." 22 | {{ if .Password }} 23 | echo "" 24 | echo "Now creating user:" 25 | echo "" 26 | 27 | # Create the user. 28 | docker-compose run --rm auth cli create -f --email "{{ .Email }}" --password "{{ .Password }}" --name "{{ .DisplayName }}" 29 | 30 | echo "" 31 | echo "User was created." 32 | echo "" 33 | echo "Please remove this file as it contains the plaintext password." 34 | {{ end }} 35 | -------------------------------------------------------------------------------- /vendor/github.com/fatih/color/LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2013 Fatih Arslan 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /vendor/github.com/fatih/color/README.md: -------------------------------------------------------------------------------- 1 | # Color [![GoDoc](http://img.shields.io/badge/go-documentation-blue.svg?style=flat-square)](http://godoc.org/github.com/fatih/color) [![Build Status](http://img.shields.io/travis/fatih/color.svg?style=flat-square)](https://travis-ci.org/fatih/color) 2 | 3 | 4 | 5 | Color lets you use colorized outputs in terms of [ANSI Escape 6 | Codes](http://en.wikipedia.org/wiki/ANSI_escape_code#Colors) in Go (Golang). It 7 | has support for Windows too! The API can be used in several ways, pick one that 8 | suits you. 9 | 10 | 11 | 12 | ![Color](http://i.imgur.com/c1JI0lA.png) 13 | 14 | 15 | ## Install 16 | 17 | ```bash 18 | go get github.com/fatih/color 19 | ``` 20 | 21 | ## Examples 22 | 23 | ### Standard colors 24 | 25 | ```go 26 | // Print with default helper functions 27 | color.Cyan("Prints text in cyan.") 28 | 29 | // A newline will be appended automatically 30 | color.Blue("Prints %s in blue.", "text") 31 | 32 | // These are using the default foreground colors 33 | color.Red("We have red") 34 | color.Magenta("And many others ..") 35 | 36 | ``` 37 | 38 | ### Mix and reuse colors 39 | 40 | ```go 41 | // Create a new color object 42 | c := color.New(color.FgCyan).Add(color.Underline) 43 | c.Println("Prints cyan text with an underline.") 44 | 45 | // Or just add them to New() 46 | d := color.New(color.FgCyan, color.Bold) 47 | d.Printf("This prints bold cyan %s\n", "too!.") 48 | 49 | // Mix up foreground and background colors, create new mixes! 50 | red := color.New(color.FgRed) 51 | 52 | boldRed := red.Add(color.Bold) 53 | boldRed.Println("This will print text in bold red.") 54 | 55 | whiteBackground := red.Add(color.BgWhite) 56 | whiteBackground.Println("Red text with white background.") 57 | ``` 58 | 59 | ### Custom print functions (PrintFunc) 60 | 61 | ```go 62 | // Create a custom print function for convenience 63 | red := color.New(color.FgRed).PrintfFunc() 64 | red("Warning") 65 | red("Error: %s", err) 66 | 67 | // Mix up multiple attributes 68 | notice := color.New(color.Bold, color.FgGreen).PrintlnFunc() 69 | notice("Don't forget this...") 70 | ``` 71 | 72 | ### Insert into noncolor strings (SprintFunc) 73 | 74 | ```go 75 | // Create SprintXxx functions to mix strings with other non-colorized strings: 76 | yellow := color.New(color.FgYellow).SprintFunc() 77 | red := color.New(color.FgRed).SprintFunc() 78 | fmt.Printf("This is a %s and this is %s.\n", yellow("warning"), red("error")) 79 | 80 | info := color.New(color.FgWhite, color.BgGreen).SprintFunc() 81 | fmt.Printf("This %s rocks!\n", info("package")) 82 | 83 | // Use helper functions 84 | fmt.Println("This", color.RedString("warning"), "should be not neglected.") 85 | fmt.Printf("%v %v\n", color.GreenString("Info:"), "an important message.") 86 | 87 | // Windows supported too! Just don't forget to change the output to color.Output 88 | fmt.Fprintf(color.Output, "Windows support: %s", color.GreenString("PASS")) 89 | ``` 90 | 91 | ### Plug into existing code 92 | 93 | ```go 94 | // Use handy standard colors 95 | color.Set(color.FgYellow) 96 | 97 | fmt.Println("Existing text will now be in yellow") 98 | fmt.Printf("This one %s\n", "too") 99 | 100 | color.Unset() // Don't forget to unset 101 | 102 | // You can mix up parameters 103 | color.Set(color.FgMagenta, color.Bold) 104 | defer color.Unset() // Use it in your function 105 | 106 | fmt.Println("All text will now be bold magenta.") 107 | ``` 108 | 109 | ### Disable color 110 | 111 | There might be a case where you want to disable color output (for example to 112 | pipe the standard output of your app to somewhere else). `Color` has support to 113 | disable colors both globally and for single color definition. For example 114 | suppose you have a CLI app and a `--no-color` bool flag. You can easily disable 115 | the color output with: 116 | 117 | ```go 118 | 119 | var flagNoColor = flag.Bool("no-color", false, "Disable color output") 120 | 121 | if *flagNoColor { 122 | color.NoColor = true // disables colorized output 123 | } 124 | ``` 125 | 126 | It also has support for single color definitions (local). You can 127 | disable/enable color output on the fly: 128 | 129 | ```go 130 | c := color.New(color.FgCyan) 131 | c.Println("Prints cyan text") 132 | 133 | c.DisableColor() 134 | c.Println("This is printed without any color") 135 | 136 | c.EnableColor() 137 | c.Println("This prints again cyan...") 138 | ``` 139 | 140 | ## Todo 141 | 142 | * Save/Return previous values 143 | * Evaluate fmt.Formatter interface 144 | 145 | 146 | ## Credits 147 | 148 | * [Fatih Arslan](https://github.com/fatih) 149 | * Windows support via @mattn: [colorable](https://github.com/mattn/go-colorable) 150 | 151 | ## License 152 | 153 | The MIT License (MIT) - see [`LICENSE.md`](https://github.com/fatih/color/blob/master/LICENSE.md) for more details 154 | 155 | -------------------------------------------------------------------------------- /vendor/github.com/fatih/color/color.go: -------------------------------------------------------------------------------- 1 | package color 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "strconv" 7 | "strings" 8 | 9 | "github.com/mattn/go-colorable" 10 | "github.com/mattn/go-isatty" 11 | ) 12 | 13 | // NoColor defines if the output is colorized or not. It's dynamically set to 14 | // false or true based on the stdout's file descriptor referring to a terminal 15 | // or not. This is a global option and affects all colors. For more control 16 | // over each color block use the methods DisableColor() individually. 17 | var NoColor = !isatty.IsTerminal(os.Stdout.Fd()) 18 | 19 | // Color defines a custom color object which is defined by SGR parameters. 20 | type Color struct { 21 | params []Attribute 22 | noColor *bool 23 | } 24 | 25 | // Attribute defines a single SGR Code 26 | type Attribute int 27 | 28 | const escape = "\x1b" 29 | 30 | // Base attributes 31 | const ( 32 | Reset Attribute = iota 33 | Bold 34 | Faint 35 | Italic 36 | Underline 37 | BlinkSlow 38 | BlinkRapid 39 | ReverseVideo 40 | Concealed 41 | CrossedOut 42 | ) 43 | 44 | // Foreground text colors 45 | const ( 46 | FgBlack Attribute = iota + 30 47 | FgRed 48 | FgGreen 49 | FgYellow 50 | FgBlue 51 | FgMagenta 52 | FgCyan 53 | FgWhite 54 | ) 55 | 56 | // Foreground Hi-Intensity text colors 57 | const ( 58 | FgHiBlack Attribute = iota + 90 59 | FgHiRed 60 | FgHiGreen 61 | FgHiYellow 62 | FgHiBlue 63 | FgHiMagenta 64 | FgHiCyan 65 | FgHiWhite 66 | ) 67 | 68 | // Background text colors 69 | const ( 70 | BgBlack Attribute = iota + 40 71 | BgRed 72 | BgGreen 73 | BgYellow 74 | BgBlue 75 | BgMagenta 76 | BgCyan 77 | BgWhite 78 | ) 79 | 80 | // Background Hi-Intensity text colors 81 | const ( 82 | BgHiBlack Attribute = iota + 100 83 | BgHiRed 84 | BgHiGreen 85 | BgHiYellow 86 | BgHiBlue 87 | BgHiMagenta 88 | BgHiCyan 89 | BgHiWhite 90 | ) 91 | 92 | // New returns a newly created color object. 93 | func New(value ...Attribute) *Color { 94 | c := &Color{params: make([]Attribute, 0)} 95 | c.Add(value...) 96 | return c 97 | } 98 | 99 | // Set sets the given parameters immediately. It will change the color of 100 | // output with the given SGR parameters until color.Unset() is called. 101 | func Set(p ...Attribute) *Color { 102 | c := New(p...) 103 | c.Set() 104 | return c 105 | } 106 | 107 | // Unset resets all escape attributes and clears the output. Usually should 108 | // be called after Set(). 109 | func Unset() { 110 | if NoColor { 111 | return 112 | } 113 | 114 | fmt.Fprintf(Output, "%s[%dm", escape, Reset) 115 | } 116 | 117 | // Set sets the SGR sequence. 118 | func (c *Color) Set() *Color { 119 | if c.isNoColorSet() { 120 | return c 121 | } 122 | 123 | fmt.Fprintf(Output, c.format()) 124 | return c 125 | } 126 | 127 | func (c *Color) unset() { 128 | if c.isNoColorSet() { 129 | return 130 | } 131 | 132 | Unset() 133 | } 134 | 135 | // Add is used to chain SGR parameters. Use as many as parameters to combine 136 | // and create custom color objects. Example: Add(color.FgRed, color.Underline). 137 | func (c *Color) Add(value ...Attribute) *Color { 138 | c.params = append(c.params, value...) 139 | return c 140 | } 141 | 142 | func (c *Color) prepend(value Attribute) { 143 | c.params = append(c.params, 0) 144 | copy(c.params[1:], c.params[0:]) 145 | c.params[0] = value 146 | } 147 | 148 | // Output defines the standard output of the print functions. By default 149 | // os.Stdout is used. 150 | var Output = colorable.NewColorableStdout() 151 | 152 | // Print formats using the default formats for its operands and writes to 153 | // standard output. Spaces are added between operands when neither is a 154 | // string. It returns the number of bytes written and any write error 155 | // encountered. This is the standard fmt.Print() method wrapped with the given 156 | // color. 157 | func (c *Color) Print(a ...interface{}) (n int, err error) { 158 | c.Set() 159 | defer c.unset() 160 | 161 | return fmt.Fprint(Output, a...) 162 | } 163 | 164 | // Printf formats according to a format specifier and writes to standard output. 165 | // It returns the number of bytes written and any write error encountered. 166 | // This is the standard fmt.Printf() method wrapped with the given color. 167 | func (c *Color) Printf(format string, a ...interface{}) (n int, err error) { 168 | c.Set() 169 | defer c.unset() 170 | 171 | return fmt.Fprintf(Output, format, a...) 172 | } 173 | 174 | // Println formats using the default formats for its operands and writes to 175 | // standard output. Spaces are always added between operands and a newline is 176 | // appended. It returns the number of bytes written and any write error 177 | // encountered. This is the standard fmt.Print() method wrapped with the given 178 | // color. 179 | func (c *Color) Println(a ...interface{}) (n int, err error) { 180 | c.Set() 181 | defer c.unset() 182 | 183 | return fmt.Fprintln(Output, a...) 184 | } 185 | 186 | // PrintFunc returns a new function that prints the passed arguments as 187 | // colorized with color.Print(). 188 | func (c *Color) PrintFunc() func(a ...interface{}) { 189 | return func(a ...interface{}) { c.Print(a...) } 190 | } 191 | 192 | // PrintfFunc returns a new function that prints the passed arguments as 193 | // colorized with color.Printf(). 194 | func (c *Color) PrintfFunc() func(format string, a ...interface{}) { 195 | return func(format string, a ...interface{}) { c.Printf(format, a...) } 196 | } 197 | 198 | // PrintlnFunc returns a new function that prints the passed arguments as 199 | // colorized with color.Println(). 200 | func (c *Color) PrintlnFunc() func(a ...interface{}) { 201 | return func(a ...interface{}) { c.Println(a...) } 202 | } 203 | 204 | // SprintFunc returns a new function that returns colorized strings for the 205 | // given arguments with fmt.Sprint(). Useful to put into or mix into other 206 | // string. Windows users should use this in conjuction with color.Output, example: 207 | // 208 | // put := New(FgYellow).SprintFunc() 209 | // fmt.Fprintf(color.Output, "This is a %s", put("warning")) 210 | func (c *Color) SprintFunc() func(a ...interface{}) string { 211 | return func(a ...interface{}) string { 212 | return c.wrap(fmt.Sprint(a...)) 213 | } 214 | } 215 | 216 | // SprintfFunc returns a new function that returns colorized strings for the 217 | // given arguments with fmt.Sprintf(). Useful to put into or mix into other 218 | // string. Windows users should use this in conjuction with color.Output. 219 | func (c *Color) SprintfFunc() func(format string, a ...interface{}) string { 220 | return func(format string, a ...interface{}) string { 221 | return c.wrap(fmt.Sprintf(format, a...)) 222 | } 223 | } 224 | 225 | // SprintlnFunc returns a new function that returns colorized strings for the 226 | // given arguments with fmt.Sprintln(). Useful to put into or mix into other 227 | // string. Windows users should use this in conjuction with color.Output. 228 | func (c *Color) SprintlnFunc() func(a ...interface{}) string { 229 | return func(a ...interface{}) string { 230 | return c.wrap(fmt.Sprintln(a...)) 231 | } 232 | } 233 | 234 | // sequence returns a formated SGR sequence to be plugged into a "\x1b[...m" 235 | // an example output might be: "1;36" -> bold cyan 236 | func (c *Color) sequence() string { 237 | format := make([]string, len(c.params)) 238 | for i, v := range c.params { 239 | format[i] = strconv.Itoa(int(v)) 240 | } 241 | 242 | return strings.Join(format, ";") 243 | } 244 | 245 | // wrap wraps the s string with the colors attributes. The string is ready to 246 | // be printed. 247 | func (c *Color) wrap(s string) string { 248 | if c.isNoColorSet() { 249 | return s 250 | } 251 | 252 | return c.format() + s + c.unformat() 253 | } 254 | 255 | func (c *Color) format() string { 256 | return fmt.Sprintf("%s[%sm", escape, c.sequence()) 257 | } 258 | 259 | func (c *Color) unformat() string { 260 | return fmt.Sprintf("%s[%dm", escape, Reset) 261 | } 262 | 263 | // DisableColor disables the color output. Useful to not change any existing 264 | // code and still being able to output. Can be used for flags like 265 | // "--no-color". To enable back use EnableColor() method. 266 | func (c *Color) DisableColor() { 267 | c.noColor = boolPtr(true) 268 | } 269 | 270 | // EnableColor enables the color output. Use it in conjuction with 271 | // DisableColor(). Otherwise this method has no side effects. 272 | func (c *Color) EnableColor() { 273 | c.noColor = boolPtr(false) 274 | } 275 | 276 | func (c *Color) isNoColorSet() bool { 277 | // check first if we have user setted action 278 | if c.noColor != nil { 279 | return *c.noColor 280 | } 281 | 282 | // if not return the global option, which is disabled by default 283 | return NoColor 284 | } 285 | 286 | // Equals returns a boolean value indicating whether two colors are equal. 287 | func (c *Color) Equals(c2 *Color) bool { 288 | if len(c.params) != len(c2.params) { 289 | return false 290 | } 291 | 292 | for _, attr := range c.params { 293 | if !c2.attrExists(attr) { 294 | return false 295 | } 296 | } 297 | 298 | return true 299 | } 300 | 301 | func (c *Color) attrExists(a Attribute) bool { 302 | for _, attr := range c.params { 303 | if attr == a { 304 | return true 305 | } 306 | } 307 | 308 | return false 309 | } 310 | 311 | func boolPtr(v bool) *bool { 312 | return &v 313 | } 314 | 315 | // Black is an convenient helper function to print with black foreground. A 316 | // newline is appended to format by default. 317 | func Black(format string, a ...interface{}) { printColor(format, FgBlack, a...) } 318 | 319 | // Red is an convenient helper function to print with red foreground. A 320 | // newline is appended to format by default. 321 | func Red(format string, a ...interface{}) { printColor(format, FgRed, a...) } 322 | 323 | // Green is an convenient helper function to print with green foreground. A 324 | // newline is appended to format by default. 325 | func Green(format string, a ...interface{}) { printColor(format, FgGreen, a...) } 326 | 327 | // Yellow is an convenient helper function to print with yellow foreground. 328 | // A newline is appended to format by default. 329 | func Yellow(format string, a ...interface{}) { printColor(format, FgYellow, a...) } 330 | 331 | // Blue is an convenient helper function to print with blue foreground. A 332 | // newline is appended to format by default. 333 | func Blue(format string, a ...interface{}) { printColor(format, FgBlue, a...) } 334 | 335 | // Magenta is an convenient helper function to print with magenta foreground. 336 | // A newline is appended to format by default. 337 | func Magenta(format string, a ...interface{}) { printColor(format, FgMagenta, a...) } 338 | 339 | // Cyan is an convenient helper function to print with cyan foreground. A 340 | // newline is appended to format by default. 341 | func Cyan(format string, a ...interface{}) { printColor(format, FgCyan, a...) } 342 | 343 | // White is an convenient helper function to print with white foreground. A 344 | // newline is appended to format by default. 345 | func White(format string, a ...interface{}) { printColor(format, FgWhite, a...) } 346 | 347 | func printColor(format string, p Attribute, a ...interface{}) { 348 | if len(a) == 0 { 349 | a = append(a, format) 350 | format = "%s" 351 | } 352 | 353 | if !strings.HasSuffix(format, "\n") { 354 | format += "\n" 355 | } 356 | 357 | c := &Color{params: []Attribute{p}} 358 | c.Printf(format, a...) 359 | } 360 | 361 | func printString(format string, p Attribute, a ...interface{}) string { 362 | if len(a) == 0 { 363 | a = append(a, format) 364 | format = "%s" 365 | } 366 | return New(p).SprintfFunc()(format, a...) 367 | } 368 | 369 | // BlackString is an convenient helper function to return a string with black 370 | // foreground. 371 | func BlackString(format string, a ...interface{}) string { return printString(format, FgBlack, a...) } 372 | 373 | // RedString is an convenient helper function to return a string with red 374 | // foreground. 375 | func RedString(format string, a ...interface{}) string { return printString(format, FgRed, a...) } 376 | 377 | // GreenString is an convenient helper function to return a string with green 378 | // foreground. 379 | func GreenString(format string, a ...interface{}) string { return printString(format, FgGreen, a...) } 380 | 381 | // YellowString is an convenient helper function to return a string with yellow 382 | // foreground. 383 | func YellowString(format string, a ...interface{}) string { return printString(format, FgYellow, a...) } 384 | 385 | // BlueString is an convenient helper function to return a string with blue 386 | // foreground. 387 | func BlueString(format string, a ...interface{}) string { return printString(format, FgBlue, a...) } 388 | 389 | // MagentaString is an convenient helper function to return a string with magenta 390 | // foreground. 391 | func MagentaString(format string, a ...interface{}) string { 392 | return printString(format, FgMagenta, a...) 393 | } 394 | 395 | // CyanString is an convenient helper function to return a string with cyan 396 | // foreground. 397 | func CyanString(format string, a ...interface{}) string { return printString(format, FgCyan, a...) } 398 | 399 | // WhiteString is an convenient helper function to return a string with white 400 | // foreground. 401 | func WhiteString(format string, a ...interface{}) string { return printString(format, FgWhite, a...) } 402 | -------------------------------------------------------------------------------- /vendor/github.com/fatih/color/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Package color is an ANSI color package to output colorized or SGR defined 3 | output to the standard output. The API can be used in several way, pick one 4 | that suits you. 5 | 6 | Use simple and default helper functions with predefined foreground colors: 7 | 8 | color.Cyan("Prints text in cyan.") 9 | 10 | // a newline will be appended automatically 11 | color.Blue("Prints %s in blue.", "text") 12 | 13 | // More default foreground colors.. 14 | color.Red("We have red") 15 | color.Yellow("Yellow color too!") 16 | color.Magenta("And many others ..") 17 | 18 | However there are times where custom color mixes are required. Below are some 19 | examples to create custom color objects and use the print functions of each 20 | separate color object. 21 | 22 | // Create a new color object 23 | c := color.New(color.FgCyan).Add(color.Underline) 24 | c.Println("Prints cyan text with an underline.") 25 | 26 | // Or just add them to New() 27 | d := color.New(color.FgCyan, color.Bold) 28 | d.Printf("This prints bold cyan %s\n", "too!.") 29 | 30 | 31 | // Mix up foreground and background colors, create new mixes! 32 | red := color.New(color.FgRed) 33 | 34 | boldRed := red.Add(color.Bold) 35 | boldRed.Println("This will print text in bold red.") 36 | 37 | whiteBackground := red.Add(color.BgWhite) 38 | whiteBackground.Println("Red text with White background.") 39 | 40 | 41 | You can create PrintXxx functions to simplify even more: 42 | 43 | // Create a custom print function for convenient 44 | red := color.New(color.FgRed).PrintfFunc() 45 | red("warning") 46 | red("error: %s", err) 47 | 48 | // Mix up multiple attributes 49 | notice := color.New(color.Bold, color.FgGreen).PrintlnFunc() 50 | notice("don't forget this...") 51 | 52 | 53 | Or create SprintXxx functions to mix strings with other non-colorized strings: 54 | 55 | yellow := New(FgYellow).SprintFunc() 56 | red := New(FgRed).SprintFunc() 57 | 58 | fmt.Printf("this is a %s and this is %s.\n", yellow("warning"), red("error")) 59 | 60 | info := New(FgWhite, BgGreen).SprintFunc() 61 | fmt.Printf("this %s rocks!\n", info("package")) 62 | 63 | Windows support is enabled by default. All Print functions works as intended. 64 | However only for color.SprintXXX functions, user should use fmt.FprintXXX and 65 | set the output to color.Output: 66 | 67 | fmt.Fprintf(color.Output, "Windows support: %s", color.GreenString("PASS")) 68 | 69 | info := New(FgWhite, BgGreen).SprintFunc() 70 | fmt.Fprintf(color.Output, "this %s rocks!\n", info("package")) 71 | 72 | Using with existing code is possible. Just use the Set() method to set the 73 | standard output to the given parameters. That way a rewrite of an existing 74 | code is not required. 75 | 76 | // Use handy standard colors. 77 | color.Set(color.FgYellow) 78 | 79 | fmt.Println("Existing text will be now in Yellow") 80 | fmt.Printf("This one %s\n", "too") 81 | 82 | color.Unset() // don't forget to unset 83 | 84 | // You can mix up parameters 85 | color.Set(color.FgMagenta, color.Bold) 86 | defer color.Unset() // use it in your function 87 | 88 | fmt.Println("All text will be now bold magenta.") 89 | 90 | There might be a case where you want to disable color output (for example to 91 | pipe the standard output of your app to somewhere else). `Color` has support to 92 | disable colors both globally and for single color definition. For example 93 | suppose you have a CLI app and a `--no-color` bool flag. You can easily disable 94 | the color output with: 95 | 96 | var flagNoColor = flag.Bool("no-color", false, "Disable color output") 97 | 98 | if *flagNoColor { 99 | color.NoColor = true // disables colorized output 100 | } 101 | 102 | It also has support for single color definitions (local). You can 103 | disable/enable color output on the fly: 104 | 105 | c := color.New(color.FgCyan) 106 | c.Println("Prints cyan text") 107 | 108 | c.DisableColor() 109 | c.Println("This is printed without any color") 110 | 111 | c.EnableColor() 112 | c.Println("This prints again cyan...") 113 | */ 114 | package color 115 | -------------------------------------------------------------------------------- /vendor/github.com/howeyc/gopass/LICENSE.txt: -------------------------------------------------------------------------------- 1 | ISC License 2 | 3 | Copyright (c) 2012 Chris Howey 4 | 5 | Permission to use, copy, modify, and distribute this software for any 6 | purpose with or without fee is hereby granted, provided that the above 7 | copyright notice and this permission notice appear in all copies. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 | -------------------------------------------------------------------------------- /vendor/github.com/howeyc/gopass/OPENSOLARIS.LICENSE: -------------------------------------------------------------------------------- 1 | Unless otherwise noted, all files in this distribution are released 2 | under the Common Development and Distribution License (CDDL). 3 | Exceptions are noted within the associated source files. 4 | 5 | -------------------------------------------------------------------- 6 | 7 | 8 | COMMON DEVELOPMENT AND DISTRIBUTION LICENSE Version 1.0 9 | 10 | 1. Definitions. 11 | 12 | 1.1. "Contributor" means each individual or entity that creates 13 | or contributes to the creation of Modifications. 14 | 15 | 1.2. "Contributor Version" means the combination of the Original 16 | Software, prior Modifications used by a Contributor (if any), 17 | and the Modifications made by that particular Contributor. 18 | 19 | 1.3. "Covered Software" means (a) the Original Software, or (b) 20 | Modifications, or (c) the combination of files containing 21 | Original Software with files containing Modifications, in 22 | each case including portions thereof. 23 | 24 | 1.4. "Executable" means the Covered Software in any form other 25 | than Source Code. 26 | 27 | 1.5. "Initial Developer" means the individual or entity that first 28 | makes Original Software available under this License. 29 | 30 | 1.6. "Larger Work" means a work which combines Covered Software or 31 | portions thereof with code not governed by the terms of this 32 | License. 33 | 34 | 1.7. "License" means this document. 35 | 36 | 1.8. "Licensable" means having the right to grant, to the maximum 37 | extent possible, whether at the time of the initial grant or 38 | subsequently acquired, any and all of the rights conveyed 39 | herein. 40 | 41 | 1.9. "Modifications" means the Source Code and Executable form of 42 | any of the following: 43 | 44 | A. Any file that results from an addition to, deletion from or 45 | modification of the contents of a file containing Original 46 | Software or previous Modifications; 47 | 48 | B. Any new file that contains any part of the Original 49 | Software or previous Modifications; or 50 | 51 | C. Any new file that is contributed or otherwise made 52 | available under the terms of this License. 53 | 54 | 1.10. "Original Software" means the Source Code and Executable 55 | form of computer software code that is originally released 56 | under this License. 57 | 58 | 1.11. "Patent Claims" means any patent claim(s), now owned or 59 | hereafter acquired, including without limitation, method, 60 | process, and apparatus claims, in any patent Licensable by 61 | grantor. 62 | 63 | 1.12. "Source Code" means (a) the common form of computer software 64 | code in which modifications are made and (b) associated 65 | documentation included in or with such code. 66 | 67 | 1.13. "You" (or "Your") means an individual or a legal entity 68 | exercising rights under, and complying with all of the terms 69 | of, this License. For legal entities, "You" includes any 70 | entity which controls, is controlled by, or is under common 71 | control with You. For purposes of this definition, 72 | "control" means (a) the power, direct or indirect, to cause 73 | the direction or management of such entity, whether by 74 | contract or otherwise, or (b) ownership of more than fifty 75 | percent (50%) of the outstanding shares or beneficial 76 | ownership of such entity. 77 | 78 | 2. License Grants. 79 | 80 | 2.1. The Initial Developer Grant. 81 | 82 | Conditioned upon Your compliance with Section 3.1 below and 83 | subject to third party intellectual property claims, the Initial 84 | Developer hereby grants You a world-wide, royalty-free, 85 | non-exclusive license: 86 | 87 | (a) under intellectual property rights (other than patent or 88 | trademark) Licensable by Initial Developer, to use, 89 | reproduce, modify, display, perform, sublicense and 90 | distribute the Original Software (or portions thereof), 91 | with or without Modifications, and/or as part of a Larger 92 | Work; and 93 | 94 | (b) under Patent Claims infringed by the making, using or 95 | selling of Original Software, to make, have made, use, 96 | practice, sell, and offer for sale, and/or otherwise 97 | dispose of the Original Software (or portions thereof). 98 | 99 | (c) The licenses granted in Sections 2.1(a) and (b) are 100 | effective on the date Initial Developer first distributes 101 | or otherwise makes the Original Software available to a 102 | third party under the terms of this License. 103 | 104 | (d) Notwithstanding Section 2.1(b) above, no patent license is 105 | granted: (1) for code that You delete from the Original 106 | Software, or (2) for infringements caused by: (i) the 107 | modification of the Original Software, or (ii) the 108 | combination of the Original Software with other software 109 | or devices. 110 | 111 | 2.2. Contributor Grant. 112 | 113 | Conditioned upon Your compliance with Section 3.1 below and 114 | subject to third party intellectual property claims, each 115 | Contributor hereby grants You a world-wide, royalty-free, 116 | non-exclusive license: 117 | 118 | (a) under intellectual property rights (other than patent or 119 | trademark) Licensable by Contributor to use, reproduce, 120 | modify, display, perform, sublicense and distribute the 121 | Modifications created by such Contributor (or portions 122 | thereof), either on an unmodified basis, with other 123 | Modifications, as Covered Software and/or as part of a 124 | Larger Work; and 125 | 126 | (b) under Patent Claims infringed by the making, using, or 127 | selling of Modifications made by that Contributor either 128 | alone and/or in combination with its Contributor Version 129 | (or portions of such combination), to make, use, sell, 130 | offer for sale, have made, and/or otherwise dispose of: 131 | (1) Modifications made by that Contributor (or portions 132 | thereof); and (2) the combination of Modifications made by 133 | that Contributor with its Contributor Version (or portions 134 | of such combination). 135 | 136 | (c) The licenses granted in Sections 2.2(a) and 2.2(b) are 137 | effective on the date Contributor first distributes or 138 | otherwise makes the Modifications available to a third 139 | party. 140 | 141 | (d) Notwithstanding Section 2.2(b) above, no patent license is 142 | granted: (1) for any code that Contributor has deleted 143 | from the Contributor Version; (2) for infringements caused 144 | by: (i) third party modifications of Contributor Version, 145 | or (ii) the combination of Modifications made by that 146 | Contributor with other software (except as part of the 147 | Contributor Version) or other devices; or (3) under Patent 148 | Claims infringed by Covered Software in the absence of 149 | Modifications made by that Contributor. 150 | 151 | 3. Distribution Obligations. 152 | 153 | 3.1. Availability of Source Code. 154 | 155 | Any Covered Software that You distribute or otherwise make 156 | available in Executable form must also be made available in Source 157 | Code form and that Source Code form must be distributed only under 158 | the terms of this License. You must include a copy of this 159 | License with every copy of the Source Code form of the Covered 160 | Software You distribute or otherwise make available. You must 161 | inform recipients of any such Covered Software in Executable form 162 | as to how they can obtain such Covered Software in Source Code 163 | form in a reasonable manner on or through a medium customarily 164 | used for software exchange. 165 | 166 | 3.2. Modifications. 167 | 168 | The Modifications that You create or to which You contribute are 169 | governed by the terms of this License. You represent that You 170 | believe Your Modifications are Your original creation(s) and/or 171 | You have sufficient rights to grant the rights conveyed by this 172 | License. 173 | 174 | 3.3. Required Notices. 175 | 176 | You must include a notice in each of Your Modifications that 177 | identifies You as the Contributor of the Modification. You may 178 | not remove or alter any copyright, patent or trademark notices 179 | contained within the Covered Software, or any notices of licensing 180 | or any descriptive text giving attribution to any Contributor or 181 | the Initial Developer. 182 | 183 | 3.4. Application of Additional Terms. 184 | 185 | You may not offer or impose any terms on any Covered Software in 186 | Source Code form that alters or restricts the applicable version 187 | of this License or the recipients' rights hereunder. You may 188 | choose to offer, and to charge a fee for, warranty, support, 189 | indemnity or liability obligations to one or more recipients of 190 | Covered Software. However, you may do so only on Your own behalf, 191 | and not on behalf of the Initial Developer or any Contributor. 192 | You must make it absolutely clear that any such warranty, support, 193 | indemnity or liability obligation is offered by You alone, and You 194 | hereby agree to indemnify the Initial Developer and every 195 | Contributor for any liability incurred by the Initial Developer or 196 | such Contributor as a result of warranty, support, indemnity or 197 | liability terms You offer. 198 | 199 | 3.5. Distribution of Executable Versions. 200 | 201 | You may distribute the Executable form of the Covered Software 202 | under the terms of this License or under the terms of a license of 203 | Your choice, which may contain terms different from this License, 204 | provided that You are in compliance with the terms of this License 205 | and that the license for the Executable form does not attempt to 206 | limit or alter the recipient's rights in the Source Code form from 207 | the rights set forth in this License. If You distribute the 208 | Covered Software in Executable form under a different license, You 209 | must make it absolutely clear that any terms which differ from 210 | this License are offered by You alone, not by the Initial 211 | Developer or Contributor. You hereby agree to indemnify the 212 | Initial Developer and every Contributor for any liability incurred 213 | by the Initial Developer or such Contributor as a result of any 214 | such terms You offer. 215 | 216 | 3.6. Larger Works. 217 | 218 | You may create a Larger Work by combining Covered Software with 219 | other code not governed by the terms of this License and 220 | distribute the Larger Work as a single product. In such a case, 221 | You must make sure the requirements of this License are fulfilled 222 | for the Covered Software. 223 | 224 | 4. Versions of the License. 225 | 226 | 4.1. New Versions. 227 | 228 | Sun Microsystems, Inc. is the initial license steward and may 229 | publish revised and/or new versions of this License from time to 230 | time. Each version will be given a distinguishing version number. 231 | Except as provided in Section 4.3, no one other than the license 232 | steward has the right to modify this License. 233 | 234 | 4.2. Effect of New Versions. 235 | 236 | You may always continue to use, distribute or otherwise make the 237 | Covered Software available under the terms of the version of the 238 | License under which You originally received the Covered Software. 239 | If the Initial Developer includes a notice in the Original 240 | Software prohibiting it from being distributed or otherwise made 241 | available under any subsequent version of the License, You must 242 | distribute and make the Covered Software available under the terms 243 | of the version of the License under which You originally received 244 | the Covered Software. Otherwise, You may also choose to use, 245 | distribute or otherwise make the Covered Software available under 246 | the terms of any subsequent version of the License published by 247 | the license steward. 248 | 249 | 4.3. Modified Versions. 250 | 251 | When You are an Initial Developer and You want to create a new 252 | license for Your Original Software, You may create and use a 253 | modified version of this License if You: (a) rename the license 254 | and remove any references to the name of the license steward 255 | (except to note that the license differs from this License); and 256 | (b) otherwise make it clear that the license contains terms which 257 | differ from this License. 258 | 259 | 5. DISCLAIMER OF WARRANTY. 260 | 261 | COVERED SOFTWARE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" 262 | BASIS, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, 263 | INCLUDING, WITHOUT LIMITATION, WARRANTIES THAT THE COVERED 264 | SOFTWARE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR 265 | PURPOSE OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND 266 | PERFORMANCE OF THE COVERED SOFTWARE IS WITH YOU. SHOULD ANY 267 | COVERED SOFTWARE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT THE 268 | INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY 269 | NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF 270 | WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF 271 | ANY COVERED SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS 272 | DISCLAIMER. 273 | 274 | 6. TERMINATION. 275 | 276 | 6.1. This License and the rights granted hereunder will terminate 277 | automatically if You fail to comply with terms herein and fail to 278 | cure such breach within 30 days of becoming aware of the breach. 279 | Provisions which, by their nature, must remain in effect beyond 280 | the termination of this License shall survive. 281 | 282 | 6.2. If You assert a patent infringement claim (excluding 283 | declaratory judgment actions) against Initial Developer or a 284 | Contributor (the Initial Developer or Contributor against whom You 285 | assert such claim is referred to as "Participant") alleging that 286 | the Participant Software (meaning the Contributor Version where 287 | the Participant is a Contributor or the Original Software where 288 | the Participant is the Initial Developer) directly or indirectly 289 | infringes any patent, then any and all rights granted directly or 290 | indirectly to You by such Participant, the Initial Developer (if 291 | the Initial Developer is not the Participant) and all Contributors 292 | under Sections 2.1 and/or 2.2 of this License shall, upon 60 days 293 | notice from Participant terminate prospectively and automatically 294 | at the expiration of such 60 day notice period, unless if within 295 | such 60 day period You withdraw Your claim with respect to the 296 | Participant Software against such Participant either unilaterally 297 | or pursuant to a written agreement with Participant. 298 | 299 | 6.3. In the event of termination under Sections 6.1 or 6.2 above, 300 | all end user licenses that have been validly granted by You or any 301 | distributor hereunder prior to termination (excluding licenses 302 | granted to You by any distributor) shall survive termination. 303 | 304 | 7. LIMITATION OF LIABILITY. 305 | 306 | UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT 307 | (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE 308 | INITIAL DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF 309 | COVERED SOFTWARE, OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE 310 | LIABLE TO ANY PERSON FOR ANY INDIRECT, SPECIAL, INCIDENTAL, OR 311 | CONSEQUENTIAL DAMAGES OF ANY CHARACTER INCLUDING, WITHOUT 312 | LIMITATION, DAMAGES FOR LOST PROFITS, LOSS OF GOODWILL, WORK 313 | STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER 314 | COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN 315 | INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF 316 | LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL 317 | INJURY RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT 318 | APPLICABLE LAW PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO 319 | NOT ALLOW THE EXCLUSION OR LIMITATION OF INCIDENTAL OR 320 | CONSEQUENTIAL DAMAGES, SO THIS EXCLUSION AND LIMITATION MAY NOT 321 | APPLY TO YOU. 322 | 323 | 8. U.S. GOVERNMENT END USERS. 324 | 325 | The Covered Software is a "commercial item," as that term is 326 | defined in 48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial 327 | computer software" (as that term is defined at 48 328 | C.F.R. 252.227-7014(a)(1)) and "commercial computer software 329 | documentation" as such terms are used in 48 C.F.R. 12.212 330 | (Sept. 1995). Consistent with 48 C.F.R. 12.212 and 48 331 | C.F.R. 227.7202-1 through 227.7202-4 (June 1995), all 332 | U.S. Government End Users acquire Covered Software with only those 333 | rights set forth herein. This U.S. Government Rights clause is in 334 | lieu of, and supersedes, any other FAR, DFAR, or other clause or 335 | provision that addresses Government rights in computer software 336 | under this License. 337 | 338 | 9. MISCELLANEOUS. 339 | 340 | This License represents the complete agreement concerning subject 341 | matter hereof. If any provision of this License is held to be 342 | unenforceable, such provision shall be reformed only to the extent 343 | necessary to make it enforceable. This License shall be governed 344 | by the law of the jurisdiction specified in a notice contained 345 | within the Original Software (except to the extent applicable law, 346 | if any, provides otherwise), excluding such jurisdiction's 347 | conflict-of-law provisions. Any litigation relating to this 348 | License shall be subject to the jurisdiction of the courts located 349 | in the jurisdiction and venue specified in a notice contained 350 | within the Original Software, with the losing party responsible 351 | for costs, including, without limitation, court costs and 352 | reasonable attorneys' fees and expenses. The application of the 353 | United Nations Convention on Contracts for the International Sale 354 | of Goods is expressly excluded. Any law or regulation which 355 | provides that the language of a contract shall be construed 356 | against the drafter shall not apply to this License. You agree 357 | that You alone are responsible for compliance with the United 358 | States export administration regulations (and the export control 359 | laws and regulation of any other countries) when You use, 360 | distribute or otherwise make available any Covered Software. 361 | 362 | 10. RESPONSIBILITY FOR CLAIMS. 363 | 364 | As between Initial Developer and the Contributors, each party is 365 | responsible for claims and damages arising, directly or 366 | indirectly, out of its utilization of rights under this License 367 | and You agree to work with Initial Developer and Contributors to 368 | distribute such responsibility on an equitable basis. Nothing 369 | herein is intended or shall be deemed to constitute any admission 370 | of liability. 371 | 372 | -------------------------------------------------------------------- 373 | 374 | NOTICE PURSUANT TO SECTION 9 OF THE COMMON DEVELOPMENT AND 375 | DISTRIBUTION LICENSE (CDDL) 376 | 377 | For Covered Software in this distribution, this License shall 378 | be governed by the laws of the State of California (excluding 379 | conflict-of-law provisions). 380 | 381 | Any litigation relating to this License shall be subject to the 382 | jurisdiction of the Federal Courts of the Northern District of 383 | California and the state courts of the State of California, with 384 | venue lying in Santa Clara County, California. 385 | -------------------------------------------------------------------------------- /vendor/github.com/howeyc/gopass/README.md: -------------------------------------------------------------------------------- 1 | # getpasswd in Go [![GoDoc](https://godoc.org/github.com/howeyc/gopass?status.svg)](https://godoc.org/github.com/howeyc/gopass) [![Build Status](https://secure.travis-ci.org/howeyc/gopass.png?branch=master)](http://travis-ci.org/howeyc/gopass) 2 | 3 | Retrieve password from user terminal or piped input without echo. 4 | 5 | Verified on BSD, Linux, and Windows. 6 | 7 | Example: 8 | ```go 9 | package main 10 | 11 | import "fmt" 12 | import "github.com/howeyc/gopass" 13 | 14 | func main() { 15 | fmt.Printf("Password: ") 16 | 17 | // Silent. For printing *'s use gopass.GetPasswdMasked() 18 | pass, err := gopass.GetPasswd() 19 | if err != nil { 20 | // Handle gopass.ErrInterrupted or getch() read error 21 | } 22 | 23 | // Do something with pass 24 | } 25 | ``` 26 | 27 | Caution: Multi-byte characters not supported! 28 | -------------------------------------------------------------------------------- /vendor/github.com/howeyc/gopass/pass.go: -------------------------------------------------------------------------------- 1 | package gopass 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | "io" 7 | "os" 8 | ) 9 | 10 | var defaultGetCh = func() (byte, error) { 11 | buf := make([]byte, 1) 12 | if n, err := os.Stdin.Read(buf); n == 0 || err != nil { 13 | if err != nil { 14 | return 0, err 15 | } 16 | return 0, io.EOF 17 | } 18 | return buf[0], nil 19 | } 20 | 21 | var ( 22 | maxLength = 512 23 | ErrInterrupted = errors.New("interrupted") 24 | ErrMaxLengthExceeded = fmt.Errorf("maximum byte limit (%v) exceeded", maxLength) 25 | 26 | // Provide variable so that tests can provide a mock implementation. 27 | getch = defaultGetCh 28 | ) 29 | 30 | // getPasswd returns the input read from terminal. 31 | // If masked is true, typing will be matched by asterisks on the screen. 32 | // Otherwise, typing will echo nothing. 33 | func getPasswd(masked bool) ([]byte, error) { 34 | var err error 35 | var pass, bs, mask []byte 36 | if masked { 37 | bs = []byte("\b \b") 38 | mask = []byte("*") 39 | } 40 | 41 | if isTerminal(os.Stdin.Fd()) { 42 | if oldState, err := makeRaw(os.Stdin.Fd()); err != nil { 43 | return pass, err 44 | } else { 45 | defer func() { 46 | restore(os.Stdin.Fd(), oldState) 47 | fmt.Println() 48 | }() 49 | } 50 | } 51 | 52 | // Track total bytes read, not just bytes in the password. This ensures any 53 | // errors that might flood the console with nil or -1 bytes infinitely are 54 | // capped. 55 | var counter int 56 | for counter = 0; counter <= maxLength; counter++ { 57 | if v, e := getch(); e != nil { 58 | err = e 59 | break 60 | } else if v == 127 || v == 8 { 61 | if l := len(pass); l > 0 { 62 | pass = pass[:l-1] 63 | fmt.Print(string(bs)) 64 | } 65 | } else if v == 13 || v == 10 { 66 | break 67 | } else if v == 3 { 68 | err = ErrInterrupted 69 | break 70 | } else if v != 0 { 71 | pass = append(pass, v) 72 | fmt.Print(string(mask)) 73 | } 74 | } 75 | 76 | if counter > maxLength { 77 | err = ErrMaxLengthExceeded 78 | } 79 | 80 | return pass, err 81 | } 82 | 83 | // GetPasswd returns the password read from the terminal without echoing input. 84 | // The returned byte array does not include end-of-line characters. 85 | func GetPasswd() ([]byte, error) { 86 | return getPasswd(false) 87 | } 88 | 89 | // GetPasswdMasked returns the password read from the terminal, echoing asterisks. 90 | // The returned byte array does not include end-of-line characters. 91 | func GetPasswdMasked() ([]byte, error) { 92 | return getPasswd(true) 93 | } 94 | -------------------------------------------------------------------------------- /vendor/github.com/howeyc/gopass/terminal.go: -------------------------------------------------------------------------------- 1 | // +build !solaris 2 | 3 | package gopass 4 | 5 | import "golang.org/x/crypto/ssh/terminal" 6 | 7 | type terminalState struct { 8 | state *terminal.State 9 | } 10 | 11 | func isTerminal(fd uintptr) bool { 12 | return terminal.IsTerminal(int(fd)) 13 | } 14 | 15 | func makeRaw(fd uintptr) (*terminalState, error) { 16 | state, err := terminal.MakeRaw(int(fd)) 17 | 18 | return &terminalState{ 19 | state: state, 20 | }, err 21 | } 22 | 23 | func restore(fd uintptr, oldState *terminalState) error { 24 | return terminal.Restore(int(fd), oldState.state) 25 | } 26 | -------------------------------------------------------------------------------- /vendor/github.com/howeyc/gopass/terminal_solaris.go: -------------------------------------------------------------------------------- 1 | /* 2 | * CDDL HEADER START 3 | * 4 | * The contents of this file are subject to the terms of the 5 | * Common Development and Distribution License, Version 1.0 only 6 | * (the "License"). You may not use this file except in compliance 7 | * with the License. 8 | * 9 | * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 | * or http://www.opensolaris.org/os/licensing. 11 | * See the License for the specific language governing permissions 12 | * and limitations under the License. 13 | * 14 | * When distributing Covered Code, include this CDDL HEADER in each 15 | * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 | * If applicable, add the following below this CDDL HEADER, with the 17 | * fields enclosed by brackets "[]" replaced with your own identifying 18 | * information: Portions Copyright [yyyy] [name of copyright owner] 19 | * 20 | * CDDL HEADER END 21 | */ 22 | // Below is derived from Solaris source, so CDDL license is included. 23 | 24 | package gopass 25 | 26 | import ( 27 | "syscall" 28 | 29 | "golang.org/x/sys/unix" 30 | ) 31 | 32 | type terminalState struct { 33 | state *unix.Termios 34 | } 35 | 36 | // isTerminal returns true if there is a terminal attached to the given 37 | // file descriptor. 38 | // Source: http://src.illumos.org/source/xref/illumos-gate/usr/src/lib/libbc/libc/gen/common/isatty.c 39 | func isTerminal(fd uintptr) bool { 40 | var termio unix.Termio 41 | err := unix.IoctlSetTermio(int(fd), unix.TCGETA, &termio) 42 | return err == nil 43 | } 44 | 45 | // makeRaw puts the terminal connected to the given file descriptor into raw 46 | // mode and returns the previous state of the terminal so that it can be 47 | // restored. 48 | // Source: http://src.illumos.org/source/xref/illumos-gate/usr/src/lib/libast/common/uwin/getpass.c 49 | func makeRaw(fd uintptr) (*terminalState, error) { 50 | oldTermiosPtr, err := unix.IoctlGetTermios(int(fd), unix.TCGETS) 51 | if err != nil { 52 | return nil, err 53 | } 54 | oldTermios := *oldTermiosPtr 55 | 56 | newTermios := oldTermios 57 | newTermios.Lflag &^= syscall.ECHO | syscall.ECHOE | syscall.ECHOK | syscall.ECHONL 58 | if err := unix.IoctlSetTermios(int(fd), unix.TCSETS, &newTermios); err != nil { 59 | return nil, err 60 | } 61 | 62 | return &terminalState{ 63 | state: oldTermiosPtr, 64 | }, nil 65 | } 66 | 67 | func restore(fd uintptr, oldState *terminalState) error { 68 | return unix.IoctlSetTermios(int(fd), unix.TCSETS, oldState.state) 69 | } 70 | -------------------------------------------------------------------------------- /vendor/github.com/mattn/go-colorable/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Yasuhiro Matsumoto 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /vendor/github.com/mattn/go-colorable/README.md: -------------------------------------------------------------------------------- 1 | # go-colorable 2 | 3 | Colorable writer for windows. 4 | 5 | For example, most of logger packages doesn't show colors on windows. (I know we can do it with ansicon. But I don't want.) 6 | This package is possible to handle escape sequence for ansi color on windows. 7 | 8 | ## Too Bad! 9 | 10 | ![](https://raw.githubusercontent.com/mattn/go-colorable/gh-pages/bad.png) 11 | 12 | 13 | ## So Good! 14 | 15 | ![](https://raw.githubusercontent.com/mattn/go-colorable/gh-pages/good.png) 16 | 17 | ## Usage 18 | 19 | ```go 20 | logrus.SetFormatter(&logrus.TextFormatter{ForceColors: true}) 21 | logrus.SetOutput(colorable.NewColorableStdout()) 22 | 23 | logrus.Info("succeeded") 24 | logrus.Warn("not correct") 25 | logrus.Error("something error") 26 | logrus.Fatal("panic") 27 | ``` 28 | 29 | You can compile above code on non-windows OSs. 30 | 31 | ## Installation 32 | 33 | ``` 34 | $ go get github.com/mattn/go-colorable 35 | ``` 36 | 37 | # License 38 | 39 | MIT 40 | 41 | # Author 42 | 43 | Yasuhiro Matsumoto (a.k.a mattn) 44 | -------------------------------------------------------------------------------- /vendor/github.com/mattn/go-colorable/colorable_others.go: -------------------------------------------------------------------------------- 1 | // +build !windows 2 | 3 | package colorable 4 | 5 | import ( 6 | "io" 7 | "os" 8 | ) 9 | 10 | func NewColorable(file *os.File) io.Writer { 11 | if file == nil { 12 | panic("nil passed instead of *os.File to NewColorable()") 13 | } 14 | 15 | return file 16 | } 17 | 18 | func NewColorableStdout() io.Writer { 19 | return os.Stdout 20 | } 21 | 22 | func NewColorableStderr() io.Writer { 23 | return os.Stderr 24 | } 25 | -------------------------------------------------------------------------------- /vendor/github.com/mattn/go-colorable/colorable_windows.go: -------------------------------------------------------------------------------- 1 | package colorable 2 | 3 | import ( 4 | "bytes" 5 | "io" 6 | "math" 7 | "os" 8 | "strconv" 9 | "strings" 10 | "syscall" 11 | "unsafe" 12 | 13 | "github.com/mattn/go-isatty" 14 | ) 15 | 16 | const ( 17 | foregroundBlue = 0x1 18 | foregroundGreen = 0x2 19 | foregroundRed = 0x4 20 | foregroundIntensity = 0x8 21 | foregroundMask = (foregroundRed | foregroundBlue | foregroundGreen | foregroundIntensity) 22 | backgroundBlue = 0x10 23 | backgroundGreen = 0x20 24 | backgroundRed = 0x40 25 | backgroundIntensity = 0x80 26 | backgroundMask = (backgroundRed | backgroundBlue | backgroundGreen | backgroundIntensity) 27 | ) 28 | 29 | type wchar uint16 30 | type short int16 31 | type dword uint32 32 | type word uint16 33 | 34 | type coord struct { 35 | x short 36 | y short 37 | } 38 | 39 | type smallRect struct { 40 | left short 41 | top short 42 | right short 43 | bottom short 44 | } 45 | 46 | type consoleScreenBufferInfo struct { 47 | size coord 48 | cursorPosition coord 49 | attributes word 50 | window smallRect 51 | maximumWindowSize coord 52 | } 53 | 54 | type consoleCursorInfo struct { 55 | size dword 56 | visible int32 57 | } 58 | 59 | var ( 60 | kernel32 = syscall.NewLazyDLL("kernel32.dll") 61 | procGetConsoleScreenBufferInfo = kernel32.NewProc("GetConsoleScreenBufferInfo") 62 | procSetConsoleTextAttribute = kernel32.NewProc("SetConsoleTextAttribute") 63 | procSetConsoleCursorPosition = kernel32.NewProc("SetConsoleCursorPosition") 64 | procFillConsoleOutputCharacter = kernel32.NewProc("FillConsoleOutputCharacterW") 65 | procFillConsoleOutputAttribute = kernel32.NewProc("FillConsoleOutputAttribute") 66 | procGetConsoleCursorInfo = kernel32.NewProc("GetConsoleCursorInfo") 67 | procSetConsoleCursorInfo = kernel32.NewProc("SetConsoleCursorInfo") 68 | ) 69 | 70 | type Writer struct { 71 | out io.Writer 72 | handle syscall.Handle 73 | lastbuf bytes.Buffer 74 | oldattr word 75 | } 76 | 77 | func NewColorable(file *os.File) io.Writer { 78 | if file == nil { 79 | panic("nil passed instead of *os.File to NewColorable()") 80 | } 81 | 82 | if isatty.IsTerminal(file.Fd()) { 83 | var csbi consoleScreenBufferInfo 84 | handle := syscall.Handle(file.Fd()) 85 | procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi))) 86 | return &Writer{out: file, handle: handle, oldattr: csbi.attributes} 87 | } else { 88 | return file 89 | } 90 | } 91 | 92 | func NewColorableStdout() io.Writer { 93 | return NewColorable(os.Stdout) 94 | } 95 | 96 | func NewColorableStderr() io.Writer { 97 | return NewColorable(os.Stderr) 98 | } 99 | 100 | var color256 = map[int]int{ 101 | 0: 0x000000, 102 | 1: 0x800000, 103 | 2: 0x008000, 104 | 3: 0x808000, 105 | 4: 0x000080, 106 | 5: 0x800080, 107 | 6: 0x008080, 108 | 7: 0xc0c0c0, 109 | 8: 0x808080, 110 | 9: 0xff0000, 111 | 10: 0x00ff00, 112 | 11: 0xffff00, 113 | 12: 0x0000ff, 114 | 13: 0xff00ff, 115 | 14: 0x00ffff, 116 | 15: 0xffffff, 117 | 16: 0x000000, 118 | 17: 0x00005f, 119 | 18: 0x000087, 120 | 19: 0x0000af, 121 | 20: 0x0000d7, 122 | 21: 0x0000ff, 123 | 22: 0x005f00, 124 | 23: 0x005f5f, 125 | 24: 0x005f87, 126 | 25: 0x005faf, 127 | 26: 0x005fd7, 128 | 27: 0x005fff, 129 | 28: 0x008700, 130 | 29: 0x00875f, 131 | 30: 0x008787, 132 | 31: 0x0087af, 133 | 32: 0x0087d7, 134 | 33: 0x0087ff, 135 | 34: 0x00af00, 136 | 35: 0x00af5f, 137 | 36: 0x00af87, 138 | 37: 0x00afaf, 139 | 38: 0x00afd7, 140 | 39: 0x00afff, 141 | 40: 0x00d700, 142 | 41: 0x00d75f, 143 | 42: 0x00d787, 144 | 43: 0x00d7af, 145 | 44: 0x00d7d7, 146 | 45: 0x00d7ff, 147 | 46: 0x00ff00, 148 | 47: 0x00ff5f, 149 | 48: 0x00ff87, 150 | 49: 0x00ffaf, 151 | 50: 0x00ffd7, 152 | 51: 0x00ffff, 153 | 52: 0x5f0000, 154 | 53: 0x5f005f, 155 | 54: 0x5f0087, 156 | 55: 0x5f00af, 157 | 56: 0x5f00d7, 158 | 57: 0x5f00ff, 159 | 58: 0x5f5f00, 160 | 59: 0x5f5f5f, 161 | 60: 0x5f5f87, 162 | 61: 0x5f5faf, 163 | 62: 0x5f5fd7, 164 | 63: 0x5f5fff, 165 | 64: 0x5f8700, 166 | 65: 0x5f875f, 167 | 66: 0x5f8787, 168 | 67: 0x5f87af, 169 | 68: 0x5f87d7, 170 | 69: 0x5f87ff, 171 | 70: 0x5faf00, 172 | 71: 0x5faf5f, 173 | 72: 0x5faf87, 174 | 73: 0x5fafaf, 175 | 74: 0x5fafd7, 176 | 75: 0x5fafff, 177 | 76: 0x5fd700, 178 | 77: 0x5fd75f, 179 | 78: 0x5fd787, 180 | 79: 0x5fd7af, 181 | 80: 0x5fd7d7, 182 | 81: 0x5fd7ff, 183 | 82: 0x5fff00, 184 | 83: 0x5fff5f, 185 | 84: 0x5fff87, 186 | 85: 0x5fffaf, 187 | 86: 0x5fffd7, 188 | 87: 0x5fffff, 189 | 88: 0x870000, 190 | 89: 0x87005f, 191 | 90: 0x870087, 192 | 91: 0x8700af, 193 | 92: 0x8700d7, 194 | 93: 0x8700ff, 195 | 94: 0x875f00, 196 | 95: 0x875f5f, 197 | 96: 0x875f87, 198 | 97: 0x875faf, 199 | 98: 0x875fd7, 200 | 99: 0x875fff, 201 | 100: 0x878700, 202 | 101: 0x87875f, 203 | 102: 0x878787, 204 | 103: 0x8787af, 205 | 104: 0x8787d7, 206 | 105: 0x8787ff, 207 | 106: 0x87af00, 208 | 107: 0x87af5f, 209 | 108: 0x87af87, 210 | 109: 0x87afaf, 211 | 110: 0x87afd7, 212 | 111: 0x87afff, 213 | 112: 0x87d700, 214 | 113: 0x87d75f, 215 | 114: 0x87d787, 216 | 115: 0x87d7af, 217 | 116: 0x87d7d7, 218 | 117: 0x87d7ff, 219 | 118: 0x87ff00, 220 | 119: 0x87ff5f, 221 | 120: 0x87ff87, 222 | 121: 0x87ffaf, 223 | 122: 0x87ffd7, 224 | 123: 0x87ffff, 225 | 124: 0xaf0000, 226 | 125: 0xaf005f, 227 | 126: 0xaf0087, 228 | 127: 0xaf00af, 229 | 128: 0xaf00d7, 230 | 129: 0xaf00ff, 231 | 130: 0xaf5f00, 232 | 131: 0xaf5f5f, 233 | 132: 0xaf5f87, 234 | 133: 0xaf5faf, 235 | 134: 0xaf5fd7, 236 | 135: 0xaf5fff, 237 | 136: 0xaf8700, 238 | 137: 0xaf875f, 239 | 138: 0xaf8787, 240 | 139: 0xaf87af, 241 | 140: 0xaf87d7, 242 | 141: 0xaf87ff, 243 | 142: 0xafaf00, 244 | 143: 0xafaf5f, 245 | 144: 0xafaf87, 246 | 145: 0xafafaf, 247 | 146: 0xafafd7, 248 | 147: 0xafafff, 249 | 148: 0xafd700, 250 | 149: 0xafd75f, 251 | 150: 0xafd787, 252 | 151: 0xafd7af, 253 | 152: 0xafd7d7, 254 | 153: 0xafd7ff, 255 | 154: 0xafff00, 256 | 155: 0xafff5f, 257 | 156: 0xafff87, 258 | 157: 0xafffaf, 259 | 158: 0xafffd7, 260 | 159: 0xafffff, 261 | 160: 0xd70000, 262 | 161: 0xd7005f, 263 | 162: 0xd70087, 264 | 163: 0xd700af, 265 | 164: 0xd700d7, 266 | 165: 0xd700ff, 267 | 166: 0xd75f00, 268 | 167: 0xd75f5f, 269 | 168: 0xd75f87, 270 | 169: 0xd75faf, 271 | 170: 0xd75fd7, 272 | 171: 0xd75fff, 273 | 172: 0xd78700, 274 | 173: 0xd7875f, 275 | 174: 0xd78787, 276 | 175: 0xd787af, 277 | 176: 0xd787d7, 278 | 177: 0xd787ff, 279 | 178: 0xd7af00, 280 | 179: 0xd7af5f, 281 | 180: 0xd7af87, 282 | 181: 0xd7afaf, 283 | 182: 0xd7afd7, 284 | 183: 0xd7afff, 285 | 184: 0xd7d700, 286 | 185: 0xd7d75f, 287 | 186: 0xd7d787, 288 | 187: 0xd7d7af, 289 | 188: 0xd7d7d7, 290 | 189: 0xd7d7ff, 291 | 190: 0xd7ff00, 292 | 191: 0xd7ff5f, 293 | 192: 0xd7ff87, 294 | 193: 0xd7ffaf, 295 | 194: 0xd7ffd7, 296 | 195: 0xd7ffff, 297 | 196: 0xff0000, 298 | 197: 0xff005f, 299 | 198: 0xff0087, 300 | 199: 0xff00af, 301 | 200: 0xff00d7, 302 | 201: 0xff00ff, 303 | 202: 0xff5f00, 304 | 203: 0xff5f5f, 305 | 204: 0xff5f87, 306 | 205: 0xff5faf, 307 | 206: 0xff5fd7, 308 | 207: 0xff5fff, 309 | 208: 0xff8700, 310 | 209: 0xff875f, 311 | 210: 0xff8787, 312 | 211: 0xff87af, 313 | 212: 0xff87d7, 314 | 213: 0xff87ff, 315 | 214: 0xffaf00, 316 | 215: 0xffaf5f, 317 | 216: 0xffaf87, 318 | 217: 0xffafaf, 319 | 218: 0xffafd7, 320 | 219: 0xffafff, 321 | 220: 0xffd700, 322 | 221: 0xffd75f, 323 | 222: 0xffd787, 324 | 223: 0xffd7af, 325 | 224: 0xffd7d7, 326 | 225: 0xffd7ff, 327 | 226: 0xffff00, 328 | 227: 0xffff5f, 329 | 228: 0xffff87, 330 | 229: 0xffffaf, 331 | 230: 0xffffd7, 332 | 231: 0xffffff, 333 | 232: 0x080808, 334 | 233: 0x121212, 335 | 234: 0x1c1c1c, 336 | 235: 0x262626, 337 | 236: 0x303030, 338 | 237: 0x3a3a3a, 339 | 238: 0x444444, 340 | 239: 0x4e4e4e, 341 | 240: 0x585858, 342 | 241: 0x626262, 343 | 242: 0x6c6c6c, 344 | 243: 0x767676, 345 | 244: 0x808080, 346 | 245: 0x8a8a8a, 347 | 246: 0x949494, 348 | 247: 0x9e9e9e, 349 | 248: 0xa8a8a8, 350 | 249: 0xb2b2b2, 351 | 250: 0xbcbcbc, 352 | 251: 0xc6c6c6, 353 | 252: 0xd0d0d0, 354 | 253: 0xdadada, 355 | 254: 0xe4e4e4, 356 | 255: 0xeeeeee, 357 | } 358 | 359 | func (w *Writer) Write(data []byte) (n int, err error) { 360 | var csbi consoleScreenBufferInfo 361 | procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) 362 | 363 | er := bytes.NewReader(data) 364 | var bw [1]byte 365 | loop: 366 | for { 367 | r1, _, err := procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) 368 | if r1 == 0 { 369 | break loop 370 | } 371 | 372 | c1, err := er.ReadByte() 373 | if err != nil { 374 | break loop 375 | } 376 | if c1 != 0x1b { 377 | bw[0] = c1 378 | w.out.Write(bw[:]) 379 | continue 380 | } 381 | c2, err := er.ReadByte() 382 | if err != nil { 383 | w.lastbuf.WriteByte(c1) 384 | break loop 385 | } 386 | if c2 != 0x5b { 387 | w.lastbuf.WriteByte(c1) 388 | w.lastbuf.WriteByte(c2) 389 | continue 390 | } 391 | 392 | var buf bytes.Buffer 393 | var m byte 394 | for { 395 | c, err := er.ReadByte() 396 | if err != nil { 397 | w.lastbuf.WriteByte(c1) 398 | w.lastbuf.WriteByte(c2) 399 | w.lastbuf.Write(buf.Bytes()) 400 | break loop 401 | } 402 | if ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || c == '@' { 403 | m = c 404 | break 405 | } 406 | buf.Write([]byte(string(c))) 407 | } 408 | 409 | var csbi consoleScreenBufferInfo 410 | switch m { 411 | case 'A': 412 | n, err = strconv.Atoi(buf.String()) 413 | if err != nil { 414 | continue 415 | } 416 | procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) 417 | csbi.cursorPosition.y -= short(n) 418 | procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) 419 | case 'B': 420 | n, err = strconv.Atoi(buf.String()) 421 | if err != nil { 422 | continue 423 | } 424 | procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) 425 | csbi.cursorPosition.y += short(n) 426 | procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) 427 | case 'C': 428 | n, err = strconv.Atoi(buf.String()) 429 | if err != nil { 430 | continue 431 | } 432 | procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) 433 | csbi.cursorPosition.x -= short(n) 434 | procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) 435 | case 'D': 436 | n, err = strconv.Atoi(buf.String()) 437 | if err != nil { 438 | continue 439 | } 440 | if n, err = strconv.Atoi(buf.String()); err == nil { 441 | var csbi consoleScreenBufferInfo 442 | procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) 443 | csbi.cursorPosition.x += short(n) 444 | procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) 445 | } 446 | case 'E': 447 | n, err = strconv.Atoi(buf.String()) 448 | if err != nil { 449 | continue 450 | } 451 | procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) 452 | csbi.cursorPosition.x = 0 453 | csbi.cursorPosition.y += short(n) 454 | procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) 455 | case 'F': 456 | n, err = strconv.Atoi(buf.String()) 457 | if err != nil { 458 | continue 459 | } 460 | procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) 461 | csbi.cursorPosition.x = 0 462 | csbi.cursorPosition.y -= short(n) 463 | procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) 464 | case 'G': 465 | n, err = strconv.Atoi(buf.String()) 466 | if err != nil { 467 | continue 468 | } 469 | procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) 470 | csbi.cursorPosition.x = short(n - 1) 471 | procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) 472 | case 'H': 473 | token := strings.Split(buf.String(), ";") 474 | if len(token) != 2 { 475 | continue 476 | } 477 | n1, err := strconv.Atoi(token[0]) 478 | if err != nil { 479 | continue 480 | } 481 | n2, err := strconv.Atoi(token[1]) 482 | if err != nil { 483 | continue 484 | } 485 | csbi.cursorPosition.x = short(n2 - 1) 486 | csbi.cursorPosition.y = short(n1 - 1) 487 | procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) 488 | case 'J': 489 | n, err := strconv.Atoi(buf.String()) 490 | if err != nil { 491 | continue 492 | } 493 | procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) 494 | var cursor coord 495 | switch n { 496 | case 0: 497 | cursor = coord{x: csbi.cursorPosition.x, y: csbi.cursorPosition.y} 498 | case 1: 499 | cursor = coord{x: csbi.window.left, y: csbi.window.top} 500 | case 2: 501 | cursor = coord{x: csbi.window.left, y: csbi.window.top} 502 | } 503 | var count, written dword 504 | count = dword(csbi.size.x - csbi.cursorPosition.x + (csbi.size.y-csbi.cursorPosition.y)*csbi.size.x) 505 | procFillConsoleOutputCharacter.Call(uintptr(w.handle), uintptr(' '), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written))) 506 | procFillConsoleOutputAttribute.Call(uintptr(w.handle), uintptr(csbi.attributes), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written))) 507 | case 'K': 508 | n, err := strconv.Atoi(buf.String()) 509 | if err != nil { 510 | continue 511 | } 512 | procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) 513 | var cursor coord 514 | switch n { 515 | case 0: 516 | cursor = coord{x: csbi.cursorPosition.x, y: csbi.cursorPosition.y} 517 | case 1: 518 | cursor = coord{x: csbi.window.left, y: csbi.window.top + csbi.cursorPosition.y} 519 | case 2: 520 | cursor = coord{x: csbi.window.left, y: csbi.window.top + csbi.cursorPosition.y} 521 | } 522 | var count, written dword 523 | count = dword(csbi.size.x - csbi.cursorPosition.x) 524 | procFillConsoleOutputCharacter.Call(uintptr(w.handle), uintptr(' '), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written))) 525 | procFillConsoleOutputAttribute.Call(uintptr(w.handle), uintptr(csbi.attributes), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written))) 526 | case 'm': 527 | procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) 528 | attr := csbi.attributes 529 | cs := buf.String() 530 | if cs == "" { 531 | procSetConsoleTextAttribute.Call(uintptr(w.handle), uintptr(w.oldattr)) 532 | continue 533 | } 534 | token := strings.Split(cs, ";") 535 | for i := 0; i < len(token); i++ { 536 | ns := token[i] 537 | if n, err = strconv.Atoi(ns); err == nil { 538 | switch { 539 | case n == 0 || n == 100: 540 | attr = w.oldattr 541 | case 1 <= n && n <= 5: 542 | attr |= foregroundIntensity 543 | case n == 7: 544 | attr = ((attr & foregroundMask) << 4) | ((attr & backgroundMask) >> 4) 545 | case 22 == n || n == 25 || n == 25: 546 | attr |= foregroundIntensity 547 | case n == 27: 548 | attr = ((attr & foregroundMask) << 4) | ((attr & backgroundMask) >> 4) 549 | case 30 <= n && n <= 37: 550 | attr &= backgroundMask 551 | if (n-30)&1 != 0 { 552 | attr |= foregroundRed 553 | } 554 | if (n-30)&2 != 0 { 555 | attr |= foregroundGreen 556 | } 557 | if (n-30)&4 != 0 { 558 | attr |= foregroundBlue 559 | } 560 | case n == 38: // set foreground color. 561 | if i < len(token)-2 && (token[i+1] == "5" || token[i+1] == "05") { 562 | if n256, err := strconv.Atoi(token[i+2]); err == nil { 563 | if n256foreAttr == nil { 564 | n256setup() 565 | } 566 | attr &= backgroundMask 567 | attr |= n256foreAttr[n256] 568 | i += 2 569 | } 570 | } else { 571 | attr = attr & (w.oldattr & backgroundMask) 572 | } 573 | case n == 39: // reset foreground color. 574 | attr &= backgroundMask 575 | attr |= w.oldattr & foregroundMask 576 | case 40 <= n && n <= 47: 577 | attr &= foregroundMask 578 | if (n-40)&1 != 0 { 579 | attr |= backgroundRed 580 | } 581 | if (n-40)&2 != 0 { 582 | attr |= backgroundGreen 583 | } 584 | if (n-40)&4 != 0 { 585 | attr |= backgroundBlue 586 | } 587 | case n == 48: // set background color. 588 | if i < len(token)-2 && token[i+1] == "5" { 589 | if n256, err := strconv.Atoi(token[i+2]); err == nil { 590 | if n256backAttr == nil { 591 | n256setup() 592 | } 593 | attr &= foregroundMask 594 | attr |= n256backAttr[n256] 595 | i += 2 596 | } 597 | } else { 598 | attr = attr & (w.oldattr & foregroundMask) 599 | } 600 | case n == 49: // reset foreground color. 601 | attr &= foregroundMask 602 | attr |= w.oldattr & backgroundMask 603 | case 90 <= n && n <= 97: 604 | attr = (attr & backgroundMask) 605 | attr |= foregroundIntensity 606 | if (n-90)&1 != 0 { 607 | attr |= foregroundRed 608 | } 609 | if (n-90)&2 != 0 { 610 | attr |= foregroundGreen 611 | } 612 | if (n-90)&4 != 0 { 613 | attr |= foregroundBlue 614 | } 615 | case 100 <= n && n <= 107: 616 | attr = (attr & foregroundMask) 617 | attr |= backgroundIntensity 618 | if (n-100)&1 != 0 { 619 | attr |= backgroundRed 620 | } 621 | if (n-100)&2 != 0 { 622 | attr |= backgroundGreen 623 | } 624 | if (n-100)&4 != 0 { 625 | attr |= backgroundBlue 626 | } 627 | } 628 | procSetConsoleTextAttribute.Call(uintptr(w.handle), uintptr(attr)) 629 | } 630 | } 631 | case 'h': 632 | cs := buf.String() 633 | if cs == "?25" { 634 | var ci consoleCursorInfo 635 | procGetConsoleCursorInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&ci))) 636 | ci.visible = 1 637 | procSetConsoleCursorInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&ci))) 638 | } 639 | case 'l': 640 | cs := buf.String() 641 | if cs == "?25" { 642 | var ci consoleCursorInfo 643 | procGetConsoleCursorInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&ci))) 644 | ci.visible = 0 645 | procSetConsoleCursorInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&ci))) 646 | } 647 | } 648 | } 649 | return len(data) - w.lastbuf.Len(), nil 650 | } 651 | 652 | type consoleColor struct { 653 | rgb int 654 | red bool 655 | green bool 656 | blue bool 657 | intensity bool 658 | } 659 | 660 | func (c consoleColor) foregroundAttr() (attr word) { 661 | if c.red { 662 | attr |= foregroundRed 663 | } 664 | if c.green { 665 | attr |= foregroundGreen 666 | } 667 | if c.blue { 668 | attr |= foregroundBlue 669 | } 670 | if c.intensity { 671 | attr |= foregroundIntensity 672 | } 673 | return 674 | } 675 | 676 | func (c consoleColor) backgroundAttr() (attr word) { 677 | if c.red { 678 | attr |= backgroundRed 679 | } 680 | if c.green { 681 | attr |= backgroundGreen 682 | } 683 | if c.blue { 684 | attr |= backgroundBlue 685 | } 686 | if c.intensity { 687 | attr |= backgroundIntensity 688 | } 689 | return 690 | } 691 | 692 | var color16 = []consoleColor{ 693 | consoleColor{0x000000, false, false, false, false}, 694 | consoleColor{0x000080, false, false, true, false}, 695 | consoleColor{0x008000, false, true, false, false}, 696 | consoleColor{0x008080, false, true, true, false}, 697 | consoleColor{0x800000, true, false, false, false}, 698 | consoleColor{0x800080, true, false, true, false}, 699 | consoleColor{0x808000, true, true, false, false}, 700 | consoleColor{0xc0c0c0, true, true, true, false}, 701 | consoleColor{0x808080, false, false, false, true}, 702 | consoleColor{0x0000ff, false, false, true, true}, 703 | consoleColor{0x00ff00, false, true, false, true}, 704 | consoleColor{0x00ffff, false, true, true, true}, 705 | consoleColor{0xff0000, true, false, false, true}, 706 | consoleColor{0xff00ff, true, false, true, true}, 707 | consoleColor{0xffff00, true, true, false, true}, 708 | consoleColor{0xffffff, true, true, true, true}, 709 | } 710 | 711 | type hsv struct { 712 | h, s, v float32 713 | } 714 | 715 | func (a hsv) dist(b hsv) float32 { 716 | dh := a.h - b.h 717 | switch { 718 | case dh > 0.5: 719 | dh = 1 - dh 720 | case dh < -0.5: 721 | dh = -1 - dh 722 | } 723 | ds := a.s - b.s 724 | dv := a.v - b.v 725 | return float32(math.Sqrt(float64(dh*dh + ds*ds + dv*dv))) 726 | } 727 | 728 | func toHSV(rgb int) hsv { 729 | r, g, b := float32((rgb&0xFF0000)>>16)/256.0, 730 | float32((rgb&0x00FF00)>>8)/256.0, 731 | float32(rgb&0x0000FF)/256.0 732 | min, max := minmax3f(r, g, b) 733 | h := max - min 734 | if h > 0 { 735 | if max == r { 736 | h = (g - b) / h 737 | if h < 0 { 738 | h += 6 739 | } 740 | } else if max == g { 741 | h = 2 + (b-r)/h 742 | } else { 743 | h = 4 + (r-g)/h 744 | } 745 | } 746 | h /= 6.0 747 | s := max - min 748 | if max != 0 { 749 | s /= max 750 | } 751 | v := max 752 | return hsv{h: h, s: s, v: v} 753 | } 754 | 755 | type hsvTable []hsv 756 | 757 | func toHSVTable(rgbTable []consoleColor) hsvTable { 758 | t := make(hsvTable, len(rgbTable)) 759 | for i, c := range rgbTable { 760 | t[i] = toHSV(c.rgb) 761 | } 762 | return t 763 | } 764 | 765 | func (t hsvTable) find(rgb int) consoleColor { 766 | hsv := toHSV(rgb) 767 | n := 7 768 | l := float32(5.0) 769 | for i, p := range t { 770 | d := hsv.dist(p) 771 | if d < l { 772 | l, n = d, i 773 | } 774 | } 775 | return color16[n] 776 | } 777 | 778 | func minmax3f(a, b, c float32) (min, max float32) { 779 | if a < b { 780 | if b < c { 781 | return a, c 782 | } else if a < c { 783 | return a, b 784 | } else { 785 | return c, b 786 | } 787 | } else { 788 | if a < c { 789 | return b, c 790 | } else if b < c { 791 | return b, a 792 | } else { 793 | return c, a 794 | } 795 | } 796 | } 797 | 798 | var n256foreAttr []word 799 | var n256backAttr []word 800 | 801 | func n256setup() { 802 | n256foreAttr = make([]word, 256) 803 | n256backAttr = make([]word, 256) 804 | t := toHSVTable(color16) 805 | for i, rgb := range color256 { 806 | c := t.find(rgb) 807 | n256foreAttr[i] = c.foregroundAttr() 808 | n256backAttr[i] = c.backgroundAttr() 809 | } 810 | } 811 | -------------------------------------------------------------------------------- /vendor/github.com/mattn/go-colorable/noncolorable.go: -------------------------------------------------------------------------------- 1 | package colorable 2 | 3 | import ( 4 | "bytes" 5 | "io" 6 | ) 7 | 8 | type NonColorable struct { 9 | out io.Writer 10 | lastbuf bytes.Buffer 11 | } 12 | 13 | func NewNonColorable(w io.Writer) io.Writer { 14 | return &NonColorable{out: w} 15 | } 16 | 17 | func (w *NonColorable) Write(data []byte) (n int, err error) { 18 | er := bytes.NewReader(data) 19 | var bw [1]byte 20 | loop: 21 | for { 22 | c1, err := er.ReadByte() 23 | if err != nil { 24 | break loop 25 | } 26 | if c1 != 0x1b { 27 | bw[0] = c1 28 | w.out.Write(bw[:]) 29 | continue 30 | } 31 | c2, err := er.ReadByte() 32 | if err != nil { 33 | w.lastbuf.WriteByte(c1) 34 | break loop 35 | } 36 | if c2 != 0x5b { 37 | w.lastbuf.WriteByte(c1) 38 | w.lastbuf.WriteByte(c2) 39 | continue 40 | } 41 | 42 | var buf bytes.Buffer 43 | for { 44 | c, err := er.ReadByte() 45 | if err != nil { 46 | w.lastbuf.WriteByte(c1) 47 | w.lastbuf.WriteByte(c2) 48 | w.lastbuf.Write(buf.Bytes()) 49 | break loop 50 | } 51 | if ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || c == '@' { 52 | break 53 | } 54 | buf.Write([]byte(string(c))) 55 | } 56 | } 57 | return len(data) - w.lastbuf.Len(), nil 58 | } 59 | -------------------------------------------------------------------------------- /vendor/github.com/mattn/go-isatty/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) Yasuhiro MATSUMOTO 2 | 3 | MIT License (Expat) 4 | 5 | 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: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | 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. 10 | -------------------------------------------------------------------------------- /vendor/github.com/mattn/go-isatty/README.md: -------------------------------------------------------------------------------- 1 | # go-isatty 2 | 3 | isatty for golang 4 | 5 | ## Usage 6 | 7 | ```go 8 | package main 9 | 10 | import ( 11 | "fmt" 12 | "github.com/mattn/go-isatty" 13 | "os" 14 | ) 15 | 16 | func main() { 17 | if isatty.IsTerminal(os.Stdout.Fd()) { 18 | fmt.Println("Is Terminal") 19 | } else { 20 | fmt.Println("Is Not Terminal") 21 | } 22 | } 23 | ``` 24 | 25 | ## Installation 26 | 27 | ``` 28 | $ go get github.com/mattn/go-isatty 29 | ``` 30 | 31 | # License 32 | 33 | MIT 34 | 35 | # Author 36 | 37 | Yasuhiro Matsumoto (a.k.a mattn) 38 | -------------------------------------------------------------------------------- /vendor/github.com/mattn/go-isatty/doc.go: -------------------------------------------------------------------------------- 1 | // Package isatty implements interface to isatty 2 | package isatty 3 | -------------------------------------------------------------------------------- /vendor/github.com/mattn/go-isatty/isatty_appengine.go: -------------------------------------------------------------------------------- 1 | // +build appengine 2 | 3 | package isatty 4 | 5 | // IsTerminal returns true if the file descriptor is terminal which 6 | // is always false on on appengine classic which is a sandboxed PaaS. 7 | func IsTerminal(fd uintptr) bool { 8 | return false 9 | } 10 | -------------------------------------------------------------------------------- /vendor/github.com/mattn/go-isatty/isatty_bsd.go: -------------------------------------------------------------------------------- 1 | // +build darwin freebsd openbsd netbsd dragonfly 2 | // +build !appengine 3 | 4 | package isatty 5 | 6 | import ( 7 | "syscall" 8 | "unsafe" 9 | ) 10 | 11 | const ioctlReadTermios = syscall.TIOCGETA 12 | 13 | // IsTerminal return true if the file descriptor is terminal. 14 | func IsTerminal(fd uintptr) bool { 15 | var termios syscall.Termios 16 | _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, fd, ioctlReadTermios, uintptr(unsafe.Pointer(&termios)), 0, 0, 0) 17 | return err == 0 18 | } 19 | -------------------------------------------------------------------------------- /vendor/github.com/mattn/go-isatty/isatty_linux.go: -------------------------------------------------------------------------------- 1 | // +build linux 2 | // +build !appengine 3 | 4 | package isatty 5 | 6 | import ( 7 | "syscall" 8 | "unsafe" 9 | ) 10 | 11 | const ioctlReadTermios = syscall.TCGETS 12 | 13 | // IsTerminal return true if the file descriptor is terminal. 14 | func IsTerminal(fd uintptr) bool { 15 | var termios syscall.Termios 16 | _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, fd, ioctlReadTermios, uintptr(unsafe.Pointer(&termios)), 0, 0, 0) 17 | return err == 0 18 | } 19 | -------------------------------------------------------------------------------- /vendor/github.com/mattn/go-isatty/isatty_solaris.go: -------------------------------------------------------------------------------- 1 | // +build solaris 2 | // +build !appengine 3 | 4 | package isatty 5 | 6 | import ( 7 | "golang.org/x/sys/unix" 8 | ) 9 | 10 | // IsTerminal returns true if the given file descriptor is a terminal. 11 | // see: http://src.illumos.org/source/xref/illumos-gate/usr/src/lib/libbc/libc/gen/common/isatty.c 12 | func IsTerminal(fd uintptr) bool { 13 | var termio unix.Termio 14 | err := unix.IoctlSetTermio(int(fd), unix.TCGETA, &termio) 15 | return err == nil 16 | } 17 | -------------------------------------------------------------------------------- /vendor/github.com/mattn/go-isatty/isatty_windows.go: -------------------------------------------------------------------------------- 1 | // +build windows 2 | // +build !appengine 3 | 4 | package isatty 5 | 6 | import ( 7 | "syscall" 8 | "unsafe" 9 | ) 10 | 11 | var kernel32 = syscall.NewLazyDLL("kernel32.dll") 12 | var procGetConsoleMode = kernel32.NewProc("GetConsoleMode") 13 | 14 | // IsTerminal return true if the file descriptor is terminal. 15 | func IsTerminal(fd uintptr) bool { 16 | var st uint32 17 | r, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, fd, uintptr(unsafe.Pointer(&st)), 0) 18 | return r != 0 && e == 0 19 | } 20 | -------------------------------------------------------------------------------- /vendor/golang.org/x/crypto/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2009 The Go Authors. All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions are 5 | met: 6 | 7 | * Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | * Redistributions in binary form must reproduce the above 10 | copyright notice, this list of conditions and the following disclaimer 11 | in the documentation and/or other materials provided with the 12 | distribution. 13 | * Neither the name of Google Inc. nor the names of its 14 | contributors may be used to endorse or promote products derived from 15 | this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /vendor/golang.org/x/crypto/PATENTS: -------------------------------------------------------------------------------- 1 | Additional IP Rights Grant (Patents) 2 | 3 | "This implementation" means the copyrightable works distributed by 4 | Google as part of the Go project. 5 | 6 | Google hereby grants to You a perpetual, worldwide, non-exclusive, 7 | no-charge, royalty-free, irrevocable (except as stated in this section) 8 | patent license to make, have made, use, offer to sell, sell, import, 9 | transfer and otherwise run, modify and propagate the contents of this 10 | implementation of Go, where such license applies only to those patent 11 | claims, both currently owned or controlled by Google and acquired in 12 | the future, licensable by Google that are necessarily infringed by this 13 | implementation of Go. This grant does not include claims that would be 14 | infringed only as a consequence of further modification of this 15 | implementation. If you or your agent or exclusive licensee institute or 16 | order or agree to the institution of patent litigation against any 17 | entity (including a cross-claim or counterclaim in a lawsuit) alleging 18 | that this implementation of Go or any code incorporated within this 19 | implementation of Go constitutes direct or contributory patent 20 | infringement, or inducement of patent infringement, then any patent 21 | rights granted to you under this License for this implementation of Go 22 | shall terminate as of the date such litigation is filed. 23 | -------------------------------------------------------------------------------- /vendor/golang.org/x/crypto/ssh/terminal/terminal.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package terminal 6 | 7 | import ( 8 | "bytes" 9 | "io" 10 | "sync" 11 | "unicode/utf8" 12 | ) 13 | 14 | // EscapeCodes contains escape sequences that can be written to the terminal in 15 | // order to achieve different styles of text. 16 | type EscapeCodes struct { 17 | // Foreground colors 18 | Black, Red, Green, Yellow, Blue, Magenta, Cyan, White []byte 19 | 20 | // Reset all attributes 21 | Reset []byte 22 | } 23 | 24 | var vt100EscapeCodes = EscapeCodes{ 25 | Black: []byte{keyEscape, '[', '3', '0', 'm'}, 26 | Red: []byte{keyEscape, '[', '3', '1', 'm'}, 27 | Green: []byte{keyEscape, '[', '3', '2', 'm'}, 28 | Yellow: []byte{keyEscape, '[', '3', '3', 'm'}, 29 | Blue: []byte{keyEscape, '[', '3', '4', 'm'}, 30 | Magenta: []byte{keyEscape, '[', '3', '5', 'm'}, 31 | Cyan: []byte{keyEscape, '[', '3', '6', 'm'}, 32 | White: []byte{keyEscape, '[', '3', '7', 'm'}, 33 | 34 | Reset: []byte{keyEscape, '[', '0', 'm'}, 35 | } 36 | 37 | // Terminal contains the state for running a VT100 terminal that is capable of 38 | // reading lines of input. 39 | type Terminal struct { 40 | // AutoCompleteCallback, if non-null, is called for each keypress with 41 | // the full input line and the current position of the cursor (in 42 | // bytes, as an index into |line|). If it returns ok=false, the key 43 | // press is processed normally. Otherwise it returns a replacement line 44 | // and the new cursor position. 45 | AutoCompleteCallback func(line string, pos int, key rune) (newLine string, newPos int, ok bool) 46 | 47 | // Escape contains a pointer to the escape codes for this terminal. 48 | // It's always a valid pointer, although the escape codes themselves 49 | // may be empty if the terminal doesn't support them. 50 | Escape *EscapeCodes 51 | 52 | // lock protects the terminal and the state in this object from 53 | // concurrent processing of a key press and a Write() call. 54 | lock sync.Mutex 55 | 56 | c io.ReadWriter 57 | prompt []rune 58 | 59 | // line is the current line being entered. 60 | line []rune 61 | // pos is the logical position of the cursor in line 62 | pos int 63 | // echo is true if local echo is enabled 64 | echo bool 65 | // pasteActive is true iff there is a bracketed paste operation in 66 | // progress. 67 | pasteActive bool 68 | 69 | // cursorX contains the current X value of the cursor where the left 70 | // edge is 0. cursorY contains the row number where the first row of 71 | // the current line is 0. 72 | cursorX, cursorY int 73 | // maxLine is the greatest value of cursorY so far. 74 | maxLine int 75 | 76 | termWidth, termHeight int 77 | 78 | // outBuf contains the terminal data to be sent. 79 | outBuf []byte 80 | // remainder contains the remainder of any partial key sequences after 81 | // a read. It aliases into inBuf. 82 | remainder []byte 83 | inBuf [256]byte 84 | 85 | // history contains previously entered commands so that they can be 86 | // accessed with the up and down keys. 87 | history stRingBuffer 88 | // historyIndex stores the currently accessed history entry, where zero 89 | // means the immediately previous entry. 90 | historyIndex int 91 | // When navigating up and down the history it's possible to return to 92 | // the incomplete, initial line. That value is stored in 93 | // historyPending. 94 | historyPending string 95 | } 96 | 97 | // NewTerminal runs a VT100 terminal on the given ReadWriter. If the ReadWriter is 98 | // a local terminal, that terminal must first have been put into raw mode. 99 | // prompt is a string that is written at the start of each input line (i.e. 100 | // "> "). 101 | func NewTerminal(c io.ReadWriter, prompt string) *Terminal { 102 | return &Terminal{ 103 | Escape: &vt100EscapeCodes, 104 | c: c, 105 | prompt: []rune(prompt), 106 | termWidth: 80, 107 | termHeight: 24, 108 | echo: true, 109 | historyIndex: -1, 110 | } 111 | } 112 | 113 | const ( 114 | keyCtrlD = 4 115 | keyCtrlU = 21 116 | keyEnter = '\r' 117 | keyEscape = 27 118 | keyBackspace = 127 119 | keyUnknown = 0xd800 /* UTF-16 surrogate area */ + iota 120 | keyUp 121 | keyDown 122 | keyLeft 123 | keyRight 124 | keyAltLeft 125 | keyAltRight 126 | keyHome 127 | keyEnd 128 | keyDeleteWord 129 | keyDeleteLine 130 | keyClearScreen 131 | keyPasteStart 132 | keyPasteEnd 133 | ) 134 | 135 | var pasteStart = []byte{keyEscape, '[', '2', '0', '0', '~'} 136 | var pasteEnd = []byte{keyEscape, '[', '2', '0', '1', '~'} 137 | 138 | // bytesToKey tries to parse a key sequence from b. If successful, it returns 139 | // the key and the remainder of the input. Otherwise it returns utf8.RuneError. 140 | func bytesToKey(b []byte, pasteActive bool) (rune, []byte) { 141 | if len(b) == 0 { 142 | return utf8.RuneError, nil 143 | } 144 | 145 | if !pasteActive { 146 | switch b[0] { 147 | case 1: // ^A 148 | return keyHome, b[1:] 149 | case 5: // ^E 150 | return keyEnd, b[1:] 151 | case 8: // ^H 152 | return keyBackspace, b[1:] 153 | case 11: // ^K 154 | return keyDeleteLine, b[1:] 155 | case 12: // ^L 156 | return keyClearScreen, b[1:] 157 | case 23: // ^W 158 | return keyDeleteWord, b[1:] 159 | } 160 | } 161 | 162 | if b[0] != keyEscape { 163 | if !utf8.FullRune(b) { 164 | return utf8.RuneError, b 165 | } 166 | r, l := utf8.DecodeRune(b) 167 | return r, b[l:] 168 | } 169 | 170 | if !pasteActive && len(b) >= 3 && b[0] == keyEscape && b[1] == '[' { 171 | switch b[2] { 172 | case 'A': 173 | return keyUp, b[3:] 174 | case 'B': 175 | return keyDown, b[3:] 176 | case 'C': 177 | return keyRight, b[3:] 178 | case 'D': 179 | return keyLeft, b[3:] 180 | case 'H': 181 | return keyHome, b[3:] 182 | case 'F': 183 | return keyEnd, b[3:] 184 | } 185 | } 186 | 187 | if !pasteActive && len(b) >= 6 && b[0] == keyEscape && b[1] == '[' && b[2] == '1' && b[3] == ';' && b[4] == '3' { 188 | switch b[5] { 189 | case 'C': 190 | return keyAltRight, b[6:] 191 | case 'D': 192 | return keyAltLeft, b[6:] 193 | } 194 | } 195 | 196 | if !pasteActive && len(b) >= 6 && bytes.Equal(b[:6], pasteStart) { 197 | return keyPasteStart, b[6:] 198 | } 199 | 200 | if pasteActive && len(b) >= 6 && bytes.Equal(b[:6], pasteEnd) { 201 | return keyPasteEnd, b[6:] 202 | } 203 | 204 | // If we get here then we have a key that we don't recognise, or a 205 | // partial sequence. It's not clear how one should find the end of a 206 | // sequence without knowing them all, but it seems that [a-zA-Z~] only 207 | // appears at the end of a sequence. 208 | for i, c := range b[0:] { 209 | if c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || c == '~' { 210 | return keyUnknown, b[i+1:] 211 | } 212 | } 213 | 214 | return utf8.RuneError, b 215 | } 216 | 217 | // queue appends data to the end of t.outBuf 218 | func (t *Terminal) queue(data []rune) { 219 | t.outBuf = append(t.outBuf, []byte(string(data))...) 220 | } 221 | 222 | var eraseUnderCursor = []rune{' ', keyEscape, '[', 'D'} 223 | var space = []rune{' '} 224 | 225 | func isPrintable(key rune) bool { 226 | isInSurrogateArea := key >= 0xd800 && key <= 0xdbff 227 | return key >= 32 && !isInSurrogateArea 228 | } 229 | 230 | // moveCursorToPos appends data to t.outBuf which will move the cursor to the 231 | // given, logical position in the text. 232 | func (t *Terminal) moveCursorToPos(pos int) { 233 | if !t.echo { 234 | return 235 | } 236 | 237 | x := visualLength(t.prompt) + pos 238 | y := x / t.termWidth 239 | x = x % t.termWidth 240 | 241 | up := 0 242 | if y < t.cursorY { 243 | up = t.cursorY - y 244 | } 245 | 246 | down := 0 247 | if y > t.cursorY { 248 | down = y - t.cursorY 249 | } 250 | 251 | left := 0 252 | if x < t.cursorX { 253 | left = t.cursorX - x 254 | } 255 | 256 | right := 0 257 | if x > t.cursorX { 258 | right = x - t.cursorX 259 | } 260 | 261 | t.cursorX = x 262 | t.cursorY = y 263 | t.move(up, down, left, right) 264 | } 265 | 266 | func (t *Terminal) move(up, down, left, right int) { 267 | movement := make([]rune, 3*(up+down+left+right)) 268 | m := movement 269 | for i := 0; i < up; i++ { 270 | m[0] = keyEscape 271 | m[1] = '[' 272 | m[2] = 'A' 273 | m = m[3:] 274 | } 275 | for i := 0; i < down; i++ { 276 | m[0] = keyEscape 277 | m[1] = '[' 278 | m[2] = 'B' 279 | m = m[3:] 280 | } 281 | for i := 0; i < left; i++ { 282 | m[0] = keyEscape 283 | m[1] = '[' 284 | m[2] = 'D' 285 | m = m[3:] 286 | } 287 | for i := 0; i < right; i++ { 288 | m[0] = keyEscape 289 | m[1] = '[' 290 | m[2] = 'C' 291 | m = m[3:] 292 | } 293 | 294 | t.queue(movement) 295 | } 296 | 297 | func (t *Terminal) clearLineToRight() { 298 | op := []rune{keyEscape, '[', 'K'} 299 | t.queue(op) 300 | } 301 | 302 | const maxLineLength = 4096 303 | 304 | func (t *Terminal) setLine(newLine []rune, newPos int) { 305 | if t.echo { 306 | t.moveCursorToPos(0) 307 | t.writeLine(newLine) 308 | for i := len(newLine); i < len(t.line); i++ { 309 | t.writeLine(space) 310 | } 311 | t.moveCursorToPos(newPos) 312 | } 313 | t.line = newLine 314 | t.pos = newPos 315 | } 316 | 317 | func (t *Terminal) advanceCursor(places int) { 318 | t.cursorX += places 319 | t.cursorY += t.cursorX / t.termWidth 320 | if t.cursorY > t.maxLine { 321 | t.maxLine = t.cursorY 322 | } 323 | t.cursorX = t.cursorX % t.termWidth 324 | 325 | if places > 0 && t.cursorX == 0 { 326 | // Normally terminals will advance the current position 327 | // when writing a character. But that doesn't happen 328 | // for the last character in a line. However, when 329 | // writing a character (except a new line) that causes 330 | // a line wrap, the position will be advanced two 331 | // places. 332 | // 333 | // So, if we are stopping at the end of a line, we 334 | // need to write a newline so that our cursor can be 335 | // advanced to the next line. 336 | t.outBuf = append(t.outBuf, '\n') 337 | } 338 | } 339 | 340 | func (t *Terminal) eraseNPreviousChars(n int) { 341 | if n == 0 { 342 | return 343 | } 344 | 345 | if t.pos < n { 346 | n = t.pos 347 | } 348 | t.pos -= n 349 | t.moveCursorToPos(t.pos) 350 | 351 | copy(t.line[t.pos:], t.line[n+t.pos:]) 352 | t.line = t.line[:len(t.line)-n] 353 | if t.echo { 354 | t.writeLine(t.line[t.pos:]) 355 | for i := 0; i < n; i++ { 356 | t.queue(space) 357 | } 358 | t.advanceCursor(n) 359 | t.moveCursorToPos(t.pos) 360 | } 361 | } 362 | 363 | // countToLeftWord returns then number of characters from the cursor to the 364 | // start of the previous word. 365 | func (t *Terminal) countToLeftWord() int { 366 | if t.pos == 0 { 367 | return 0 368 | } 369 | 370 | pos := t.pos - 1 371 | for pos > 0 { 372 | if t.line[pos] != ' ' { 373 | break 374 | } 375 | pos-- 376 | } 377 | for pos > 0 { 378 | if t.line[pos] == ' ' { 379 | pos++ 380 | break 381 | } 382 | pos-- 383 | } 384 | 385 | return t.pos - pos 386 | } 387 | 388 | // countToRightWord returns then number of characters from the cursor to the 389 | // start of the next word. 390 | func (t *Terminal) countToRightWord() int { 391 | pos := t.pos 392 | for pos < len(t.line) { 393 | if t.line[pos] == ' ' { 394 | break 395 | } 396 | pos++ 397 | } 398 | for pos < len(t.line) { 399 | if t.line[pos] != ' ' { 400 | break 401 | } 402 | pos++ 403 | } 404 | return pos - t.pos 405 | } 406 | 407 | // visualLength returns the number of visible glyphs in s. 408 | func visualLength(runes []rune) int { 409 | inEscapeSeq := false 410 | length := 0 411 | 412 | for _, r := range runes { 413 | switch { 414 | case inEscapeSeq: 415 | if (r >= 'a' && r <= 'z') || (r >= 'A' && r <= 'Z') { 416 | inEscapeSeq = false 417 | } 418 | case r == '\x1b': 419 | inEscapeSeq = true 420 | default: 421 | length++ 422 | } 423 | } 424 | 425 | return length 426 | } 427 | 428 | // handleKey processes the given key and, optionally, returns a line of text 429 | // that the user has entered. 430 | func (t *Terminal) handleKey(key rune) (line string, ok bool) { 431 | if t.pasteActive && key != keyEnter { 432 | t.addKeyToLine(key) 433 | return 434 | } 435 | 436 | switch key { 437 | case keyBackspace: 438 | if t.pos == 0 { 439 | return 440 | } 441 | t.eraseNPreviousChars(1) 442 | case keyAltLeft: 443 | // move left by a word. 444 | t.pos -= t.countToLeftWord() 445 | t.moveCursorToPos(t.pos) 446 | case keyAltRight: 447 | // move right by a word. 448 | t.pos += t.countToRightWord() 449 | t.moveCursorToPos(t.pos) 450 | case keyLeft: 451 | if t.pos == 0 { 452 | return 453 | } 454 | t.pos-- 455 | t.moveCursorToPos(t.pos) 456 | case keyRight: 457 | if t.pos == len(t.line) { 458 | return 459 | } 460 | t.pos++ 461 | t.moveCursorToPos(t.pos) 462 | case keyHome: 463 | if t.pos == 0 { 464 | return 465 | } 466 | t.pos = 0 467 | t.moveCursorToPos(t.pos) 468 | case keyEnd: 469 | if t.pos == len(t.line) { 470 | return 471 | } 472 | t.pos = len(t.line) 473 | t.moveCursorToPos(t.pos) 474 | case keyUp: 475 | entry, ok := t.history.NthPreviousEntry(t.historyIndex + 1) 476 | if !ok { 477 | return "", false 478 | } 479 | if t.historyIndex == -1 { 480 | t.historyPending = string(t.line) 481 | } 482 | t.historyIndex++ 483 | runes := []rune(entry) 484 | t.setLine(runes, len(runes)) 485 | case keyDown: 486 | switch t.historyIndex { 487 | case -1: 488 | return 489 | case 0: 490 | runes := []rune(t.historyPending) 491 | t.setLine(runes, len(runes)) 492 | t.historyIndex-- 493 | default: 494 | entry, ok := t.history.NthPreviousEntry(t.historyIndex - 1) 495 | if ok { 496 | t.historyIndex-- 497 | runes := []rune(entry) 498 | t.setLine(runes, len(runes)) 499 | } 500 | } 501 | case keyEnter: 502 | t.moveCursorToPos(len(t.line)) 503 | t.queue([]rune("\r\n")) 504 | line = string(t.line) 505 | ok = true 506 | t.line = t.line[:0] 507 | t.pos = 0 508 | t.cursorX = 0 509 | t.cursorY = 0 510 | t.maxLine = 0 511 | case keyDeleteWord: 512 | // Delete zero or more spaces and then one or more characters. 513 | t.eraseNPreviousChars(t.countToLeftWord()) 514 | case keyDeleteLine: 515 | // Delete everything from the current cursor position to the 516 | // end of line. 517 | for i := t.pos; i < len(t.line); i++ { 518 | t.queue(space) 519 | t.advanceCursor(1) 520 | } 521 | t.line = t.line[:t.pos] 522 | t.moveCursorToPos(t.pos) 523 | case keyCtrlD: 524 | // Erase the character under the current position. 525 | // The EOF case when the line is empty is handled in 526 | // readLine(). 527 | if t.pos < len(t.line) { 528 | t.pos++ 529 | t.eraseNPreviousChars(1) 530 | } 531 | case keyCtrlU: 532 | t.eraseNPreviousChars(t.pos) 533 | case keyClearScreen: 534 | // Erases the screen and moves the cursor to the home position. 535 | t.queue([]rune("\x1b[2J\x1b[H")) 536 | t.queue(t.prompt) 537 | t.cursorX, t.cursorY = 0, 0 538 | t.advanceCursor(visualLength(t.prompt)) 539 | t.setLine(t.line, t.pos) 540 | default: 541 | if t.AutoCompleteCallback != nil { 542 | prefix := string(t.line[:t.pos]) 543 | suffix := string(t.line[t.pos:]) 544 | 545 | t.lock.Unlock() 546 | newLine, newPos, completeOk := t.AutoCompleteCallback(prefix+suffix, len(prefix), key) 547 | t.lock.Lock() 548 | 549 | if completeOk { 550 | t.setLine([]rune(newLine), utf8.RuneCount([]byte(newLine)[:newPos])) 551 | return 552 | } 553 | } 554 | if !isPrintable(key) { 555 | return 556 | } 557 | if len(t.line) == maxLineLength { 558 | return 559 | } 560 | t.addKeyToLine(key) 561 | } 562 | return 563 | } 564 | 565 | // addKeyToLine inserts the given key at the current position in the current 566 | // line. 567 | func (t *Terminal) addKeyToLine(key rune) { 568 | if len(t.line) == cap(t.line) { 569 | newLine := make([]rune, len(t.line), 2*(1+len(t.line))) 570 | copy(newLine, t.line) 571 | t.line = newLine 572 | } 573 | t.line = t.line[:len(t.line)+1] 574 | copy(t.line[t.pos+1:], t.line[t.pos:]) 575 | t.line[t.pos] = key 576 | if t.echo { 577 | t.writeLine(t.line[t.pos:]) 578 | } 579 | t.pos++ 580 | t.moveCursorToPos(t.pos) 581 | } 582 | 583 | func (t *Terminal) writeLine(line []rune) { 584 | for len(line) != 0 { 585 | remainingOnLine := t.termWidth - t.cursorX 586 | todo := len(line) 587 | if todo > remainingOnLine { 588 | todo = remainingOnLine 589 | } 590 | t.queue(line[:todo]) 591 | t.advanceCursor(visualLength(line[:todo])) 592 | line = line[todo:] 593 | } 594 | } 595 | 596 | func (t *Terminal) Write(buf []byte) (n int, err error) { 597 | t.lock.Lock() 598 | defer t.lock.Unlock() 599 | 600 | if t.cursorX == 0 && t.cursorY == 0 { 601 | // This is the easy case: there's nothing on the screen that we 602 | // have to move out of the way. 603 | return t.c.Write(buf) 604 | } 605 | 606 | // We have a prompt and possibly user input on the screen. We 607 | // have to clear it first. 608 | t.move(0 /* up */, 0 /* down */, t.cursorX /* left */, 0 /* right */) 609 | t.cursorX = 0 610 | t.clearLineToRight() 611 | 612 | for t.cursorY > 0 { 613 | t.move(1 /* up */, 0, 0, 0) 614 | t.cursorY-- 615 | t.clearLineToRight() 616 | } 617 | 618 | if _, err = t.c.Write(t.outBuf); err != nil { 619 | return 620 | } 621 | t.outBuf = t.outBuf[:0] 622 | 623 | if n, err = t.c.Write(buf); err != nil { 624 | return 625 | } 626 | 627 | t.writeLine(t.prompt) 628 | if t.echo { 629 | t.writeLine(t.line) 630 | } 631 | 632 | t.moveCursorToPos(t.pos) 633 | 634 | if _, err = t.c.Write(t.outBuf); err != nil { 635 | return 636 | } 637 | t.outBuf = t.outBuf[:0] 638 | return 639 | } 640 | 641 | // ReadPassword temporarily changes the prompt and reads a password, without 642 | // echo, from the terminal. 643 | func (t *Terminal) ReadPassword(prompt string) (line string, err error) { 644 | t.lock.Lock() 645 | defer t.lock.Unlock() 646 | 647 | oldPrompt := t.prompt 648 | t.prompt = []rune(prompt) 649 | t.echo = false 650 | 651 | line, err = t.readLine() 652 | 653 | t.prompt = oldPrompt 654 | t.echo = true 655 | 656 | return 657 | } 658 | 659 | // ReadLine returns a line of input from the terminal. 660 | func (t *Terminal) ReadLine() (line string, err error) { 661 | t.lock.Lock() 662 | defer t.lock.Unlock() 663 | 664 | return t.readLine() 665 | } 666 | 667 | func (t *Terminal) readLine() (line string, err error) { 668 | // t.lock must be held at this point 669 | 670 | if t.cursorX == 0 && t.cursorY == 0 { 671 | t.writeLine(t.prompt) 672 | t.c.Write(t.outBuf) 673 | t.outBuf = t.outBuf[:0] 674 | } 675 | 676 | lineIsPasted := t.pasteActive 677 | 678 | for { 679 | rest := t.remainder 680 | lineOk := false 681 | for !lineOk { 682 | var key rune 683 | key, rest = bytesToKey(rest, t.pasteActive) 684 | if key == utf8.RuneError { 685 | break 686 | } 687 | if !t.pasteActive { 688 | if key == keyCtrlD { 689 | if len(t.line) == 0 { 690 | return "", io.EOF 691 | } 692 | } 693 | if key == keyPasteStart { 694 | t.pasteActive = true 695 | if len(t.line) == 0 { 696 | lineIsPasted = true 697 | } 698 | continue 699 | } 700 | } else if key == keyPasteEnd { 701 | t.pasteActive = false 702 | continue 703 | } 704 | if !t.pasteActive { 705 | lineIsPasted = false 706 | } 707 | line, lineOk = t.handleKey(key) 708 | } 709 | if len(rest) > 0 { 710 | n := copy(t.inBuf[:], rest) 711 | t.remainder = t.inBuf[:n] 712 | } else { 713 | t.remainder = nil 714 | } 715 | t.c.Write(t.outBuf) 716 | t.outBuf = t.outBuf[:0] 717 | if lineOk { 718 | if t.echo { 719 | t.historyIndex = -1 720 | t.history.Add(line) 721 | } 722 | if lineIsPasted { 723 | err = ErrPasteIndicator 724 | } 725 | return 726 | } 727 | 728 | // t.remainder is a slice at the beginning of t.inBuf 729 | // containing a partial key sequence 730 | readBuf := t.inBuf[len(t.remainder):] 731 | var n int 732 | 733 | t.lock.Unlock() 734 | n, err = t.c.Read(readBuf) 735 | t.lock.Lock() 736 | 737 | if err != nil { 738 | return 739 | } 740 | 741 | t.remainder = t.inBuf[:n+len(t.remainder)] 742 | } 743 | 744 | panic("unreachable") // for Go 1.0. 745 | } 746 | 747 | // SetPrompt sets the prompt to be used when reading subsequent lines. 748 | func (t *Terminal) SetPrompt(prompt string) { 749 | t.lock.Lock() 750 | defer t.lock.Unlock() 751 | 752 | t.prompt = []rune(prompt) 753 | } 754 | 755 | func (t *Terminal) clearAndRepaintLinePlusNPrevious(numPrevLines int) { 756 | // Move cursor to column zero at the start of the line. 757 | t.move(t.cursorY, 0, t.cursorX, 0) 758 | t.cursorX, t.cursorY = 0, 0 759 | t.clearLineToRight() 760 | for t.cursorY < numPrevLines { 761 | // Move down a line 762 | t.move(0, 1, 0, 0) 763 | t.cursorY++ 764 | t.clearLineToRight() 765 | } 766 | // Move back to beginning. 767 | t.move(t.cursorY, 0, 0, 0) 768 | t.cursorX, t.cursorY = 0, 0 769 | 770 | t.queue(t.prompt) 771 | t.advanceCursor(visualLength(t.prompt)) 772 | t.writeLine(t.line) 773 | t.moveCursorToPos(t.pos) 774 | } 775 | 776 | func (t *Terminal) SetSize(width, height int) error { 777 | t.lock.Lock() 778 | defer t.lock.Unlock() 779 | 780 | if width == 0 { 781 | width = 1 782 | } 783 | 784 | oldWidth := t.termWidth 785 | t.termWidth, t.termHeight = width, height 786 | 787 | switch { 788 | case width == oldWidth: 789 | // If the width didn't change then nothing else needs to be 790 | // done. 791 | return nil 792 | case len(t.line) == 0 && t.cursorX == 0 && t.cursorY == 0: 793 | // If there is nothing on current line and no prompt printed, 794 | // just do nothing 795 | return nil 796 | case width < oldWidth: 797 | // Some terminals (e.g. xterm) will truncate lines that were 798 | // too long when shinking. Others, (e.g. gnome-terminal) will 799 | // attempt to wrap them. For the former, repainting t.maxLine 800 | // works great, but that behaviour goes badly wrong in the case 801 | // of the latter because they have doubled every full line. 802 | 803 | // We assume that we are working on a terminal that wraps lines 804 | // and adjust the cursor position based on every previous line 805 | // wrapping and turning into two. This causes the prompt on 806 | // xterms to move upwards, which isn't great, but it avoids a 807 | // huge mess with gnome-terminal. 808 | if t.cursorX >= t.termWidth { 809 | t.cursorX = t.termWidth - 1 810 | } 811 | t.cursorY *= 2 812 | t.clearAndRepaintLinePlusNPrevious(t.maxLine * 2) 813 | case width > oldWidth: 814 | // If the terminal expands then our position calculations will 815 | // be wrong in the future because we think the cursor is 816 | // |t.pos| chars into the string, but there will be a gap at 817 | // the end of any wrapped line. 818 | // 819 | // But the position will actually be correct until we move, so 820 | // we can move back to the beginning and repaint everything. 821 | t.clearAndRepaintLinePlusNPrevious(t.maxLine) 822 | } 823 | 824 | _, err := t.c.Write(t.outBuf) 825 | t.outBuf = t.outBuf[:0] 826 | return err 827 | } 828 | 829 | type pasteIndicatorError struct{} 830 | 831 | func (pasteIndicatorError) Error() string { 832 | return "terminal: ErrPasteIndicator not correctly handled" 833 | } 834 | 835 | // ErrPasteIndicator may be returned from ReadLine as the error, in addition 836 | // to valid line data. It indicates that bracketed paste mode is enabled and 837 | // that the returned line consists only of pasted data. Programs may wish to 838 | // interpret pasted data more literally than typed data. 839 | var ErrPasteIndicator = pasteIndicatorError{} 840 | 841 | // SetBracketedPasteMode requests that the terminal bracket paste operations 842 | // with markers. Not all terminals support this but, if it is supported, then 843 | // enabling this mode will stop any autocomplete callback from running due to 844 | // pastes. Additionally, any lines that are completely pasted will be returned 845 | // from ReadLine with the error set to ErrPasteIndicator. 846 | func (t *Terminal) SetBracketedPasteMode(on bool) { 847 | if on { 848 | io.WriteString(t.c, "\x1b[?2004h") 849 | } else { 850 | io.WriteString(t.c, "\x1b[?2004l") 851 | } 852 | } 853 | 854 | // stRingBuffer is a ring buffer of strings. 855 | type stRingBuffer struct { 856 | // entries contains max elements. 857 | entries []string 858 | max int 859 | // head contains the index of the element most recently added to the ring. 860 | head int 861 | // size contains the number of elements in the ring. 862 | size int 863 | } 864 | 865 | func (s *stRingBuffer) Add(a string) { 866 | if s.entries == nil { 867 | const defaultNumEntries = 100 868 | s.entries = make([]string, defaultNumEntries) 869 | s.max = defaultNumEntries 870 | } 871 | 872 | s.head = (s.head + 1) % s.max 873 | s.entries[s.head] = a 874 | if s.size < s.max { 875 | s.size++ 876 | } 877 | } 878 | 879 | // NthPreviousEntry returns the value passed to the nth previous call to Add. 880 | // If n is zero then the immediately prior value is returned, if one, then the 881 | // next most recent, and so on. If such an element doesn't exist then ok is 882 | // false. 883 | func (s *stRingBuffer) NthPreviousEntry(n int) (value string, ok bool) { 884 | if n >= s.size { 885 | return "", false 886 | } 887 | index := s.head - n 888 | if index < 0 { 889 | index += s.max 890 | } 891 | return s.entries[index], true 892 | } 893 | -------------------------------------------------------------------------------- /vendor/golang.org/x/crypto/ssh/terminal/util.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build darwin dragonfly freebsd linux,!appengine netbsd openbsd 6 | 7 | // Package terminal provides support functions for dealing with terminals, as 8 | // commonly found on UNIX systems. 9 | // 10 | // Putting a terminal into raw mode is the most common requirement: 11 | // 12 | // oldState, err := terminal.MakeRaw(0) 13 | // if err != nil { 14 | // panic(err) 15 | // } 16 | // defer terminal.Restore(0, oldState) 17 | package terminal // import "golang.org/x/crypto/ssh/terminal" 18 | 19 | import ( 20 | "io" 21 | "syscall" 22 | "unsafe" 23 | ) 24 | 25 | // State contains the state of a terminal. 26 | type State struct { 27 | termios syscall.Termios 28 | } 29 | 30 | // IsTerminal returns true if the given file descriptor is a terminal. 31 | func IsTerminal(fd int) bool { 32 | var termios syscall.Termios 33 | _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlReadTermios, uintptr(unsafe.Pointer(&termios)), 0, 0, 0) 34 | return err == 0 35 | } 36 | 37 | // MakeRaw put the terminal connected to the given file descriptor into raw 38 | // mode and returns the previous state of the terminal so that it can be 39 | // restored. 40 | func MakeRaw(fd int) (*State, error) { 41 | var oldState State 42 | if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlReadTermios, uintptr(unsafe.Pointer(&oldState.termios)), 0, 0, 0); err != 0 { 43 | return nil, err 44 | } 45 | 46 | newState := oldState.termios 47 | // This attempts to replicate the behaviour documented for cfmakeraw in 48 | // the termios(3) manpage. 49 | newState.Iflag &^= syscall.IGNBRK | syscall.BRKINT | syscall.PARMRK | syscall.ISTRIP | syscall.INLCR | syscall.IGNCR | syscall.ICRNL | syscall.IXON 50 | newState.Oflag &^= syscall.OPOST 51 | newState.Lflag &^= syscall.ECHO | syscall.ECHONL | syscall.ICANON | syscall.ISIG | syscall.IEXTEN 52 | newState.Cflag &^= syscall.CSIZE | syscall.PARENB 53 | newState.Cflag |= syscall.CS8 54 | if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlWriteTermios, uintptr(unsafe.Pointer(&newState)), 0, 0, 0); err != 0 { 55 | return nil, err 56 | } 57 | 58 | return &oldState, nil 59 | } 60 | 61 | // GetState returns the current state of a terminal which may be useful to 62 | // restore the terminal after a signal. 63 | func GetState(fd int) (*State, error) { 64 | var oldState State 65 | if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlReadTermios, uintptr(unsafe.Pointer(&oldState.termios)), 0, 0, 0); err != 0 { 66 | return nil, err 67 | } 68 | 69 | return &oldState, nil 70 | } 71 | 72 | // Restore restores the terminal connected to the given file descriptor to a 73 | // previous state. 74 | func Restore(fd int, state *State) error { 75 | _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlWriteTermios, uintptr(unsafe.Pointer(&state.termios)), 0, 0, 0) 76 | return err 77 | } 78 | 79 | // GetSize returns the dimensions of the given terminal. 80 | func GetSize(fd int) (width, height int, err error) { 81 | var dimensions [4]uint16 82 | 83 | if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), uintptr(syscall.TIOCGWINSZ), uintptr(unsafe.Pointer(&dimensions)), 0, 0, 0); err != 0 { 84 | return -1, -1, err 85 | } 86 | return int(dimensions[1]), int(dimensions[0]), nil 87 | } 88 | 89 | // ReadPassword reads a line of input from a terminal without local echo. This 90 | // is commonly used for inputting passwords and other sensitive data. The slice 91 | // returned does not include the \n. 92 | func ReadPassword(fd int) ([]byte, error) { 93 | var oldState syscall.Termios 94 | if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlReadTermios, uintptr(unsafe.Pointer(&oldState)), 0, 0, 0); err != 0 { 95 | return nil, err 96 | } 97 | 98 | newState := oldState 99 | newState.Lflag &^= syscall.ECHO 100 | newState.Lflag |= syscall.ICANON | syscall.ISIG 101 | newState.Iflag |= syscall.ICRNL 102 | if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlWriteTermios, uintptr(unsafe.Pointer(&newState)), 0, 0, 0); err != 0 { 103 | return nil, err 104 | } 105 | 106 | defer func() { 107 | syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlWriteTermios, uintptr(unsafe.Pointer(&oldState)), 0, 0, 0) 108 | }() 109 | 110 | var buf [16]byte 111 | var ret []byte 112 | for { 113 | n, err := syscall.Read(fd, buf[:]) 114 | if err != nil { 115 | return nil, err 116 | } 117 | if n == 0 { 118 | if len(ret) == 0 { 119 | return nil, io.EOF 120 | } 121 | break 122 | } 123 | if buf[n-1] == '\n' { 124 | n-- 125 | } 126 | ret = append(ret, buf[:n]...) 127 | if n < len(buf) { 128 | break 129 | } 130 | } 131 | 132 | return ret, nil 133 | } 134 | -------------------------------------------------------------------------------- /vendor/golang.org/x/crypto/ssh/terminal/util_bsd.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build darwin dragonfly freebsd netbsd openbsd 6 | 7 | package terminal 8 | 9 | import "syscall" 10 | 11 | const ioctlReadTermios = syscall.TIOCGETA 12 | const ioctlWriteTermios = syscall.TIOCSETA 13 | -------------------------------------------------------------------------------- /vendor/golang.org/x/crypto/ssh/terminal/util_linux.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package terminal 6 | 7 | // These constants are declared here, rather than importing 8 | // them from the syscall package as some syscall packages, even 9 | // on linux, for example gccgo, do not declare them. 10 | const ioctlReadTermios = 0x5401 // syscall.TCGETS 11 | const ioctlWriteTermios = 0x5402 // syscall.TCSETS 12 | -------------------------------------------------------------------------------- /vendor/golang.org/x/crypto/ssh/terminal/util_plan9.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // Package terminal provides support functions for dealing with terminals, as 6 | // commonly found on UNIX systems. 7 | // 8 | // Putting a terminal into raw mode is the most common requirement: 9 | // 10 | // oldState, err := terminal.MakeRaw(0) 11 | // if err != nil { 12 | // panic(err) 13 | // } 14 | // defer terminal.Restore(0, oldState) 15 | package terminal 16 | 17 | import ( 18 | "fmt" 19 | "runtime" 20 | ) 21 | 22 | type State struct{} 23 | 24 | // IsTerminal returns true if the given file descriptor is a terminal. 25 | func IsTerminal(fd int) bool { 26 | return false 27 | } 28 | 29 | // MakeRaw put the terminal connected to the given file descriptor into raw 30 | // mode and returns the previous state of the terminal so that it can be 31 | // restored. 32 | func MakeRaw(fd int) (*State, error) { 33 | return nil, fmt.Errorf("terminal: MakeRaw not implemented on %s/%s", runtime.GOOS, runtime.GOARCH) 34 | } 35 | 36 | // GetState returns the current state of a terminal which may be useful to 37 | // restore the terminal after a signal. 38 | func GetState(fd int) (*State, error) { 39 | return nil, fmt.Errorf("terminal: GetState not implemented on %s/%s", runtime.GOOS, runtime.GOARCH) 40 | } 41 | 42 | // Restore restores the terminal connected to the given file descriptor to a 43 | // previous state. 44 | func Restore(fd int, state *State) error { 45 | return fmt.Errorf("terminal: Restore not implemented on %s/%s", runtime.GOOS, runtime.GOARCH) 46 | } 47 | 48 | // GetSize returns the dimensions of the given terminal. 49 | func GetSize(fd int) (width, height int, err error) { 50 | return 0, 0, fmt.Errorf("terminal: GetSize not implemented on %s/%s", runtime.GOOS, runtime.GOARCH) 51 | } 52 | 53 | // ReadPassword reads a line of input from a terminal without local echo. This 54 | // is commonly used for inputting passwords and other sensitive data. The slice 55 | // returned does not include the \n. 56 | func ReadPassword(fd int) ([]byte, error) { 57 | return nil, fmt.Errorf("terminal: ReadPassword not implemented on %s/%s", runtime.GOOS, runtime.GOARCH) 58 | } 59 | -------------------------------------------------------------------------------- /vendor/golang.org/x/crypto/ssh/terminal/util_solaris.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build solaris 6 | 7 | package terminal // import "golang.org/x/crypto/ssh/terminal" 8 | 9 | import ( 10 | "golang.org/x/sys/unix" 11 | "io" 12 | "syscall" 13 | ) 14 | 15 | // State contains the state of a terminal. 16 | type State struct { 17 | termios syscall.Termios 18 | } 19 | 20 | // IsTerminal returns true if the given file descriptor is a terminal. 21 | func IsTerminal(fd int) bool { 22 | // see: http://src.illumos.org/source/xref/illumos-gate/usr/src/lib/libbc/libc/gen/common/isatty.c 23 | var termio unix.Termio 24 | err := unix.IoctlSetTermio(fd, unix.TCGETA, &termio) 25 | return err == nil 26 | } 27 | 28 | // ReadPassword reads a line of input from a terminal without local echo. This 29 | // is commonly used for inputting passwords and other sensitive data. The slice 30 | // returned does not include the \n. 31 | func ReadPassword(fd int) ([]byte, error) { 32 | // see also: http://src.illumos.org/source/xref/illumos-gate/usr/src/lib/libast/common/uwin/getpass.c 33 | val, err := unix.IoctlGetTermios(fd, unix.TCGETS) 34 | if err != nil { 35 | return nil, err 36 | } 37 | oldState := *val 38 | 39 | newState := oldState 40 | newState.Lflag &^= syscall.ECHO 41 | newState.Lflag |= syscall.ICANON | syscall.ISIG 42 | newState.Iflag |= syscall.ICRNL 43 | err = unix.IoctlSetTermios(fd, unix.TCSETS, &newState) 44 | if err != nil { 45 | return nil, err 46 | } 47 | 48 | defer unix.IoctlSetTermios(fd, unix.TCSETS, &oldState) 49 | 50 | var buf [16]byte 51 | var ret []byte 52 | for { 53 | n, err := syscall.Read(fd, buf[:]) 54 | if err != nil { 55 | return nil, err 56 | } 57 | if n == 0 { 58 | if len(ret) == 0 { 59 | return nil, io.EOF 60 | } 61 | break 62 | } 63 | if buf[n-1] == '\n' { 64 | n-- 65 | } 66 | ret = append(ret, buf[:n]...) 67 | if n < len(buf) { 68 | break 69 | } 70 | } 71 | 72 | return ret, nil 73 | } 74 | -------------------------------------------------------------------------------- /vendor/golang.org/x/crypto/ssh/terminal/util_windows.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build windows 6 | 7 | // Package terminal provides support functions for dealing with terminals, as 8 | // commonly found on UNIX systems. 9 | // 10 | // Putting a terminal into raw mode is the most common requirement: 11 | // 12 | // oldState, err := terminal.MakeRaw(0) 13 | // if err != nil { 14 | // panic(err) 15 | // } 16 | // defer terminal.Restore(0, oldState) 17 | package terminal 18 | 19 | import ( 20 | "io" 21 | "syscall" 22 | "unsafe" 23 | ) 24 | 25 | const ( 26 | enableLineInput = 2 27 | enableEchoInput = 4 28 | enableProcessedInput = 1 29 | enableWindowInput = 8 30 | enableMouseInput = 16 31 | enableInsertMode = 32 32 | enableQuickEditMode = 64 33 | enableExtendedFlags = 128 34 | enableAutoPosition = 256 35 | enableProcessedOutput = 1 36 | enableWrapAtEolOutput = 2 37 | ) 38 | 39 | var kernel32 = syscall.NewLazyDLL("kernel32.dll") 40 | 41 | var ( 42 | procGetConsoleMode = kernel32.NewProc("GetConsoleMode") 43 | procSetConsoleMode = kernel32.NewProc("SetConsoleMode") 44 | procGetConsoleScreenBufferInfo = kernel32.NewProc("GetConsoleScreenBufferInfo") 45 | ) 46 | 47 | type ( 48 | short int16 49 | word uint16 50 | 51 | coord struct { 52 | x short 53 | y short 54 | } 55 | smallRect struct { 56 | left short 57 | top short 58 | right short 59 | bottom short 60 | } 61 | consoleScreenBufferInfo struct { 62 | size coord 63 | cursorPosition coord 64 | attributes word 65 | window smallRect 66 | maximumWindowSize coord 67 | } 68 | ) 69 | 70 | type State struct { 71 | mode uint32 72 | } 73 | 74 | // IsTerminal returns true if the given file descriptor is a terminal. 75 | func IsTerminal(fd int) bool { 76 | var st uint32 77 | r, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, uintptr(fd), uintptr(unsafe.Pointer(&st)), 0) 78 | return r != 0 && e == 0 79 | } 80 | 81 | // MakeRaw put the terminal connected to the given file descriptor into raw 82 | // mode and returns the previous state of the terminal so that it can be 83 | // restored. 84 | func MakeRaw(fd int) (*State, error) { 85 | var st uint32 86 | _, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, uintptr(fd), uintptr(unsafe.Pointer(&st)), 0) 87 | if e != 0 { 88 | return nil, error(e) 89 | } 90 | raw := st &^ (enableEchoInput | enableProcessedInput | enableLineInput | enableProcessedOutput) 91 | _, _, e = syscall.Syscall(procSetConsoleMode.Addr(), 2, uintptr(fd), uintptr(raw), 0) 92 | if e != 0 { 93 | return nil, error(e) 94 | } 95 | return &State{st}, nil 96 | } 97 | 98 | // GetState returns the current state of a terminal which may be useful to 99 | // restore the terminal after a signal. 100 | func GetState(fd int) (*State, error) { 101 | var st uint32 102 | _, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, uintptr(fd), uintptr(unsafe.Pointer(&st)), 0) 103 | if e != 0 { 104 | return nil, error(e) 105 | } 106 | return &State{st}, nil 107 | } 108 | 109 | // Restore restores the terminal connected to the given file descriptor to a 110 | // previous state. 111 | func Restore(fd int, state *State) error { 112 | _, _, err := syscall.Syscall(procSetConsoleMode.Addr(), 2, uintptr(fd), uintptr(state.mode), 0) 113 | return err 114 | } 115 | 116 | // GetSize returns the dimensions of the given terminal. 117 | func GetSize(fd int) (width, height int, err error) { 118 | var info consoleScreenBufferInfo 119 | _, _, e := syscall.Syscall(procGetConsoleScreenBufferInfo.Addr(), 2, uintptr(fd), uintptr(unsafe.Pointer(&info)), 0) 120 | if e != 0 { 121 | return 0, 0, error(e) 122 | } 123 | return int(info.size.x), int(info.size.y), nil 124 | } 125 | 126 | // ReadPassword reads a line of input from a terminal without local echo. This 127 | // is commonly used for inputting passwords and other sensitive data. The slice 128 | // returned does not include the \n. 129 | func ReadPassword(fd int) ([]byte, error) { 130 | var st uint32 131 | _, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, uintptr(fd), uintptr(unsafe.Pointer(&st)), 0) 132 | if e != 0 { 133 | return nil, error(e) 134 | } 135 | old := st 136 | 137 | st &^= (enableEchoInput) 138 | st |= (enableProcessedInput | enableLineInput | enableProcessedOutput) 139 | _, _, e = syscall.Syscall(procSetConsoleMode.Addr(), 2, uintptr(fd), uintptr(st), 0) 140 | if e != 0 { 141 | return nil, error(e) 142 | } 143 | 144 | defer func() { 145 | syscall.Syscall(procSetConsoleMode.Addr(), 2, uintptr(fd), uintptr(old), 0) 146 | }() 147 | 148 | var buf [16]byte 149 | var ret []byte 150 | for { 151 | n, err := syscall.Read(syscall.Handle(fd), buf[:]) 152 | if err != nil { 153 | return nil, err 154 | } 155 | if n == 0 { 156 | if len(ret) == 0 { 157 | return nil, io.EOF 158 | } 159 | break 160 | } 161 | if buf[n-1] == '\n' { 162 | n-- 163 | } 164 | if n > 0 && buf[n-1] == '\r' { 165 | n-- 166 | } 167 | ret = append(ret, buf[:n]...) 168 | if n < len(buf) { 169 | break 170 | } 171 | } 172 | 173 | return ret, nil 174 | } 175 | -------------------------------------------------------------------------------- /vendor/vendor.json: -------------------------------------------------------------------------------- 1 | { 2 | "comment": "", 3 | "ignore": "test", 4 | "package": [ 5 | { 6 | "checksumSHA1": "lEuAuEXh42xoG+Ygw90K3EF99Xo=", 7 | "path": "github.com/fatih/color", 8 | "revision": "dea9d3a26a087187530244679c1cfb3a42937794", 9 | "revisionTime": "2016-10-02T08:12:59Z" 10 | }, 11 | { 12 | "checksumSHA1": "lJDwzzEBuS9sjxVOSsq7+rvw+cA=", 13 | "path": "github.com/howeyc/gopass", 14 | "revision": "f5387c492211eb133053880d23dfae62aa14123d", 15 | "revisionTime": "2016-10-03T13:09:00Z" 16 | }, 17 | { 18 | "checksumSHA1": "ugnSryGF6VPBb5s87QgoRH6730g=", 19 | "path": "github.com/mattn/go-colorable", 20 | "revision": "6c903ff4aa50920ca86087a280590b36b3152b9c", 21 | "revisionTime": "2016-09-30T08:41:57Z" 22 | }, 23 | { 24 | "checksumSHA1": "xZuhljnmBysJPta/lMyYmJdujCg=", 25 | "path": "github.com/mattn/go-isatty", 26 | "revision": "66b8e73f3f5cda9f96b69efd03dd3d7fc4a5cdb8", 27 | "revisionTime": "2016-08-06T12:27:52Z" 28 | }, 29 | { 30 | "checksumSHA1": "9C4Av3ypK5pi173F76ogJT/d8x4=", 31 | "path": "golang.org/x/crypto/ssh/terminal", 32 | "revision": "4428aee3e5957ee2252b9c7a17460e5147363b4b", 33 | "revisionTime": "2016-10-12T19:11:18Z" 34 | } 35 | ], 36 | "rootPath": "github.com/coralproject/ask-install" 37 | } 38 | --------------------------------------------------------------------------------